VPP-362 Implement dumping of LISP adjacencies
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #if DPDK > 0
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #else
44 #include <inttypes.h>
45 #endif
46 #include <vnet/map/map.h>
47 #include <vnet/cop/cop.h>
48 #include <vnet/ip/ip6_hop_by_hop.h>
49 #include <vnet/ip/ip_source_and_port_range_check.h>
50 #include <vnet/policer/xlate.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53
54 #include "vat/json_format.h"
55
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp-api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp-api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp-api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 uword
75 unformat_sw_if_index (unformat_input_t * input, va_list * args)
76 {
77   vat_main_t *vam = va_arg (*args, vat_main_t *);
78   u32 *result = va_arg (*args, u32 *);
79   u8 *if_name;
80   uword *p;
81
82   if (!unformat (input, "%s", &if_name))
83     return 0;
84
85   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
86   if (p == 0)
87     return 0;
88   *result = p[0];
89   return 1;
90 }
91
92 /* Parse an IP4 address %d.%d.%d.%d. */
93 uword
94 unformat_ip4_address (unformat_input_t * input, va_list * args)
95 {
96   u8 *result = va_arg (*args, u8 *);
97   unsigned a[4];
98
99   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
100     return 0;
101
102   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
103     return 0;
104
105   result[0] = a[0];
106   result[1] = a[1];
107   result[2] = a[2];
108   result[3] = a[3];
109
110   return 1;
111 }
112
113
114 uword
115 unformat_ethernet_address (unformat_input_t * input, va_list * args)
116 {
117   u8 *result = va_arg (*args, u8 *);
118   u32 i, a[6];
119
120   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
121                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
122     return 0;
123
124   /* Check range. */
125   for (i = 0; i < 6; i++)
126     if (a[i] >= (1 << 8))
127       return 0;
128
129   for (i = 0; i < 6; i++)
130     result[i] = a[i];
131
132   return 1;
133 }
134
135 /* Returns ethernet type as an int in host byte order. */
136 uword
137 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
138                                         va_list * args)
139 {
140   u16 *result = va_arg (*args, u16 *);
141   int type;
142
143   /* Numeric type. */
144   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
145     {
146       if (type >= (1 << 16))
147         return 0;
148       *result = type;
149       return 1;
150     }
151   return 0;
152 }
153
154 /* Parse an IP6 address. */
155 uword
156 unformat_ip6_address (unformat_input_t * input, va_list * args)
157 {
158   ip6_address_t *result = va_arg (*args, ip6_address_t *);
159   u16 hex_quads[8];
160   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
161   uword c, n_colon, double_colon_index;
162
163   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
164   double_colon_index = ARRAY_LEN (hex_quads);
165   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
166     {
167       hex_digit = 16;
168       if (c >= '0' && c <= '9')
169         hex_digit = c - '0';
170       else if (c >= 'a' && c <= 'f')
171         hex_digit = c + 10 - 'a';
172       else if (c >= 'A' && c <= 'F')
173         hex_digit = c + 10 - 'A';
174       else if (c == ':' && n_colon < 2)
175         n_colon++;
176       else
177         {
178           unformat_put_input (input);
179           break;
180         }
181
182       /* Too many hex quads. */
183       if (n_hex_quads >= ARRAY_LEN (hex_quads))
184         return 0;
185
186       if (hex_digit < 16)
187         {
188           hex_quad = (hex_quad << 4) | hex_digit;
189
190           /* Hex quad must fit in 16 bits. */
191           if (n_hex_digits >= 4)
192             return 0;
193
194           n_colon = 0;
195           n_hex_digits++;
196         }
197
198       /* Save position of :: */
199       if (n_colon == 2)
200         {
201           /* More than one :: ? */
202           if (double_colon_index < ARRAY_LEN (hex_quads))
203             return 0;
204           double_colon_index = n_hex_quads;
205         }
206
207       if (n_colon > 0 && n_hex_digits > 0)
208         {
209           hex_quads[n_hex_quads++] = hex_quad;
210           hex_quad = 0;
211           n_hex_digits = 0;
212         }
213     }
214
215   if (n_hex_digits > 0)
216     hex_quads[n_hex_quads++] = hex_quad;
217
218   {
219     word i;
220
221     /* Expand :: to appropriate number of zero hex quads. */
222     if (double_colon_index < ARRAY_LEN (hex_quads))
223       {
224         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
225
226         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
227           hex_quads[n_zero + i] = hex_quads[i];
228
229         for (i = 0; i < n_zero; i++)
230           hex_quads[double_colon_index + i] = 0;
231
232         n_hex_quads = ARRAY_LEN (hex_quads);
233       }
234
235     /* Too few hex quads given. */
236     if (n_hex_quads < ARRAY_LEN (hex_quads))
237       return 0;
238
239     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
240       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
241
242     return 1;
243   }
244 }
245
246 uword
247 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
248 {
249 #if DPDK > 0
250   u32 *r = va_arg (*args, u32 *);
251
252   if (0);
253 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
254   foreach_ipsec_policy_action
255 #undef _
256     else
257     return 0;
258   return 1;
259 #else
260   return 0;
261 #endif
262 }
263
264 uword
265 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
266 {
267 #if DPDK > 0
268   u32 *r = va_arg (*args, u32 *);
269
270   if (0);
271 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
272   foreach_ipsec_crypto_alg
273 #undef _
274     else
275     return 0;
276   return 1;
277 #else
278   return 0;
279 #endif
280 }
281
282 u8 *
283 format_ipsec_crypto_alg (u8 * s, va_list * args)
284 {
285 #if DPDK > 0
286   u32 i = va_arg (*args, u32);
287   u8 *t = 0;
288
289   switch (i)
290     {
291 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
292       foreach_ipsec_crypto_alg
293 #undef _
294     default:
295       return format (s, "unknown");
296     }
297   return format (s, "%s", t);
298 #else
299   return format (s, "Unimplemented");
300 #endif
301 }
302
303 uword
304 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
305 {
306 #if DPDK > 0
307   u32 *r = va_arg (*args, u32 *);
308
309   if (0);
310 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
311   foreach_ipsec_integ_alg
312 #undef _
313     else
314     return 0;
315   return 1;
316 #else
317   return 0;
318 #endif
319 }
320
321 u8 *
322 format_ipsec_integ_alg (u8 * s, va_list * args)
323 {
324 #if DPDK > 0
325   u32 i = va_arg (*args, u32);
326   u8 *t = 0;
327
328   switch (i)
329     {
330 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
331       foreach_ipsec_integ_alg
332 #undef _
333     default:
334       return format (s, "unknown");
335     }
336   return format (s, "%s", t);
337 #else
338   return format (s, "Unsupported");
339 #endif
340 }
341
342 uword
343 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
344 {
345 #if DPDK > 0
346   u32 *r = va_arg (*args, u32 *);
347
348   if (0);
349 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
350   foreach_ikev2_auth_method
351 #undef _
352     else
353     return 0;
354   return 1;
355 #else
356   return 0;
357 #endif
358 }
359
360 uword
361 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
362 {
363 #if DPDK > 0
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
368   foreach_ikev2_id_type
369 #undef _
370     else
371     return 0;
372   return 1;
373 #else
374   return 0;
375 #endif
376 }
377
378 uword
379 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
380 {
381   u8 *r = va_arg (*args, u8 *);
382
383   if (unformat (input, "kbps"))
384     *r = SSE2_QOS_RATE_KBPS;
385   else if (unformat (input, "pps"))
386     *r = SSE2_QOS_RATE_PPS;
387   else
388     return 0;
389   return 1;
390 }
391
392 uword
393 unformat_policer_round_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "closest"))
398     *r = SSE2_QOS_ROUND_TO_CLOSEST;
399   else if (unformat (input, "up"))
400     *r = SSE2_QOS_ROUND_TO_UP;
401   else if (unformat (input, "down"))
402     *r = SSE2_QOS_ROUND_TO_DOWN;
403   else
404     return 0;
405   return 1;
406 }
407
408 uword
409 unformat_policer_type (unformat_input_t * input, va_list * args)
410 {
411   u8 *r = va_arg (*args, u8 *);
412
413   if (unformat (input, "1r2c"))
414     *r = SSE2_QOS_POLICER_TYPE_1R2C;
415   else if (unformat (input, "1r3c"))
416     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
417   else if (unformat (input, "2r3c-2698"))
418     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
419   else if (unformat (input, "2r3c-4115"))
420     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
421   else if (unformat (input, "2r3c-mef5cf1"))
422     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
423   else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_dscp (unformat_input_t * input, va_list * va)
430 {
431   u8 *r = va_arg (*va, u8 *);
432
433   if (0);
434 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
435   foreach_vnet_dscp
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_policer_action_type (unformat_input_t * input, va_list * va)
444 {
445   sse2_qos_pol_action_params_st *a
446     = va_arg (*va, sse2_qos_pol_action_params_st *);
447
448   if (unformat (input, "drop"))
449     a->action_type = SSE2_QOS_ACTION_DROP;
450   else if (unformat (input, "transmit"))
451     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
452   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
453     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
454   else
455     return 0;
456   return 1;
457 }
458
459 uword
460 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
461 {
462   u32 *r = va_arg (*va, u32 *);
463   u32 tid;
464
465   if (unformat (input, "ip4"))
466     tid = POLICER_CLASSIFY_TABLE_IP4;
467   else if (unformat (input, "ip6"))
468     tid = POLICER_CLASSIFY_TABLE_IP6;
469   else if (unformat (input, "l2"))
470     tid = POLICER_CLASSIFY_TABLE_L2;
471   else
472     return 0;
473
474   *r = tid;
475   return 1;
476 }
477
478 uword
479 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
480 {
481   u32 *r = va_arg (*va, u32 *);
482   u32 tid;
483
484   if (unformat (input, "ip4"))
485     tid = FLOW_CLASSIFY_TABLE_IP4;
486   else if (unformat (input, "ip6"))
487     tid = FLOW_CLASSIFY_TABLE_IP6;
488   else
489     return 0;
490
491   *r = tid;
492   return 1;
493 }
494
495 u8 *
496 format_ip4_address (u8 * s, va_list * args)
497 {
498   u8 *a = va_arg (*args, u8 *);
499   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
500 }
501
502 u8 *
503 format_ip6_address (u8 * s, va_list * args)
504 {
505   ip6_address_t *a = va_arg (*args, ip6_address_t *);
506   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
507
508   i_max_n_zero = ARRAY_LEN (a->as_u16);
509   max_n_zeros = 0;
510   i_first_zero = i_max_n_zero;
511   n_zeros = 0;
512   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
513     {
514       u32 is_zero = a->as_u16[i] == 0;
515       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
516         {
517           i_first_zero = i;
518           n_zeros = 0;
519         }
520       n_zeros += is_zero;
521       if ((!is_zero && n_zeros > max_n_zeros)
522           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
523         {
524           i_max_n_zero = i_first_zero;
525           max_n_zeros = n_zeros;
526           i_first_zero = ARRAY_LEN (a->as_u16);
527           n_zeros = 0;
528         }
529     }
530
531   last_double_colon = 0;
532   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
533     {
534       if (i == i_max_n_zero && max_n_zeros > 1)
535         {
536           s = format (s, "::");
537           i += max_n_zeros - 1;
538           last_double_colon = 1;
539         }
540       else
541         {
542           s = format (s, "%s%x",
543                       (last_double_colon || i == 0) ? "" : ":",
544                       clib_net_to_host_u16 (a->as_u16[i]));
545           last_double_colon = 0;
546         }
547     }
548
549   return s;
550 }
551
552 /* Format an IP46 address. */
553 u8 *
554 format_ip46_address (u8 * s, va_list * args)
555 {
556   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
557   ip46_type_t type = va_arg (*args, ip46_type_t);
558   int is_ip4 = 1;
559
560   switch (type)
561     {
562     case IP46_TYPE_ANY:
563       is_ip4 = ip46_address_is_ip4 (ip46);
564       break;
565     case IP46_TYPE_IP4:
566       is_ip4 = 1;
567       break;
568     case IP46_TYPE_IP6:
569       is_ip4 = 0;
570       break;
571     }
572
573   return is_ip4 ?
574     format (s, "%U", format_ip4_address, &ip46->ip4) :
575     format (s, "%U", format_ip6_address, &ip46->ip6);
576 }
577
578 u8 *
579 format_ethernet_address (u8 * s, va_list * args)
580 {
581   u8 *a = va_arg (*args, u8 *);
582
583   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
584                  a[0], a[1], a[2], a[3], a[4], a[5]);
585 }
586
587 void
588 increment_v4_address (ip4_address_t * a)
589 {
590   u32 v;
591
592   v = ntohl (a->as_u32) + 1;
593   a->as_u32 = ntohl (v);
594 }
595
596 void
597 increment_v6_address (ip6_address_t * a)
598 {
599   u64 v0, v1;
600
601   v0 = clib_net_to_host_u64 (a->as_u64[0]);
602   v1 = clib_net_to_host_u64 (a->as_u64[1]);
603
604   v1 += 1;
605   if (v1 == 0)
606     v0 += 1;
607   a->as_u64[0] = clib_net_to_host_u64 (v0);
608   a->as_u64[1] = clib_net_to_host_u64 (v1);
609 }
610
611 void
612 increment_mac_address (u64 * mac)
613 {
614   u64 tmp = *mac;
615
616   tmp = clib_net_to_host_u64 (tmp);
617   tmp += 1 << 16;               /* skip unused (least significant) octets */
618   tmp = clib_host_to_net_u64 (tmp);
619   *mac = tmp;
620 }
621
622 static void vl_api_create_loopback_reply_t_handler
623   (vl_api_create_loopback_reply_t * mp)
624 {
625   vat_main_t *vam = &vat_main;
626   i32 retval = ntohl (mp->retval);
627
628   vam->retval = retval;
629   vam->regenerate_interface_table = 1;
630   vam->sw_if_index = ntohl (mp->sw_if_index);
631   vam->result_ready = 1;
632 }
633
634 static void vl_api_create_loopback_reply_t_handler_json
635   (vl_api_create_loopback_reply_t * mp)
636 {
637   vat_main_t *vam = &vat_main;
638   vat_json_node_t node;
639
640   vat_json_init_object (&node);
641   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
642   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
643
644   vat_json_print (vam->ofp, &node);
645   vat_json_free (&node);
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_af_packet_create_reply_t_handler
651   (vl_api_af_packet_create_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_af_packet_create_reply_t_handler_json
663   (vl_api_af_packet_create_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_vlan_subif_reply_t_handler
680   (vl_api_create_vlan_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_vlan_subif_reply_t_handler_json
692   (vl_api_create_vlan_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_create_subif_reply_t_handler
709   (vl_api_create_subif_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->sw_if_index = ntohl (mp->sw_if_index);
717   vam->result_ready = 1;
718 }
719
720 static void vl_api_create_subif_reply_t_handler_json
721   (vl_api_create_subif_reply_t * mp)
722 {
723   vat_main_t *vam = &vat_main;
724   vat_json_node_t node;
725
726   vat_json_init_object (&node);
727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
729
730   vat_json_print (vam->ofp, &node);
731   vat_json_free (&node);
732
733   vam->retval = ntohl (mp->retval);
734   vam->result_ready = 1;
735 }
736
737 static void vl_api_interface_name_renumber_reply_t_handler
738   (vl_api_interface_name_renumber_reply_t * mp)
739 {
740   vat_main_t *vam = &vat_main;
741   i32 retval = ntohl (mp->retval);
742
743   vam->retval = retval;
744   vam->regenerate_interface_table = 1;
745   vam->result_ready = 1;
746 }
747
748 static void vl_api_interface_name_renumber_reply_t_handler_json
749   (vl_api_interface_name_renumber_reply_t * mp)
750 {
751   vat_main_t *vam = &vat_main;
752   vat_json_node_t node;
753
754   vat_json_init_object (&node);
755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
756
757   vat_json_print (vam->ofp, &node);
758   vat_json_free (&node);
759
760   vam->retval = ntohl (mp->retval);
761   vam->result_ready = 1;
762 }
763
764 /*
765  * Special-case: build the interface table, maintain
766  * the next loopback sw_if_index vbl.
767  */
768 static void vl_api_sw_interface_details_t_handler
769   (vl_api_sw_interface_details_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   u8 *s = format (0, "%s%c", mp->interface_name, 0);
773
774   hash_set_mem (vam->sw_if_index_by_interface_name, s,
775                 ntohl (mp->sw_if_index));
776
777   /* In sub interface case, fill the sub interface table entry */
778   if (mp->sw_if_index != mp->sup_sw_if_index)
779     {
780       sw_interface_subif_t *sub = NULL;
781
782       vec_add2 (vam->sw_if_subif_table, sub, 1);
783
784       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
785       strncpy ((char *) sub->interface_name, (char *) s,
786                vec_len (sub->interface_name));
787       sub->sw_if_index = ntohl (mp->sw_if_index);
788       sub->sub_id = ntohl (mp->sub_id);
789
790       sub->sub_dot1ad = mp->sub_dot1ad;
791       sub->sub_number_of_tags = mp->sub_number_of_tags;
792       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
793       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
794       sub->sub_exact_match = mp->sub_exact_match;
795       sub->sub_default = mp->sub_default;
796       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
797       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
798
799       /* vlan tag rewrite */
800       sub->vtr_op = ntohl (mp->vtr_op);
801       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
802       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
803       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
804     }
805 }
806
807 static void vl_api_sw_interface_details_t_handler_json
808   (vl_api_sw_interface_details_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t *node = NULL;
812
813   if (VAT_JSON_ARRAY != vam->json_tree.type)
814     {
815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
816       vat_json_init_array (&vam->json_tree);
817     }
818   node = vat_json_array_add (&vam->json_tree);
819
820   vat_json_init_object (node);
821   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
822   vat_json_object_add_uint (node, "sup_sw_if_index",
823                             ntohl (mp->sup_sw_if_index));
824   vat_json_object_add_uint (node, "l2_address_length",
825                             ntohl (mp->l2_address_length));
826   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
827                              sizeof (mp->l2_address));
828   vat_json_object_add_string_copy (node, "interface_name",
829                                    mp->interface_name);
830   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
831   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
832   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
833   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
834   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
835   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
836   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
837   vat_json_object_add_uint (node, "sub_number_of_tags",
838                             mp->sub_number_of_tags);
839   vat_json_object_add_uint (node, "sub_outer_vlan_id",
840                             ntohs (mp->sub_outer_vlan_id));
841   vat_json_object_add_uint (node, "sub_inner_vlan_id",
842                             ntohs (mp->sub_inner_vlan_id));
843   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
844   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
845   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
846                             mp->sub_outer_vlan_id_any);
847   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
848                             mp->sub_inner_vlan_id_any);
849   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
850   vat_json_object_add_uint (node, "vtr_push_dot1q",
851                             ntohl (mp->vtr_push_dot1q));
852   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
853   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
854 }
855
856 static void vl_api_sw_interface_set_flags_t_handler
857   (vl_api_sw_interface_set_flags_t * mp)
858 {
859   vat_main_t *vam = &vat_main;
860   if (vam->interface_event_display)
861     errmsg ("interface flags: sw_if_index %d %s %s\n",
862             ntohl (mp->sw_if_index),
863             mp->admin_up_down ? "admin-up" : "admin-down",
864             mp->link_up_down ? "link-up" : "link-down");
865 }
866
867 static void vl_api_sw_interface_set_flags_t_handler_json
868   (vl_api_sw_interface_set_flags_t * mp)
869 {
870   /* JSON output not supported */
871 }
872
873 static void
874 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   i32 retval = ntohl (mp->retval);
878
879   vam->retval = retval;
880   vam->shmem_result = (u8 *) mp->reply_in_shmem;
881   vam->result_ready = 1;
882 }
883
884 static void
885 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   vat_json_node_t node;
889   api_main_t *am = &api_main;
890   void *oldheap;
891   u8 *reply;
892
893   vat_json_init_object (&node);
894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
895   vat_json_object_add_uint (&node, "reply_in_shmem",
896                             ntohl (mp->reply_in_shmem));
897   /* Toss the shared-memory original... */
898   pthread_mutex_lock (&am->vlib_rp->mutex);
899   oldheap = svm_push_data_heap (am->vlib_rp);
900
901   reply = (u8 *) (mp->reply_in_shmem);
902   vec_free (reply);
903
904   svm_pop_heap (oldheap);
905   pthread_mutex_unlock (&am->vlib_rp->mutex);
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 static void
915 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   i32 retval = ntohl (mp->retval);
919
920   vam->retval = retval;
921   vam->cmd_reply = mp->reply;
922   vam->result_ready = 1;
923 }
924
925 static void
926 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_string_copy (&node, "reply", mp->reply);
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_classify_add_del_table_reply_t_handler
943   (vl_api_classify_add_del_table_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947   if (vam->async_mode)
948     {
949       vam->async_errors += (retval < 0);
950     }
951   else
952     {
953       vam->retval = retval;
954       if (retval == 0 &&
955           ((mp->new_table_index != 0xFFFFFFFF) ||
956            (mp->skip_n_vectors != 0xFFFFFFFF) ||
957            (mp->match_n_vectors != 0xFFFFFFFF)))
958         /*
959          * Note: this is just barely thread-safe, depends on
960          * the main thread spinning waiting for an answer...
961          */
962         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
963                 ntohl (mp->new_table_index),
964                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
965       vam->result_ready = 1;
966     }
967 }
968
969 static void vl_api_classify_add_del_table_reply_t_handler_json
970   (vl_api_classify_add_del_table_reply_t * mp)
971 {
972   vat_main_t *vam = &vat_main;
973   vat_json_node_t node;
974
975   vat_json_init_object (&node);
976   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
977   vat_json_object_add_uint (&node, "new_table_index",
978                             ntohl (mp->new_table_index));
979   vat_json_object_add_uint (&node, "skip_n_vectors",
980                             ntohl (mp->skip_n_vectors));
981   vat_json_object_add_uint (&node, "match_n_vectors",
982                             ntohl (mp->match_n_vectors));
983
984   vat_json_print (vam->ofp, &node);
985   vat_json_free (&node);
986
987   vam->retval = ntohl (mp->retval);
988   vam->result_ready = 1;
989 }
990
991 static void vl_api_get_node_index_reply_t_handler
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   i32 retval = ntohl (mp->retval);
996   if (vam->async_mode)
997     {
998       vam->async_errors += (retval < 0);
999     }
1000   else
1001     {
1002       vam->retval = retval;
1003       if (retval == 0)
1004         errmsg ("node index %d\n", ntohl (mp->node_index));
1005       vam->result_ready = 1;
1006     }
1007 }
1008
1009 static void vl_api_get_node_index_reply_t_handler_json
1010   (vl_api_get_node_index_reply_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t node;
1014
1015   vat_json_init_object (&node);
1016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1017   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1018
1019   vat_json_print (vam->ofp, &node);
1020   vat_json_free (&node);
1021
1022   vam->retval = ntohl (mp->retval);
1023   vam->result_ready = 1;
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031   if (vam->async_mode)
1032     {
1033       vam->async_errors += (retval < 0);
1034     }
1035   else
1036     {
1037       vam->retval = retval;
1038       if (retval == 0)
1039         errmsg ("next node index %d\n", ntohl (mp->next_index));
1040       vam->result_ready = 1;
1041     }
1042 }
1043
1044 static void vl_api_get_next_index_reply_t_handler_json
1045   (vl_api_get_next_index_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049
1050   vat_json_init_object (&node);
1051   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1052   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1053
1054   vat_json_print (vam->ofp, &node);
1055   vat_json_free (&node);
1056
1057   vam->retval = ntohl (mp->retval);
1058   vam->result_ready = 1;
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   i32 retval = ntohl (mp->retval);
1066   if (vam->async_mode)
1067     {
1068       vam->async_errors += (retval < 0);
1069     }
1070   else
1071     {
1072       vam->retval = retval;
1073       if (retval == 0)
1074         errmsg ("next index %d\n", ntohl (mp->next_index));
1075       vam->result_ready = 1;
1076     }
1077 }
1078
1079 static void vl_api_add_node_next_reply_t_handler_json
1080   (vl_api_add_node_next_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   vat_json_node_t node;
1084
1085   vat_json_init_object (&node);
1086   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1087   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1088
1089   vat_json_print (vam->ofp, &node);
1090   vat_json_free (&node);
1091
1092   vam->retval = ntohl (mp->retval);
1093   vam->result_ready = 1;
1094 }
1095
1096 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1097   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   i32 retval = ntohl (mp->retval);
1101   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1102
1103   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1104     {
1105       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1106     }
1107   vam->retval = retval;
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1112   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   vat_json_node_t node;
1116
1117   vat_json_init_object (&node);
1118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1119   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1120                             ntohl (mp->tunnel_sw_if_index));
1121
1122   vat_json_print (vam->ofp, &node);
1123   vat_json_free (&node);
1124
1125   vam->retval = ntohl (mp->retval);
1126   vam->result_ready = 1;
1127 }
1128
1129
1130 static void vl_api_show_version_reply_t_handler
1131   (vl_api_show_version_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   i32 retval = ntohl (mp->retval);
1135
1136   if (retval >= 0)
1137     {
1138       errmsg ("        program: %s\n", mp->program);
1139       errmsg ("        version: %s\n", mp->version);
1140       errmsg ("     build date: %s\n", mp->build_date);
1141       errmsg ("build directory: %s\n", mp->build_directory);
1142     }
1143   vam->retval = retval;
1144   vam->result_ready = 1;
1145 }
1146
1147 static void vl_api_show_version_reply_t_handler_json
1148   (vl_api_show_version_reply_t * mp)
1149 {
1150   vat_main_t *vam = &vat_main;
1151   vat_json_node_t node;
1152
1153   vat_json_init_object (&node);
1154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1155   vat_json_object_add_string_copy (&node, "program", mp->program);
1156   vat_json_object_add_string_copy (&node, "version", mp->version);
1157   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1158   vat_json_object_add_string_copy (&node, "build_directory",
1159                                    mp->build_directory);
1160
1161   vat_json_print (vam->ofp, &node);
1162   vat_json_free (&node);
1163
1164   vam->retval = ntohl (mp->retval);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void
1169 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1173           mp->mac_ip ? "mac/ip binding" : "address resolution",
1174           format_ip4_address, &mp->address,
1175           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1176 }
1177
1178 static void
1179 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1180 {
1181   /* JSON output not supported */
1182 }
1183
1184 static void
1185 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1189           mp->mac_ip ? "mac/ip binding" : "address resolution",
1190           format_ip6_address, mp->address,
1191           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1192 }
1193
1194 static void
1195 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1196 {
1197   /* JSON output not supported */
1198 }
1199
1200 /*
1201  * Special-case: build the bridge domain table, maintain
1202  * the next bd id vbl.
1203  */
1204 static void vl_api_bridge_domain_details_t_handler
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1209
1210   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1211            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1212
1213   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1214            ntohl (mp->bd_id), mp->learn, mp->forward,
1215            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1216
1217   if (n_sw_ifs)
1218     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1219              "Interface Name");
1220 }
1221
1222 static void vl_api_bridge_domain_details_t_handler_json
1223   (vl_api_bridge_domain_details_t * mp)
1224 {
1225   vat_main_t *vam = &vat_main;
1226   vat_json_node_t *node, *array = NULL;
1227
1228   if (VAT_JSON_ARRAY != vam->json_tree.type)
1229     {
1230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1231       vat_json_init_array (&vam->json_tree);
1232     }
1233   node = vat_json_array_add (&vam->json_tree);
1234
1235   vat_json_init_object (node);
1236   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1237   vat_json_object_add_uint (node, "flood", mp->flood);
1238   vat_json_object_add_uint (node, "forward", mp->forward);
1239   vat_json_object_add_uint (node, "learn", mp->learn);
1240   vat_json_object_add_uint (node, "bvi_sw_if_index",
1241                             ntohl (mp->bvi_sw_if_index));
1242   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1243   array = vat_json_object_add (node, "sw_if");
1244   vat_json_init_array (array);
1245 }
1246
1247 /*
1248  * Special-case: build the bridge domain sw if table.
1249  */
1250 static void vl_api_bridge_domain_sw_if_details_t_handler
1251   (vl_api_bridge_domain_sw_if_details_t * mp)
1252 {
1253   vat_main_t *vam = &vat_main;
1254   hash_pair_t *p;
1255   u8 *sw_if_name = 0;
1256   u32 sw_if_index;
1257
1258   sw_if_index = ntohl (mp->sw_if_index);
1259   /* *INDENT-OFF* */
1260   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1261   ({
1262     if ((u32) p->value[0] == sw_if_index)
1263       {
1264         sw_if_name = (u8 *)(p->key);
1265         break;
1266       }
1267   }));
1268   /* *INDENT-ON* */
1269
1270   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1271            mp->shg, sw_if_name ? (char *) sw_if_name :
1272            "sw_if_index not found!");
1273 }
1274
1275 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1276   (vl_api_bridge_domain_sw_if_details_t * mp)
1277 {
1278   vat_main_t *vam = &vat_main;
1279   vat_json_node_t *node = NULL;
1280   uword last_index = 0;
1281
1282   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1283   ASSERT (vec_len (vam->json_tree.array) >= 1);
1284   last_index = vec_len (vam->json_tree.array) - 1;
1285   node = &vam->json_tree.array[last_index];
1286   node = vat_json_object_get_element (node, "sw_if");
1287   ASSERT (NULL != node);
1288   node = vat_json_array_add (node);
1289
1290   vat_json_init_object (node);
1291   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1292   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1293   vat_json_object_add_uint (node, "shg", mp->shg);
1294 }
1295
1296 static void vl_api_control_ping_reply_t_handler
1297   (vl_api_control_ping_reply_t * mp)
1298 {
1299   vat_main_t *vam = &vat_main;
1300   i32 retval = ntohl (mp->retval);
1301   if (vam->async_mode)
1302     {
1303       vam->async_errors += (retval < 0);
1304     }
1305   else
1306     {
1307       vam->retval = retval;
1308       vam->result_ready = 1;
1309     }
1310 }
1311
1312 static void vl_api_control_ping_reply_t_handler_json
1313   (vl_api_control_ping_reply_t * mp)
1314 {
1315   vat_main_t *vam = &vat_main;
1316   i32 retval = ntohl (mp->retval);
1317
1318   if (VAT_JSON_NONE != vam->json_tree.type)
1319     {
1320       vat_json_print (vam->ofp, &vam->json_tree);
1321       vat_json_free (&vam->json_tree);
1322       vam->json_tree.type = VAT_JSON_NONE;
1323     }
1324   else
1325     {
1326       /* just print [] */
1327       vat_json_init_array (&vam->json_tree);
1328       vat_json_print (vam->ofp, &vam->json_tree);
1329       vam->json_tree.type = VAT_JSON_NONE;
1330     }
1331
1332   vam->retval = retval;
1333   vam->result_ready = 1;
1334 }
1335
1336 static void
1337 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   i32 retval = ntohl (mp->retval);
1341   if (vam->async_mode)
1342     {
1343       vam->async_errors += (retval < 0);
1344     }
1345   else
1346     {
1347       vam->retval = retval;
1348       vam->result_ready = 1;
1349     }
1350 }
1351
1352 static void vl_api_l2_flags_reply_t_handler_json
1353   (vl_api_l2_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   vat_json_node_t node;
1357
1358   vat_json_init_object (&node);
1359   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1360   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1361                             ntohl (mp->resulting_feature_bitmap));
1362
1363   vat_json_print (vam->ofp, &node);
1364   vat_json_free (&node);
1365
1366   vam->retval = ntohl (mp->retval);
1367   vam->result_ready = 1;
1368 }
1369
1370 static void vl_api_bridge_flags_reply_t_handler
1371   (vl_api_bridge_flags_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   i32 retval = ntohl (mp->retval);
1375   if (vam->async_mode)
1376     {
1377       vam->async_errors += (retval < 0);
1378     }
1379   else
1380     {
1381       vam->retval = retval;
1382       vam->result_ready = 1;
1383     }
1384 }
1385
1386 static void vl_api_bridge_flags_reply_t_handler_json
1387   (vl_api_bridge_flags_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   vat_json_node_t node;
1391
1392   vat_json_init_object (&node);
1393   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1394   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1395                             ntohl (mp->resulting_feature_bitmap));
1396
1397   vat_json_print (vam->ofp, &node);
1398   vat_json_free (&node);
1399
1400   vam->retval = ntohl (mp->retval);
1401   vam->result_ready = 1;
1402 }
1403
1404 static void vl_api_tap_connect_reply_t_handler
1405   (vl_api_tap_connect_reply_t * mp)
1406 {
1407   vat_main_t *vam = &vat_main;
1408   i32 retval = ntohl (mp->retval);
1409   if (vam->async_mode)
1410     {
1411       vam->async_errors += (retval < 0);
1412     }
1413   else
1414     {
1415       vam->retval = retval;
1416       vam->sw_if_index = ntohl (mp->sw_if_index);
1417       vam->result_ready = 1;
1418     }
1419
1420 }
1421
1422 static void vl_api_tap_connect_reply_t_handler_json
1423   (vl_api_tap_connect_reply_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   vat_json_node_t node;
1427
1428   vat_json_init_object (&node);
1429   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1430   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1431
1432   vat_json_print (vam->ofp, &node);
1433   vat_json_free (&node);
1434
1435   vam->retval = ntohl (mp->retval);
1436   vam->result_ready = 1;
1437
1438 }
1439
1440 static void
1441 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1442 {
1443   vat_main_t *vam = &vat_main;
1444   i32 retval = ntohl (mp->retval);
1445   if (vam->async_mode)
1446     {
1447       vam->async_errors += (retval < 0);
1448     }
1449   else
1450     {
1451       vam->retval = retval;
1452       vam->sw_if_index = ntohl (mp->sw_if_index);
1453       vam->result_ready = 1;
1454     }
1455 }
1456
1457 static void vl_api_tap_modify_reply_t_handler_json
1458   (vl_api_tap_modify_reply_t * mp)
1459 {
1460   vat_main_t *vam = &vat_main;
1461   vat_json_node_t node;
1462
1463   vat_json_init_object (&node);
1464   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1465   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1466
1467   vat_json_print (vam->ofp, &node);
1468   vat_json_free (&node);
1469
1470   vam->retval = ntohl (mp->retval);
1471   vam->result_ready = 1;
1472 }
1473
1474 static void
1475 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1476 {
1477   vat_main_t *vam = &vat_main;
1478   i32 retval = ntohl (mp->retval);
1479   if (vam->async_mode)
1480     {
1481       vam->async_errors += (retval < 0);
1482     }
1483   else
1484     {
1485       vam->retval = retval;
1486       vam->result_ready = 1;
1487     }
1488 }
1489
1490 static void vl_api_tap_delete_reply_t_handler_json
1491   (vl_api_tap_delete_reply_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   vat_json_node_t node;
1495
1496   vat_json_init_object (&node);
1497   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1498
1499   vat_json_print (vam->ofp, &node);
1500   vat_json_free (&node);
1501
1502   vam->retval = ntohl (mp->retval);
1503   vam->result_ready = 1;
1504 }
1505
1506 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1507   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   i32 retval = ntohl (mp->retval);
1511   if (vam->async_mode)
1512     {
1513       vam->async_errors += (retval < 0);
1514     }
1515   else
1516     {
1517       vam->retval = retval;
1518       vam->result_ready = 1;
1519     }
1520 }
1521
1522 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1523   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1524 {
1525   vat_main_t *vam = &vat_main;
1526   vat_json_node_t node;
1527
1528   vat_json_init_object (&node);
1529   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1530   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1531                             ntohl (mp->tunnel_sw_if_index));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1541   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   i32 retval = ntohl (mp->retval);
1545   if (vam->async_mode)
1546     {
1547       vam->async_errors += (retval < 0);
1548     }
1549   else
1550     {
1551       vam->retval = retval;
1552       vam->sw_if_index = ntohl (mp->sw_if_index);
1553       vam->result_ready = 1;
1554     }
1555 }
1556
1557 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1558   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   vat_json_node_t node;
1562
1563   vat_json_init_object (&node);
1564   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1565   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574
1575 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1576   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   i32 retval = ntohl (mp->retval);
1580   if (vam->async_mode)
1581     {
1582       vam->async_errors += (retval < 0);
1583     }
1584   else
1585     {
1586       vam->retval = retval;
1587       vam->result_ready = 1;
1588     }
1589 }
1590
1591 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1592   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   vat_json_node_t node;
1596
1597   vat_json_init_object (&node);
1598   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1599   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1609   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623 }
1624
1625 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1626   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   vat_json_node_t node;
1630
1631   vat_json_init_object (&node);
1632   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1633   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1634
1635   vat_json_print (vam->ofp, &node);
1636   vat_json_free (&node);
1637
1638   vam->retval = ntohl (mp->retval);
1639   vam->result_ready = 1;
1640 }
1641
1642 static void vl_api_gre_add_del_tunnel_reply_t_handler
1643   (vl_api_gre_add_del_tunnel_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   i32 retval = ntohl (mp->retval);
1647   if (vam->async_mode)
1648     {
1649       vam->async_errors += (retval < 0);
1650     }
1651   else
1652     {
1653       vam->retval = retval;
1654       vam->sw_if_index = ntohl (mp->sw_if_index);
1655       vam->result_ready = 1;
1656     }
1657 }
1658
1659 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1660   (vl_api_gre_add_del_tunnel_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   vat_json_node_t node;
1664
1665   vat_json_init_object (&node);
1666   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1667   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1668
1669   vat_json_print (vam->ofp, &node);
1670   vat_json_free (&node);
1671
1672   vam->retval = ntohl (mp->retval);
1673   vam->result_ready = 1;
1674 }
1675
1676 static void vl_api_create_vhost_user_if_reply_t_handler
1677   (vl_api_create_vhost_user_if_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   i32 retval = ntohl (mp->retval);
1681   if (vam->async_mode)
1682     {
1683       vam->async_errors += (retval < 0);
1684     }
1685   else
1686     {
1687       vam->retval = retval;
1688       vam->sw_if_index = ntohl (mp->sw_if_index);
1689       vam->result_ready = 1;
1690     }
1691 }
1692
1693 static void vl_api_create_vhost_user_if_reply_t_handler_json
1694   (vl_api_create_vhost_user_if_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   vat_json_node_t node;
1698
1699   vat_json_init_object (&node);
1700   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1701   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1702
1703   vat_json_print (vam->ofp, &node);
1704   vat_json_free (&node);
1705
1706   vam->retval = ntohl (mp->retval);
1707   vam->result_ready = 1;
1708 }
1709
1710 static void vl_api_ip_address_details_t_handler
1711   (vl_api_ip_address_details_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   static ip_address_details_t empty_ip_address_details = { {0} };
1715   ip_address_details_t *address = NULL;
1716   ip_details_t *current_ip_details = NULL;
1717   ip_details_t *details = NULL;
1718
1719   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1720
1721   if (!details || vam->current_sw_if_index >= vec_len (details)
1722       || !details[vam->current_sw_if_index].present)
1723     {
1724       errmsg ("ip address details arrived but not stored\n");
1725       errmsg ("ip_dump should be called first\n");
1726       return;
1727     }
1728
1729   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1730
1731 #define addresses (current_ip_details->addr)
1732
1733   vec_validate_init_empty (addresses, vec_len (addresses),
1734                            empty_ip_address_details);
1735
1736   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1737
1738   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1739   address->prefix_length = mp->prefix_length;
1740 #undef addresses
1741 }
1742
1743 static void vl_api_ip_address_details_t_handler_json
1744   (vl_api_ip_address_details_t * mp)
1745 {
1746   vat_main_t *vam = &vat_main;
1747   vat_json_node_t *node = NULL;
1748   struct in6_addr ip6;
1749   struct in_addr ip4;
1750
1751   if (VAT_JSON_ARRAY != vam->json_tree.type)
1752     {
1753       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1754       vat_json_init_array (&vam->json_tree);
1755     }
1756   node = vat_json_array_add (&vam->json_tree);
1757
1758   vat_json_init_object (node);
1759   if (vam->is_ipv6)
1760     {
1761       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1762       vat_json_object_add_ip6 (node, "ip", ip6);
1763     }
1764   else
1765     {
1766       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1767       vat_json_object_add_ip4 (node, "ip", ip4);
1768     }
1769   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1770 }
1771
1772 static void
1773 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1774 {
1775   vat_main_t *vam = &vat_main;
1776   static ip_details_t empty_ip_details = { 0 };
1777   ip_details_t *ip = NULL;
1778   u32 sw_if_index = ~0;
1779
1780   sw_if_index = ntohl (mp->sw_if_index);
1781
1782   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1783                            sw_if_index, empty_ip_details);
1784
1785   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1786                          sw_if_index);
1787
1788   ip->present = 1;
1789 }
1790
1791 static void
1792 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795
1796   if (VAT_JSON_ARRAY != vam->json_tree.type)
1797     {
1798       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1799       vat_json_init_array (&vam->json_tree);
1800     }
1801   vat_json_array_add_uint (&vam->json_tree,
1802                            clib_net_to_host_u32 (mp->sw_if_index));
1803 }
1804
1805 static void vl_api_map_domain_details_t_handler_json
1806   (vl_api_map_domain_details_t * mp)
1807 {
1808   vat_json_node_t *node = NULL;
1809   vat_main_t *vam = &vat_main;
1810   struct in6_addr ip6;
1811   struct in_addr ip4;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "domain_index",
1823                             clib_net_to_host_u32 (mp->domain_index));
1824   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1825   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1826   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1827   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1828   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1829   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1830   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1831   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1832   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1833   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1834   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1835   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1836   vat_json_object_add_uint (node, "flags", mp->flags);
1837   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1838   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1839 }
1840
1841 static void vl_api_map_domain_details_t_handler
1842   (vl_api_map_domain_details_t * mp)
1843 {
1844   vat_main_t *vam = &vat_main;
1845
1846   if (mp->is_translation)
1847     {
1848       fformat (vam->ofp,
1849                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1850                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1851                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1852                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1853                clib_net_to_host_u32 (mp->domain_index));
1854     }
1855   else
1856     {
1857       fformat (vam->ofp,
1858                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1859                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1860                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1861                format_ip6_address, mp->ip6_src,
1862                clib_net_to_host_u32 (mp->domain_index));
1863     }
1864   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1865            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1866            mp->is_translation ? "map-t" : "");
1867 }
1868
1869 static void vl_api_map_rule_details_t_handler_json
1870   (vl_api_map_rule_details_t * mp)
1871 {
1872   struct in6_addr ip6;
1873   vat_json_node_t *node = NULL;
1874   vat_main_t *vam = &vat_main;
1875
1876   if (VAT_JSON_ARRAY != vam->json_tree.type)
1877     {
1878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1879       vat_json_init_array (&vam->json_tree);
1880     }
1881
1882   node = vat_json_array_add (&vam->json_tree);
1883   vat_json_init_object (node);
1884
1885   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1886   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1887   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1888 }
1889
1890 static void
1891 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1895            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1896 }
1897
1898 static void
1899 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1903           "router_addr %U host_mac %U\n",
1904           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1905           format_ip4_address, &mp->host_address,
1906           format_ip4_address, &mp->router_address,
1907           format_ethernet_address, mp->host_mac);
1908 }
1909
1910 static void vl_api_dhcp_compl_event_t_handler_json
1911   (vl_api_dhcp_compl_event_t * mp)
1912 {
1913   /* JSON output not supported */
1914 }
1915
1916 static void
1917 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1918                               u32 counter)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   static u64 default_counter = 0;
1922
1923   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1924                            NULL);
1925   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1926                            sw_if_index, default_counter);
1927   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1928 }
1929
1930 static void
1931 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1932                                 interface_counter_t counter)
1933 {
1934   vat_main_t *vam = &vat_main;
1935   static interface_counter_t default_counter = { 0, };
1936
1937   vec_validate_init_empty (vam->combined_interface_counters,
1938                            vnet_counter_type, NULL);
1939   vec_validate_init_empty (vam->combined_interface_counters
1940                            [vnet_counter_type], sw_if_index, default_counter);
1941   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1942 }
1943
1944 static void vl_api_vnet_interface_counters_t_handler
1945   (vl_api_vnet_interface_counters_t * mp)
1946 {
1947   /* not supported */
1948 }
1949
1950 static void vl_api_vnet_interface_counters_t_handler_json
1951   (vl_api_vnet_interface_counters_t * mp)
1952 {
1953   interface_counter_t counter;
1954   vlib_counter_t *v;
1955   u64 *v_packets;
1956   u64 packets;
1957   u32 count;
1958   u32 first_sw_if_index;
1959   int i;
1960
1961   count = ntohl (mp->count);
1962   first_sw_if_index = ntohl (mp->first_sw_if_index);
1963
1964   if (!mp->is_combined)
1965     {
1966       v_packets = (u64 *) & mp->data;
1967       for (i = 0; i < count; i++)
1968         {
1969           packets =
1970             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1971           set_simple_interface_counter (mp->vnet_counter_type,
1972                                         first_sw_if_index + i, packets);
1973           v_packets++;
1974         }
1975     }
1976   else
1977     {
1978       v = (vlib_counter_t *) & mp->data;
1979       for (i = 0; i < count; i++)
1980         {
1981           counter.packets =
1982             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1983           counter.bytes =
1984             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1985           set_combined_interface_counter (mp->vnet_counter_type,
1986                                           first_sw_if_index + i, counter);
1987           v++;
1988         }
1989     }
1990 }
1991
1992 static u32
1993 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   u32 i;
1997
1998   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1999     {
2000       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2001         {
2002           return i;
2003         }
2004     }
2005   return ~0;
2006 }
2007
2008 static u32
2009 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2010 {
2011   vat_main_t *vam = &vat_main;
2012   u32 i;
2013
2014   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2015     {
2016       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2017         {
2018           return i;
2019         }
2020     }
2021   return ~0;
2022 }
2023
2024 static void vl_api_vnet_ip4_fib_counters_t_handler
2025   (vl_api_vnet_ip4_fib_counters_t * mp)
2026 {
2027   /* not supported */
2028 }
2029
2030 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2031   (vl_api_vnet_ip4_fib_counters_t * mp)
2032 {
2033   vat_main_t *vam = &vat_main;
2034   vl_api_ip4_fib_counter_t *v;
2035   ip4_fib_counter_t *counter;
2036   struct in_addr ip4;
2037   u32 vrf_id;
2038   u32 vrf_index;
2039   u32 count;
2040   int i;
2041
2042   vrf_id = ntohl (mp->vrf_id);
2043   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2044   if (~0 == vrf_index)
2045     {
2046       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2047       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2048       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2049       vec_validate (vam->ip4_fib_counters, vrf_index);
2050       vam->ip4_fib_counters[vrf_index] = NULL;
2051     }
2052
2053   vec_free (vam->ip4_fib_counters[vrf_index]);
2054   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2055   count = ntohl (mp->count);
2056   for (i = 0; i < count; i++)
2057     {
2058       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2059       counter = &vam->ip4_fib_counters[vrf_index][i];
2060       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2061       counter->address = ip4;
2062       counter->address_length = v->address_length;
2063       counter->packets = clib_net_to_host_u64 (v->packets);
2064       counter->bytes = clib_net_to_host_u64 (v->bytes);
2065       v++;
2066     }
2067 }
2068
2069 static void vl_api_vnet_ip6_fib_counters_t_handler
2070   (vl_api_vnet_ip6_fib_counters_t * mp)
2071 {
2072   /* not supported */
2073 }
2074
2075 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2076   (vl_api_vnet_ip6_fib_counters_t * mp)
2077 {
2078   vat_main_t *vam = &vat_main;
2079   vl_api_ip6_fib_counter_t *v;
2080   ip6_fib_counter_t *counter;
2081   struct in6_addr ip6;
2082   u32 vrf_id;
2083   u32 vrf_index;
2084   u32 count;
2085   int i;
2086
2087   vrf_id = ntohl (mp->vrf_id);
2088   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2089   if (~0 == vrf_index)
2090     {
2091       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2092       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2093       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2094       vec_validate (vam->ip6_fib_counters, vrf_index);
2095       vam->ip6_fib_counters[vrf_index] = NULL;
2096     }
2097
2098   vec_free (vam->ip6_fib_counters[vrf_index]);
2099   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2100   count = ntohl (mp->count);
2101   for (i = 0; i < count; i++)
2102     {
2103       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2104       counter = &vam->ip6_fib_counters[vrf_index][i];
2105       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2106       counter->address = ip6;
2107       counter->address_length = v->address_length;
2108       counter->packets = clib_net_to_host_u64 (v->packets);
2109       counter->bytes = clib_net_to_host_u64 (v->bytes);
2110       v++;
2111     }
2112 }
2113
2114 static void vl_api_get_first_msg_id_reply_t_handler
2115   (vl_api_get_first_msg_id_reply_t * mp)
2116 {
2117   vat_main_t *vam = &vat_main;
2118   i32 retval = ntohl (mp->retval);
2119
2120   if (vam->async_mode)
2121     {
2122       vam->async_errors += (retval < 0);
2123     }
2124   else
2125     {
2126       vam->retval = retval;
2127       vam->result_ready = 1;
2128     }
2129   if (retval >= 0)
2130     {
2131       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2132     }
2133 }
2134
2135 static void vl_api_get_first_msg_id_reply_t_handler_json
2136   (vl_api_get_first_msg_id_reply_t * mp)
2137 {
2138   vat_main_t *vam = &vat_main;
2139   vat_json_node_t node;
2140
2141   vat_json_init_object (&node);
2142   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2143   vat_json_object_add_uint (&node, "first_msg_id",
2144                             (uint) ntohs (mp->first_msg_id));
2145
2146   vat_json_print (vam->ofp, &node);
2147   vat_json_free (&node);
2148
2149   vam->retval = ntohl (mp->retval);
2150   vam->result_ready = 1;
2151 }
2152
2153 static void vl_api_get_node_graph_reply_t_handler
2154   (vl_api_get_node_graph_reply_t * mp)
2155 {
2156   vat_main_t *vam = &vat_main;
2157   api_main_t *am = &api_main;
2158   i32 retval = ntohl (mp->retval);
2159   u8 *pvt_copy, *reply;
2160   void *oldheap;
2161   vlib_node_t *node;
2162   int i;
2163
2164   if (vam->async_mode)
2165     {
2166       vam->async_errors += (retval < 0);
2167     }
2168   else
2169     {
2170       vam->retval = retval;
2171       vam->result_ready = 1;
2172     }
2173
2174   /* "Should never happen..." */
2175   if (retval != 0)
2176     return;
2177
2178   reply = (u8 *) (mp->reply_in_shmem);
2179   pvt_copy = vec_dup (reply);
2180
2181   /* Toss the shared-memory original... */
2182   pthread_mutex_lock (&am->vlib_rp->mutex);
2183   oldheap = svm_push_data_heap (am->vlib_rp);
2184
2185   vec_free (reply);
2186
2187   svm_pop_heap (oldheap);
2188   pthread_mutex_unlock (&am->vlib_rp->mutex);
2189
2190   if (vam->graph_nodes)
2191     {
2192       hash_free (vam->graph_node_index_by_name);
2193
2194       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2195         {
2196           node = vam->graph_nodes[i];
2197           vec_free (node->name);
2198           vec_free (node->next_nodes);
2199           vec_free (node);
2200         }
2201       vec_free (vam->graph_nodes);
2202     }
2203
2204   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2205   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2206   vec_free (pvt_copy);
2207
2208   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2209     {
2210       node = vam->graph_nodes[i];
2211       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2212     }
2213 }
2214
2215 static void vl_api_get_node_graph_reply_t_handler_json
2216   (vl_api_get_node_graph_reply_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   api_main_t *am = &api_main;
2220   void *oldheap;
2221   vat_json_node_t node;
2222   u8 *reply;
2223
2224   /* $$$$ make this real? */
2225   vat_json_init_object (&node);
2226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2227   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2228
2229   reply = (u8 *) (mp->reply_in_shmem);
2230
2231   /* Toss the shared-memory original... */
2232   pthread_mutex_lock (&am->vlib_rp->mutex);
2233   oldheap = svm_push_data_heap (am->vlib_rp);
2234
2235   vec_free (reply);
2236
2237   svm_pop_heap (oldheap);
2238   pthread_mutex_unlock (&am->vlib_rp->mutex);
2239
2240   vat_json_print (vam->ofp, &node);
2241   vat_json_free (&node);
2242
2243   vam->retval = ntohl (mp->retval);
2244   vam->result_ready = 1;
2245 }
2246
2247 static void
2248 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *s = 0;
2252
2253   if (mp->local)
2254     {
2255       s = format (s, "%=16d%=16d%=16d\n",
2256                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2257     }
2258   else
2259     {
2260       s = format (s, "%=16U%=16d%=16d\n",
2261                   mp->is_ipv6 ? format_ip6_address :
2262                   format_ip4_address,
2263                   mp->ip_address, mp->priority, mp->weight);
2264     }
2265
2266   fformat (vam->ofp, "%v", s);
2267   vec_free (s);
2268 }
2269
2270 static void
2271 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2272                                             mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   vat_json_node_t *node = NULL;
2276   struct in6_addr ip6;
2277   struct in_addr ip4;
2278
2279   if (VAT_JSON_ARRAY != vam->json_tree.type)
2280     {
2281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2282       vat_json_init_array (&vam->json_tree);
2283     }
2284   node = vat_json_array_add (&vam->json_tree);
2285   vat_json_init_object (node);
2286
2287   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2288   vat_json_object_add_uint (node, "priority", mp->priority);
2289   vat_json_object_add_uint (node, "weight", mp->weight);
2290
2291   if (mp->local)
2292     vat_json_object_add_uint (node, "sw_if_index",
2293                               clib_net_to_host_u32 (mp->sw_if_index));
2294   else
2295     {
2296       if (mp->is_ipv6)
2297         {
2298           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2299           vat_json_object_add_ip6 (node, "address", ip6);
2300         }
2301       else
2302         {
2303           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2304           vat_json_object_add_ip4 (node, "address", ip4);
2305         }
2306     }
2307 }
2308
2309 static void
2310 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2311                                            mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   u8 *ls_name = 0;
2315
2316   ls_name = format (0, "%s", mp->ls_name);
2317
2318   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2319            ls_name);
2320   vec_free (ls_name);
2321 }
2322
2323 static void
2324   vl_api_lisp_locator_set_details_t_handler_json
2325   (vl_api_lisp_locator_set_details_t * mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t *node = 0;
2329   u8 *ls_name = 0;
2330
2331   ls_name = format (0, "%s", mp->ls_name);
2332   vec_add1 (ls_name, 0);
2333
2334   if (VAT_JSON_ARRAY != vam->json_tree.type)
2335     {
2336       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2337       vat_json_init_array (&vam->json_tree);
2338     }
2339   node = vat_json_array_add (&vam->json_tree);
2340
2341   vat_json_init_object (node);
2342   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2343   vat_json_object_add_uint (node, "ls_index",
2344                             clib_net_to_host_u32 (mp->ls_index));
2345   vec_free (ls_name);
2346 }
2347
2348 static u8 *
2349 format_lisp_flat_eid (u8 * s, va_list * args)
2350 {
2351   u32 type = va_arg (*args, u32);
2352   u8 *eid = va_arg (*args, u8 *);
2353   u32 eid_len = va_arg (*args, u32);
2354
2355   switch (type)
2356     {
2357     case 0:
2358       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2359     case 1:
2360       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2361     case 2:
2362       return format (s, "%U", format_ethernet_address, eid);
2363     }
2364   return 0;
2365 }
2366
2367 static u8 *
2368 format_lisp_eid_vat (u8 * s, va_list * args)
2369 {
2370   u32 type = va_arg (*args, u32);
2371   u8 *eid = va_arg (*args, u8 *);
2372   u32 eid_len = va_arg (*args, u32);
2373   u8 *seid = va_arg (*args, u8 *);
2374   u32 seid_len = va_arg (*args, u32);
2375   u32 is_src_dst = va_arg (*args, u32);
2376
2377   if (is_src_dst)
2378     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2379
2380   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2381
2382   return s;
2383 }
2384
2385 static void
2386 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2387 {
2388   vat_main_t *vam = &vat_main;
2389   u8 *s = 0, *eid = 0;
2390
2391   if (~0 == mp->locator_set_index)
2392     s = format (0, "action: %d", mp->action);
2393   else
2394     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2395
2396   eid = format (0, "%U", format_lisp_eid_vat,
2397                 mp->eid_type,
2398                 mp->eid,
2399                 mp->eid_prefix_len,
2400                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2401   vec_add1 (eid, 0);
2402
2403   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2404            clib_net_to_host_u32 (mp->vni),
2405            eid,
2406            mp->is_local ? "local" : "remote",
2407            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2408   vec_free (s);
2409   vec_free (eid);
2410 }
2411
2412 static void
2413 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2414                                               * mp)
2415 {
2416   vat_main_t *vam = &vat_main;
2417   vat_json_node_t *node = 0;
2418   u8 *eid = 0;
2419
2420   if (VAT_JSON_ARRAY != vam->json_tree.type)
2421     {
2422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2423       vat_json_init_array (&vam->json_tree);
2424     }
2425   node = vat_json_array_add (&vam->json_tree);
2426
2427   vat_json_init_object (node);
2428   if (~0 == mp->locator_set_index)
2429     vat_json_object_add_uint (node, "action", mp->action);
2430   else
2431     vat_json_object_add_uint (node, "locator_set_index",
2432                               clib_net_to_host_u32 (mp->locator_set_index));
2433
2434   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2435   eid = format (0, "%U", format_lisp_eid_vat,
2436                 mp->eid_type,
2437                 mp->eid,
2438                 mp->eid_prefix_len,
2439                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2440   vec_add1 (eid, 0);
2441   vat_json_object_add_string_copy (node, "eid", eid);
2442   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2443   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2444   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2445   vec_free (eid);
2446 }
2447
2448 static void
2449   vl_api_lisp_eid_table_map_details_t_handler
2450   (vl_api_lisp_eid_table_map_details_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453
2454   u8 *line = format (0, "%=10d%=10d",
2455                      clib_net_to_host_u32 (mp->vni),
2456                      clib_net_to_host_u32 (mp->dp_table));
2457   fformat (vam->ofp, "%v\n", line);
2458   vec_free (line);
2459 }
2460
2461 static void
2462   vl_api_lisp_eid_table_map_details_t_handler_json
2463   (vl_api_lisp_eid_table_map_details_t * mp)
2464 {
2465   vat_main_t *vam = &vat_main;
2466   vat_json_node_t *node = NULL;
2467
2468   if (VAT_JSON_ARRAY != vam->json_tree.type)
2469     {
2470       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2471       vat_json_init_array (&vam->json_tree);
2472     }
2473   node = vat_json_array_add (&vam->json_tree);
2474   vat_json_init_object (node);
2475   vat_json_object_add_uint (node, "dp_table",
2476                             clib_net_to_host_u32 (mp->dp_table));
2477   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2478 }
2479
2480 static void
2481   vl_api_lisp_eid_table_vni_details_t_handler
2482   (vl_api_lisp_eid_table_vni_details_t * mp)
2483 {
2484   vat_main_t *vam = &vat_main;
2485
2486   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2487   fformat (vam->ofp, "%v\n", line);
2488   vec_free (line);
2489 }
2490
2491 static void
2492   vl_api_lisp_eid_table_vni_details_t_handler_json
2493   (vl_api_lisp_eid_table_vni_details_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   vat_json_node_t *node = NULL;
2497
2498   if (VAT_JSON_ARRAY != vam->json_tree.type)
2499     {
2500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2501       vat_json_init_array (&vam->json_tree);
2502     }
2503   node = vat_json_array_add (&vam->json_tree);
2504   vat_json_init_object (node);
2505   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2506 }
2507
2508 static u8 *
2509 format_decap_next (u8 * s, va_list * args)
2510 {
2511   u32 next_index = va_arg (*args, u32);
2512
2513   switch (next_index)
2514     {
2515     case LISP_GPE_INPUT_NEXT_DROP:
2516       return format (s, "drop");
2517     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2518       return format (s, "ip4");
2519     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2520       return format (s, "ip6");
2521     default:
2522       return format (s, "unknown %d", next_index);
2523     }
2524   return s;
2525 }
2526
2527 static void
2528 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2529                                           mp)
2530 {
2531   vat_main_t *vam = &vat_main;
2532   u8 *iid_str;
2533   u8 *flag_str = NULL;
2534
2535   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2536
2537 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2538   foreach_lisp_gpe_flag_bit;
2539 #undef _
2540
2541   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2542            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2543            mp->tunnels,
2544            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2545            mp->source_ip,
2546            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2547            mp->destination_ip,
2548            ntohl (mp->encap_fib_id),
2549            ntohl (mp->decap_fib_id),
2550            format_decap_next, ntohl (mp->dcap_next),
2551            mp->ver_res >> 6,
2552            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2553
2554   vec_free (iid_str);
2555 }
2556
2557 static void
2558   vl_api_lisp_gpe_tunnel_details_t_handler_json
2559   (vl_api_lisp_gpe_tunnel_details_t * mp)
2560 {
2561   vat_main_t *vam = &vat_main;
2562   vat_json_node_t *node = NULL;
2563   struct in6_addr ip6;
2564   struct in_addr ip4;
2565   u8 *next_decap_str;
2566
2567   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2568
2569   if (VAT_JSON_ARRAY != vam->json_tree.type)
2570     {
2571       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2572       vat_json_init_array (&vam->json_tree);
2573     }
2574   node = vat_json_array_add (&vam->json_tree);
2575
2576   vat_json_init_object (node);
2577   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2578   if (mp->is_ipv6)
2579     {
2580       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2581       vat_json_object_add_ip6 (node, "source address", ip6);
2582       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2583       vat_json_object_add_ip6 (node, "destination address", ip6);
2584     }
2585   else
2586     {
2587       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2588       vat_json_object_add_ip4 (node, "source address", ip4);
2589       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2590       vat_json_object_add_ip4 (node, "destination address", ip4);
2591     }
2592   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2593   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2594   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2595   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2596   vat_json_object_add_uint (node, "flags", mp->flags);
2597   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2598   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2599   vat_json_object_add_uint (node, "res", mp->res);
2600   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2601
2602   vec_free (next_decap_str);
2603 }
2604
2605 static void
2606   vl_api_lisp_adjacencies_get_reply_t_handler
2607   (vl_api_lisp_adjacencies_get_reply_t * mp)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u32 i, n;
2611   int retval = clib_net_to_host_u32 (mp->retval);
2612   vl_api_lisp_adjacency_t *a;
2613
2614   if (retval)
2615     goto end;
2616
2617   n = clib_net_to_host_u32 (mp->count);
2618
2619   for (i = 0; i < n; i++)
2620     {
2621       a = &mp->adjacencies[i];
2622       fformat (vam->ofp, "%U %40U\n",
2623                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2624                format_lisp_flat_eid, a->eid_type, a->reid,
2625                a->reid_prefix_len);
2626     }
2627
2628 end:
2629   vam->retval = retval;
2630   vam->result_ready = 1;
2631 }
2632
2633 static void
2634   vl_api_lisp_adjacencies_get_reply_t_handler_json
2635   (vl_api_lisp_adjacencies_get_reply_t * mp)
2636 {
2637   u8 *s = 0;
2638   vat_main_t *vam = &vat_main;
2639   vat_json_node_t *e = 0, root;
2640   u32 i, n;
2641   int retval = clib_net_to_host_u32 (mp->retval);
2642   vl_api_lisp_adjacency_t *a;
2643
2644   if (retval)
2645     goto end;
2646
2647   n = clib_net_to_host_u32 (mp->count);
2648   vat_json_init_array (&root);
2649
2650   for (i = 0; i < n; i++)
2651     {
2652       e = vat_json_array_add (&root);
2653       a = &mp->adjacencies[i];
2654
2655       vat_json_init_object (e);
2656       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2657                   a->leid_prefix_len);
2658       vec_add1 (s, 0);
2659       vat_json_object_add_string_copy (e, "leid", s);
2660       vec_free (s);
2661
2662       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2663                   a->reid_prefix_len);
2664       vec_add1 (s, 0);
2665       vat_json_object_add_string_copy (e, "reid", s);
2666       vec_free (s);
2667     }
2668
2669   vat_json_print (vam->ofp, &root);
2670   vat_json_free (&root);
2671
2672 end:
2673   vam->retval = retval;
2674   vam->result_ready = 1;
2675 }
2676
2677 static void
2678 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2679                                             * mp)
2680 {
2681   vat_main_t *vam = &vat_main;
2682
2683   fformat (vam->ofp, "%=20U\n",
2684            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2685            mp->ip_address);
2686 }
2687
2688 static void
2689   vl_api_lisp_map_resolver_details_t_handler_json
2690   (vl_api_lisp_map_resolver_details_t * mp)
2691 {
2692   vat_main_t *vam = &vat_main;
2693   vat_json_node_t *node = NULL;
2694   struct in6_addr ip6;
2695   struct in_addr ip4;
2696
2697   if (VAT_JSON_ARRAY != vam->json_tree.type)
2698     {
2699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2700       vat_json_init_array (&vam->json_tree);
2701     }
2702   node = vat_json_array_add (&vam->json_tree);
2703
2704   vat_json_init_object (node);
2705   if (mp->is_ipv6)
2706     {
2707       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2708       vat_json_object_add_ip6 (node, "map resolver", ip6);
2709     }
2710   else
2711     {
2712       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2713       vat_json_object_add_ip4 (node, "map resolver", ip4);
2714     }
2715 }
2716
2717 static void
2718   vl_api_show_lisp_status_reply_t_handler
2719   (vl_api_show_lisp_status_reply_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   i32 retval = ntohl (mp->retval);
2723
2724   if (0 <= retval)
2725     {
2726       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2727                mp->feature_status ? "enabled" : "disabled",
2728                mp->gpe_status ? "enabled" : "disabled");
2729     }
2730
2731   vam->retval = retval;
2732   vam->result_ready = 1;
2733 }
2734
2735 static void
2736   vl_api_show_lisp_status_reply_t_handler_json
2737   (vl_api_show_lisp_status_reply_t * mp)
2738 {
2739   vat_main_t *vam = &vat_main;
2740   vat_json_node_t node;
2741   u8 *gpe_status = NULL;
2742   u8 *feature_status = NULL;
2743
2744   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2745   feature_status = format (0, "%s",
2746                            mp->feature_status ? "enabled" : "disabled");
2747   vec_add1 (gpe_status, 0);
2748   vec_add1 (feature_status, 0);
2749
2750   vat_json_init_object (&node);
2751   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2752   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2753
2754   vec_free (gpe_status);
2755   vec_free (feature_status);
2756
2757   vat_json_print (vam->ofp, &node);
2758   vat_json_free (&node);
2759
2760   vam->retval = ntohl (mp->retval);
2761   vam->result_ready = 1;
2762 }
2763
2764 static void
2765   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2766   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2767 {
2768   vat_main_t *vam = &vat_main;
2769   i32 retval = ntohl (mp->retval);
2770
2771   if (retval >= 0)
2772     {
2773       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2774     }
2775
2776   vam->retval = retval;
2777   vam->result_ready = 1;
2778 }
2779
2780 static void
2781   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2782   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2783 {
2784   vat_main_t *vam = &vat_main;
2785   vat_json_node_t *node = NULL;
2786
2787   if (VAT_JSON_ARRAY != vam->json_tree.type)
2788     {
2789       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2790       vat_json_init_array (&vam->json_tree);
2791     }
2792   node = vat_json_array_add (&vam->json_tree);
2793
2794   vat_json_init_object (node);
2795   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2796
2797   vat_json_print (vam->ofp, node);
2798   vat_json_free (node);
2799
2800   vam->retval = ntohl (mp->retval);
2801   vam->result_ready = 1;
2802 }
2803
2804 static u8 *
2805 format_lisp_map_request_mode (u8 * s, va_list * args)
2806 {
2807   u32 mode = va_arg (*args, u32);
2808
2809   switch (mode)
2810     {
2811     case 0:
2812       return format (0, "dst-only");
2813     case 1:
2814       return format (0, "src-dst");
2815     }
2816   return 0;
2817 }
2818
2819 static void
2820   vl_api_show_lisp_map_request_mode_reply_t_handler
2821   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2822 {
2823   vat_main_t *vam = &vat_main;
2824   i32 retval = ntohl (mp->retval);
2825
2826   if (0 <= retval)
2827     {
2828       u32 mode = mp->mode;
2829       fformat (vam->ofp, "map_request_mode: %U\n",
2830                format_lisp_map_request_mode, mode);
2831     }
2832
2833   vam->retval = retval;
2834   vam->result_ready = 1;
2835 }
2836
2837 static void
2838   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2839   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2840 {
2841   vat_main_t *vam = &vat_main;
2842   vat_json_node_t node;
2843   u8 *s = 0;
2844   u32 mode;
2845
2846   mode = mp->mode;
2847   s = format (0, "%U", format_lisp_map_request_mode, mode);
2848   vec_add1 (s, 0);
2849
2850   vat_json_init_object (&node);
2851   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2852   vat_json_print (vam->ofp, &node);
2853   vat_json_free (&node);
2854
2855   vec_free (s);
2856   vam->retval = ntohl (mp->retval);
2857   vam->result_ready = 1;
2858 }
2859
2860 static void
2861 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2862 {
2863   vat_main_t *vam = &vat_main;
2864   i32 retval = ntohl (mp->retval);
2865
2866   if (0 <= retval)
2867     {
2868       fformat (vam->ofp, "%-20s%-16s\n",
2869                mp->status ? "enabled" : "disabled",
2870                mp->status ? (char *) mp->locator_set_name : "");
2871     }
2872
2873   vam->retval = retval;
2874   vam->result_ready = 1;
2875 }
2876
2877 static void
2878 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2879                                             mp)
2880 {
2881   vat_main_t *vam = &vat_main;
2882   vat_json_node_t node;
2883   u8 *status = 0;
2884
2885   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2886   vec_add1 (status, 0);
2887
2888   vat_json_init_object (&node);
2889   vat_json_object_add_string_copy (&node, "status", status);
2890   if (mp->status)
2891     {
2892       vat_json_object_add_string_copy (&node, "locator_set",
2893                                        mp->locator_set_name);
2894     }
2895
2896   vec_free (status);
2897
2898   vat_json_print (vam->ofp, &node);
2899   vat_json_free (&node);
2900
2901   vam->retval = ntohl (mp->retval);
2902   vam->result_ready = 1;
2903 }
2904
2905 static u8 *
2906 format_policer_type (u8 * s, va_list * va)
2907 {
2908   u32 i = va_arg (*va, u32);
2909
2910   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2911     s = format (s, "1r2c");
2912   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2913     s = format (s, "1r3c");
2914   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2915     s = format (s, "2r3c-2698");
2916   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2917     s = format (s, "2r3c-4115");
2918   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2919     s = format (s, "2r3c-mef5cf1");
2920   else
2921     s = format (s, "ILLEGAL");
2922   return s;
2923 }
2924
2925 static u8 *
2926 format_policer_rate_type (u8 * s, va_list * va)
2927 {
2928   u32 i = va_arg (*va, u32);
2929
2930   if (i == SSE2_QOS_RATE_KBPS)
2931     s = format (s, "kbps");
2932   else if (i == SSE2_QOS_RATE_PPS)
2933     s = format (s, "pps");
2934   else
2935     s = format (s, "ILLEGAL");
2936   return s;
2937 }
2938
2939 static u8 *
2940 format_policer_round_type (u8 * s, va_list * va)
2941 {
2942   u32 i = va_arg (*va, u32);
2943
2944   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2945     s = format (s, "closest");
2946   else if (i == SSE2_QOS_ROUND_TO_UP)
2947     s = format (s, "up");
2948   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2949     s = format (s, "down");
2950   else
2951     s = format (s, "ILLEGAL");
2952   return s;
2953 }
2954
2955 static u8 *
2956 format_policer_action_type (u8 * s, va_list * va)
2957 {
2958   u32 i = va_arg (*va, u32);
2959
2960   if (i == SSE2_QOS_ACTION_DROP)
2961     s = format (s, "drop");
2962   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2963     s = format (s, "transmit");
2964   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2965     s = format (s, "mark-and-transmit");
2966   else
2967     s = format (s, "ILLEGAL");
2968   return s;
2969 }
2970
2971 static u8 *
2972 format_dscp (u8 * s, va_list * va)
2973 {
2974   u32 i = va_arg (*va, u32);
2975   char *t = 0;
2976
2977   switch (i)
2978     {
2979 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2980       foreach_vnet_dscp
2981 #undef _
2982     default:
2983       return format (s, "ILLEGAL");
2984     }
2985   s = format (s, "%s", t);
2986   return s;
2987 }
2988
2989 static void
2990 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2991 {
2992   vat_main_t *vam = &vat_main;
2993   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2994
2995   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2996     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2997   else
2998     conform_dscp_str = format (0, "");
2999
3000   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3001     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3002   else
3003     exceed_dscp_str = format (0, "");
3004
3005   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3006     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3007   else
3008     violate_dscp_str = format (0, "");
3009
3010   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3011            "rate type %U, round type %U, %s rate, %s color-aware, "
3012            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3013            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3014            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
3015            mp->name,
3016            format_policer_type, mp->type,
3017            ntohl (mp->cir),
3018            ntohl (mp->eir),
3019            clib_net_to_host_u64 (mp->cb),
3020            clib_net_to_host_u64 (mp->eb),
3021            format_policer_rate_type, mp->rate_type,
3022            format_policer_round_type, mp->round_type,
3023            mp->single_rate ? "single" : "dual",
3024            mp->color_aware ? "is" : "not",
3025            ntohl (mp->cir_tokens_per_period),
3026            ntohl (mp->pir_tokens_per_period),
3027            ntohl (mp->scale),
3028            ntohl (mp->current_limit),
3029            ntohl (mp->current_bucket),
3030            ntohl (mp->extended_limit),
3031            ntohl (mp->extended_bucket),
3032            clib_net_to_host_u64 (mp->last_update_time),
3033            format_policer_action_type, mp->conform_action_type,
3034            conform_dscp_str,
3035            format_policer_action_type, mp->exceed_action_type,
3036            exceed_dscp_str,
3037            format_policer_action_type, mp->violate_action_type,
3038            violate_dscp_str);
3039
3040   vec_free (conform_dscp_str);
3041   vec_free (exceed_dscp_str);
3042   vec_free (violate_dscp_str);
3043 }
3044
3045 static void vl_api_policer_details_t_handler_json
3046   (vl_api_policer_details_t * mp)
3047 {
3048   vat_main_t *vam = &vat_main;
3049   vat_json_node_t *node;
3050   u8 *rate_type_str, *round_type_str, *type_str;
3051   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3052
3053   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3054   round_type_str =
3055     format (0, "%U", format_policer_round_type, mp->round_type);
3056   type_str = format (0, "%U", format_policer_type, mp->type);
3057   conform_action_str = format (0, "%U", format_policer_action_type,
3058                                mp->conform_action_type);
3059   exceed_action_str = format (0, "%U", format_policer_action_type,
3060                               mp->exceed_action_type);
3061   violate_action_str = format (0, "%U", format_policer_action_type,
3062                                mp->violate_action_type);
3063
3064   if (VAT_JSON_ARRAY != vam->json_tree.type)
3065     {
3066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3067       vat_json_init_array (&vam->json_tree);
3068     }
3069   node = vat_json_array_add (&vam->json_tree);
3070
3071   vat_json_init_object (node);
3072   vat_json_object_add_string_copy (node, "name", mp->name);
3073   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3074   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3075   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3076   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3077   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3078   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3079   vat_json_object_add_string_copy (node, "type", type_str);
3080   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3081   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3082   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3083   vat_json_object_add_uint (node, "cir_tokens_per_period",
3084                             ntohl (mp->cir_tokens_per_period));
3085   vat_json_object_add_uint (node, "eir_tokens_per_period",
3086                             ntohl (mp->pir_tokens_per_period));
3087   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3088   vat_json_object_add_uint (node, "current_bucket",
3089                             ntohl (mp->current_bucket));
3090   vat_json_object_add_uint (node, "extended_limit",
3091                             ntohl (mp->extended_limit));
3092   vat_json_object_add_uint (node, "extended_bucket",
3093                             ntohl (mp->extended_bucket));
3094   vat_json_object_add_uint (node, "last_update_time",
3095                             ntohl (mp->last_update_time));
3096   vat_json_object_add_string_copy (node, "conform_action",
3097                                    conform_action_str);
3098   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3099     {
3100       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3101       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3102       vec_free (dscp_str);
3103     }
3104   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3105   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3106     {
3107       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3108       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3109       vec_free (dscp_str);
3110     }
3111   vat_json_object_add_string_copy (node, "violate_action",
3112                                    violate_action_str);
3113   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3114     {
3115       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3116       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3117       vec_free (dscp_str);
3118     }
3119
3120   vec_free (rate_type_str);
3121   vec_free (round_type_str);
3122   vec_free (type_str);
3123   vec_free (conform_action_str);
3124   vec_free (exceed_action_str);
3125   vec_free (violate_action_str);
3126 }
3127
3128 static void
3129 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3130                                            mp)
3131 {
3132   vat_main_t *vam = &vat_main;
3133   int i, count = ntohl (mp->count);
3134
3135   if (count > 0)
3136     fformat (vam->ofp, "classify table ids (%d) : ", count);
3137   for (i = 0; i < count; i++)
3138     {
3139       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3140       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3141     }
3142   vam->retval = ntohl (mp->retval);
3143   vam->result_ready = 1;
3144 }
3145
3146 static void
3147   vl_api_classify_table_ids_reply_t_handler_json
3148   (vl_api_classify_table_ids_reply_t * mp)
3149 {
3150   vat_main_t *vam = &vat_main;
3151   int i, count = ntohl (mp->count);
3152
3153   if (count > 0)
3154     {
3155       vat_json_node_t node;
3156
3157       vat_json_init_object (&node);
3158       for (i = 0; i < count; i++)
3159         {
3160           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3161         }
3162       vat_json_print (vam->ofp, &node);
3163       vat_json_free (&node);
3164     }
3165   vam->retval = ntohl (mp->retval);
3166   vam->result_ready = 1;
3167 }
3168
3169 static void
3170   vl_api_classify_table_by_interface_reply_t_handler
3171   (vl_api_classify_table_by_interface_reply_t * mp)
3172 {
3173   vat_main_t *vam = &vat_main;
3174   u32 table_id;
3175
3176   table_id = ntohl (mp->l2_table_id);
3177   if (table_id != ~0)
3178     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3179   else
3180     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3181   table_id = ntohl (mp->ip4_table_id);
3182   if (table_id != ~0)
3183     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3184   else
3185     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3186   table_id = ntohl (mp->ip6_table_id);
3187   if (table_id != ~0)
3188     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3189   else
3190     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3191   vam->retval = ntohl (mp->retval);
3192   vam->result_ready = 1;
3193 }
3194
3195 static void
3196   vl_api_classify_table_by_interface_reply_t_handler_json
3197   (vl_api_classify_table_by_interface_reply_t * mp)
3198 {
3199   vat_main_t *vam = &vat_main;
3200   vat_json_node_t node;
3201
3202   vat_json_init_object (&node);
3203
3204   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3205   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3206   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3207
3208   vat_json_print (vam->ofp, &node);
3209   vat_json_free (&node);
3210
3211   vam->retval = ntohl (mp->retval);
3212   vam->result_ready = 1;
3213 }
3214
3215 static void vl_api_policer_add_del_reply_t_handler
3216   (vl_api_policer_add_del_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   i32 retval = ntohl (mp->retval);
3220   if (vam->async_mode)
3221     {
3222       vam->async_errors += (retval < 0);
3223     }
3224   else
3225     {
3226       vam->retval = retval;
3227       vam->result_ready = 1;
3228       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3229         /*
3230          * Note: this is just barely thread-safe, depends on
3231          * the main thread spinning waiting for an answer...
3232          */
3233         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3234     }
3235 }
3236
3237 static void vl_api_policer_add_del_reply_t_handler_json
3238   (vl_api_policer_add_del_reply_t * mp)
3239 {
3240   vat_main_t *vam = &vat_main;
3241   vat_json_node_t node;
3242
3243   vat_json_init_object (&node);
3244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3245   vat_json_object_add_uint (&node, "policer_index",
3246                             ntohl (mp->policer_index));
3247
3248   vat_json_print (vam->ofp, &node);
3249   vat_json_free (&node);
3250
3251   vam->retval = ntohl (mp->retval);
3252   vam->result_ready = 1;
3253 }
3254
3255 /* Format hex dump. */
3256 u8 *
3257 format_hex_bytes (u8 * s, va_list * va)
3258 {
3259   u8 *bytes = va_arg (*va, u8 *);
3260   int n_bytes = va_arg (*va, int);
3261   uword i;
3262
3263   /* Print short or long form depending on byte count. */
3264   uword short_form = n_bytes <= 32;
3265   uword indent = format_get_indent (s);
3266
3267   if (n_bytes == 0)
3268     return s;
3269
3270   for (i = 0; i < n_bytes; i++)
3271     {
3272       if (!short_form && (i % 32) == 0)
3273         s = format (s, "%08x: ", i);
3274       s = format (s, "%02x", bytes[i]);
3275       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3276         s = format (s, "\n%U", format_white_space, indent);
3277     }
3278
3279   return s;
3280 }
3281
3282 static void
3283 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3284                                             * mp)
3285 {
3286   vat_main_t *vam = &vat_main;
3287   i32 retval = ntohl (mp->retval);
3288   if (retval == 0)
3289     {
3290       fformat (vam->ofp, "classify table info :\n");
3291       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3292                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3293                ntohl (mp->miss_next_index));
3294       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3295                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3296                ntohl (mp->match_n_vectors));
3297       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3298                ntohl (mp->mask_length));
3299     }
3300   vam->retval = retval;
3301   vam->result_ready = 1;
3302 }
3303
3304 static void
3305   vl_api_classify_table_info_reply_t_handler_json
3306   (vl_api_classify_table_info_reply_t * mp)
3307 {
3308   vat_main_t *vam = &vat_main;
3309   vat_json_node_t node;
3310
3311   i32 retval = ntohl (mp->retval);
3312   if (retval == 0)
3313     {
3314       vat_json_init_object (&node);
3315
3316       vat_json_object_add_int (&node, "sessions",
3317                                ntohl (mp->active_sessions));
3318       vat_json_object_add_int (&node, "nexttbl",
3319                                ntohl (mp->next_table_index));
3320       vat_json_object_add_int (&node, "nextnode",
3321                                ntohl (mp->miss_next_index));
3322       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3323       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3324       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3325       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3326                       ntohl (mp->mask_length), 0);
3327       vat_json_object_add_string_copy (&node, "mask", s);
3328
3329       vat_json_print (vam->ofp, &node);
3330       vat_json_free (&node);
3331     }
3332   vam->retval = ntohl (mp->retval);
3333   vam->result_ready = 1;
3334 }
3335
3336 static void
3337 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3338                                            mp)
3339 {
3340   vat_main_t *vam = &vat_main;
3341
3342   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3343            ntohl (mp->hit_next_index), ntohl (mp->advance),
3344            ntohl (mp->opaque_index));
3345   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3346            ntohl (mp->match_length));
3347 }
3348
3349 static void
3350   vl_api_classify_session_details_t_handler_json
3351   (vl_api_classify_session_details_t * mp)
3352 {
3353   vat_main_t *vam = &vat_main;
3354   vat_json_node_t *node = NULL;
3355
3356   if (VAT_JSON_ARRAY != vam->json_tree.type)
3357     {
3358       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3359       vat_json_init_array (&vam->json_tree);
3360     }
3361   node = vat_json_array_add (&vam->json_tree);
3362
3363   vat_json_init_object (node);
3364   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3365   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3366   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3367   u8 *s =
3368     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3369             0);
3370   vat_json_object_add_string_copy (node, "match", s);
3371 }
3372
3373 static void vl_api_pg_create_interface_reply_t_handler
3374   (vl_api_pg_create_interface_reply_t * mp)
3375 {
3376   vat_main_t *vam = &vat_main;
3377
3378   vam->retval = ntohl (mp->retval);
3379   vam->result_ready = 1;
3380 }
3381
3382 static void vl_api_pg_create_interface_reply_t_handler_json
3383   (vl_api_pg_create_interface_reply_t * mp)
3384 {
3385   vat_main_t *vam = &vat_main;
3386   vat_json_node_t node;
3387
3388   i32 retval = ntohl (mp->retval);
3389   if (retval == 0)
3390     {
3391       vat_json_init_object (&node);
3392
3393       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3394
3395       vat_json_print (vam->ofp, &node);
3396       vat_json_free (&node);
3397     }
3398   vam->retval = ntohl (mp->retval);
3399   vam->result_ready = 1;
3400 }
3401
3402 static void vl_api_policer_classify_details_t_handler
3403   (vl_api_policer_classify_details_t * mp)
3404 {
3405   vat_main_t *vam = &vat_main;
3406
3407   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3408            ntohl (mp->table_index));
3409 }
3410
3411 static void vl_api_policer_classify_details_t_handler_json
3412   (vl_api_policer_classify_details_t * mp)
3413 {
3414   vat_main_t *vam = &vat_main;
3415   vat_json_node_t *node;
3416
3417   if (VAT_JSON_ARRAY != vam->json_tree.type)
3418     {
3419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3420       vat_json_init_array (&vam->json_tree);
3421     }
3422   node = vat_json_array_add (&vam->json_tree);
3423
3424   vat_json_init_object (node);
3425   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3426   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3427 }
3428
3429 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3430   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433   i32 retval = ntohl (mp->retval);
3434   if (vam->async_mode)
3435     {
3436       vam->async_errors += (retval < 0);
3437     }
3438   else
3439     {
3440       vam->retval = retval;
3441       vam->sw_if_index = ntohl (mp->sw_if_index);
3442       vam->result_ready = 1;
3443     }
3444 }
3445
3446 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3447   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3448 {
3449   vat_main_t *vam = &vat_main;
3450   vat_json_node_t node;
3451
3452   vat_json_init_object (&node);
3453   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3454   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3455
3456   vat_json_print (vam->ofp, &node);
3457   vat_json_free (&node);
3458
3459   vam->retval = ntohl (mp->retval);
3460   vam->result_ready = 1;
3461 }
3462
3463 static void vl_api_flow_classify_details_t_handler
3464   (vl_api_flow_classify_details_t * mp)
3465 {
3466   vat_main_t *vam = &vat_main;
3467
3468   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3469            ntohl (mp->table_index));
3470 }
3471
3472 static void vl_api_flow_classify_details_t_handler_json
3473   (vl_api_flow_classify_details_t * mp)
3474 {
3475   vat_main_t *vam = &vat_main;
3476   vat_json_node_t *node;
3477
3478   if (VAT_JSON_ARRAY != vam->json_tree.type)
3479     {
3480       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3481       vat_json_init_array (&vam->json_tree);
3482     }
3483   node = vat_json_array_add (&vam->json_tree);
3484
3485   vat_json_init_object (node);
3486   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3487   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3488 }
3489
3490
3491
3492 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3493 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3494 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3495 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3496 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3497 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3498
3499 /*
3500  * Generate boilerplate reply handlers, which
3501  * dig the return value out of the xxx_reply_t API message,
3502  * stick it into vam->retval, and set vam->result_ready
3503  *
3504  * Could also do this by pointing N message decode slots at
3505  * a single function, but that could break in subtle ways.
3506  */
3507
3508 #define foreach_standard_reply_retval_handler           \
3509 _(sw_interface_set_flags_reply)                         \
3510 _(sw_interface_add_del_address_reply)                   \
3511 _(sw_interface_set_table_reply)                         \
3512 _(sw_interface_set_vpath_reply)                         \
3513 _(sw_interface_set_l2_bridge_reply)                     \
3514 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3515 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3516 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3517 _(bridge_domain_add_del_reply)                          \
3518 _(sw_interface_set_l2_xconnect_reply)                   \
3519 _(l2fib_add_del_reply)                                  \
3520 _(ip_add_del_route_reply)                               \
3521 _(proxy_arp_add_del_reply)                              \
3522 _(proxy_arp_intfc_enable_disable_reply)                 \
3523 _(mpls_add_del_encap_reply)                             \
3524 _(mpls_add_del_decap_reply)                             \
3525 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3526 _(sw_interface_set_unnumbered_reply)                    \
3527 _(ip_neighbor_add_del_reply)                            \
3528 _(reset_vrf_reply)                                      \
3529 _(oam_add_del_reply)                                    \
3530 _(reset_fib_reply)                                      \
3531 _(dhcp_proxy_config_reply)                              \
3532 _(dhcp_proxy_config_2_reply)                            \
3533 _(dhcp_proxy_set_vss_reply)                             \
3534 _(dhcp_client_config_reply)                             \
3535 _(set_ip_flow_hash_reply)                               \
3536 _(sw_interface_ip6_enable_disable_reply)                \
3537 _(sw_interface_ip6_set_link_local_address_reply)        \
3538 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3539 _(sw_interface_ip6nd_ra_config_reply)                   \
3540 _(set_arp_neighbor_limit_reply)                         \
3541 _(l2_patch_add_del_reply)                               \
3542 _(sr_tunnel_add_del_reply)                              \
3543 _(sr_policy_add_del_reply)                              \
3544 _(sr_multicast_map_add_del_reply)                       \
3545 _(classify_add_del_session_reply)                       \
3546 _(classify_set_interface_ip_table_reply)                \
3547 _(classify_set_interface_l2_tables_reply)               \
3548 _(l2tpv3_set_tunnel_cookies_reply)                      \
3549 _(l2tpv3_interface_enable_disable_reply)                \
3550 _(l2tpv3_set_lookup_key_reply)                          \
3551 _(l2_fib_clear_table_reply)                             \
3552 _(l2_interface_efp_filter_reply)                        \
3553 _(l2_interface_vlan_tag_rewrite_reply)                  \
3554 _(modify_vhost_user_if_reply)                           \
3555 _(delete_vhost_user_if_reply)                           \
3556 _(want_ip4_arp_events_reply)                            \
3557 _(want_ip6_nd_events_reply)                             \
3558 _(input_acl_set_interface_reply)                        \
3559 _(ipsec_spd_add_del_reply)                              \
3560 _(ipsec_interface_add_del_spd_reply)                    \
3561 _(ipsec_spd_add_del_entry_reply)                        \
3562 _(ipsec_sad_add_del_entry_reply)                        \
3563 _(ipsec_sa_set_key_reply)                               \
3564 _(ikev2_profile_add_del_reply)                          \
3565 _(ikev2_profile_set_auth_reply)                         \
3566 _(ikev2_profile_set_id_reply)                           \
3567 _(ikev2_profile_set_ts_reply)                           \
3568 _(ikev2_set_local_key_reply)                            \
3569 _(delete_loopback_reply)                                \
3570 _(bd_ip_mac_add_del_reply)                              \
3571 _(map_del_domain_reply)                                 \
3572 _(map_add_del_rule_reply)                               \
3573 _(want_interface_events_reply)                          \
3574 _(want_stats_reply)                                     \
3575 _(cop_interface_enable_disable_reply)                   \
3576 _(cop_whitelist_enable_disable_reply)                   \
3577 _(sw_interface_clear_stats_reply)                       \
3578 _(ioam_enable_reply)                              \
3579 _(ioam_disable_reply)                              \
3580 _(lisp_add_del_locator_reply)                           \
3581 _(lisp_add_del_local_eid_reply)                         \
3582 _(lisp_add_del_remote_mapping_reply)                    \
3583 _(lisp_add_del_adjacency_reply)                         \
3584 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3585 _(lisp_add_del_map_resolver_reply)                      \
3586 _(lisp_gpe_enable_disable_reply)                        \
3587 _(lisp_gpe_add_del_iface_reply)                         \
3588 _(lisp_enable_disable_reply)                            \
3589 _(lisp_pitr_set_locator_set_reply)                      \
3590 _(lisp_map_request_mode_reply)                          \
3591 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3592 _(lisp_eid_table_add_del_map_reply)                     \
3593 _(vxlan_gpe_add_del_tunnel_reply)                       \
3594 _(af_packet_delete_reply)                               \
3595 _(policer_classify_set_interface_reply)                 \
3596 _(netmap_create_reply)                                  \
3597 _(netmap_delete_reply)                                  \
3598 _(set_ipfix_exporter_reply)                             \
3599 _(set_ipfix_classify_stream_reply)                      \
3600 _(ipfix_classify_table_add_del_reply)                   \
3601 _(flow_classify_set_interface_reply)                    \
3602 _(pg_capture_reply)                                     \
3603 _(pg_enable_disable_reply)                              \
3604 _(ip_source_and_port_range_check_add_del_reply)         \
3605 _(ip_source_and_port_range_check_interface_add_del_reply)\
3606 _(delete_subif_reply)                                   \
3607 _(l2_interface_pbb_tag_rewrite_reply)                   \
3608 _(punt_reply)
3609
3610 #define _(n)                                    \
3611     static void vl_api_##n##_t_handler          \
3612     (vl_api_##n##_t * mp)                       \
3613     {                                           \
3614         vat_main_t * vam = &vat_main;           \
3615         i32 retval = ntohl(mp->retval);         \
3616         if (vam->async_mode) {                  \
3617             vam->async_errors += (retval < 0);  \
3618         } else {                                \
3619             vam->retval = retval;               \
3620             vam->result_ready = 1;              \
3621         }                                       \
3622     }
3623 foreach_standard_reply_retval_handler;
3624 #undef _
3625
3626 #define _(n)                                    \
3627     static void vl_api_##n##_t_handler_json     \
3628     (vl_api_##n##_t * mp)                       \
3629     {                                           \
3630         vat_main_t * vam = &vat_main;           \
3631         vat_json_node_t node;                   \
3632         vat_json_init_object(&node);            \
3633         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3634         vat_json_print(vam->ofp, &node);        \
3635         vam->retval = ntohl(mp->retval);        \
3636         vam->result_ready = 1;                  \
3637     }
3638 foreach_standard_reply_retval_handler;
3639 #undef _
3640
3641 /*
3642  * Table of message reply handlers, must include boilerplate handlers
3643  * we just generated
3644  */
3645
3646 #define foreach_vpe_api_reply_msg                                       \
3647 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3648 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3649 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3650 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3651 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3652 _(CLI_REPLY, cli_reply)                                                 \
3653 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3654 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3655   sw_interface_add_del_address_reply)                                   \
3656 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3657 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3658 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3659   sw_interface_set_l2_xconnect_reply)                                   \
3660 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3661   sw_interface_set_l2_bridge_reply)                                     \
3662 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3663   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3664 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3665   sw_interface_set_dpdk_hqos_subport_reply)                             \
3666 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3667   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3668 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3669 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3670 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3671 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3672 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3673 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3674 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3675 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3676 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3677 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3678 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3679 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3680 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3681   proxy_arp_intfc_enable_disable_reply)                                 \
3682 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3683 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3684 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3685 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3686   mpls_ethernet_add_del_tunnel_reply)                                   \
3687 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3688   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3689 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3690   sw_interface_set_unnumbered_reply)                                    \
3691 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3692 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3693 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3694 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3695 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3696 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3697 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3698 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3699 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3700 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3701 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3702 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3703   sw_interface_ip6_enable_disable_reply)                                \
3704 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3705   sw_interface_ip6_set_link_local_address_reply)                        \
3706 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3707   sw_interface_ip6nd_ra_prefix_reply)                                   \
3708 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3709   sw_interface_ip6nd_ra_config_reply)                                   \
3710 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3711 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3712 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3713 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3714 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3715 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3716 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3717 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3718 classify_set_interface_ip_table_reply)                                  \
3719 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3720   classify_set_interface_l2_tables_reply)                               \
3721 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3722 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3723 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3724 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3725 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3726   l2tpv3_interface_enable_disable_reply)                                \
3727 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3728 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3729 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3730 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3731 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3732 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3733 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3734 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3735 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3736 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3737 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3738 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3739 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3740 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3741 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3742 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3743 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3744 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3745 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3746 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3747 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3748 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3749 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3750 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3751 _(IP_DETAILS, ip_details)                                               \
3752 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3753 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3754 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3755 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3756 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3757 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3758 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3759 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3760 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3761 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3762 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3763 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3764 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3765 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3766 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3767 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3768 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3769 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3770 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3771 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3772 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3773 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3774 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3775 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3776 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3777 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3778 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3779 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3780 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3781 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3782 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3783 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3784 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3785 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3786 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3787 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3788 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3789 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3790 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3791 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3792 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3793 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3794 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3795 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3796 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3797 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3798 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3799 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3800 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3801 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3802 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3803 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3804 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3805   lisp_add_del_map_request_itr_rlocs_reply)                             \
3806 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3807   lisp_get_map_request_itr_rlocs_reply)                                 \
3808 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3809 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3810 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3811 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3812 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3813 _(POLICER_DETAILS, policer_details)                                     \
3814 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3815 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3816 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3817 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3818 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3819 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3820 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3821 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3822 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3823 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3824 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3825 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3826 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3827 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3828 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3829 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3830 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3831 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3832 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3833 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3834 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3835 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3836 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3837 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3838 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3839  ip_source_and_port_range_check_add_del_reply)                          \
3840 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3841  ip_source_and_port_range_check_interface_add_del_reply)                \
3842 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3843 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3844 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3845 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3846 _(PUNT_REPLY, punt_reply)
3847
3848 /* M: construct, but don't yet send a message */
3849
3850 #define M(T,t)                                  \
3851 do {                                            \
3852     vam->result_ready = 0;                      \
3853     mp = vl_msg_api_alloc(sizeof(*mp));         \
3854     memset (mp, 0, sizeof (*mp));               \
3855     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3856     mp->client_index = vam->my_client_index;    \
3857 } while(0);
3858
3859 #define M2(T,t,n)                               \
3860 do {                                            \
3861     vam->result_ready = 0;                      \
3862     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3863     memset (mp, 0, sizeof (*mp));               \
3864     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3865     mp->client_index = vam->my_client_index;    \
3866 } while(0);
3867
3868
3869 /* S: send a message */
3870 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3871
3872 /* W: wait for results, with timeout */
3873 #define W                                       \
3874 do {                                            \
3875     timeout = vat_time_now (vam) + 1.0;         \
3876                                                 \
3877     while (vat_time_now (vam) < timeout) {      \
3878         if (vam->result_ready == 1) {           \
3879             return (vam->retval);               \
3880         }                                       \
3881     }                                           \
3882     return -99;                                 \
3883 } while(0);
3884
3885 /* W2: wait for results, with timeout */
3886 #define W2(body)                                \
3887 do {                                            \
3888     timeout = vat_time_now (vam) + 1.0;         \
3889                                                 \
3890     while (vat_time_now (vam) < timeout) {      \
3891         if (vam->result_ready == 1) {           \
3892           (body);                               \
3893           return (vam->retval);                 \
3894         }                                       \
3895     }                                           \
3896     return -99;                                 \
3897 } while(0);
3898
3899 typedef struct
3900 {
3901   u8 *name;
3902   u32 value;
3903 } name_sort_t;
3904
3905
3906 #define STR_VTR_OP_CASE(op)     \
3907     case L2_VTR_ ## op:         \
3908         return "" # op;
3909
3910 static const char *
3911 str_vtr_op (u32 vtr_op)
3912 {
3913   switch (vtr_op)
3914     {
3915       STR_VTR_OP_CASE (DISABLED);
3916       STR_VTR_OP_CASE (PUSH_1);
3917       STR_VTR_OP_CASE (PUSH_2);
3918       STR_VTR_OP_CASE (POP_1);
3919       STR_VTR_OP_CASE (POP_2);
3920       STR_VTR_OP_CASE (TRANSLATE_1_1);
3921       STR_VTR_OP_CASE (TRANSLATE_1_2);
3922       STR_VTR_OP_CASE (TRANSLATE_2_1);
3923       STR_VTR_OP_CASE (TRANSLATE_2_2);
3924     }
3925
3926   return "UNKNOWN";
3927 }
3928
3929 static int
3930 dump_sub_interface_table (vat_main_t * vam)
3931 {
3932   const sw_interface_subif_t *sub = NULL;
3933
3934   if (vam->json_output)
3935     {
3936       clib_warning
3937         ("JSON output supported only for VPE API calls and dump_stats_table");
3938       return -99;
3939     }
3940
3941   fformat (vam->ofp,
3942            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3943            "Interface", "sw_if_index",
3944            "sub id", "dot1ad", "tags", "outer id",
3945            "inner id", "exact", "default", "outer any", "inner any");
3946
3947   vec_foreach (sub, vam->sw_if_subif_table)
3948   {
3949     fformat (vam->ofp,
3950              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3951              sub->interface_name,
3952              sub->sw_if_index,
3953              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3954              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3955              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3956              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3957     if (sub->vtr_op != L2_VTR_DISABLED)
3958       {
3959         fformat (vam->ofp,
3960                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3961                  "tag1: %d tag2: %d ]\n",
3962                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3963                  sub->vtr_tag1, sub->vtr_tag2);
3964       }
3965   }
3966
3967   return 0;
3968 }
3969
3970 static int
3971 name_sort_cmp (void *a1, void *a2)
3972 {
3973   name_sort_t *n1 = a1;
3974   name_sort_t *n2 = a2;
3975
3976   return strcmp ((char *) n1->name, (char *) n2->name);
3977 }
3978
3979 static int
3980 dump_interface_table (vat_main_t * vam)
3981 {
3982   hash_pair_t *p;
3983   name_sort_t *nses = 0, *ns;
3984
3985   if (vam->json_output)
3986     {
3987       clib_warning
3988         ("JSON output supported only for VPE API calls and dump_stats_table");
3989       return -99;
3990     }
3991
3992   /* *INDENT-OFF* */
3993   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3994   ({
3995     vec_add2 (nses, ns, 1);
3996     ns->name = (u8 *)(p->key);
3997     ns->value = (u32) p->value[0];
3998   }));
3999   /* *INDENT-ON* */
4000
4001   vec_sort_with_function (nses, name_sort_cmp);
4002
4003   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
4004   vec_foreach (ns, nses)
4005   {
4006     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
4007   }
4008   vec_free (nses);
4009   return 0;
4010 }
4011
4012 static int
4013 dump_ip_table (vat_main_t * vam, int is_ipv6)
4014 {
4015   const ip_details_t *det = NULL;
4016   const ip_address_details_t *address = NULL;
4017   u32 i = ~0;
4018
4019   fformat (vam->ofp, "%-12s\n", "sw_if_index");
4020
4021   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4022   {
4023     i++;
4024     if (!det->present)
4025       {
4026         continue;
4027       }
4028     fformat (vam->ofp, "%-12d\n", i);
4029     fformat (vam->ofp,
4030              "            %-30s%-13s\n", "Address", "Prefix length");
4031     if (!det->addr)
4032       {
4033         continue;
4034       }
4035     vec_foreach (address, det->addr)
4036     {
4037       fformat (vam->ofp,
4038                "            %-30U%-13d\n",
4039                is_ipv6 ? format_ip6_address : format_ip4_address,
4040                address->ip, address->prefix_length);
4041     }
4042   }
4043
4044   return 0;
4045 }
4046
4047 static int
4048 dump_ipv4_table (vat_main_t * vam)
4049 {
4050   if (vam->json_output)
4051     {
4052       clib_warning
4053         ("JSON output supported only for VPE API calls and dump_stats_table");
4054       return -99;
4055     }
4056
4057   return dump_ip_table (vam, 0);
4058 }
4059
4060 static int
4061 dump_ipv6_table (vat_main_t * vam)
4062 {
4063   if (vam->json_output)
4064     {
4065       clib_warning
4066         ("JSON output supported only for VPE API calls and dump_stats_table");
4067       return -99;
4068     }
4069
4070   return dump_ip_table (vam, 1);
4071 }
4072
4073 static char *
4074 counter_type_to_str (u8 counter_type, u8 is_combined)
4075 {
4076   if (!is_combined)
4077     {
4078       switch (counter_type)
4079         {
4080         case VNET_INTERFACE_COUNTER_DROP:
4081           return "drop";
4082         case VNET_INTERFACE_COUNTER_PUNT:
4083           return "punt";
4084         case VNET_INTERFACE_COUNTER_IP4:
4085           return "ip4";
4086         case VNET_INTERFACE_COUNTER_IP6:
4087           return "ip6";
4088         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4089           return "rx-no-buf";
4090         case VNET_INTERFACE_COUNTER_RX_MISS:
4091           return "rx-miss";
4092         case VNET_INTERFACE_COUNTER_RX_ERROR:
4093           return "rx-error";
4094         case VNET_INTERFACE_COUNTER_TX_ERROR:
4095           return "tx-error";
4096         default:
4097           return "INVALID-COUNTER-TYPE";
4098         }
4099     }
4100   else
4101     {
4102       switch (counter_type)
4103         {
4104         case VNET_INTERFACE_COUNTER_RX:
4105           return "rx";
4106         case VNET_INTERFACE_COUNTER_TX:
4107           return "tx";
4108         default:
4109           return "INVALID-COUNTER-TYPE";
4110         }
4111     }
4112 }
4113
4114 static int
4115 dump_stats_table (vat_main_t * vam)
4116 {
4117   vat_json_node_t node;
4118   vat_json_node_t *msg_array;
4119   vat_json_node_t *msg;
4120   vat_json_node_t *counter_array;
4121   vat_json_node_t *counter;
4122   interface_counter_t c;
4123   u64 packets;
4124   ip4_fib_counter_t *c4;
4125   ip6_fib_counter_t *c6;
4126   int i, j;
4127
4128   if (!vam->json_output)
4129     {
4130       clib_warning ("dump_stats_table supported only in JSON format");
4131       return -99;
4132     }
4133
4134   vat_json_init_object (&node);
4135
4136   /* interface counters */
4137   msg_array = vat_json_object_add (&node, "interface_counters");
4138   vat_json_init_array (msg_array);
4139   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4140     {
4141       msg = vat_json_array_add (msg_array);
4142       vat_json_init_object (msg);
4143       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4144                                        (u8 *) counter_type_to_str (i, 0));
4145       vat_json_object_add_int (msg, "is_combined", 0);
4146       counter_array = vat_json_object_add (msg, "data");
4147       vat_json_init_array (counter_array);
4148       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4149         {
4150           packets = vam->simple_interface_counters[i][j];
4151           vat_json_array_add_uint (counter_array, packets);
4152         }
4153     }
4154   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4155     {
4156       msg = vat_json_array_add (msg_array);
4157       vat_json_init_object (msg);
4158       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4159                                        (u8 *) counter_type_to_str (i, 1));
4160       vat_json_object_add_int (msg, "is_combined", 1);
4161       counter_array = vat_json_object_add (msg, "data");
4162       vat_json_init_array (counter_array);
4163       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4164         {
4165           c = vam->combined_interface_counters[i][j];
4166           counter = vat_json_array_add (counter_array);
4167           vat_json_init_object (counter);
4168           vat_json_object_add_uint (counter, "packets", c.packets);
4169           vat_json_object_add_uint (counter, "bytes", c.bytes);
4170         }
4171     }
4172
4173   /* ip4 fib counters */
4174   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4175   vat_json_init_array (msg_array);
4176   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4177     {
4178       msg = vat_json_array_add (msg_array);
4179       vat_json_init_object (msg);
4180       vat_json_object_add_uint (msg, "vrf_id",
4181                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4182       counter_array = vat_json_object_add (msg, "c");
4183       vat_json_init_array (counter_array);
4184       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4185         {
4186           counter = vat_json_array_add (counter_array);
4187           vat_json_init_object (counter);
4188           c4 = &vam->ip4_fib_counters[i][j];
4189           vat_json_object_add_ip4 (counter, "address", c4->address);
4190           vat_json_object_add_uint (counter, "address_length",
4191                                     c4->address_length);
4192           vat_json_object_add_uint (counter, "packets", c4->packets);
4193           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4194         }
4195     }
4196
4197   /* ip6 fib counters */
4198   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4199   vat_json_init_array (msg_array);
4200   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4201     {
4202       msg = vat_json_array_add (msg_array);
4203       vat_json_init_object (msg);
4204       vat_json_object_add_uint (msg, "vrf_id",
4205                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4206       counter_array = vat_json_object_add (msg, "c");
4207       vat_json_init_array (counter_array);
4208       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4209         {
4210           counter = vat_json_array_add (counter_array);
4211           vat_json_init_object (counter);
4212           c6 = &vam->ip6_fib_counters[i][j];
4213           vat_json_object_add_ip6 (counter, "address", c6->address);
4214           vat_json_object_add_uint (counter, "address_length",
4215                                     c6->address_length);
4216           vat_json_object_add_uint (counter, "packets", c6->packets);
4217           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4218         }
4219     }
4220
4221   vat_json_print (vam->ofp, &node);
4222   vat_json_free (&node);
4223
4224   return 0;
4225 }
4226
4227 int
4228 exec (vat_main_t * vam)
4229 {
4230   api_main_t *am = &api_main;
4231   vl_api_cli_request_t *mp;
4232   f64 timeout;
4233   void *oldheap;
4234   u8 *cmd = 0;
4235   unformat_input_t *i = vam->input;
4236
4237   if (vec_len (i->buffer) == 0)
4238     return -1;
4239
4240   if (vam->exec_mode == 0 && unformat (i, "mode"))
4241     {
4242       vam->exec_mode = 1;
4243       return 0;
4244     }
4245   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4246     {
4247       vam->exec_mode = 0;
4248       return 0;
4249     }
4250
4251
4252   M (CLI_REQUEST, cli_request);
4253
4254   /*
4255    * Copy cmd into shared memory.
4256    * In order for the CLI command to work, it
4257    * must be a vector ending in \n, not a C-string ending
4258    * in \n\0.
4259    */
4260   pthread_mutex_lock (&am->vlib_rp->mutex);
4261   oldheap = svm_push_data_heap (am->vlib_rp);
4262
4263   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4264   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4265
4266   svm_pop_heap (oldheap);
4267   pthread_mutex_unlock (&am->vlib_rp->mutex);
4268
4269   mp->cmd_in_shmem = (u64) cmd;
4270   S;
4271   timeout = vat_time_now (vam) + 10.0;
4272
4273   while (vat_time_now (vam) < timeout)
4274     {
4275       if (vam->result_ready == 1)
4276         {
4277           u8 *free_me;
4278           if (vam->shmem_result != NULL)
4279             fformat (vam->ofp, "%s", vam->shmem_result);
4280           pthread_mutex_lock (&am->vlib_rp->mutex);
4281           oldheap = svm_push_data_heap (am->vlib_rp);
4282
4283           free_me = (u8 *) vam->shmem_result;
4284           vec_free (free_me);
4285
4286           svm_pop_heap (oldheap);
4287           pthread_mutex_unlock (&am->vlib_rp->mutex);
4288           return 0;
4289         }
4290     }
4291   return -99;
4292 }
4293
4294 /*
4295  * Future replacement of exec() that passes CLI buffers directly in
4296  * the API messages instead of an additional shared memory area.
4297  */
4298 static int
4299 exec_inband (vat_main_t * vam)
4300 {
4301   vl_api_cli_inband_t *mp;
4302   f64 timeout;
4303   unformat_input_t *i = vam->input;
4304
4305   if (vec_len (i->buffer) == 0)
4306     return -1;
4307
4308   if (vam->exec_mode == 0 && unformat (i, "mode"))
4309     {
4310       vam->exec_mode = 1;
4311       return 0;
4312     }
4313   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4314     {
4315       vam->exec_mode = 0;
4316       return 0;
4317     }
4318
4319   /*
4320    * In order for the CLI command to work, it
4321    * must be a vector ending in \n, not a C-string ending
4322    * in \n\0.
4323    */
4324   u32 len = vec_len (vam->input->buffer);
4325   M2 (CLI_INBAND, cli_inband, len);
4326   clib_memcpy (mp->cmd, vam->input->buffer, len);
4327   mp->length = htonl (len);
4328
4329   S;
4330   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4331 }
4332
4333 static int
4334 api_create_loopback (vat_main_t * vam)
4335 {
4336   unformat_input_t *i = vam->input;
4337   vl_api_create_loopback_t *mp;
4338   f64 timeout;
4339   u8 mac_address[6];
4340   u8 mac_set = 0;
4341
4342   memset (mac_address, 0, sizeof (mac_address));
4343
4344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4345     {
4346       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4347         mac_set = 1;
4348       else
4349         break;
4350     }
4351
4352   /* Construct the API message */
4353   M (CREATE_LOOPBACK, create_loopback);
4354   if (mac_set)
4355     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4356
4357   S;
4358   W;
4359 }
4360
4361 static int
4362 api_delete_loopback (vat_main_t * vam)
4363 {
4364   unformat_input_t *i = vam->input;
4365   vl_api_delete_loopback_t *mp;
4366   f64 timeout;
4367   u32 sw_if_index = ~0;
4368
4369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4370     {
4371       if (unformat (i, "sw_if_index %d", &sw_if_index))
4372         ;
4373       else
4374         break;
4375     }
4376
4377   if (sw_if_index == ~0)
4378     {
4379       errmsg ("missing sw_if_index\n");
4380       return -99;
4381     }
4382
4383   /* Construct the API message */
4384   M (DELETE_LOOPBACK, delete_loopback);
4385   mp->sw_if_index = ntohl (sw_if_index);
4386
4387   S;
4388   W;
4389 }
4390
4391 static int
4392 api_want_stats (vat_main_t * vam)
4393 {
4394   unformat_input_t *i = vam->input;
4395   vl_api_want_stats_t *mp;
4396   f64 timeout;
4397   int enable = -1;
4398
4399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4400     {
4401       if (unformat (i, "enable"))
4402         enable = 1;
4403       else if (unformat (i, "disable"))
4404         enable = 0;
4405       else
4406         break;
4407     }
4408
4409   if (enable == -1)
4410     {
4411       errmsg ("missing enable|disable\n");
4412       return -99;
4413     }
4414
4415   M (WANT_STATS, want_stats);
4416   mp->enable_disable = enable;
4417
4418   S;
4419   W;
4420 }
4421
4422 static int
4423 api_want_interface_events (vat_main_t * vam)
4424 {
4425   unformat_input_t *i = vam->input;
4426   vl_api_want_interface_events_t *mp;
4427   f64 timeout;
4428   int enable = -1;
4429
4430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4431     {
4432       if (unformat (i, "enable"))
4433         enable = 1;
4434       else if (unformat (i, "disable"))
4435         enable = 0;
4436       else
4437         break;
4438     }
4439
4440   if (enable == -1)
4441     {
4442       errmsg ("missing enable|disable\n");
4443       return -99;
4444     }
4445
4446   M (WANT_INTERFACE_EVENTS, want_interface_events);
4447   mp->enable_disable = enable;
4448
4449   vam->interface_event_display = enable;
4450
4451   S;
4452   W;
4453 }
4454
4455
4456 /* Note: non-static, called once to set up the initial intfc table */
4457 int
4458 api_sw_interface_dump (vat_main_t * vam)
4459 {
4460   vl_api_sw_interface_dump_t *mp;
4461   f64 timeout;
4462   hash_pair_t *p;
4463   name_sort_t *nses = 0, *ns;
4464   sw_interface_subif_t *sub = NULL;
4465
4466   /* Toss the old name table */
4467   /* *INDENT-OFF* */
4468   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4469   ({
4470     vec_add2 (nses, ns, 1);
4471     ns->name = (u8 *)(p->key);
4472     ns->value = (u32) p->value[0];
4473   }));
4474   /* *INDENT-ON* */
4475
4476   hash_free (vam->sw_if_index_by_interface_name);
4477
4478   vec_foreach (ns, nses) vec_free (ns->name);
4479
4480   vec_free (nses);
4481
4482   vec_foreach (sub, vam->sw_if_subif_table)
4483   {
4484     vec_free (sub->interface_name);
4485   }
4486   vec_free (vam->sw_if_subif_table);
4487
4488   /* recreate the interface name hash table */
4489   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4490
4491   /* Get list of ethernets */
4492   M (SW_INTERFACE_DUMP, sw_interface_dump);
4493   mp->name_filter_valid = 1;
4494   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4495   S;
4496
4497   /* and local / loopback interfaces */
4498   M (SW_INTERFACE_DUMP, sw_interface_dump);
4499   mp->name_filter_valid = 1;
4500   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4501   S;
4502
4503   /* and packet-generator interfaces */
4504   M (SW_INTERFACE_DUMP, sw_interface_dump);
4505   mp->name_filter_valid = 1;
4506   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4507   S;
4508
4509   /* and vxlan-gpe tunnel interfaces */
4510   M (SW_INTERFACE_DUMP, sw_interface_dump);
4511   mp->name_filter_valid = 1;
4512   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4513            sizeof (mp->name_filter) - 1);
4514   S;
4515
4516   /* and vxlan tunnel interfaces */
4517   M (SW_INTERFACE_DUMP, sw_interface_dump);
4518   mp->name_filter_valid = 1;
4519   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4520   S;
4521
4522   /* and host (af_packet) interfaces */
4523   M (SW_INTERFACE_DUMP, sw_interface_dump);
4524   mp->name_filter_valid = 1;
4525   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4526   S;
4527
4528   /* and l2tpv3 tunnel interfaces */
4529   M (SW_INTERFACE_DUMP, sw_interface_dump);
4530   mp->name_filter_valid = 1;
4531   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4532            sizeof (mp->name_filter) - 1);
4533   S;
4534
4535   /* and GRE tunnel interfaces */
4536   M (SW_INTERFACE_DUMP, sw_interface_dump);
4537   mp->name_filter_valid = 1;
4538   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4539   S;
4540
4541   /* and LISP-GPE interfaces */
4542   M (SW_INTERFACE_DUMP, sw_interface_dump);
4543   mp->name_filter_valid = 1;
4544   strncpy ((char *) mp->name_filter, "lisp_gpe",
4545            sizeof (mp->name_filter) - 1);
4546   S;
4547
4548   /* and IPSEC tunnel interfaces */
4549   M (SW_INTERFACE_DUMP, sw_interface_dump);
4550   mp->name_filter_valid = 1;
4551   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4552   S;
4553
4554   /* Use a control ping for synchronization */
4555   {
4556     vl_api_control_ping_t *mp;
4557     M (CONTROL_PING, control_ping);
4558     S;
4559   }
4560   W;
4561 }
4562
4563 static int
4564 api_sw_interface_set_flags (vat_main_t * vam)
4565 {
4566   unformat_input_t *i = vam->input;
4567   vl_api_sw_interface_set_flags_t *mp;
4568   f64 timeout;
4569   u32 sw_if_index;
4570   u8 sw_if_index_set = 0;
4571   u8 admin_up = 0, link_up = 0;
4572
4573   /* Parse args required to build the message */
4574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4575     {
4576       if (unformat (i, "admin-up"))
4577         admin_up = 1;
4578       else if (unformat (i, "admin-down"))
4579         admin_up = 0;
4580       else if (unformat (i, "link-up"))
4581         link_up = 1;
4582       else if (unformat (i, "link-down"))
4583         link_up = 0;
4584       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4585         sw_if_index_set = 1;
4586       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4587         sw_if_index_set = 1;
4588       else
4589         break;
4590     }
4591
4592   if (sw_if_index_set == 0)
4593     {
4594       errmsg ("missing interface name or sw_if_index\n");
4595       return -99;
4596     }
4597
4598   /* Construct the API message */
4599   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4600   mp->sw_if_index = ntohl (sw_if_index);
4601   mp->admin_up_down = admin_up;
4602   mp->link_up_down = link_up;
4603
4604   /* send it... */
4605   S;
4606
4607   /* Wait for a reply, return the good/bad news... */
4608   W;
4609 }
4610
4611 static int
4612 api_sw_interface_clear_stats (vat_main_t * vam)
4613 {
4614   unformat_input_t *i = vam->input;
4615   vl_api_sw_interface_clear_stats_t *mp;
4616   f64 timeout;
4617   u32 sw_if_index;
4618   u8 sw_if_index_set = 0;
4619
4620   /* Parse args required to build the message */
4621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4622     {
4623       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4624         sw_if_index_set = 1;
4625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4626         sw_if_index_set = 1;
4627       else
4628         break;
4629     }
4630
4631   /* Construct the API message */
4632   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4633
4634   if (sw_if_index_set == 1)
4635     mp->sw_if_index = ntohl (sw_if_index);
4636   else
4637     mp->sw_if_index = ~0;
4638
4639   /* send it... */
4640   S;
4641
4642   /* Wait for a reply, return the good/bad news... */
4643   W;
4644 }
4645
4646 static int
4647 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4648 {
4649   unformat_input_t *i = vam->input;
4650   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4651   f64 timeout;
4652   u32 sw_if_index;
4653   u8 sw_if_index_set = 0;
4654   u32 subport;
4655   u8 subport_set = 0;
4656   u32 pipe;
4657   u8 pipe_set = 0;
4658   u32 profile;
4659   u8 profile_set = 0;
4660
4661   /* Parse args required to build the message */
4662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4663     {
4664       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4665         sw_if_index_set = 1;
4666       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4667         sw_if_index_set = 1;
4668       else if (unformat (i, "subport %u", &subport))
4669         subport_set = 1;
4670       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4671         sw_if_index_set = 1;
4672       else if (unformat (i, "pipe %u", &pipe))
4673         pipe_set = 1;
4674       else if (unformat (i, "profile %u", &profile))
4675         profile_set = 1;
4676       else
4677         break;
4678     }
4679
4680   if (sw_if_index_set == 0)
4681     {
4682       errmsg ("missing interface name or sw_if_index\n");
4683       return -99;
4684     }
4685
4686   if (subport_set == 0)
4687     {
4688       errmsg ("missing subport \n");
4689       return -99;
4690     }
4691
4692   if (pipe_set == 0)
4693     {
4694       errmsg ("missing pipe\n");
4695       return -99;
4696     }
4697
4698   if (profile_set == 0)
4699     {
4700       errmsg ("missing profile\n");
4701       return -99;
4702     }
4703
4704   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4705
4706   mp->sw_if_index = ntohl (sw_if_index);
4707   mp->subport = ntohl (subport);
4708   mp->pipe = ntohl (pipe);
4709   mp->profile = ntohl (profile);
4710
4711
4712   S;
4713   W;
4714   /* NOTREACHED */
4715   return 0;
4716 }
4717
4718 static int
4719 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4720 {
4721   unformat_input_t *i = vam->input;
4722   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4723   f64 timeout;
4724   u32 sw_if_index;
4725   u8 sw_if_index_set = 0;
4726   u32 subport;
4727   u8 subport_set = 0;
4728   u32 tb_rate = 1250000000;     /* 10GbE */
4729   u32 tb_size = 1000000;
4730   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4731   u32 tc_period = 10;
4732
4733   /* Parse args required to build the message */
4734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4735     {
4736       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4737         sw_if_index_set = 1;
4738       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4739         sw_if_index_set = 1;
4740       else if (unformat (i, "subport %u", &subport))
4741         subport_set = 1;
4742       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4743         sw_if_index_set = 1;
4744       else if (unformat (i, "rate %u", &tb_rate))
4745         {
4746           u32 tc_id;
4747
4748           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4749                tc_id++)
4750             tc_rate[tc_id] = tb_rate;
4751         }
4752       else if (unformat (i, "bktsize %u", &tb_size))
4753         ;
4754       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4755         ;
4756       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4757         ;
4758       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4759         ;
4760       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4761         ;
4762       else if (unformat (i, "period %u", &tc_period))
4763         ;
4764       else
4765         break;
4766     }
4767
4768   if (sw_if_index_set == 0)
4769     {
4770       errmsg ("missing interface name or sw_if_index\n");
4771       return -99;
4772     }
4773
4774   if (subport_set == 0)
4775     {
4776       errmsg ("missing subport \n");
4777       return -99;
4778     }
4779
4780   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4781
4782   mp->sw_if_index = ntohl (sw_if_index);
4783   mp->subport = ntohl (subport);
4784   mp->tb_rate = ntohl (tb_rate);
4785   mp->tb_size = ntohl (tb_size);
4786   mp->tc_rate[0] = ntohl (tc_rate[0]);
4787   mp->tc_rate[1] = ntohl (tc_rate[1]);
4788   mp->tc_rate[2] = ntohl (tc_rate[2]);
4789   mp->tc_rate[3] = ntohl (tc_rate[3]);
4790   mp->tc_period = ntohl (tc_period);
4791
4792   S;
4793   W;
4794   /* NOTREACHED */
4795   return 0;
4796 }
4797
4798 static int
4799 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4800 {
4801   unformat_input_t *i = vam->input;
4802   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4803   f64 timeout;
4804   u32 sw_if_index;
4805   u8 sw_if_index_set = 0;
4806   u8 entry_set = 0;
4807   u8 tc_set = 0;
4808   u8 queue_set = 0;
4809   u32 entry, tc, queue;
4810
4811   /* Parse args required to build the message */
4812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4813     {
4814       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4815         sw_if_index_set = 1;
4816       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4817         sw_if_index_set = 1;
4818       else if (unformat (i, "entry %d", &entry))
4819         entry_set = 1;
4820       else if (unformat (i, "tc %d", &tc))
4821         tc_set = 1;
4822       else if (unformat (i, "queue %d", &queue))
4823         queue_set = 1;
4824       else
4825         break;
4826     }
4827
4828   if (sw_if_index_set == 0)
4829     {
4830       errmsg ("missing interface name or sw_if_index\n");
4831       return -99;
4832     }
4833
4834   if (entry_set == 0)
4835     {
4836       errmsg ("missing entry \n");
4837       return -99;
4838     }
4839
4840   if (tc_set == 0)
4841     {
4842       errmsg ("missing traffic class \n");
4843       return -99;
4844     }
4845
4846   if (queue_set == 0)
4847     {
4848       errmsg ("missing queue \n");
4849       return -99;
4850     }
4851
4852   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4853
4854   mp->sw_if_index = ntohl (sw_if_index);
4855   mp->entry = ntohl (entry);
4856   mp->tc = ntohl (tc);
4857   mp->queue = ntohl (queue);
4858
4859   S;
4860   W;
4861   /* NOTREACHED */
4862   return 0;
4863 }
4864
4865 static int
4866 api_sw_interface_add_del_address (vat_main_t * vam)
4867 {
4868   unformat_input_t *i = vam->input;
4869   vl_api_sw_interface_add_del_address_t *mp;
4870   f64 timeout;
4871   u32 sw_if_index;
4872   u8 sw_if_index_set = 0;
4873   u8 is_add = 1, del_all = 0;
4874   u32 address_length = 0;
4875   u8 v4_address_set = 0;
4876   u8 v6_address_set = 0;
4877   ip4_address_t v4address;
4878   ip6_address_t v6address;
4879
4880   /* Parse args required to build the message */
4881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4882     {
4883       if (unformat (i, "del-all"))
4884         del_all = 1;
4885       else if (unformat (i, "del"))
4886         is_add = 0;
4887       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4888         sw_if_index_set = 1;
4889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4890         sw_if_index_set = 1;
4891       else if (unformat (i, "%U/%d",
4892                          unformat_ip4_address, &v4address, &address_length))
4893         v4_address_set = 1;
4894       else if (unformat (i, "%U/%d",
4895                          unformat_ip6_address, &v6address, &address_length))
4896         v6_address_set = 1;
4897       else
4898         break;
4899     }
4900
4901   if (sw_if_index_set == 0)
4902     {
4903       errmsg ("missing interface name or sw_if_index\n");
4904       return -99;
4905     }
4906   if (v4_address_set && v6_address_set)
4907     {
4908       errmsg ("both v4 and v6 addresses set\n");
4909       return -99;
4910     }
4911   if (!v4_address_set && !v6_address_set && !del_all)
4912     {
4913       errmsg ("no addresses set\n");
4914       return -99;
4915     }
4916
4917   /* Construct the API message */
4918   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4919
4920   mp->sw_if_index = ntohl (sw_if_index);
4921   mp->is_add = is_add;
4922   mp->del_all = del_all;
4923   if (v6_address_set)
4924     {
4925       mp->is_ipv6 = 1;
4926       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4927     }
4928   else
4929     {
4930       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4931     }
4932   mp->address_length = address_length;
4933
4934   /* send it... */
4935   S;
4936
4937   /* Wait for a reply, return good/bad news  */
4938   W;
4939 }
4940
4941 static int
4942 api_sw_interface_set_table (vat_main_t * vam)
4943 {
4944   unformat_input_t *i = vam->input;
4945   vl_api_sw_interface_set_table_t *mp;
4946   f64 timeout;
4947   u32 sw_if_index, vrf_id = 0;
4948   u8 sw_if_index_set = 0;
4949   u8 is_ipv6 = 0;
4950
4951   /* Parse args required to build the message */
4952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4953     {
4954       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4955         sw_if_index_set = 1;
4956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4957         sw_if_index_set = 1;
4958       else if (unformat (i, "vrf %d", &vrf_id))
4959         ;
4960       else if (unformat (i, "ipv6"))
4961         is_ipv6 = 1;
4962       else
4963         break;
4964     }
4965
4966   if (sw_if_index_set == 0)
4967     {
4968       errmsg ("missing interface name or sw_if_index\n");
4969       return -99;
4970     }
4971
4972   /* Construct the API message */
4973   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4974
4975   mp->sw_if_index = ntohl (sw_if_index);
4976   mp->is_ipv6 = is_ipv6;
4977   mp->vrf_id = ntohl (vrf_id);
4978
4979   /* send it... */
4980   S;
4981
4982   /* Wait for a reply... */
4983   W;
4984 }
4985
4986 static int
4987 api_sw_interface_set_vpath (vat_main_t * vam)
4988 {
4989   unformat_input_t *i = vam->input;
4990   vl_api_sw_interface_set_vpath_t *mp;
4991   f64 timeout;
4992   u32 sw_if_index = 0;
4993   u8 sw_if_index_set = 0;
4994   u8 is_enable = 0;
4995
4996   /* Parse args required to build the message */
4997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4998     {
4999       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5000         sw_if_index_set = 1;
5001       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5002         sw_if_index_set = 1;
5003       else if (unformat (i, "enable"))
5004         is_enable = 1;
5005       else if (unformat (i, "disable"))
5006         is_enable = 0;
5007       else
5008         break;
5009     }
5010
5011   if (sw_if_index_set == 0)
5012     {
5013       errmsg ("missing interface name or sw_if_index\n");
5014       return -99;
5015     }
5016
5017   /* Construct the API message */
5018   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5019
5020   mp->sw_if_index = ntohl (sw_if_index);
5021   mp->enable = is_enable;
5022
5023   /* send it... */
5024   S;
5025
5026   /* Wait for a reply... */
5027   W;
5028 }
5029
5030 static int
5031 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5032 {
5033   unformat_input_t *i = vam->input;
5034   vl_api_sw_interface_set_l2_xconnect_t *mp;
5035   f64 timeout;
5036   u32 rx_sw_if_index;
5037   u8 rx_sw_if_index_set = 0;
5038   u32 tx_sw_if_index;
5039   u8 tx_sw_if_index_set = 0;
5040   u8 enable = 1;
5041
5042   /* Parse args required to build the message */
5043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5044     {
5045       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5046         rx_sw_if_index_set = 1;
5047       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5048         tx_sw_if_index_set = 1;
5049       else if (unformat (i, "rx"))
5050         {
5051           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5052             {
5053               if (unformat (i, "%U", unformat_sw_if_index, vam,
5054                             &rx_sw_if_index))
5055                 rx_sw_if_index_set = 1;
5056             }
5057           else
5058             break;
5059         }
5060       else if (unformat (i, "tx"))
5061         {
5062           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5063             {
5064               if (unformat (i, "%U", unformat_sw_if_index, vam,
5065                             &tx_sw_if_index))
5066                 tx_sw_if_index_set = 1;
5067             }
5068           else
5069             break;
5070         }
5071       else if (unformat (i, "enable"))
5072         enable = 1;
5073       else if (unformat (i, "disable"))
5074         enable = 0;
5075       else
5076         break;
5077     }
5078
5079   if (rx_sw_if_index_set == 0)
5080     {
5081       errmsg ("missing rx interface name or rx_sw_if_index\n");
5082       return -99;
5083     }
5084
5085   if (enable && (tx_sw_if_index_set == 0))
5086     {
5087       errmsg ("missing tx interface name or tx_sw_if_index\n");
5088       return -99;
5089     }
5090
5091   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5092
5093   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5094   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5095   mp->enable = enable;
5096
5097   S;
5098   W;
5099   /* NOTREACHED */
5100   return 0;
5101 }
5102
5103 static int
5104 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5105 {
5106   unformat_input_t *i = vam->input;
5107   vl_api_sw_interface_set_l2_bridge_t *mp;
5108   f64 timeout;
5109   u32 rx_sw_if_index;
5110   u8 rx_sw_if_index_set = 0;
5111   u32 bd_id;
5112   u8 bd_id_set = 0;
5113   u8 bvi = 0;
5114   u32 shg = 0;
5115   u8 enable = 1;
5116
5117   /* Parse args required to build the message */
5118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5119     {
5120       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5121         rx_sw_if_index_set = 1;
5122       else if (unformat (i, "bd_id %d", &bd_id))
5123         bd_id_set = 1;
5124       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5125         rx_sw_if_index_set = 1;
5126       else if (unformat (i, "shg %d", &shg))
5127         ;
5128       else if (unformat (i, "bvi"))
5129         bvi = 1;
5130       else if (unformat (i, "enable"))
5131         enable = 1;
5132       else if (unformat (i, "disable"))
5133         enable = 0;
5134       else
5135         break;
5136     }
5137
5138   if (rx_sw_if_index_set == 0)
5139     {
5140       errmsg ("missing rx interface name or sw_if_index\n");
5141       return -99;
5142     }
5143
5144   if (enable && (bd_id_set == 0))
5145     {
5146       errmsg ("missing bridge domain\n");
5147       return -99;
5148     }
5149
5150   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5151
5152   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5153   mp->bd_id = ntohl (bd_id);
5154   mp->shg = (u8) shg;
5155   mp->bvi = bvi;
5156   mp->enable = enable;
5157
5158   S;
5159   W;
5160   /* NOTREACHED */
5161   return 0;
5162 }
5163
5164 static int
5165 api_bridge_domain_dump (vat_main_t * vam)
5166 {
5167   unformat_input_t *i = vam->input;
5168   vl_api_bridge_domain_dump_t *mp;
5169   f64 timeout;
5170   u32 bd_id = ~0;
5171
5172   /* Parse args required to build the message */
5173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5174     {
5175       if (unformat (i, "bd_id %d", &bd_id))
5176         ;
5177       else
5178         break;
5179     }
5180
5181   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5182   mp->bd_id = ntohl (bd_id);
5183   S;
5184
5185   /* Use a control ping for synchronization */
5186   {
5187     vl_api_control_ping_t *mp;
5188     M (CONTROL_PING, control_ping);
5189     S;
5190   }
5191
5192   W;
5193   /* NOTREACHED */
5194   return 0;
5195 }
5196
5197 static int
5198 api_bridge_domain_add_del (vat_main_t * vam)
5199 {
5200   unformat_input_t *i = vam->input;
5201   vl_api_bridge_domain_add_del_t *mp;
5202   f64 timeout;
5203   u32 bd_id = ~0;
5204   u8 is_add = 1;
5205   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5206
5207   /* Parse args required to build the message */
5208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5209     {
5210       if (unformat (i, "bd_id %d", &bd_id))
5211         ;
5212       else if (unformat (i, "flood %d", &flood))
5213         ;
5214       else if (unformat (i, "uu-flood %d", &uu_flood))
5215         ;
5216       else if (unformat (i, "forward %d", &forward))
5217         ;
5218       else if (unformat (i, "learn %d", &learn))
5219         ;
5220       else if (unformat (i, "arp-term %d", &arp_term))
5221         ;
5222       else if (unformat (i, "del"))
5223         {
5224           is_add = 0;
5225           flood = uu_flood = forward = learn = 0;
5226         }
5227       else
5228         break;
5229     }
5230
5231   if (bd_id == ~0)
5232     {
5233       errmsg ("missing bridge domain\n");
5234       return -99;
5235     }
5236
5237   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5238
5239   mp->bd_id = ntohl (bd_id);
5240   mp->flood = flood;
5241   mp->uu_flood = uu_flood;
5242   mp->forward = forward;
5243   mp->learn = learn;
5244   mp->arp_term = arp_term;
5245   mp->is_add = is_add;
5246
5247   S;
5248   W;
5249   /* NOTREACHED */
5250   return 0;
5251 }
5252
5253 static int
5254 api_l2fib_add_del (vat_main_t * vam)
5255 {
5256   unformat_input_t *i = vam->input;
5257   vl_api_l2fib_add_del_t *mp;
5258   f64 timeout;
5259   u64 mac = 0;
5260   u8 mac_set = 0;
5261   u32 bd_id;
5262   u8 bd_id_set = 0;
5263   u32 sw_if_index;
5264   u8 sw_if_index_set = 0;
5265   u8 is_add = 1;
5266   u8 static_mac = 0;
5267   u8 filter_mac = 0;
5268   u8 bvi_mac = 0;
5269   int count = 1;
5270   f64 before = 0;
5271   int j;
5272
5273   /* Parse args required to build the message */
5274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5275     {
5276       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5277         mac_set = 1;
5278       else if (unformat (i, "bd_id %d", &bd_id))
5279         bd_id_set = 1;
5280       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5281         sw_if_index_set = 1;
5282       else if (unformat (i, "sw_if"))
5283         {
5284           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5285             {
5286               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5287                 sw_if_index_set = 1;
5288             }
5289           else
5290             break;
5291         }
5292       else if (unformat (i, "static"))
5293         static_mac = 1;
5294       else if (unformat (i, "filter"))
5295         {
5296           filter_mac = 1;
5297           static_mac = 1;
5298         }
5299       else if (unformat (i, "bvi"))
5300         {
5301           bvi_mac = 1;
5302           static_mac = 1;
5303         }
5304       else if (unformat (i, "del"))
5305         is_add = 0;
5306       else if (unformat (i, "count %d", &count))
5307         ;
5308       else
5309         break;
5310     }
5311
5312   if (mac_set == 0)
5313     {
5314       errmsg ("missing mac address\n");
5315       return -99;
5316     }
5317
5318   if (bd_id_set == 0)
5319     {
5320       errmsg ("missing bridge domain\n");
5321       return -99;
5322     }
5323
5324   if (is_add && (sw_if_index_set == 0))
5325     {
5326       errmsg ("missing interface name or sw_if_index\n");
5327       return -99;
5328     }
5329
5330   if (count > 1)
5331     {
5332       /* Turn on async mode */
5333       vam->async_mode = 1;
5334       vam->async_errors = 0;
5335       before = vat_time_now (vam);
5336     }
5337
5338   for (j = 0; j < count; j++)
5339     {
5340       M (L2FIB_ADD_DEL, l2fib_add_del);
5341
5342       mp->mac = mac;
5343       mp->bd_id = ntohl (bd_id);
5344       mp->is_add = is_add;
5345
5346       if (is_add)
5347         {
5348           mp->sw_if_index = ntohl (sw_if_index);
5349           mp->static_mac = static_mac;
5350           mp->filter_mac = filter_mac;
5351           mp->bvi_mac = bvi_mac;
5352         }
5353       increment_mac_address (&mac);
5354       /* send it... */
5355       S;
5356     }
5357
5358   if (count > 1)
5359     {
5360       vl_api_control_ping_t *mp;
5361       f64 after;
5362
5363       /* Shut off async mode */
5364       vam->async_mode = 0;
5365
5366       M (CONTROL_PING, control_ping);
5367       S;
5368
5369       timeout = vat_time_now (vam) + 1.0;
5370       while (vat_time_now (vam) < timeout)
5371         if (vam->result_ready == 1)
5372           goto out;
5373       vam->retval = -99;
5374
5375     out:
5376       if (vam->retval == -99)
5377         errmsg ("timeout\n");
5378
5379       if (vam->async_errors > 0)
5380         {
5381           errmsg ("%d asynchronous errors\n", vam->async_errors);
5382           vam->retval = -98;
5383         }
5384       vam->async_errors = 0;
5385       after = vat_time_now (vam);
5386
5387       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5388                count, after - before, count / (after - before));
5389     }
5390   else
5391     {
5392       /* Wait for a reply... */
5393       W;
5394     }
5395   /* Return the good/bad news */
5396   return (vam->retval);
5397 }
5398
5399 static int
5400 api_l2_flags (vat_main_t * vam)
5401 {
5402   unformat_input_t *i = vam->input;
5403   vl_api_l2_flags_t *mp;
5404   f64 timeout;
5405   u32 sw_if_index;
5406   u32 feature_bitmap = 0;
5407   u8 sw_if_index_set = 0;
5408
5409   /* Parse args required to build the message */
5410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5411     {
5412       if (unformat (i, "sw_if_index %d", &sw_if_index))
5413         sw_if_index_set = 1;
5414       else if (unformat (i, "sw_if"))
5415         {
5416           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5417             {
5418               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5419                 sw_if_index_set = 1;
5420             }
5421           else
5422             break;
5423         }
5424       else if (unformat (i, "learn"))
5425         feature_bitmap |= L2INPUT_FEAT_LEARN;
5426       else if (unformat (i, "forward"))
5427         feature_bitmap |= L2INPUT_FEAT_FWD;
5428       else if (unformat (i, "flood"))
5429         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5430       else if (unformat (i, "uu-flood"))
5431         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5432       else
5433         break;
5434     }
5435
5436   if (sw_if_index_set == 0)
5437     {
5438       errmsg ("missing interface name or sw_if_index\n");
5439       return -99;
5440     }
5441
5442   M (L2_FLAGS, l2_flags);
5443
5444   mp->sw_if_index = ntohl (sw_if_index);
5445   mp->feature_bitmap = ntohl (feature_bitmap);
5446
5447   S;
5448   W;
5449   /* NOTREACHED */
5450   return 0;
5451 }
5452
5453 static int
5454 api_bridge_flags (vat_main_t * vam)
5455 {
5456   unformat_input_t *i = vam->input;
5457   vl_api_bridge_flags_t *mp;
5458   f64 timeout;
5459   u32 bd_id;
5460   u8 bd_id_set = 0;
5461   u8 is_set = 1;
5462   u32 flags = 0;
5463
5464   /* Parse args required to build the message */
5465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5466     {
5467       if (unformat (i, "bd_id %d", &bd_id))
5468         bd_id_set = 1;
5469       else if (unformat (i, "learn"))
5470         flags |= L2_LEARN;
5471       else if (unformat (i, "forward"))
5472         flags |= L2_FWD;
5473       else if (unformat (i, "flood"))
5474         flags |= L2_FLOOD;
5475       else if (unformat (i, "uu-flood"))
5476         flags |= L2_UU_FLOOD;
5477       else if (unformat (i, "arp-term"))
5478         flags |= L2_ARP_TERM;
5479       else if (unformat (i, "off"))
5480         is_set = 0;
5481       else if (unformat (i, "disable"))
5482         is_set = 0;
5483       else
5484         break;
5485     }
5486
5487   if (bd_id_set == 0)
5488     {
5489       errmsg ("missing bridge domain\n");
5490       return -99;
5491     }
5492
5493   M (BRIDGE_FLAGS, bridge_flags);
5494
5495   mp->bd_id = ntohl (bd_id);
5496   mp->feature_bitmap = ntohl (flags);
5497   mp->is_set = is_set;
5498
5499   S;
5500   W;
5501   /* NOTREACHED */
5502   return 0;
5503 }
5504
5505 static int
5506 api_bd_ip_mac_add_del (vat_main_t * vam)
5507 {
5508   unformat_input_t *i = vam->input;
5509   vl_api_bd_ip_mac_add_del_t *mp;
5510   f64 timeout;
5511   u32 bd_id;
5512   u8 is_ipv6 = 0;
5513   u8 is_add = 1;
5514   u8 bd_id_set = 0;
5515   u8 ip_set = 0;
5516   u8 mac_set = 0;
5517   ip4_address_t v4addr;
5518   ip6_address_t v6addr;
5519   u8 macaddr[6];
5520
5521
5522   /* Parse args required to build the message */
5523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5524     {
5525       if (unformat (i, "bd_id %d", &bd_id))
5526         {
5527           bd_id_set++;
5528         }
5529       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5530         {
5531           ip_set++;
5532         }
5533       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5534         {
5535           ip_set++;
5536           is_ipv6++;
5537         }
5538       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5539         {
5540           mac_set++;
5541         }
5542       else if (unformat (i, "del"))
5543         is_add = 0;
5544       else
5545         break;
5546     }
5547
5548   if (bd_id_set == 0)
5549     {
5550       errmsg ("missing bridge domain\n");
5551       return -99;
5552     }
5553   else if (ip_set == 0)
5554     {
5555       errmsg ("missing IP address\n");
5556       return -99;
5557     }
5558   else if (mac_set == 0)
5559     {
5560       errmsg ("missing MAC address\n");
5561       return -99;
5562     }
5563
5564   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5565
5566   mp->bd_id = ntohl (bd_id);
5567   mp->is_ipv6 = is_ipv6;
5568   mp->is_add = is_add;
5569   if (is_ipv6)
5570     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5571   else
5572     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5573   clib_memcpy (mp->mac_address, macaddr, 6);
5574   S;
5575   W;
5576   /* NOTREACHED */
5577   return 0;
5578 }
5579
5580 static int
5581 api_tap_connect (vat_main_t * vam)
5582 {
5583   unformat_input_t *i = vam->input;
5584   vl_api_tap_connect_t *mp;
5585   f64 timeout;
5586   u8 mac_address[6];
5587   u8 random_mac = 1;
5588   u8 name_set = 0;
5589   u8 *tap_name;
5590
5591   memset (mac_address, 0, sizeof (mac_address));
5592
5593   /* Parse args required to build the message */
5594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5595     {
5596       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5597         {
5598           random_mac = 0;
5599         }
5600       else if (unformat (i, "random-mac"))
5601         random_mac = 1;
5602       else if (unformat (i, "tapname %s", &tap_name))
5603         name_set = 1;
5604       else
5605         break;
5606     }
5607
5608   if (name_set == 0)
5609     {
5610       errmsg ("missing tap name\n");
5611       return -99;
5612     }
5613   if (vec_len (tap_name) > 63)
5614     {
5615       errmsg ("tap name too long\n");
5616     }
5617   vec_add1 (tap_name, 0);
5618
5619   /* Construct the API message */
5620   M (TAP_CONNECT, tap_connect);
5621
5622   mp->use_random_mac = random_mac;
5623   clib_memcpy (mp->mac_address, mac_address, 6);
5624   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5625   vec_free (tap_name);
5626
5627   /* send it... */
5628   S;
5629
5630   /* Wait for a reply... */
5631   W;
5632 }
5633
5634 static int
5635 api_tap_modify (vat_main_t * vam)
5636 {
5637   unformat_input_t *i = vam->input;
5638   vl_api_tap_modify_t *mp;
5639   f64 timeout;
5640   u8 mac_address[6];
5641   u8 random_mac = 1;
5642   u8 name_set = 0;
5643   u8 *tap_name;
5644   u32 sw_if_index = ~0;
5645   u8 sw_if_index_set = 0;
5646
5647   memset (mac_address, 0, sizeof (mac_address));
5648
5649   /* Parse args required to build the message */
5650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5651     {
5652       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5653         sw_if_index_set = 1;
5654       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5655         sw_if_index_set = 1;
5656       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5657         {
5658           random_mac = 0;
5659         }
5660       else if (unformat (i, "random-mac"))
5661         random_mac = 1;
5662       else if (unformat (i, "tapname %s", &tap_name))
5663         name_set = 1;
5664       else
5665         break;
5666     }
5667
5668   if (sw_if_index_set == 0)
5669     {
5670       errmsg ("missing vpp interface name");
5671       return -99;
5672     }
5673   if (name_set == 0)
5674     {
5675       errmsg ("missing tap name\n");
5676       return -99;
5677     }
5678   if (vec_len (tap_name) > 63)
5679     {
5680       errmsg ("tap name too long\n");
5681     }
5682   vec_add1 (tap_name, 0);
5683
5684   /* Construct the API message */
5685   M (TAP_MODIFY, tap_modify);
5686
5687   mp->use_random_mac = random_mac;
5688   mp->sw_if_index = ntohl (sw_if_index);
5689   clib_memcpy (mp->mac_address, mac_address, 6);
5690   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5691   vec_free (tap_name);
5692
5693   /* send it... */
5694   S;
5695
5696   /* Wait for a reply... */
5697   W;
5698 }
5699
5700 static int
5701 api_tap_delete (vat_main_t * vam)
5702 {
5703   unformat_input_t *i = vam->input;
5704   vl_api_tap_delete_t *mp;
5705   f64 timeout;
5706   u32 sw_if_index = ~0;
5707   u8 sw_if_index_set = 0;
5708
5709   /* Parse args required to build the message */
5710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5711     {
5712       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5713         sw_if_index_set = 1;
5714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5715         sw_if_index_set = 1;
5716       else
5717         break;
5718     }
5719
5720   if (sw_if_index_set == 0)
5721     {
5722       errmsg ("missing vpp interface name");
5723       return -99;
5724     }
5725
5726   /* Construct the API message */
5727   M (TAP_DELETE, tap_delete);
5728
5729   mp->sw_if_index = ntohl (sw_if_index);
5730
5731   /* send it... */
5732   S;
5733
5734   /* Wait for a reply... */
5735   W;
5736 }
5737
5738 static int
5739 api_ip_add_del_route (vat_main_t * vam)
5740 {
5741   unformat_input_t *i = vam->input;
5742   vl_api_ip_add_del_route_t *mp;
5743   f64 timeout;
5744   u32 sw_if_index = ~0, vrf_id = 0;
5745   u8 sw_if_index_set = 0;
5746   u8 is_ipv6 = 0;
5747   u8 is_local = 0, is_drop = 0;
5748   u8 create_vrf_if_needed = 0;
5749   u8 is_add = 1;
5750   u8 next_hop_weight = 1;
5751   u8 not_last = 0;
5752   u8 is_multipath = 0;
5753   u8 address_set = 0;
5754   u8 address_length_set = 0;
5755   u32 lookup_in_vrf = 0;
5756   u32 resolve_attempts = 0;
5757   u32 dst_address_length = 0;
5758   u8 next_hop_set = 0;
5759   ip4_address_t v4_dst_address, v4_next_hop_address;
5760   ip6_address_t v6_dst_address, v6_next_hop_address;
5761   int count = 1;
5762   int j;
5763   f64 before = 0;
5764   u32 random_add_del = 0;
5765   u32 *random_vector = 0;
5766   uword *random_hash;
5767   u32 random_seed = 0xdeaddabe;
5768   u32 classify_table_index = ~0;
5769   u8 is_classify = 0;
5770   u8 resolve_host = 0, resolve_attached = 0;
5771
5772   /* Parse args required to build the message */
5773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5774     {
5775       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5776         sw_if_index_set = 1;
5777       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5778         sw_if_index_set = 1;
5779       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5780         {
5781           address_set = 1;
5782           is_ipv6 = 0;
5783         }
5784       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5785         {
5786           address_set = 1;
5787           is_ipv6 = 1;
5788         }
5789       else if (unformat (i, "/%d", &dst_address_length))
5790         {
5791           address_length_set = 1;
5792         }
5793
5794       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5795                                          &v4_next_hop_address))
5796         {
5797           next_hop_set = 1;
5798         }
5799       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5800                                          &v6_next_hop_address))
5801         {
5802           next_hop_set = 1;
5803         }
5804       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5805         ;
5806       else if (unformat (i, "weight %d", &next_hop_weight))
5807         ;
5808       else if (unformat (i, "drop"))
5809         {
5810           is_drop = 1;
5811         }
5812       else if (unformat (i, "local"))
5813         {
5814           is_local = 1;
5815         }
5816       else if (unformat (i, "classify %d", &classify_table_index))
5817         {
5818           is_classify = 1;
5819         }
5820       else if (unformat (i, "del"))
5821         is_add = 0;
5822       else if (unformat (i, "add"))
5823         is_add = 1;
5824       else if (unformat (i, "not-last"))
5825         not_last = 1;
5826       else if (unformat (i, "resolve-via-host"))
5827         resolve_host = 1;
5828       else if (unformat (i, "resolve-via-attached"))
5829         resolve_attached = 1;
5830       else if (unformat (i, "multipath"))
5831         is_multipath = 1;
5832       else if (unformat (i, "vrf %d", &vrf_id))
5833         ;
5834       else if (unformat (i, "create-vrf"))
5835         create_vrf_if_needed = 1;
5836       else if (unformat (i, "count %d", &count))
5837         ;
5838       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5839         ;
5840       else if (unformat (i, "random"))
5841         random_add_del = 1;
5842       else if (unformat (i, "seed %d", &random_seed))
5843         ;
5844       else
5845         {
5846           clib_warning ("parse error '%U'", format_unformat_error, i);
5847           return -99;
5848         }
5849     }
5850
5851   if (resolve_attempts > 0 && sw_if_index_set == 0)
5852     {
5853       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5854       return -99;
5855     }
5856
5857   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5858     {
5859       errmsg ("next hop / local / drop / classify not set\n");
5860       return -99;
5861     }
5862
5863   if (address_set == 0)
5864     {
5865       errmsg ("missing addresses\n");
5866       return -99;
5867     }
5868
5869   if (address_length_set == 0)
5870     {
5871       errmsg ("missing address length\n");
5872       return -99;
5873     }
5874
5875   /* Generate a pile of unique, random routes */
5876   if (random_add_del)
5877     {
5878       u32 this_random_address;
5879       random_hash = hash_create (count, sizeof (uword));
5880
5881       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5882       for (j = 0; j <= count; j++)
5883         {
5884           do
5885             {
5886               this_random_address = random_u32 (&random_seed);
5887               this_random_address =
5888                 clib_host_to_net_u32 (this_random_address);
5889             }
5890           while (hash_get (random_hash, this_random_address));
5891           vec_add1 (random_vector, this_random_address);
5892           hash_set (random_hash, this_random_address, 1);
5893         }
5894       hash_free (random_hash);
5895       v4_dst_address.as_u32 = random_vector[0];
5896     }
5897
5898   if (count > 1)
5899     {
5900       /* Turn on async mode */
5901       vam->async_mode = 1;
5902       vam->async_errors = 0;
5903       before = vat_time_now (vam);
5904     }
5905
5906   for (j = 0; j < count; j++)
5907     {
5908       /* Construct the API message */
5909       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5910
5911       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5912       mp->vrf_id = ntohl (vrf_id);
5913       if (resolve_attempts > 0)
5914         {
5915           mp->resolve_attempts = ntohl (resolve_attempts);
5916           mp->resolve_if_needed = 1;
5917         }
5918       mp->create_vrf_if_needed = create_vrf_if_needed;
5919
5920       mp->is_add = is_add;
5921       mp->is_drop = is_drop;
5922       mp->is_ipv6 = is_ipv6;
5923       mp->is_local = is_local;
5924       mp->is_classify = is_classify;
5925       mp->is_multipath = is_multipath;
5926       mp->is_resolve_host = resolve_host;
5927       mp->is_resolve_attached = resolve_attached;
5928       mp->not_last = not_last;
5929       mp->next_hop_weight = next_hop_weight;
5930       mp->dst_address_length = dst_address_length;
5931       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5932       mp->classify_table_index = ntohl (classify_table_index);
5933
5934       if (is_ipv6)
5935         {
5936           clib_memcpy (mp->dst_address, &v6_dst_address,
5937                        sizeof (v6_dst_address));
5938           if (next_hop_set)
5939             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5940                          sizeof (v6_next_hop_address));
5941           increment_v6_address (&v6_dst_address);
5942         }
5943       else
5944         {
5945           clib_memcpy (mp->dst_address, &v4_dst_address,
5946                        sizeof (v4_dst_address));
5947           if (next_hop_set)
5948             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5949                          sizeof (v4_next_hop_address));
5950           if (random_add_del)
5951             v4_dst_address.as_u32 = random_vector[j + 1];
5952           else
5953             increment_v4_address (&v4_dst_address);
5954         }
5955       /* send it... */
5956       S;
5957       /* If we receive SIGTERM, stop now... */
5958       if (vam->do_exit)
5959         break;
5960     }
5961
5962   /* When testing multiple add/del ops, use a control-ping to sync */
5963   if (count > 1)
5964     {
5965       vl_api_control_ping_t *mp;
5966       f64 after;
5967
5968       /* Shut off async mode */
5969       vam->async_mode = 0;
5970
5971       M (CONTROL_PING, control_ping);
5972       S;
5973
5974       timeout = vat_time_now (vam) + 1.0;
5975       while (vat_time_now (vam) < timeout)
5976         if (vam->result_ready == 1)
5977           goto out;
5978       vam->retval = -99;
5979
5980     out:
5981       if (vam->retval == -99)
5982         errmsg ("timeout\n");
5983
5984       if (vam->async_errors > 0)
5985         {
5986           errmsg ("%d asynchronous errors\n", vam->async_errors);
5987           vam->retval = -98;
5988         }
5989       vam->async_errors = 0;
5990       after = vat_time_now (vam);
5991
5992       /* slim chance, but we might have eaten SIGTERM on the first iteration */
5993       if (j > 0)
5994         count = j;
5995
5996       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5997                count, after - before, count / (after - before));
5998     }
5999   else
6000     {
6001       /* Wait for a reply... */
6002       W;
6003     }
6004
6005   /* Return the good/bad news */
6006   return (vam->retval);
6007 }
6008
6009 static int
6010 api_proxy_arp_add_del (vat_main_t * vam)
6011 {
6012   unformat_input_t *i = vam->input;
6013   vl_api_proxy_arp_add_del_t *mp;
6014   f64 timeout;
6015   u32 vrf_id = 0;
6016   u8 is_add = 1;
6017   ip4_address_t lo, hi;
6018   u8 range_set = 0;
6019
6020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6021     {
6022       if (unformat (i, "vrf %d", &vrf_id))
6023         ;
6024       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6025                          unformat_ip4_address, &hi))
6026         range_set = 1;
6027       else if (unformat (i, "del"))
6028         is_add = 0;
6029       else
6030         {
6031           clib_warning ("parse error '%U'", format_unformat_error, i);
6032           return -99;
6033         }
6034     }
6035
6036   if (range_set == 0)
6037     {
6038       errmsg ("address range not set\n");
6039       return -99;
6040     }
6041
6042   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6043
6044   mp->vrf_id = ntohl (vrf_id);
6045   mp->is_add = is_add;
6046   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6047   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6048
6049   S;
6050   W;
6051   /* NOTREACHED */
6052   return 0;
6053 }
6054
6055 static int
6056 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6057 {
6058   unformat_input_t *i = vam->input;
6059   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6060   f64 timeout;
6061   u32 sw_if_index;
6062   u8 enable = 1;
6063   u8 sw_if_index_set = 0;
6064
6065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6066     {
6067       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6068         sw_if_index_set = 1;
6069       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6070         sw_if_index_set = 1;
6071       else if (unformat (i, "enable"))
6072         enable = 1;
6073       else if (unformat (i, "disable"))
6074         enable = 0;
6075       else
6076         {
6077           clib_warning ("parse error '%U'", format_unformat_error, i);
6078           return -99;
6079         }
6080     }
6081
6082   if (sw_if_index_set == 0)
6083     {
6084       errmsg ("missing interface name or sw_if_index\n");
6085       return -99;
6086     }
6087
6088   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6089
6090   mp->sw_if_index = ntohl (sw_if_index);
6091   mp->enable_disable = enable;
6092
6093   S;
6094   W;
6095   /* NOTREACHED */
6096   return 0;
6097 }
6098
6099 static int
6100 api_mpls_add_del_decap (vat_main_t * vam)
6101 {
6102   unformat_input_t *i = vam->input;
6103   vl_api_mpls_add_del_decap_t *mp;
6104   f64 timeout;
6105   u32 rx_vrf_id = 0;
6106   u32 tx_vrf_id = 0;
6107   u32 label = 0;
6108   u8 is_add = 1;
6109   u8 s_bit = 1;
6110   u32 next_index = 1;
6111
6112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6113     {
6114       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6115         ;
6116       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
6117         ;
6118       else if (unformat (i, "label %d", &label))
6119         ;
6120       else if (unformat (i, "next-index %d", &next_index))
6121         ;
6122       else if (unformat (i, "del"))
6123         is_add = 0;
6124       else if (unformat (i, "s-bit-clear"))
6125         s_bit = 0;
6126       else
6127         {
6128           clib_warning ("parse error '%U'", format_unformat_error, i);
6129           return -99;
6130         }
6131     }
6132
6133   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
6134
6135   mp->rx_vrf_id = ntohl (rx_vrf_id);
6136   mp->tx_vrf_id = ntohl (tx_vrf_id);
6137   mp->label = ntohl (label);
6138   mp->next_index = ntohl (next_index);
6139   mp->s_bit = s_bit;
6140   mp->is_add = is_add;
6141
6142   S;
6143   W;
6144   /* NOTREACHED */
6145   return 0;
6146 }
6147
6148 static int
6149 api_mpls_add_del_encap (vat_main_t * vam)
6150 {
6151   unformat_input_t *i = vam->input;
6152   vl_api_mpls_add_del_encap_t *mp;
6153   f64 timeout;
6154   u32 vrf_id = 0;
6155   u32 *labels = 0;
6156   u32 label;
6157   ip4_address_t dst_address;
6158   u8 is_add = 1;
6159
6160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6161     {
6162       if (unformat (i, "vrf %d", &vrf_id))
6163         ;
6164       else if (unformat (i, "label %d", &label))
6165         vec_add1 (labels, ntohl (label));
6166       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6167         ;
6168       else if (unformat (i, "del"))
6169         is_add = 0;
6170       else
6171         {
6172           clib_warning ("parse error '%U'", format_unformat_error, i);
6173           return -99;
6174         }
6175     }
6176
6177   if (vec_len (labels) == 0)
6178     {
6179       errmsg ("missing encap label stack\n");
6180       return -99;
6181     }
6182
6183   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6184       sizeof (u32) * vec_len (labels));
6185
6186   mp->vrf_id = ntohl (vrf_id);
6187   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6188   mp->is_add = is_add;
6189   mp->nlabels = vec_len (labels);
6190   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6191
6192   vec_free (labels);
6193
6194   S;
6195   W;
6196   /* NOTREACHED */
6197   return 0;
6198 }
6199
6200 static int
6201 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
6202 {
6203   unformat_input_t *i = vam->input;
6204   vl_api_mpls_gre_add_del_tunnel_t *mp;
6205   f64 timeout;
6206   u32 inner_vrf_id = 0;
6207   u32 outer_vrf_id = 0;
6208   ip4_address_t src_address;
6209   ip4_address_t dst_address;
6210   ip4_address_t intfc_address;
6211   u32 tmp;
6212   u8 intfc_address_length = 0;
6213   u8 is_add = 1;
6214   u8 l2_only = 0;
6215
6216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6217     {
6218       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6219         ;
6220       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6221         ;
6222       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
6223         ;
6224       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6225         ;
6226       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6227                          &intfc_address, &tmp))
6228         intfc_address_length = tmp;
6229       else if (unformat (i, "l2-only"))
6230         l2_only = 1;
6231       else if (unformat (i, "del"))
6232         is_add = 0;
6233       else
6234         {
6235           clib_warning ("parse error '%U'", format_unformat_error, i);
6236           return -99;
6237         }
6238     }
6239
6240   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
6241
6242   mp->inner_vrf_id = ntohl (inner_vrf_id);
6243   mp->outer_vrf_id = ntohl (outer_vrf_id);
6244   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
6245   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6246   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
6247   mp->intfc_address_length = intfc_address_length;
6248   mp->l2_only = l2_only;
6249   mp->is_add = is_add;
6250
6251   S;
6252   W;
6253   /* NOTREACHED */
6254   return 0;
6255 }
6256
6257 static int
6258 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6259 {
6260   unformat_input_t *i = vam->input;
6261   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6262   f64 timeout;
6263   u32 inner_vrf_id = 0;
6264   ip4_address_t intfc_address;
6265   u8 dst_mac_address[6];
6266   int dst_set = 1;
6267   u32 tmp;
6268   u8 intfc_address_length = 0;
6269   u8 is_add = 1;
6270   u8 l2_only = 0;
6271   u32 tx_sw_if_index;
6272   int tx_sw_if_index_set = 0;
6273
6274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6275     {
6276       if (unformat (i, "vrf %d", &inner_vrf_id))
6277         ;
6278       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6279                          &intfc_address, &tmp))
6280         intfc_address_length = tmp;
6281       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6282         tx_sw_if_index_set = 1;
6283       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6284         tx_sw_if_index_set = 1;
6285       else if (unformat (i, "dst %U", unformat_ethernet_address,
6286                          dst_mac_address))
6287         dst_set = 1;
6288       else if (unformat (i, "l2-only"))
6289         l2_only = 1;
6290       else if (unformat (i, "del"))
6291         is_add = 0;
6292       else
6293         {
6294           clib_warning ("parse error '%U'", format_unformat_error, i);
6295           return -99;
6296         }
6297     }
6298
6299   if (!dst_set)
6300     {
6301       errmsg ("dst (mac address) not set\n");
6302       return -99;
6303     }
6304   if (!tx_sw_if_index_set)
6305     {
6306       errmsg ("tx-intfc not set\n");
6307       return -99;
6308     }
6309
6310   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6311
6312   mp->vrf_id = ntohl (inner_vrf_id);
6313   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6314   mp->adj_address_length = intfc_address_length;
6315   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6316                sizeof (dst_mac_address));
6317   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6318   mp->l2_only = l2_only;
6319   mp->is_add = is_add;
6320
6321   S;
6322   W;
6323   /* NOTREACHED */
6324   return 0;
6325 }
6326
6327 static int
6328 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6329 {
6330   unformat_input_t *i = vam->input;
6331   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6332   f64 timeout;
6333   u32 inner_vrf_id = 0;
6334   u32 outer_vrf_id = 0;
6335   ip4_address_t adj_address;
6336   int adj_address_set = 0;
6337   ip4_address_t next_hop_address;
6338   int next_hop_address_set = 0;
6339   u32 tmp;
6340   u8 adj_address_length = 0;
6341   u8 l2_only = 0;
6342   u8 is_add = 1;
6343   u32 resolve_attempts = 5;
6344   u8 resolve_if_needed = 1;
6345
6346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6347     {
6348       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6349         ;
6350       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6351         ;
6352       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6353                          &adj_address, &tmp))
6354         {
6355           adj_address_length = tmp;
6356           adj_address_set = 1;
6357         }
6358       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6359                          &next_hop_address))
6360         next_hop_address_set = 1;
6361       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6362         ;
6363       else if (unformat (i, "resolve-if-needed %d", &tmp))
6364         resolve_if_needed = tmp;
6365       else if (unformat (i, "l2-only"))
6366         l2_only = 1;
6367       else if (unformat (i, "del"))
6368         is_add = 0;
6369       else
6370         {
6371           clib_warning ("parse error '%U'", format_unformat_error, i);
6372           return -99;
6373         }
6374     }
6375
6376   if (!adj_address_set)
6377     {
6378       errmsg ("adjacency address/mask not set\n");
6379       return -99;
6380     }
6381   if (!next_hop_address_set)
6382     {
6383       errmsg ("ip4 next hop address (in outer fib) not set\n");
6384       return -99;
6385     }
6386
6387   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6388
6389   mp->inner_vrf_id = ntohl (inner_vrf_id);
6390   mp->outer_vrf_id = ntohl (outer_vrf_id);
6391   mp->resolve_attempts = ntohl (resolve_attempts);
6392   mp->resolve_if_needed = resolve_if_needed;
6393   mp->is_add = is_add;
6394   mp->l2_only = l2_only;
6395   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6396   mp->adj_address_length = adj_address_length;
6397   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6398                sizeof (next_hop_address));
6399
6400   S;
6401   W;
6402   /* NOTREACHED */
6403   return 0;
6404 }
6405
6406 static int
6407 api_sw_interface_set_unnumbered (vat_main_t * vam)
6408 {
6409   unformat_input_t *i = vam->input;
6410   vl_api_sw_interface_set_unnumbered_t *mp;
6411   f64 timeout;
6412   u32 sw_if_index;
6413   u32 unnum_sw_index = ~0;
6414   u8 is_add = 1;
6415   u8 sw_if_index_set = 0;
6416
6417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6418     {
6419       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6420         sw_if_index_set = 1;
6421       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6422         sw_if_index_set = 1;
6423       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6424         ;
6425       else if (unformat (i, "del"))
6426         is_add = 0;
6427       else
6428         {
6429           clib_warning ("parse error '%U'", format_unformat_error, i);
6430           return -99;
6431         }
6432     }
6433
6434   if (sw_if_index_set == 0)
6435     {
6436       errmsg ("missing interface name or sw_if_index\n");
6437       return -99;
6438     }
6439
6440   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6441
6442   mp->sw_if_index = ntohl (sw_if_index);
6443   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6444   mp->is_add = is_add;
6445
6446   S;
6447   W;
6448   /* NOTREACHED */
6449   return 0;
6450 }
6451
6452 static int
6453 api_ip_neighbor_add_del (vat_main_t * vam)
6454 {
6455   unformat_input_t *i = vam->input;
6456   vl_api_ip_neighbor_add_del_t *mp;
6457   f64 timeout;
6458   u32 sw_if_index;
6459   u8 sw_if_index_set = 0;
6460   u32 vrf_id = 0;
6461   u8 is_add = 1;
6462   u8 is_static = 0;
6463   u8 mac_address[6];
6464   u8 mac_set = 0;
6465   u8 v4_address_set = 0;
6466   u8 v6_address_set = 0;
6467   ip4_address_t v4address;
6468   ip6_address_t v6address;
6469
6470   memset (mac_address, 0, sizeof (mac_address));
6471
6472   /* Parse args required to build the message */
6473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6474     {
6475       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6476         {
6477           mac_set = 1;
6478         }
6479       else if (unformat (i, "del"))
6480         is_add = 0;
6481       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6482         sw_if_index_set = 1;
6483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6484         sw_if_index_set = 1;
6485       else if (unformat (i, "is_static"))
6486         is_static = 1;
6487       else if (unformat (i, "vrf %d", &vrf_id))
6488         ;
6489       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6490         v4_address_set = 1;
6491       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6492         v6_address_set = 1;
6493       else
6494         {
6495           clib_warning ("parse error '%U'", format_unformat_error, i);
6496           return -99;
6497         }
6498     }
6499
6500   if (sw_if_index_set == 0)
6501     {
6502       errmsg ("missing interface name or sw_if_index\n");
6503       return -99;
6504     }
6505   if (v4_address_set && v6_address_set)
6506     {
6507       errmsg ("both v4 and v6 addresses set\n");
6508       return -99;
6509     }
6510   if (!v4_address_set && !v6_address_set)
6511     {
6512       errmsg ("no address set\n");
6513       return -99;
6514     }
6515
6516   /* Construct the API message */
6517   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6518
6519   mp->sw_if_index = ntohl (sw_if_index);
6520   mp->is_add = is_add;
6521   mp->vrf_id = ntohl (vrf_id);
6522   mp->is_static = is_static;
6523   if (mac_set)
6524     clib_memcpy (mp->mac_address, mac_address, 6);
6525   if (v6_address_set)
6526     {
6527       mp->is_ipv6 = 1;
6528       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6529     }
6530   else
6531     {
6532       /* mp->is_ipv6 = 0; via memset in M macro above */
6533       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6534     }
6535
6536   /* send it... */
6537   S;
6538
6539   /* Wait for a reply, return good/bad news  */
6540   W;
6541
6542   /* NOTREACHED */
6543   return 0;
6544 }
6545
6546 static int
6547 api_reset_vrf (vat_main_t * vam)
6548 {
6549   unformat_input_t *i = vam->input;
6550   vl_api_reset_vrf_t *mp;
6551   f64 timeout;
6552   u32 vrf_id = 0;
6553   u8 is_ipv6 = 0;
6554   u8 vrf_id_set = 0;
6555
6556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6557     {
6558       if (unformat (i, "vrf %d", &vrf_id))
6559         vrf_id_set = 1;
6560       else if (unformat (i, "ipv6"))
6561         is_ipv6 = 1;
6562       else
6563         {
6564           clib_warning ("parse error '%U'", format_unformat_error, i);
6565           return -99;
6566         }
6567     }
6568
6569   if (vrf_id_set == 0)
6570     {
6571       errmsg ("missing vrf id\n");
6572       return -99;
6573     }
6574
6575   M (RESET_VRF, reset_vrf);
6576
6577   mp->vrf_id = ntohl (vrf_id);
6578   mp->is_ipv6 = is_ipv6;
6579
6580   S;
6581   W;
6582   /* NOTREACHED */
6583   return 0;
6584 }
6585
6586 static int
6587 api_create_vlan_subif (vat_main_t * vam)
6588 {
6589   unformat_input_t *i = vam->input;
6590   vl_api_create_vlan_subif_t *mp;
6591   f64 timeout;
6592   u32 sw_if_index;
6593   u8 sw_if_index_set = 0;
6594   u32 vlan_id;
6595   u8 vlan_id_set = 0;
6596
6597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6598     {
6599       if (unformat (i, "sw_if_index %d", &sw_if_index))
6600         sw_if_index_set = 1;
6601       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6602         sw_if_index_set = 1;
6603       else if (unformat (i, "vlan %d", &vlan_id))
6604         vlan_id_set = 1;
6605       else
6606         {
6607           clib_warning ("parse error '%U'", format_unformat_error, i);
6608           return -99;
6609         }
6610     }
6611
6612   if (sw_if_index_set == 0)
6613     {
6614       errmsg ("missing interface name or sw_if_index\n");
6615       return -99;
6616     }
6617
6618   if (vlan_id_set == 0)
6619     {
6620       errmsg ("missing vlan_id\n");
6621       return -99;
6622     }
6623   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6624
6625   mp->sw_if_index = ntohl (sw_if_index);
6626   mp->vlan_id = ntohl (vlan_id);
6627
6628   S;
6629   W;
6630   /* NOTREACHED */
6631   return 0;
6632 }
6633
6634 #define foreach_create_subif_bit                \
6635 _(no_tags)                                      \
6636 _(one_tag)                                      \
6637 _(two_tags)                                     \
6638 _(dot1ad)                                       \
6639 _(exact_match)                                  \
6640 _(default_sub)                                  \
6641 _(outer_vlan_id_any)                            \
6642 _(inner_vlan_id_any)
6643
6644 static int
6645 api_create_subif (vat_main_t * vam)
6646 {
6647   unformat_input_t *i = vam->input;
6648   vl_api_create_subif_t *mp;
6649   f64 timeout;
6650   u32 sw_if_index;
6651   u8 sw_if_index_set = 0;
6652   u32 sub_id;
6653   u8 sub_id_set = 0;
6654   u32 no_tags = 0;
6655   u32 one_tag = 0;
6656   u32 two_tags = 0;
6657   u32 dot1ad = 0;
6658   u32 exact_match = 0;
6659   u32 default_sub = 0;
6660   u32 outer_vlan_id_any = 0;
6661   u32 inner_vlan_id_any = 0;
6662   u32 tmp;
6663   u16 outer_vlan_id = 0;
6664   u16 inner_vlan_id = 0;
6665
6666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6667     {
6668       if (unformat (i, "sw_if_index %d", &sw_if_index))
6669         sw_if_index_set = 1;
6670       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6671         sw_if_index_set = 1;
6672       else if (unformat (i, "sub_id %d", &sub_id))
6673         sub_id_set = 1;
6674       else if (unformat (i, "outer_vlan_id %d", &tmp))
6675         outer_vlan_id = tmp;
6676       else if (unformat (i, "inner_vlan_id %d", &tmp))
6677         inner_vlan_id = tmp;
6678
6679 #define _(a) else if (unformat (i, #a)) a = 1 ;
6680       foreach_create_subif_bit
6681 #undef _
6682         else
6683         {
6684           clib_warning ("parse error '%U'", format_unformat_error, i);
6685           return -99;
6686         }
6687     }
6688
6689   if (sw_if_index_set == 0)
6690     {
6691       errmsg ("missing interface name or sw_if_index\n");
6692       return -99;
6693     }
6694
6695   if (sub_id_set == 0)
6696     {
6697       errmsg ("missing sub_id\n");
6698       return -99;
6699     }
6700   M (CREATE_SUBIF, create_subif);
6701
6702   mp->sw_if_index = ntohl (sw_if_index);
6703   mp->sub_id = ntohl (sub_id);
6704
6705 #define _(a) mp->a = a;
6706   foreach_create_subif_bit;
6707 #undef _
6708
6709   mp->outer_vlan_id = ntohs (outer_vlan_id);
6710   mp->inner_vlan_id = ntohs (inner_vlan_id);
6711
6712   S;
6713   W;
6714   /* NOTREACHED */
6715   return 0;
6716 }
6717
6718 static int
6719 api_oam_add_del (vat_main_t * vam)
6720 {
6721   unformat_input_t *i = vam->input;
6722   vl_api_oam_add_del_t *mp;
6723   f64 timeout;
6724   u32 vrf_id = 0;
6725   u8 is_add = 1;
6726   ip4_address_t src, dst;
6727   u8 src_set = 0;
6728   u8 dst_set = 0;
6729
6730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6731     {
6732       if (unformat (i, "vrf %d", &vrf_id))
6733         ;
6734       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6735         src_set = 1;
6736       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6737         dst_set = 1;
6738       else if (unformat (i, "del"))
6739         is_add = 0;
6740       else
6741         {
6742           clib_warning ("parse error '%U'", format_unformat_error, i);
6743           return -99;
6744         }
6745     }
6746
6747   if (src_set == 0)
6748     {
6749       errmsg ("missing src addr\n");
6750       return -99;
6751     }
6752
6753   if (dst_set == 0)
6754     {
6755       errmsg ("missing dst addr\n");
6756       return -99;
6757     }
6758
6759   M (OAM_ADD_DEL, oam_add_del);
6760
6761   mp->vrf_id = ntohl (vrf_id);
6762   mp->is_add = is_add;
6763   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6764   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6765
6766   S;
6767   W;
6768   /* NOTREACHED */
6769   return 0;
6770 }
6771
6772 static int
6773 api_reset_fib (vat_main_t * vam)
6774 {
6775   unformat_input_t *i = vam->input;
6776   vl_api_reset_fib_t *mp;
6777   f64 timeout;
6778   u32 vrf_id = 0;
6779   u8 is_ipv6 = 0;
6780   u8 vrf_id_set = 0;
6781
6782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6783     {
6784       if (unformat (i, "vrf %d", &vrf_id))
6785         vrf_id_set = 1;
6786       else if (unformat (i, "ipv6"))
6787         is_ipv6 = 1;
6788       else
6789         {
6790           clib_warning ("parse error '%U'", format_unformat_error, i);
6791           return -99;
6792         }
6793     }
6794
6795   if (vrf_id_set == 0)
6796     {
6797       errmsg ("missing vrf id\n");
6798       return -99;
6799     }
6800
6801   M (RESET_FIB, reset_fib);
6802
6803   mp->vrf_id = ntohl (vrf_id);
6804   mp->is_ipv6 = is_ipv6;
6805
6806   S;
6807   W;
6808   /* NOTREACHED */
6809   return 0;
6810 }
6811
6812 static int
6813 api_dhcp_proxy_config (vat_main_t * vam)
6814 {
6815   unformat_input_t *i = vam->input;
6816   vl_api_dhcp_proxy_config_t *mp;
6817   f64 timeout;
6818   u32 vrf_id = 0;
6819   u8 is_add = 1;
6820   u8 insert_cid = 1;
6821   u8 v4_address_set = 0;
6822   u8 v6_address_set = 0;
6823   ip4_address_t v4address;
6824   ip6_address_t v6address;
6825   u8 v4_src_address_set = 0;
6826   u8 v6_src_address_set = 0;
6827   ip4_address_t v4srcaddress;
6828   ip6_address_t v6srcaddress;
6829
6830   /* Parse args required to build the message */
6831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6832     {
6833       if (unformat (i, "del"))
6834         is_add = 0;
6835       else if (unformat (i, "vrf %d", &vrf_id))
6836         ;
6837       else if (unformat (i, "insert-cid %d", &insert_cid))
6838         ;
6839       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6840         v4_address_set = 1;
6841       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6842         v6_address_set = 1;
6843       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6844         v4_src_address_set = 1;
6845       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6846         v6_src_address_set = 1;
6847       else
6848         break;
6849     }
6850
6851   if (v4_address_set && v6_address_set)
6852     {
6853       errmsg ("both v4 and v6 server addresses set\n");
6854       return -99;
6855     }
6856   if (!v4_address_set && !v6_address_set)
6857     {
6858       errmsg ("no server addresses set\n");
6859       return -99;
6860     }
6861
6862   if (v4_src_address_set && v6_src_address_set)
6863     {
6864       errmsg ("both v4 and v6  src addresses set\n");
6865       return -99;
6866     }
6867   if (!v4_src_address_set && !v6_src_address_set)
6868     {
6869       errmsg ("no src addresses set\n");
6870       return -99;
6871     }
6872
6873   if (!(v4_src_address_set && v4_address_set) &&
6874       !(v6_src_address_set && v6_address_set))
6875     {
6876       errmsg ("no matching server and src addresses set\n");
6877       return -99;
6878     }
6879
6880   /* Construct the API message */
6881   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6882
6883   mp->insert_circuit_id = insert_cid;
6884   mp->is_add = is_add;
6885   mp->vrf_id = ntohl (vrf_id);
6886   if (v6_address_set)
6887     {
6888       mp->is_ipv6 = 1;
6889       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6890       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6891     }
6892   else
6893     {
6894       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6895       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6896     }
6897
6898   /* send it... */
6899   S;
6900
6901   /* Wait for a reply, return good/bad news  */
6902   W;
6903   /* NOTREACHED */
6904   return 0;
6905 }
6906
6907 static int
6908 api_dhcp_proxy_config_2 (vat_main_t * vam)
6909 {
6910   unformat_input_t *i = vam->input;
6911   vl_api_dhcp_proxy_config_2_t *mp;
6912   f64 timeout;
6913   u32 rx_vrf_id = 0;
6914   u32 server_vrf_id = 0;
6915   u8 is_add = 1;
6916   u8 insert_cid = 1;
6917   u8 v4_address_set = 0;
6918   u8 v6_address_set = 0;
6919   ip4_address_t v4address;
6920   ip6_address_t v6address;
6921   u8 v4_src_address_set = 0;
6922   u8 v6_src_address_set = 0;
6923   ip4_address_t v4srcaddress;
6924   ip6_address_t v6srcaddress;
6925
6926   /* Parse args required to build the message */
6927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6928     {
6929       if (unformat (i, "del"))
6930         is_add = 0;
6931       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6932         ;
6933       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6934         ;
6935       else if (unformat (i, "insert-cid %d", &insert_cid))
6936         ;
6937       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6938         v4_address_set = 1;
6939       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6940         v6_address_set = 1;
6941       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6942         v4_src_address_set = 1;
6943       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6944         v6_src_address_set = 1;
6945       else
6946         break;
6947     }
6948
6949   if (v4_address_set && v6_address_set)
6950     {
6951       errmsg ("both v4 and v6 server addresses set\n");
6952       return -99;
6953     }
6954   if (!v4_address_set && !v6_address_set)
6955     {
6956       errmsg ("no server addresses set\n");
6957       return -99;
6958     }
6959
6960   if (v4_src_address_set && v6_src_address_set)
6961     {
6962       errmsg ("both v4 and v6  src addresses set\n");
6963       return -99;
6964     }
6965   if (!v4_src_address_set && !v6_src_address_set)
6966     {
6967       errmsg ("no src addresses set\n");
6968       return -99;
6969     }
6970
6971   if (!(v4_src_address_set && v4_address_set) &&
6972       !(v6_src_address_set && v6_address_set))
6973     {
6974       errmsg ("no matching server and src addresses set\n");
6975       return -99;
6976     }
6977
6978   /* Construct the API message */
6979   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6980
6981   mp->insert_circuit_id = insert_cid;
6982   mp->is_add = is_add;
6983   mp->rx_vrf_id = ntohl (rx_vrf_id);
6984   mp->server_vrf_id = ntohl (server_vrf_id);
6985   if (v6_address_set)
6986     {
6987       mp->is_ipv6 = 1;
6988       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6989       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6990     }
6991   else
6992     {
6993       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6994       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6995     }
6996
6997   /* send it... */
6998   S;
6999
7000   /* Wait for a reply, return good/bad news  */
7001   W;
7002   /* NOTREACHED */
7003   return 0;
7004 }
7005
7006 static int
7007 api_dhcp_proxy_set_vss (vat_main_t * vam)
7008 {
7009   unformat_input_t *i = vam->input;
7010   vl_api_dhcp_proxy_set_vss_t *mp;
7011   f64 timeout;
7012   u8 is_ipv6 = 0;
7013   u8 is_add = 1;
7014   u32 tbl_id;
7015   u8 tbl_id_set = 0;
7016   u32 oui;
7017   u8 oui_set = 0;
7018   u32 fib_id;
7019   u8 fib_id_set = 0;
7020
7021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7022     {
7023       if (unformat (i, "tbl_id %d", &tbl_id))
7024         tbl_id_set = 1;
7025       if (unformat (i, "fib_id %d", &fib_id))
7026         fib_id_set = 1;
7027       if (unformat (i, "oui %d", &oui))
7028         oui_set = 1;
7029       else if (unformat (i, "ipv6"))
7030         is_ipv6 = 1;
7031       else if (unformat (i, "del"))
7032         is_add = 0;
7033       else
7034         {
7035           clib_warning ("parse error '%U'", format_unformat_error, i);
7036           return -99;
7037         }
7038     }
7039
7040   if (tbl_id_set == 0)
7041     {
7042       errmsg ("missing tbl id\n");
7043       return -99;
7044     }
7045
7046   if (fib_id_set == 0)
7047     {
7048       errmsg ("missing fib id\n");
7049       return -99;
7050     }
7051   if (oui_set == 0)
7052     {
7053       errmsg ("missing oui\n");
7054       return -99;
7055     }
7056
7057   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7058   mp->tbl_id = ntohl (tbl_id);
7059   mp->fib_id = ntohl (fib_id);
7060   mp->oui = ntohl (oui);
7061   mp->is_ipv6 = is_ipv6;
7062   mp->is_add = is_add;
7063
7064   S;
7065   W;
7066   /* NOTREACHED */
7067   return 0;
7068 }
7069
7070 static int
7071 api_dhcp_client_config (vat_main_t * vam)
7072 {
7073   unformat_input_t *i = vam->input;
7074   vl_api_dhcp_client_config_t *mp;
7075   f64 timeout;
7076   u32 sw_if_index;
7077   u8 sw_if_index_set = 0;
7078   u8 is_add = 1;
7079   u8 *hostname = 0;
7080   u8 disable_event = 0;
7081
7082   /* Parse args required to build the message */
7083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7084     {
7085       if (unformat (i, "del"))
7086         is_add = 0;
7087       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7088         sw_if_index_set = 1;
7089       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7090         sw_if_index_set = 1;
7091       else if (unformat (i, "hostname %s", &hostname))
7092         ;
7093       else if (unformat (i, "disable_event"))
7094         disable_event = 1;
7095       else
7096         break;
7097     }
7098
7099   if (sw_if_index_set == 0)
7100     {
7101       errmsg ("missing interface name or sw_if_index\n");
7102       return -99;
7103     }
7104
7105   if (vec_len (hostname) > 63)
7106     {
7107       errmsg ("hostname too long\n");
7108     }
7109   vec_add1 (hostname, 0);
7110
7111   /* Construct the API message */
7112   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7113
7114   mp->sw_if_index = ntohl (sw_if_index);
7115   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7116   vec_free (hostname);
7117   mp->is_add = is_add;
7118   mp->want_dhcp_event = disable_event ? 0 : 1;
7119   mp->pid = getpid ();
7120
7121   /* send it... */
7122   S;
7123
7124   /* Wait for a reply, return good/bad news  */
7125   W;
7126   /* NOTREACHED */
7127   return 0;
7128 }
7129
7130 static int
7131 api_set_ip_flow_hash (vat_main_t * vam)
7132 {
7133   unformat_input_t *i = vam->input;
7134   vl_api_set_ip_flow_hash_t *mp;
7135   f64 timeout;
7136   u32 vrf_id = 0;
7137   u8 is_ipv6 = 0;
7138   u8 vrf_id_set = 0;
7139   u8 src = 0;
7140   u8 dst = 0;
7141   u8 sport = 0;
7142   u8 dport = 0;
7143   u8 proto = 0;
7144   u8 reverse = 0;
7145
7146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7147     {
7148       if (unformat (i, "vrf %d", &vrf_id))
7149         vrf_id_set = 1;
7150       else if (unformat (i, "ipv6"))
7151         is_ipv6 = 1;
7152       else if (unformat (i, "src"))
7153         src = 1;
7154       else if (unformat (i, "dst"))
7155         dst = 1;
7156       else if (unformat (i, "sport"))
7157         sport = 1;
7158       else if (unformat (i, "dport"))
7159         dport = 1;
7160       else if (unformat (i, "proto"))
7161         proto = 1;
7162       else if (unformat (i, "reverse"))
7163         reverse = 1;
7164
7165       else
7166         {
7167           clib_warning ("parse error '%U'", format_unformat_error, i);
7168           return -99;
7169         }
7170     }
7171
7172   if (vrf_id_set == 0)
7173     {
7174       errmsg ("missing vrf id\n");
7175       return -99;
7176     }
7177
7178   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7179   mp->src = src;
7180   mp->dst = dst;
7181   mp->sport = sport;
7182   mp->dport = dport;
7183   mp->proto = proto;
7184   mp->reverse = reverse;
7185   mp->vrf_id = ntohl (vrf_id);
7186   mp->is_ipv6 = is_ipv6;
7187
7188   S;
7189   W;
7190   /* NOTREACHED */
7191   return 0;
7192 }
7193
7194 static int
7195 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7196 {
7197   unformat_input_t *i = vam->input;
7198   vl_api_sw_interface_ip6_enable_disable_t *mp;
7199   f64 timeout;
7200   u32 sw_if_index;
7201   u8 sw_if_index_set = 0;
7202   u8 enable = 0;
7203
7204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7205     {
7206       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7207         sw_if_index_set = 1;
7208       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7209         sw_if_index_set = 1;
7210       else if (unformat (i, "enable"))
7211         enable = 1;
7212       else if (unformat (i, "disable"))
7213         enable = 0;
7214       else
7215         {
7216           clib_warning ("parse error '%U'", format_unformat_error, i);
7217           return -99;
7218         }
7219     }
7220
7221   if (sw_if_index_set == 0)
7222     {
7223       errmsg ("missing interface name or sw_if_index\n");
7224       return -99;
7225     }
7226
7227   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7228
7229   mp->sw_if_index = ntohl (sw_if_index);
7230   mp->enable = enable;
7231
7232   S;
7233   W;
7234   /* NOTREACHED */
7235   return 0;
7236 }
7237
7238 static int
7239 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7240 {
7241   unformat_input_t *i = vam->input;
7242   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7243   f64 timeout;
7244   u32 sw_if_index;
7245   u8 sw_if_index_set = 0;
7246   u32 address_length = 0;
7247   u8 v6_address_set = 0;
7248   ip6_address_t v6address;
7249
7250   /* Parse args required to build the message */
7251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7252     {
7253       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7254         sw_if_index_set = 1;
7255       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7256         sw_if_index_set = 1;
7257       else if (unformat (i, "%U/%d",
7258                          unformat_ip6_address, &v6address, &address_length))
7259         v6_address_set = 1;
7260       else
7261         break;
7262     }
7263
7264   if (sw_if_index_set == 0)
7265     {
7266       errmsg ("missing interface name or sw_if_index\n");
7267       return -99;
7268     }
7269   if (!v6_address_set)
7270     {
7271       errmsg ("no address set\n");
7272       return -99;
7273     }
7274
7275   /* Construct the API message */
7276   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7277      sw_interface_ip6_set_link_local_address);
7278
7279   mp->sw_if_index = ntohl (sw_if_index);
7280   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7281   mp->address_length = address_length;
7282
7283   /* send it... */
7284   S;
7285
7286   /* Wait for a reply, return good/bad news  */
7287   W;
7288
7289   /* NOTREACHED */
7290   return 0;
7291 }
7292
7293
7294 static int
7295 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7296 {
7297   unformat_input_t *i = vam->input;
7298   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7299   f64 timeout;
7300   u32 sw_if_index;
7301   u8 sw_if_index_set = 0;
7302   u32 address_length = 0;
7303   u8 v6_address_set = 0;
7304   ip6_address_t v6address;
7305   u8 use_default = 0;
7306   u8 no_advertise = 0;
7307   u8 off_link = 0;
7308   u8 no_autoconfig = 0;
7309   u8 no_onlink = 0;
7310   u8 is_no = 0;
7311   u32 val_lifetime = 0;
7312   u32 pref_lifetime = 0;
7313
7314   /* Parse args required to build the message */
7315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7316     {
7317       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7318         sw_if_index_set = 1;
7319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7320         sw_if_index_set = 1;
7321       else if (unformat (i, "%U/%d",
7322                          unformat_ip6_address, &v6address, &address_length))
7323         v6_address_set = 1;
7324       else if (unformat (i, "val_life %d", &val_lifetime))
7325         ;
7326       else if (unformat (i, "pref_life %d", &pref_lifetime))
7327         ;
7328       else if (unformat (i, "def"))
7329         use_default = 1;
7330       else if (unformat (i, "noadv"))
7331         no_advertise = 1;
7332       else if (unformat (i, "offl"))
7333         off_link = 1;
7334       else if (unformat (i, "noauto"))
7335         no_autoconfig = 1;
7336       else if (unformat (i, "nolink"))
7337         no_onlink = 1;
7338       else if (unformat (i, "isno"))
7339         is_no = 1;
7340       else
7341         {
7342           clib_warning ("parse error '%U'", format_unformat_error, i);
7343           return -99;
7344         }
7345     }
7346
7347   if (sw_if_index_set == 0)
7348     {
7349       errmsg ("missing interface name or sw_if_index\n");
7350       return -99;
7351     }
7352   if (!v6_address_set)
7353     {
7354       errmsg ("no address set\n");
7355       return -99;
7356     }
7357
7358   /* Construct the API message */
7359   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7360
7361   mp->sw_if_index = ntohl (sw_if_index);
7362   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7363   mp->address_length = address_length;
7364   mp->use_default = use_default;
7365   mp->no_advertise = no_advertise;
7366   mp->off_link = off_link;
7367   mp->no_autoconfig = no_autoconfig;
7368   mp->no_onlink = no_onlink;
7369   mp->is_no = is_no;
7370   mp->val_lifetime = ntohl (val_lifetime);
7371   mp->pref_lifetime = ntohl (pref_lifetime);
7372
7373   /* send it... */
7374   S;
7375
7376   /* Wait for a reply, return good/bad news  */
7377   W;
7378
7379   /* NOTREACHED */
7380   return 0;
7381 }
7382
7383 static int
7384 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7385 {
7386   unformat_input_t *i = vam->input;
7387   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7388   f64 timeout;
7389   u32 sw_if_index;
7390   u8 sw_if_index_set = 0;
7391   u8 suppress = 0;
7392   u8 managed = 0;
7393   u8 other = 0;
7394   u8 ll_option = 0;
7395   u8 send_unicast = 0;
7396   u8 cease = 0;
7397   u8 is_no = 0;
7398   u8 default_router = 0;
7399   u32 max_interval = 0;
7400   u32 min_interval = 0;
7401   u32 lifetime = 0;
7402   u32 initial_count = 0;
7403   u32 initial_interval = 0;
7404
7405
7406   /* Parse args required to build the message */
7407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7408     {
7409       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7410         sw_if_index_set = 1;
7411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7412         sw_if_index_set = 1;
7413       else if (unformat (i, "maxint %d", &max_interval))
7414         ;
7415       else if (unformat (i, "minint %d", &min_interval))
7416         ;
7417       else if (unformat (i, "life %d", &lifetime))
7418         ;
7419       else if (unformat (i, "count %d", &initial_count))
7420         ;
7421       else if (unformat (i, "interval %d", &initial_interval))
7422         ;
7423       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7424         suppress = 1;
7425       else if (unformat (i, "managed"))
7426         managed = 1;
7427       else if (unformat (i, "other"))
7428         other = 1;
7429       else if (unformat (i, "ll"))
7430         ll_option = 1;
7431       else if (unformat (i, "send"))
7432         send_unicast = 1;
7433       else if (unformat (i, "cease"))
7434         cease = 1;
7435       else if (unformat (i, "isno"))
7436         is_no = 1;
7437       else if (unformat (i, "def"))
7438         default_router = 1;
7439       else
7440         {
7441           clib_warning ("parse error '%U'", format_unformat_error, i);
7442           return -99;
7443         }
7444     }
7445
7446   if (sw_if_index_set == 0)
7447     {
7448       errmsg ("missing interface name or sw_if_index\n");
7449       return -99;
7450     }
7451
7452   /* Construct the API message */
7453   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7454
7455   mp->sw_if_index = ntohl (sw_if_index);
7456   mp->max_interval = ntohl (max_interval);
7457   mp->min_interval = ntohl (min_interval);
7458   mp->lifetime = ntohl (lifetime);
7459   mp->initial_count = ntohl (initial_count);
7460   mp->initial_interval = ntohl (initial_interval);
7461   mp->suppress = suppress;
7462   mp->managed = managed;
7463   mp->other = other;
7464   mp->ll_option = ll_option;
7465   mp->send_unicast = send_unicast;
7466   mp->cease = cease;
7467   mp->is_no = is_no;
7468   mp->default_router = default_router;
7469
7470   /* send it... */
7471   S;
7472
7473   /* Wait for a reply, return good/bad news  */
7474   W;
7475
7476   /* NOTREACHED */
7477   return 0;
7478 }
7479
7480 static int
7481 api_set_arp_neighbor_limit (vat_main_t * vam)
7482 {
7483   unformat_input_t *i = vam->input;
7484   vl_api_set_arp_neighbor_limit_t *mp;
7485   f64 timeout;
7486   u32 arp_nbr_limit;
7487   u8 limit_set = 0;
7488   u8 is_ipv6 = 0;
7489
7490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7491     {
7492       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7493         limit_set = 1;
7494       else if (unformat (i, "ipv6"))
7495         is_ipv6 = 1;
7496       else
7497         {
7498           clib_warning ("parse error '%U'", format_unformat_error, i);
7499           return -99;
7500         }
7501     }
7502
7503   if (limit_set == 0)
7504     {
7505       errmsg ("missing limit value\n");
7506       return -99;
7507     }
7508
7509   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7510
7511   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7512   mp->is_ipv6 = is_ipv6;
7513
7514   S;
7515   W;
7516   /* NOTREACHED */
7517   return 0;
7518 }
7519
7520 static int
7521 api_l2_patch_add_del (vat_main_t * vam)
7522 {
7523   unformat_input_t *i = vam->input;
7524   vl_api_l2_patch_add_del_t *mp;
7525   f64 timeout;
7526   u32 rx_sw_if_index;
7527   u8 rx_sw_if_index_set = 0;
7528   u32 tx_sw_if_index;
7529   u8 tx_sw_if_index_set = 0;
7530   u8 is_add = 1;
7531
7532   /* Parse args required to build the message */
7533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7534     {
7535       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7536         rx_sw_if_index_set = 1;
7537       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7538         tx_sw_if_index_set = 1;
7539       else if (unformat (i, "rx"))
7540         {
7541           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7542             {
7543               if (unformat (i, "%U", unformat_sw_if_index, vam,
7544                             &rx_sw_if_index))
7545                 rx_sw_if_index_set = 1;
7546             }
7547           else
7548             break;
7549         }
7550       else if (unformat (i, "tx"))
7551         {
7552           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7553             {
7554               if (unformat (i, "%U", unformat_sw_if_index, vam,
7555                             &tx_sw_if_index))
7556                 tx_sw_if_index_set = 1;
7557             }
7558           else
7559             break;
7560         }
7561       else if (unformat (i, "del"))
7562         is_add = 0;
7563       else
7564         break;
7565     }
7566
7567   if (rx_sw_if_index_set == 0)
7568     {
7569       errmsg ("missing rx interface name or rx_sw_if_index\n");
7570       return -99;
7571     }
7572
7573   if (tx_sw_if_index_set == 0)
7574     {
7575       errmsg ("missing tx interface name or tx_sw_if_index\n");
7576       return -99;
7577     }
7578
7579   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7580
7581   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7582   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7583   mp->is_add = is_add;
7584
7585   S;
7586   W;
7587   /* NOTREACHED */
7588   return 0;
7589 }
7590
7591 static int
7592 api_ioam_enable (vat_main_t * vam)
7593 {
7594   unformat_input_t *input = vam->input;
7595   vl_api_ioam_enable_t *mp;
7596   f64 timeout;
7597   u32 id = 0;
7598   int has_trace_option = 0;
7599   int has_pow_option = 0;
7600   int has_ppc_option = 0;
7601
7602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7603     {
7604       if (unformat (input, "trace"))
7605         has_trace_option = 1;
7606       else if (unformat (input, "pow"))
7607         has_pow_option = 1;
7608       else if (unformat (input, "ppc encap"))
7609         has_ppc_option = PPC_ENCAP;
7610       else if (unformat (input, "ppc decap"))
7611         has_ppc_option = PPC_DECAP;
7612       else if (unformat (input, "ppc none"))
7613         has_ppc_option = PPC_NONE;
7614       else
7615         break;
7616     }
7617   M (IOAM_ENABLE, ioam_enable);
7618   mp->id = htons (id);
7619   mp->trace_ppc = has_ppc_option;
7620   mp->pow_enable = has_pow_option;
7621   mp->trace_enable = has_trace_option;
7622
7623   S;
7624   W;
7625
7626   return (0);
7627
7628 }
7629
7630
7631 static int
7632 api_ioam_disable (vat_main_t * vam)
7633 {
7634   vl_api_ioam_disable_t *mp;
7635   f64 timeout;
7636
7637   M (IOAM_DISABLE, ioam_disable);
7638   S;
7639   W;
7640   return 0;
7641 }
7642
7643 static int
7644 api_sr_tunnel_add_del (vat_main_t * vam)
7645 {
7646   unformat_input_t *i = vam->input;
7647   vl_api_sr_tunnel_add_del_t *mp;
7648   f64 timeout;
7649   int is_del = 0;
7650   int pl_index;
7651   ip6_address_t src_address;
7652   int src_address_set = 0;
7653   ip6_address_t dst_address;
7654   u32 dst_mask_width;
7655   int dst_address_set = 0;
7656   u16 flags = 0;
7657   u32 rx_table_id = 0;
7658   u32 tx_table_id = 0;
7659   ip6_address_t *segments = 0;
7660   ip6_address_t *this_seg;
7661   ip6_address_t *tags = 0;
7662   ip6_address_t *this_tag;
7663   ip6_address_t next_address, tag;
7664   u8 *name = 0;
7665   u8 *policy_name = 0;
7666
7667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7668     {
7669       if (unformat (i, "del"))
7670         is_del = 1;
7671       else if (unformat (i, "name %s", &name))
7672         ;
7673       else if (unformat (i, "policy %s", &policy_name))
7674         ;
7675       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7676         ;
7677       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7678         ;
7679       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7680         src_address_set = 1;
7681       else if (unformat (i, "dst %U/%d",
7682                          unformat_ip6_address, &dst_address, &dst_mask_width))
7683         dst_address_set = 1;
7684       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7685         {
7686           vec_add2 (segments, this_seg, 1);
7687           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7688                        sizeof (*this_seg));
7689         }
7690       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7691         {
7692           vec_add2 (tags, this_tag, 1);
7693           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7694         }
7695       else if (unformat (i, "clean"))
7696         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7697       else if (unformat (i, "protected"))
7698         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7699       else if (unformat (i, "InPE %d", &pl_index))
7700         {
7701           if (pl_index <= 0 || pl_index > 4)
7702             {
7703             pl_index_range_error:
7704               errmsg ("pl index %d out of range\n", pl_index);
7705               return -99;
7706             }
7707           flags |=
7708             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7709         }
7710       else if (unformat (i, "EgPE %d", &pl_index))
7711         {
7712           if (pl_index <= 0 || pl_index > 4)
7713             goto pl_index_range_error;
7714           flags |=
7715             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7716         }
7717       else if (unformat (i, "OrgSrc %d", &pl_index))
7718         {
7719           if (pl_index <= 0 || pl_index > 4)
7720             goto pl_index_range_error;
7721           flags |=
7722             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7723         }
7724       else
7725         break;
7726     }
7727
7728   if (!src_address_set)
7729     {
7730       errmsg ("src address required\n");
7731       return -99;
7732     }
7733
7734   if (!dst_address_set)
7735     {
7736       errmsg ("dst address required\n");
7737       return -99;
7738     }
7739
7740   if (!segments)
7741     {
7742       errmsg ("at least one sr segment required\n");
7743       return -99;
7744     }
7745
7746   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7747       vec_len (segments) * sizeof (ip6_address_t)
7748       + vec_len (tags) * sizeof (ip6_address_t));
7749
7750   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7751   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7752   mp->dst_mask_width = dst_mask_width;
7753   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7754   mp->n_segments = vec_len (segments);
7755   mp->n_tags = vec_len (tags);
7756   mp->is_add = is_del == 0;
7757   clib_memcpy (mp->segs_and_tags, segments,
7758                vec_len (segments) * sizeof (ip6_address_t));
7759   clib_memcpy (mp->segs_and_tags +
7760                vec_len (segments) * sizeof (ip6_address_t), tags,
7761                vec_len (tags) * sizeof (ip6_address_t));
7762
7763   mp->outer_vrf_id = ntohl (rx_table_id);
7764   mp->inner_vrf_id = ntohl (tx_table_id);
7765   memcpy (mp->name, name, vec_len (name));
7766   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7767
7768   vec_free (segments);
7769   vec_free (tags);
7770
7771   S;
7772   W;
7773   /* NOTREACHED */
7774 }
7775
7776 static int
7777 api_sr_policy_add_del (vat_main_t * vam)
7778 {
7779   unformat_input_t *input = vam->input;
7780   vl_api_sr_policy_add_del_t *mp;
7781   f64 timeout;
7782   int is_del = 0;
7783   u8 *name = 0;
7784   u8 *tunnel_name = 0;
7785   u8 **tunnel_names = 0;
7786
7787   int name_set = 0;
7788   int tunnel_set = 0;
7789   int j = 0;
7790   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7791   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7792
7793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7794     {
7795       if (unformat (input, "del"))
7796         is_del = 1;
7797       else if (unformat (input, "name %s", &name))
7798         name_set = 1;
7799       else if (unformat (input, "tunnel %s", &tunnel_name))
7800         {
7801           if (tunnel_name)
7802             {
7803               vec_add1 (tunnel_names, tunnel_name);
7804               /* For serializer:
7805                  - length = #bytes to store in serial vector
7806                  - +1 = byte to store that length
7807                */
7808               tunnel_names_length += (vec_len (tunnel_name) + 1);
7809               tunnel_set = 1;
7810               tunnel_name = 0;
7811             }
7812         }
7813       else
7814         break;
7815     }
7816
7817   if (!name_set)
7818     {
7819       errmsg ("policy name required\n");
7820       return -99;
7821     }
7822
7823   if ((!tunnel_set) && (!is_del))
7824     {
7825       errmsg ("tunnel name required\n");
7826       return -99;
7827     }
7828
7829   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7830
7831
7832
7833   mp->is_add = !is_del;
7834
7835   memcpy (mp->name, name, vec_len (name));
7836   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7837   u8 *serial_orig = 0;
7838   vec_validate (serial_orig, tunnel_names_length);
7839   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7840   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7841
7842   for (j = 0; j < vec_len (tunnel_names); j++)
7843     {
7844       tun_name_len = vec_len (tunnel_names[j]);
7845       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7846       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7847       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7848       serial_orig += tun_name_len;      // Advance past the copy
7849     }
7850   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7851
7852   vec_free (tunnel_names);
7853   vec_free (tunnel_name);
7854
7855   S;
7856   W;
7857   /* NOTREACHED */
7858 }
7859
7860 static int
7861 api_sr_multicast_map_add_del (vat_main_t * vam)
7862 {
7863   unformat_input_t *input = vam->input;
7864   vl_api_sr_multicast_map_add_del_t *mp;
7865   f64 timeout;
7866   int is_del = 0;
7867   ip6_address_t multicast_address;
7868   u8 *policy_name = 0;
7869   int multicast_address_set = 0;
7870
7871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7872     {
7873       if (unformat (input, "del"))
7874         is_del = 1;
7875       else
7876         if (unformat
7877             (input, "address %U", unformat_ip6_address, &multicast_address))
7878         multicast_address_set = 1;
7879       else if (unformat (input, "sr-policy %s", &policy_name))
7880         ;
7881       else
7882         break;
7883     }
7884
7885   if (!is_del && !policy_name)
7886     {
7887       errmsg ("sr-policy name required\n");
7888       return -99;
7889     }
7890
7891
7892   if (!multicast_address_set)
7893     {
7894       errmsg ("address required\n");
7895       return -99;
7896     }
7897
7898   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7899
7900   mp->is_add = !is_del;
7901   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7902   clib_memcpy (mp->multicast_address, &multicast_address,
7903                sizeof (mp->multicast_address));
7904
7905
7906   vec_free (policy_name);
7907
7908   S;
7909   W;
7910   /* NOTREACHED */
7911 }
7912
7913
7914 #define foreach_tcp_proto_field                 \
7915 _(src_port)                                     \
7916 _(dst_port)
7917
7918 #define foreach_udp_proto_field                 \
7919 _(src_port)                                     \
7920 _(dst_port)
7921
7922 #define foreach_ip4_proto_field                 \
7923 _(src_address)                                  \
7924 _(dst_address)                                  \
7925 _(tos)                                          \
7926 _(length)                                       \
7927 _(fragment_id)                                  \
7928 _(ttl)                                          \
7929 _(protocol)                                     \
7930 _(checksum)
7931
7932 uword
7933 unformat_tcp_mask (unformat_input_t * input, va_list * args)
7934 {
7935   u8 **maskp = va_arg (*args, u8 **);
7936   u8 *mask = 0;
7937   u8 found_something = 0;
7938   tcp_header_t *tcp;
7939
7940 #define _(a) u8 a=0;
7941   foreach_tcp_proto_field;
7942 #undef _
7943
7944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7945     {
7946       if (0);
7947 #define _(a) else if (unformat (input, #a)) a=1;
7948       foreach_tcp_proto_field
7949 #undef _
7950         else
7951         break;
7952     }
7953
7954 #define _(a) found_something += a;
7955   foreach_tcp_proto_field;
7956 #undef _
7957
7958   if (found_something == 0)
7959     return 0;
7960
7961   vec_validate (mask, sizeof (*tcp) - 1);
7962
7963   tcp = (tcp_header_t *) mask;
7964
7965 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
7966   foreach_tcp_proto_field;
7967 #undef _
7968
7969   *maskp = mask;
7970   return 1;
7971 }
7972
7973 uword
7974 unformat_udp_mask (unformat_input_t * input, va_list * args)
7975 {
7976   u8 **maskp = va_arg (*args, u8 **);
7977   u8 *mask = 0;
7978   u8 found_something = 0;
7979   udp_header_t *udp;
7980
7981 #define _(a) u8 a=0;
7982   foreach_udp_proto_field;
7983 #undef _
7984
7985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7986     {
7987       if (0);
7988 #define _(a) else if (unformat (input, #a)) a=1;
7989       foreach_udp_proto_field
7990 #undef _
7991         else
7992         break;
7993     }
7994
7995 #define _(a) found_something += a;
7996   foreach_udp_proto_field;
7997 #undef _
7998
7999   if (found_something == 0)
8000     return 0;
8001
8002   vec_validate (mask, sizeof (*udp) - 1);
8003
8004   udp = (udp_header_t *) mask;
8005
8006 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8007   foreach_udp_proto_field;
8008 #undef _
8009
8010   *maskp = mask;
8011   return 1;
8012 }
8013
8014 typedef struct
8015 {
8016   u16 src_port, dst_port;
8017 } tcpudp_header_t;
8018
8019 uword
8020 unformat_l4_mask (unformat_input_t * input, va_list * args)
8021 {
8022   u8 **maskp = va_arg (*args, u8 **);
8023   u16 src_port = 0, dst_port = 0;
8024   tcpudp_header_t *tcpudp;
8025
8026   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8027     {
8028       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8029         return 1;
8030       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8031         return 1;
8032       else if (unformat (input, "src_port"))
8033         src_port = 0xFFFF;
8034       else if (unformat (input, "dst_port"))
8035         dst_port = 0xFFFF;
8036       else
8037         return 0;
8038     }
8039
8040   if (!src_port && !dst_port)
8041     return 0;
8042
8043   u8 *mask = 0;
8044   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8045
8046   tcpudp = (tcpudp_header_t *) mask;
8047   tcpudp->src_port = src_port;
8048   tcpudp->dst_port = dst_port;
8049
8050   *maskp = mask;
8051
8052   return 1;
8053 }
8054
8055 uword
8056 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8057 {
8058   u8 **maskp = va_arg (*args, u8 **);
8059   u8 *mask = 0;
8060   u8 found_something = 0;
8061   ip4_header_t *ip;
8062
8063 #define _(a) u8 a=0;
8064   foreach_ip4_proto_field;
8065 #undef _
8066   u8 version = 0;
8067   u8 hdr_length = 0;
8068
8069
8070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8071     {
8072       if (unformat (input, "version"))
8073         version = 1;
8074       else if (unformat (input, "hdr_length"))
8075         hdr_length = 1;
8076       else if (unformat (input, "src"))
8077         src_address = 1;
8078       else if (unformat (input, "dst"))
8079         dst_address = 1;
8080       else if (unformat (input, "proto"))
8081         protocol = 1;
8082
8083 #define _(a) else if (unformat (input, #a)) a=1;
8084       foreach_ip4_proto_field
8085 #undef _
8086         else
8087         break;
8088     }
8089
8090 #define _(a) found_something += a;
8091   foreach_ip4_proto_field;
8092 #undef _
8093
8094   if (found_something == 0)
8095     return 0;
8096
8097   vec_validate (mask, sizeof (*ip) - 1);
8098
8099   ip = (ip4_header_t *) mask;
8100
8101 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8102   foreach_ip4_proto_field;
8103 #undef _
8104
8105   ip->ip_version_and_header_length = 0;
8106
8107   if (version)
8108     ip->ip_version_and_header_length |= 0xF0;
8109
8110   if (hdr_length)
8111     ip->ip_version_and_header_length |= 0x0F;
8112
8113   *maskp = mask;
8114   return 1;
8115 }
8116
8117 #define foreach_ip6_proto_field                 \
8118 _(src_address)                                  \
8119 _(dst_address)                                  \
8120 _(payload_length)                               \
8121 _(hop_limit)                                    \
8122 _(protocol)
8123
8124 uword
8125 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8126 {
8127   u8 **maskp = va_arg (*args, u8 **);
8128   u8 *mask = 0;
8129   u8 found_something = 0;
8130   ip6_header_t *ip;
8131   u32 ip_version_traffic_class_and_flow_label;
8132
8133 #define _(a) u8 a=0;
8134   foreach_ip6_proto_field;
8135 #undef _
8136   u8 version = 0;
8137   u8 traffic_class = 0;
8138   u8 flow_label = 0;
8139
8140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8141     {
8142       if (unformat (input, "version"))
8143         version = 1;
8144       else if (unformat (input, "traffic-class"))
8145         traffic_class = 1;
8146       else if (unformat (input, "flow-label"))
8147         flow_label = 1;
8148       else if (unformat (input, "src"))
8149         src_address = 1;
8150       else if (unformat (input, "dst"))
8151         dst_address = 1;
8152       else if (unformat (input, "proto"))
8153         protocol = 1;
8154
8155 #define _(a) else if (unformat (input, #a)) a=1;
8156       foreach_ip6_proto_field
8157 #undef _
8158         else
8159         break;
8160     }
8161
8162 #define _(a) found_something += a;
8163   foreach_ip6_proto_field;
8164 #undef _
8165
8166   if (found_something == 0)
8167     return 0;
8168
8169   vec_validate (mask, sizeof (*ip) - 1);
8170
8171   ip = (ip6_header_t *) mask;
8172
8173 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8174   foreach_ip6_proto_field;
8175 #undef _
8176
8177   ip_version_traffic_class_and_flow_label = 0;
8178
8179   if (version)
8180     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8181
8182   if (traffic_class)
8183     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8184
8185   if (flow_label)
8186     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8187
8188   ip->ip_version_traffic_class_and_flow_label =
8189     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8190
8191   *maskp = mask;
8192   return 1;
8193 }
8194
8195 uword
8196 unformat_l3_mask (unformat_input_t * input, va_list * args)
8197 {
8198   u8 **maskp = va_arg (*args, u8 **);
8199
8200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8201     {
8202       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8203         return 1;
8204       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8205         return 1;
8206       else
8207         break;
8208     }
8209   return 0;
8210 }
8211
8212 uword
8213 unformat_l2_mask (unformat_input_t * input, va_list * args)
8214 {
8215   u8 **maskp = va_arg (*args, u8 **);
8216   u8 *mask = 0;
8217   u8 src = 0;
8218   u8 dst = 0;
8219   u8 proto = 0;
8220   u8 tag1 = 0;
8221   u8 tag2 = 0;
8222   u8 ignore_tag1 = 0;
8223   u8 ignore_tag2 = 0;
8224   u8 cos1 = 0;
8225   u8 cos2 = 0;
8226   u8 dot1q = 0;
8227   u8 dot1ad = 0;
8228   int len = 14;
8229
8230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8231     {
8232       if (unformat (input, "src"))
8233         src = 1;
8234       else if (unformat (input, "dst"))
8235         dst = 1;
8236       else if (unformat (input, "proto"))
8237         proto = 1;
8238       else if (unformat (input, "tag1"))
8239         tag1 = 1;
8240       else if (unformat (input, "tag2"))
8241         tag2 = 1;
8242       else if (unformat (input, "ignore-tag1"))
8243         ignore_tag1 = 1;
8244       else if (unformat (input, "ignore-tag2"))
8245         ignore_tag2 = 1;
8246       else if (unformat (input, "cos1"))
8247         cos1 = 1;
8248       else if (unformat (input, "cos2"))
8249         cos2 = 1;
8250       else if (unformat (input, "dot1q"))
8251         dot1q = 1;
8252       else if (unformat (input, "dot1ad"))
8253         dot1ad = 1;
8254       else
8255         break;
8256     }
8257   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8258        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8259     return 0;
8260
8261   if (tag1 || ignore_tag1 || cos1 || dot1q)
8262     len = 18;
8263   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8264     len = 22;
8265
8266   vec_validate (mask, len - 1);
8267
8268   if (dst)
8269     memset (mask, 0xff, 6);
8270
8271   if (src)
8272     memset (mask + 6, 0xff, 6);
8273
8274   if (tag2 || dot1ad)
8275     {
8276       /* inner vlan tag */
8277       if (tag2)
8278         {
8279           mask[19] = 0xff;
8280           mask[18] = 0x0f;
8281         }
8282       if (cos2)
8283         mask[18] |= 0xe0;
8284       if (proto)
8285         mask[21] = mask[20] = 0xff;
8286       if (tag1)
8287         {
8288           mask[15] = 0xff;
8289           mask[14] = 0x0f;
8290         }
8291       if (cos1)
8292         mask[14] |= 0xe0;
8293       *maskp = mask;
8294       return 1;
8295     }
8296   if (tag1 | dot1q)
8297     {
8298       if (tag1)
8299         {
8300           mask[15] = 0xff;
8301           mask[14] = 0x0f;
8302         }
8303       if (cos1)
8304         mask[14] |= 0xe0;
8305       if (proto)
8306         mask[16] = mask[17] = 0xff;
8307
8308       *maskp = mask;
8309       return 1;
8310     }
8311   if (cos2)
8312     mask[18] |= 0xe0;
8313   if (cos1)
8314     mask[14] |= 0xe0;
8315   if (proto)
8316     mask[12] = mask[13] = 0xff;
8317
8318   *maskp = mask;
8319   return 1;
8320 }
8321
8322 uword
8323 unformat_classify_mask (unformat_input_t * input, va_list * args)
8324 {
8325   u8 **maskp = va_arg (*args, u8 **);
8326   u32 *skipp = va_arg (*args, u32 *);
8327   u32 *matchp = va_arg (*args, u32 *);
8328   u32 match;
8329   u8 *mask = 0;
8330   u8 *l2 = 0;
8331   u8 *l3 = 0;
8332   u8 *l4 = 0;
8333   int i;
8334
8335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8336     {
8337       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8338         ;
8339       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8340         ;
8341       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8342         ;
8343       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8344         ;
8345       else
8346         break;
8347     }
8348
8349   if (l4 && !l3)
8350     {
8351       vec_free (mask);
8352       vec_free (l2);
8353       vec_free (l4);
8354       return 0;
8355     }
8356
8357   if (mask || l2 || l3 || l4)
8358     {
8359       if (l2 || l3 || l4)
8360         {
8361           /* "With a free Ethernet header in every package" */
8362           if (l2 == 0)
8363             vec_validate (l2, 13);
8364           mask = l2;
8365           if (vec_len (l3))
8366             {
8367               vec_append (mask, l3);
8368               vec_free (l3);
8369             }
8370           if (vec_len (l4))
8371             {
8372               vec_append (mask, l4);
8373               vec_free (l4);
8374             }
8375         }
8376
8377       /* Scan forward looking for the first significant mask octet */
8378       for (i = 0; i < vec_len (mask); i++)
8379         if (mask[i])
8380           break;
8381
8382       /* compute (skip, match) params */
8383       *skipp = i / sizeof (u32x4);
8384       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8385
8386       /* Pad mask to an even multiple of the vector size */
8387       while (vec_len (mask) % sizeof (u32x4))
8388         vec_add1 (mask, 0);
8389
8390       match = vec_len (mask) / sizeof (u32x4);
8391
8392       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8393         {
8394           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8395           if (*tmp || *(tmp + 1))
8396             break;
8397           match--;
8398         }
8399       if (match == 0)
8400         clib_warning ("BUG: match 0");
8401
8402       _vec_len (mask) = match * sizeof (u32x4);
8403
8404       *matchp = match;
8405       *maskp = mask;
8406
8407       return 1;
8408     }
8409
8410   return 0;
8411 }
8412
8413 #define foreach_l2_next                         \
8414 _(drop, DROP)                                   \
8415 _(ethernet, ETHERNET_INPUT)                     \
8416 _(ip4, IP4_INPUT)                               \
8417 _(ip6, IP6_INPUT)
8418
8419 uword
8420 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8421 {
8422   u32 *miss_next_indexp = va_arg (*args, u32 *);
8423   u32 next_index = 0;
8424   u32 tmp;
8425
8426 #define _(n,N) \
8427   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8428   foreach_l2_next;
8429 #undef _
8430
8431   if (unformat (input, "%d", &tmp))
8432     {
8433       next_index = tmp;
8434       goto out;
8435     }
8436
8437   return 0;
8438
8439 out:
8440   *miss_next_indexp = next_index;
8441   return 1;
8442 }
8443
8444 #define foreach_ip_next                         \
8445 _(drop, DROP)                                   \
8446 _(local, LOCAL)                                 \
8447 _(rewrite, REWRITE)
8448
8449 uword
8450 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8451 {
8452   u32 *miss_next_indexp = va_arg (*args, u32 *);
8453   u32 next_index = 0;
8454   u32 tmp;
8455
8456 #define _(n,N) \
8457   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8458   foreach_ip_next;
8459 #undef _
8460
8461   if (unformat (input, "%d", &tmp))
8462     {
8463       next_index = tmp;
8464       goto out;
8465     }
8466
8467   return 0;
8468
8469 out:
8470   *miss_next_indexp = next_index;
8471   return 1;
8472 }
8473
8474 #define foreach_acl_next                        \
8475 _(deny, DENY)
8476
8477 uword
8478 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8479 {
8480   u32 *miss_next_indexp = va_arg (*args, u32 *);
8481   u32 next_index = 0;
8482   u32 tmp;
8483
8484 #define _(n,N) \
8485   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8486   foreach_acl_next;
8487 #undef _
8488
8489   if (unformat (input, "permit"))
8490     {
8491       next_index = ~0;
8492       goto out;
8493     }
8494   else if (unformat (input, "%d", &tmp))
8495     {
8496       next_index = tmp;
8497       goto out;
8498     }
8499
8500   return 0;
8501
8502 out:
8503   *miss_next_indexp = next_index;
8504   return 1;
8505 }
8506
8507 uword
8508 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8509 {
8510   u32 *r = va_arg (*args, u32 *);
8511
8512   if (unformat (input, "conform-color"))
8513     *r = POLICE_CONFORM;
8514   else if (unformat (input, "exceed-color"))
8515     *r = POLICE_EXCEED;
8516   else
8517     return 0;
8518
8519   return 1;
8520 }
8521
8522 static int
8523 api_classify_add_del_table (vat_main_t * vam)
8524 {
8525   unformat_input_t *i = vam->input;
8526   vl_api_classify_add_del_table_t *mp;
8527
8528   u32 nbuckets = 2;
8529   u32 skip = ~0;
8530   u32 match = ~0;
8531   int is_add = 1;
8532   u32 table_index = ~0;
8533   u32 next_table_index = ~0;
8534   u32 miss_next_index = ~0;
8535   u32 memory_size = 32 << 20;
8536   u8 *mask = 0;
8537   f64 timeout;
8538
8539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8540     {
8541       if (unformat (i, "del"))
8542         is_add = 0;
8543       else if (unformat (i, "buckets %d", &nbuckets))
8544         ;
8545       else if (unformat (i, "memory_size %d", &memory_size))
8546         ;
8547       else if (unformat (i, "skip %d", &skip))
8548         ;
8549       else if (unformat (i, "match %d", &match))
8550         ;
8551       else if (unformat (i, "table %d", &table_index))
8552         ;
8553       else if (unformat (i, "mask %U", unformat_classify_mask,
8554                          &mask, &skip, &match))
8555         ;
8556       else if (unformat (i, "next-table %d", &next_table_index))
8557         ;
8558       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8559                          &miss_next_index))
8560         ;
8561       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8562                          &miss_next_index))
8563         ;
8564       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8565                          &miss_next_index))
8566         ;
8567       else
8568         break;
8569     }
8570
8571   if (is_add && mask == 0)
8572     {
8573       errmsg ("Mask required\n");
8574       return -99;
8575     }
8576
8577   if (is_add && skip == ~0)
8578     {
8579       errmsg ("skip count required\n");
8580       return -99;
8581     }
8582
8583   if (is_add && match == ~0)
8584     {
8585       errmsg ("match count required\n");
8586       return -99;
8587     }
8588
8589   if (!is_add && table_index == ~0)
8590     {
8591       errmsg ("table index required for delete\n");
8592       return -99;
8593     }
8594
8595   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8596
8597   mp->is_add = is_add;
8598   mp->table_index = ntohl (table_index);
8599   mp->nbuckets = ntohl (nbuckets);
8600   mp->memory_size = ntohl (memory_size);
8601   mp->skip_n_vectors = ntohl (skip);
8602   mp->match_n_vectors = ntohl (match);
8603   mp->next_table_index = ntohl (next_table_index);
8604   mp->miss_next_index = ntohl (miss_next_index);
8605   clib_memcpy (mp->mask, mask, vec_len (mask));
8606
8607   vec_free (mask);
8608
8609   S;
8610   W;
8611   /* NOTREACHED */
8612 }
8613
8614 uword
8615 unformat_l4_match (unformat_input_t * input, va_list * args)
8616 {
8617   u8 **matchp = va_arg (*args, u8 **);
8618
8619   u8 *proto_header = 0;
8620   int src_port = 0;
8621   int dst_port = 0;
8622
8623   tcpudp_header_t h;
8624
8625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8626     {
8627       if (unformat (input, "src_port %d", &src_port))
8628         ;
8629       else if (unformat (input, "dst_port %d", &dst_port))
8630         ;
8631       else
8632         return 0;
8633     }
8634
8635   h.src_port = clib_host_to_net_u16 (src_port);
8636   h.dst_port = clib_host_to_net_u16 (dst_port);
8637   vec_validate (proto_header, sizeof (h) - 1);
8638   memcpy (proto_header, &h, sizeof (h));
8639
8640   *matchp = proto_header;
8641
8642   return 1;
8643 }
8644
8645 uword
8646 unformat_ip4_match (unformat_input_t * input, va_list * args)
8647 {
8648   u8 **matchp = va_arg (*args, u8 **);
8649   u8 *match = 0;
8650   ip4_header_t *ip;
8651   int version = 0;
8652   u32 version_val;
8653   int hdr_length = 0;
8654   u32 hdr_length_val;
8655   int src = 0, dst = 0;
8656   ip4_address_t src_val, dst_val;
8657   int proto = 0;
8658   u32 proto_val;
8659   int tos = 0;
8660   u32 tos_val;
8661   int length = 0;
8662   u32 length_val;
8663   int fragment_id = 0;
8664   u32 fragment_id_val;
8665   int ttl = 0;
8666   int ttl_val;
8667   int checksum = 0;
8668   u32 checksum_val;
8669
8670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8671     {
8672       if (unformat (input, "version %d", &version_val))
8673         version = 1;
8674       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8675         hdr_length = 1;
8676       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8677         src = 1;
8678       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8679         dst = 1;
8680       else if (unformat (input, "proto %d", &proto_val))
8681         proto = 1;
8682       else if (unformat (input, "tos %d", &tos_val))
8683         tos = 1;
8684       else if (unformat (input, "length %d", &length_val))
8685         length = 1;
8686       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8687         fragment_id = 1;
8688       else if (unformat (input, "ttl %d", &ttl_val))
8689         ttl = 1;
8690       else if (unformat (input, "checksum %d", &checksum_val))
8691         checksum = 1;
8692       else
8693         break;
8694     }
8695
8696   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8697       + ttl + checksum == 0)
8698     return 0;
8699
8700   /*
8701    * Aligned because we use the real comparison functions
8702    */
8703   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8704
8705   ip = (ip4_header_t *) match;
8706
8707   /* These are realistically matched in practice */
8708   if (src)
8709     ip->src_address.as_u32 = src_val.as_u32;
8710
8711   if (dst)
8712     ip->dst_address.as_u32 = dst_val.as_u32;
8713
8714   if (proto)
8715     ip->protocol = proto_val;
8716
8717
8718   /* These are not, but they're included for completeness */
8719   if (version)
8720     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8721
8722   if (hdr_length)
8723     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8724
8725   if (tos)
8726     ip->tos = tos_val;
8727
8728   if (length)
8729     ip->length = clib_host_to_net_u16 (length_val);
8730
8731   if (ttl)
8732     ip->ttl = ttl_val;
8733
8734   if (checksum)
8735     ip->checksum = clib_host_to_net_u16 (checksum_val);
8736
8737   *matchp = match;
8738   return 1;
8739 }
8740
8741 uword
8742 unformat_ip6_match (unformat_input_t * input, va_list * args)
8743 {
8744   u8 **matchp = va_arg (*args, u8 **);
8745   u8 *match = 0;
8746   ip6_header_t *ip;
8747   int version = 0;
8748   u32 version_val;
8749   u8 traffic_class = 0;
8750   u32 traffic_class_val = 0;
8751   u8 flow_label = 0;
8752   u8 flow_label_val;
8753   int src = 0, dst = 0;
8754   ip6_address_t src_val, dst_val;
8755   int proto = 0;
8756   u32 proto_val;
8757   int payload_length = 0;
8758   u32 payload_length_val;
8759   int hop_limit = 0;
8760   int hop_limit_val;
8761   u32 ip_version_traffic_class_and_flow_label;
8762
8763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8764     {
8765       if (unformat (input, "version %d", &version_val))
8766         version = 1;
8767       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8768         traffic_class = 1;
8769       else if (unformat (input, "flow_label %d", &flow_label_val))
8770         flow_label = 1;
8771       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8772         src = 1;
8773       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8774         dst = 1;
8775       else if (unformat (input, "proto %d", &proto_val))
8776         proto = 1;
8777       else if (unformat (input, "payload_length %d", &payload_length_val))
8778         payload_length = 1;
8779       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8780         hop_limit = 1;
8781       else
8782         break;
8783     }
8784
8785   if (version + traffic_class + flow_label + src + dst + proto +
8786       payload_length + hop_limit == 0)
8787     return 0;
8788
8789   /*
8790    * Aligned because we use the real comparison functions
8791    */
8792   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8793
8794   ip = (ip6_header_t *) match;
8795
8796   if (src)
8797     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8798
8799   if (dst)
8800     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8801
8802   if (proto)
8803     ip->protocol = proto_val;
8804
8805   ip_version_traffic_class_and_flow_label = 0;
8806
8807   if (version)
8808     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8809
8810   if (traffic_class)
8811     ip_version_traffic_class_and_flow_label |=
8812       (traffic_class_val & 0xFF) << 20;
8813
8814   if (flow_label)
8815     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8816
8817   ip->ip_version_traffic_class_and_flow_label =
8818     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8819
8820   if (payload_length)
8821     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8822
8823   if (hop_limit)
8824     ip->hop_limit = hop_limit_val;
8825
8826   *matchp = match;
8827   return 1;
8828 }
8829
8830 uword
8831 unformat_l3_match (unformat_input_t * input, va_list * args)
8832 {
8833   u8 **matchp = va_arg (*args, u8 **);
8834
8835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8836     {
8837       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8838         return 1;
8839       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8840         return 1;
8841       else
8842         break;
8843     }
8844   return 0;
8845 }
8846
8847 uword
8848 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8849 {
8850   u8 *tagp = va_arg (*args, u8 *);
8851   u32 tag;
8852
8853   if (unformat (input, "%d", &tag))
8854     {
8855       tagp[0] = (tag >> 8) & 0x0F;
8856       tagp[1] = tag & 0xFF;
8857       return 1;
8858     }
8859
8860   return 0;
8861 }
8862
8863 uword
8864 unformat_l2_match (unformat_input_t * input, va_list * args)
8865 {
8866   u8 **matchp = va_arg (*args, u8 **);
8867   u8 *match = 0;
8868   u8 src = 0;
8869   u8 src_val[6];
8870   u8 dst = 0;
8871   u8 dst_val[6];
8872   u8 proto = 0;
8873   u16 proto_val;
8874   u8 tag1 = 0;
8875   u8 tag1_val[2];
8876   u8 tag2 = 0;
8877   u8 tag2_val[2];
8878   int len = 14;
8879   u8 ignore_tag1 = 0;
8880   u8 ignore_tag2 = 0;
8881   u8 cos1 = 0;
8882   u8 cos2 = 0;
8883   u32 cos1_val = 0;
8884   u32 cos2_val = 0;
8885
8886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8887     {
8888       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8889         src = 1;
8890       else
8891         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8892         dst = 1;
8893       else if (unformat (input, "proto %U",
8894                          unformat_ethernet_type_host_byte_order, &proto_val))
8895         proto = 1;
8896       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8897         tag1 = 1;
8898       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8899         tag2 = 1;
8900       else if (unformat (input, "ignore-tag1"))
8901         ignore_tag1 = 1;
8902       else if (unformat (input, "ignore-tag2"))
8903         ignore_tag2 = 1;
8904       else if (unformat (input, "cos1 %d", &cos1_val))
8905         cos1 = 1;
8906       else if (unformat (input, "cos2 %d", &cos2_val))
8907         cos2 = 1;
8908       else
8909         break;
8910     }
8911   if ((src + dst + proto + tag1 + tag2 +
8912        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8913     return 0;
8914
8915   if (tag1 || ignore_tag1 || cos1)
8916     len = 18;
8917   if (tag2 || ignore_tag2 || cos2)
8918     len = 22;
8919
8920   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8921
8922   if (dst)
8923     clib_memcpy (match, dst_val, 6);
8924
8925   if (src)
8926     clib_memcpy (match + 6, src_val, 6);
8927
8928   if (tag2)
8929     {
8930       /* inner vlan tag */
8931       match[19] = tag2_val[1];
8932       match[18] = tag2_val[0];
8933       if (cos2)
8934         match[18] |= (cos2_val & 0x7) << 5;
8935       if (proto)
8936         {
8937           match[21] = proto_val & 0xff;
8938           match[20] = proto_val >> 8;
8939         }
8940       if (tag1)
8941         {
8942           match[15] = tag1_val[1];
8943           match[14] = tag1_val[0];
8944         }
8945       if (cos1)
8946         match[14] |= (cos1_val & 0x7) << 5;
8947       *matchp = match;
8948       return 1;
8949     }
8950   if (tag1)
8951     {
8952       match[15] = tag1_val[1];
8953       match[14] = tag1_val[0];
8954       if (proto)
8955         {
8956           match[17] = proto_val & 0xff;
8957           match[16] = proto_val >> 8;
8958         }
8959       if (cos1)
8960         match[14] |= (cos1_val & 0x7) << 5;
8961
8962       *matchp = match;
8963       return 1;
8964     }
8965   if (cos2)
8966     match[18] |= (cos2_val & 0x7) << 5;
8967   if (cos1)
8968     match[14] |= (cos1_val & 0x7) << 5;
8969   if (proto)
8970     {
8971       match[13] = proto_val & 0xff;
8972       match[12] = proto_val >> 8;
8973     }
8974
8975   *matchp = match;
8976   return 1;
8977 }
8978
8979
8980 uword
8981 unformat_classify_match (unformat_input_t * input, va_list * args)
8982 {
8983   u8 **matchp = va_arg (*args, u8 **);
8984   u32 skip_n_vectors = va_arg (*args, u32);
8985   u32 match_n_vectors = va_arg (*args, u32);
8986
8987   u8 *match = 0;
8988   u8 *l2 = 0;
8989   u8 *l3 = 0;
8990   u8 *l4 = 0;
8991
8992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8993     {
8994       if (unformat (input, "hex %U", unformat_hex_string, &match))
8995         ;
8996       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8997         ;
8998       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8999         ;
9000       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9001         ;
9002       else
9003         break;
9004     }
9005
9006   if (l4 && !l3)
9007     {
9008       vec_free (match);
9009       vec_free (l2);
9010       vec_free (l4);
9011       return 0;
9012     }
9013
9014   if (match || l2 || l3 || l4)
9015     {
9016       if (l2 || l3 || l4)
9017         {
9018           /* "Win a free Ethernet header in every packet" */
9019           if (l2 == 0)
9020             vec_validate_aligned (l2, 13, sizeof (u32x4));
9021           match = l2;
9022           if (vec_len (l3))
9023             {
9024               vec_append_aligned (match, l3, sizeof (u32x4));
9025               vec_free (l3);
9026             }
9027           if (vec_len (l4))
9028             {
9029               vec_append_aligned (match, l4, sizeof (u32x4));
9030               vec_free (l4);
9031             }
9032         }
9033
9034       /* Make sure the vector is big enough even if key is all 0's */
9035       vec_validate_aligned
9036         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9037          sizeof (u32x4));
9038
9039       /* Set size, include skipped vectors */
9040       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9041
9042       *matchp = match;
9043
9044       return 1;
9045     }
9046
9047   return 0;
9048 }
9049
9050 static int
9051 api_classify_add_del_session (vat_main_t * vam)
9052 {
9053   unformat_input_t *i = vam->input;
9054   vl_api_classify_add_del_session_t *mp;
9055   int is_add = 1;
9056   u32 table_index = ~0;
9057   u32 hit_next_index = ~0;
9058   u32 opaque_index = ~0;
9059   u8 *match = 0;
9060   i32 advance = 0;
9061   f64 timeout;
9062   u32 skip_n_vectors = 0;
9063   u32 match_n_vectors = 0;
9064
9065   /*
9066    * Warning: you have to supply skip_n and match_n
9067    * because the API client cant simply look at the classify
9068    * table object.
9069    */
9070
9071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9072     {
9073       if (unformat (i, "del"))
9074         is_add = 0;
9075       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9076                          &hit_next_index))
9077         ;
9078       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9079                          &hit_next_index))
9080         ;
9081       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9082                          &hit_next_index))
9083         ;
9084       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9085         ;
9086       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9087         ;
9088       else if (unformat (i, "opaque-index %d", &opaque_index))
9089         ;
9090       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9091         ;
9092       else if (unformat (i, "match_n %d", &match_n_vectors))
9093         ;
9094       else if (unformat (i, "match %U", unformat_classify_match,
9095                          &match, skip_n_vectors, match_n_vectors))
9096         ;
9097       else if (unformat (i, "advance %d", &advance))
9098         ;
9099       else if (unformat (i, "table-index %d", &table_index))
9100         ;
9101       else
9102         break;
9103     }
9104
9105   if (table_index == ~0)
9106     {
9107       errmsg ("Table index required\n");
9108       return -99;
9109     }
9110
9111   if (is_add && match == 0)
9112     {
9113       errmsg ("Match value required\n");
9114       return -99;
9115     }
9116
9117   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9118
9119   mp->is_add = is_add;
9120   mp->table_index = ntohl (table_index);
9121   mp->hit_next_index = ntohl (hit_next_index);
9122   mp->opaque_index = ntohl (opaque_index);
9123   mp->advance = ntohl (advance);
9124   clib_memcpy (mp->match, match, vec_len (match));
9125   vec_free (match);
9126
9127   S;
9128   W;
9129   /* NOTREACHED */
9130 }
9131
9132 static int
9133 api_classify_set_interface_ip_table (vat_main_t * vam)
9134 {
9135   unformat_input_t *i = vam->input;
9136   vl_api_classify_set_interface_ip_table_t *mp;
9137   f64 timeout;
9138   u32 sw_if_index;
9139   int sw_if_index_set;
9140   u32 table_index = ~0;
9141   u8 is_ipv6 = 0;
9142
9143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9144     {
9145       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9146         sw_if_index_set = 1;
9147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9148         sw_if_index_set = 1;
9149       else if (unformat (i, "table %d", &table_index))
9150         ;
9151       else
9152         {
9153           clib_warning ("parse error '%U'", format_unformat_error, i);
9154           return -99;
9155         }
9156     }
9157
9158   if (sw_if_index_set == 0)
9159     {
9160       errmsg ("missing interface name or sw_if_index\n");
9161       return -99;
9162     }
9163
9164
9165   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9166
9167   mp->sw_if_index = ntohl (sw_if_index);
9168   mp->table_index = ntohl (table_index);
9169   mp->is_ipv6 = is_ipv6;
9170
9171   S;
9172   W;
9173   /* NOTREACHED */
9174   return 0;
9175 }
9176
9177 static int
9178 api_classify_set_interface_l2_tables (vat_main_t * vam)
9179 {
9180   unformat_input_t *i = vam->input;
9181   vl_api_classify_set_interface_l2_tables_t *mp;
9182   f64 timeout;
9183   u32 sw_if_index;
9184   int sw_if_index_set;
9185   u32 ip4_table_index = ~0;
9186   u32 ip6_table_index = ~0;
9187   u32 other_table_index = ~0;
9188   u32 is_input = 1;
9189
9190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9191     {
9192       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9193         sw_if_index_set = 1;
9194       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9195         sw_if_index_set = 1;
9196       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9197         ;
9198       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9199         ;
9200       else if (unformat (i, "other-table %d", &other_table_index))
9201         ;
9202       else if (unformat (i, "is-input %d", &is_input))
9203         ;
9204       else
9205         {
9206           clib_warning ("parse error '%U'", format_unformat_error, i);
9207           return -99;
9208         }
9209     }
9210
9211   if (sw_if_index_set == 0)
9212     {
9213       errmsg ("missing interface name or sw_if_index\n");
9214       return -99;
9215     }
9216
9217
9218   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9219
9220   mp->sw_if_index = ntohl (sw_if_index);
9221   mp->ip4_table_index = ntohl (ip4_table_index);
9222   mp->ip6_table_index = ntohl (ip6_table_index);
9223   mp->other_table_index = ntohl (other_table_index);
9224   mp->is_input = (u8) is_input;
9225
9226   S;
9227   W;
9228   /* NOTREACHED */
9229   return 0;
9230 }
9231
9232 static int
9233 api_set_ipfix_exporter (vat_main_t * vam)
9234 {
9235   unformat_input_t *i = vam->input;
9236   vl_api_set_ipfix_exporter_t *mp;
9237   ip4_address_t collector_address;
9238   u8 collector_address_set = 0;
9239   u32 collector_port = ~0;
9240   ip4_address_t src_address;
9241   u8 src_address_set = 0;
9242   u32 vrf_id = ~0;
9243   u32 path_mtu = ~0;
9244   u32 template_interval = ~0;
9245   u8 udp_checksum = 0;
9246   f64 timeout;
9247
9248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9249     {
9250       if (unformat (i, "collector_address %U", unformat_ip4_address,
9251                     &collector_address))
9252         collector_address_set = 1;
9253       else if (unformat (i, "collector_port %d", &collector_port))
9254         ;
9255       else if (unformat (i, "src_address %U", unformat_ip4_address,
9256                          &src_address))
9257         src_address_set = 1;
9258       else if (unformat (i, "vrf_id %d", &vrf_id))
9259         ;
9260       else if (unformat (i, "path_mtu %d", &path_mtu))
9261         ;
9262       else if (unformat (i, "template_interval %d", &template_interval))
9263         ;
9264       else if (unformat (i, "udp_checksum"))
9265         udp_checksum = 1;
9266       else
9267         break;
9268     }
9269
9270   if (collector_address_set == 0)
9271     {
9272       errmsg ("collector_address required\n");
9273       return -99;
9274     }
9275
9276   if (src_address_set == 0)
9277     {
9278       errmsg ("src_address required\n");
9279       return -99;
9280     }
9281
9282   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9283
9284   memcpy (mp->collector_address, collector_address.data,
9285           sizeof (collector_address.data));
9286   mp->collector_port = htons ((u16) collector_port);
9287   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9288   mp->vrf_id = htonl (vrf_id);
9289   mp->path_mtu = htonl (path_mtu);
9290   mp->template_interval = htonl (template_interval);
9291   mp->udp_checksum = udp_checksum;
9292
9293   S;
9294   W;
9295   /* NOTREACHED */
9296 }
9297
9298 static int
9299 api_set_ipfix_classify_stream (vat_main_t * vam)
9300 {
9301   unformat_input_t *i = vam->input;
9302   vl_api_set_ipfix_classify_stream_t *mp;
9303   u32 domain_id = 0;
9304   u32 src_port = UDP_DST_PORT_ipfix;
9305   f64 timeout;
9306
9307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9308     {
9309       if (unformat (i, "domain %d", &domain_id))
9310         ;
9311       else if (unformat (i, "src_port %d", &src_port))
9312         ;
9313       else
9314         {
9315           errmsg ("unknown input `%U'", format_unformat_error, i);
9316           return -99;
9317         }
9318     }
9319
9320   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9321
9322   mp->domain_id = htonl (domain_id);
9323   mp->src_port = htons ((u16) src_port);
9324
9325   S;
9326   W;
9327   /* NOTREACHED */
9328 }
9329
9330 static int
9331 api_ipfix_classify_table_add_del (vat_main_t * vam)
9332 {
9333   unformat_input_t *i = vam->input;
9334   vl_api_ipfix_classify_table_add_del_t *mp;
9335   int is_add = -1;
9336   u32 classify_table_index = ~0;
9337   u8 ip_version = 0;
9338   u8 transport_protocol = 255;
9339   f64 timeout;
9340
9341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9342     {
9343       if (unformat (i, "add"))
9344         is_add = 1;
9345       else if (unformat (i, "del"))
9346         is_add = 0;
9347       else if (unformat (i, "table %d", &classify_table_index))
9348         ;
9349       else if (unformat (i, "ip4"))
9350         ip_version = 4;
9351       else if (unformat (i, "ip6"))
9352         ip_version = 6;
9353       else if (unformat (i, "tcp"))
9354         transport_protocol = 6;
9355       else if (unformat (i, "udp"))
9356         transport_protocol = 17;
9357       else
9358         {
9359           errmsg ("unknown input `%U'", format_unformat_error, i);
9360           return -99;
9361         }
9362     }
9363
9364   if (is_add == -1)
9365     {
9366       errmsg ("expecting: add|del");
9367       return -99;
9368     }
9369   if (classify_table_index == ~0)
9370     {
9371       errmsg ("classifier table not specified");
9372       return -99;
9373     }
9374   if (ip_version == 0)
9375     {
9376       errmsg ("IP version not specified");
9377       return -99;
9378     }
9379
9380   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9381
9382   mp->is_add = is_add;
9383   mp->table_id = htonl (classify_table_index);
9384   mp->ip_version = ip_version;
9385   mp->transport_protocol = transport_protocol;
9386
9387   S;
9388   W;
9389   /* NOTREACHED */
9390 }
9391
9392 static int
9393 api_get_node_index (vat_main_t * vam)
9394 {
9395   unformat_input_t *i = vam->input;
9396   vl_api_get_node_index_t *mp;
9397   f64 timeout;
9398   u8 *name = 0;
9399
9400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9401     {
9402       if (unformat (i, "node %s", &name))
9403         ;
9404       else
9405         break;
9406     }
9407   if (name == 0)
9408     {
9409       errmsg ("node name required\n");
9410       return -99;
9411     }
9412   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9413     {
9414       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9415       return -99;
9416     }
9417
9418   M (GET_NODE_INDEX, get_node_index);
9419   clib_memcpy (mp->node_name, name, vec_len (name));
9420   vec_free (name);
9421
9422   S;
9423   W;
9424   /* NOTREACHED */
9425   return 0;
9426 }
9427
9428 static int
9429 api_get_next_index (vat_main_t * vam)
9430 {
9431   unformat_input_t *i = vam->input;
9432   vl_api_get_next_index_t *mp;
9433   f64 timeout;
9434   u8 *node_name = 0, *next_node_name = 0;
9435
9436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9437     {
9438       if (unformat (i, "node-name %s", &node_name))
9439         ;
9440       else if (unformat (i, "next-node-name %s", &next_node_name))
9441         break;
9442     }
9443
9444   if (node_name == 0)
9445     {
9446       errmsg ("node name required\n");
9447       return -99;
9448     }
9449   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9450     {
9451       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9452       return -99;
9453     }
9454
9455   if (next_node_name == 0)
9456     {
9457       errmsg ("next node name required\n");
9458       return -99;
9459     }
9460   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9461     {
9462       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9463       return -99;
9464     }
9465
9466   M (GET_NEXT_INDEX, get_next_index);
9467   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9468   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9469   vec_free (node_name);
9470   vec_free (next_node_name);
9471
9472   S;
9473   W;
9474   /* NOTREACHED */
9475   return 0;
9476 }
9477
9478 static int
9479 api_add_node_next (vat_main_t * vam)
9480 {
9481   unformat_input_t *i = vam->input;
9482   vl_api_add_node_next_t *mp;
9483   f64 timeout;
9484   u8 *name = 0;
9485   u8 *next = 0;
9486
9487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9488     {
9489       if (unformat (i, "node %s", &name))
9490         ;
9491       else if (unformat (i, "next %s", &next))
9492         ;
9493       else
9494         break;
9495     }
9496   if (name == 0)
9497     {
9498       errmsg ("node name required\n");
9499       return -99;
9500     }
9501   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9502     {
9503       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9504       return -99;
9505     }
9506   if (next == 0)
9507     {
9508       errmsg ("next node required\n");
9509       return -99;
9510     }
9511   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9512     {
9513       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9514       return -99;
9515     }
9516
9517   M (ADD_NODE_NEXT, add_node_next);
9518   clib_memcpy (mp->node_name, name, vec_len (name));
9519   clib_memcpy (mp->next_name, next, vec_len (next));
9520   vec_free (name);
9521   vec_free (next);
9522
9523   S;
9524   W;
9525   /* NOTREACHED */
9526   return 0;
9527 }
9528
9529 static int
9530 api_l2tpv3_create_tunnel (vat_main_t * vam)
9531 {
9532   unformat_input_t *i = vam->input;
9533   ip6_address_t client_address, our_address;
9534   int client_address_set = 0;
9535   int our_address_set = 0;
9536   u32 local_session_id = 0;
9537   u32 remote_session_id = 0;
9538   u64 local_cookie = 0;
9539   u64 remote_cookie = 0;
9540   u8 l2_sublayer_present = 0;
9541   vl_api_l2tpv3_create_tunnel_t *mp;
9542   f64 timeout;
9543
9544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9545     {
9546       if (unformat (i, "client_address %U", unformat_ip6_address,
9547                     &client_address))
9548         client_address_set = 1;
9549       else if (unformat (i, "our_address %U", unformat_ip6_address,
9550                          &our_address))
9551         our_address_set = 1;
9552       else if (unformat (i, "local_session_id %d", &local_session_id))
9553         ;
9554       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9555         ;
9556       else if (unformat (i, "local_cookie %lld", &local_cookie))
9557         ;
9558       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9559         ;
9560       else if (unformat (i, "l2-sublayer-present"))
9561         l2_sublayer_present = 1;
9562       else
9563         break;
9564     }
9565
9566   if (client_address_set == 0)
9567     {
9568       errmsg ("client_address required\n");
9569       return -99;
9570     }
9571
9572   if (our_address_set == 0)
9573     {
9574       errmsg ("our_address required\n");
9575       return -99;
9576     }
9577
9578   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9579
9580   clib_memcpy (mp->client_address, client_address.as_u8,
9581                sizeof (mp->client_address));
9582
9583   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9584
9585   mp->local_session_id = ntohl (local_session_id);
9586   mp->remote_session_id = ntohl (remote_session_id);
9587   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9588   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9589   mp->l2_sublayer_present = l2_sublayer_present;
9590   mp->is_ipv6 = 1;
9591
9592   S;
9593   W;
9594   /* NOTREACHED */
9595   return 0;
9596 }
9597
9598 static int
9599 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9600 {
9601   unformat_input_t *i = vam->input;
9602   u32 sw_if_index;
9603   u8 sw_if_index_set = 0;
9604   u64 new_local_cookie = 0;
9605   u64 new_remote_cookie = 0;
9606   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9607   f64 timeout;
9608
9609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9610     {
9611       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9612         sw_if_index_set = 1;
9613       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9614         sw_if_index_set = 1;
9615       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9616         ;
9617       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9618         ;
9619       else
9620         break;
9621     }
9622
9623   if (sw_if_index_set == 0)
9624     {
9625       errmsg ("missing interface name or sw_if_index\n");
9626       return -99;
9627     }
9628
9629   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9630
9631   mp->sw_if_index = ntohl (sw_if_index);
9632   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9633   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9634
9635   S;
9636   W;
9637   /* NOTREACHED */
9638   return 0;
9639 }
9640
9641 static int
9642 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9643 {
9644   unformat_input_t *i = vam->input;
9645   vl_api_l2tpv3_interface_enable_disable_t *mp;
9646   f64 timeout;
9647   u32 sw_if_index;
9648   u8 sw_if_index_set = 0;
9649   u8 enable_disable = 1;
9650
9651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9652     {
9653       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9654         sw_if_index_set = 1;
9655       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9656         sw_if_index_set = 1;
9657       else if (unformat (i, "enable"))
9658         enable_disable = 1;
9659       else if (unformat (i, "disable"))
9660         enable_disable = 0;
9661       else
9662         break;
9663     }
9664
9665   if (sw_if_index_set == 0)
9666     {
9667       errmsg ("missing interface name or sw_if_index\n");
9668       return -99;
9669     }
9670
9671   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9672
9673   mp->sw_if_index = ntohl (sw_if_index);
9674   mp->enable_disable = enable_disable;
9675
9676   S;
9677   W;
9678   /* NOTREACHED */
9679   return 0;
9680 }
9681
9682 static int
9683 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9684 {
9685   unformat_input_t *i = vam->input;
9686   vl_api_l2tpv3_set_lookup_key_t *mp;
9687   f64 timeout;
9688   u8 key = ~0;
9689
9690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9691     {
9692       if (unformat (i, "lookup_v6_src"))
9693         key = L2T_LOOKUP_SRC_ADDRESS;
9694       else if (unformat (i, "lookup_v6_dst"))
9695         key = L2T_LOOKUP_DST_ADDRESS;
9696       else if (unformat (i, "lookup_session_id"))
9697         key = L2T_LOOKUP_SESSION_ID;
9698       else
9699         break;
9700     }
9701
9702   if (key == (u8) ~ 0)
9703     {
9704       errmsg ("l2tp session lookup key unset\n");
9705       return -99;
9706     }
9707
9708   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9709
9710   mp->key = key;
9711
9712   S;
9713   W;
9714   /* NOTREACHED */
9715   return 0;
9716 }
9717
9718 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9719   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9720 {
9721   vat_main_t *vam = &vat_main;
9722
9723   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9724            format_ip6_address, mp->our_address,
9725            format_ip6_address, mp->client_address,
9726            clib_net_to_host_u32 (mp->sw_if_index));
9727
9728   fformat (vam->ofp,
9729            "   local cookies %016llx %016llx remote cookie %016llx\n",
9730            clib_net_to_host_u64 (mp->local_cookie[0]),
9731            clib_net_to_host_u64 (mp->local_cookie[1]),
9732            clib_net_to_host_u64 (mp->remote_cookie));
9733
9734   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9735            clib_net_to_host_u32 (mp->local_session_id),
9736            clib_net_to_host_u32 (mp->remote_session_id));
9737
9738   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9739            mp->l2_sublayer_present ? "preset" : "absent");
9740
9741 }
9742
9743 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9744   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9745 {
9746   vat_main_t *vam = &vat_main;
9747   vat_json_node_t *node = NULL;
9748   struct in6_addr addr;
9749
9750   if (VAT_JSON_ARRAY != vam->json_tree.type)
9751     {
9752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9753       vat_json_init_array (&vam->json_tree);
9754     }
9755   node = vat_json_array_add (&vam->json_tree);
9756
9757   vat_json_init_object (node);
9758
9759   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9760   vat_json_object_add_ip6 (node, "our_address", addr);
9761   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9762   vat_json_object_add_ip6 (node, "client_address", addr);
9763
9764   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9765   vat_json_init_array (lc);
9766   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9767   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9768   vat_json_object_add_uint (node, "remote_cookie",
9769                             clib_net_to_host_u64 (mp->remote_cookie));
9770
9771   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9772   vat_json_object_add_uint (node, "local_session_id",
9773                             clib_net_to_host_u32 (mp->local_session_id));
9774   vat_json_object_add_uint (node, "remote_session_id",
9775                             clib_net_to_host_u32 (mp->remote_session_id));
9776   vat_json_object_add_string_copy (node, "l2_sublayer",
9777                                    mp->l2_sublayer_present ? (u8 *) "present"
9778                                    : (u8 *) "absent");
9779 }
9780
9781 static int
9782 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9783 {
9784   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9785   f64 timeout;
9786
9787   /* Get list of l2tpv3-tunnel interfaces */
9788   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9789   S;
9790
9791   /* Use a control ping for synchronization */
9792   {
9793     vl_api_control_ping_t *mp;
9794     M (CONTROL_PING, control_ping);
9795     S;
9796   }
9797   W;
9798 }
9799
9800
9801 static void vl_api_sw_interface_tap_details_t_handler
9802   (vl_api_sw_interface_tap_details_t * mp)
9803 {
9804   vat_main_t *vam = &vat_main;
9805
9806   fformat (vam->ofp, "%-16s %d\n",
9807            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9808 }
9809
9810 static void vl_api_sw_interface_tap_details_t_handler_json
9811   (vl_api_sw_interface_tap_details_t * mp)
9812 {
9813   vat_main_t *vam = &vat_main;
9814   vat_json_node_t *node = NULL;
9815
9816   if (VAT_JSON_ARRAY != vam->json_tree.type)
9817     {
9818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9819       vat_json_init_array (&vam->json_tree);
9820     }
9821   node = vat_json_array_add (&vam->json_tree);
9822
9823   vat_json_init_object (node);
9824   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9825   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9826 }
9827
9828 static int
9829 api_sw_interface_tap_dump (vat_main_t * vam)
9830 {
9831   vl_api_sw_interface_tap_dump_t *mp;
9832   f64 timeout;
9833
9834   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9835   /* Get list of tap interfaces */
9836   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9837   S;
9838
9839   /* Use a control ping for synchronization */
9840   {
9841     vl_api_control_ping_t *mp;
9842     M (CONTROL_PING, control_ping);
9843     S;
9844   }
9845   W;
9846 }
9847
9848 static uword unformat_vxlan_decap_next
9849   (unformat_input_t * input, va_list * args)
9850 {
9851   u32 *result = va_arg (*args, u32 *);
9852   u32 tmp;
9853
9854   if (unformat (input, "drop"))
9855     *result = VXLAN_INPUT_NEXT_DROP;
9856   else if (unformat (input, "ip4"))
9857     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9858   else if (unformat (input, "ip6"))
9859     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9860   else if (unformat (input, "l2"))
9861     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9862   else if (unformat (input, "%d", &tmp))
9863     *result = tmp;
9864   else
9865     return 0;
9866   return 1;
9867 }
9868
9869 static int
9870 api_vxlan_add_del_tunnel (vat_main_t * vam)
9871 {
9872   unformat_input_t *line_input = vam->input;
9873   vl_api_vxlan_add_del_tunnel_t *mp;
9874   f64 timeout;
9875   ip4_address_t src4, dst4;
9876   ip6_address_t src6, dst6;
9877   u8 is_add = 1;
9878   u8 ipv4_set = 0, ipv6_set = 0;
9879   u8 src_set = 0;
9880   u8 dst_set = 0;
9881   u32 encap_vrf_id = 0;
9882   u32 decap_next_index = ~0;
9883   u32 vni = 0;
9884
9885   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9886     {
9887       if (unformat (line_input, "del"))
9888         is_add = 0;
9889       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9890         {
9891           ipv4_set = 1;
9892           src_set = 1;
9893         }
9894       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9895         {
9896           ipv4_set = 1;
9897           dst_set = 1;
9898         }
9899       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9900         {
9901           ipv6_set = 1;
9902           src_set = 1;
9903         }
9904       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9905         {
9906           ipv6_set = 1;
9907           dst_set = 1;
9908         }
9909       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9910         ;
9911       else if (unformat (line_input, "decap-next %U",
9912                          unformat_vxlan_decap_next, &decap_next_index))
9913         ;
9914       else if (unformat (line_input, "vni %d", &vni))
9915         ;
9916       else
9917         {
9918           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9919           return -99;
9920         }
9921     }
9922
9923   if (src_set == 0)
9924     {
9925       errmsg ("tunnel src address not specified\n");
9926       return -99;
9927     }
9928   if (dst_set == 0)
9929     {
9930       errmsg ("tunnel dst address not specified\n");
9931       return -99;
9932     }
9933
9934   if (ipv4_set && ipv6_set)
9935     {
9936       errmsg ("both IPv4 and IPv6 addresses specified");
9937       return -99;
9938     }
9939
9940   if ((vni == 0) || (vni >> 24))
9941     {
9942       errmsg ("vni not specified or out of range\n");
9943       return -99;
9944     }
9945
9946   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9947
9948   if (ipv6_set)
9949     {
9950       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9951       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9952     }
9953   else
9954     {
9955       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9956       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9957     }
9958   mp->encap_vrf_id = ntohl (encap_vrf_id);
9959   mp->decap_next_index = ntohl (decap_next_index);
9960   mp->vni = ntohl (vni);
9961   mp->is_add = is_add;
9962   mp->is_ipv6 = ipv6_set;
9963
9964   S;
9965   W;
9966   /* NOTREACHED */
9967   return 0;
9968 }
9969
9970 static void vl_api_vxlan_tunnel_details_t_handler
9971   (vl_api_vxlan_tunnel_details_t * mp)
9972 {
9973   vat_main_t *vam = &vat_main;
9974
9975   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9976            ntohl (mp->sw_if_index),
9977            format_ip46_address, &(mp->src_address[0]),
9978            IP46_TYPE_ANY,
9979            format_ip46_address, &(mp->dst_address[0]),
9980            IP46_TYPE_ANY,
9981            ntohl (mp->encap_vrf_id),
9982            ntohl (mp->decap_next_index), ntohl (mp->vni));
9983 }
9984
9985 static void vl_api_vxlan_tunnel_details_t_handler_json
9986   (vl_api_vxlan_tunnel_details_t * mp)
9987 {
9988   vat_main_t *vam = &vat_main;
9989   vat_json_node_t *node = NULL;
9990   struct in_addr ip4;
9991   struct in6_addr ip6;
9992
9993   if (VAT_JSON_ARRAY != vam->json_tree.type)
9994     {
9995       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9996       vat_json_init_array (&vam->json_tree);
9997     }
9998   node = vat_json_array_add (&vam->json_tree);
9999
10000   vat_json_init_object (node);
10001   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10002   if (mp->is_ipv6)
10003     {
10004       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10005       vat_json_object_add_ip6 (node, "src_address", ip6);
10006       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10007       vat_json_object_add_ip6 (node, "dst_address", ip6);
10008     }
10009   else
10010     {
10011       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10012       vat_json_object_add_ip4 (node, "src_address", ip4);
10013       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10014       vat_json_object_add_ip4 (node, "dst_address", ip4);
10015     }
10016   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10017   vat_json_object_add_uint (node, "decap_next_index",
10018                             ntohl (mp->decap_next_index));
10019   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10020   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10021 }
10022
10023 static int
10024 api_vxlan_tunnel_dump (vat_main_t * vam)
10025 {
10026   unformat_input_t *i = vam->input;
10027   vl_api_vxlan_tunnel_dump_t *mp;
10028   f64 timeout;
10029   u32 sw_if_index;
10030   u8 sw_if_index_set = 0;
10031
10032   /* Parse args required to build the message */
10033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10034     {
10035       if (unformat (i, "sw_if_index %d", &sw_if_index))
10036         sw_if_index_set = 1;
10037       else
10038         break;
10039     }
10040
10041   if (sw_if_index_set == 0)
10042     {
10043       sw_if_index = ~0;
10044     }
10045
10046   if (!vam->json_output)
10047     {
10048       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10049                "sw_if_index", "src_address", "dst_address",
10050                "encap_vrf_id", "decap_next_index", "vni");
10051     }
10052
10053   /* Get list of vxlan-tunnel interfaces */
10054   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10055
10056   mp->sw_if_index = htonl (sw_if_index);
10057
10058   S;
10059
10060   /* Use a control ping for synchronization */
10061   {
10062     vl_api_control_ping_t *mp;
10063     M (CONTROL_PING, control_ping);
10064     S;
10065   }
10066   W;
10067 }
10068
10069 static int
10070 api_gre_add_del_tunnel (vat_main_t * vam)
10071 {
10072   unformat_input_t *line_input = vam->input;
10073   vl_api_gre_add_del_tunnel_t *mp;
10074   f64 timeout;
10075   ip4_address_t src4, dst4;
10076   u8 is_add = 1;
10077   u8 teb = 0;
10078   u8 src_set = 0;
10079   u8 dst_set = 0;
10080   u32 outer_fib_id = 0;
10081
10082   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10083     {
10084       if (unformat (line_input, "del"))
10085         is_add = 0;
10086       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10087         src_set = 1;
10088       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10089         dst_set = 1;
10090       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10091         ;
10092       else if (unformat (line_input, "teb"))
10093         teb = 1;
10094       else
10095         {
10096           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10097           return -99;
10098         }
10099     }
10100
10101   if (src_set == 0)
10102     {
10103       errmsg ("tunnel src address not specified\n");
10104       return -99;
10105     }
10106   if (dst_set == 0)
10107     {
10108       errmsg ("tunnel dst address not specified\n");
10109       return -99;
10110     }
10111
10112
10113   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10114
10115   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10116   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10117   mp->outer_fib_id = ntohl (outer_fib_id);
10118   mp->is_add = is_add;
10119   mp->teb = teb;
10120
10121   S;
10122   W;
10123   /* NOTREACHED */
10124   return 0;
10125 }
10126
10127 static void vl_api_gre_tunnel_details_t_handler
10128   (vl_api_gre_tunnel_details_t * mp)
10129 {
10130   vat_main_t *vam = &vat_main;
10131
10132   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10133            ntohl (mp->sw_if_index),
10134            format_ip4_address, &mp->src_address,
10135            format_ip4_address, &mp->dst_address,
10136            mp->teb, ntohl (mp->outer_fib_id));
10137 }
10138
10139 static void vl_api_gre_tunnel_details_t_handler_json
10140   (vl_api_gre_tunnel_details_t * mp)
10141 {
10142   vat_main_t *vam = &vat_main;
10143   vat_json_node_t *node = NULL;
10144   struct in_addr ip4;
10145
10146   if (VAT_JSON_ARRAY != vam->json_tree.type)
10147     {
10148       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10149       vat_json_init_array (&vam->json_tree);
10150     }
10151   node = vat_json_array_add (&vam->json_tree);
10152
10153   vat_json_init_object (node);
10154   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10155   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10156   vat_json_object_add_ip4 (node, "src_address", ip4);
10157   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10158   vat_json_object_add_ip4 (node, "dst_address", ip4);
10159   vat_json_object_add_uint (node, "teb", mp->teb);
10160   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10161 }
10162
10163 static int
10164 api_gre_tunnel_dump (vat_main_t * vam)
10165 {
10166   unformat_input_t *i = vam->input;
10167   vl_api_gre_tunnel_dump_t *mp;
10168   f64 timeout;
10169   u32 sw_if_index;
10170   u8 sw_if_index_set = 0;
10171
10172   /* Parse args required to build the message */
10173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10174     {
10175       if (unformat (i, "sw_if_index %d", &sw_if_index))
10176         sw_if_index_set = 1;
10177       else
10178         break;
10179     }
10180
10181   if (sw_if_index_set == 0)
10182     {
10183       sw_if_index = ~0;
10184     }
10185
10186   if (!vam->json_output)
10187     {
10188       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10189                "sw_if_index", "src_address", "dst_address", "teb",
10190                "outer_fib_id");
10191     }
10192
10193   /* Get list of gre-tunnel interfaces */
10194   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10195
10196   mp->sw_if_index = htonl (sw_if_index);
10197
10198   S;
10199
10200   /* Use a control ping for synchronization */
10201   {
10202     vl_api_control_ping_t *mp;
10203     M (CONTROL_PING, control_ping);
10204     S;
10205   }
10206   W;
10207 }
10208
10209 static int
10210 api_l2_fib_clear_table (vat_main_t * vam)
10211 {
10212 //  unformat_input_t * i = vam->input;
10213   vl_api_l2_fib_clear_table_t *mp;
10214   f64 timeout;
10215
10216   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10217
10218   S;
10219   W;
10220   /* NOTREACHED */
10221   return 0;
10222 }
10223
10224 static int
10225 api_l2_interface_efp_filter (vat_main_t * vam)
10226 {
10227   unformat_input_t *i = vam->input;
10228   vl_api_l2_interface_efp_filter_t *mp;
10229   f64 timeout;
10230   u32 sw_if_index;
10231   u8 enable = 1;
10232   u8 sw_if_index_set = 0;
10233
10234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10235     {
10236       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10237         sw_if_index_set = 1;
10238       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10239         sw_if_index_set = 1;
10240       else if (unformat (i, "enable"))
10241         enable = 1;
10242       else if (unformat (i, "disable"))
10243         enable = 0;
10244       else
10245         {
10246           clib_warning ("parse error '%U'", format_unformat_error, i);
10247           return -99;
10248         }
10249     }
10250
10251   if (sw_if_index_set == 0)
10252     {
10253       errmsg ("missing sw_if_index\n");
10254       return -99;
10255     }
10256
10257   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10258
10259   mp->sw_if_index = ntohl (sw_if_index);
10260   mp->enable_disable = enable;
10261
10262   S;
10263   W;
10264   /* NOTREACHED */
10265   return 0;
10266 }
10267
10268 #define foreach_vtr_op                          \
10269 _("disable",  L2_VTR_DISABLED)                  \
10270 _("push-1",  L2_VTR_PUSH_1)                     \
10271 _("push-2",  L2_VTR_PUSH_2)                     \
10272 _("pop-1",  L2_VTR_POP_1)                       \
10273 _("pop-2",  L2_VTR_POP_2)                       \
10274 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10275 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10276 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10277 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10278
10279 static int
10280 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10281 {
10282   unformat_input_t *i = vam->input;
10283   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10284   f64 timeout;
10285   u32 sw_if_index;
10286   u8 sw_if_index_set = 0;
10287   u8 vtr_op_set = 0;
10288   u32 vtr_op = 0;
10289   u32 push_dot1q = 1;
10290   u32 tag1 = ~0;
10291   u32 tag2 = ~0;
10292
10293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10294     {
10295       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10296         sw_if_index_set = 1;
10297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10298         sw_if_index_set = 1;
10299       else if (unformat (i, "vtr_op %d", &vtr_op))
10300         vtr_op_set = 1;
10301 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10302       foreach_vtr_op
10303 #undef _
10304         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10305         ;
10306       else if (unformat (i, "tag1 %d", &tag1))
10307         ;
10308       else if (unformat (i, "tag2 %d", &tag2))
10309         ;
10310       else
10311         {
10312           clib_warning ("parse error '%U'", format_unformat_error, i);
10313           return -99;
10314         }
10315     }
10316
10317   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10318     {
10319       errmsg ("missing vtr operation or sw_if_index\n");
10320       return -99;
10321     }
10322
10323   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10324     mp->sw_if_index = ntohl (sw_if_index);
10325   mp->vtr_op = ntohl (vtr_op);
10326   mp->push_dot1q = ntohl (push_dot1q);
10327   mp->tag1 = ntohl (tag1);
10328   mp->tag2 = ntohl (tag2);
10329
10330   S;
10331   W;
10332   /* NOTREACHED */
10333   return 0;
10334 }
10335
10336 static int
10337 api_create_vhost_user_if (vat_main_t * vam)
10338 {
10339   unformat_input_t *i = vam->input;
10340   vl_api_create_vhost_user_if_t *mp;
10341   f64 timeout;
10342   u8 *file_name;
10343   u8 is_server = 0;
10344   u8 file_name_set = 0;
10345   u32 custom_dev_instance = ~0;
10346   u8 hwaddr[6];
10347   u8 use_custom_mac = 0;
10348
10349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10350     {
10351       if (unformat (i, "socket %s", &file_name))
10352         {
10353           file_name_set = 1;
10354         }
10355       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10356         ;
10357       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10358         use_custom_mac = 1;
10359       else if (unformat (i, "server"))
10360         is_server = 1;
10361       else
10362         break;
10363     }
10364
10365   if (file_name_set == 0)
10366     {
10367       errmsg ("missing socket file name\n");
10368       return -99;
10369     }
10370
10371   if (vec_len (file_name) > 255)
10372     {
10373       errmsg ("socket file name too long\n");
10374       return -99;
10375     }
10376   vec_add1 (file_name, 0);
10377
10378   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10379
10380   mp->is_server = is_server;
10381   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10382   vec_free (file_name);
10383   if (custom_dev_instance != ~0)
10384     {
10385       mp->renumber = 1;
10386       mp->custom_dev_instance = ntohl (custom_dev_instance);
10387     }
10388   mp->use_custom_mac = use_custom_mac;
10389   clib_memcpy (mp->mac_address, hwaddr, 6);
10390
10391   S;
10392   W;
10393   /* NOTREACHED */
10394   return 0;
10395 }
10396
10397 static int
10398 api_modify_vhost_user_if (vat_main_t * vam)
10399 {
10400   unformat_input_t *i = vam->input;
10401   vl_api_modify_vhost_user_if_t *mp;
10402   f64 timeout;
10403   u8 *file_name;
10404   u8 is_server = 0;
10405   u8 file_name_set = 0;
10406   u32 custom_dev_instance = ~0;
10407   u8 sw_if_index_set = 0;
10408   u32 sw_if_index = (u32) ~ 0;
10409
10410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10411     {
10412       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10413         sw_if_index_set = 1;
10414       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10415         sw_if_index_set = 1;
10416       else if (unformat (i, "socket %s", &file_name))
10417         {
10418           file_name_set = 1;
10419         }
10420       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10421         ;
10422       else if (unformat (i, "server"))
10423         is_server = 1;
10424       else
10425         break;
10426     }
10427
10428   if (sw_if_index_set == 0)
10429     {
10430       errmsg ("missing sw_if_index or interface name\n");
10431       return -99;
10432     }
10433
10434   if (file_name_set == 0)
10435     {
10436       errmsg ("missing socket file name\n");
10437       return -99;
10438     }
10439
10440   if (vec_len (file_name) > 255)
10441     {
10442       errmsg ("socket file name too long\n");
10443       return -99;
10444     }
10445   vec_add1 (file_name, 0);
10446
10447   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10448
10449   mp->sw_if_index = ntohl (sw_if_index);
10450   mp->is_server = is_server;
10451   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10452   vec_free (file_name);
10453   if (custom_dev_instance != ~0)
10454     {
10455       mp->renumber = 1;
10456       mp->custom_dev_instance = ntohl (custom_dev_instance);
10457     }
10458
10459   S;
10460   W;
10461   /* NOTREACHED */
10462   return 0;
10463 }
10464
10465 static int
10466 api_delete_vhost_user_if (vat_main_t * vam)
10467 {
10468   unformat_input_t *i = vam->input;
10469   vl_api_delete_vhost_user_if_t *mp;
10470   f64 timeout;
10471   u32 sw_if_index = ~0;
10472   u8 sw_if_index_set = 0;
10473
10474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10475     {
10476       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10477         sw_if_index_set = 1;
10478       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10479         sw_if_index_set = 1;
10480       else
10481         break;
10482     }
10483
10484   if (sw_if_index_set == 0)
10485     {
10486       errmsg ("missing sw_if_index or interface name\n");
10487       return -99;
10488     }
10489
10490
10491   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10492
10493   mp->sw_if_index = ntohl (sw_if_index);
10494
10495   S;
10496   W;
10497   /* NOTREACHED */
10498   return 0;
10499 }
10500
10501 static void vl_api_sw_interface_vhost_user_details_t_handler
10502   (vl_api_sw_interface_vhost_user_details_t * mp)
10503 {
10504   vat_main_t *vam = &vat_main;
10505
10506   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10507            (char *) mp->interface_name,
10508            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10509            clib_net_to_host_u64 (mp->features), mp->is_server,
10510            ntohl (mp->num_regions), (char *) mp->sock_filename);
10511   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10512 }
10513
10514 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10515   (vl_api_sw_interface_vhost_user_details_t * mp)
10516 {
10517   vat_main_t *vam = &vat_main;
10518   vat_json_node_t *node = NULL;
10519
10520   if (VAT_JSON_ARRAY != vam->json_tree.type)
10521     {
10522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10523       vat_json_init_array (&vam->json_tree);
10524     }
10525   node = vat_json_array_add (&vam->json_tree);
10526
10527   vat_json_init_object (node);
10528   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10529   vat_json_object_add_string_copy (node, "interface_name",
10530                                    mp->interface_name);
10531   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10532                             ntohl (mp->virtio_net_hdr_sz));
10533   vat_json_object_add_uint (node, "features",
10534                             clib_net_to_host_u64 (mp->features));
10535   vat_json_object_add_uint (node, "is_server", mp->is_server);
10536   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10537   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10538   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10539 }
10540
10541 static int
10542 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10543 {
10544   vl_api_sw_interface_vhost_user_dump_t *mp;
10545   f64 timeout;
10546   fformat (vam->ofp,
10547            "Interface name           idx hdr_sz features server regions filename\n");
10548
10549   /* Get list of vhost-user interfaces */
10550   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10551   S;
10552
10553   /* Use a control ping for synchronization */
10554   {
10555     vl_api_control_ping_t *mp;
10556     M (CONTROL_PING, control_ping);
10557     S;
10558   }
10559   W;
10560 }
10561
10562 static int
10563 api_show_version (vat_main_t * vam)
10564 {
10565   vl_api_show_version_t *mp;
10566   f64 timeout;
10567
10568   M (SHOW_VERSION, show_version);
10569
10570   S;
10571   W;
10572   /* NOTREACHED */
10573   return 0;
10574 }
10575
10576
10577 static int
10578 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10579 {
10580   unformat_input_t *line_input = vam->input;
10581   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10582   f64 timeout;
10583   ip4_address_t local4, remote4;
10584   ip6_address_t local6, remote6;
10585   u8 is_add = 1;
10586   u8 ipv4_set = 0, ipv6_set = 0;
10587   u8 local_set = 0;
10588   u8 remote_set = 0;
10589   u32 encap_vrf_id = 0;
10590   u32 decap_vrf_id = 0;
10591   u8 protocol = ~0;
10592   u32 vni;
10593   u8 vni_set = 0;
10594
10595   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10596     {
10597       if (unformat (line_input, "del"))
10598         is_add = 0;
10599       else if (unformat (line_input, "local %U",
10600                          unformat_ip4_address, &local4))
10601         {
10602           local_set = 1;
10603           ipv4_set = 1;
10604         }
10605       else if (unformat (line_input, "remote %U",
10606                          unformat_ip4_address, &remote4))
10607         {
10608           remote_set = 1;
10609           ipv4_set = 1;
10610         }
10611       else if (unformat (line_input, "local %U",
10612                          unformat_ip6_address, &local6))
10613         {
10614           local_set = 1;
10615           ipv6_set = 1;
10616         }
10617       else if (unformat (line_input, "remote %U",
10618                          unformat_ip6_address, &remote6))
10619         {
10620           remote_set = 1;
10621           ipv6_set = 1;
10622         }
10623       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10624         ;
10625       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10626         ;
10627       else if (unformat (line_input, "vni %d", &vni))
10628         vni_set = 1;
10629       else if (unformat (line_input, "next-ip4"))
10630         protocol = 1;
10631       else if (unformat (line_input, "next-ip6"))
10632         protocol = 2;
10633       else if (unformat (line_input, "next-ethernet"))
10634         protocol = 3;
10635       else if (unformat (line_input, "next-nsh"))
10636         protocol = 4;
10637       else
10638         {
10639           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10640           return -99;
10641         }
10642     }
10643
10644   if (local_set == 0)
10645     {
10646       errmsg ("tunnel local address not specified\n");
10647       return -99;
10648     }
10649   if (remote_set == 0)
10650     {
10651       errmsg ("tunnel remote address not specified\n");
10652       return -99;
10653     }
10654   if (ipv4_set && ipv6_set)
10655     {
10656       errmsg ("both IPv4 and IPv6 addresses specified");
10657       return -99;
10658     }
10659
10660   if (vni_set == 0)
10661     {
10662       errmsg ("vni not specified\n");
10663       return -99;
10664     }
10665
10666   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10667
10668
10669   if (ipv6_set)
10670     {
10671       clib_memcpy (&mp->local, &local6, sizeof (local6));
10672       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10673     }
10674   else
10675     {
10676       clib_memcpy (&mp->local, &local4, sizeof (local4));
10677       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10678     }
10679
10680   mp->encap_vrf_id = ntohl (encap_vrf_id);
10681   mp->decap_vrf_id = ntohl (decap_vrf_id);
10682   mp->protocol = ntohl (protocol);
10683   mp->vni = ntohl (vni);
10684   mp->is_add = is_add;
10685   mp->is_ipv6 = ipv6_set;
10686
10687   S;
10688   W;
10689   /* NOTREACHED */
10690   return 0;
10691 }
10692
10693 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10694   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10695 {
10696   vat_main_t *vam = &vat_main;
10697
10698   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10699            ntohl (mp->sw_if_index),
10700            format_ip46_address, &(mp->local[0]),
10701            format_ip46_address, &(mp->remote[0]),
10702            ntohl (mp->vni),
10703            ntohl (mp->protocol),
10704            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10705 }
10706
10707 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10708   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10709 {
10710   vat_main_t *vam = &vat_main;
10711   vat_json_node_t *node = NULL;
10712   struct in_addr ip4;
10713   struct in6_addr ip6;
10714
10715   if (VAT_JSON_ARRAY != vam->json_tree.type)
10716     {
10717       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10718       vat_json_init_array (&vam->json_tree);
10719     }
10720   node = vat_json_array_add (&vam->json_tree);
10721
10722   vat_json_init_object (node);
10723   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10724   if (mp->is_ipv6)
10725     {
10726       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10727       vat_json_object_add_ip6 (node, "local", ip6);
10728       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10729       vat_json_object_add_ip6 (node, "remote", ip6);
10730     }
10731   else
10732     {
10733       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10734       vat_json_object_add_ip4 (node, "local", ip4);
10735       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10736       vat_json_object_add_ip4 (node, "remote", ip4);
10737     }
10738   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10739   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10740   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10741   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10742   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10743 }
10744
10745 static int
10746 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10747 {
10748   unformat_input_t *i = vam->input;
10749   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10750   f64 timeout;
10751   u32 sw_if_index;
10752   u8 sw_if_index_set = 0;
10753
10754   /* Parse args required to build the message */
10755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10756     {
10757       if (unformat (i, "sw_if_index %d", &sw_if_index))
10758         sw_if_index_set = 1;
10759       else
10760         break;
10761     }
10762
10763   if (sw_if_index_set == 0)
10764     {
10765       sw_if_index = ~0;
10766     }
10767
10768   if (!vam->json_output)
10769     {
10770       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10771                "sw_if_index", "local", "remote", "vni",
10772                "protocol", "encap_vrf_id", "decap_vrf_id");
10773     }
10774
10775   /* Get list of vxlan-tunnel interfaces */
10776   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10777
10778   mp->sw_if_index = htonl (sw_if_index);
10779
10780   S;
10781
10782   /* Use a control ping for synchronization */
10783   {
10784     vl_api_control_ping_t *mp;
10785     M (CONTROL_PING, control_ping);
10786     S;
10787   }
10788   W;
10789 }
10790
10791 u8 *
10792 format_l2_fib_mac_address (u8 * s, va_list * args)
10793 {
10794   u8 *a = va_arg (*args, u8 *);
10795
10796   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10797                  a[2], a[3], a[4], a[5], a[6], a[7]);
10798 }
10799
10800 static void vl_api_l2_fib_table_entry_t_handler
10801   (vl_api_l2_fib_table_entry_t * mp)
10802 {
10803   vat_main_t *vam = &vat_main;
10804
10805   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10806            "       %d       %d     %d\n",
10807            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10808            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10809            mp->bvi_mac);
10810 }
10811
10812 static void vl_api_l2_fib_table_entry_t_handler_json
10813   (vl_api_l2_fib_table_entry_t * mp)
10814 {
10815   vat_main_t *vam = &vat_main;
10816   vat_json_node_t *node = NULL;
10817
10818   if (VAT_JSON_ARRAY != vam->json_tree.type)
10819     {
10820       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10821       vat_json_init_array (&vam->json_tree);
10822     }
10823   node = vat_json_array_add (&vam->json_tree);
10824
10825   vat_json_init_object (node);
10826   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10827   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10828   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10829   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10830   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10831   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10832 }
10833
10834 static int
10835 api_l2_fib_table_dump (vat_main_t * vam)
10836 {
10837   unformat_input_t *i = vam->input;
10838   vl_api_l2_fib_table_dump_t *mp;
10839   f64 timeout;
10840   u32 bd_id;
10841   u8 bd_id_set = 0;
10842
10843   /* Parse args required to build the message */
10844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10845     {
10846       if (unformat (i, "bd_id %d", &bd_id))
10847         bd_id_set = 1;
10848       else
10849         break;
10850     }
10851
10852   if (bd_id_set == 0)
10853     {
10854       errmsg ("missing bridge domain\n");
10855       return -99;
10856     }
10857
10858   fformat (vam->ofp,
10859            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10860
10861   /* Get list of l2 fib entries */
10862   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10863
10864   mp->bd_id = ntohl (bd_id);
10865   S;
10866
10867   /* Use a control ping for synchronization */
10868   {
10869     vl_api_control_ping_t *mp;
10870     M (CONTROL_PING, control_ping);
10871     S;
10872   }
10873   W;
10874 }
10875
10876
10877 static int
10878 api_interface_name_renumber (vat_main_t * vam)
10879 {
10880   unformat_input_t *line_input = vam->input;
10881   vl_api_interface_name_renumber_t *mp;
10882   u32 sw_if_index = ~0;
10883   f64 timeout;
10884   u32 new_show_dev_instance = ~0;
10885
10886   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10887     {
10888       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10889                     &sw_if_index))
10890         ;
10891       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10892         ;
10893       else if (unformat (line_input, "new_show_dev_instance %d",
10894                          &new_show_dev_instance))
10895         ;
10896       else
10897         break;
10898     }
10899
10900   if (sw_if_index == ~0)
10901     {
10902       errmsg ("missing interface name or sw_if_index\n");
10903       return -99;
10904     }
10905
10906   if (new_show_dev_instance == ~0)
10907     {
10908       errmsg ("missing new_show_dev_instance\n");
10909       return -99;
10910     }
10911
10912   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10913
10914   mp->sw_if_index = ntohl (sw_if_index);
10915   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10916
10917   S;
10918   W;
10919 }
10920
10921 static int
10922 api_want_ip4_arp_events (vat_main_t * vam)
10923 {
10924   unformat_input_t *line_input = vam->input;
10925   vl_api_want_ip4_arp_events_t *mp;
10926   f64 timeout;
10927   ip4_address_t address;
10928   int address_set = 0;
10929   u32 enable_disable = 1;
10930
10931   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10932     {
10933       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10934         address_set = 1;
10935       else if (unformat (line_input, "del"))
10936         enable_disable = 0;
10937       else
10938         break;
10939     }
10940
10941   if (address_set == 0)
10942     {
10943       errmsg ("missing addresses\n");
10944       return -99;
10945     }
10946
10947   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10948   mp->enable_disable = enable_disable;
10949   mp->pid = getpid ();
10950   mp->address = address.as_u32;
10951
10952   S;
10953   W;
10954 }
10955
10956 static int
10957 api_want_ip6_nd_events (vat_main_t * vam)
10958 {
10959   unformat_input_t *line_input = vam->input;
10960   vl_api_want_ip6_nd_events_t *mp;
10961   f64 timeout;
10962   ip6_address_t address;
10963   int address_set = 0;
10964   u32 enable_disable = 1;
10965
10966   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10967     {
10968       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10969         address_set = 1;
10970       else if (unformat (line_input, "del"))
10971         enable_disable = 0;
10972       else
10973         break;
10974     }
10975
10976   if (address_set == 0)
10977     {
10978       errmsg ("missing addresses\n");
10979       return -99;
10980     }
10981
10982   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10983   mp->enable_disable = enable_disable;
10984   mp->pid = getpid ();
10985   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10986
10987   S;
10988   W;
10989 }
10990
10991 static int
10992 api_input_acl_set_interface (vat_main_t * vam)
10993 {
10994   unformat_input_t *i = vam->input;
10995   vl_api_input_acl_set_interface_t *mp;
10996   f64 timeout;
10997   u32 sw_if_index;
10998   int sw_if_index_set;
10999   u32 ip4_table_index = ~0;
11000   u32 ip6_table_index = ~0;
11001   u32 l2_table_index = ~0;
11002   u8 is_add = 1;
11003
11004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11005     {
11006       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11007         sw_if_index_set = 1;
11008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11009         sw_if_index_set = 1;
11010       else if (unformat (i, "del"))
11011         is_add = 0;
11012       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11013         ;
11014       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11015         ;
11016       else if (unformat (i, "l2-table %d", &l2_table_index))
11017         ;
11018       else
11019         {
11020           clib_warning ("parse error '%U'", format_unformat_error, i);
11021           return -99;
11022         }
11023     }
11024
11025   if (sw_if_index_set == 0)
11026     {
11027       errmsg ("missing interface name or sw_if_index\n");
11028       return -99;
11029     }
11030
11031   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11032
11033   mp->sw_if_index = ntohl (sw_if_index);
11034   mp->ip4_table_index = ntohl (ip4_table_index);
11035   mp->ip6_table_index = ntohl (ip6_table_index);
11036   mp->l2_table_index = ntohl (l2_table_index);
11037   mp->is_add = is_add;
11038
11039   S;
11040   W;
11041   /* NOTREACHED */
11042   return 0;
11043 }
11044
11045 static int
11046 api_ip_address_dump (vat_main_t * vam)
11047 {
11048   unformat_input_t *i = vam->input;
11049   vl_api_ip_address_dump_t *mp;
11050   u32 sw_if_index = ~0;
11051   u8 sw_if_index_set = 0;
11052   u8 ipv4_set = 0;
11053   u8 ipv6_set = 0;
11054   f64 timeout;
11055
11056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11057     {
11058       if (unformat (i, "sw_if_index %d", &sw_if_index))
11059         sw_if_index_set = 1;
11060       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11061         sw_if_index_set = 1;
11062       else if (unformat (i, "ipv4"))
11063         ipv4_set = 1;
11064       else if (unformat (i, "ipv6"))
11065         ipv6_set = 1;
11066       else
11067         break;
11068     }
11069
11070   if (ipv4_set && ipv6_set)
11071     {
11072       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11073       return -99;
11074     }
11075
11076   if ((!ipv4_set) && (!ipv6_set))
11077     {
11078       errmsg ("no ipv4 nor ipv6 flag set\n");
11079       return -99;
11080     }
11081
11082   if (sw_if_index_set == 0)
11083     {
11084       errmsg ("missing interface name or sw_if_index\n");
11085       return -99;
11086     }
11087
11088   vam->current_sw_if_index = sw_if_index;
11089   vam->is_ipv6 = ipv6_set;
11090
11091   M (IP_ADDRESS_DUMP, ip_address_dump);
11092   mp->sw_if_index = ntohl (sw_if_index);
11093   mp->is_ipv6 = ipv6_set;
11094   S;
11095
11096   /* Use a control ping for synchronization */
11097   {
11098     vl_api_control_ping_t *mp;
11099     M (CONTROL_PING, control_ping);
11100     S;
11101   }
11102   W;
11103 }
11104
11105 static int
11106 api_ip_dump (vat_main_t * vam)
11107 {
11108   vl_api_ip_dump_t *mp;
11109   unformat_input_t *in = vam->input;
11110   int ipv4_set = 0;
11111   int ipv6_set = 0;
11112   int is_ipv6;
11113   f64 timeout;
11114   int i;
11115
11116   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11117     {
11118       if (unformat (in, "ipv4"))
11119         ipv4_set = 1;
11120       else if (unformat (in, "ipv6"))
11121         ipv6_set = 1;
11122       else
11123         break;
11124     }
11125
11126   if (ipv4_set && ipv6_set)
11127     {
11128       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11129       return -99;
11130     }
11131
11132   if ((!ipv4_set) && (!ipv6_set))
11133     {
11134       errmsg ("no ipv4 nor ipv6 flag set\n");
11135       return -99;
11136     }
11137
11138   is_ipv6 = ipv6_set;
11139   vam->is_ipv6 = is_ipv6;
11140
11141   /* free old data */
11142   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11143     {
11144       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11145     }
11146   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11147
11148   M (IP_DUMP, ip_dump);
11149   mp->is_ipv6 = ipv6_set;
11150   S;
11151
11152   /* Use a control ping for synchronization */
11153   {
11154     vl_api_control_ping_t *mp;
11155     M (CONTROL_PING, control_ping);
11156     S;
11157   }
11158   W;
11159 }
11160
11161 static int
11162 api_ipsec_spd_add_del (vat_main_t * vam)
11163 {
11164 #if DPDK > 0
11165   unformat_input_t *i = vam->input;
11166   vl_api_ipsec_spd_add_del_t *mp;
11167   f64 timeout;
11168   u32 spd_id = ~0;
11169   u8 is_add = 1;
11170
11171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11172     {
11173       if (unformat (i, "spd_id %d", &spd_id))
11174         ;
11175       else if (unformat (i, "del"))
11176         is_add = 0;
11177       else
11178         {
11179           clib_warning ("parse error '%U'", format_unformat_error, i);
11180           return -99;
11181         }
11182     }
11183   if (spd_id == ~0)
11184     {
11185       errmsg ("spd_id must be set\n");
11186       return -99;
11187     }
11188
11189   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11190
11191   mp->spd_id = ntohl (spd_id);
11192   mp->is_add = is_add;
11193
11194   S;
11195   W;
11196   /* NOTREACHED */
11197   return 0;
11198 #else
11199   clib_warning ("unsupported (no dpdk)");
11200   return -99;
11201 #endif
11202 }
11203
11204 static int
11205 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11206 {
11207 #if DPDK > 0
11208   unformat_input_t *i = vam->input;
11209   vl_api_ipsec_interface_add_del_spd_t *mp;
11210   f64 timeout;
11211   u32 sw_if_index;
11212   u8 sw_if_index_set = 0;
11213   u32 spd_id = (u32) ~ 0;
11214   u8 is_add = 1;
11215
11216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11217     {
11218       if (unformat (i, "del"))
11219         is_add = 0;
11220       else if (unformat (i, "spd_id %d", &spd_id))
11221         ;
11222       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11223         sw_if_index_set = 1;
11224       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11225         sw_if_index_set = 1;
11226       else
11227         {
11228           clib_warning ("parse error '%U'", format_unformat_error, i);
11229           return -99;
11230         }
11231
11232     }
11233
11234   if (spd_id == (u32) ~ 0)
11235     {
11236       errmsg ("spd_id must be set\n");
11237       return -99;
11238     }
11239
11240   if (sw_if_index_set == 0)
11241     {
11242       errmsg ("missing interface name or sw_if_index\n");
11243       return -99;
11244     }
11245
11246   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11247
11248   mp->spd_id = ntohl (spd_id);
11249   mp->sw_if_index = ntohl (sw_if_index);
11250   mp->is_add = is_add;
11251
11252   S;
11253   W;
11254   /* NOTREACHED */
11255   return 0;
11256 #else
11257   clib_warning ("unsupported (no dpdk)");
11258   return -99;
11259 #endif
11260 }
11261
11262 static int
11263 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11264 {
11265 #if DPDK > 0
11266   unformat_input_t *i = vam->input;
11267   vl_api_ipsec_spd_add_del_entry_t *mp;
11268   f64 timeout;
11269   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11270   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11271   i32 priority = 0;
11272   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11273   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11274   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11275   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11276
11277   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11278   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11279   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11280   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11281   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11282   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11283
11284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11285     {
11286       if (unformat (i, "del"))
11287         is_add = 0;
11288       if (unformat (i, "outbound"))
11289         is_outbound = 1;
11290       if (unformat (i, "inbound"))
11291         is_outbound = 0;
11292       else if (unformat (i, "spd_id %d", &spd_id))
11293         ;
11294       else if (unformat (i, "sa_id %d", &sa_id))
11295         ;
11296       else if (unformat (i, "priority %d", &priority))
11297         ;
11298       else if (unformat (i, "protocol %d", &protocol))
11299         ;
11300       else if (unformat (i, "lport_start %d", &lport_start))
11301         ;
11302       else if (unformat (i, "lport_stop %d", &lport_stop))
11303         ;
11304       else if (unformat (i, "rport_start %d", &rport_start))
11305         ;
11306       else if (unformat (i, "rport_stop %d", &rport_stop))
11307         ;
11308       else
11309         if (unformat
11310             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11311         {
11312           is_ipv6 = 0;
11313           is_ip_any = 0;
11314         }
11315       else
11316         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11317         {
11318           is_ipv6 = 0;
11319           is_ip_any = 0;
11320         }
11321       else
11322         if (unformat
11323             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11324         {
11325           is_ipv6 = 0;
11326           is_ip_any = 0;
11327         }
11328       else
11329         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11330         {
11331           is_ipv6 = 0;
11332           is_ip_any = 0;
11333         }
11334       else
11335         if (unformat
11336             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11337         {
11338           is_ipv6 = 1;
11339           is_ip_any = 0;
11340         }
11341       else
11342         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11343         {
11344           is_ipv6 = 1;
11345           is_ip_any = 0;
11346         }
11347       else
11348         if (unformat
11349             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11350         {
11351           is_ipv6 = 1;
11352           is_ip_any = 0;
11353         }
11354       else
11355         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11356         {
11357           is_ipv6 = 1;
11358           is_ip_any = 0;
11359         }
11360       else
11361         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11362         {
11363           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11364             {
11365               clib_warning ("unsupported action: 'resolve'");
11366               return -99;
11367             }
11368         }
11369       else
11370         {
11371           clib_warning ("parse error '%U'", format_unformat_error, i);
11372           return -99;
11373         }
11374
11375     }
11376
11377   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11378
11379   mp->spd_id = ntohl (spd_id);
11380   mp->priority = ntohl (priority);
11381   mp->is_outbound = is_outbound;
11382
11383   mp->is_ipv6 = is_ipv6;
11384   if (is_ipv6 || is_ip_any)
11385     {
11386       clib_memcpy (mp->remote_address_start, &raddr6_start,
11387                    sizeof (ip6_address_t));
11388       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11389                    sizeof (ip6_address_t));
11390       clib_memcpy (mp->local_address_start, &laddr6_start,
11391                    sizeof (ip6_address_t));
11392       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11393                    sizeof (ip6_address_t));
11394     }
11395   else
11396     {
11397       clib_memcpy (mp->remote_address_start, &raddr4_start,
11398                    sizeof (ip4_address_t));
11399       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11400                    sizeof (ip4_address_t));
11401       clib_memcpy (mp->local_address_start, &laddr4_start,
11402                    sizeof (ip4_address_t));
11403       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11404                    sizeof (ip4_address_t));
11405     }
11406   mp->protocol = (u8) protocol;
11407   mp->local_port_start = ntohs ((u16) lport_start);
11408   mp->local_port_stop = ntohs ((u16) lport_stop);
11409   mp->remote_port_start = ntohs ((u16) rport_start);
11410   mp->remote_port_stop = ntohs ((u16) rport_stop);
11411   mp->policy = (u8) policy;
11412   mp->sa_id = ntohl (sa_id);
11413   mp->is_add = is_add;
11414   mp->is_ip_any = is_ip_any;
11415   S;
11416   W;
11417   /* NOTREACHED */
11418   return 0;
11419 #else
11420   clib_warning ("unsupported (no dpdk)");
11421   return -99;
11422 #endif
11423 }
11424
11425 static int
11426 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11427 {
11428 #if DPDK > 0
11429   unformat_input_t *i = vam->input;
11430   vl_api_ipsec_sad_add_del_entry_t *mp;
11431   f64 timeout;
11432   u32 sad_id = 0, spi = 0;
11433   u8 *ck = 0, *ik = 0;
11434   u8 is_add = 1;
11435
11436   u8 protocol = IPSEC_PROTOCOL_AH;
11437   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11438   u32 crypto_alg = 0, integ_alg = 0;
11439   ip4_address_t tun_src4;
11440   ip4_address_t tun_dst4;
11441   ip6_address_t tun_src6;
11442   ip6_address_t tun_dst6;
11443
11444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11445     {
11446       if (unformat (i, "del"))
11447         is_add = 0;
11448       else if (unformat (i, "sad_id %d", &sad_id))
11449         ;
11450       else if (unformat (i, "spi %d", &spi))
11451         ;
11452       else if (unformat (i, "esp"))
11453         protocol = IPSEC_PROTOCOL_ESP;
11454       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11455         {
11456           is_tunnel = 1;
11457           is_tunnel_ipv6 = 0;
11458         }
11459       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11460         {
11461           is_tunnel = 1;
11462           is_tunnel_ipv6 = 0;
11463         }
11464       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11465         {
11466           is_tunnel = 1;
11467           is_tunnel_ipv6 = 1;
11468         }
11469       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11470         {
11471           is_tunnel = 1;
11472           is_tunnel_ipv6 = 1;
11473         }
11474       else
11475         if (unformat
11476             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11477         {
11478           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11479               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11480             {
11481               clib_warning ("unsupported crypto-alg: '%U'",
11482                             format_ipsec_crypto_alg, crypto_alg);
11483               return -99;
11484             }
11485         }
11486       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11487         ;
11488       else
11489         if (unformat
11490             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11491         {
11492           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11493               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11494             {
11495               clib_warning ("unsupported integ-alg: '%U'",
11496                             format_ipsec_integ_alg, integ_alg);
11497               return -99;
11498             }
11499         }
11500       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11501         ;
11502       else
11503         {
11504           clib_warning ("parse error '%U'", format_unformat_error, i);
11505           return -99;
11506         }
11507
11508     }
11509
11510   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11511
11512   mp->sad_id = ntohl (sad_id);
11513   mp->is_add = is_add;
11514   mp->protocol = protocol;
11515   mp->spi = ntohl (spi);
11516   mp->is_tunnel = is_tunnel;
11517   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11518   mp->crypto_algorithm = crypto_alg;
11519   mp->integrity_algorithm = integ_alg;
11520   mp->crypto_key_length = vec_len (ck);
11521   mp->integrity_key_length = vec_len (ik);
11522
11523   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11524     mp->crypto_key_length = sizeof (mp->crypto_key);
11525
11526   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11527     mp->integrity_key_length = sizeof (mp->integrity_key);
11528
11529   if (ck)
11530     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11531   if (ik)
11532     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11533
11534   if (is_tunnel)
11535     {
11536       if (is_tunnel_ipv6)
11537         {
11538           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11539                        sizeof (ip6_address_t));
11540           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11541                        sizeof (ip6_address_t));
11542         }
11543       else
11544         {
11545           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11546                        sizeof (ip4_address_t));
11547           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11548                        sizeof (ip4_address_t));
11549         }
11550     }
11551
11552   S;
11553   W;
11554   /* NOTREACHED */
11555   return 0;
11556 #else
11557   clib_warning ("unsupported (no dpdk)");
11558   return -99;
11559 #endif
11560 }
11561
11562 static int
11563 api_ipsec_sa_set_key (vat_main_t * vam)
11564 {
11565 #if DPDK > 0
11566   unformat_input_t *i = vam->input;
11567   vl_api_ipsec_sa_set_key_t *mp;
11568   f64 timeout;
11569   u32 sa_id;
11570   u8 *ck = 0, *ik = 0;
11571
11572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11573     {
11574       if (unformat (i, "sa_id %d", &sa_id))
11575         ;
11576       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11577         ;
11578       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11579         ;
11580       else
11581         {
11582           clib_warning ("parse error '%U'", format_unformat_error, i);
11583           return -99;
11584         }
11585     }
11586
11587   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11588
11589   mp->sa_id = ntohl (sa_id);
11590   mp->crypto_key_length = vec_len (ck);
11591   mp->integrity_key_length = vec_len (ik);
11592
11593   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11594     mp->crypto_key_length = sizeof (mp->crypto_key);
11595
11596   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11597     mp->integrity_key_length = sizeof (mp->integrity_key);
11598
11599   if (ck)
11600     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11601   if (ik)
11602     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11603
11604   S;
11605   W;
11606   /* NOTREACHED */
11607   return 0;
11608 #else
11609   clib_warning ("unsupported (no dpdk)");
11610   return -99;
11611 #endif
11612 }
11613
11614 static int
11615 api_ikev2_profile_add_del (vat_main_t * vam)
11616 {
11617 #if DPDK > 0
11618   unformat_input_t *i = vam->input;
11619   vl_api_ikev2_profile_add_del_t *mp;
11620   f64 timeout;
11621   u8 is_add = 1;
11622   u8 *name = 0;
11623
11624   const char *valid_chars = "a-zA-Z0-9_";
11625
11626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11627     {
11628       if (unformat (i, "del"))
11629         is_add = 0;
11630       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11631         vec_add1 (name, 0);
11632       else
11633         {
11634           errmsg ("parse error '%U'", format_unformat_error, i);
11635           return -99;
11636         }
11637     }
11638
11639   if (!vec_len (name))
11640     {
11641       errmsg ("profile name must be specified");
11642       return -99;
11643     }
11644
11645   if (vec_len (name) > 64)
11646     {
11647       errmsg ("profile name too long");
11648       return -99;
11649     }
11650
11651   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11652
11653   clib_memcpy (mp->name, name, vec_len (name));
11654   mp->is_add = is_add;
11655   vec_free (name);
11656
11657   S;
11658   W;
11659   /* NOTREACHED */
11660   return 0;
11661 #else
11662   clib_warning ("unsupported (no dpdk)");
11663   return -99;
11664 #endif
11665 }
11666
11667 static int
11668 api_ikev2_profile_set_auth (vat_main_t * vam)
11669 {
11670 #if DPDK > 0
11671   unformat_input_t *i = vam->input;
11672   vl_api_ikev2_profile_set_auth_t *mp;
11673   f64 timeout;
11674   u8 *name = 0;
11675   u8 *data = 0;
11676   u32 auth_method = 0;
11677   u8 is_hex = 0;
11678
11679   const char *valid_chars = "a-zA-Z0-9_";
11680
11681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11682     {
11683       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11684         vec_add1 (name, 0);
11685       else if (unformat (i, "auth_method %U",
11686                          unformat_ikev2_auth_method, &auth_method))
11687         ;
11688       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11689         is_hex = 1;
11690       else if (unformat (i, "auth_data %v", &data))
11691         ;
11692       else
11693         {
11694           errmsg ("parse error '%U'", format_unformat_error, i);
11695           return -99;
11696         }
11697     }
11698
11699   if (!vec_len (name))
11700     {
11701       errmsg ("profile name must be specified");
11702       return -99;
11703     }
11704
11705   if (vec_len (name) > 64)
11706     {
11707       errmsg ("profile name too long");
11708       return -99;
11709     }
11710
11711   if (!vec_len (data))
11712     {
11713       errmsg ("auth_data must be specified");
11714       return -99;
11715     }
11716
11717   if (!auth_method)
11718     {
11719       errmsg ("auth_method must be specified");
11720       return -99;
11721     }
11722
11723   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11724
11725   mp->is_hex = is_hex;
11726   mp->auth_method = (u8) auth_method;
11727   mp->data_len = vec_len (data);
11728   clib_memcpy (mp->name, name, vec_len (name));
11729   clib_memcpy (mp->data, data, vec_len (data));
11730   vec_free (name);
11731   vec_free (data);
11732
11733   S;
11734   W;
11735   /* NOTREACHED */
11736   return 0;
11737 #else
11738   clib_warning ("unsupported (no dpdk)");
11739   return -99;
11740 #endif
11741 }
11742
11743 static int
11744 api_ikev2_profile_set_id (vat_main_t * vam)
11745 {
11746 #if DPDK > 0
11747   unformat_input_t *i = vam->input;
11748   vl_api_ikev2_profile_set_id_t *mp;
11749   f64 timeout;
11750   u8 *name = 0;
11751   u8 *data = 0;
11752   u8 is_local = 0;
11753   u32 id_type = 0;
11754   ip4_address_t ip4;
11755
11756   const char *valid_chars = "a-zA-Z0-9_";
11757
11758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11759     {
11760       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11761         vec_add1 (name, 0);
11762       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11763         ;
11764       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11765         {
11766           data = vec_new (u8, 4);
11767           clib_memcpy (data, ip4.as_u8, 4);
11768         }
11769       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11770         ;
11771       else if (unformat (i, "id_data %v", &data))
11772         ;
11773       else if (unformat (i, "local"))
11774         is_local = 1;
11775       else if (unformat (i, "remote"))
11776         is_local = 0;
11777       else
11778         {
11779           errmsg ("parse error '%U'", format_unformat_error, i);
11780           return -99;
11781         }
11782     }
11783
11784   if (!vec_len (name))
11785     {
11786       errmsg ("profile name must be specified");
11787       return -99;
11788     }
11789
11790   if (vec_len (name) > 64)
11791     {
11792       errmsg ("profile name too long");
11793       return -99;
11794     }
11795
11796   if (!vec_len (data))
11797     {
11798       errmsg ("id_data must be specified");
11799       return -99;
11800     }
11801
11802   if (!id_type)
11803     {
11804       errmsg ("id_type must be specified");
11805       return -99;
11806     }
11807
11808   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11809
11810   mp->is_local = is_local;
11811   mp->id_type = (u8) id_type;
11812   mp->data_len = vec_len (data);
11813   clib_memcpy (mp->name, name, vec_len (name));
11814   clib_memcpy (mp->data, data, vec_len (data));
11815   vec_free (name);
11816   vec_free (data);
11817
11818   S;
11819   W;
11820   /* NOTREACHED */
11821   return 0;
11822 #else
11823   clib_warning ("unsupported (no dpdk)");
11824   return -99;
11825 #endif
11826 }
11827
11828 static int
11829 api_ikev2_profile_set_ts (vat_main_t * vam)
11830 {
11831 #if DPDK > 0
11832   unformat_input_t *i = vam->input;
11833   vl_api_ikev2_profile_set_ts_t *mp;
11834   f64 timeout;
11835   u8 *name = 0;
11836   u8 is_local = 0;
11837   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11838   ip4_address_t start_addr, end_addr;
11839
11840   const char *valid_chars = "a-zA-Z0-9_";
11841
11842   start_addr.as_u32 = 0;
11843   end_addr.as_u32 = (u32) ~ 0;
11844
11845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11846     {
11847       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11848         vec_add1 (name, 0);
11849       else if (unformat (i, "protocol %d", &proto))
11850         ;
11851       else if (unformat (i, "start_port %d", &start_port))
11852         ;
11853       else if (unformat (i, "end_port %d", &end_port))
11854         ;
11855       else
11856         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11857         ;
11858       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11859         ;
11860       else if (unformat (i, "local"))
11861         is_local = 1;
11862       else if (unformat (i, "remote"))
11863         is_local = 0;
11864       else
11865         {
11866           errmsg ("parse error '%U'", format_unformat_error, i);
11867           return -99;
11868         }
11869     }
11870
11871   if (!vec_len (name))
11872     {
11873       errmsg ("profile name must be specified");
11874       return -99;
11875     }
11876
11877   if (vec_len (name) > 64)
11878     {
11879       errmsg ("profile name too long");
11880       return -99;
11881     }
11882
11883   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11884
11885   mp->is_local = is_local;
11886   mp->proto = (u8) proto;
11887   mp->start_port = (u16) start_port;
11888   mp->end_port = (u16) end_port;
11889   mp->start_addr = start_addr.as_u32;
11890   mp->end_addr = end_addr.as_u32;
11891   clib_memcpy (mp->name, name, vec_len (name));
11892   vec_free (name);
11893
11894   S;
11895   W;
11896   /* NOTREACHED */
11897   return 0;
11898 #else
11899   clib_warning ("unsupported (no dpdk)");
11900   return -99;
11901 #endif
11902 }
11903
11904 static int
11905 api_ikev2_set_local_key (vat_main_t * vam)
11906 {
11907 #if DPDK > 0
11908   unformat_input_t *i = vam->input;
11909   vl_api_ikev2_set_local_key_t *mp;
11910   f64 timeout;
11911   u8 *file = 0;
11912
11913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11914     {
11915       if (unformat (i, "file %v", &file))
11916         vec_add1 (file, 0);
11917       else
11918         {
11919           errmsg ("parse error '%U'", format_unformat_error, i);
11920           return -99;
11921         }
11922     }
11923
11924   if (!vec_len (file))
11925     {
11926       errmsg ("RSA key file must be specified");
11927       return -99;
11928     }
11929
11930   if (vec_len (file) > 256)
11931     {
11932       errmsg ("file name too long");
11933       return -99;
11934     }
11935
11936   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11937
11938   clib_memcpy (mp->key_file, file, vec_len (file));
11939   vec_free (file);
11940
11941   S;
11942   W;
11943   /* NOTREACHED */
11944   return 0;
11945 #else
11946   clib_warning ("unsupported (no dpdk)");
11947   return -99;
11948 #endif
11949 }
11950
11951 /*
11952  * MAP
11953  */
11954 static int
11955 api_map_add_domain (vat_main_t * vam)
11956 {
11957   unformat_input_t *i = vam->input;
11958   vl_api_map_add_domain_t *mp;
11959   f64 timeout;
11960
11961   ip4_address_t ip4_prefix;
11962   ip6_address_t ip6_prefix;
11963   ip6_address_t ip6_src;
11964   u32 num_m_args = 0;
11965   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11966     0, psid_length = 0;
11967   u8 is_translation = 0;
11968   u32 mtu = 0;
11969   u32 ip6_src_len = 128;
11970
11971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11972     {
11973       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11974                     &ip4_prefix, &ip4_prefix_len))
11975         num_m_args++;
11976       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11977                          &ip6_prefix, &ip6_prefix_len))
11978         num_m_args++;
11979       else
11980         if (unformat
11981             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11982              &ip6_src_len))
11983         num_m_args++;
11984       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11985         num_m_args++;
11986       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11987         num_m_args++;
11988       else if (unformat (i, "psid-offset %d", &psid_offset))
11989         num_m_args++;
11990       else if (unformat (i, "psid-len %d", &psid_length))
11991         num_m_args++;
11992       else if (unformat (i, "mtu %d", &mtu))
11993         num_m_args++;
11994       else if (unformat (i, "map-t"))
11995         is_translation = 1;
11996       else
11997         {
11998           clib_warning ("parse error '%U'", format_unformat_error, i);
11999           return -99;
12000         }
12001     }
12002
12003   if (num_m_args < 3)
12004     {
12005       errmsg ("mandatory argument(s) missing\n");
12006       return -99;
12007     }
12008
12009   /* Construct the API message */
12010   M (MAP_ADD_DOMAIN, map_add_domain);
12011
12012   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12013   mp->ip4_prefix_len = ip4_prefix_len;
12014
12015   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12016   mp->ip6_prefix_len = ip6_prefix_len;
12017
12018   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12019   mp->ip6_src_prefix_len = ip6_src_len;
12020
12021   mp->ea_bits_len = ea_bits_len;
12022   mp->psid_offset = psid_offset;
12023   mp->psid_length = psid_length;
12024   mp->is_translation = is_translation;
12025   mp->mtu = htons (mtu);
12026
12027   /* send it... */
12028   S;
12029
12030   /* Wait for a reply, return good/bad news  */
12031   W;
12032 }
12033
12034 static int
12035 api_map_del_domain (vat_main_t * vam)
12036 {
12037   unformat_input_t *i = vam->input;
12038   vl_api_map_del_domain_t *mp;
12039   f64 timeout;
12040
12041   u32 num_m_args = 0;
12042   u32 index;
12043
12044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12045     {
12046       if (unformat (i, "index %d", &index))
12047         num_m_args++;
12048       else
12049         {
12050           clib_warning ("parse error '%U'", format_unformat_error, i);
12051           return -99;
12052         }
12053     }
12054
12055   if (num_m_args != 1)
12056     {
12057       errmsg ("mandatory argument(s) missing\n");
12058       return -99;
12059     }
12060
12061   /* Construct the API message */
12062   M (MAP_DEL_DOMAIN, map_del_domain);
12063
12064   mp->index = ntohl (index);
12065
12066   /* send it... */
12067   S;
12068
12069   /* Wait for a reply, return good/bad news  */
12070   W;
12071 }
12072
12073 static int
12074 api_map_add_del_rule (vat_main_t * vam)
12075 {
12076   unformat_input_t *i = vam->input;
12077   vl_api_map_add_del_rule_t *mp;
12078   f64 timeout;
12079   u8 is_add = 1;
12080   ip6_address_t ip6_dst;
12081   u32 num_m_args = 0, index, psid = 0;
12082
12083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12084     {
12085       if (unformat (i, "index %d", &index))
12086         num_m_args++;
12087       else if (unformat (i, "psid %d", &psid))
12088         num_m_args++;
12089       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12090         num_m_args++;
12091       else if (unformat (i, "del"))
12092         {
12093           is_add = 0;
12094         }
12095       else
12096         {
12097           clib_warning ("parse error '%U'", format_unformat_error, i);
12098           return -99;
12099         }
12100     }
12101
12102   /* Construct the API message */
12103   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12104
12105   mp->index = ntohl (index);
12106   mp->is_add = is_add;
12107   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12108   mp->psid = ntohs (psid);
12109
12110   /* send it... */
12111   S;
12112
12113   /* Wait for a reply, return good/bad news  */
12114   W;
12115 }
12116
12117 static int
12118 api_map_domain_dump (vat_main_t * vam)
12119 {
12120   vl_api_map_domain_dump_t *mp;
12121   f64 timeout;
12122
12123   /* Construct the API message */
12124   M (MAP_DOMAIN_DUMP, map_domain_dump);
12125
12126   /* send it... */
12127   S;
12128
12129   /* Use a control ping for synchronization */
12130   {
12131     vl_api_control_ping_t *mp;
12132     M (CONTROL_PING, control_ping);
12133     S;
12134   }
12135   W;
12136 }
12137
12138 static int
12139 api_map_rule_dump (vat_main_t * vam)
12140 {
12141   unformat_input_t *i = vam->input;
12142   vl_api_map_rule_dump_t *mp;
12143   f64 timeout;
12144   u32 domain_index = ~0;
12145
12146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12147     {
12148       if (unformat (i, "index %u", &domain_index))
12149         ;
12150       else
12151         break;
12152     }
12153
12154   if (domain_index == ~0)
12155     {
12156       clib_warning ("parse error: domain index expected");
12157       return -99;
12158     }
12159
12160   /* Construct the API message */
12161   M (MAP_RULE_DUMP, map_rule_dump);
12162
12163   mp->domain_index = htonl (domain_index);
12164
12165   /* send it... */
12166   S;
12167
12168   /* Use a control ping for synchronization */
12169   {
12170     vl_api_control_ping_t *mp;
12171     M (CONTROL_PING, control_ping);
12172     S;
12173   }
12174   W;
12175 }
12176
12177 static void vl_api_map_add_domain_reply_t_handler
12178   (vl_api_map_add_domain_reply_t * mp)
12179 {
12180   vat_main_t *vam = &vat_main;
12181   i32 retval = ntohl (mp->retval);
12182
12183   if (vam->async_mode)
12184     {
12185       vam->async_errors += (retval < 0);
12186     }
12187   else
12188     {
12189       vam->retval = retval;
12190       vam->result_ready = 1;
12191     }
12192 }
12193
12194 static void vl_api_map_add_domain_reply_t_handler_json
12195   (vl_api_map_add_domain_reply_t * mp)
12196 {
12197   vat_main_t *vam = &vat_main;
12198   vat_json_node_t node;
12199
12200   vat_json_init_object (&node);
12201   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12202   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12203
12204   vat_json_print (vam->ofp, &node);
12205   vat_json_free (&node);
12206
12207   vam->retval = ntohl (mp->retval);
12208   vam->result_ready = 1;
12209 }
12210
12211 static int
12212 api_get_first_msg_id (vat_main_t * vam)
12213 {
12214   vl_api_get_first_msg_id_t *mp;
12215   f64 timeout;
12216   unformat_input_t *i = vam->input;
12217   u8 *name;
12218   u8 name_set = 0;
12219
12220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12221     {
12222       if (unformat (i, "client %s", &name))
12223         name_set = 1;
12224       else
12225         break;
12226     }
12227
12228   if (name_set == 0)
12229     {
12230       errmsg ("missing client name\n");
12231       return -99;
12232     }
12233   vec_add1 (name, 0);
12234
12235   if (vec_len (name) > 63)
12236     {
12237       errmsg ("client name too long\n");
12238       return -99;
12239     }
12240
12241   M (GET_FIRST_MSG_ID, get_first_msg_id);
12242   clib_memcpy (mp->name, name, vec_len (name));
12243   S;
12244   W;
12245   /* NOTREACHED */
12246   return 0;
12247 }
12248
12249 static int
12250 api_cop_interface_enable_disable (vat_main_t * vam)
12251 {
12252   unformat_input_t *line_input = vam->input;
12253   vl_api_cop_interface_enable_disable_t *mp;
12254   f64 timeout;
12255   u32 sw_if_index = ~0;
12256   u8 enable_disable = 1;
12257
12258   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12259     {
12260       if (unformat (line_input, "disable"))
12261         enable_disable = 0;
12262       if (unformat (line_input, "enable"))
12263         enable_disable = 1;
12264       else if (unformat (line_input, "%U", unformat_sw_if_index,
12265                          vam, &sw_if_index))
12266         ;
12267       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12268         ;
12269       else
12270         break;
12271     }
12272
12273   if (sw_if_index == ~0)
12274     {
12275       errmsg ("missing interface name or sw_if_index\n");
12276       return -99;
12277     }
12278
12279   /* Construct the API message */
12280   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12281   mp->sw_if_index = ntohl (sw_if_index);
12282   mp->enable_disable = enable_disable;
12283
12284   /* send it... */
12285   S;
12286   /* Wait for the reply */
12287   W;
12288 }
12289
12290 static int
12291 api_cop_whitelist_enable_disable (vat_main_t * vam)
12292 {
12293   unformat_input_t *line_input = vam->input;
12294   vl_api_cop_whitelist_enable_disable_t *mp;
12295   f64 timeout;
12296   u32 sw_if_index = ~0;
12297   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12298   u32 fib_id = 0;
12299
12300   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12301     {
12302       if (unformat (line_input, "ip4"))
12303         ip4 = 1;
12304       else if (unformat (line_input, "ip6"))
12305         ip6 = 1;
12306       else if (unformat (line_input, "default"))
12307         default_cop = 1;
12308       else if (unformat (line_input, "%U", unformat_sw_if_index,
12309                          vam, &sw_if_index))
12310         ;
12311       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12312         ;
12313       else if (unformat (line_input, "fib-id %d", &fib_id))
12314         ;
12315       else
12316         break;
12317     }
12318
12319   if (sw_if_index == ~0)
12320     {
12321       errmsg ("missing interface name or sw_if_index\n");
12322       return -99;
12323     }
12324
12325   /* Construct the API message */
12326   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12327   mp->sw_if_index = ntohl (sw_if_index);
12328   mp->fib_id = ntohl (fib_id);
12329   mp->ip4 = ip4;
12330   mp->ip6 = ip6;
12331   mp->default_cop = default_cop;
12332
12333   /* send it... */
12334   S;
12335   /* Wait for the reply */
12336   W;
12337 }
12338
12339 static int
12340 api_get_node_graph (vat_main_t * vam)
12341 {
12342   vl_api_get_node_graph_t *mp;
12343   f64 timeout;
12344
12345   M (GET_NODE_GRAPH, get_node_graph);
12346
12347   /* send it... */
12348   S;
12349   /* Wait for the reply */
12350   W;
12351 }
12352
12353 /* *INDENT-OFF* */
12354 /** Used for parsing LISP eids */
12355 typedef CLIB_PACKED(struct{
12356   u8 addr[16];   /**< eid address */
12357   u32 len;       /**< prefix length if IP */
12358   u8 type;      /**< type of eid */
12359 }) lisp_eid_vat_t;
12360 /* *INDENT-ON* */
12361
12362 static uword
12363 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12364 {
12365   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12366
12367   memset (a, 0, sizeof (a[0]));
12368
12369   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12370     {
12371       a->type = 0;              /* ipv4 type */
12372     }
12373   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12374     {
12375       a->type = 1;              /* ipv6 type */
12376     }
12377   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12378     {
12379       a->type = 2;              /* mac type */
12380     }
12381   else
12382     {
12383       return 0;
12384     }
12385
12386   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12387     {
12388       return 0;
12389     }
12390
12391   return 1;
12392 }
12393
12394 static int
12395 lisp_eid_size_vat (u8 type)
12396 {
12397   switch (type)
12398     {
12399     case 0:
12400       return 4;
12401     case 1:
12402       return 16;
12403     case 2:
12404       return 6;
12405     }
12406   return 0;
12407 }
12408
12409 static void
12410 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12411 {
12412   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12413 }
12414
12415 /* *INDENT-OFF* */
12416 /** Used for transferring locators via VPP API */
12417 typedef CLIB_PACKED(struct
12418 {
12419   u32 sw_if_index; /**< locator sw_if_index */
12420   u8 priority; /**< locator priority */
12421   u8 weight;   /**< locator weight */
12422 }) ls_locator_t;
12423 /* *INDENT-ON* */
12424
12425 static int
12426 api_lisp_add_del_locator_set (vat_main_t * vam)
12427 {
12428   unformat_input_t *input = vam->input;
12429   vl_api_lisp_add_del_locator_set_t *mp;
12430   f64 timeout = ~0;
12431   u8 is_add = 1;
12432   u8 *locator_set_name = NULL;
12433   u8 locator_set_name_set = 0;
12434   ls_locator_t locator, *locators = 0;
12435   u32 sw_if_index, priority, weight;
12436   u32 data_len = 0;
12437
12438   /* Parse args required to build the message */
12439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12440     {
12441       if (unformat (input, "del"))
12442         {
12443           is_add = 0;
12444         }
12445       else if (unformat (input, "locator-set %s", &locator_set_name))
12446         {
12447           locator_set_name_set = 1;
12448         }
12449       else if (unformat (input, "sw_if_index %u p %u w %u",
12450                          &sw_if_index, &priority, &weight))
12451         {
12452           locator.sw_if_index = htonl (sw_if_index);
12453           locator.priority = priority;
12454           locator.weight = weight;
12455           vec_add1 (locators, locator);
12456         }
12457       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12458                          vam, &sw_if_index, &priority, &weight))
12459         {
12460           locator.sw_if_index = htonl (sw_if_index);
12461           locator.priority = priority;
12462           locator.weight = weight;
12463           vec_add1 (locators, locator);
12464         }
12465       else
12466         break;
12467     }
12468
12469   if (locator_set_name_set == 0)
12470     {
12471       errmsg ("missing locator-set name");
12472       vec_free (locators);
12473       return -99;
12474     }
12475
12476   if (vec_len (locator_set_name) > 64)
12477     {
12478       errmsg ("locator-set name too long\n");
12479       vec_free (locator_set_name);
12480       vec_free (locators);
12481       return -99;
12482     }
12483   vec_add1 (locator_set_name, 0);
12484
12485   data_len = sizeof (ls_locator_t) * vec_len (locators);
12486
12487   /* Construct the API message */
12488   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12489
12490   mp->is_add = is_add;
12491   clib_memcpy (mp->locator_set_name, locator_set_name,
12492                vec_len (locator_set_name));
12493   vec_free (locator_set_name);
12494
12495   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12496   if (locators)
12497     clib_memcpy (mp->locators, locators, data_len);
12498   vec_free (locators);
12499
12500   /* send it... */
12501   S;
12502
12503   /* Wait for a reply... */
12504   W;
12505
12506   /* NOTREACHED */
12507   return 0;
12508 }
12509
12510 static int
12511 api_lisp_add_del_locator (vat_main_t * vam)
12512 {
12513   unformat_input_t *input = vam->input;
12514   vl_api_lisp_add_del_locator_t *mp;
12515   f64 timeout = ~0;
12516   u32 tmp_if_index = ~0;
12517   u32 sw_if_index = ~0;
12518   u8 sw_if_index_set = 0;
12519   u8 sw_if_index_if_name_set = 0;
12520   u32 priority = ~0;
12521   u8 priority_set = 0;
12522   u32 weight = ~0;
12523   u8 weight_set = 0;
12524   u8 is_add = 1;
12525   u8 *locator_set_name = NULL;
12526   u8 locator_set_name_set = 0;
12527
12528   /* Parse args required to build the message */
12529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12530     {
12531       if (unformat (input, "del"))
12532         {
12533           is_add = 0;
12534         }
12535       else if (unformat (input, "locator-set %s", &locator_set_name))
12536         {
12537           locator_set_name_set = 1;
12538         }
12539       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12540                          &tmp_if_index))
12541         {
12542           sw_if_index_if_name_set = 1;
12543           sw_if_index = tmp_if_index;
12544         }
12545       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12546         {
12547           sw_if_index_set = 1;
12548           sw_if_index = tmp_if_index;
12549         }
12550       else if (unformat (input, "p %d", &priority))
12551         {
12552           priority_set = 1;
12553         }
12554       else if (unformat (input, "w %d", &weight))
12555         {
12556           weight_set = 1;
12557         }
12558       else
12559         break;
12560     }
12561
12562   if (locator_set_name_set == 0)
12563     {
12564       errmsg ("missing locator-set name");
12565       return -99;
12566     }
12567
12568   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12569     {
12570       errmsg ("missing sw_if_index");
12571       vec_free (locator_set_name);
12572       return -99;
12573     }
12574
12575   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12576     {
12577       errmsg ("cannot use both params interface name and sw_if_index");
12578       vec_free (locator_set_name);
12579       return -99;
12580     }
12581
12582   if (priority_set == 0)
12583     {
12584       errmsg ("missing locator-set priority\n");
12585       vec_free (locator_set_name);
12586       return -99;
12587     }
12588
12589   if (weight_set == 0)
12590     {
12591       errmsg ("missing locator-set weight\n");
12592       vec_free (locator_set_name);
12593       return -99;
12594     }
12595
12596   if (vec_len (locator_set_name) > 64)
12597     {
12598       errmsg ("locator-set name too long\n");
12599       vec_free (locator_set_name);
12600       return -99;
12601     }
12602   vec_add1 (locator_set_name, 0);
12603
12604   /* Construct the API message */
12605   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12606
12607   mp->is_add = is_add;
12608   mp->sw_if_index = ntohl (sw_if_index);
12609   mp->priority = priority;
12610   mp->weight = weight;
12611   clib_memcpy (mp->locator_set_name, locator_set_name,
12612                vec_len (locator_set_name));
12613   vec_free (locator_set_name);
12614
12615   /* send it... */
12616   S;
12617
12618   /* Wait for a reply... */
12619   W;
12620
12621   /* NOTREACHED */
12622   return 0;
12623 }
12624
12625 static int
12626 api_lisp_add_del_local_eid (vat_main_t * vam)
12627 {
12628   unformat_input_t *input = vam->input;
12629   vl_api_lisp_add_del_local_eid_t *mp;
12630   f64 timeout = ~0;
12631   u8 is_add = 1;
12632   u8 eid_set = 0;
12633   lisp_eid_vat_t _eid, *eid = &_eid;
12634   u8 *locator_set_name = 0;
12635   u8 locator_set_name_set = 0;
12636   u32 vni = 0;
12637
12638   /* Parse args required to build the message */
12639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12640     {
12641       if (unformat (input, "del"))
12642         {
12643           is_add = 0;
12644         }
12645       else if (unformat (input, "vni %d", &vni))
12646         {
12647           ;
12648         }
12649       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12650         {
12651           eid_set = 1;
12652         }
12653       else if (unformat (input, "locator-set %s", &locator_set_name))
12654         {
12655           locator_set_name_set = 1;
12656         }
12657       else
12658         break;
12659     }
12660
12661   if (locator_set_name_set == 0)
12662     {
12663       errmsg ("missing locator-set name\n");
12664       return -99;
12665     }
12666
12667   if (0 == eid_set)
12668     {
12669       errmsg ("EID address not set!");
12670       vec_free (locator_set_name);
12671       return -99;
12672     }
12673
12674   if (vec_len (locator_set_name) > 64)
12675     {
12676       errmsg ("locator-set name too long\n");
12677       vec_free (locator_set_name);
12678       return -99;
12679     }
12680   vec_add1 (locator_set_name, 0);
12681
12682   /* Construct the API message */
12683   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12684
12685   mp->is_add = is_add;
12686   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12687   mp->eid_type = eid->type;
12688   mp->prefix_len = eid->len;
12689   mp->vni = clib_host_to_net_u32 (vni);
12690   clib_memcpy (mp->locator_set_name, locator_set_name,
12691                vec_len (locator_set_name));
12692
12693   vec_free (locator_set_name);
12694
12695   /* send it... */
12696   S;
12697
12698   /* Wait for a reply... */
12699   W;
12700
12701   /* NOTREACHED */
12702   return 0;
12703 }
12704
12705 /* *INDENT-OFF* */
12706 /** Used for transferring locators via VPP API */
12707 typedef CLIB_PACKED(struct
12708 {
12709   u8 is_ip4; /**< is locator an IPv4 address? */
12710   u8 priority; /**< locator priority */
12711   u8 weight;   /**< locator weight */
12712   u8 addr[16]; /**< IPv4/IPv6 address */
12713 }) rloc_t;
12714 /* *INDENT-ON* */
12715
12716 static int
12717 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12718 {
12719   unformat_input_t *input = vam->input;
12720   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12721   f64 timeout = ~0;
12722   u8 is_add = 1;
12723   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12724   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12725   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12726   u32 action = ~0, p, w;
12727   ip4_address_t rmt_rloc4, lcl_rloc4;
12728   ip6_address_t rmt_rloc6, lcl_rloc6;
12729   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12730
12731   memset (&rloc, 0, sizeof (rloc));
12732
12733   /* Parse args required to build the message */
12734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12735     {
12736       if (unformat (input, "del"))
12737         {
12738           is_add = 0;
12739         }
12740       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12741         {
12742           rmt_eid_set = 1;
12743         }
12744       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12745         {
12746           lcl_eid_set = 1;
12747         }
12748       else if (unformat (input, "p %d w %d", &p, &w))
12749         {
12750           if (!curr_rloc)
12751             {
12752               errmsg ("No RLOC configured for setting priority/weight!");
12753               return -99;
12754             }
12755           curr_rloc->priority = p;
12756           curr_rloc->weight = w;
12757         }
12758       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12759                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12760         {
12761           rloc.is_ip4 = 1;
12762
12763           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12764           rloc.priority = rloc.weight = 0;
12765           vec_add1 (lcl_locs, rloc);
12766
12767           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12768           vec_add1 (rmt_locs, rloc);
12769           /* priority and weight saved in rmt loc */
12770           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12771         }
12772       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12773                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12774         {
12775           rloc.is_ip4 = 0;
12776           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12777           rloc.priority = rloc.weight = 0;
12778           vec_add1 (lcl_locs, rloc);
12779
12780           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12781           vec_add1 (rmt_locs, rloc);
12782           /* priority and weight saved in rmt loc */
12783           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12784         }
12785       else if (unformat (input, "action %d", &action))
12786         {
12787           ;
12788         }
12789       else
12790         {
12791           clib_warning ("parse error '%U'", format_unformat_error, input);
12792           return -99;
12793         }
12794     }
12795
12796   if (!rmt_eid_set)
12797     {
12798       errmsg ("remote eid addresses not set\n");
12799       return -99;
12800     }
12801
12802   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12803     {
12804       errmsg ("eid types don't match\n");
12805       return -99;
12806     }
12807
12808   if (0 == rmt_locs && (u32) ~ 0 == action)
12809     {
12810       errmsg ("action not set for negative mapping\n");
12811       return -99;
12812     }
12813
12814   /* Construct the API message */
12815   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12816
12817   mp->is_add = is_add;
12818   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12819   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12820   mp->eid_type = rmt_eid->type;
12821   mp->rmt_len = rmt_eid->len;
12822   mp->lcl_len = lcl_eid->len;
12823   mp->action = action;
12824
12825   if (0 != rmt_locs && 0 != lcl_locs)
12826     {
12827       mp->loc_num = vec_len (rmt_locs);
12828       clib_memcpy (mp->lcl_locs, lcl_locs,
12829                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12830       clib_memcpy (mp->rmt_locs, rmt_locs,
12831                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12832     }
12833   vec_free (lcl_locs);
12834   vec_free (rmt_locs);
12835
12836   /* send it... */
12837   S;
12838
12839   /* Wait for a reply... */
12840   W;
12841
12842   /* NOTREACHED */
12843   return 0;
12844 }
12845
12846 static int
12847 api_lisp_add_del_map_resolver (vat_main_t * vam)
12848 {
12849   unformat_input_t *input = vam->input;
12850   vl_api_lisp_add_del_map_resolver_t *mp;
12851   f64 timeout = ~0;
12852   u8 is_add = 1;
12853   u8 ipv4_set = 0;
12854   u8 ipv6_set = 0;
12855   ip4_address_t ipv4;
12856   ip6_address_t ipv6;
12857
12858   /* Parse args required to build the message */
12859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12860     {
12861       if (unformat (input, "del"))
12862         {
12863           is_add = 0;
12864         }
12865       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12866         {
12867           ipv4_set = 1;
12868         }
12869       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12870         {
12871           ipv6_set = 1;
12872         }
12873       else
12874         break;
12875     }
12876
12877   if (ipv4_set && ipv6_set)
12878     {
12879       errmsg ("both eid v4 and v6 addresses set\n");
12880       return -99;
12881     }
12882
12883   if (!ipv4_set && !ipv6_set)
12884     {
12885       errmsg ("eid addresses not set\n");
12886       return -99;
12887     }
12888
12889   /* Construct the API message */
12890   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12891
12892   mp->is_add = is_add;
12893   if (ipv6_set)
12894     {
12895       mp->is_ipv6 = 1;
12896       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12897     }
12898   else
12899     {
12900       mp->is_ipv6 = 0;
12901       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12902     }
12903
12904   /* send it... */
12905   S;
12906
12907   /* Wait for a reply... */
12908   W;
12909
12910   /* NOTREACHED */
12911   return 0;
12912 }
12913
12914 static int
12915 api_lisp_gpe_enable_disable (vat_main_t * vam)
12916 {
12917   unformat_input_t *input = vam->input;
12918   vl_api_lisp_gpe_enable_disable_t *mp;
12919   f64 timeout = ~0;
12920   u8 is_set = 0;
12921   u8 is_en = 1;
12922
12923   /* Parse args required to build the message */
12924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12925     {
12926       if (unformat (input, "enable"))
12927         {
12928           is_set = 1;
12929           is_en = 1;
12930         }
12931       else if (unformat (input, "disable"))
12932         {
12933           is_set = 1;
12934           is_en = 0;
12935         }
12936       else
12937         break;
12938     }
12939
12940   if (is_set == 0)
12941     {
12942       errmsg ("Value not set\n");
12943       return -99;
12944     }
12945
12946   /* Construct the API message */
12947   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12948
12949   mp->is_en = is_en;
12950
12951   /* send it... */
12952   S;
12953
12954   /* Wait for a reply... */
12955   W;
12956
12957   /* NOTREACHED */
12958   return 0;
12959 }
12960
12961 static int
12962 api_lisp_enable_disable (vat_main_t * vam)
12963 {
12964   unformat_input_t *input = vam->input;
12965   vl_api_lisp_enable_disable_t *mp;
12966   f64 timeout = ~0;
12967   u8 is_set = 0;
12968   u8 is_en = 0;
12969
12970   /* Parse args required to build the message */
12971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12972     {
12973       if (unformat (input, "enable"))
12974         {
12975           is_set = 1;
12976           is_en = 1;
12977         }
12978       else if (unformat (input, "disable"))
12979         {
12980           is_set = 1;
12981         }
12982       else
12983         break;
12984     }
12985
12986   if (!is_set)
12987     {
12988       errmsg ("Value not set\n");
12989       return -99;
12990     }
12991
12992   /* Construct the API message */
12993   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12994
12995   mp->is_en = is_en;
12996
12997   /* send it... */
12998   S;
12999
13000   /* Wait for a reply... */
13001   W;
13002
13003   /* NOTREACHED */
13004   return 0;
13005 }
13006
13007 static int
13008 api_show_lisp_map_request_mode (vat_main_t * vam)
13009 {
13010   f64 timeout = ~0;
13011   vl_api_show_lisp_map_request_mode_t *mp;
13012
13013   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13014
13015   /* send */
13016   S;
13017
13018   /* wait for reply */
13019   W;
13020
13021   return 0;
13022 }
13023
13024 static int
13025 api_lisp_map_request_mode (vat_main_t * vam)
13026 {
13027   f64 timeout = ~0;
13028   unformat_input_t *input = vam->input;
13029   vl_api_lisp_map_request_mode_t *mp;
13030   u8 mode = 0;
13031
13032   /* Parse args required to build the message */
13033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13034     {
13035       if (unformat (input, "dst-only"))
13036         mode = 0;
13037       else if (unformat (input, "src-dst"))
13038         mode = 1;
13039       else
13040         {
13041           errmsg ("parse error '%U'", format_unformat_error, input);
13042           return -99;
13043         }
13044     }
13045
13046   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13047
13048   mp->mode = mode;
13049
13050   /* send */
13051   S;
13052
13053   /* wait for reply */
13054   W;
13055
13056   /* notreached */
13057   return 0;
13058 }
13059
13060 /**
13061  * Enable/disable LISP proxy ITR.
13062  *
13063  * @param vam vpp API test context
13064  * @return return code
13065  */
13066 static int
13067 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13068 {
13069   f64 timeout = ~0;
13070   u8 ls_name_set = 0;
13071   unformat_input_t *input = vam->input;
13072   vl_api_lisp_pitr_set_locator_set_t *mp;
13073   u8 is_add = 1;
13074   u8 *ls_name = 0;
13075
13076   /* Parse args required to build the message */
13077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13078     {
13079       if (unformat (input, "del"))
13080         is_add = 0;
13081       else if (unformat (input, "locator-set %s", &ls_name))
13082         ls_name_set = 1;
13083       else
13084         {
13085           errmsg ("parse error '%U'", format_unformat_error, input);
13086           return -99;
13087         }
13088     }
13089
13090   if (!ls_name_set)
13091     {
13092       errmsg ("locator-set name not set!");
13093       return -99;
13094     }
13095
13096   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13097
13098   mp->is_add = is_add;
13099   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13100   vec_free (ls_name);
13101
13102   /* send */
13103   S;
13104
13105   /* wait for reply */
13106   W;
13107
13108   /* notreached */
13109   return 0;
13110 }
13111
13112 static int
13113 api_show_lisp_pitr (vat_main_t * vam)
13114 {
13115   vl_api_show_lisp_pitr_t *mp;
13116   f64 timeout = ~0;
13117
13118   if (!vam->json_output)
13119     {
13120       fformat (vam->ofp, "%=20s\n", "lisp status:");
13121     }
13122
13123   M (SHOW_LISP_PITR, show_lisp_pitr);
13124   /* send it... */
13125   S;
13126
13127   /* Wait for a reply... */
13128   W;
13129
13130   /* NOTREACHED */
13131   return 0;
13132 }
13133
13134 /**
13135  * Add/delete mapping between vni and vrf
13136  */
13137 static int
13138 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13139 {
13140   f64 timeout = ~0;
13141   unformat_input_t *input = vam->input;
13142   vl_api_lisp_eid_table_add_del_map_t *mp;
13143   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13144   u32 vni, vrf, bd_index;
13145
13146   /* Parse args required to build the message */
13147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13148     {
13149       if (unformat (input, "del"))
13150         is_add = 0;
13151       else if (unformat (input, "vrf %d", &vrf))
13152         vrf_set = 1;
13153       else if (unformat (input, "bd_index %d", &bd_index))
13154         bd_index_set = 1;
13155       else if (unformat (input, "vni %d", &vni))
13156         vni_set = 1;
13157       else
13158         break;
13159     }
13160
13161   if (!vni_set || (!vrf_set && !bd_index_set))
13162     {
13163       errmsg ("missing arguments!");
13164       return -99;
13165     }
13166
13167   if (vrf_set && bd_index_set)
13168     {
13169       errmsg ("error: both vrf and bd entered!");
13170       return -99;
13171     }
13172
13173   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13174
13175   mp->is_add = is_add;
13176   mp->vni = htonl (vni);
13177   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13178   mp->is_l2 = bd_index_set;
13179
13180   /* send */
13181   S;
13182
13183   /* wait for reply */
13184   W;
13185
13186   /* notreached */
13187   return 0;
13188 }
13189
13190 uword
13191 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13192 {
13193   u32 *action = va_arg (*args, u32 *);
13194   u8 *s = 0;
13195
13196   if (unformat (input, "%s", &s))
13197     {
13198       if (!strcmp ((char *) s, "no-action"))
13199         action[0] = 0;
13200       else if (!strcmp ((char *) s, "natively-forward"))
13201         action[0] = 1;
13202       else if (!strcmp ((char *) s, "send-map-request"))
13203         action[0] = 2;
13204       else if (!strcmp ((char *) s, "drop"))
13205         action[0] = 3;
13206       else
13207         {
13208           clib_warning ("invalid action: '%s'", s);
13209           action[0] = 3;
13210         }
13211     }
13212   else
13213     return 0;
13214
13215   vec_free (s);
13216   return 1;
13217 }
13218
13219 /**
13220  * Add/del remote mapping to/from LISP control plane
13221  *
13222  * @param vam vpp API test context
13223  * @return return code
13224  */
13225 static int
13226 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13227 {
13228   unformat_input_t *input = vam->input;
13229   vl_api_lisp_add_del_remote_mapping_t *mp;
13230   f64 timeout = ~0;
13231   u32 vni = 0;
13232   lisp_eid_vat_t _eid, *eid = &_eid;
13233   lisp_eid_vat_t _seid, *seid = &_seid;
13234   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13235   u32 action = ~0, p, w, data_len;
13236   ip4_address_t rloc4;
13237   ip6_address_t rloc6;
13238   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13239
13240   memset (&rloc, 0, sizeof (rloc));
13241
13242   /* Parse args required to build the message */
13243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13244     {
13245       if (unformat (input, "del-all"))
13246         {
13247           del_all = 1;
13248         }
13249       else if (unformat (input, "del"))
13250         {
13251           is_add = 0;
13252         }
13253       else if (unformat (input, "add"))
13254         {
13255           is_add = 1;
13256         }
13257       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13258         {
13259           eid_set = 1;
13260         }
13261       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13262         {
13263           seid_set = 1;
13264         }
13265       else if (unformat (input, "vni %d", &vni))
13266         {
13267           ;
13268         }
13269       else if (unformat (input, "p %d w %d", &p, &w))
13270         {
13271           if (!curr_rloc)
13272             {
13273               errmsg ("No RLOC configured for setting priority/weight!");
13274               return -99;
13275             }
13276           curr_rloc->priority = p;
13277           curr_rloc->weight = w;
13278         }
13279       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13280         {
13281           rloc.is_ip4 = 1;
13282           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13283           vec_add1 (rlocs, rloc);
13284           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13285         }
13286       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13287         {
13288           rloc.is_ip4 = 0;
13289           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13290           vec_add1 (rlocs, rloc);
13291           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13292         }
13293       else if (unformat (input, "action %U",
13294                          unformat_negative_mapping_action, &action))
13295         {
13296           ;
13297         }
13298       else
13299         {
13300           clib_warning ("parse error '%U'", format_unformat_error, input);
13301           return -99;
13302         }
13303     }
13304
13305   if (0 == eid_set)
13306     {
13307       errmsg ("missing params!");
13308       return -99;
13309     }
13310
13311   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13312     {
13313       errmsg ("no action set for negative map-reply!");
13314       return -99;
13315     }
13316
13317   data_len = vec_len (rlocs) * sizeof (rloc_t);
13318
13319   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13320   mp->is_add = is_add;
13321   mp->vni = htonl (vni);
13322   mp->action = (u8) action;
13323   mp->is_src_dst = seid_set;
13324   mp->eid_len = eid->len;
13325   mp->seid_len = seid->len;
13326   mp->del_all = del_all;
13327   mp->eid_type = eid->type;
13328   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13329   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13330
13331   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13332   clib_memcpy (mp->rlocs, rlocs, data_len);
13333   vec_free (rlocs);
13334
13335   /* send it... */
13336   S;
13337
13338   /* Wait for a reply... */
13339   W;
13340
13341   /* NOTREACHED */
13342   return 0;
13343 }
13344
13345 /**
13346  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13347  * forwarding entries in data-plane accordingly.
13348  *
13349  * @param vam vpp API test context
13350  * @return return code
13351  */
13352 static int
13353 api_lisp_add_del_adjacency (vat_main_t * vam)
13354 {
13355   unformat_input_t *input = vam->input;
13356   vl_api_lisp_add_del_adjacency_t *mp;
13357   f64 timeout = ~0;
13358   u32 vni = 0;
13359   ip4_address_t leid4, reid4;
13360   ip6_address_t leid6, reid6;
13361   u8 reid_mac[6] = { 0 };
13362   u8 leid_mac[6] = { 0 };
13363   u8 reid_type, leid_type;
13364   u32 leid_len = 0, reid_len = 0, len;
13365   u8 is_add = 1;
13366
13367   leid_type = reid_type = (u8) ~ 0;
13368
13369   /* Parse args required to build the message */
13370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13371     {
13372       if (unformat (input, "del"))
13373         {
13374           is_add = 0;
13375         }
13376       else if (unformat (input, "add"))
13377         {
13378           is_add = 1;
13379         }
13380       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13381                          &reid4, &len))
13382         {
13383           reid_type = 0;        /* ipv4 */
13384           reid_len = len;
13385         }
13386       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13387                          &reid6, &len))
13388         {
13389           reid_type = 1;        /* ipv6 */
13390           reid_len = len;
13391         }
13392       else if (unformat (input, "reid %U", unformat_ethernet_address,
13393                          reid_mac))
13394         {
13395           reid_type = 2;        /* mac */
13396         }
13397       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13398                          &leid4, &len))
13399         {
13400           leid_type = 0;        /* ipv4 */
13401           leid_len = len;
13402         }
13403       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13404                          &leid6, &len))
13405         {
13406           leid_type = 1;        /* ipv6 */
13407           leid_len = len;
13408         }
13409       else if (unformat (input, "leid %U", unformat_ethernet_address,
13410                          leid_mac))
13411         {
13412           leid_type = 2;        /* mac */
13413         }
13414       else if (unformat (input, "vni %d", &vni))
13415         {
13416           ;
13417         }
13418       else
13419         {
13420           errmsg ("parse error '%U'", format_unformat_error, input);
13421           return -99;
13422         }
13423     }
13424
13425   if ((u8) ~ 0 == reid_type)
13426     {
13427       errmsg ("missing params!");
13428       return -99;
13429     }
13430
13431   if (leid_type != reid_type)
13432     {
13433       errmsg ("remote and local EIDs are of different types!");
13434       return -99;
13435     }
13436
13437   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13438   mp->is_add = is_add;
13439   mp->vni = htonl (vni);
13440   mp->leid_len = leid_len;
13441   mp->reid_len = reid_len;
13442   mp->eid_type = reid_type;
13443
13444   switch (mp->eid_type)
13445     {
13446     case 0:
13447       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13448       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13449       break;
13450     case 1:
13451       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13452       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13453       break;
13454     case 2:
13455       clib_memcpy (mp->leid, leid_mac, 6);
13456       clib_memcpy (mp->reid, reid_mac, 6);
13457       break;
13458     default:
13459       errmsg ("unknown EID type %d!", mp->eid_type);
13460       return 0;
13461     }
13462
13463   /* send it... */
13464   S;
13465
13466   /* Wait for a reply... */
13467   W;
13468
13469   /* NOTREACHED */
13470   return 0;
13471 }
13472
13473 static int
13474 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13475 {
13476   unformat_input_t *input = vam->input;
13477   vl_api_lisp_gpe_add_del_iface_t *mp;
13478   f64 timeout = ~0;
13479   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13480   u32 dp_table = 0, vni = 0;
13481
13482   /* Parse args required to build the message */
13483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13484     {
13485       if (unformat (input, "up"))
13486         {
13487           action_set = 1;
13488           is_add = 1;
13489         }
13490       else if (unformat (input, "down"))
13491         {
13492           action_set = 1;
13493           is_add = 0;
13494         }
13495       else if (unformat (input, "table_id %d", &dp_table))
13496         {
13497           dp_table_set = 1;
13498         }
13499       else if (unformat (input, "bd_id %d", &dp_table))
13500         {
13501           dp_table_set = 1;
13502           is_l2 = 1;
13503         }
13504       else if (unformat (input, "vni %d", &vni))
13505         {
13506           vni_set = 1;
13507         }
13508       else
13509         break;
13510     }
13511
13512   if (action_set == 0)
13513     {
13514       errmsg ("Action not set\n");
13515       return -99;
13516     }
13517   if (dp_table_set == 0 || vni_set == 0)
13518     {
13519       errmsg ("vni and dp_table must be set\n");
13520       return -99;
13521     }
13522
13523   /* Construct the API message */
13524   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13525
13526   mp->is_add = is_add;
13527   mp->dp_table = dp_table;
13528   mp->is_l2 = is_l2;
13529   mp->vni = vni;
13530
13531   /* send it... */
13532   S;
13533
13534   /* Wait for a reply... */
13535   W;
13536
13537   /* NOTREACHED */
13538   return 0;
13539 }
13540
13541 /**
13542  * Add/del map request itr rlocs from LISP control plane and updates
13543  *
13544  * @param vam vpp API test context
13545  * @return return code
13546  */
13547 static int
13548 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13549 {
13550   unformat_input_t *input = vam->input;
13551   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13552   f64 timeout = ~0;
13553   u8 *locator_set_name = 0;
13554   u8 locator_set_name_set = 0;
13555   u8 is_add = 1;
13556
13557   /* Parse args required to build the message */
13558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13559     {
13560       if (unformat (input, "del"))
13561         {
13562           is_add = 0;
13563         }
13564       else if (unformat (input, "%_%v%_", &locator_set_name))
13565         {
13566           locator_set_name_set = 1;
13567         }
13568       else
13569         {
13570           clib_warning ("parse error '%U'", format_unformat_error, input);
13571           return -99;
13572         }
13573     }
13574
13575   if (is_add && !locator_set_name_set)
13576     {
13577       errmsg ("itr-rloc is not set!");
13578       return -99;
13579     }
13580
13581   if (is_add && vec_len (locator_set_name) > 64)
13582     {
13583       errmsg ("itr-rloc locator-set name too long\n");
13584       vec_free (locator_set_name);
13585       return -99;
13586     }
13587
13588   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13589   mp->is_add = is_add;
13590   if (is_add)
13591     {
13592       clib_memcpy (mp->locator_set_name, locator_set_name,
13593                    vec_len (locator_set_name));
13594     }
13595   else
13596     {
13597       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13598     }
13599   vec_free (locator_set_name);
13600
13601   /* send it... */
13602   S;
13603
13604   /* Wait for a reply... */
13605   W;
13606
13607   /* NOTREACHED */
13608   return 0;
13609 }
13610
13611 static int
13612 api_lisp_locator_dump (vat_main_t * vam)
13613 {
13614   unformat_input_t *input = vam->input;
13615   vl_api_lisp_locator_dump_t *mp;
13616   f64 timeout = ~0;
13617   u8 is_index_set = 0, is_name_set = 0;
13618   u8 *ls_name = 0;
13619   u32 ls_index = ~0;
13620
13621   /* Parse args required to build the message */
13622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13623     {
13624       if (unformat (input, "ls_name %_%v%_", &ls_name))
13625         {
13626           is_name_set = 1;
13627         }
13628       else if (unformat (input, "ls_index %d", &ls_index))
13629         {
13630           is_index_set = 1;
13631         }
13632       else
13633         {
13634           errmsg ("parse error '%U'", format_unformat_error, input);
13635           return -99;
13636         }
13637     }
13638
13639   if (!is_index_set && !is_name_set)
13640     {
13641       errmsg ("error: expected one of index or name!\n");
13642       return -99;
13643     }
13644
13645   if (is_index_set && is_name_set)
13646     {
13647       errmsg ("error: only one param expected!\n");
13648       return -99;
13649     }
13650
13651   if (vec_len (ls_name) > 62)
13652     {
13653       errmsg ("error: locator set name too long!");
13654       return -99;
13655     }
13656
13657   if (!vam->json_output)
13658     {
13659       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13660                "weight");
13661     }
13662
13663   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13664   mp->is_index_set = is_index_set;
13665
13666   if (is_index_set)
13667     mp->ls_index = clib_host_to_net_u32 (ls_index);
13668   else
13669     {
13670       vec_add1 (ls_name, 0);
13671       strncpy ((char *) mp->ls_name, (char *) ls_name,
13672                sizeof (mp->ls_name) - 1);
13673     }
13674
13675   /* send it... */
13676   S;
13677
13678   /* Use a control ping for synchronization */
13679   {
13680     vl_api_control_ping_t *mp;
13681     M (CONTROL_PING, control_ping);
13682     S;
13683   }
13684   /* Wait for a reply... */
13685   W;
13686
13687   /* NOTREACHED */
13688   return 0;
13689 }
13690
13691 static int
13692 api_lisp_locator_set_dump (vat_main_t * vam)
13693 {
13694   vl_api_lisp_locator_set_dump_t *mp;
13695   unformat_input_t *input = vam->input;
13696   f64 timeout = ~0;
13697   u8 filter = 0;
13698
13699   /* Parse args required to build the message */
13700   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13701     {
13702       if (unformat (input, "local"))
13703         {
13704           filter = 1;
13705         }
13706       else if (unformat (input, "remote"))
13707         {
13708           filter = 2;
13709         }
13710       else
13711         {
13712           errmsg ("parse error '%U'", format_unformat_error, input);
13713           return -99;
13714         }
13715     }
13716
13717   if (!vam->json_output)
13718     {
13719       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13720     }
13721
13722   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13723
13724   mp->filter = filter;
13725
13726   /* send it... */
13727   S;
13728
13729   /* Use a control ping for synchronization */
13730   {
13731     vl_api_control_ping_t *mp;
13732     M (CONTROL_PING, control_ping);
13733     S;
13734   }
13735   /* Wait for a reply... */
13736   W;
13737
13738   /* NOTREACHED */
13739   return 0;
13740 }
13741
13742 static int
13743 api_lisp_eid_table_map_dump (vat_main_t * vam)
13744 {
13745   u8 is_l2 = 0;
13746   u8 mode_set = 0;
13747   unformat_input_t *input = vam->input;
13748   vl_api_lisp_eid_table_map_dump_t *mp;
13749   f64 timeout = ~0;
13750
13751   /* Parse args required to build the message */
13752   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13753     {
13754       if (unformat (input, "l2"))
13755         {
13756           is_l2 = 1;
13757           mode_set = 1;
13758         }
13759       else if (unformat (input, "l3"))
13760         {
13761           is_l2 = 0;
13762           mode_set = 1;
13763         }
13764       else
13765         {
13766           errmsg ("parse error '%U'", format_unformat_error, input);
13767           return -99;
13768         }
13769     }
13770
13771   if (!mode_set)
13772     {
13773       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13774       return -99;
13775     }
13776
13777   if (!vam->json_output)
13778     {
13779       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13780     }
13781
13782   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13783   mp->is_l2 = is_l2;
13784
13785   /* send it... */
13786   S;
13787
13788   /* Use a control ping for synchronization */
13789   {
13790     vl_api_control_ping_t *mp;
13791     M (CONTROL_PING, control_ping);
13792     S;
13793   }
13794   /* Wait for a reply... */
13795   W;
13796
13797   /* NOTREACHED */
13798   return 0;
13799 }
13800
13801 static int
13802 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13803 {
13804   vl_api_lisp_eid_table_vni_dump_t *mp;
13805   f64 timeout = ~0;
13806
13807   if (!vam->json_output)
13808     {
13809       fformat (vam->ofp, "VNI\n");
13810     }
13811
13812   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13813
13814   /* send it... */
13815   S;
13816
13817   /* Use a control ping for synchronization */
13818   {
13819     vl_api_control_ping_t *mp;
13820     M (CONTROL_PING, control_ping);
13821     S;
13822   }
13823   /* Wait for a reply... */
13824   W;
13825
13826   /* NOTREACHED */
13827   return 0;
13828 }
13829
13830 static int
13831 api_lisp_eid_table_dump (vat_main_t * vam)
13832 {
13833   unformat_input_t *i = vam->input;
13834   vl_api_lisp_eid_table_dump_t *mp;
13835   f64 timeout = ~0;
13836   struct in_addr ip4;
13837   struct in6_addr ip6;
13838   u8 mac[6];
13839   u8 eid_type = ~0, eid_set = 0;
13840   u32 prefix_length = ~0, t, vni = 0;
13841   u8 filter = 0;
13842
13843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13844     {
13845       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13846         {
13847           eid_set = 1;
13848           eid_type = 0;
13849           prefix_length = t;
13850         }
13851       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13852         {
13853           eid_set = 1;
13854           eid_type = 1;
13855           prefix_length = t;
13856         }
13857       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13858         {
13859           eid_set = 1;
13860           eid_type = 2;
13861         }
13862       else if (unformat (i, "vni %d", &t))
13863         {
13864           vni = t;
13865         }
13866       else if (unformat (i, "local"))
13867         {
13868           filter = 1;
13869         }
13870       else if (unformat (i, "remote"))
13871         {
13872           filter = 2;
13873         }
13874       else
13875         {
13876           errmsg ("parse error '%U'", format_unformat_error, i);
13877           return -99;
13878         }
13879     }
13880
13881   if (!vam->json_output)
13882     {
13883       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
13884                "ls_index", "ttl", "authoritative");
13885     }
13886
13887   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13888
13889   mp->filter = filter;
13890   if (eid_set)
13891     {
13892       mp->eid_set = 1;
13893       mp->vni = htonl (vni);
13894       mp->eid_type = eid_type;
13895       switch (eid_type)
13896         {
13897         case 0:
13898           mp->prefix_length = prefix_length;
13899           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13900           break;
13901         case 1:
13902           mp->prefix_length = prefix_length;
13903           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13904           break;
13905         case 2:
13906           clib_memcpy (mp->eid, mac, sizeof (mac));
13907           break;
13908         default:
13909           errmsg ("unknown EID type %d!", eid_type);
13910           return -99;
13911         }
13912     }
13913
13914   /* send it... */
13915   S;
13916
13917   /* Use a control ping for synchronization */
13918   {
13919     vl_api_control_ping_t *mp;
13920     M (CONTROL_PING, control_ping);
13921     S;
13922   }
13923
13924   /* Wait for a reply... */
13925   W;
13926
13927   /* NOTREACHED */
13928   return 0;
13929 }
13930
13931 static int
13932 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13933 {
13934   vl_api_lisp_gpe_tunnel_dump_t *mp;
13935   f64 timeout = ~0;
13936
13937   if (!vam->json_output)
13938     {
13939       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13940                "%=16s%=16s%=16s%=16s%=16s\n",
13941                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13942                "Decap next", "Lisp version", "Flags", "Next protocol",
13943                "ver_res", "res", "iid");
13944     }
13945
13946   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13947   /* send it... */
13948   S;
13949
13950   /* Use a control ping for synchronization */
13951   {
13952     vl_api_control_ping_t *mp;
13953     M (CONTROL_PING, control_ping);
13954     S;
13955   }
13956   /* Wait for a reply... */
13957   W;
13958
13959   /* NOTREACHED */
13960   return 0;
13961 }
13962
13963 static int
13964 api_lisp_adjacencies_get (vat_main_t * vam)
13965 {
13966   unformat_input_t *i = vam->input;
13967   vl_api_lisp_adjacencies_get_t *mp;
13968   f64 timeout = ~0;
13969   u8 vni_set = 0;
13970   u32 vni = ~0;
13971
13972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13973     {
13974       if (unformat (i, "vni %d", &vni))
13975         {
13976           vni_set = 1;
13977         }
13978       else
13979         {
13980           errmsg ("parse error '%U'\n", format_unformat_error, i);
13981           return -99;
13982         }
13983     }
13984
13985   if (!vni_set)
13986     {
13987       errmsg ("vni not set!\n");
13988       return -99;
13989     }
13990
13991   if (!vam->json_output)
13992     {
13993       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
13994     }
13995
13996   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
13997   mp->vni = clib_host_to_net_u32 (vni);
13998
13999   /* send it... */
14000   S;
14001
14002   /* Wait for a reply... */
14003   W;
14004
14005   /* NOTREACHED */
14006   return 0;
14007 }
14008
14009 static int
14010 api_lisp_map_resolver_dump (vat_main_t * vam)
14011 {
14012   vl_api_lisp_map_resolver_dump_t *mp;
14013   f64 timeout = ~0;
14014
14015   if (!vam->json_output)
14016     {
14017       fformat (vam->ofp, "%=20s\n", "Map resolver");
14018     }
14019
14020   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14021   /* send it... */
14022   S;
14023
14024   /* Use a control ping for synchronization */
14025   {
14026     vl_api_control_ping_t *mp;
14027     M (CONTROL_PING, control_ping);
14028     S;
14029   }
14030   /* Wait for a reply... */
14031   W;
14032
14033   /* NOTREACHED */
14034   return 0;
14035 }
14036
14037 static int
14038 api_show_lisp_status (vat_main_t * vam)
14039 {
14040   vl_api_show_lisp_status_t *mp;
14041   f64 timeout = ~0;
14042
14043   if (!vam->json_output)
14044     {
14045       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14046     }
14047
14048   M (SHOW_LISP_STATUS, show_lisp_status);
14049   /* send it... */
14050   S;
14051   /* Wait for a reply... */
14052   W;
14053
14054   /* NOTREACHED */
14055   return 0;
14056 }
14057
14058 static int
14059 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14060 {
14061   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14062   f64 timeout = ~0;
14063
14064   if (!vam->json_output)
14065     {
14066       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14067     }
14068
14069   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14070   /* send it... */
14071   S;
14072   /* Wait for a reply... */
14073   W;
14074
14075   /* NOTREACHED */
14076   return 0;
14077 }
14078
14079 static int
14080 api_af_packet_create (vat_main_t * vam)
14081 {
14082   unformat_input_t *i = vam->input;
14083   vl_api_af_packet_create_t *mp;
14084   f64 timeout;
14085   u8 *host_if_name = 0;
14086   u8 hw_addr[6];
14087   u8 random_hw_addr = 1;
14088
14089   memset (hw_addr, 0, sizeof (hw_addr));
14090
14091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14092     {
14093       if (unformat (i, "name %s", &host_if_name))
14094         vec_add1 (host_if_name, 0);
14095       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14096         random_hw_addr = 0;
14097       else
14098         break;
14099     }
14100
14101   if (!vec_len (host_if_name))
14102     {
14103       errmsg ("host-interface name must be specified");
14104       return -99;
14105     }
14106
14107   if (vec_len (host_if_name) > 64)
14108     {
14109       errmsg ("host-interface name too long");
14110       return -99;
14111     }
14112
14113   M (AF_PACKET_CREATE, af_packet_create);
14114
14115   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14116   clib_memcpy (mp->hw_addr, hw_addr, 6);
14117   mp->use_random_hw_addr = random_hw_addr;
14118   vec_free (host_if_name);
14119
14120   S;
14121   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14122   /* NOTREACHED */
14123   return 0;
14124 }
14125
14126 static int
14127 api_af_packet_delete (vat_main_t * vam)
14128 {
14129   unformat_input_t *i = vam->input;
14130   vl_api_af_packet_delete_t *mp;
14131   f64 timeout;
14132   u8 *host_if_name = 0;
14133
14134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14135     {
14136       if (unformat (i, "name %s", &host_if_name))
14137         vec_add1 (host_if_name, 0);
14138       else
14139         break;
14140     }
14141
14142   if (!vec_len (host_if_name))
14143     {
14144       errmsg ("host-interface name must be specified");
14145       return -99;
14146     }
14147
14148   if (vec_len (host_if_name) > 64)
14149     {
14150       errmsg ("host-interface name too long");
14151       return -99;
14152     }
14153
14154   M (AF_PACKET_DELETE, af_packet_delete);
14155
14156   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14157   vec_free (host_if_name);
14158
14159   S;
14160   W;
14161   /* NOTREACHED */
14162   return 0;
14163 }
14164
14165 static int
14166 api_policer_add_del (vat_main_t * vam)
14167 {
14168   unformat_input_t *i = vam->input;
14169   vl_api_policer_add_del_t *mp;
14170   f64 timeout;
14171   u8 is_add = 1;
14172   u8 *name = 0;
14173   u32 cir = 0;
14174   u32 eir = 0;
14175   u64 cb = 0;
14176   u64 eb = 0;
14177   u8 rate_type = 0;
14178   u8 round_type = 0;
14179   u8 type = 0;
14180   u8 color_aware = 0;
14181   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14182
14183   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14184   conform_action.dscp = 0;
14185   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14186   exceed_action.dscp = 0;
14187   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14188   violate_action.dscp = 0;
14189
14190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14191     {
14192       if (unformat (i, "del"))
14193         is_add = 0;
14194       else if (unformat (i, "name %s", &name))
14195         vec_add1 (name, 0);
14196       else if (unformat (i, "cir %u", &cir))
14197         ;
14198       else if (unformat (i, "eir %u", &eir))
14199         ;
14200       else if (unformat (i, "cb %u", &cb))
14201         ;
14202       else if (unformat (i, "eb %u", &eb))
14203         ;
14204       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14205                          &rate_type))
14206         ;
14207       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14208                          &round_type))
14209         ;
14210       else if (unformat (i, "type %U", unformat_policer_type, &type))
14211         ;
14212       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14213                          &conform_action))
14214         ;
14215       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14216                          &exceed_action))
14217         ;
14218       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14219                          &violate_action))
14220         ;
14221       else if (unformat (i, "color-aware"))
14222         color_aware = 1;
14223       else
14224         break;
14225     }
14226
14227   if (!vec_len (name))
14228     {
14229       errmsg ("policer name must be specified");
14230       return -99;
14231     }
14232
14233   if (vec_len (name) > 64)
14234     {
14235       errmsg ("policer name too long");
14236       return -99;
14237     }
14238
14239   M (POLICER_ADD_DEL, policer_add_del);
14240
14241   clib_memcpy (mp->name, name, vec_len (name));
14242   vec_free (name);
14243   mp->is_add = is_add;
14244   mp->cir = cir;
14245   mp->eir = eir;
14246   mp->cb = cb;
14247   mp->eb = eb;
14248   mp->rate_type = rate_type;
14249   mp->round_type = round_type;
14250   mp->type = type;
14251   mp->conform_action_type = conform_action.action_type;
14252   mp->conform_dscp = conform_action.dscp;
14253   mp->exceed_action_type = exceed_action.action_type;
14254   mp->exceed_dscp = exceed_action.dscp;
14255   mp->violate_action_type = violate_action.action_type;
14256   mp->violate_dscp = violate_action.dscp;
14257   mp->color_aware = color_aware;
14258
14259   S;
14260   W;
14261   /* NOTREACHED */
14262   return 0;
14263 }
14264
14265 static int
14266 api_policer_dump (vat_main_t * vam)
14267 {
14268   unformat_input_t *i = vam->input;
14269   vl_api_policer_dump_t *mp;
14270   f64 timeout = ~0;
14271   u8 *match_name = 0;
14272   u8 match_name_valid = 0;
14273
14274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14275     {
14276       if (unformat (i, "name %s", &match_name))
14277         {
14278           vec_add1 (match_name, 0);
14279           match_name_valid = 1;
14280         }
14281       else
14282         break;
14283     }
14284
14285   M (POLICER_DUMP, policer_dump);
14286   mp->match_name_valid = match_name_valid;
14287   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14288   vec_free (match_name);
14289   /* send it... */
14290   S;
14291
14292   /* Use a control ping for synchronization */
14293   {
14294     vl_api_control_ping_t *mp;
14295     M (CONTROL_PING, control_ping);
14296     S;
14297   }
14298   /* Wait for a reply... */
14299   W;
14300
14301   /* NOTREACHED */
14302   return 0;
14303 }
14304
14305 static int
14306 api_policer_classify_set_interface (vat_main_t * vam)
14307 {
14308   unformat_input_t *i = vam->input;
14309   vl_api_policer_classify_set_interface_t *mp;
14310   f64 timeout;
14311   u32 sw_if_index;
14312   int sw_if_index_set;
14313   u32 ip4_table_index = ~0;
14314   u32 ip6_table_index = ~0;
14315   u32 l2_table_index = ~0;
14316   u8 is_add = 1;
14317
14318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14319     {
14320       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14321         sw_if_index_set = 1;
14322       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14323         sw_if_index_set = 1;
14324       else if (unformat (i, "del"))
14325         is_add = 0;
14326       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14327         ;
14328       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14329         ;
14330       else if (unformat (i, "l2-table %d", &l2_table_index))
14331         ;
14332       else
14333         {
14334           clib_warning ("parse error '%U'", format_unformat_error, i);
14335           return -99;
14336         }
14337     }
14338
14339   if (sw_if_index_set == 0)
14340     {
14341       errmsg ("missing interface name or sw_if_index\n");
14342       return -99;
14343     }
14344
14345   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14346
14347   mp->sw_if_index = ntohl (sw_if_index);
14348   mp->ip4_table_index = ntohl (ip4_table_index);
14349   mp->ip6_table_index = ntohl (ip6_table_index);
14350   mp->l2_table_index = ntohl (l2_table_index);
14351   mp->is_add = is_add;
14352
14353   S;
14354   W;
14355   /* NOTREACHED */
14356   return 0;
14357 }
14358
14359 static int
14360 api_policer_classify_dump (vat_main_t * vam)
14361 {
14362   unformat_input_t *i = vam->input;
14363   vl_api_policer_classify_dump_t *mp;
14364   f64 timeout = ~0;
14365   u8 type = POLICER_CLASSIFY_N_TABLES;
14366
14367   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14368     ;
14369   else
14370     {
14371       errmsg ("classify table type must be specified\n");
14372       return -99;
14373     }
14374
14375   if (!vam->json_output)
14376     {
14377       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14378     }
14379
14380   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14381   mp->type = type;
14382   /* send it... */
14383   S;
14384
14385   /* Use a control ping for synchronization */
14386   {
14387     vl_api_control_ping_t *mp;
14388     M (CONTROL_PING, control_ping);
14389     S;
14390   }
14391   /* Wait for a reply... */
14392   W;
14393
14394   /* NOTREACHED */
14395   return 0;
14396 }
14397
14398 static int
14399 api_netmap_create (vat_main_t * vam)
14400 {
14401   unformat_input_t *i = vam->input;
14402   vl_api_netmap_create_t *mp;
14403   f64 timeout;
14404   u8 *if_name = 0;
14405   u8 hw_addr[6];
14406   u8 random_hw_addr = 1;
14407   u8 is_pipe = 0;
14408   u8 is_master = 0;
14409
14410   memset (hw_addr, 0, sizeof (hw_addr));
14411
14412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14413     {
14414       if (unformat (i, "name %s", &if_name))
14415         vec_add1 (if_name, 0);
14416       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14417         random_hw_addr = 0;
14418       else if (unformat (i, "pipe"))
14419         is_pipe = 1;
14420       else if (unformat (i, "master"))
14421         is_master = 1;
14422       else if (unformat (i, "slave"))
14423         is_master = 0;
14424       else
14425         break;
14426     }
14427
14428   if (!vec_len (if_name))
14429     {
14430       errmsg ("interface name must be specified");
14431       return -99;
14432     }
14433
14434   if (vec_len (if_name) > 64)
14435     {
14436       errmsg ("interface name too long");
14437       return -99;
14438     }
14439
14440   M (NETMAP_CREATE, netmap_create);
14441
14442   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14443   clib_memcpy (mp->hw_addr, hw_addr, 6);
14444   mp->use_random_hw_addr = random_hw_addr;
14445   mp->is_pipe = is_pipe;
14446   mp->is_master = is_master;
14447   vec_free (if_name);
14448
14449   S;
14450   W;
14451   /* NOTREACHED */
14452   return 0;
14453 }
14454
14455 static int
14456 api_netmap_delete (vat_main_t * vam)
14457 {
14458   unformat_input_t *i = vam->input;
14459   vl_api_netmap_delete_t *mp;
14460   f64 timeout;
14461   u8 *if_name = 0;
14462
14463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14464     {
14465       if (unformat (i, "name %s", &if_name))
14466         vec_add1 (if_name, 0);
14467       else
14468         break;
14469     }
14470
14471   if (!vec_len (if_name))
14472     {
14473       errmsg ("interface name must be specified");
14474       return -99;
14475     }
14476
14477   if (vec_len (if_name) > 64)
14478     {
14479       errmsg ("interface name too long");
14480       return -99;
14481     }
14482
14483   M (NETMAP_DELETE, netmap_delete);
14484
14485   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14486   vec_free (if_name);
14487
14488   S;
14489   W;
14490   /* NOTREACHED */
14491   return 0;
14492 }
14493
14494 static void vl_api_mpls_gre_tunnel_details_t_handler
14495   (vl_api_mpls_gre_tunnel_details_t * mp)
14496 {
14497   vat_main_t *vam = &vat_main;
14498   i32 i;
14499   i32 len = ntohl (mp->nlabels);
14500
14501   if (mp->l2_only == 0)
14502     {
14503       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14504                ntohl (mp->tunnel_index),
14505                format_ip4_address, &mp->tunnel_src,
14506                format_ip4_address, &mp->tunnel_dst,
14507                format_ip4_address, &mp->intfc_address,
14508                ntohl (mp->mask_width));
14509       for (i = 0; i < len; i++)
14510         {
14511           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14512         }
14513       fformat (vam->ofp, "\n");
14514       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14515                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14516     }
14517   else
14518     {
14519       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14520                ntohl (mp->tunnel_index),
14521                format_ip4_address, &mp->tunnel_src,
14522                format_ip4_address, &mp->tunnel_dst,
14523                format_ip4_address, &mp->intfc_address);
14524       for (i = 0; i < len; i++)
14525         {
14526           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14527         }
14528       fformat (vam->ofp, "\n");
14529       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14530                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14531     }
14532 }
14533
14534 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14535   (vl_api_mpls_gre_tunnel_details_t * mp)
14536 {
14537   vat_main_t *vam = &vat_main;
14538   vat_json_node_t *node = NULL;
14539   struct in_addr ip4;
14540   i32 i;
14541   i32 len = ntohl (mp->nlabels);
14542
14543   if (VAT_JSON_ARRAY != vam->json_tree.type)
14544     {
14545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14546       vat_json_init_array (&vam->json_tree);
14547     }
14548   node = vat_json_array_add (&vam->json_tree);
14549
14550   vat_json_init_object (node);
14551   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14552   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14553   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14554   vat_json_object_add_uint (node, "inner_fib_index",
14555                             ntohl (mp->inner_fib_index));
14556   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14557   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14558   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14559   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14560   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14561   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14562   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14563   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14564   vat_json_object_add_uint (node, "outer_fib_index",
14565                             ntohl (mp->outer_fib_index));
14566   vat_json_object_add_uint (node, "label_count", len);
14567   for (i = 0; i < len; i++)
14568     {
14569       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14570     }
14571 }
14572
14573 static int
14574 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14575 {
14576   vl_api_mpls_gre_tunnel_dump_t *mp;
14577   f64 timeout;
14578   i32 index = -1;
14579
14580   /* Parse args required to build the message */
14581   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14582     {
14583       if (!unformat (vam->input, "tunnel_index %d", &index))
14584         {
14585           index = -1;
14586           break;
14587         }
14588     }
14589
14590   fformat (vam->ofp, "  tunnel_index %d\n", index);
14591
14592   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14593   mp->tunnel_index = htonl (index);
14594   S;
14595
14596   /* Use a control ping for synchronization */
14597   {
14598     vl_api_control_ping_t *mp;
14599     M (CONTROL_PING, control_ping);
14600     S;
14601   }
14602   W;
14603 }
14604
14605 static void vl_api_mpls_eth_tunnel_details_t_handler
14606   (vl_api_mpls_eth_tunnel_details_t * mp)
14607 {
14608   vat_main_t *vam = &vat_main;
14609   i32 i;
14610   i32 len = ntohl (mp->nlabels);
14611
14612   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14613            ntohl (mp->tunnel_index),
14614            format_ethernet_address, &mp->tunnel_dst_mac,
14615            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14616   for (i = 0; i < len; i++)
14617     {
14618       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14619     }
14620   fformat (vam->ofp, "\n");
14621   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14622            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14623 }
14624
14625 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14626   (vl_api_mpls_eth_tunnel_details_t * mp)
14627 {
14628   vat_main_t *vam = &vat_main;
14629   vat_json_node_t *node = NULL;
14630   struct in_addr ip4;
14631   i32 i;
14632   i32 len = ntohl (mp->nlabels);
14633
14634   if (VAT_JSON_ARRAY != vam->json_tree.type)
14635     {
14636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14637       vat_json_init_array (&vam->json_tree);
14638     }
14639   node = vat_json_array_add (&vam->json_tree);
14640
14641   vat_json_init_object (node);
14642   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14643   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14644   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14645   vat_json_object_add_uint (node, "inner_fib_index",
14646                             ntohl (mp->inner_fib_index));
14647   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14648   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14649   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14650   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14651   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14652                                    format (0, "%U", format_ethernet_address,
14653                                            &mp->tunnel_dst_mac));
14654   vat_json_object_add_uint (node, "tx_sw_if_index",
14655                             ntohl (mp->tx_sw_if_index));
14656   vat_json_object_add_uint (node, "label_count", len);
14657   for (i = 0; i < len; i++)
14658     {
14659       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14660     }
14661 }
14662
14663 static int
14664 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14665 {
14666   vl_api_mpls_eth_tunnel_dump_t *mp;
14667   f64 timeout;
14668   i32 index = -1;
14669
14670   /* Parse args required to build the message */
14671   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14672     {
14673       if (!unformat (vam->input, "tunnel_index %d", &index))
14674         {
14675           index = -1;
14676           break;
14677         }
14678     }
14679
14680   fformat (vam->ofp, "  tunnel_index %d\n", index);
14681
14682   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14683   mp->tunnel_index = htonl (index);
14684   S;
14685
14686   /* Use a control ping for synchronization */
14687   {
14688     vl_api_control_ping_t *mp;
14689     M (CONTROL_PING, control_ping);
14690     S;
14691   }
14692   W;
14693 }
14694
14695 static void vl_api_mpls_fib_encap_details_t_handler
14696   (vl_api_mpls_fib_encap_details_t * mp)
14697 {
14698   vat_main_t *vam = &vat_main;
14699   i32 i;
14700   i32 len = ntohl (mp->nlabels);
14701
14702   fformat (vam->ofp, "table %d, dest %U, label ",
14703            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14704   for (i = 0; i < len; i++)
14705     {
14706       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14707     }
14708   fformat (vam->ofp, "\n");
14709 }
14710
14711 static void vl_api_mpls_fib_encap_details_t_handler_json
14712   (vl_api_mpls_fib_encap_details_t * mp)
14713 {
14714   vat_main_t *vam = &vat_main;
14715   vat_json_node_t *node = NULL;
14716   i32 i;
14717   i32 len = ntohl (mp->nlabels);
14718   struct in_addr ip4;
14719
14720   if (VAT_JSON_ARRAY != vam->json_tree.type)
14721     {
14722       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14723       vat_json_init_array (&vam->json_tree);
14724     }
14725   node = vat_json_array_add (&vam->json_tree);
14726
14727   vat_json_init_object (node);
14728   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14729   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14730   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14731   vat_json_object_add_ip4 (node, "dest", ip4);
14732   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14733   vat_json_object_add_uint (node, "label_count", len);
14734   for (i = 0; i < len; i++)
14735     {
14736       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14737     }
14738 }
14739
14740 static int
14741 api_mpls_fib_encap_dump (vat_main_t * vam)
14742 {
14743   vl_api_mpls_fib_encap_dump_t *mp;
14744   f64 timeout;
14745
14746   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14747   S;
14748
14749   /* Use a control ping for synchronization */
14750   {
14751     vl_api_control_ping_t *mp;
14752     M (CONTROL_PING, control_ping);
14753     S;
14754   }
14755   W;
14756 }
14757
14758 static void vl_api_mpls_fib_decap_details_t_handler
14759   (vl_api_mpls_fib_decap_details_t * mp)
14760 {
14761   vat_main_t *vam = &vat_main;
14762
14763   fformat (vam->ofp,
14764            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14765            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14766            ntohl (mp->label), ntohl (mp->s_bit));
14767 }
14768
14769 static void vl_api_mpls_fib_decap_details_t_handler_json
14770   (vl_api_mpls_fib_decap_details_t * mp)
14771 {
14772   vat_main_t *vam = &vat_main;
14773   vat_json_node_t *node = NULL;
14774   struct in_addr ip4;
14775
14776   if (VAT_JSON_ARRAY != vam->json_tree.type)
14777     {
14778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14779       vat_json_init_array (&vam->json_tree);
14780     }
14781   node = vat_json_array_add (&vam->json_tree);
14782
14783   vat_json_init_object (node);
14784   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14785   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14786   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14787   vat_json_object_add_ip4 (node, "dest", ip4);
14788   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14789   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14790   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14791   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14792   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14793 }
14794
14795 static int
14796 api_mpls_fib_decap_dump (vat_main_t * vam)
14797 {
14798   vl_api_mpls_fib_decap_dump_t *mp;
14799   f64 timeout;
14800
14801   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14802   S;
14803
14804   /* Use a control ping for synchronization */
14805   {
14806     vl_api_control_ping_t *mp;
14807     M (CONTROL_PING, control_ping);
14808     S;
14809   }
14810   W;
14811 }
14812
14813 int
14814 api_classify_table_ids (vat_main_t * vam)
14815 {
14816   vl_api_classify_table_ids_t *mp;
14817   f64 timeout;
14818
14819   /* Construct the API message */
14820   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14821   mp->context = 0;
14822
14823   S;
14824   W;
14825   /* NOTREACHED */
14826   return 0;
14827 }
14828
14829 int
14830 api_classify_table_by_interface (vat_main_t * vam)
14831 {
14832   unformat_input_t *input = vam->input;
14833   vl_api_classify_table_by_interface_t *mp;
14834   f64 timeout;
14835
14836   u32 sw_if_index = ~0;
14837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14838     {
14839       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14840         ;
14841       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14842         ;
14843       else
14844         break;
14845     }
14846   if (sw_if_index == ~0)
14847     {
14848       errmsg ("missing interface name or sw_if_index\n");
14849       return -99;
14850     }
14851
14852   /* Construct the API message */
14853   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14854   mp->context = 0;
14855   mp->sw_if_index = ntohl (sw_if_index);
14856
14857   S;
14858   W;
14859   /* NOTREACHED */
14860   return 0;
14861 }
14862
14863 int
14864 api_classify_table_info (vat_main_t * vam)
14865 {
14866   unformat_input_t *input = vam->input;
14867   vl_api_classify_table_info_t *mp;
14868   f64 timeout;
14869
14870   u32 table_id = ~0;
14871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14872     {
14873       if (unformat (input, "table_id %d", &table_id))
14874         ;
14875       else
14876         break;
14877     }
14878   if (table_id == ~0)
14879     {
14880       errmsg ("missing table id\n");
14881       return -99;
14882     }
14883
14884   /* Construct the API message */
14885   M (CLASSIFY_TABLE_INFO, classify_table_info);
14886   mp->context = 0;
14887   mp->table_id = ntohl (table_id);
14888
14889   S;
14890   W;
14891   /* NOTREACHED */
14892   return 0;
14893 }
14894
14895 int
14896 api_classify_session_dump (vat_main_t * vam)
14897 {
14898   unformat_input_t *input = vam->input;
14899   vl_api_classify_session_dump_t *mp;
14900   f64 timeout;
14901
14902   u32 table_id = ~0;
14903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14904     {
14905       if (unformat (input, "table_id %d", &table_id))
14906         ;
14907       else
14908         break;
14909     }
14910   if (table_id == ~0)
14911     {
14912       errmsg ("missing table id\n");
14913       return -99;
14914     }
14915
14916   /* Construct the API message */
14917   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14918   mp->context = 0;
14919   mp->table_id = ntohl (table_id);
14920   S;
14921
14922   /* Use a control ping for synchronization */
14923   {
14924     vl_api_control_ping_t *mp;
14925     M (CONTROL_PING, control_ping);
14926     S;
14927   }
14928   W;
14929   /* NOTREACHED */
14930   return 0;
14931 }
14932
14933 static void
14934 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14935 {
14936   vat_main_t *vam = &vat_main;
14937
14938   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14939            "src_address %U, vrf_id %d, path_mtu %u, "
14940            "template_interval %u, udp_checksum %d\n",
14941            format_ip4_address, mp->collector_address,
14942            ntohs (mp->collector_port),
14943            format_ip4_address, mp->src_address,
14944            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14945            ntohl (mp->template_interval), mp->udp_checksum);
14946
14947   vam->retval = 0;
14948   vam->result_ready = 1;
14949 }
14950
14951 static void
14952   vl_api_ipfix_exporter_details_t_handler_json
14953   (vl_api_ipfix_exporter_details_t * mp)
14954 {
14955   vat_main_t *vam = &vat_main;
14956   vat_json_node_t node;
14957   struct in_addr collector_address;
14958   struct in_addr src_address;
14959
14960   vat_json_init_object (&node);
14961   clib_memcpy (&collector_address, &mp->collector_address,
14962                sizeof (collector_address));
14963   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14964   vat_json_object_add_uint (&node, "collector_port",
14965                             ntohs (mp->collector_port));
14966   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14967   vat_json_object_add_ip4 (&node, "src_address", src_address);
14968   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14969   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14970   vat_json_object_add_uint (&node, "template_interval",
14971                             ntohl (mp->template_interval));
14972   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14973
14974   vat_json_print (vam->ofp, &node);
14975   vat_json_free (&node);
14976   vam->retval = 0;
14977   vam->result_ready = 1;
14978 }
14979
14980 int
14981 api_ipfix_exporter_dump (vat_main_t * vam)
14982 {
14983   vl_api_ipfix_exporter_dump_t *mp;
14984   f64 timeout;
14985
14986   /* Construct the API message */
14987   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14988   mp->context = 0;
14989
14990   S;
14991   W;
14992   /* NOTREACHED */
14993   return 0;
14994 }
14995
14996 static int
14997 api_ipfix_classify_stream_dump (vat_main_t * vam)
14998 {
14999   vl_api_ipfix_classify_stream_dump_t *mp;
15000   f64 timeout;
15001
15002   /* Construct the API message */
15003   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15004   mp->context = 0;
15005
15006   S;
15007   W;
15008   /* NOTREACHED */
15009   return 0;
15010 }
15011
15012 static void
15013   vl_api_ipfix_classify_stream_details_t_handler
15014   (vl_api_ipfix_classify_stream_details_t * mp)
15015 {
15016   vat_main_t *vam = &vat_main;
15017   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15018            ntohl (mp->domain_id), ntohs (mp->src_port));
15019   vam->retval = 0;
15020   vam->result_ready = 1;
15021 }
15022
15023 static void
15024   vl_api_ipfix_classify_stream_details_t_handler_json
15025   (vl_api_ipfix_classify_stream_details_t * mp)
15026 {
15027   vat_main_t *vam = &vat_main;
15028   vat_json_node_t node;
15029
15030   vat_json_init_object (&node);
15031   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15032   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15033
15034   vat_json_print (vam->ofp, &node);
15035   vat_json_free (&node);
15036   vam->retval = 0;
15037   vam->result_ready = 1;
15038 }
15039
15040 static int
15041 api_ipfix_classify_table_dump (vat_main_t * vam)
15042 {
15043   vl_api_ipfix_classify_table_dump_t *mp;
15044   f64 timeout;
15045
15046   if (!vam->json_output)
15047     {
15048       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15049                "transport_protocol");
15050     }
15051
15052   /* Construct the API message */
15053   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15054
15055   /* send it... */
15056   S;
15057
15058   /* Use a control ping for synchronization */
15059   {
15060     vl_api_control_ping_t *mp;
15061     M (CONTROL_PING, control_ping);
15062     S;
15063   }
15064   W;
15065 }
15066
15067 static void
15068   vl_api_ipfix_classify_table_details_t_handler
15069   (vl_api_ipfix_classify_table_details_t * mp)
15070 {
15071   vat_main_t *vam = &vat_main;
15072   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15073            mp->transport_protocol);
15074 }
15075
15076 static void
15077   vl_api_ipfix_classify_table_details_t_handler_json
15078   (vl_api_ipfix_classify_table_details_t * mp)
15079 {
15080   vat_json_node_t *node = NULL;
15081   vat_main_t *vam = &vat_main;
15082
15083   if (VAT_JSON_ARRAY != vam->json_tree.type)
15084     {
15085       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15086       vat_json_init_array (&vam->json_tree);
15087     }
15088
15089   node = vat_json_array_add (&vam->json_tree);
15090   vat_json_init_object (node);
15091
15092   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15093   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15094   vat_json_object_add_uint (node, "transport_protocol",
15095                             mp->transport_protocol);
15096 }
15097
15098 int
15099 api_pg_create_interface (vat_main_t * vam)
15100 {
15101   unformat_input_t *input = vam->input;
15102   vl_api_pg_create_interface_t *mp;
15103   f64 timeout;
15104
15105   u32 if_id = ~0;
15106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15107     {
15108       if (unformat (input, "if_id %d", &if_id))
15109         ;
15110       else
15111         break;
15112     }
15113   if (if_id == ~0)
15114     {
15115       errmsg ("missing pg interface index\n");
15116       return -99;
15117     }
15118
15119   /* Construct the API message */
15120   M (PG_CREATE_INTERFACE, pg_create_interface);
15121   mp->context = 0;
15122   mp->interface_id = ntohl (if_id);
15123
15124   S;
15125   W;
15126   /* NOTREACHED */
15127   return 0;
15128 }
15129
15130 int
15131 api_pg_capture (vat_main_t * vam)
15132 {
15133   unformat_input_t *input = vam->input;
15134   vl_api_pg_capture_t *mp;
15135   f64 timeout;
15136
15137   u32 if_id = ~0;
15138   u8 enable = 1;
15139   u32 count = 1;
15140   u8 pcap_file_set = 0;
15141   u8 *pcap_file = 0;
15142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15143     {
15144       if (unformat (input, "if_id %d", &if_id))
15145         ;
15146       else if (unformat (input, "pcap %s", &pcap_file))
15147         pcap_file_set = 1;
15148       else if (unformat (input, "count %d", &count))
15149         ;
15150       else if (unformat (input, "disable"))
15151         enable = 0;
15152       else
15153         break;
15154     }
15155   if (if_id == ~0)
15156     {
15157       errmsg ("missing pg interface index\n");
15158       return -99;
15159     }
15160   if (pcap_file_set > 0)
15161     {
15162       if (vec_len (pcap_file) > 255)
15163         {
15164           errmsg ("pcap file name is too long\n");
15165           return -99;
15166         }
15167     }
15168
15169   u32 name_len = vec_len (pcap_file);
15170   /* Construct the API message */
15171   M (PG_CAPTURE, pg_capture);
15172   mp->context = 0;
15173   mp->interface_id = ntohl (if_id);
15174   mp->is_enabled = enable;
15175   mp->count = ntohl (count);
15176   mp->pcap_name_length = ntohl (name_len);
15177   if (pcap_file_set != 0)
15178     {
15179       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15180     }
15181   vec_free (pcap_file);
15182
15183   S;
15184   W;
15185   /* NOTREACHED */
15186   return 0;
15187 }
15188
15189 int
15190 api_pg_enable_disable (vat_main_t * vam)
15191 {
15192   unformat_input_t *input = vam->input;
15193   vl_api_pg_enable_disable_t *mp;
15194   f64 timeout;
15195
15196   u8 enable = 1;
15197   u8 stream_name_set = 0;
15198   u8 *stream_name = 0;
15199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15200     {
15201       if (unformat (input, "stream %s", &stream_name))
15202         stream_name_set = 1;
15203       else if (unformat (input, "disable"))
15204         enable = 0;
15205       else
15206         break;
15207     }
15208
15209   if (stream_name_set > 0)
15210     {
15211       if (vec_len (stream_name) > 255)
15212         {
15213           errmsg ("stream name too long\n");
15214           return -99;
15215         }
15216     }
15217
15218   u32 name_len = vec_len (stream_name);
15219   /* Construct the API message */
15220   M (PG_ENABLE_DISABLE, pg_enable_disable);
15221   mp->context = 0;
15222   mp->is_enabled = enable;
15223   if (stream_name_set != 0)
15224     {
15225       mp->stream_name_length = ntohl (name_len);
15226       clib_memcpy (mp->stream_name, stream_name, name_len);
15227     }
15228   vec_free (stream_name);
15229
15230   S;
15231   W;
15232   /* NOTREACHED */
15233   return 0;
15234 }
15235
15236 int
15237 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15238 {
15239   unformat_input_t *input = vam->input;
15240   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15241   f64 timeout;
15242
15243   u16 *low_ports = 0;
15244   u16 *high_ports = 0;
15245   u16 this_low;
15246   u16 this_hi;
15247   ip4_address_t ip4_addr;
15248   ip6_address_t ip6_addr;
15249   u32 length;
15250   u32 tmp, tmp2;
15251   u8 prefix_set = 0;
15252   u32 vrf_id = ~0;
15253   u8 is_add = 1;
15254   u8 is_ipv6 = 0;
15255
15256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15257     {
15258       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15259         {
15260           prefix_set = 1;
15261         }
15262       else
15263         if (unformat
15264             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15265         {
15266           prefix_set = 1;
15267           is_ipv6 = 1;
15268         }
15269       else if (unformat (input, "vrf %d", &vrf_id))
15270         ;
15271       else if (unformat (input, "del"))
15272         is_add = 0;
15273       else if (unformat (input, "port %d", &tmp))
15274         {
15275           if (tmp == 0 || tmp > 65535)
15276             {
15277               errmsg ("port %d out of range", tmp);
15278               return -99;
15279             }
15280           this_low = tmp;
15281           this_hi = this_low + 1;
15282           vec_add1 (low_ports, this_low);
15283           vec_add1 (high_ports, this_hi);
15284         }
15285       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15286         {
15287           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15288             {
15289               errmsg ("incorrect range parameters\n");
15290               return -99;
15291             }
15292           this_low = tmp;
15293           /* Note: in debug CLI +1 is added to high before
15294              passing to real fn that does "the work"
15295              (ip_source_and_port_range_check_add_del).
15296              This fn is a wrapper around the binary API fn a
15297              control plane will call, which expects this increment
15298              to have occurred. Hence letting the binary API control
15299              plane fn do the increment for consistency between VAT
15300              and other control planes.
15301            */
15302           this_hi = tmp2;
15303           vec_add1 (low_ports, this_low);
15304           vec_add1 (high_ports, this_hi);
15305         }
15306       else
15307         break;
15308     }
15309
15310   if (prefix_set == 0)
15311     {
15312       errmsg ("<address>/<mask> not specified\n");
15313       return -99;
15314     }
15315
15316   if (vrf_id == ~0)
15317     {
15318       errmsg ("VRF ID required, not specified\n");
15319       return -99;
15320     }
15321
15322   if (vrf_id == 0)
15323     {
15324       errmsg
15325         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15326       return -99;
15327     }
15328
15329   if (vec_len (low_ports) == 0)
15330     {
15331       errmsg ("At least one port or port range required\n");
15332       return -99;
15333     }
15334
15335   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15336      ip_source_and_port_range_check_add_del);
15337
15338   mp->is_add = is_add;
15339
15340   if (is_ipv6)
15341     {
15342       mp->is_ipv6 = 1;
15343       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15344     }
15345   else
15346     {
15347       mp->is_ipv6 = 0;
15348       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15349     }
15350
15351   mp->mask_length = length;
15352   mp->number_of_ranges = vec_len (low_ports);
15353
15354   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15355   vec_free (low_ports);
15356
15357   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15358   vec_free (high_ports);
15359
15360   mp->vrf_id = ntohl (vrf_id);
15361
15362   S;
15363   W;
15364   /* NOTREACHED */
15365   return 0;
15366 }
15367
15368 int
15369 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15370 {
15371   unformat_input_t *input = vam->input;
15372   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15373   f64 timeout;
15374   u32 sw_if_index = ~0;
15375   int vrf_set = 0;
15376   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15377   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15378   u8 is_add = 1;
15379
15380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15381     {
15382       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15383         ;
15384       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15385         ;
15386       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15387         vrf_set = 1;
15388       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15389         vrf_set = 1;
15390       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15391         vrf_set = 1;
15392       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15393         vrf_set = 1;
15394       else if (unformat (input, "del"))
15395         is_add = 0;
15396       else
15397         break;
15398     }
15399
15400   if (sw_if_index == ~0)
15401     {
15402       errmsg ("Interface required but not specified\n");
15403       return -99;
15404     }
15405
15406   if (vrf_set == 0)
15407     {
15408       errmsg ("VRF ID required but not specified\n");
15409       return -99;
15410     }
15411
15412   if (tcp_out_vrf_id == 0
15413       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15414     {
15415       errmsg
15416         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15417       return -99;
15418     }
15419
15420   /* Construct the API message */
15421   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15422      ip_source_and_port_range_check_interface_add_del);
15423
15424   mp->sw_if_index = ntohl (sw_if_index);
15425   mp->is_add = is_add;
15426   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15427   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15428   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15429   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15430
15431   /* send it... */
15432   S;
15433
15434   /* Wait for a reply... */
15435   W;
15436 }
15437
15438 static int
15439 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15440 {
15441   unformat_input_t *i = vam->input;
15442   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15443   f64 timeout;
15444   u32 local_sa_id = 0;
15445   u32 remote_sa_id = 0;
15446   ip4_address_t src_address;
15447   ip4_address_t dst_address;
15448   u8 is_add = 1;
15449
15450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15451     {
15452       if (unformat (i, "local_sa %d", &local_sa_id))
15453         ;
15454       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15455         ;
15456       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15457         ;
15458       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15459         ;
15460       else if (unformat (i, "del"))
15461         is_add = 0;
15462       else
15463         {
15464           clib_warning ("parse error '%U'", format_unformat_error, i);
15465           return -99;
15466         }
15467     }
15468
15469   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15470
15471   mp->local_sa_id = ntohl (local_sa_id);
15472   mp->remote_sa_id = ntohl (remote_sa_id);
15473   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15474   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15475   mp->is_add = is_add;
15476
15477   S;
15478   W;
15479   /* NOTREACHED */
15480   return 0;
15481 }
15482
15483 static int
15484 api_punt (vat_main_t * vam)
15485 {
15486   unformat_input_t *i = vam->input;
15487   vl_api_punt_t *mp;
15488   f64 timeout;
15489   u32 ipv = ~0;
15490   u32 protocol = ~0;
15491   u32 port = ~0;
15492   int is_add = 1;
15493
15494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15495     {
15496       if (unformat (i, "ip %d", &ipv))
15497         ;
15498       else if (unformat (i, "protocol %d", &protocol))
15499         ;
15500       else if (unformat (i, "port %d", &port))
15501         ;
15502       else if (unformat (i, "del"))
15503         is_add = 0;
15504       else
15505         {
15506           clib_warning ("parse error '%U'", format_unformat_error, i);
15507           return -99;
15508         }
15509     }
15510
15511   M (PUNT, punt);
15512
15513   mp->is_add = (u8) is_add;
15514   mp->ipv = (u8) ipv;
15515   mp->l4_protocol = (u8) protocol;
15516   mp->l4_port = htons ((u16) port);
15517
15518   S;
15519   W;
15520   /* NOTREACHED */
15521   return 0;
15522 }
15523
15524 static void vl_api_ipsec_gre_tunnel_details_t_handler
15525   (vl_api_ipsec_gre_tunnel_details_t * mp)
15526 {
15527   vat_main_t *vam = &vat_main;
15528
15529   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15530            ntohl (mp->sw_if_index),
15531            format_ip4_address, &mp->src_address,
15532            format_ip4_address, &mp->dst_address,
15533            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15534 }
15535
15536 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15537   (vl_api_ipsec_gre_tunnel_details_t * mp)
15538 {
15539   vat_main_t *vam = &vat_main;
15540   vat_json_node_t *node = NULL;
15541   struct in_addr ip4;
15542
15543   if (VAT_JSON_ARRAY != vam->json_tree.type)
15544     {
15545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15546       vat_json_init_array (&vam->json_tree);
15547     }
15548   node = vat_json_array_add (&vam->json_tree);
15549
15550   vat_json_init_object (node);
15551   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15552   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15553   vat_json_object_add_ip4 (node, "src_address", ip4);
15554   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15555   vat_json_object_add_ip4 (node, "dst_address", ip4);
15556   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15557   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15558 }
15559
15560 static int
15561 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15562 {
15563   unformat_input_t *i = vam->input;
15564   vl_api_ipsec_gre_tunnel_dump_t *mp;
15565   f64 timeout;
15566   u32 sw_if_index;
15567   u8 sw_if_index_set = 0;
15568
15569   /* Parse args required to build the message */
15570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15571     {
15572       if (unformat (i, "sw_if_index %d", &sw_if_index))
15573         sw_if_index_set = 1;
15574       else
15575         break;
15576     }
15577
15578   if (sw_if_index_set == 0)
15579     {
15580       sw_if_index = ~0;
15581     }
15582
15583   if (!vam->json_output)
15584     {
15585       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15586                "sw_if_index", "src_address", "dst_address",
15587                "local_sa_id", "remote_sa_id");
15588     }
15589
15590   /* Get list of gre-tunnel interfaces */
15591   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15592
15593   mp->sw_if_index = htonl (sw_if_index);
15594
15595   S;
15596
15597   /* Use a control ping for synchronization */
15598   {
15599     vl_api_control_ping_t *mp;
15600     M (CONTROL_PING, control_ping);
15601     S;
15602   }
15603   W;
15604 }
15605
15606 static int
15607 api_delete_subif (vat_main_t * vam)
15608 {
15609   unformat_input_t *i = vam->input;
15610   vl_api_delete_subif_t *mp;
15611   f64 timeout;
15612   u32 sw_if_index = ~0;
15613
15614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15615     {
15616       if (unformat (i, "sw_if_index %d", &sw_if_index))
15617         ;
15618       else
15619         break;
15620     }
15621
15622   if (sw_if_index == ~0)
15623     {
15624       errmsg ("missing sw_if_index\n");
15625       return -99;
15626     }
15627
15628   /* Construct the API message */
15629   M (DELETE_SUBIF, delete_subif);
15630   mp->sw_if_index = ntohl (sw_if_index);
15631
15632   S;
15633   W;
15634 }
15635
15636 #define foreach_pbb_vtr_op      \
15637 _("disable",  L2_VTR_DISABLED)  \
15638 _("pop",  L2_VTR_POP_2)         \
15639 _("push",  L2_VTR_PUSH_2)
15640
15641 static int
15642 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15643 {
15644   unformat_input_t *i = vam->input;
15645   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15646   f64 timeout;
15647   u32 sw_if_index = ~0, vtr_op = ~0;
15648   u16 outer_tag = ~0;
15649   u8 dmac[6], smac[6];
15650   u8 dmac_set = 0, smac_set = 0;
15651   u16 vlanid = 0;
15652   u32 sid = ~0;
15653   u32 tmp;
15654
15655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15656     {
15657       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15658         ;
15659       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15660         ;
15661       else if (unformat (i, "vtr_op %d", &vtr_op))
15662         ;
15663 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15664       foreach_pbb_vtr_op
15665 #undef _
15666         else if (unformat (i, "translate_pbb_stag"))
15667         {
15668           if (unformat (i, "%d", &tmp))
15669             {
15670               vtr_op = L2_VTR_TRANSLATE_2_1;
15671               outer_tag = tmp;
15672             }
15673           else
15674             {
15675               errmsg
15676                 ("translate_pbb_stag operation requires outer tag definition\n");
15677               return -99;
15678             }
15679         }
15680       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
15681         dmac_set++;
15682       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
15683         smac_set++;
15684       else if (unformat (i, "sid %d", &sid))
15685         ;
15686       else if (unformat (i, "vlanid %d", &tmp))
15687         vlanid = tmp;
15688       else
15689         {
15690           clib_warning ("parse error '%U'", format_unformat_error, i);
15691           return -99;
15692         }
15693     }
15694
15695   if ((sw_if_index == ~0) || (vtr_op == ~0))
15696     {
15697       errmsg ("missing sw_if_index or vtr operation\n");
15698       return -99;
15699     }
15700   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
15701       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
15702     {
15703       errmsg
15704         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
15705       return -99;
15706     }
15707
15708   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
15709   mp->sw_if_index = ntohl (sw_if_index);
15710   mp->vtr_op = ntohl (vtr_op);
15711   mp->outer_tag = ntohs (outer_tag);
15712   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
15713   clib_memcpy (mp->b_smac, smac, sizeof (smac));
15714   mp->b_vlanid = ntohs (vlanid);
15715   mp->i_sid = ntohl (sid);
15716
15717   S;
15718   W;
15719   /* NOTREACHED */
15720   return 0;
15721 }
15722
15723 static int
15724 api_flow_classify_set_interface (vat_main_t * vam)
15725 {
15726   unformat_input_t *i = vam->input;
15727   vl_api_flow_classify_set_interface_t *mp;
15728   f64 timeout;
15729   u32 sw_if_index;
15730   int sw_if_index_set;
15731   u32 ip4_table_index = ~0;
15732   u32 ip6_table_index = ~0;
15733   u8 is_add = 1;
15734
15735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15736     {
15737       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15738         sw_if_index_set = 1;
15739       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15740         sw_if_index_set = 1;
15741       else if (unformat (i, "del"))
15742         is_add = 0;
15743       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15744         ;
15745       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15746         ;
15747       else
15748         {
15749           clib_warning ("parse error '%U'", format_unformat_error, i);
15750           return -99;
15751         }
15752     }
15753
15754   if (sw_if_index_set == 0)
15755     {
15756       errmsg ("missing interface name or sw_if_index\n");
15757       return -99;
15758     }
15759
15760   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
15761
15762   mp->sw_if_index = ntohl (sw_if_index);
15763   mp->ip4_table_index = ntohl (ip4_table_index);
15764   mp->ip6_table_index = ntohl (ip6_table_index);
15765   mp->is_add = is_add;
15766
15767   S;
15768   W;
15769   /* NOTREACHED */
15770   return 0;
15771 }
15772
15773 static int
15774 api_flow_classify_dump (vat_main_t * vam)
15775 {
15776   unformat_input_t *i = vam->input;
15777   vl_api_flow_classify_dump_t *mp;
15778   f64 timeout = ~0;
15779   u8 type = FLOW_CLASSIFY_N_TABLES;
15780
15781   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
15782     ;
15783   else
15784     {
15785       errmsg ("classify table type must be specified\n");
15786       return -99;
15787     }
15788
15789   if (!vam->json_output)
15790     {
15791       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15792     }
15793
15794   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
15795   mp->type = type;
15796   /* send it... */
15797   S;
15798
15799   /* Use a control ping for synchronization */
15800   {
15801     vl_api_control_ping_t *mp;
15802     M (CONTROL_PING, control_ping);
15803     S;
15804   }
15805   /* Wait for a reply... */
15806   W;
15807
15808   /* NOTREACHED */
15809   return 0;
15810 }
15811
15812 static int
15813 q_or_quit (vat_main_t * vam)
15814 {
15815   longjmp (vam->jump_buf, 1);
15816   return 0;                     /* not so much */
15817 }
15818
15819 static int
15820 q (vat_main_t * vam)
15821 {
15822   return q_or_quit (vam);
15823 }
15824
15825 static int
15826 quit (vat_main_t * vam)
15827 {
15828   return q_or_quit (vam);
15829 }
15830
15831 static int
15832 comment (vat_main_t * vam)
15833 {
15834   return 0;
15835 }
15836
15837 static int
15838 cmd_cmp (void *a1, void *a2)
15839 {
15840   u8 **c1 = a1;
15841   u8 **c2 = a2;
15842
15843   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15844 }
15845
15846 static int
15847 help (vat_main_t * vam)
15848 {
15849   u8 **cmds = 0;
15850   u8 *name = 0;
15851   hash_pair_t *p;
15852   unformat_input_t *i = vam->input;
15853   int j;
15854
15855   if (unformat (i, "%s", &name))
15856     {
15857       uword *hs;
15858
15859       vec_add1 (name, 0);
15860
15861       hs = hash_get_mem (vam->help_by_name, name);
15862       if (hs)
15863         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15864       else
15865         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15866       vec_free (name);
15867       return 0;
15868     }
15869
15870   fformat (vam->ofp, "Help is available for the following:\n");
15871
15872     /* *INDENT-OFF* */
15873     hash_foreach_pair (p, vam->function_by_name,
15874     ({
15875       vec_add1 (cmds, (u8 *)(p->key));
15876     }));
15877     /* *INDENT-ON* */
15878
15879   vec_sort_with_function (cmds, cmd_cmp);
15880
15881   for (j = 0; j < vec_len (cmds); j++)
15882     fformat (vam->ofp, "%s\n", cmds[j]);
15883
15884   vec_free (cmds);
15885   return 0;
15886 }
15887
15888 static int
15889 set (vat_main_t * vam)
15890 {
15891   u8 *name = 0, *value = 0;
15892   unformat_input_t *i = vam->input;
15893
15894   if (unformat (i, "%s", &name))
15895     {
15896       /* The input buffer is a vector, not a string. */
15897       value = vec_dup (i->buffer);
15898       vec_delete (value, i->index, 0);
15899       /* Almost certainly has a trailing newline */
15900       if (value[vec_len (value) - 1] == '\n')
15901         value[vec_len (value) - 1] = 0;
15902       /* Make sure it's a proper string, one way or the other */
15903       vec_add1 (value, 0);
15904       (void) clib_macro_set_value (&vam->macro_main,
15905                                    (char *) name, (char *) value);
15906     }
15907   else
15908     errmsg ("usage: set <name> <value>\n");
15909
15910   vec_free (name);
15911   vec_free (value);
15912   return 0;
15913 }
15914
15915 static int
15916 unset (vat_main_t * vam)
15917 {
15918   u8 *name = 0;
15919
15920   if (unformat (vam->input, "%s", &name))
15921     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15922       errmsg ("unset: %s wasn't set\n", name);
15923   vec_free (name);
15924   return 0;
15925 }
15926
15927 typedef struct
15928 {
15929   u8 *name;
15930   u8 *value;
15931 } macro_sort_t;
15932
15933
15934 static int
15935 macro_sort_cmp (void *a1, void *a2)
15936 {
15937   macro_sort_t *s1 = a1;
15938   macro_sort_t *s2 = a2;
15939
15940   return strcmp ((char *) (s1->name), (char *) (s2->name));
15941 }
15942
15943 static int
15944 dump_macro_table (vat_main_t * vam)
15945 {
15946   macro_sort_t *sort_me = 0, *sm;
15947   int i;
15948   hash_pair_t *p;
15949
15950     /* *INDENT-OFF* */
15951     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15952     ({
15953       vec_add2 (sort_me, sm, 1);
15954       sm->name = (u8 *)(p->key);
15955       sm->value = (u8 *) (p->value[0]);
15956     }));
15957     /* *INDENT-ON* */
15958
15959   vec_sort_with_function (sort_me, macro_sort_cmp);
15960
15961   if (vec_len (sort_me))
15962     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15963   else
15964     fformat (vam->ofp, "The macro table is empty...\n");
15965
15966   for (i = 0; i < vec_len (sort_me); i++)
15967     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15968   return 0;
15969 }
15970
15971 static int
15972 dump_node_table (vat_main_t * vam)
15973 {
15974   int i, j;
15975   vlib_node_t *node, *next_node;
15976
15977   if (vec_len (vam->graph_nodes) == 0)
15978     {
15979       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15980       return 0;
15981     }
15982
15983   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15984     {
15985       node = vam->graph_nodes[i];
15986       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15987       for (j = 0; j < vec_len (node->next_nodes); j++)
15988         {
15989           if (node->next_nodes[j] != ~0)
15990             {
15991               next_node = vam->graph_nodes[node->next_nodes[j]];
15992               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15993             }
15994         }
15995     }
15996   return 0;
15997 }
15998
15999 static int
16000 search_node_table (vat_main_t * vam)
16001 {
16002   unformat_input_t *line_input = vam->input;
16003   u8 *node_to_find;
16004   int j;
16005   vlib_node_t *node, *next_node;
16006   uword *p;
16007
16008   if (vam->graph_node_index_by_name == 0)
16009     {
16010       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16011       return 0;
16012     }
16013
16014   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16015     {
16016       if (unformat (line_input, "%s", &node_to_find))
16017         {
16018           vec_add1 (node_to_find, 0);
16019           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16020           if (p == 0)
16021             {
16022               fformat (vam->ofp, "%s not found...\n", node_to_find);
16023               goto out;
16024             }
16025           node = vam->graph_nodes[p[0]];
16026           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16027           for (j = 0; j < vec_len (node->next_nodes); j++)
16028             {
16029               if (node->next_nodes[j] != ~0)
16030                 {
16031                   next_node = vam->graph_nodes[node->next_nodes[j]];
16032                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16033                 }
16034             }
16035         }
16036
16037       else
16038         {
16039           clib_warning ("parse error '%U'", format_unformat_error,
16040                         line_input);
16041           return -99;
16042         }
16043
16044     out:
16045       vec_free (node_to_find);
16046
16047     }
16048
16049   return 0;
16050 }
16051
16052
16053 static int
16054 script (vat_main_t * vam)
16055 {
16056   u8 *s = 0;
16057   char *save_current_file;
16058   unformat_input_t save_input;
16059   jmp_buf save_jump_buf;
16060   u32 save_line_number;
16061
16062   FILE *new_fp, *save_ifp;
16063
16064   if (unformat (vam->input, "%s", &s))
16065     {
16066       new_fp = fopen ((char *) s, "r");
16067       if (new_fp == 0)
16068         {
16069           errmsg ("Couldn't open script file %s\n", s);
16070           vec_free (s);
16071           return -99;
16072         }
16073     }
16074   else
16075     {
16076       errmsg ("Missing script name\n");
16077       return -99;
16078     }
16079
16080   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16081   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16082   save_ifp = vam->ifp;
16083   save_line_number = vam->input_line_number;
16084   save_current_file = (char *) vam->current_file;
16085
16086   vam->input_line_number = 0;
16087   vam->ifp = new_fp;
16088   vam->current_file = s;
16089   do_one_file (vam);
16090
16091   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16092   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16093   vam->ifp = save_ifp;
16094   vam->input_line_number = save_line_number;
16095   vam->current_file = (u8 *) save_current_file;
16096   vec_free (s);
16097
16098   return 0;
16099 }
16100
16101 static int
16102 echo (vat_main_t * vam)
16103 {
16104   fformat (vam->ofp, "%v", vam->input->buffer);
16105   return 0;
16106 }
16107
16108 /* List of API message constructors, CLI names map to api_xxx */
16109 #define foreach_vpe_api_msg                                             \
16110 _(create_loopback,"[mac <mac-addr>]")                                   \
16111 _(sw_interface_dump,"")                                                 \
16112 _(sw_interface_set_flags,                                               \
16113   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16114 _(sw_interface_add_del_address,                                         \
16115   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16116 _(sw_interface_set_table,                                               \
16117   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16118 _(sw_interface_set_vpath,                                               \
16119   "<intfc> | sw_if_index <id> enable | disable")                        \
16120 _(sw_interface_set_l2_xconnect,                                         \
16121   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16122   "enable | disable")                                                   \
16123 _(sw_interface_set_l2_bridge,                                           \
16124   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16125   "[shg <split-horizon-group>] [bvi]\n"                                 \
16126   "enable | disable")                                                   \
16127 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16128   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16129   "profile <profile-id>\n")                                             \
16130 _(sw_interface_set_dpdk_hqos_subport,                                   \
16131   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16132   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16133 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16134   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16135 _(bridge_domain_add_del,                                                \
16136   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16137 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16138 _(l2fib_add_del,                                                        \
16139   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16140 _(l2_flags,                                                             \
16141   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16142 _(bridge_flags,                                                         \
16143   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16144 _(tap_connect,                                                          \
16145   "tapname <name> mac <mac-addr> | random-mac")                         \
16146 _(tap_modify,                                                           \
16147   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16148 _(tap_delete,                                                           \
16149   "<vpp-if-name> | sw_if_index <id>")                                   \
16150 _(sw_interface_tap_dump, "")                                            \
16151 _(ip_add_del_route,                                                     \
16152   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
16153   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16154   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16155   "[multipath] [count <n>]")                                            \
16156 _(proxy_arp_add_del,                                                    \
16157   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16158 _(proxy_arp_intfc_enable_disable,                                       \
16159   "<intfc> | sw_if_index <id> enable | disable")                        \
16160 _(mpls_add_del_encap,                                                   \
16161   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16162 _(mpls_add_del_decap,                                                   \
16163   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
16164 _(mpls_gre_add_del_tunnel,                                              \
16165   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
16166   "adj <ip4-address>/<mask-width> [del]")                               \
16167 _(sw_interface_set_unnumbered,                                          \
16168   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16169 _(ip_neighbor_add_del,                                                  \
16170   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16171   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16172 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16173 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16174 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16175   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16176   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16177   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16178 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16179 _(reset_fib, "vrf <n> [ipv6]")                                          \
16180 _(dhcp_proxy_config,                                                    \
16181   "svr <v46-address> src <v46-address>\n"                               \
16182    "insert-cid <n> [del]")                                              \
16183 _(dhcp_proxy_config_2,                                                  \
16184   "svr <v46-address> src <v46-address>\n"                               \
16185    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16186 _(dhcp_proxy_set_vss,                                                   \
16187   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16188 _(dhcp_client_config,                                                   \
16189   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16190 _(set_ip_flow_hash,                                                     \
16191   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16192 _(sw_interface_ip6_enable_disable,                                      \
16193   "<intfc> | sw_if_index <id> enable | disable")                        \
16194 _(sw_interface_ip6_set_link_local_address,                              \
16195   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16196 _(sw_interface_ip6nd_ra_prefix,                                         \
16197   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16198   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16199   "[nolink] [isno]")                                                    \
16200 _(sw_interface_ip6nd_ra_config,                                         \
16201   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16202   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16203   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16204 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16205 _(l2_patch_add_del,                                                     \
16206   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16207   "enable | disable")                                                   \
16208 _(mpls_ethernet_add_del_tunnel,                                         \
16209   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16210   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16211 _(mpls_ethernet_add_del_tunnel_2,                                       \
16212   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16213   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16214 _(sr_tunnel_add_del,                                                    \
16215   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16216   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16217   "[policy <policy_name>]")                                             \
16218 _(sr_policy_add_del,                                                    \
16219   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16220 _(sr_multicast_map_add_del,                                             \
16221   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16222 _(classify_add_del_table,                                               \
16223   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16224   "[del] mask <mask-value>\n"                                           \
16225   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
16226 _(classify_add_del_session,                                             \
16227   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16228   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16229   "  [l3 [ip4|ip6]]")                                                   \
16230 _(classify_set_interface_ip_table,                                      \
16231   "<intfc> | sw_if_index <nn> table <nn>")                              \
16232 _(classify_set_interface_l2_tables,                                     \
16233   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16234   "  [other-table <nn>]")                                               \
16235 _(get_node_index, "node <node-name")                                    \
16236 _(add_node_next, "node <node-name> next <next-node-name>")              \
16237 _(l2tpv3_create_tunnel,                                                 \
16238   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16239   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16240   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16241 _(l2tpv3_set_tunnel_cookies,                                            \
16242   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16243   "[new_remote_cookie <nn>]\n")                                         \
16244 _(l2tpv3_interface_enable_disable,                                      \
16245   "<intfc> | sw_if_index <nn> enable | disable")                        \
16246 _(l2tpv3_set_lookup_key,                                                \
16247   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16248 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16249 _(vxlan_add_del_tunnel,                                                 \
16250   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16251   " [decap-next l2|ip4|ip6] [del]")                                     \
16252 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16253 _(gre_add_del_tunnel,                                                   \
16254   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16255 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16256 _(l2_fib_clear_table, "")                                               \
16257 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16258 _(l2_interface_vlan_tag_rewrite,                                        \
16259   "<intfc> | sw_if_index <nn> \n"                                       \
16260   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16261   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16262 _(create_vhost_user_if,                                                 \
16263         "socket <filename> [server] [renumber <dev_instance>] "         \
16264         "[mac <mac_address>]")                                          \
16265 _(modify_vhost_user_if,                                                 \
16266         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16267         "[server] [renumber <dev_instance>]")                           \
16268 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16269 _(sw_interface_vhost_user_dump, "")                                     \
16270 _(show_version, "")                                                     \
16271 _(vxlan_gpe_add_del_tunnel,                                             \
16272   "local <addr> remote <addr> vni <nn>\n"                               \
16273     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16274   "[next-ethernet] [next-nsh]\n")                                       \
16275 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16276 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16277 _(interface_name_renumber,                                              \
16278   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16279 _(input_acl_set_interface,                                              \
16280   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16281   "  [l2-table <nn>] [del]")                                            \
16282 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16283 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16284 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16285 _(ip_dump, "ipv4 | ipv6")                                               \
16286 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16287 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16288   "  spid_id <n> ")                                                     \
16289 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16290   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16291   "  integ_alg <alg> integ_key <hex>")                                  \
16292 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16293   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16294   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16295   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16296 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16297 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16298 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16299   "(auth_data 0x<data> | auth_data <data>)")                            \
16300 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16301   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16302 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16303   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16304   "(local|remote)")                                                     \
16305 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16306 _(delete_loopback,"sw_if_index <nn>")                                   \
16307 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16308 _(map_add_domain,                                                       \
16309   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16310   "ip6-src <ip6addr> "                                                  \
16311   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16312 _(map_del_domain, "index <n>")                                          \
16313 _(map_add_del_rule,                                                     \
16314   "index <n> psid <n> dst <ip6addr> [del]")                             \
16315 _(map_domain_dump, "")                                                  \
16316 _(map_rule_dump, "index <map-domain>")                                  \
16317 _(want_interface_events,  "enable|disable")                             \
16318 _(want_stats,"enable|disable")                                          \
16319 _(get_first_msg_id, "client <name>")                                    \
16320 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16321 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16322   "fib-id <nn> [ip4][ip6][default]")                                    \
16323 _(get_node_graph, " ")                                                  \
16324 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16325 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16326 _(ioam_disable, "")                                                \
16327 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16328                             " sw_if_index <sw_if_index> p <priority> "  \
16329                             "w <weight>] [del]")                        \
16330 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16331                         "iface <intf> | sw_if_index <sw_if_index> "     \
16332                         "p <priority> w <weight> [del]")                \
16333 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16334                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16335                           "locator-set <locator_name> [del]")           \
16336 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16337   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16338 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16339 _(lisp_gpe_enable_disable, "enable|disable")                            \
16340 _(lisp_enable_disable, "enable|disable")                                \
16341 _(lisp_gpe_add_del_iface, "up|down")                                    \
16342 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16343                                "[seid <seid>] "                         \
16344                                "rloc <locator> p <prio> "               \
16345                                "w <weight> [rloc <loc> ... ] "          \
16346                                "action <action> [del-all]")             \
16347 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16348                           "<local-eid>")                                \
16349 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16350 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16351 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16352 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16353 _(lisp_locator_set_dump, "[local | remote]")                            \
16354 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16355 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16356                        "[local] | [remote]")                            \
16357 _(lisp_eid_table_vni_dump, "")                                          \
16358 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16359 _(lisp_gpe_tunnel_dump, "")                                             \
16360 _(lisp_map_resolver_dump, "")                                           \
16361 _(lisp_adjacencies_get, "vni <vni>")                                    \
16362 _(show_lisp_status, "")                                                 \
16363 _(lisp_get_map_request_itr_rlocs, "")                                   \
16364 _(show_lisp_pitr, "")                                                   \
16365 _(show_lisp_map_request_mode, "")                                       \
16366 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16367 _(af_packet_delete, "name <host interface name>")                       \
16368 _(policer_add_del, "name <policer name> <params> [del]")                \
16369 _(policer_dump, "[name <policer name>]")                                \
16370 _(policer_classify_set_interface,                                       \
16371   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16372   "  [l2-table <nn>] [del]")                                            \
16373 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16374 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16375     "[master|slave]")                                                   \
16376 _(netmap_delete, "name <interface name>")                               \
16377 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16378 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16379 _(mpls_fib_encap_dump, "")                                              \
16380 _(mpls_fib_decap_dump, "")                                              \
16381 _(classify_table_ids, "")                                               \
16382 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16383 _(classify_table_info, "table_id <nn>")                                 \
16384 _(classify_session_dump, "table_id <nn>")                               \
16385 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16386     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16387     "[template_interval <nn>] [udp_checksum]")                          \
16388 _(ipfix_exporter_dump, "")                                              \
16389 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16390 _(ipfix_classify_stream_dump, "")                                       \
16391 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16392 _(ipfix_classify_table_dump, "")                                        \
16393 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16394 _(pg_create_interface, "if_id <nn>")                                    \
16395 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16396 _(pg_enable_disable, "[stream <id>] disable")                           \
16397 _(ip_source_and_port_range_check_add_del,                               \
16398   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16399 _(ip_source_and_port_range_check_interface_add_del,                     \
16400   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16401   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16402 _(ipsec_gre_add_del_tunnel,                                             \
16403   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16404 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16405 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")                   \
16406 _(l2_interface_pbb_tag_rewrite,                                         \
16407   "<intfc> | sw_if_index <nn> \n"                                       \
16408   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16409   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16410 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16411 _(flow_classify_set_interface,                                          \
16412   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16413 _(flow_classify_dump, "type [ip4|ip6]")
16414
16415 /* List of command functions, CLI names map directly to functions */
16416 #define foreach_cli_function                                    \
16417 _(comment, "usage: comment <ignore-rest-of-line>")              \
16418 _(dump_interface_table, "usage: dump_interface_table")          \
16419 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16420 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16421 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16422 _(dump_stats_table, "usage: dump_stats_table")                  \
16423 _(dump_macro_table, "usage: dump_macro_table ")                 \
16424 _(dump_node_table, "usage: dump_node_table")                    \
16425 _(echo, "usage: echo <message>")                                \
16426 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16427 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16428 _(help, "usage: help")                                          \
16429 _(q, "usage: quit")                                             \
16430 _(quit, "usage: quit")                                          \
16431 _(search_node_table, "usage: search_node_table <name>...")      \
16432 _(set, "usage: set <variable-name> <value>")                    \
16433 _(script, "usage: script <file-name>")                          \
16434 _(unset, "usage: unset <variable-name>")
16435
16436 #define _(N,n)                                  \
16437     static void vl_api_##n##_t_handler_uni      \
16438     (vl_api_##n##_t * mp)                       \
16439     {                                           \
16440         vat_main_t * vam = &vat_main;           \
16441         if (vam->json_output) {                 \
16442             vl_api_##n##_t_handler_json(mp);    \
16443         } else {                                \
16444             vl_api_##n##_t_handler(mp);         \
16445         }                                       \
16446     }
16447 foreach_vpe_api_reply_msg;
16448 #undef _
16449
16450 void
16451 vat_api_hookup (vat_main_t * vam)
16452 {
16453 #define _(N,n)                                                  \
16454     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16455                            vl_api_##n##_t_handler_uni,          \
16456                            vl_noop_handler,                     \
16457                            vl_api_##n##_t_endian,               \
16458                            vl_api_##n##_t_print,                \
16459                            sizeof(vl_api_##n##_t), 1);
16460   foreach_vpe_api_reply_msg;
16461 #undef _
16462
16463   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16464
16465   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16466
16467   vam->function_by_name = hash_create_string (0, sizeof (uword));
16468
16469   vam->help_by_name = hash_create_string (0, sizeof (uword));
16470
16471   /* API messages we can send */
16472 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16473   foreach_vpe_api_msg;
16474 #undef _
16475
16476   /* Help strings */
16477 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16478   foreach_vpe_api_msg;
16479 #undef _
16480
16481   /* CLI functions */
16482 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16483   foreach_cli_function;
16484 #undef _
16485
16486   /* Help strings */
16487 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16488   foreach_cli_function;
16489 #undef _
16490 }
16491
16492 #undef vl_api_version
16493 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16494 #include <vpp-api/vpe.api.h>
16495 #undef vl_api_version
16496
16497 void
16498 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16499 {
16500   /*
16501    * Send the main API signature in slot 0. This bit of code must
16502    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16503    */
16504   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16505 }
16506
16507 /*
16508  * fd.io coding-style-patch-verification: ON
16509  *
16510  * Local Variables:
16511  * eval: (c-set-style "gnu")
16512  * End:
16513  */