LISP: enhance binary part of some APIs
[vpp.git] / src / 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 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52
53 #include "vat/json_format.h"
54
55 #include <inttypes.h>
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 #define __plugin_msg_base 0
75 #include <vlibapi/vat_helper_macros.h>
76
77 f64
78 vat_time_now (vat_main_t * vam)
79 {
80 #if VPP_API_TEST_BUILTIN
81   return vlib_time_now (vam->vlib_main);
82 #else
83   return clib_time_now (&vam->clib_time);
84 #endif
85 }
86
87 void
88 errmsg (char *fmt, ...)
89 {
90   vat_main_t *vam = &vat_main;
91   va_list va;
92   u8 *s;
93
94   va_start (va, fmt);
95   s = va_format (0, fmt, &va);
96   va_end (va);
97
98   vec_add1 (s, 0);
99
100 #if VPP_API_TEST_BUILTIN
101   vlib_cli_output (vam->vlib_main, (char *) s);
102 #else
103   {
104     if (vam->ifp != stdin)
105       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
106                vam->input_line_number);
107     fformat (vam->ofp, (char *) s);
108     fflush (vam->ofp);
109   }
110 #endif
111
112   vec_free (s);
113 }
114
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 #if VPP_API_TEST_BUILTIN == 0
134 /* Parse an IP4 address %d.%d.%d.%d. */
135 uword
136 unformat_ip4_address (unformat_input_t * input, va_list * args)
137 {
138   u8 *result = va_arg (*args, u8 *);
139   unsigned a[4];
140
141   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
142     return 0;
143
144   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
145     return 0;
146
147   result[0] = a[0];
148   result[1] = a[1];
149   result[2] = a[2];
150   result[3] = a[3];
151
152   return 1;
153 }
154
155 uword
156 unformat_ethernet_address (unformat_input_t * input, va_list * args)
157 {
158   u8 *result = va_arg (*args, u8 *);
159   u32 i, a[6];
160
161   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
162                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
163     return 0;
164
165   /* Check range. */
166   for (i = 0; i < 6; i++)
167     if (a[i] >= (1 << 8))
168       return 0;
169
170   for (i = 0; i < 6; i++)
171     result[i] = a[i];
172
173   return 1;
174 }
175
176 /* Returns ethernet type as an int in host byte order. */
177 uword
178 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
179                                         va_list * args)
180 {
181   u16 *result = va_arg (*args, u16 *);
182   int type;
183
184   /* Numeric type. */
185   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
186     {
187       if (type >= (1 << 16))
188         return 0;
189       *result = type;
190       return 1;
191     }
192   return 0;
193 }
194
195 /* Parse an IP6 address. */
196 uword
197 unformat_ip6_address (unformat_input_t * input, va_list * args)
198 {
199   ip6_address_t *result = va_arg (*args, ip6_address_t *);
200   u16 hex_quads[8];
201   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
202   uword c, n_colon, double_colon_index;
203
204   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
205   double_colon_index = ARRAY_LEN (hex_quads);
206   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
207     {
208       hex_digit = 16;
209       if (c >= '0' && c <= '9')
210         hex_digit = c - '0';
211       else if (c >= 'a' && c <= 'f')
212         hex_digit = c + 10 - 'a';
213       else if (c >= 'A' && c <= 'F')
214         hex_digit = c + 10 - 'A';
215       else if (c == ':' && n_colon < 2)
216         n_colon++;
217       else
218         {
219           unformat_put_input (input);
220           break;
221         }
222
223       /* Too many hex quads. */
224       if (n_hex_quads >= ARRAY_LEN (hex_quads))
225         return 0;
226
227       if (hex_digit < 16)
228         {
229           hex_quad = (hex_quad << 4) | hex_digit;
230
231           /* Hex quad must fit in 16 bits. */
232           if (n_hex_digits >= 4)
233             return 0;
234
235           n_colon = 0;
236           n_hex_digits++;
237         }
238
239       /* Save position of :: */
240       if (n_colon == 2)
241         {
242           /* More than one :: ? */
243           if (double_colon_index < ARRAY_LEN (hex_quads))
244             return 0;
245           double_colon_index = n_hex_quads;
246         }
247
248       if (n_colon > 0 && n_hex_digits > 0)
249         {
250           hex_quads[n_hex_quads++] = hex_quad;
251           hex_quad = 0;
252           n_hex_digits = 0;
253         }
254     }
255
256   if (n_hex_digits > 0)
257     hex_quads[n_hex_quads++] = hex_quad;
258
259   {
260     word i;
261
262     /* Expand :: to appropriate number of zero hex quads. */
263     if (double_colon_index < ARRAY_LEN (hex_quads))
264       {
265         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
266
267         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
268           hex_quads[n_zero + i] = hex_quads[i];
269
270         for (i = 0; i < n_zero; i++)
271           hex_quads[double_colon_index + i] = 0;
272
273         n_hex_quads = ARRAY_LEN (hex_quads);
274       }
275
276     /* Too few hex quads given. */
277     if (n_hex_quads < ARRAY_LEN (hex_quads))
278       return 0;
279
280     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
281       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
282
283     return 1;
284   }
285 }
286
287 uword
288 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
289 {
290   u32 *r = va_arg (*args, u32 *);
291
292   if (0);
293 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
294   foreach_ipsec_policy_action
295 #undef _
296     else
297     return 0;
298   return 1;
299 }
300
301 uword
302 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
303 {
304   u32 *r = va_arg (*args, u32 *);
305
306   if (0);
307 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
308   foreach_ipsec_crypto_alg
309 #undef _
310     else
311     return 0;
312   return 1;
313 }
314
315 u8 *
316 format_ipsec_crypto_alg (u8 * s, va_list * args)
317 {
318   u32 i = va_arg (*args, u32);
319   u8 *t = 0;
320
321   switch (i)
322     {
323 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
324       foreach_ipsec_crypto_alg
325 #undef _
326     default:
327       return format (s, "unknown");
328     }
329   return format (s, "%s", t);
330 }
331
332 uword
333 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
334 {
335   u32 *r = va_arg (*args, u32 *);
336
337   if (0);
338 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
339   foreach_ipsec_integ_alg
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 u8 *
347 format_ipsec_integ_alg (u8 * s, va_list * args)
348 {
349   u32 i = va_arg (*args, u32);
350   u8 *t = 0;
351
352   switch (i)
353     {
354 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
355       foreach_ipsec_integ_alg
356 #undef _
357     default:
358       return format (s, "unknown");
359     }
360   return format (s, "%s", t);
361 }
362
363 uword
364 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
370   foreach_ikev2_auth_method
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 uword
378 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
379 {
380   u32 *r = va_arg (*args, u32 *);
381
382   if (0);
383 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
384   foreach_ikev2_id_type
385 #undef _
386     else
387     return 0;
388   return 1;
389 }
390 #endif /* VPP_API_TEST_BUILTIN */
391
392 static uword
393 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "kbps"))
398     *r = SSE2_QOS_RATE_KBPS;
399   else if (unformat (input, "pps"))
400     *r = SSE2_QOS_RATE_PPS;
401   else
402     return 0;
403   return 1;
404 }
405
406 static uword
407 unformat_policer_round_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "closest"))
412     *r = SSE2_QOS_ROUND_TO_CLOSEST;
413   else if (unformat (input, "up"))
414     *r = SSE2_QOS_ROUND_TO_UP;
415   else if (unformat (input, "down"))
416     *r = SSE2_QOS_ROUND_TO_DOWN;
417   else
418     return 0;
419   return 1;
420 }
421
422 static uword
423 unformat_policer_type (unformat_input_t * input, va_list * args)
424 {
425   u8 *r = va_arg (*args, u8 *);
426
427   if (unformat (input, "1r2c"))
428     *r = SSE2_QOS_POLICER_TYPE_1R2C;
429   else if (unformat (input, "1r3c"))
430     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
431   else if (unformat (input, "2r3c-2698"))
432     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
433   else if (unformat (input, "2r3c-4115"))
434     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
435   else if (unformat (input, "2r3c-mef5cf1"))
436     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
437   else
438     return 0;
439   return 1;
440 }
441
442 static uword
443 unformat_dscp (unformat_input_t * input, va_list * va)
444 {
445   u8 *r = va_arg (*va, u8 *);
446
447   if (0);
448 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
449   foreach_vnet_dscp
450 #undef _
451     else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_policer_action_type (unformat_input_t * input, va_list * va)
458 {
459   sse2_qos_pol_action_params_st *a
460     = va_arg (*va, sse2_qos_pol_action_params_st *);
461
462   if (unformat (input, "drop"))
463     a->action_type = SSE2_QOS_ACTION_DROP;
464   else if (unformat (input, "transmit"))
465     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
466   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
467     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
468   else
469     return 0;
470   return 1;
471 }
472
473 static uword
474 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
475 {
476   u32 *r = va_arg (*va, u32 *);
477   u32 tid;
478
479   if (unformat (input, "ip4"))
480     tid = POLICER_CLASSIFY_TABLE_IP4;
481   else if (unformat (input, "ip6"))
482     tid = POLICER_CLASSIFY_TABLE_IP6;
483   else if (unformat (input, "l2"))
484     tid = POLICER_CLASSIFY_TABLE_L2;
485   else
486     return 0;
487
488   *r = tid;
489   return 1;
490 }
491
492 static uword
493 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
494 {
495   u32 *r = va_arg (*va, u32 *);
496   u32 tid;
497
498   if (unformat (input, "ip4"))
499     tid = FLOW_CLASSIFY_TABLE_IP4;
500   else if (unformat (input, "ip6"))
501     tid = FLOW_CLASSIFY_TABLE_IP6;
502   else
503     return 0;
504
505   *r = tid;
506   return 1;
507 }
508
509 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
510 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
511 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
512 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
513
514 uword
515 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
516 {
517   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
518   mfib_itf_attribute_t attr;
519
520   old = *iflags;
521   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
522   {
523     if (unformat (input, mfib_itf_flag_long_names[attr]))
524       *iflags |= (1 << attr);
525   }
526   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
527   {
528     if (unformat (input, mfib_itf_flag_names[attr]))
529       *iflags |= (1 << attr);
530   }
531
532   return (old == *iflags ? 0 : 1);
533 }
534
535 uword
536 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
537 {
538   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
539   mfib_entry_attribute_t attr;
540
541   old = *eflags;
542   FOR_EACH_MFIB_ATTRIBUTE (attr)
543   {
544     if (unformat (input, mfib_flag_long_names[attr]))
545       *eflags |= (1 << attr);
546   }
547   FOR_EACH_MFIB_ATTRIBUTE (attr)
548   {
549     if (unformat (input, mfib_flag_names[attr]))
550       *eflags |= (1 << attr);
551   }
552
553   return (old == *eflags ? 0 : 1);
554 }
555
556 #if (VPP_API_TEST_BUILTIN==0)
557 u8 *
558 format_ip4_address (u8 * s, va_list * args)
559 {
560   u8 *a = va_arg (*args, u8 *);
561   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
562 }
563
564 u8 *
565 format_ip6_address (u8 * s, va_list * args)
566 {
567   ip6_address_t *a = va_arg (*args, ip6_address_t *);
568   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
569
570   i_max_n_zero = ARRAY_LEN (a->as_u16);
571   max_n_zeros = 0;
572   i_first_zero = i_max_n_zero;
573   n_zeros = 0;
574   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
575     {
576       u32 is_zero = a->as_u16[i] == 0;
577       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
578         {
579           i_first_zero = i;
580           n_zeros = 0;
581         }
582       n_zeros += is_zero;
583       if ((!is_zero && n_zeros > max_n_zeros)
584           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
585         {
586           i_max_n_zero = i_first_zero;
587           max_n_zeros = n_zeros;
588           i_first_zero = ARRAY_LEN (a->as_u16);
589           n_zeros = 0;
590         }
591     }
592
593   last_double_colon = 0;
594   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
595     {
596       if (i == i_max_n_zero && max_n_zeros > 1)
597         {
598           s = format (s, "::");
599           i += max_n_zeros - 1;
600           last_double_colon = 1;
601         }
602       else
603         {
604           s = format (s, "%s%x",
605                       (last_double_colon || i == 0) ? "" : ":",
606                       clib_net_to_host_u16 (a->as_u16[i]));
607           last_double_colon = 0;
608         }
609     }
610
611   return s;
612 }
613
614 /* Format an IP46 address. */
615 u8 *
616 format_ip46_address (u8 * s, va_list * args)
617 {
618   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
619   ip46_type_t type = va_arg (*args, ip46_type_t);
620   int is_ip4 = 1;
621
622   switch (type)
623     {
624     case IP46_TYPE_ANY:
625       is_ip4 = ip46_address_is_ip4 (ip46);
626       break;
627     case IP46_TYPE_IP4:
628       is_ip4 = 1;
629       break;
630     case IP46_TYPE_IP6:
631       is_ip4 = 0;
632       break;
633     }
634
635   return is_ip4 ?
636     format (s, "%U", format_ip4_address, &ip46->ip4) :
637     format (s, "%U", format_ip6_address, &ip46->ip6);
638 }
639
640 u8 *
641 format_ethernet_address (u8 * s, va_list * args)
642 {
643   u8 *a = va_arg (*args, u8 *);
644
645   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
646                  a[0], a[1], a[2], a[3], a[4], a[5]);
647 }
648 #endif
649
650 static void
651 increment_v4_address (ip4_address_t * a)
652 {
653   u32 v;
654
655   v = ntohl (a->as_u32) + 1;
656   a->as_u32 = ntohl (v);
657 }
658
659 static void
660 increment_v6_address (ip6_address_t * a)
661 {
662   u64 v0, v1;
663
664   v0 = clib_net_to_host_u64 (a->as_u64[0]);
665   v1 = clib_net_to_host_u64 (a->as_u64[1]);
666
667   v1 += 1;
668   if (v1 == 0)
669     v0 += 1;
670   a->as_u64[0] = clib_net_to_host_u64 (v0);
671   a->as_u64[1] = clib_net_to_host_u64 (v1);
672 }
673
674 static void
675 increment_mac_address (u64 * mac)
676 {
677   u64 tmp = *mac;
678
679   tmp = clib_net_to_host_u64 (tmp);
680   tmp += 1 << 16;               /* skip unused (least significant) octets */
681   tmp = clib_host_to_net_u64 (tmp);
682   *mac = tmp;
683 }
684
685 static void vl_api_create_loopback_reply_t_handler
686   (vl_api_create_loopback_reply_t * mp)
687 {
688   vat_main_t *vam = &vat_main;
689   i32 retval = ntohl (mp->retval);
690
691   vam->retval = retval;
692   vam->regenerate_interface_table = 1;
693   vam->sw_if_index = ntohl (mp->sw_if_index);
694   vam->result_ready = 1;
695 }
696
697 static void vl_api_create_loopback_reply_t_handler_json
698   (vl_api_create_loopback_reply_t * mp)
699 {
700   vat_main_t *vam = &vat_main;
701   vat_json_node_t node;
702
703   vat_json_init_object (&node);
704   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
705   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
706
707   vat_json_print (vam->ofp, &node);
708   vat_json_free (&node);
709   vam->retval = ntohl (mp->retval);
710   vam->result_ready = 1;
711 }
712
713 static void vl_api_af_packet_create_reply_t_handler
714   (vl_api_af_packet_create_reply_t * mp)
715 {
716   vat_main_t *vam = &vat_main;
717   i32 retval = ntohl (mp->retval);
718
719   vam->retval = retval;
720   vam->regenerate_interface_table = 1;
721   vam->sw_if_index = ntohl (mp->sw_if_index);
722   vam->result_ready = 1;
723 }
724
725 static void vl_api_af_packet_create_reply_t_handler_json
726   (vl_api_af_packet_create_reply_t * mp)
727 {
728   vat_main_t *vam = &vat_main;
729   vat_json_node_t node;
730
731   vat_json_init_object (&node);
732   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
733   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
734
735   vat_json_print (vam->ofp, &node);
736   vat_json_free (&node);
737
738   vam->retval = ntohl (mp->retval);
739   vam->result_ready = 1;
740 }
741
742 static void vl_api_create_vlan_subif_reply_t_handler
743   (vl_api_create_vlan_subif_reply_t * mp)
744 {
745   vat_main_t *vam = &vat_main;
746   i32 retval = ntohl (mp->retval);
747
748   vam->retval = retval;
749   vam->regenerate_interface_table = 1;
750   vam->sw_if_index = ntohl (mp->sw_if_index);
751   vam->result_ready = 1;
752 }
753
754 static void vl_api_create_vlan_subif_reply_t_handler_json
755   (vl_api_create_vlan_subif_reply_t * mp)
756 {
757   vat_main_t *vam = &vat_main;
758   vat_json_node_t node;
759
760   vat_json_init_object (&node);
761   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
762   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
763
764   vat_json_print (vam->ofp, &node);
765   vat_json_free (&node);
766
767   vam->retval = ntohl (mp->retval);
768   vam->result_ready = 1;
769 }
770
771 static void vl_api_create_subif_reply_t_handler
772   (vl_api_create_subif_reply_t * mp)
773 {
774   vat_main_t *vam = &vat_main;
775   i32 retval = ntohl (mp->retval);
776
777   vam->retval = retval;
778   vam->regenerate_interface_table = 1;
779   vam->sw_if_index = ntohl (mp->sw_if_index);
780   vam->result_ready = 1;
781 }
782
783 static void vl_api_create_subif_reply_t_handler_json
784   (vl_api_create_subif_reply_t * mp)
785 {
786   vat_main_t *vam = &vat_main;
787   vat_json_node_t node;
788
789   vat_json_init_object (&node);
790   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
791   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
792
793   vat_json_print (vam->ofp, &node);
794   vat_json_free (&node);
795
796   vam->retval = ntohl (mp->retval);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_interface_name_renumber_reply_t_handler
801   (vl_api_interface_name_renumber_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   i32 retval = ntohl (mp->retval);
805
806   vam->retval = retval;
807   vam->regenerate_interface_table = 1;
808   vam->result_ready = 1;
809 }
810
811 static void vl_api_interface_name_renumber_reply_t_handler_json
812   (vl_api_interface_name_renumber_reply_t * mp)
813 {
814   vat_main_t *vam = &vat_main;
815   vat_json_node_t node;
816
817   vat_json_init_object (&node);
818   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
819
820   vat_json_print (vam->ofp, &node);
821   vat_json_free (&node);
822
823   vam->retval = ntohl (mp->retval);
824   vam->result_ready = 1;
825 }
826
827 /*
828  * Special-case: build the interface table, maintain
829  * the next loopback sw_if_index vbl.
830  */
831 static void vl_api_sw_interface_details_t_handler
832   (vl_api_sw_interface_details_t * mp)
833 {
834   vat_main_t *vam = &vat_main;
835   u8 *s = format (0, "%s%c", mp->interface_name, 0);
836
837   hash_set_mem (vam->sw_if_index_by_interface_name, s,
838                 ntohl (mp->sw_if_index));
839
840   /* In sub interface case, fill the sub interface table entry */
841   if (mp->sw_if_index != mp->sup_sw_if_index)
842     {
843       sw_interface_subif_t *sub = NULL;
844
845       vec_add2 (vam->sw_if_subif_table, sub, 1);
846
847       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
848       strncpy ((char *) sub->interface_name, (char *) s,
849                vec_len (sub->interface_name));
850       sub->sw_if_index = ntohl (mp->sw_if_index);
851       sub->sub_id = ntohl (mp->sub_id);
852
853       sub->sub_dot1ad = mp->sub_dot1ad;
854       sub->sub_number_of_tags = mp->sub_number_of_tags;
855       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
856       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
857       sub->sub_exact_match = mp->sub_exact_match;
858       sub->sub_default = mp->sub_default;
859       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
860       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
861
862       /* vlan tag rewrite */
863       sub->vtr_op = ntohl (mp->vtr_op);
864       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
865       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
866       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
867     }
868 }
869
870 static void vl_api_sw_interface_details_t_handler_json
871   (vl_api_sw_interface_details_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t *node = NULL;
875
876   if (VAT_JSON_ARRAY != vam->json_tree.type)
877     {
878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
879       vat_json_init_array (&vam->json_tree);
880     }
881   node = vat_json_array_add (&vam->json_tree);
882
883   vat_json_init_object (node);
884   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
885   vat_json_object_add_uint (node, "sup_sw_if_index",
886                             ntohl (mp->sup_sw_if_index));
887   vat_json_object_add_uint (node, "l2_address_length",
888                             ntohl (mp->l2_address_length));
889   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
890                              sizeof (mp->l2_address));
891   vat_json_object_add_string_copy (node, "interface_name",
892                                    mp->interface_name);
893   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
894   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
895   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
896   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
897   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
898   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
899   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
900   vat_json_object_add_uint (node, "sub_number_of_tags",
901                             mp->sub_number_of_tags);
902   vat_json_object_add_uint (node, "sub_outer_vlan_id",
903                             ntohs (mp->sub_outer_vlan_id));
904   vat_json_object_add_uint (node, "sub_inner_vlan_id",
905                             ntohs (mp->sub_inner_vlan_id));
906   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
907   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
908   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
909                             mp->sub_outer_vlan_id_any);
910   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
911                             mp->sub_inner_vlan_id_any);
912   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
913   vat_json_object_add_uint (node, "vtr_push_dot1q",
914                             ntohl (mp->vtr_push_dot1q));
915   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
916   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
917 }
918
919 static void vl_api_sw_interface_set_flags_t_handler
920   (vl_api_sw_interface_set_flags_t * mp)
921 {
922   vat_main_t *vam = &vat_main;
923   if (vam->interface_event_display)
924     errmsg ("interface flags: sw_if_index %d %s %s",
925             ntohl (mp->sw_if_index),
926             mp->admin_up_down ? "admin-up" : "admin-down",
927             mp->link_up_down ? "link-up" : "link-down");
928 }
929
930 static void vl_api_sw_interface_set_flags_t_handler_json
931   (vl_api_sw_interface_set_flags_t * mp)
932 {
933   /* JSON output not supported */
934 }
935
936 static void
937 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
938 {
939   vat_main_t *vam = &vat_main;
940   i32 retval = ntohl (mp->retval);
941
942   vam->retval = retval;
943   vam->shmem_result = (u8 *) mp->reply_in_shmem;
944   vam->result_ready = 1;
945 }
946
947 static void
948 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
949 {
950   vat_main_t *vam = &vat_main;
951   vat_json_node_t node;
952   api_main_t *am = &api_main;
953   void *oldheap;
954   u8 *reply;
955
956   vat_json_init_object (&node);
957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
958   vat_json_object_add_uint (&node, "reply_in_shmem",
959                             ntohl (mp->reply_in_shmem));
960   /* Toss the shared-memory original... */
961   pthread_mutex_lock (&am->vlib_rp->mutex);
962   oldheap = svm_push_data_heap (am->vlib_rp);
963
964   reply = (u8 *) (mp->reply_in_shmem);
965   vec_free (reply);
966
967   svm_pop_heap (oldheap);
968   pthread_mutex_unlock (&am->vlib_rp->mutex);
969
970   vat_json_print (vam->ofp, &node);
971   vat_json_free (&node);
972
973   vam->retval = ntohl (mp->retval);
974   vam->result_ready = 1;
975 }
976
977 static void
978 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
979 {
980   vat_main_t *vam = &vat_main;
981   i32 retval = ntohl (mp->retval);
982
983   vam->retval = retval;
984   vam->cmd_reply = mp->reply;
985   vam->result_ready = 1;
986 }
987
988 static void
989 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
990 {
991   vat_main_t *vam = &vat_main;
992   vat_json_node_t node;
993
994   vat_json_init_object (&node);
995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
996   vat_json_object_add_string_copy (&node, "reply", mp->reply);
997
998   vat_json_print (vam->ofp, &node);
999   vat_json_free (&node);
1000
1001   vam->retval = ntohl (mp->retval);
1002   vam->result_ready = 1;
1003 }
1004
1005 static void vl_api_classify_add_del_table_reply_t_handler
1006   (vl_api_classify_add_del_table_reply_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   i32 retval = ntohl (mp->retval);
1010   if (vam->async_mode)
1011     {
1012       vam->async_errors += (retval < 0);
1013     }
1014   else
1015     {
1016       vam->retval = retval;
1017       if (retval == 0 &&
1018           ((mp->new_table_index != 0xFFFFFFFF) ||
1019            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1020            (mp->match_n_vectors != 0xFFFFFFFF)))
1021         /*
1022          * Note: this is just barely thread-safe, depends on
1023          * the main thread spinning waiting for an answer...
1024          */
1025         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1026                 ntohl (mp->new_table_index),
1027                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1028       vam->result_ready = 1;
1029     }
1030 }
1031
1032 static void vl_api_classify_add_del_table_reply_t_handler_json
1033   (vl_api_classify_add_del_table_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   vat_json_node_t node;
1037
1038   vat_json_init_object (&node);
1039   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1040   vat_json_object_add_uint (&node, "new_table_index",
1041                             ntohl (mp->new_table_index));
1042   vat_json_object_add_uint (&node, "skip_n_vectors",
1043                             ntohl (mp->skip_n_vectors));
1044   vat_json_object_add_uint (&node, "match_n_vectors",
1045                             ntohl (mp->match_n_vectors));
1046
1047   vat_json_print (vam->ofp, &node);
1048   vat_json_free (&node);
1049
1050   vam->retval = ntohl (mp->retval);
1051   vam->result_ready = 1;
1052 }
1053
1054 static void vl_api_get_node_index_reply_t_handler
1055   (vl_api_get_node_index_reply_t * mp)
1056 {
1057   vat_main_t *vam = &vat_main;
1058   i32 retval = ntohl (mp->retval);
1059   if (vam->async_mode)
1060     {
1061       vam->async_errors += (retval < 0);
1062     }
1063   else
1064     {
1065       vam->retval = retval;
1066       if (retval == 0)
1067         errmsg ("node index %d", ntohl (mp->node_index));
1068       vam->result_ready = 1;
1069     }
1070 }
1071
1072 static void vl_api_get_node_index_reply_t_handler_json
1073   (vl_api_get_node_index_reply_t * mp)
1074 {
1075   vat_main_t *vam = &vat_main;
1076   vat_json_node_t node;
1077
1078   vat_json_init_object (&node);
1079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1080   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1081
1082   vat_json_print (vam->ofp, &node);
1083   vat_json_free (&node);
1084
1085   vam->retval = ntohl (mp->retval);
1086   vam->result_ready = 1;
1087 }
1088
1089 static void vl_api_get_next_index_reply_t_handler
1090   (vl_api_get_next_index_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   i32 retval = ntohl (mp->retval);
1094   if (vam->async_mode)
1095     {
1096       vam->async_errors += (retval < 0);
1097     }
1098   else
1099     {
1100       vam->retval = retval;
1101       if (retval == 0)
1102         errmsg ("next node index %d", ntohl (mp->next_index));
1103       vam->result_ready = 1;
1104     }
1105 }
1106
1107 static void vl_api_get_next_index_reply_t_handler_json
1108   (vl_api_get_next_index_reply_t * mp)
1109 {
1110   vat_main_t *vam = &vat_main;
1111   vat_json_node_t node;
1112
1113   vat_json_init_object (&node);
1114   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1115   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1116
1117   vat_json_print (vam->ofp, &node);
1118   vat_json_free (&node);
1119
1120   vam->retval = ntohl (mp->retval);
1121   vam->result_ready = 1;
1122 }
1123
1124 static void vl_api_add_node_next_reply_t_handler
1125   (vl_api_add_node_next_reply_t * mp)
1126 {
1127   vat_main_t *vam = &vat_main;
1128   i32 retval = ntohl (mp->retval);
1129   if (vam->async_mode)
1130     {
1131       vam->async_errors += (retval < 0);
1132     }
1133   else
1134     {
1135       vam->retval = retval;
1136       if (retval == 0)
1137         errmsg ("next index %d", ntohl (mp->next_index));
1138       vam->result_ready = 1;
1139     }
1140 }
1141
1142 static void vl_api_add_node_next_reply_t_handler_json
1143   (vl_api_add_node_next_reply_t * mp)
1144 {
1145   vat_main_t *vam = &vat_main;
1146   vat_json_node_t node;
1147
1148   vat_json_init_object (&node);
1149   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1150   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1151
1152   vat_json_print (vam->ofp, &node);
1153   vat_json_free (&node);
1154
1155   vam->retval = ntohl (mp->retval);
1156   vam->result_ready = 1;
1157 }
1158
1159 static void vl_api_show_version_reply_t_handler
1160   (vl_api_show_version_reply_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   i32 retval = ntohl (mp->retval);
1164
1165   if (retval >= 0)
1166     {
1167       errmsg ("        program: %s", mp->program);
1168       errmsg ("        version: %s", mp->version);
1169       errmsg ("     build date: %s", mp->build_date);
1170       errmsg ("build directory: %s", mp->build_directory);
1171     }
1172   vam->retval = retval;
1173   vam->result_ready = 1;
1174 }
1175
1176 static void vl_api_show_version_reply_t_handler_json
1177   (vl_api_show_version_reply_t * mp)
1178 {
1179   vat_main_t *vam = &vat_main;
1180   vat_json_node_t node;
1181
1182   vat_json_init_object (&node);
1183   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1184   vat_json_object_add_string_copy (&node, "program", mp->program);
1185   vat_json_object_add_string_copy (&node, "version", mp->version);
1186   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1187   vat_json_object_add_string_copy (&node, "build_directory",
1188                                    mp->build_directory);
1189
1190   vat_json_print (vam->ofp, &node);
1191   vat_json_free (&node);
1192
1193   vam->retval = ntohl (mp->retval);
1194   vam->result_ready = 1;
1195 }
1196
1197 static void
1198 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1199 {
1200   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1201           mp->mac_ip ? "mac/ip binding" : "address resolution",
1202           format_ip4_address, &mp->address,
1203           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1204 }
1205
1206 static void
1207 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1208 {
1209   /* JSON output not supported */
1210 }
1211
1212 static void
1213 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1214 {
1215   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1216           mp->mac_ip ? "mac/ip binding" : "address resolution",
1217           format_ip6_address, mp->address,
1218           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1219 }
1220
1221 static void
1222 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1223 {
1224   /* JSON output not supported */
1225 }
1226
1227 /*
1228  * Special-case: build the bridge domain table, maintain
1229  * the next bd id vbl.
1230  */
1231 static void vl_api_bridge_domain_details_t_handler
1232   (vl_api_bridge_domain_details_t * mp)
1233 {
1234   vat_main_t *vam = &vat_main;
1235   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1236
1237   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1238          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1239
1240   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1241          ntohl (mp->bd_id), mp->learn, mp->forward,
1242          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1243
1244   if (n_sw_ifs)
1245     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1246 }
1247
1248 static void vl_api_bridge_domain_details_t_handler_json
1249   (vl_api_bridge_domain_details_t * mp)
1250 {
1251   vat_main_t *vam = &vat_main;
1252   vat_json_node_t *node, *array = NULL;
1253
1254   if (VAT_JSON_ARRAY != vam->json_tree.type)
1255     {
1256       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1257       vat_json_init_array (&vam->json_tree);
1258     }
1259   node = vat_json_array_add (&vam->json_tree);
1260
1261   vat_json_init_object (node);
1262   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1263   vat_json_object_add_uint (node, "flood", mp->flood);
1264   vat_json_object_add_uint (node, "forward", mp->forward);
1265   vat_json_object_add_uint (node, "learn", mp->learn);
1266   vat_json_object_add_uint (node, "bvi_sw_if_index",
1267                             ntohl (mp->bvi_sw_if_index));
1268   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1269   array = vat_json_object_add (node, "sw_if");
1270   vat_json_init_array (array);
1271 }
1272
1273 /*
1274  * Special-case: build the bridge domain sw if table.
1275  */
1276 static void vl_api_bridge_domain_sw_if_details_t_handler
1277   (vl_api_bridge_domain_sw_if_details_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   hash_pair_t *p;
1281   u8 *sw_if_name = 0;
1282   u32 sw_if_index;
1283
1284   sw_if_index = ntohl (mp->sw_if_index);
1285   /* *INDENT-OFF* */
1286   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1287   ({
1288     if ((u32) p->value[0] == sw_if_index)
1289       {
1290         sw_if_name = (u8 *)(p->key);
1291         break;
1292       }
1293   }));
1294   /* *INDENT-ON* */
1295
1296   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1297          mp->shg, sw_if_name ? (char *) sw_if_name :
1298          "sw_if_index not found!");
1299 }
1300
1301 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1302   (vl_api_bridge_domain_sw_if_details_t * mp)
1303 {
1304   vat_main_t *vam = &vat_main;
1305   vat_json_node_t *node = NULL;
1306   uword last_index = 0;
1307
1308   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1309   ASSERT (vec_len (vam->json_tree.array) >= 1);
1310   last_index = vec_len (vam->json_tree.array) - 1;
1311   node = &vam->json_tree.array[last_index];
1312   node = vat_json_object_get_element (node, "sw_if");
1313   ASSERT (NULL != node);
1314   node = vat_json_array_add (node);
1315
1316   vat_json_init_object (node);
1317   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1318   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1319   vat_json_object_add_uint (node, "shg", mp->shg);
1320 }
1321
1322 static void vl_api_control_ping_reply_t_handler
1323   (vl_api_control_ping_reply_t * mp)
1324 {
1325   vat_main_t *vam = &vat_main;
1326   i32 retval = ntohl (mp->retval);
1327   if (vam->async_mode)
1328     {
1329       vam->async_errors += (retval < 0);
1330     }
1331   else
1332     {
1333       vam->retval = retval;
1334       vam->result_ready = 1;
1335     }
1336 }
1337
1338 static void vl_api_control_ping_reply_t_handler_json
1339   (vl_api_control_ping_reply_t * mp)
1340 {
1341   vat_main_t *vam = &vat_main;
1342   i32 retval = ntohl (mp->retval);
1343
1344   if (VAT_JSON_NONE != vam->json_tree.type)
1345     {
1346       vat_json_print (vam->ofp, &vam->json_tree);
1347       vat_json_free (&vam->json_tree);
1348       vam->json_tree.type = VAT_JSON_NONE;
1349     }
1350   else
1351     {
1352       /* just print [] */
1353       vat_json_init_array (&vam->json_tree);
1354       vat_json_print (vam->ofp, &vam->json_tree);
1355       vam->json_tree.type = VAT_JSON_NONE;
1356     }
1357
1358   vam->retval = retval;
1359   vam->result_ready = 1;
1360 }
1361
1362 static void
1363 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1364 {
1365   vat_main_t *vam = &vat_main;
1366   i32 retval = ntohl (mp->retval);
1367   if (vam->async_mode)
1368     {
1369       vam->async_errors += (retval < 0);
1370     }
1371   else
1372     {
1373       vam->retval = retval;
1374       vam->result_ready = 1;
1375     }
1376 }
1377
1378 static void vl_api_l2_flags_reply_t_handler_json
1379   (vl_api_l2_flags_reply_t * mp)
1380 {
1381   vat_main_t *vam = &vat_main;
1382   vat_json_node_t node;
1383
1384   vat_json_init_object (&node);
1385   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1386   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1387                             ntohl (mp->resulting_feature_bitmap));
1388
1389   vat_json_print (vam->ofp, &node);
1390   vat_json_free (&node);
1391
1392   vam->retval = ntohl (mp->retval);
1393   vam->result_ready = 1;
1394 }
1395
1396 static void vl_api_bridge_flags_reply_t_handler
1397   (vl_api_bridge_flags_reply_t * mp)
1398 {
1399   vat_main_t *vam = &vat_main;
1400   i32 retval = ntohl (mp->retval);
1401   if (vam->async_mode)
1402     {
1403       vam->async_errors += (retval < 0);
1404     }
1405   else
1406     {
1407       vam->retval = retval;
1408       vam->result_ready = 1;
1409     }
1410 }
1411
1412 static void vl_api_bridge_flags_reply_t_handler_json
1413   (vl_api_bridge_flags_reply_t * mp)
1414 {
1415   vat_main_t *vam = &vat_main;
1416   vat_json_node_t node;
1417
1418   vat_json_init_object (&node);
1419   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1420   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1421                             ntohl (mp->resulting_feature_bitmap));
1422
1423   vat_json_print (vam->ofp, &node);
1424   vat_json_free (&node);
1425
1426   vam->retval = ntohl (mp->retval);
1427   vam->result_ready = 1;
1428 }
1429
1430 static void vl_api_tap_connect_reply_t_handler
1431   (vl_api_tap_connect_reply_t * mp)
1432 {
1433   vat_main_t *vam = &vat_main;
1434   i32 retval = ntohl (mp->retval);
1435   if (vam->async_mode)
1436     {
1437       vam->async_errors += (retval < 0);
1438     }
1439   else
1440     {
1441       vam->retval = retval;
1442       vam->sw_if_index = ntohl (mp->sw_if_index);
1443       vam->result_ready = 1;
1444     }
1445
1446 }
1447
1448 static void vl_api_tap_connect_reply_t_handler_json
1449   (vl_api_tap_connect_reply_t * mp)
1450 {
1451   vat_main_t *vam = &vat_main;
1452   vat_json_node_t node;
1453
1454   vat_json_init_object (&node);
1455   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1456   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1457
1458   vat_json_print (vam->ofp, &node);
1459   vat_json_free (&node);
1460
1461   vam->retval = ntohl (mp->retval);
1462   vam->result_ready = 1;
1463
1464 }
1465
1466 static void
1467 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1468 {
1469   vat_main_t *vam = &vat_main;
1470   i32 retval = ntohl (mp->retval);
1471   if (vam->async_mode)
1472     {
1473       vam->async_errors += (retval < 0);
1474     }
1475   else
1476     {
1477       vam->retval = retval;
1478       vam->sw_if_index = ntohl (mp->sw_if_index);
1479       vam->result_ready = 1;
1480     }
1481 }
1482
1483 static void vl_api_tap_modify_reply_t_handler_json
1484   (vl_api_tap_modify_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   vat_json_node_t node;
1488
1489   vat_json_init_object (&node);
1490   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1491   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1492
1493   vat_json_print (vam->ofp, &node);
1494   vat_json_free (&node);
1495
1496   vam->retval = ntohl (mp->retval);
1497   vam->result_ready = 1;
1498 }
1499
1500 static void
1501 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1502 {
1503   vat_main_t *vam = &vat_main;
1504   i32 retval = ntohl (mp->retval);
1505   if (vam->async_mode)
1506     {
1507       vam->async_errors += (retval < 0);
1508     }
1509   else
1510     {
1511       vam->retval = retval;
1512       vam->result_ready = 1;
1513     }
1514 }
1515
1516 static void vl_api_tap_delete_reply_t_handler_json
1517   (vl_api_tap_delete_reply_t * mp)
1518 {
1519   vat_main_t *vam = &vat_main;
1520   vat_json_node_t node;
1521
1522   vat_json_init_object (&node);
1523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1524
1525   vat_json_print (vam->ofp, &node);
1526   vat_json_free (&node);
1527
1528   vam->retval = ntohl (mp->retval);
1529   vam->result_ready = 1;
1530 }
1531
1532 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1533   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1534 {
1535   vat_main_t *vam = &vat_main;
1536   i32 retval = ntohl (mp->retval);
1537   if (vam->async_mode)
1538     {
1539       vam->async_errors += (retval < 0);
1540     }
1541   else
1542     {
1543       vam->retval = retval;
1544       vam->result_ready = 1;
1545     }
1546 }
1547
1548 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1549   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1550 {
1551   vat_main_t *vam = &vat_main;
1552   vat_json_node_t node;
1553
1554   vat_json_init_object (&node);
1555   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1556   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1557                             ntohl (mp->sw_if_index));
1558
1559   vat_json_print (vam->ofp, &node);
1560   vat_json_free (&node);
1561
1562   vam->retval = ntohl (mp->retval);
1563   vam->result_ready = 1;
1564 }
1565
1566 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1567   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1568 {
1569   vat_main_t *vam = &vat_main;
1570   i32 retval = ntohl (mp->retval);
1571   if (vam->async_mode)
1572     {
1573       vam->async_errors += (retval < 0);
1574     }
1575   else
1576     {
1577       vam->retval = retval;
1578       vam->sw_if_index = ntohl (mp->sw_if_index);
1579       vam->result_ready = 1;
1580     }
1581 }
1582
1583 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1584   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1585 {
1586   vat_main_t *vam = &vat_main;
1587   vat_json_node_t node;
1588
1589   vat_json_init_object (&node);
1590   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1591   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1592
1593   vat_json_print (vam->ofp, &node);
1594   vat_json_free (&node);
1595
1596   vam->retval = ntohl (mp->retval);
1597   vam->result_ready = 1;
1598 }
1599
1600
1601 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1602   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1603 {
1604   vat_main_t *vam = &vat_main;
1605   i32 retval = ntohl (mp->retval);
1606   if (vam->async_mode)
1607     {
1608       vam->async_errors += (retval < 0);
1609     }
1610   else
1611     {
1612       vam->retval = retval;
1613       vam->result_ready = 1;
1614     }
1615 }
1616
1617 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1618   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1619 {
1620   vat_main_t *vam = &vat_main;
1621   vat_json_node_t node;
1622
1623   vat_json_init_object (&node);
1624   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1625   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1626
1627   vat_json_print (vam->ofp, &node);
1628   vat_json_free (&node);
1629
1630   vam->retval = ntohl (mp->retval);
1631   vam->result_ready = 1;
1632 }
1633
1634 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1635   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1636 {
1637   vat_main_t *vam = &vat_main;
1638   i32 retval = ntohl (mp->retval);
1639   if (vam->async_mode)
1640     {
1641       vam->async_errors += (retval < 0);
1642     }
1643   else
1644     {
1645       vam->retval = retval;
1646       vam->sw_if_index = ntohl (mp->sw_if_index);
1647       vam->result_ready = 1;
1648     }
1649 }
1650
1651 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1652   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1653 {
1654   vat_main_t *vam = &vat_main;
1655   vat_json_node_t node;
1656
1657   vat_json_init_object (&node);
1658   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1659   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1660
1661   vat_json_print (vam->ofp, &node);
1662   vat_json_free (&node);
1663
1664   vam->retval = ntohl (mp->retval);
1665   vam->result_ready = 1;
1666 }
1667
1668 static void vl_api_gre_add_del_tunnel_reply_t_handler
1669   (vl_api_gre_add_del_tunnel_reply_t * mp)
1670 {
1671   vat_main_t *vam = &vat_main;
1672   i32 retval = ntohl (mp->retval);
1673   if (vam->async_mode)
1674     {
1675       vam->async_errors += (retval < 0);
1676     }
1677   else
1678     {
1679       vam->retval = retval;
1680       vam->sw_if_index = ntohl (mp->sw_if_index);
1681       vam->result_ready = 1;
1682     }
1683 }
1684
1685 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1686   (vl_api_gre_add_del_tunnel_reply_t * mp)
1687 {
1688   vat_main_t *vam = &vat_main;
1689   vat_json_node_t node;
1690
1691   vat_json_init_object (&node);
1692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1694
1695   vat_json_print (vam->ofp, &node);
1696   vat_json_free (&node);
1697
1698   vam->retval = ntohl (mp->retval);
1699   vam->result_ready = 1;
1700 }
1701
1702 static void vl_api_create_vhost_user_if_reply_t_handler
1703   (vl_api_create_vhost_user_if_reply_t * mp)
1704 {
1705   vat_main_t *vam = &vat_main;
1706   i32 retval = ntohl (mp->retval);
1707   if (vam->async_mode)
1708     {
1709       vam->async_errors += (retval < 0);
1710     }
1711   else
1712     {
1713       vam->retval = retval;
1714       vam->sw_if_index = ntohl (mp->sw_if_index);
1715       vam->result_ready = 1;
1716     }
1717 }
1718
1719 static void vl_api_create_vhost_user_if_reply_t_handler_json
1720   (vl_api_create_vhost_user_if_reply_t * mp)
1721 {
1722   vat_main_t *vam = &vat_main;
1723   vat_json_node_t node;
1724
1725   vat_json_init_object (&node);
1726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1727   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1728
1729   vat_json_print (vam->ofp, &node);
1730   vat_json_free (&node);
1731
1732   vam->retval = ntohl (mp->retval);
1733   vam->result_ready = 1;
1734 }
1735
1736 static void vl_api_ip_address_details_t_handler
1737   (vl_api_ip_address_details_t * mp)
1738 {
1739   vat_main_t *vam = &vat_main;
1740   static ip_address_details_t empty_ip_address_details = { {0} };
1741   ip_address_details_t *address = NULL;
1742   ip_details_t *current_ip_details = NULL;
1743   ip_details_t *details = NULL;
1744
1745   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1746
1747   if (!details || vam->current_sw_if_index >= vec_len (details)
1748       || !details[vam->current_sw_if_index].present)
1749     {
1750       errmsg ("ip address details arrived but not stored");
1751       errmsg ("ip_dump should be called first");
1752       return;
1753     }
1754
1755   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1756
1757 #define addresses (current_ip_details->addr)
1758
1759   vec_validate_init_empty (addresses, vec_len (addresses),
1760                            empty_ip_address_details);
1761
1762   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1763
1764   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1765   address->prefix_length = mp->prefix_length;
1766 #undef addresses
1767 }
1768
1769 static void vl_api_ip_address_details_t_handler_json
1770   (vl_api_ip_address_details_t * mp)
1771 {
1772   vat_main_t *vam = &vat_main;
1773   vat_json_node_t *node = NULL;
1774   struct in6_addr ip6;
1775   struct in_addr ip4;
1776
1777   if (VAT_JSON_ARRAY != vam->json_tree.type)
1778     {
1779       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1780       vat_json_init_array (&vam->json_tree);
1781     }
1782   node = vat_json_array_add (&vam->json_tree);
1783
1784   vat_json_init_object (node);
1785   if (vam->is_ipv6)
1786     {
1787       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1788       vat_json_object_add_ip6 (node, "ip", ip6);
1789     }
1790   else
1791     {
1792       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1793       vat_json_object_add_ip4 (node, "ip", ip4);
1794     }
1795   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1796 }
1797
1798 static void
1799 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   static ip_details_t empty_ip_details = { 0 };
1803   ip_details_t *ip = NULL;
1804   u32 sw_if_index = ~0;
1805
1806   sw_if_index = ntohl (mp->sw_if_index);
1807
1808   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1809                            sw_if_index, empty_ip_details);
1810
1811   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1812                          sw_if_index);
1813
1814   ip->present = 1;
1815 }
1816
1817 static void
1818 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1819 {
1820   vat_main_t *vam = &vat_main;
1821
1822   if (VAT_JSON_ARRAY != vam->json_tree.type)
1823     {
1824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1825       vat_json_init_array (&vam->json_tree);
1826     }
1827   vat_json_array_add_uint (&vam->json_tree,
1828                            clib_net_to_host_u32 (mp->sw_if_index));
1829 }
1830
1831 static void vl_api_map_domain_details_t_handler_json
1832   (vl_api_map_domain_details_t * mp)
1833 {
1834   vat_json_node_t *node = NULL;
1835   vat_main_t *vam = &vat_main;
1836   struct in6_addr ip6;
1837   struct in_addr ip4;
1838
1839   if (VAT_JSON_ARRAY != vam->json_tree.type)
1840     {
1841       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1842       vat_json_init_array (&vam->json_tree);
1843     }
1844
1845   node = vat_json_array_add (&vam->json_tree);
1846   vat_json_init_object (node);
1847
1848   vat_json_object_add_uint (node, "domain_index",
1849                             clib_net_to_host_u32 (mp->domain_index));
1850   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1851   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1852   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1853   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1854   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1855   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1856   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1857   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1858   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1859   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1860   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1861   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1862   vat_json_object_add_uint (node, "flags", mp->flags);
1863   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1864   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1865 }
1866
1867 static void vl_api_map_domain_details_t_handler
1868   (vl_api_map_domain_details_t * mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871
1872   if (mp->is_translation)
1873     {
1874       print (vam->ofp,
1875              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1876              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1877              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1878              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1879              clib_net_to_host_u32 (mp->domain_index));
1880     }
1881   else
1882     {
1883       print (vam->ofp,
1884              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1885              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1886              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1887              format_ip6_address, mp->ip6_src,
1888              clib_net_to_host_u32 (mp->domain_index));
1889     }
1890   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1891          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1892          mp->is_translation ? "map-t" : "");
1893 }
1894
1895 static void vl_api_map_rule_details_t_handler_json
1896   (vl_api_map_rule_details_t * mp)
1897 {
1898   struct in6_addr ip6;
1899   vat_json_node_t *node = NULL;
1900   vat_main_t *vam = &vat_main;
1901
1902   if (VAT_JSON_ARRAY != vam->json_tree.type)
1903     {
1904       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1905       vat_json_init_array (&vam->json_tree);
1906     }
1907
1908   node = vat_json_array_add (&vam->json_tree);
1909   vat_json_init_object (node);
1910
1911   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1912   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1913   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1914 }
1915
1916 static void
1917 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1921          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1922 }
1923
1924 static void
1925 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1926 {
1927   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1928           "router_addr %U host_mac %U",
1929           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1930           format_ip4_address, &mp->host_address,
1931           format_ip4_address, &mp->router_address,
1932           format_ethernet_address, mp->host_mac);
1933 }
1934
1935 static void vl_api_dhcp_compl_event_t_handler_json
1936   (vl_api_dhcp_compl_event_t * mp)
1937 {
1938   /* JSON output not supported */
1939 }
1940
1941 static void
1942 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1943                               u32 counter)
1944 {
1945   vat_main_t *vam = &vat_main;
1946   static u64 default_counter = 0;
1947
1948   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1949                            NULL);
1950   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1951                            sw_if_index, default_counter);
1952   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1953 }
1954
1955 static void
1956 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1957                                 interface_counter_t counter)
1958 {
1959   vat_main_t *vam = &vat_main;
1960   static interface_counter_t default_counter = { 0, };
1961
1962   vec_validate_init_empty (vam->combined_interface_counters,
1963                            vnet_counter_type, NULL);
1964   vec_validate_init_empty (vam->combined_interface_counters
1965                            [vnet_counter_type], sw_if_index, default_counter);
1966   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1967 }
1968
1969 static void vl_api_vnet_interface_counters_t_handler
1970   (vl_api_vnet_interface_counters_t * mp)
1971 {
1972   /* not supported */
1973 }
1974
1975 static void vl_api_vnet_interface_counters_t_handler_json
1976   (vl_api_vnet_interface_counters_t * mp)
1977 {
1978   interface_counter_t counter;
1979   vlib_counter_t *v;
1980   u64 *v_packets;
1981   u64 packets;
1982   u32 count;
1983   u32 first_sw_if_index;
1984   int i;
1985
1986   count = ntohl (mp->count);
1987   first_sw_if_index = ntohl (mp->first_sw_if_index);
1988
1989   if (!mp->is_combined)
1990     {
1991       v_packets = (u64 *) & mp->data;
1992       for (i = 0; i < count; i++)
1993         {
1994           packets =
1995             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1996           set_simple_interface_counter (mp->vnet_counter_type,
1997                                         first_sw_if_index + i, packets);
1998           v_packets++;
1999         }
2000     }
2001   else
2002     {
2003       v = (vlib_counter_t *) & mp->data;
2004       for (i = 0; i < count; i++)
2005         {
2006           counter.packets =
2007             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2008           counter.bytes =
2009             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2010           set_combined_interface_counter (mp->vnet_counter_type,
2011                                           first_sw_if_index + i, counter);
2012           v++;
2013         }
2014     }
2015 }
2016
2017 static u32
2018 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2019 {
2020   vat_main_t *vam = &vat_main;
2021   u32 i;
2022
2023   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2024     {
2025       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2026         {
2027           return i;
2028         }
2029     }
2030   return ~0;
2031 }
2032
2033 static u32
2034 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2035 {
2036   vat_main_t *vam = &vat_main;
2037   u32 i;
2038
2039   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2040     {
2041       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2042         {
2043           return i;
2044         }
2045     }
2046   return ~0;
2047 }
2048
2049 static void vl_api_vnet_ip4_fib_counters_t_handler
2050   (vl_api_vnet_ip4_fib_counters_t * mp)
2051 {
2052   /* not supported */
2053 }
2054
2055 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2056   (vl_api_vnet_ip4_fib_counters_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vl_api_ip4_fib_counter_t *v;
2060   ip4_fib_counter_t *counter;
2061   struct in_addr ip4;
2062   u32 vrf_id;
2063   u32 vrf_index;
2064   u32 count;
2065   int i;
2066
2067   vrf_id = ntohl (mp->vrf_id);
2068   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2069   if (~0 == vrf_index)
2070     {
2071       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2072       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2073       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2074       vec_validate (vam->ip4_fib_counters, vrf_index);
2075       vam->ip4_fib_counters[vrf_index] = NULL;
2076     }
2077
2078   vec_free (vam->ip4_fib_counters[vrf_index]);
2079   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2080   count = ntohl (mp->count);
2081   for (i = 0; i < count; i++)
2082     {
2083       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2084       counter = &vam->ip4_fib_counters[vrf_index][i];
2085       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2086       counter->address = ip4;
2087       counter->address_length = v->address_length;
2088       counter->packets = clib_net_to_host_u64 (v->packets);
2089       counter->bytes = clib_net_to_host_u64 (v->bytes);
2090       v++;
2091     }
2092 }
2093
2094 static void vl_api_vnet_ip4_nbr_counters_t_handler
2095   (vl_api_vnet_ip4_nbr_counters_t * mp)
2096 {
2097   /* not supported */
2098 }
2099
2100 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2101   (vl_api_vnet_ip4_nbr_counters_t * mp)
2102 {
2103   vat_main_t *vam = &vat_main;
2104   vl_api_ip4_nbr_counter_t *v;
2105   ip4_nbr_counter_t *counter;
2106   u32 sw_if_index;
2107   u32 count;
2108   int i;
2109
2110   sw_if_index = ntohl (mp->sw_if_index);
2111   count = ntohl (mp->count);
2112   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2113
2114   if (mp->begin)
2115     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2116
2117   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2118   for (i = 0; i < count; i++)
2119     {
2120       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2121       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2122       counter->address.s_addr = v->address;
2123       counter->packets = clib_net_to_host_u64 (v->packets);
2124       counter->bytes = clib_net_to_host_u64 (v->bytes);
2125       counter->linkt = v->link_type;
2126       v++;
2127     }
2128 }
2129
2130 static void vl_api_vnet_ip6_fib_counters_t_handler
2131   (vl_api_vnet_ip6_fib_counters_t * mp)
2132 {
2133   /* not supported */
2134 }
2135
2136 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2137   (vl_api_vnet_ip6_fib_counters_t * mp)
2138 {
2139   vat_main_t *vam = &vat_main;
2140   vl_api_ip6_fib_counter_t *v;
2141   ip6_fib_counter_t *counter;
2142   struct in6_addr ip6;
2143   u32 vrf_id;
2144   u32 vrf_index;
2145   u32 count;
2146   int i;
2147
2148   vrf_id = ntohl (mp->vrf_id);
2149   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2150   if (~0 == vrf_index)
2151     {
2152       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2153       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2154       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2155       vec_validate (vam->ip6_fib_counters, vrf_index);
2156       vam->ip6_fib_counters[vrf_index] = NULL;
2157     }
2158
2159   vec_free (vam->ip6_fib_counters[vrf_index]);
2160   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2161   count = ntohl (mp->count);
2162   for (i = 0; i < count; i++)
2163     {
2164       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2165       counter = &vam->ip6_fib_counters[vrf_index][i];
2166       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2167       counter->address = ip6;
2168       counter->address_length = v->address_length;
2169       counter->packets = clib_net_to_host_u64 (v->packets);
2170       counter->bytes = clib_net_to_host_u64 (v->bytes);
2171       v++;
2172     }
2173 }
2174
2175 static void vl_api_vnet_ip6_nbr_counters_t_handler
2176   (vl_api_vnet_ip6_nbr_counters_t * mp)
2177 {
2178   /* not supported */
2179 }
2180
2181 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2182   (vl_api_vnet_ip6_nbr_counters_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   vl_api_ip6_nbr_counter_t *v;
2186   ip6_nbr_counter_t *counter;
2187   struct in6_addr ip6;
2188   u32 sw_if_index;
2189   u32 count;
2190   int i;
2191
2192   sw_if_index = ntohl (mp->sw_if_index);
2193   count = ntohl (mp->count);
2194   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2195
2196   if (mp->begin)
2197     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2198
2199   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2200   for (i = 0; i < count; i++)
2201     {
2202       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2203       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2204       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2205       counter->address = ip6;
2206       counter->packets = clib_net_to_host_u64 (v->packets);
2207       counter->bytes = clib_net_to_host_u64 (v->bytes);
2208       v++;
2209     }
2210 }
2211
2212 static void vl_api_get_first_msg_id_reply_t_handler
2213   (vl_api_get_first_msg_id_reply_t * mp)
2214 {
2215   vat_main_t *vam = &vat_main;
2216   i32 retval = ntohl (mp->retval);
2217
2218   if (vam->async_mode)
2219     {
2220       vam->async_errors += (retval < 0);
2221     }
2222   else
2223     {
2224       vam->retval = retval;
2225       vam->result_ready = 1;
2226     }
2227   if (retval >= 0)
2228     {
2229       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2230     }
2231 }
2232
2233 static void vl_api_get_first_msg_id_reply_t_handler_json
2234   (vl_api_get_first_msg_id_reply_t * mp)
2235 {
2236   vat_main_t *vam = &vat_main;
2237   vat_json_node_t node;
2238
2239   vat_json_init_object (&node);
2240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2241   vat_json_object_add_uint (&node, "first_msg_id",
2242                             (uint) ntohs (mp->first_msg_id));
2243
2244   vat_json_print (vam->ofp, &node);
2245   vat_json_free (&node);
2246
2247   vam->retval = ntohl (mp->retval);
2248   vam->result_ready = 1;
2249 }
2250
2251 static void vl_api_get_node_graph_reply_t_handler
2252   (vl_api_get_node_graph_reply_t * mp)
2253 {
2254   vat_main_t *vam = &vat_main;
2255   api_main_t *am = &api_main;
2256   i32 retval = ntohl (mp->retval);
2257   u8 *pvt_copy, *reply;
2258   void *oldheap;
2259   vlib_node_t *node;
2260   int i;
2261
2262   if (vam->async_mode)
2263     {
2264       vam->async_errors += (retval < 0);
2265     }
2266   else
2267     {
2268       vam->retval = retval;
2269       vam->result_ready = 1;
2270     }
2271
2272   /* "Should never happen..." */
2273   if (retval != 0)
2274     return;
2275
2276   reply = (u8 *) (mp->reply_in_shmem);
2277   pvt_copy = vec_dup (reply);
2278
2279   /* Toss the shared-memory original... */
2280   pthread_mutex_lock (&am->vlib_rp->mutex);
2281   oldheap = svm_push_data_heap (am->vlib_rp);
2282
2283   vec_free (reply);
2284
2285   svm_pop_heap (oldheap);
2286   pthread_mutex_unlock (&am->vlib_rp->mutex);
2287
2288   if (vam->graph_nodes)
2289     {
2290       hash_free (vam->graph_node_index_by_name);
2291
2292       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2293         {
2294           node = vam->graph_nodes[i];
2295           vec_free (node->name);
2296           vec_free (node->next_nodes);
2297           vec_free (node);
2298         }
2299       vec_free (vam->graph_nodes);
2300     }
2301
2302   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2303   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2304   vec_free (pvt_copy);
2305
2306   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2307     {
2308       node = vam->graph_nodes[i];
2309       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2310     }
2311 }
2312
2313 static void vl_api_get_node_graph_reply_t_handler_json
2314   (vl_api_get_node_graph_reply_t * mp)
2315 {
2316   vat_main_t *vam = &vat_main;
2317   api_main_t *am = &api_main;
2318   void *oldheap;
2319   vat_json_node_t node;
2320   u8 *reply;
2321
2322   /* $$$$ make this real? */
2323   vat_json_init_object (&node);
2324   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2325   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2326
2327   reply = (u8 *) (mp->reply_in_shmem);
2328
2329   /* Toss the shared-memory original... */
2330   pthread_mutex_lock (&am->vlib_rp->mutex);
2331   oldheap = svm_push_data_heap (am->vlib_rp);
2332
2333   vec_free (reply);
2334
2335   svm_pop_heap (oldheap);
2336   pthread_mutex_unlock (&am->vlib_rp->mutex);
2337
2338   vat_json_print (vam->ofp, &node);
2339   vat_json_free (&node);
2340
2341   vam->retval = ntohl (mp->retval);
2342   vam->result_ready = 1;
2343 }
2344
2345 static void
2346 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2347 {
2348   vat_main_t *vam = &vat_main;
2349   u8 *s = 0;
2350
2351   if (mp->local)
2352     {
2353       s = format (s, "%=16d%=16d%=16d",
2354                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2355     }
2356   else
2357     {
2358       s = format (s, "%=16U%=16d%=16d",
2359                   mp->is_ipv6 ? format_ip6_address :
2360                   format_ip4_address,
2361                   mp->ip_address, mp->priority, mp->weight);
2362     }
2363
2364   print (vam->ofp, "%v", s);
2365   vec_free (s);
2366 }
2367
2368 static void
2369 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2370                                             mp)
2371 {
2372   vat_main_t *vam = &vat_main;
2373   vat_json_node_t *node = NULL;
2374   struct in6_addr ip6;
2375   struct in_addr ip4;
2376
2377   if (VAT_JSON_ARRAY != vam->json_tree.type)
2378     {
2379       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2380       vat_json_init_array (&vam->json_tree);
2381     }
2382   node = vat_json_array_add (&vam->json_tree);
2383   vat_json_init_object (node);
2384
2385   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2386   vat_json_object_add_uint (node, "priority", mp->priority);
2387   vat_json_object_add_uint (node, "weight", mp->weight);
2388
2389   if (mp->local)
2390     vat_json_object_add_uint (node, "sw_if_index",
2391                               clib_net_to_host_u32 (mp->sw_if_index));
2392   else
2393     {
2394       if (mp->is_ipv6)
2395         {
2396           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2397           vat_json_object_add_ip6 (node, "address", ip6);
2398         }
2399       else
2400         {
2401           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2402           vat_json_object_add_ip4 (node, "address", ip4);
2403         }
2404     }
2405 }
2406
2407 static void
2408 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2409                                            mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   u8 *ls_name = 0;
2413
2414   ls_name = format (0, "%s", mp->ls_name);
2415
2416   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2417          ls_name);
2418   vec_free (ls_name);
2419 }
2420
2421 static void
2422   vl_api_lisp_locator_set_details_t_handler_json
2423   (vl_api_lisp_locator_set_details_t * mp)
2424 {
2425   vat_main_t *vam = &vat_main;
2426   vat_json_node_t *node = 0;
2427   u8 *ls_name = 0;
2428
2429   ls_name = format (0, "%s", mp->ls_name);
2430   vec_add1 (ls_name, 0);
2431
2432   if (VAT_JSON_ARRAY != vam->json_tree.type)
2433     {
2434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2435       vat_json_init_array (&vam->json_tree);
2436     }
2437   node = vat_json_array_add (&vam->json_tree);
2438
2439   vat_json_init_object (node);
2440   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2441   vat_json_object_add_uint (node, "ls_index",
2442                             clib_net_to_host_u32 (mp->ls_index));
2443   vec_free (ls_name);
2444 }
2445
2446 static u8 *
2447 format_lisp_flat_eid (u8 * s, va_list * args)
2448 {
2449   u32 type = va_arg (*args, u32);
2450   u8 *eid = va_arg (*args, u8 *);
2451   u32 eid_len = va_arg (*args, u32);
2452
2453   switch (type)
2454     {
2455     case 0:
2456       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2457     case 1:
2458       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2459     case 2:
2460       return format (s, "%U", format_ethernet_address, eid);
2461     }
2462   return 0;
2463 }
2464
2465 static u8 *
2466 format_lisp_eid_vat (u8 * s, va_list * args)
2467 {
2468   u32 type = va_arg (*args, u32);
2469   u8 *eid = va_arg (*args, u8 *);
2470   u32 eid_len = va_arg (*args, u32);
2471   u8 *seid = va_arg (*args, u8 *);
2472   u32 seid_len = va_arg (*args, u32);
2473   u32 is_src_dst = va_arg (*args, u32);
2474
2475   if (is_src_dst)
2476     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2477
2478   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2479
2480   return s;
2481 }
2482
2483 static void
2484 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2485 {
2486   vat_main_t *vam = &vat_main;
2487   u8 *s = 0, *eid = 0;
2488
2489   if (~0 == mp->locator_set_index)
2490     s = format (0, "action: %d", mp->action);
2491   else
2492     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2493
2494   eid = format (0, "%U", format_lisp_eid_vat,
2495                 mp->eid_type,
2496                 mp->eid,
2497                 mp->eid_prefix_len,
2498                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2499   vec_add1 (eid, 0);
2500
2501   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2502          clib_net_to_host_u32 (mp->vni),
2503          eid,
2504          mp->is_local ? "local" : "remote",
2505          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2506          clib_net_to_host_u16 (mp->key_id), mp->key);
2507
2508   vec_free (s);
2509   vec_free (eid);
2510 }
2511
2512 static void
2513 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2514                                               * mp)
2515 {
2516   vat_main_t *vam = &vat_main;
2517   vat_json_node_t *node = 0;
2518   u8 *eid = 0;
2519
2520   if (VAT_JSON_ARRAY != vam->json_tree.type)
2521     {
2522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2523       vat_json_init_array (&vam->json_tree);
2524     }
2525   node = vat_json_array_add (&vam->json_tree);
2526
2527   vat_json_init_object (node);
2528   if (~0 == mp->locator_set_index)
2529     vat_json_object_add_uint (node, "action", mp->action);
2530   else
2531     vat_json_object_add_uint (node, "locator_set_index",
2532                               clib_net_to_host_u32 (mp->locator_set_index));
2533
2534   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2535   eid = format (0, "%U", format_lisp_eid_vat,
2536                 mp->eid_type,
2537                 mp->eid,
2538                 mp->eid_prefix_len,
2539                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2540   vec_add1 (eid, 0);
2541   vat_json_object_add_string_copy (node, "eid", eid);
2542   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2543   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2544   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2545
2546   if (mp->key_id)
2547     {
2548       vat_json_object_add_uint (node, "key_id",
2549                                 clib_net_to_host_u16 (mp->key_id));
2550       vat_json_object_add_string_copy (node, "key", mp->key);
2551     }
2552   vec_free (eid);
2553 }
2554
2555 static void
2556   vl_api_lisp_eid_table_map_details_t_handler
2557   (vl_api_lisp_eid_table_map_details_t * mp)
2558 {
2559   vat_main_t *vam = &vat_main;
2560
2561   u8 *line = format (0, "%=10d%=10d",
2562                      clib_net_to_host_u32 (mp->vni),
2563                      clib_net_to_host_u32 (mp->dp_table));
2564   print (vam->ofp, "%v", line);
2565   vec_free (line);
2566 }
2567
2568 static void
2569   vl_api_lisp_eid_table_map_details_t_handler_json
2570   (vl_api_lisp_eid_table_map_details_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   vat_json_node_t *node = NULL;
2574
2575   if (VAT_JSON_ARRAY != vam->json_tree.type)
2576     {
2577       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2578       vat_json_init_array (&vam->json_tree);
2579     }
2580   node = vat_json_array_add (&vam->json_tree);
2581   vat_json_init_object (node);
2582   vat_json_object_add_uint (node, "dp_table",
2583                             clib_net_to_host_u32 (mp->dp_table));
2584   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2585 }
2586
2587 static void
2588   vl_api_lisp_eid_table_vni_details_t_handler
2589   (vl_api_lisp_eid_table_vni_details_t * mp)
2590 {
2591   vat_main_t *vam = &vat_main;
2592
2593   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2594   print (vam->ofp, "%v", line);
2595   vec_free (line);
2596 }
2597
2598 static void
2599   vl_api_lisp_eid_table_vni_details_t_handler_json
2600   (vl_api_lisp_eid_table_vni_details_t * mp)
2601 {
2602   vat_main_t *vam = &vat_main;
2603   vat_json_node_t *node = NULL;
2604
2605   if (VAT_JSON_ARRAY != vam->json_tree.type)
2606     {
2607       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2608       vat_json_init_array (&vam->json_tree);
2609     }
2610   node = vat_json_array_add (&vam->json_tree);
2611   vat_json_init_object (node);
2612   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2613 }
2614
2615 static void
2616   vl_api_show_lisp_map_register_state_reply_t_handler
2617   (vl_api_show_lisp_map_register_state_reply_t * mp)
2618 {
2619   vat_main_t *vam = &vat_main;
2620   int retval = clib_net_to_host_u32 (mp->retval);
2621
2622   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2623
2624   vam->retval = retval;
2625   vam->result_ready = 1;
2626 }
2627
2628 static void
2629   vl_api_show_lisp_map_register_state_reply_t_handler_json
2630   (vl_api_show_lisp_map_register_state_reply_t * mp)
2631 {
2632   vat_main_t *vam = &vat_main;
2633   vat_json_node_t _node, *node = &_node;
2634   int retval = clib_net_to_host_u32 (mp->retval);
2635
2636   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2637
2638   vat_json_init_object (node);
2639   vat_json_object_add_string_copy (node, "state", s);
2640
2641   vat_json_print (vam->ofp, node);
2642   vat_json_free (node);
2643
2644   vam->retval = retval;
2645   vam->result_ready = 1;
2646   vec_free (s);
2647 }
2648
2649 static void
2650   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2651   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2652 {
2653   vat_main_t *vam = &vat_main;
2654   int retval = clib_net_to_host_u32 (mp->retval);
2655
2656   if (retval)
2657     goto end;
2658
2659   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2660 end:
2661   vam->retval = retval;
2662   vam->result_ready = 1;
2663 }
2664
2665 static void
2666   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2667   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2668 {
2669   vat_main_t *vam = &vat_main;
2670   vat_json_node_t _node, *node = &_node;
2671   int retval = clib_net_to_host_u32 (mp->retval);
2672
2673   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2674   vat_json_init_object (node);
2675   vat_json_object_add_string_copy (node, "state", s);
2676
2677   vat_json_print (vam->ofp, node);
2678   vat_json_free (node);
2679
2680   vam->retval = retval;
2681   vam->result_ready = 1;
2682   vec_free (s);
2683 }
2684
2685 static void
2686 api_lisp_gpe_fwd_entry_net_to_host (vl_api_lisp_gpe_fwd_entry_t * e)
2687 {
2688   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2689   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2690 }
2691
2692 static void
2693   lisp_gpe_fwd_entries_get_reply_t_net_to_host
2694   (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2695 {
2696   u32 i;
2697
2698   mp->count = clib_net_to_host_u32 (mp->count);
2699   for (i = 0; i < mp->count; i++)
2700     {
2701       api_lisp_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2702     }
2703 }
2704
2705 static void
2706   vl_api_lisp_gpe_fwd_entry_path_details_t_handler
2707   (vl_api_lisp_gpe_fwd_entry_path_details_t * mp)
2708 {
2709   vat_main_t *vam = &vat_main;
2710   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2711
2712   if (mp->lcl_loc.is_ip4)
2713     format_ip_address_fcn = format_ip4_address;
2714   else
2715     format_ip_address_fcn = format_ip6_address;
2716
2717   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2718          format_ip_address_fcn, &mp->lcl_loc,
2719          format_ip_address_fcn, &mp->rmt_loc);
2720 }
2721
2722 static void
2723 lisp_fill_locator_node (vat_json_node_t * n, vl_api_lisp_gpe_locator_t * loc)
2724 {
2725   struct in6_addr ip6;
2726   struct in_addr ip4;
2727
2728   if (loc->is_ip4)
2729     {
2730       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2731       vat_json_object_add_ip4 (n, "address", ip4);
2732     }
2733   else
2734     {
2735       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2736       vat_json_object_add_ip6 (n, "address", ip6);
2737     }
2738   vat_json_object_add_uint (n, "weight", loc->weight);
2739 }
2740
2741 static void
2742   vl_api_lisp_gpe_fwd_entry_path_details_t_handler_json
2743   (vl_api_lisp_gpe_fwd_entry_path_details_t * mp)
2744 {
2745   vat_main_t *vam = &vat_main;
2746   vat_json_node_t *node = NULL;
2747   vat_json_node_t *loc_node;
2748
2749   if (VAT_JSON_ARRAY != vam->json_tree.type)
2750     {
2751       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2752       vat_json_init_array (&vam->json_tree);
2753     }
2754   node = vat_json_array_add (&vam->json_tree);
2755   vat_json_init_object (node);
2756
2757   loc_node = vat_json_object_add (node, "local_locator");
2758   vat_json_init_object (loc_node);
2759   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2760
2761   loc_node = vat_json_object_add (node, "remote_locator");
2762   vat_json_init_object (loc_node);
2763   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2764 }
2765
2766 static void
2767   vl_api_lisp_gpe_fwd_entries_get_reply_t_handler
2768   (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2769 {
2770   vat_main_t *vam = &vat_main;
2771   u32 i;
2772   int retval = clib_net_to_host_u32 (mp->retval);
2773   vl_api_lisp_gpe_fwd_entry_t *e;
2774
2775   if (retval)
2776     goto end;
2777
2778   lisp_gpe_fwd_entries_get_reply_t_net_to_host (mp);
2779
2780   for (i = 0; i < mp->count; i++)
2781     {
2782       e = &mp->entries[i];
2783       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2784              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2785              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2786     }
2787
2788 end:
2789   vam->retval = retval;
2790   vam->result_ready = 1;
2791 }
2792
2793 static void
2794   vl_api_lisp_gpe_fwd_entries_get_reply_t_handler_json
2795   (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2796 {
2797   u8 *s = 0;
2798   vat_main_t *vam = &vat_main;
2799   vat_json_node_t *e = 0, root;
2800   u32 i;
2801   int retval = clib_net_to_host_u32 (mp->retval);
2802   vl_api_lisp_gpe_fwd_entry_t *fwd;
2803
2804   if (retval)
2805     goto end;
2806
2807   lisp_gpe_fwd_entries_get_reply_t_net_to_host (mp);
2808   vat_json_init_array (&root);
2809
2810   for (i = 0; i < mp->count; i++)
2811     {
2812       e = vat_json_array_add (&root);
2813       fwd = &mp->entries[i];
2814
2815       vat_json_init_object (e);
2816       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2817       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2818
2819       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2820                   fwd->leid_prefix_len);
2821       vec_add1 (s, 0);
2822       vat_json_object_add_string_copy (e, "leid", s);
2823       vec_free (s);
2824
2825       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2826                   fwd->reid_prefix_len);
2827       vec_add1 (s, 0);
2828       vat_json_object_add_string_copy (e, "reid", s);
2829       vec_free (s);
2830     }
2831
2832   vat_json_print (vam->ofp, &root);
2833   vat_json_free (&root);
2834
2835 end:
2836   vam->retval = retval;
2837   vam->result_ready = 1;
2838 }
2839
2840 static void
2841   vl_api_lisp_adjacencies_get_reply_t_handler
2842   (vl_api_lisp_adjacencies_get_reply_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   u32 i, n;
2846   int retval = clib_net_to_host_u32 (mp->retval);
2847   vl_api_lisp_adjacency_t *a;
2848
2849   if (retval)
2850     goto end;
2851
2852   n = clib_net_to_host_u32 (mp->count);
2853
2854   for (i = 0; i < n; i++)
2855     {
2856       a = &mp->adjacencies[i];
2857       print (vam->ofp, "%U %40U",
2858              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2859              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2860     }
2861
2862 end:
2863   vam->retval = retval;
2864   vam->result_ready = 1;
2865 }
2866
2867 static void
2868   vl_api_lisp_adjacencies_get_reply_t_handler_json
2869   (vl_api_lisp_adjacencies_get_reply_t * mp)
2870 {
2871   u8 *s = 0;
2872   vat_main_t *vam = &vat_main;
2873   vat_json_node_t *e = 0, root;
2874   u32 i, n;
2875   int retval = clib_net_to_host_u32 (mp->retval);
2876   vl_api_lisp_adjacency_t *a;
2877
2878   if (retval)
2879     goto end;
2880
2881   n = clib_net_to_host_u32 (mp->count);
2882   vat_json_init_array (&root);
2883
2884   for (i = 0; i < n; i++)
2885     {
2886       e = vat_json_array_add (&root);
2887       a = &mp->adjacencies[i];
2888
2889       vat_json_init_object (e);
2890       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2891                   a->leid_prefix_len);
2892       vec_add1 (s, 0);
2893       vat_json_object_add_string_copy (e, "leid", s);
2894       vec_free (s);
2895
2896       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2897                   a->reid_prefix_len);
2898       vec_add1 (s, 0);
2899       vat_json_object_add_string_copy (e, "reid", s);
2900       vec_free (s);
2901     }
2902
2903   vat_json_print (vam->ofp, &root);
2904   vat_json_free (&root);
2905
2906 end:
2907   vam->retval = retval;
2908   vam->result_ready = 1;
2909 }
2910
2911 static void
2912 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2913                                           * mp)
2914 {
2915   vat_main_t *vam = &vat_main;
2916
2917   print (vam->ofp, "%=20U",
2918          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2919          mp->ip_address);
2920 }
2921
2922 static void
2923   vl_api_lisp_map_server_details_t_handler_json
2924   (vl_api_lisp_map_server_details_t * mp)
2925 {
2926   vat_main_t *vam = &vat_main;
2927   vat_json_node_t *node = NULL;
2928   struct in6_addr ip6;
2929   struct in_addr ip4;
2930
2931   if (VAT_JSON_ARRAY != vam->json_tree.type)
2932     {
2933       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2934       vat_json_init_array (&vam->json_tree);
2935     }
2936   node = vat_json_array_add (&vam->json_tree);
2937
2938   vat_json_init_object (node);
2939   if (mp->is_ipv6)
2940     {
2941       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2942       vat_json_object_add_ip6 (node, "map-server", ip6);
2943     }
2944   else
2945     {
2946       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2947       vat_json_object_add_ip4 (node, "map-server", ip4);
2948     }
2949 }
2950
2951 static void
2952 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2953                                             * mp)
2954 {
2955   vat_main_t *vam = &vat_main;
2956
2957   print (vam->ofp, "%=20U",
2958          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2959          mp->ip_address);
2960 }
2961
2962 static void
2963   vl_api_lisp_map_resolver_details_t_handler_json
2964   (vl_api_lisp_map_resolver_details_t * mp)
2965 {
2966   vat_main_t *vam = &vat_main;
2967   vat_json_node_t *node = NULL;
2968   struct in6_addr ip6;
2969   struct in_addr ip4;
2970
2971   if (VAT_JSON_ARRAY != vam->json_tree.type)
2972     {
2973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2974       vat_json_init_array (&vam->json_tree);
2975     }
2976   node = vat_json_array_add (&vam->json_tree);
2977
2978   vat_json_init_object (node);
2979   if (mp->is_ipv6)
2980     {
2981       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2982       vat_json_object_add_ip6 (node, "map resolver", ip6);
2983     }
2984   else
2985     {
2986       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2987       vat_json_object_add_ip4 (node, "map resolver", ip4);
2988     }
2989 }
2990
2991 static void
2992   vl_api_show_lisp_status_reply_t_handler
2993   (vl_api_show_lisp_status_reply_t * mp)
2994 {
2995   vat_main_t *vam = &vat_main;
2996   i32 retval = ntohl (mp->retval);
2997
2998   if (0 <= retval)
2999     {
3000       print (vam->ofp, "feature: %s\ngpe: %s",
3001              mp->feature_status ? "enabled" : "disabled",
3002              mp->gpe_status ? "enabled" : "disabled");
3003     }
3004
3005   vam->retval = retval;
3006   vam->result_ready = 1;
3007 }
3008
3009 static void
3010   vl_api_show_lisp_status_reply_t_handler_json
3011   (vl_api_show_lisp_status_reply_t * mp)
3012 {
3013   vat_main_t *vam = &vat_main;
3014   vat_json_node_t node;
3015   u8 *gpe_status = NULL;
3016   u8 *feature_status = NULL;
3017
3018   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3019   feature_status = format (0, "%s",
3020                            mp->feature_status ? "enabled" : "disabled");
3021   vec_add1 (gpe_status, 0);
3022   vec_add1 (feature_status, 0);
3023
3024   vat_json_init_object (&node);
3025   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3026   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3027
3028   vec_free (gpe_status);
3029   vec_free (feature_status);
3030
3031   vat_json_print (vam->ofp, &node);
3032   vat_json_free (&node);
3033
3034   vam->retval = ntohl (mp->retval);
3035   vam->result_ready = 1;
3036 }
3037
3038 static void
3039   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
3040   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
3041 {
3042   vat_main_t *vam = &vat_main;
3043   i32 retval = ntohl (mp->retval);
3044
3045   if (retval >= 0)
3046     {
3047       print (vam->ofp, "%=20s", mp->locator_set_name);
3048     }
3049
3050   vam->retval = retval;
3051   vam->result_ready = 1;
3052 }
3053
3054 static void
3055   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
3056   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
3057 {
3058   vat_main_t *vam = &vat_main;
3059   vat_json_node_t *node = NULL;
3060
3061   if (VAT_JSON_ARRAY != vam->json_tree.type)
3062     {
3063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3064       vat_json_init_array (&vam->json_tree);
3065     }
3066   node = vat_json_array_add (&vam->json_tree);
3067
3068   vat_json_init_object (node);
3069   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3070
3071   vat_json_print (vam->ofp, node);
3072   vat_json_free (node);
3073
3074   vam->retval = ntohl (mp->retval);
3075   vam->result_ready = 1;
3076 }
3077
3078 static u8 *
3079 format_lisp_map_request_mode (u8 * s, va_list * args)
3080 {
3081   u32 mode = va_arg (*args, u32);
3082
3083   switch (mode)
3084     {
3085     case 0:
3086       return format (0, "dst-only");
3087     case 1:
3088       return format (0, "src-dst");
3089     }
3090   return 0;
3091 }
3092
3093 static void
3094   vl_api_show_lisp_map_request_mode_reply_t_handler
3095   (vl_api_show_lisp_map_request_mode_reply_t * mp)
3096 {
3097   vat_main_t *vam = &vat_main;
3098   i32 retval = ntohl (mp->retval);
3099
3100   if (0 <= retval)
3101     {
3102       u32 mode = mp->mode;
3103       print (vam->ofp, "map_request_mode: %U",
3104              format_lisp_map_request_mode, mode);
3105     }
3106
3107   vam->retval = retval;
3108   vam->result_ready = 1;
3109 }
3110
3111 static void
3112   vl_api_show_lisp_map_request_mode_reply_t_handler_json
3113   (vl_api_show_lisp_map_request_mode_reply_t * mp)
3114 {
3115   vat_main_t *vam = &vat_main;
3116   vat_json_node_t node;
3117   u8 *s = 0;
3118   u32 mode;
3119
3120   mode = mp->mode;
3121   s = format (0, "%U", format_lisp_map_request_mode, mode);
3122   vec_add1 (s, 0);
3123
3124   vat_json_init_object (&node);
3125   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3126   vat_json_print (vam->ofp, &node);
3127   vat_json_free (&node);
3128
3129   vec_free (s);
3130   vam->retval = ntohl (mp->retval);
3131   vam->result_ready = 1;
3132 }
3133
3134 static void
3135 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
3136 {
3137   vat_main_t *vam = &vat_main;
3138   i32 retval = ntohl (mp->retval);
3139
3140   if (0 <= retval)
3141     {
3142       print (vam->ofp, "%-20s%-16s",
3143              mp->status ? "enabled" : "disabled",
3144              mp->status ? (char *) mp->locator_set_name : "");
3145     }
3146
3147   vam->retval = retval;
3148   vam->result_ready = 1;
3149 }
3150
3151 static void
3152 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
3153                                             mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   vat_json_node_t node;
3157   u8 *status = 0;
3158
3159   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3160   vec_add1 (status, 0);
3161
3162   vat_json_init_object (&node);
3163   vat_json_object_add_string_copy (&node, "status", status);
3164   if (mp->status)
3165     {
3166       vat_json_object_add_string_copy (&node, "locator_set",
3167                                        mp->locator_set_name);
3168     }
3169
3170   vec_free (status);
3171
3172   vat_json_print (vam->ofp, &node);
3173   vat_json_free (&node);
3174
3175   vam->retval = ntohl (mp->retval);
3176   vam->result_ready = 1;
3177 }
3178
3179 static u8 *
3180 format_policer_type (u8 * s, va_list * va)
3181 {
3182   u32 i = va_arg (*va, u32);
3183
3184   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3185     s = format (s, "1r2c");
3186   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3187     s = format (s, "1r3c");
3188   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3189     s = format (s, "2r3c-2698");
3190   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3191     s = format (s, "2r3c-4115");
3192   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3193     s = format (s, "2r3c-mef5cf1");
3194   else
3195     s = format (s, "ILLEGAL");
3196   return s;
3197 }
3198
3199 static u8 *
3200 format_policer_rate_type (u8 * s, va_list * va)
3201 {
3202   u32 i = va_arg (*va, u32);
3203
3204   if (i == SSE2_QOS_RATE_KBPS)
3205     s = format (s, "kbps");
3206   else if (i == SSE2_QOS_RATE_PPS)
3207     s = format (s, "pps");
3208   else
3209     s = format (s, "ILLEGAL");
3210   return s;
3211 }
3212
3213 static u8 *
3214 format_policer_round_type (u8 * s, va_list * va)
3215 {
3216   u32 i = va_arg (*va, u32);
3217
3218   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3219     s = format (s, "closest");
3220   else if (i == SSE2_QOS_ROUND_TO_UP)
3221     s = format (s, "up");
3222   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3223     s = format (s, "down");
3224   else
3225     s = format (s, "ILLEGAL");
3226   return s;
3227 }
3228
3229 static u8 *
3230 format_policer_action_type (u8 * s, va_list * va)
3231 {
3232   u32 i = va_arg (*va, u32);
3233
3234   if (i == SSE2_QOS_ACTION_DROP)
3235     s = format (s, "drop");
3236   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3237     s = format (s, "transmit");
3238   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3239     s = format (s, "mark-and-transmit");
3240   else
3241     s = format (s, "ILLEGAL");
3242   return s;
3243 }
3244
3245 static u8 *
3246 format_dscp (u8 * s, va_list * va)
3247 {
3248   u32 i = va_arg (*va, u32);
3249   char *t = 0;
3250
3251   switch (i)
3252     {
3253 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3254       foreach_vnet_dscp
3255 #undef _
3256     default:
3257       return format (s, "ILLEGAL");
3258     }
3259   s = format (s, "%s", t);
3260   return s;
3261 }
3262
3263 static void
3264 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3265 {
3266   vat_main_t *vam = &vat_main;
3267   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3268
3269   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3270     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3271   else
3272     conform_dscp_str = format (0, "");
3273
3274   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3275     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3276   else
3277     exceed_dscp_str = format (0, "");
3278
3279   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3280     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3281   else
3282     violate_dscp_str = format (0, "");
3283
3284   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3285          "rate type %U, round type %U, %s rate, %s color-aware, "
3286          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3287          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3288          "conform action %U%s, exceed action %U%s, violate action %U%s",
3289          mp->name,
3290          format_policer_type, mp->type,
3291          ntohl (mp->cir),
3292          ntohl (mp->eir),
3293          clib_net_to_host_u64 (mp->cb),
3294          clib_net_to_host_u64 (mp->eb),
3295          format_policer_rate_type, mp->rate_type,
3296          format_policer_round_type, mp->round_type,
3297          mp->single_rate ? "single" : "dual",
3298          mp->color_aware ? "is" : "not",
3299          ntohl (mp->cir_tokens_per_period),
3300          ntohl (mp->pir_tokens_per_period),
3301          ntohl (mp->scale),
3302          ntohl (mp->current_limit),
3303          ntohl (mp->current_bucket),
3304          ntohl (mp->extended_limit),
3305          ntohl (mp->extended_bucket),
3306          clib_net_to_host_u64 (mp->last_update_time),
3307          format_policer_action_type, mp->conform_action_type,
3308          conform_dscp_str,
3309          format_policer_action_type, mp->exceed_action_type,
3310          exceed_dscp_str,
3311          format_policer_action_type, mp->violate_action_type,
3312          violate_dscp_str);
3313
3314   vec_free (conform_dscp_str);
3315   vec_free (exceed_dscp_str);
3316   vec_free (violate_dscp_str);
3317 }
3318
3319 static void vl_api_policer_details_t_handler_json
3320   (vl_api_policer_details_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t *node;
3324   u8 *rate_type_str, *round_type_str, *type_str;
3325   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3326
3327   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3328   round_type_str =
3329     format (0, "%U", format_policer_round_type, mp->round_type);
3330   type_str = format (0, "%U", format_policer_type, mp->type);
3331   conform_action_str = format (0, "%U", format_policer_action_type,
3332                                mp->conform_action_type);
3333   exceed_action_str = format (0, "%U", format_policer_action_type,
3334                               mp->exceed_action_type);
3335   violate_action_str = format (0, "%U", format_policer_action_type,
3336                                mp->violate_action_type);
3337
3338   if (VAT_JSON_ARRAY != vam->json_tree.type)
3339     {
3340       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3341       vat_json_init_array (&vam->json_tree);
3342     }
3343   node = vat_json_array_add (&vam->json_tree);
3344
3345   vat_json_init_object (node);
3346   vat_json_object_add_string_copy (node, "name", mp->name);
3347   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3348   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3349   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3350   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3351   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3352   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3353   vat_json_object_add_string_copy (node, "type", type_str);
3354   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3355   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3356   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3357   vat_json_object_add_uint (node, "cir_tokens_per_period",
3358                             ntohl (mp->cir_tokens_per_period));
3359   vat_json_object_add_uint (node, "eir_tokens_per_period",
3360                             ntohl (mp->pir_tokens_per_period));
3361   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3362   vat_json_object_add_uint (node, "current_bucket",
3363                             ntohl (mp->current_bucket));
3364   vat_json_object_add_uint (node, "extended_limit",
3365                             ntohl (mp->extended_limit));
3366   vat_json_object_add_uint (node, "extended_bucket",
3367                             ntohl (mp->extended_bucket));
3368   vat_json_object_add_uint (node, "last_update_time",
3369                             ntohl (mp->last_update_time));
3370   vat_json_object_add_string_copy (node, "conform_action",
3371                                    conform_action_str);
3372   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3373     {
3374       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3375       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3376       vec_free (dscp_str);
3377     }
3378   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3379   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3380     {
3381       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3382       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3383       vec_free (dscp_str);
3384     }
3385   vat_json_object_add_string_copy (node, "violate_action",
3386                                    violate_action_str);
3387   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3388     {
3389       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3390       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3391       vec_free (dscp_str);
3392     }
3393
3394   vec_free (rate_type_str);
3395   vec_free (round_type_str);
3396   vec_free (type_str);
3397   vec_free (conform_action_str);
3398   vec_free (exceed_action_str);
3399   vec_free (violate_action_str);
3400 }
3401
3402 static void
3403 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3404                                            mp)
3405 {
3406   vat_main_t *vam = &vat_main;
3407   int i, count = ntohl (mp->count);
3408
3409   if (count > 0)
3410     print (vam->ofp, "classify table ids (%d) : ", count);
3411   for (i = 0; i < count; i++)
3412     {
3413       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3414       print (vam->ofp, (i < count - 1) ? "," : "");
3415     }
3416   vam->retval = ntohl (mp->retval);
3417   vam->result_ready = 1;
3418 }
3419
3420 static void
3421   vl_api_classify_table_ids_reply_t_handler_json
3422   (vl_api_classify_table_ids_reply_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   int i, count = ntohl (mp->count);
3426
3427   if (count > 0)
3428     {
3429       vat_json_node_t node;
3430
3431       vat_json_init_object (&node);
3432       for (i = 0; i < count; i++)
3433         {
3434           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3435         }
3436       vat_json_print (vam->ofp, &node);
3437       vat_json_free (&node);
3438     }
3439   vam->retval = ntohl (mp->retval);
3440   vam->result_ready = 1;
3441 }
3442
3443 static void
3444   vl_api_classify_table_by_interface_reply_t_handler
3445   (vl_api_classify_table_by_interface_reply_t * mp)
3446 {
3447   vat_main_t *vam = &vat_main;
3448   u32 table_id;
3449
3450   table_id = ntohl (mp->l2_table_id);
3451   if (table_id != ~0)
3452     print (vam->ofp, "l2 table id : %d", table_id);
3453   else
3454     print (vam->ofp, "l2 table id : No input ACL tables configured");
3455   table_id = ntohl (mp->ip4_table_id);
3456   if (table_id != ~0)
3457     print (vam->ofp, "ip4 table id : %d", table_id);
3458   else
3459     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3460   table_id = ntohl (mp->ip6_table_id);
3461   if (table_id != ~0)
3462     print (vam->ofp, "ip6 table id : %d", table_id);
3463   else
3464     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3465   vam->retval = ntohl (mp->retval);
3466   vam->result_ready = 1;
3467 }
3468
3469 static void
3470   vl_api_classify_table_by_interface_reply_t_handler_json
3471   (vl_api_classify_table_by_interface_reply_t * mp)
3472 {
3473   vat_main_t *vam = &vat_main;
3474   vat_json_node_t node;
3475
3476   vat_json_init_object (&node);
3477
3478   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3479   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3480   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3481
3482   vat_json_print (vam->ofp, &node);
3483   vat_json_free (&node);
3484
3485   vam->retval = ntohl (mp->retval);
3486   vam->result_ready = 1;
3487 }
3488
3489 static void vl_api_policer_add_del_reply_t_handler
3490   (vl_api_policer_add_del_reply_t * mp)
3491 {
3492   vat_main_t *vam = &vat_main;
3493   i32 retval = ntohl (mp->retval);
3494   if (vam->async_mode)
3495     {
3496       vam->async_errors += (retval < 0);
3497     }
3498   else
3499     {
3500       vam->retval = retval;
3501       vam->result_ready = 1;
3502       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3503         /*
3504          * Note: this is just barely thread-safe, depends on
3505          * the main thread spinning waiting for an answer...
3506          */
3507         errmsg ("policer index %d", ntohl (mp->policer_index));
3508     }
3509 }
3510
3511 static void vl_api_policer_add_del_reply_t_handler_json
3512   (vl_api_policer_add_del_reply_t * mp)
3513 {
3514   vat_main_t *vam = &vat_main;
3515   vat_json_node_t node;
3516
3517   vat_json_init_object (&node);
3518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3519   vat_json_object_add_uint (&node, "policer_index",
3520                             ntohl (mp->policer_index));
3521
3522   vat_json_print (vam->ofp, &node);
3523   vat_json_free (&node);
3524
3525   vam->retval = ntohl (mp->retval);
3526   vam->result_ready = 1;
3527 }
3528
3529 /* Format hex dump. */
3530 u8 *
3531 format_hex_bytes (u8 * s, va_list * va)
3532 {
3533   u8 *bytes = va_arg (*va, u8 *);
3534   int n_bytes = va_arg (*va, int);
3535   uword i;
3536
3537   /* Print short or long form depending on byte count. */
3538   uword short_form = n_bytes <= 32;
3539   uword indent = format_get_indent (s);
3540
3541   if (n_bytes == 0)
3542     return s;
3543
3544   for (i = 0; i < n_bytes; i++)
3545     {
3546       if (!short_form && (i % 32) == 0)
3547         s = format (s, "%08x: ", i);
3548       s = format (s, "%02x", bytes[i]);
3549       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3550         s = format (s, "\n%U", format_white_space, indent);
3551     }
3552
3553   return s;
3554 }
3555
3556 static void
3557 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3558                                             * mp)
3559 {
3560   vat_main_t *vam = &vat_main;
3561   i32 retval = ntohl (mp->retval);
3562   if (retval == 0)
3563     {
3564       print (vam->ofp, "classify table info :");
3565       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3566              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3567              ntohl (mp->miss_next_index));
3568       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3569              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3570              ntohl (mp->match_n_vectors));
3571       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3572              ntohl (mp->mask_length));
3573     }
3574   vam->retval = retval;
3575   vam->result_ready = 1;
3576 }
3577
3578 static void
3579   vl_api_classify_table_info_reply_t_handler_json
3580   (vl_api_classify_table_info_reply_t * mp)
3581 {
3582   vat_main_t *vam = &vat_main;
3583   vat_json_node_t node;
3584
3585   i32 retval = ntohl (mp->retval);
3586   if (retval == 0)
3587     {
3588       vat_json_init_object (&node);
3589
3590       vat_json_object_add_int (&node, "sessions",
3591                                ntohl (mp->active_sessions));
3592       vat_json_object_add_int (&node, "nexttbl",
3593                                ntohl (mp->next_table_index));
3594       vat_json_object_add_int (&node, "nextnode",
3595                                ntohl (mp->miss_next_index));
3596       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3597       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3598       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3599       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3600                       ntohl (mp->mask_length), 0);
3601       vat_json_object_add_string_copy (&node, "mask", s);
3602
3603       vat_json_print (vam->ofp, &node);
3604       vat_json_free (&node);
3605     }
3606   vam->retval = ntohl (mp->retval);
3607   vam->result_ready = 1;
3608 }
3609
3610 static void
3611 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3612                                            mp)
3613 {
3614   vat_main_t *vam = &vat_main;
3615
3616   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3617          ntohl (mp->hit_next_index), ntohl (mp->advance),
3618          ntohl (mp->opaque_index));
3619   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3620          ntohl (mp->match_length));
3621 }
3622
3623 static void
3624   vl_api_classify_session_details_t_handler_json
3625   (vl_api_classify_session_details_t * mp)
3626 {
3627   vat_main_t *vam = &vat_main;
3628   vat_json_node_t *node = NULL;
3629
3630   if (VAT_JSON_ARRAY != vam->json_tree.type)
3631     {
3632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3633       vat_json_init_array (&vam->json_tree);
3634     }
3635   node = vat_json_array_add (&vam->json_tree);
3636
3637   vat_json_init_object (node);
3638   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3639   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3640   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3641   u8 *s =
3642     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3643             0);
3644   vat_json_object_add_string_copy (node, "match", s);
3645 }
3646
3647 static void vl_api_pg_create_interface_reply_t_handler
3648   (vl_api_pg_create_interface_reply_t * mp)
3649 {
3650   vat_main_t *vam = &vat_main;
3651
3652   vam->retval = ntohl (mp->retval);
3653   vam->result_ready = 1;
3654 }
3655
3656 static void vl_api_pg_create_interface_reply_t_handler_json
3657   (vl_api_pg_create_interface_reply_t * mp)
3658 {
3659   vat_main_t *vam = &vat_main;
3660   vat_json_node_t node;
3661
3662   i32 retval = ntohl (mp->retval);
3663   if (retval == 0)
3664     {
3665       vat_json_init_object (&node);
3666
3667       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3668
3669       vat_json_print (vam->ofp, &node);
3670       vat_json_free (&node);
3671     }
3672   vam->retval = ntohl (mp->retval);
3673   vam->result_ready = 1;
3674 }
3675
3676 static void vl_api_policer_classify_details_t_handler
3677   (vl_api_policer_classify_details_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680
3681   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3682          ntohl (mp->table_index));
3683 }
3684
3685 static void vl_api_policer_classify_details_t_handler_json
3686   (vl_api_policer_classify_details_t * mp)
3687 {
3688   vat_main_t *vam = &vat_main;
3689   vat_json_node_t *node;
3690
3691   if (VAT_JSON_ARRAY != vam->json_tree.type)
3692     {
3693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3694       vat_json_init_array (&vam->json_tree);
3695     }
3696   node = vat_json_array_add (&vam->json_tree);
3697
3698   vat_json_init_object (node);
3699   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3700   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3701 }
3702
3703 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3704   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3705 {
3706   vat_main_t *vam = &vat_main;
3707   i32 retval = ntohl (mp->retval);
3708   if (vam->async_mode)
3709     {
3710       vam->async_errors += (retval < 0);
3711     }
3712   else
3713     {
3714       vam->retval = retval;
3715       vam->sw_if_index = ntohl (mp->sw_if_index);
3716       vam->result_ready = 1;
3717     }
3718 }
3719
3720 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3721   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3722 {
3723   vat_main_t *vam = &vat_main;
3724   vat_json_node_t node;
3725
3726   vat_json_init_object (&node);
3727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3729
3730   vat_json_print (vam->ofp, &node);
3731   vat_json_free (&node);
3732
3733   vam->retval = ntohl (mp->retval);
3734   vam->result_ready = 1;
3735 }
3736
3737 static void vl_api_flow_classify_details_t_handler
3738   (vl_api_flow_classify_details_t * mp)
3739 {
3740   vat_main_t *vam = &vat_main;
3741
3742   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3743          ntohl (mp->table_index));
3744 }
3745
3746 static void vl_api_flow_classify_details_t_handler_json
3747   (vl_api_flow_classify_details_t * mp)
3748 {
3749   vat_main_t *vam = &vat_main;
3750   vat_json_node_t *node;
3751
3752   if (VAT_JSON_ARRAY != vam->json_tree.type)
3753     {
3754       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3755       vat_json_init_array (&vam->json_tree);
3756     }
3757   node = vat_json_array_add (&vam->json_tree);
3758
3759   vat_json_init_object (node);
3760   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3761   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3762 }
3763
3764
3765
3766 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3767 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3768 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3769 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3770 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3771 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3772 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3773 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3774 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3775 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3776
3777 /*
3778  * Generate boilerplate reply handlers, which
3779  * dig the return value out of the xxx_reply_t API message,
3780  * stick it into vam->retval, and set vam->result_ready
3781  *
3782  * Could also do this by pointing N message decode slots at
3783  * a single function, but that could break in subtle ways.
3784  */
3785
3786 #define foreach_standard_reply_retval_handler           \
3787 _(sw_interface_set_flags_reply)                         \
3788 _(sw_interface_add_del_address_reply)                   \
3789 _(sw_interface_set_table_reply)                         \
3790 _(sw_interface_set_mpls_enable_reply)                   \
3791 _(sw_interface_set_vpath_reply)                         \
3792 _(sw_interface_set_vxlan_bypass_reply)                  \
3793 _(sw_interface_set_l2_bridge_reply)                     \
3794 _(bridge_domain_add_del_reply)                          \
3795 _(sw_interface_set_l2_xconnect_reply)                   \
3796 _(l2fib_add_del_reply)                                  \
3797 _(ip_add_del_route_reply)                               \
3798 _(ip_mroute_add_del_reply)                              \
3799 _(mpls_route_add_del_reply)                             \
3800 _(mpls_ip_bind_unbind_reply)                            \
3801 _(proxy_arp_add_del_reply)                              \
3802 _(proxy_arp_intfc_enable_disable_reply)                 \
3803 _(sw_interface_set_unnumbered_reply)                    \
3804 _(ip_neighbor_add_del_reply)                            \
3805 _(reset_vrf_reply)                                      \
3806 _(oam_add_del_reply)                                    \
3807 _(reset_fib_reply)                                      \
3808 _(dhcp_proxy_config_reply)                              \
3809 _(dhcp_proxy_config_2_reply)                            \
3810 _(dhcp_proxy_set_vss_reply)                             \
3811 _(dhcp_client_config_reply)                             \
3812 _(set_ip_flow_hash_reply)                               \
3813 _(sw_interface_ip6_enable_disable_reply)                \
3814 _(sw_interface_ip6_set_link_local_address_reply)        \
3815 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3816 _(sw_interface_ip6nd_ra_config_reply)                   \
3817 _(set_arp_neighbor_limit_reply)                         \
3818 _(l2_patch_add_del_reply)                               \
3819 _(sr_tunnel_add_del_reply)                              \
3820 _(sr_policy_add_del_reply)                              \
3821 _(sr_multicast_map_add_del_reply)                       \
3822 _(classify_add_del_session_reply)                       \
3823 _(classify_set_interface_ip_table_reply)                \
3824 _(classify_set_interface_l2_tables_reply)               \
3825 _(l2tpv3_set_tunnel_cookies_reply)                      \
3826 _(l2tpv3_interface_enable_disable_reply)                \
3827 _(l2tpv3_set_lookup_key_reply)                          \
3828 _(l2_fib_clear_table_reply)                             \
3829 _(l2_interface_efp_filter_reply)                        \
3830 _(l2_interface_vlan_tag_rewrite_reply)                  \
3831 _(modify_vhost_user_if_reply)                           \
3832 _(delete_vhost_user_if_reply)                           \
3833 _(want_ip4_arp_events_reply)                            \
3834 _(want_ip6_nd_events_reply)                             \
3835 _(input_acl_set_interface_reply)                        \
3836 _(ipsec_spd_add_del_reply)                              \
3837 _(ipsec_interface_add_del_spd_reply)                    \
3838 _(ipsec_spd_add_del_entry_reply)                        \
3839 _(ipsec_sad_add_del_entry_reply)                        \
3840 _(ipsec_sa_set_key_reply)                               \
3841 _(ikev2_profile_add_del_reply)                          \
3842 _(ikev2_profile_set_auth_reply)                         \
3843 _(ikev2_profile_set_id_reply)                           \
3844 _(ikev2_profile_set_ts_reply)                           \
3845 _(ikev2_set_local_key_reply)                            \
3846 _(delete_loopback_reply)                                \
3847 _(bd_ip_mac_add_del_reply)                              \
3848 _(map_del_domain_reply)                                 \
3849 _(map_add_del_rule_reply)                               \
3850 _(want_interface_events_reply)                          \
3851 _(want_stats_reply)                                     \
3852 _(cop_interface_enable_disable_reply)                   \
3853 _(cop_whitelist_enable_disable_reply)                   \
3854 _(sw_interface_clear_stats_reply)                       \
3855 _(ioam_enable_reply)                              \
3856 _(ioam_disable_reply)                              \
3857 _(lisp_add_del_locator_reply)                           \
3858 _(lisp_add_del_local_eid_reply)                         \
3859 _(lisp_add_del_remote_mapping_reply)                    \
3860 _(lisp_add_del_adjacency_reply)                         \
3861 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3862 _(lisp_add_del_map_resolver_reply)                      \
3863 _(lisp_add_del_map_server_reply)                        \
3864 _(lisp_gpe_enable_disable_reply)                        \
3865 _(lisp_gpe_add_del_iface_reply)                         \
3866 _(lisp_enable_disable_reply)                            \
3867 _(lisp_rloc_probe_enable_disable_reply)                 \
3868 _(lisp_map_register_enable_disable_reply)               \
3869 _(lisp_pitr_set_locator_set_reply)                      \
3870 _(lisp_map_request_mode_reply)                          \
3871 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3872 _(lisp_eid_table_add_del_map_reply)                     \
3873 _(vxlan_gpe_add_del_tunnel_reply)                       \
3874 _(af_packet_delete_reply)                               \
3875 _(policer_classify_set_interface_reply)                 \
3876 _(netmap_create_reply)                                  \
3877 _(netmap_delete_reply)                                  \
3878 _(set_ipfix_exporter_reply)                             \
3879 _(set_ipfix_classify_stream_reply)                      \
3880 _(ipfix_classify_table_add_del_reply)                   \
3881 _(flow_classify_set_interface_reply)                    \
3882 _(sw_interface_span_enable_disable_reply)               \
3883 _(pg_capture_reply)                                     \
3884 _(pg_enable_disable_reply)                              \
3885 _(ip_source_and_port_range_check_add_del_reply)         \
3886 _(ip_source_and_port_range_check_interface_add_del_reply)\
3887 _(delete_subif_reply)                                   \
3888 _(l2_interface_pbb_tag_rewrite_reply)                   \
3889 _(punt_reply)                                           \
3890 _(feature_enable_disable_reply)                         \
3891 _(sw_interface_tag_add_del_reply)                       \
3892 _(sw_interface_set_mtu_reply)
3893
3894 #if DPDK > 0
3895 #define foreach_standard_dpdk_reply_retval_handler      \
3896 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3897 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3898 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3899 #endif
3900
3901 #define _(n)                                    \
3902     static void vl_api_##n##_t_handler          \
3903     (vl_api_##n##_t * mp)                       \
3904     {                                           \
3905         vat_main_t * vam = &vat_main;           \
3906         i32 retval = ntohl(mp->retval);         \
3907         if (vam->async_mode) {                  \
3908             vam->async_errors += (retval < 0);  \
3909         } else {                                \
3910             vam->retval = retval;               \
3911             vam->result_ready = 1;              \
3912         }                                       \
3913     }
3914 foreach_standard_reply_retval_handler;
3915 #undef _
3916
3917 #define _(n)                                    \
3918     static void vl_api_##n##_t_handler_json     \
3919     (vl_api_##n##_t * mp)                       \
3920     {                                           \
3921         vat_main_t * vam = &vat_main;           \
3922         vat_json_node_t node;                   \
3923         vat_json_init_object(&node);            \
3924         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3925         vat_json_print(vam->ofp, &node);        \
3926         vam->retval = ntohl(mp->retval);        \
3927         vam->result_ready = 1;                  \
3928     }
3929 foreach_standard_reply_retval_handler;
3930 #undef _
3931
3932 #if DPDK > 0
3933 #define _(n)                                    \
3934     static void vl_api_##n##_t_handler          \
3935     (vl_api_##n##_t * mp)                       \
3936     {                                           \
3937         vat_main_t * vam = &vat_main;           \
3938         i32 retval = ntohl(mp->retval);         \
3939         if (vam->async_mode) {                  \
3940             vam->async_errors += (retval < 0);  \
3941         } else {                                \
3942             vam->retval = retval;               \
3943             vam->result_ready = 1;              \
3944         }                                       \
3945     }
3946 foreach_standard_dpdk_reply_retval_handler;
3947 #undef _
3948
3949 #define _(n)                                    \
3950     static void vl_api_##n##_t_handler_json     \
3951     (vl_api_##n##_t * mp)                       \
3952     {                                           \
3953         vat_main_t * vam = &vat_main;           \
3954         vat_json_node_t node;                   \
3955         vat_json_init_object(&node);            \
3956         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3957         vat_json_print(vam->ofp, &node);        \
3958         vam->retval = ntohl(mp->retval);        \
3959         vam->result_ready = 1;                  \
3960     }
3961 foreach_standard_dpdk_reply_retval_handler;
3962 #undef _
3963 #endif
3964
3965 /*
3966  * Table of message reply handlers, must include boilerplate handlers
3967  * we just generated
3968  */
3969
3970 #define foreach_vpe_api_reply_msg                                       \
3971 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3972 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3973 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3974 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3975 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3976 _(CLI_REPLY, cli_reply)                                                 \
3977 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3978 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3979   sw_interface_add_del_address_reply)                                   \
3980 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3981 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3982 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3983 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3984 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3985   sw_interface_set_l2_xconnect_reply)                                   \
3986 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3987   sw_interface_set_l2_bridge_reply)                                     \
3988 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3989 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3990 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3991 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3992 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3993 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3994 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3995 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3996 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3997 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3998 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3999 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4000 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4001 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4002 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4003 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4004   proxy_arp_intfc_enable_disable_reply)                                 \
4005 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4006 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4007   sw_interface_set_unnumbered_reply)                                    \
4008 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4009 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4010 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4011 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4012 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4013 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4014 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4015 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
4016 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4017 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4018 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4019 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4020   sw_interface_ip6_enable_disable_reply)                                \
4021 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4022   sw_interface_ip6_set_link_local_address_reply)                        \
4023 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4024   sw_interface_ip6nd_ra_prefix_reply)                                   \
4025 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4026   sw_interface_ip6nd_ra_config_reply)                                   \
4027 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4028 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4029 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4030 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4031 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4032 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4033 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4034 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4035 classify_set_interface_ip_table_reply)                                  \
4036 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4037   classify_set_interface_l2_tables_reply)                               \
4038 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4039 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4040 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4041 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4042 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4043   l2tpv3_interface_enable_disable_reply)                                \
4044 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4045 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4046 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4047 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4048 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4049 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4050 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4051 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4052 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4053 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4054 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4055 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4056 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4057 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4058 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4059 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4060 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4061 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4062 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4063 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4064 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4065 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4066 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4067 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4068 _(IP_DETAILS, ip_details)                                               \
4069 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4070 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4071 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4072 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4073 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4074 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4075 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4076 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4077 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4078 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4079 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4080 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4081 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4082 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4083 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4084 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4085 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4086 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
4087 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4088 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4089 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4090 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4091 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4092 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4093 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4094 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4095 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4096 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4097 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4098 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4099 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4100 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4101 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
4102 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
4103 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
4104 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
4105 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
4106 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
4107 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
4108 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
4109 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
4110 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
4111 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
4112   lisp_map_register_enable_disable_reply)                               \
4113 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
4114   lisp_rloc_probe_enable_disable_reply)                                 \
4115 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
4116 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
4117 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
4118 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
4119 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
4120 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
4121 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
4122 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
4123 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
4124 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
4125 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
4126 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
4127 _(LISP_GPE_FWD_ENTRIES_GET_REPLY, lisp_gpe_fwd_entries_get_reply)       \
4128 _(LISP_GPE_FWD_ENTRY_PATH_DETAILS,                                      \
4129   lisp_gpe_fwd_entry_path_details)                                      \
4130 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
4131 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
4132   lisp_add_del_map_request_itr_rlocs_reply)                             \
4133 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
4134   lisp_get_map_request_itr_rlocs_reply)                                 \
4135 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
4136 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
4137 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
4138 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
4139   show_lisp_map_register_state_reply)                                   \
4140 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4141 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4142 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4143 _(POLICER_DETAILS, policer_details)                                     \
4144 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4145 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4146 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4147 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4148 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4149 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4150 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4151 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4152 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4153 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4154 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4155 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4156 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4157 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4158 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4159 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4160 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4161 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4162 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4163 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4164 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4165 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4166 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4167 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4168 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4169  ip_source_and_port_range_check_add_del_reply)                          \
4170 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4171  ip_source_and_port_range_check_interface_add_del_reply)                \
4172 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4173 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4174 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4175 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4176 _(PUNT_REPLY, punt_reply)                                               \
4177 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4178 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4179 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4180 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4181 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4182 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4183 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4184 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4185
4186 #if DPDK > 0
4187 #define foreach_vpe_dpdk_api_reply_msg                                  \
4188 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
4189   sw_interface_set_dpdk_hqos_pipe_reply)                                \
4190 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
4191   sw_interface_set_dpdk_hqos_subport_reply)                             \
4192 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
4193   sw_interface_set_dpdk_hqos_tctbl_reply)
4194 #endif
4195
4196 typedef struct
4197 {
4198   u8 *name;
4199   u32 value;
4200 } name_sort_t;
4201
4202
4203 #define STR_VTR_OP_CASE(op)     \
4204     case L2_VTR_ ## op:         \
4205         return "" # op;
4206
4207 static const char *
4208 str_vtr_op (u32 vtr_op)
4209 {
4210   switch (vtr_op)
4211     {
4212       STR_VTR_OP_CASE (DISABLED);
4213       STR_VTR_OP_CASE (PUSH_1);
4214       STR_VTR_OP_CASE (PUSH_2);
4215       STR_VTR_OP_CASE (POP_1);
4216       STR_VTR_OP_CASE (POP_2);
4217       STR_VTR_OP_CASE (TRANSLATE_1_1);
4218       STR_VTR_OP_CASE (TRANSLATE_1_2);
4219       STR_VTR_OP_CASE (TRANSLATE_2_1);
4220       STR_VTR_OP_CASE (TRANSLATE_2_2);
4221     }
4222
4223   return "UNKNOWN";
4224 }
4225
4226 static int
4227 dump_sub_interface_table (vat_main_t * vam)
4228 {
4229   const sw_interface_subif_t *sub = NULL;
4230
4231   if (vam->json_output)
4232     {
4233       clib_warning
4234         ("JSON output supported only for VPE API calls and dump_stats_table");
4235       return -99;
4236     }
4237
4238   print (vam->ofp,
4239          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4240          "Interface", "sw_if_index",
4241          "sub id", "dot1ad", "tags", "outer id",
4242          "inner id", "exact", "default", "outer any", "inner any");
4243
4244   vec_foreach (sub, vam->sw_if_subif_table)
4245   {
4246     print (vam->ofp,
4247            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4248            sub->interface_name,
4249            sub->sw_if_index,
4250            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4251            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4252            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4253            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4254     if (sub->vtr_op != L2_VTR_DISABLED)
4255       {
4256         print (vam->ofp,
4257                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4258                "tag1: %d tag2: %d ]",
4259                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4260                sub->vtr_tag1, sub->vtr_tag2);
4261       }
4262   }
4263
4264   return 0;
4265 }
4266
4267 static int
4268 name_sort_cmp (void *a1, void *a2)
4269 {
4270   name_sort_t *n1 = a1;
4271   name_sort_t *n2 = a2;
4272
4273   return strcmp ((char *) n1->name, (char *) n2->name);
4274 }
4275
4276 static int
4277 dump_interface_table (vat_main_t * vam)
4278 {
4279   hash_pair_t *p;
4280   name_sort_t *nses = 0, *ns;
4281
4282   if (vam->json_output)
4283     {
4284       clib_warning
4285         ("JSON output supported only for VPE API calls and dump_stats_table");
4286       return -99;
4287     }
4288
4289   /* *INDENT-OFF* */
4290   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4291   ({
4292     vec_add2 (nses, ns, 1);
4293     ns->name = (u8 *)(p->key);
4294     ns->value = (u32) p->value[0];
4295   }));
4296   /* *INDENT-ON* */
4297
4298   vec_sort_with_function (nses, name_sort_cmp);
4299
4300   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4301   vec_foreach (ns, nses)
4302   {
4303     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4304   }
4305   vec_free (nses);
4306   return 0;
4307 }
4308
4309 static int
4310 dump_ip_table (vat_main_t * vam, int is_ipv6)
4311 {
4312   const ip_details_t *det = NULL;
4313   const ip_address_details_t *address = NULL;
4314   u32 i = ~0;
4315
4316   print (vam->ofp, "%-12s", "sw_if_index");
4317
4318   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4319   {
4320     i++;
4321     if (!det->present)
4322       {
4323         continue;
4324       }
4325     print (vam->ofp, "%-12d", i);
4326     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4327     if (!det->addr)
4328       {
4329         continue;
4330       }
4331     vec_foreach (address, det->addr)
4332     {
4333       print (vam->ofp,
4334              "            %-30U%-13d",
4335              is_ipv6 ? format_ip6_address : format_ip4_address,
4336              address->ip, address->prefix_length);
4337     }
4338   }
4339
4340   return 0;
4341 }
4342
4343 static int
4344 dump_ipv4_table (vat_main_t * vam)
4345 {
4346   if (vam->json_output)
4347     {
4348       clib_warning
4349         ("JSON output supported only for VPE API calls and dump_stats_table");
4350       return -99;
4351     }
4352
4353   return dump_ip_table (vam, 0);
4354 }
4355
4356 static int
4357 dump_ipv6_table (vat_main_t * vam)
4358 {
4359   if (vam->json_output)
4360     {
4361       clib_warning
4362         ("JSON output supported only for VPE API calls and dump_stats_table");
4363       return -99;
4364     }
4365
4366   return dump_ip_table (vam, 1);
4367 }
4368
4369 static char *
4370 counter_type_to_str (u8 counter_type, u8 is_combined)
4371 {
4372   if (!is_combined)
4373     {
4374       switch (counter_type)
4375         {
4376         case VNET_INTERFACE_COUNTER_DROP:
4377           return "drop";
4378         case VNET_INTERFACE_COUNTER_PUNT:
4379           return "punt";
4380         case VNET_INTERFACE_COUNTER_IP4:
4381           return "ip4";
4382         case VNET_INTERFACE_COUNTER_IP6:
4383           return "ip6";
4384         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4385           return "rx-no-buf";
4386         case VNET_INTERFACE_COUNTER_RX_MISS:
4387           return "rx-miss";
4388         case VNET_INTERFACE_COUNTER_RX_ERROR:
4389           return "rx-error";
4390         case VNET_INTERFACE_COUNTER_TX_ERROR:
4391           return "tx-error";
4392         default:
4393           return "INVALID-COUNTER-TYPE";
4394         }
4395     }
4396   else
4397     {
4398       switch (counter_type)
4399         {
4400         case VNET_INTERFACE_COUNTER_RX:
4401           return "rx";
4402         case VNET_INTERFACE_COUNTER_TX:
4403           return "tx";
4404         default:
4405           return "INVALID-COUNTER-TYPE";
4406         }
4407     }
4408 }
4409
4410 static int
4411 dump_stats_table (vat_main_t * vam)
4412 {
4413   vat_json_node_t node;
4414   vat_json_node_t *msg_array;
4415   vat_json_node_t *msg;
4416   vat_json_node_t *counter_array;
4417   vat_json_node_t *counter;
4418   interface_counter_t c;
4419   u64 packets;
4420   ip4_fib_counter_t *c4;
4421   ip6_fib_counter_t *c6;
4422   ip4_nbr_counter_t *n4;
4423   ip6_nbr_counter_t *n6;
4424   int i, j;
4425
4426   if (!vam->json_output)
4427     {
4428       clib_warning ("dump_stats_table supported only in JSON format");
4429       return -99;
4430     }
4431
4432   vat_json_init_object (&node);
4433
4434   /* interface counters */
4435   msg_array = vat_json_object_add (&node, "interface_counters");
4436   vat_json_init_array (msg_array);
4437   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4438     {
4439       msg = vat_json_array_add (msg_array);
4440       vat_json_init_object (msg);
4441       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4442                                        (u8 *) counter_type_to_str (i, 0));
4443       vat_json_object_add_int (msg, "is_combined", 0);
4444       counter_array = vat_json_object_add (msg, "data");
4445       vat_json_init_array (counter_array);
4446       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4447         {
4448           packets = vam->simple_interface_counters[i][j];
4449           vat_json_array_add_uint (counter_array, packets);
4450         }
4451     }
4452   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4453     {
4454       msg = vat_json_array_add (msg_array);
4455       vat_json_init_object (msg);
4456       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4457                                        (u8 *) counter_type_to_str (i, 1));
4458       vat_json_object_add_int (msg, "is_combined", 1);
4459       counter_array = vat_json_object_add (msg, "data");
4460       vat_json_init_array (counter_array);
4461       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4462         {
4463           c = vam->combined_interface_counters[i][j];
4464           counter = vat_json_array_add (counter_array);
4465           vat_json_init_object (counter);
4466           vat_json_object_add_uint (counter, "packets", c.packets);
4467           vat_json_object_add_uint (counter, "bytes", c.bytes);
4468         }
4469     }
4470
4471   /* ip4 fib counters */
4472   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4473   vat_json_init_array (msg_array);
4474   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4475     {
4476       msg = vat_json_array_add (msg_array);
4477       vat_json_init_object (msg);
4478       vat_json_object_add_uint (msg, "vrf_id",
4479                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4480       counter_array = vat_json_object_add (msg, "c");
4481       vat_json_init_array (counter_array);
4482       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4483         {
4484           counter = vat_json_array_add (counter_array);
4485           vat_json_init_object (counter);
4486           c4 = &vam->ip4_fib_counters[i][j];
4487           vat_json_object_add_ip4 (counter, "address", c4->address);
4488           vat_json_object_add_uint (counter, "address_length",
4489                                     c4->address_length);
4490           vat_json_object_add_uint (counter, "packets", c4->packets);
4491           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4492         }
4493     }
4494
4495   /* ip6 fib counters */
4496   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4497   vat_json_init_array (msg_array);
4498   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4499     {
4500       msg = vat_json_array_add (msg_array);
4501       vat_json_init_object (msg);
4502       vat_json_object_add_uint (msg, "vrf_id",
4503                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4504       counter_array = vat_json_object_add (msg, "c");
4505       vat_json_init_array (counter_array);
4506       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4507         {
4508           counter = vat_json_array_add (counter_array);
4509           vat_json_init_object (counter);
4510           c6 = &vam->ip6_fib_counters[i][j];
4511           vat_json_object_add_ip6 (counter, "address", c6->address);
4512           vat_json_object_add_uint (counter, "address_length",
4513                                     c6->address_length);
4514           vat_json_object_add_uint (counter, "packets", c6->packets);
4515           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4516         }
4517     }
4518
4519   /* ip4 nbr counters */
4520   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4521   vat_json_init_array (msg_array);
4522   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4523     {
4524       msg = vat_json_array_add (msg_array);
4525       vat_json_init_object (msg);
4526       vat_json_object_add_uint (msg, "sw_if_index", i);
4527       counter_array = vat_json_object_add (msg, "c");
4528       vat_json_init_array (counter_array);
4529       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4530         {
4531           counter = vat_json_array_add (counter_array);
4532           vat_json_init_object (counter);
4533           n4 = &vam->ip4_nbr_counters[i][j];
4534           vat_json_object_add_ip4 (counter, "address", n4->address);
4535           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4536           vat_json_object_add_uint (counter, "packets", n4->packets);
4537           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4538         }
4539     }
4540
4541   /* ip6 nbr counters */
4542   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4543   vat_json_init_array (msg_array);
4544   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4545     {
4546       msg = vat_json_array_add (msg_array);
4547       vat_json_init_object (msg);
4548       vat_json_object_add_uint (msg, "sw_if_index", i);
4549       counter_array = vat_json_object_add (msg, "c");
4550       vat_json_init_array (counter_array);
4551       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4552         {
4553           counter = vat_json_array_add (counter_array);
4554           vat_json_init_object (counter);
4555           n6 = &vam->ip6_nbr_counters[i][j];
4556           vat_json_object_add_ip6 (counter, "address", n6->address);
4557           vat_json_object_add_uint (counter, "packets", n6->packets);
4558           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4559         }
4560     }
4561
4562   vat_json_print (vam->ofp, &node);
4563   vat_json_free (&node);
4564
4565   return 0;
4566 }
4567
4568 int
4569 exec (vat_main_t * vam)
4570 {
4571   api_main_t *am = &api_main;
4572   vl_api_cli_request_t *mp;
4573   f64 timeout;
4574   void *oldheap;
4575   u8 *cmd = 0;
4576   unformat_input_t *i = vam->input;
4577
4578   if (vec_len (i->buffer) == 0)
4579     return -1;
4580
4581   if (vam->exec_mode == 0 && unformat (i, "mode"))
4582     {
4583       vam->exec_mode = 1;
4584       return 0;
4585     }
4586   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4587     {
4588       vam->exec_mode = 0;
4589       return 0;
4590     }
4591
4592
4593   M (CLI_REQUEST, cli_request);
4594
4595   /*
4596    * Copy cmd into shared memory.
4597    * In order for the CLI command to work, it
4598    * must be a vector ending in \n, not a C-string ending
4599    * in \n\0.
4600    */
4601   pthread_mutex_lock (&am->vlib_rp->mutex);
4602   oldheap = svm_push_data_heap (am->vlib_rp);
4603
4604   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4605   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4606
4607   svm_pop_heap (oldheap);
4608   pthread_mutex_unlock (&am->vlib_rp->mutex);
4609
4610   mp->cmd_in_shmem = (u64) cmd;
4611   S;
4612   timeout = vat_time_now (vam) + 10.0;
4613
4614   while (vat_time_now (vam) < timeout)
4615     {
4616       if (vam->result_ready == 1)
4617         {
4618           u8 *free_me;
4619           if (vam->shmem_result != NULL)
4620             print (vam->ofp, "%s", vam->shmem_result);
4621           pthread_mutex_lock (&am->vlib_rp->mutex);
4622           oldheap = svm_push_data_heap (am->vlib_rp);
4623
4624           free_me = (u8 *) vam->shmem_result;
4625           vec_free (free_me);
4626
4627           svm_pop_heap (oldheap);
4628           pthread_mutex_unlock (&am->vlib_rp->mutex);
4629           return 0;
4630         }
4631     }
4632   return -99;
4633 }
4634
4635 /*
4636  * Future replacement of exec() that passes CLI buffers directly in
4637  * the API messages instead of an additional shared memory area.
4638  */
4639 static int
4640 exec_inband (vat_main_t * vam)
4641 {
4642   vl_api_cli_inband_t *mp;
4643   f64 timeout;
4644   unformat_input_t *i = vam->input;
4645
4646   if (vec_len (i->buffer) == 0)
4647     return -1;
4648
4649   if (vam->exec_mode == 0 && unformat (i, "mode"))
4650     {
4651       vam->exec_mode = 1;
4652       return 0;
4653     }
4654   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4655     {
4656       vam->exec_mode = 0;
4657       return 0;
4658     }
4659
4660   /*
4661    * In order for the CLI command to work, it
4662    * must be a vector ending in \n, not a C-string ending
4663    * in \n\0.
4664    */
4665   u32 len = vec_len (vam->input->buffer);
4666   M2 (CLI_INBAND, cli_inband, len);
4667   clib_memcpy (mp->cmd, vam->input->buffer, len);
4668   mp->length = htonl (len);
4669
4670   S;
4671   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4672 }
4673
4674 static int
4675 api_create_loopback (vat_main_t * vam)
4676 {
4677   unformat_input_t *i = vam->input;
4678   vl_api_create_loopback_t *mp;
4679   f64 timeout;
4680   u8 mac_address[6];
4681   u8 mac_set = 0;
4682
4683   memset (mac_address, 0, sizeof (mac_address));
4684
4685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4686     {
4687       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4688         mac_set = 1;
4689       else
4690         break;
4691     }
4692
4693   /* Construct the API message */
4694   M (CREATE_LOOPBACK, create_loopback);
4695   if (mac_set)
4696     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4697
4698   S;
4699   W;
4700 }
4701
4702 static int
4703 api_delete_loopback (vat_main_t * vam)
4704 {
4705   unformat_input_t *i = vam->input;
4706   vl_api_delete_loopback_t *mp;
4707   f64 timeout;
4708   u32 sw_if_index = ~0;
4709
4710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4711     {
4712       if (unformat (i, "sw_if_index %d", &sw_if_index))
4713         ;
4714       else
4715         break;
4716     }
4717
4718   if (sw_if_index == ~0)
4719     {
4720       errmsg ("missing sw_if_index");
4721       return -99;
4722     }
4723
4724   /* Construct the API message */
4725   M (DELETE_LOOPBACK, delete_loopback);
4726   mp->sw_if_index = ntohl (sw_if_index);
4727
4728   S;
4729   W;
4730 }
4731
4732 static int
4733 api_want_stats (vat_main_t * vam)
4734 {
4735   unformat_input_t *i = vam->input;
4736   vl_api_want_stats_t *mp;
4737   f64 timeout;
4738   int enable = -1;
4739
4740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4741     {
4742       if (unformat (i, "enable"))
4743         enable = 1;
4744       else if (unformat (i, "disable"))
4745         enable = 0;
4746       else
4747         break;
4748     }
4749
4750   if (enable == -1)
4751     {
4752       errmsg ("missing enable|disable");
4753       return -99;
4754     }
4755
4756   M (WANT_STATS, want_stats);
4757   mp->enable_disable = enable;
4758
4759   S;
4760   W;
4761 }
4762
4763 static int
4764 api_want_interface_events (vat_main_t * vam)
4765 {
4766   unformat_input_t *i = vam->input;
4767   vl_api_want_interface_events_t *mp;
4768   f64 timeout;
4769   int enable = -1;
4770
4771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4772     {
4773       if (unformat (i, "enable"))
4774         enable = 1;
4775       else if (unformat (i, "disable"))
4776         enable = 0;
4777       else
4778         break;
4779     }
4780
4781   if (enable == -1)
4782     {
4783       errmsg ("missing enable|disable");
4784       return -99;
4785     }
4786
4787   M (WANT_INTERFACE_EVENTS, want_interface_events);
4788   mp->enable_disable = enable;
4789
4790   vam->interface_event_display = enable;
4791
4792   S;
4793   W;
4794 }
4795
4796
4797 /* Note: non-static, called once to set up the initial intfc table */
4798 int
4799 api_sw_interface_dump (vat_main_t * vam)
4800 {
4801   vl_api_sw_interface_dump_t *mp;
4802   f64 timeout;
4803   hash_pair_t *p;
4804   name_sort_t *nses = 0, *ns;
4805   sw_interface_subif_t *sub = NULL;
4806
4807   /* Toss the old name table */
4808   /* *INDENT-OFF* */
4809   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4810   ({
4811     vec_add2 (nses, ns, 1);
4812     ns->name = (u8 *)(p->key);
4813     ns->value = (u32) p->value[0];
4814   }));
4815   /* *INDENT-ON* */
4816
4817   hash_free (vam->sw_if_index_by_interface_name);
4818
4819   vec_foreach (ns, nses) vec_free (ns->name);
4820
4821   vec_free (nses);
4822
4823   vec_foreach (sub, vam->sw_if_subif_table)
4824   {
4825     vec_free (sub->interface_name);
4826   }
4827   vec_free (vam->sw_if_subif_table);
4828
4829   /* recreate the interface name hash table */
4830   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4831
4832   /* Get list of ethernets */
4833   M (SW_INTERFACE_DUMP, sw_interface_dump);
4834   mp->name_filter_valid = 1;
4835   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4836   S;
4837
4838   /* and local / loopback interfaces */
4839   M (SW_INTERFACE_DUMP, sw_interface_dump);
4840   mp->name_filter_valid = 1;
4841   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4842   S;
4843
4844   /* and packet-generator interfaces */
4845   M (SW_INTERFACE_DUMP, sw_interface_dump);
4846   mp->name_filter_valid = 1;
4847   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4848   S;
4849
4850   /* and vxlan-gpe tunnel interfaces */
4851   M (SW_INTERFACE_DUMP, sw_interface_dump);
4852   mp->name_filter_valid = 1;
4853   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4854            sizeof (mp->name_filter) - 1);
4855   S;
4856
4857   /* and vxlan tunnel interfaces */
4858   M (SW_INTERFACE_DUMP, sw_interface_dump);
4859   mp->name_filter_valid = 1;
4860   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4861   S;
4862
4863   /* and host (af_packet) interfaces */
4864   M (SW_INTERFACE_DUMP, sw_interface_dump);
4865   mp->name_filter_valid = 1;
4866   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4867   S;
4868
4869   /* and l2tpv3 tunnel interfaces */
4870   M (SW_INTERFACE_DUMP, sw_interface_dump);
4871   mp->name_filter_valid = 1;
4872   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4873            sizeof (mp->name_filter) - 1);
4874   S;
4875
4876   /* and GRE tunnel interfaces */
4877   M (SW_INTERFACE_DUMP, sw_interface_dump);
4878   mp->name_filter_valid = 1;
4879   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4880   S;
4881
4882   /* and LISP-GPE interfaces */
4883   M (SW_INTERFACE_DUMP, sw_interface_dump);
4884   mp->name_filter_valid = 1;
4885   strncpy ((char *) mp->name_filter, "lisp_gpe",
4886            sizeof (mp->name_filter) - 1);
4887   S;
4888
4889   /* and IPSEC tunnel interfaces */
4890   M (SW_INTERFACE_DUMP, sw_interface_dump);
4891   mp->name_filter_valid = 1;
4892   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4893   S;
4894
4895   /* Use a control ping for synchronization */
4896   {
4897     vl_api_control_ping_t *mp;
4898     M (CONTROL_PING, control_ping);
4899     S;
4900   }
4901   W;
4902 }
4903
4904 static int
4905 api_sw_interface_set_flags (vat_main_t * vam)
4906 {
4907   unformat_input_t *i = vam->input;
4908   vl_api_sw_interface_set_flags_t *mp;
4909   f64 timeout;
4910   u32 sw_if_index;
4911   u8 sw_if_index_set = 0;
4912   u8 admin_up = 0, link_up = 0;
4913
4914   /* Parse args required to build the message */
4915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4916     {
4917       if (unformat (i, "admin-up"))
4918         admin_up = 1;
4919       else if (unformat (i, "admin-down"))
4920         admin_up = 0;
4921       else if (unformat (i, "link-up"))
4922         link_up = 1;
4923       else if (unformat (i, "link-down"))
4924         link_up = 0;
4925       else
4926         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4927         sw_if_index_set = 1;
4928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4929         sw_if_index_set = 1;
4930       else
4931         break;
4932     }
4933
4934   if (sw_if_index_set == 0)
4935     {
4936       errmsg ("missing interface name or sw_if_index");
4937       return -99;
4938     }
4939
4940   /* Construct the API message */
4941   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4942   mp->sw_if_index = ntohl (sw_if_index);
4943   mp->admin_up_down = admin_up;
4944   mp->link_up_down = link_up;
4945
4946   /* send it... */
4947   S;
4948
4949   /* Wait for a reply, return the good/bad news... */
4950   W;
4951 }
4952
4953 static int
4954 api_sw_interface_clear_stats (vat_main_t * vam)
4955 {
4956   unformat_input_t *i = vam->input;
4957   vl_api_sw_interface_clear_stats_t *mp;
4958   f64 timeout;
4959   u32 sw_if_index;
4960   u8 sw_if_index_set = 0;
4961
4962   /* Parse args required to build the message */
4963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4964     {
4965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4966         sw_if_index_set = 1;
4967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4968         sw_if_index_set = 1;
4969       else
4970         break;
4971     }
4972
4973   /* Construct the API message */
4974   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4975
4976   if (sw_if_index_set == 1)
4977     mp->sw_if_index = ntohl (sw_if_index);
4978   else
4979     mp->sw_if_index = ~0;
4980
4981   /* send it... */
4982   S;
4983
4984   /* Wait for a reply, return the good/bad news... */
4985   W;
4986 }
4987
4988 #if DPDK >0
4989 static int
4990 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4991 {
4992   unformat_input_t *i = vam->input;
4993   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4994   f64 timeout;
4995   u32 sw_if_index;
4996   u8 sw_if_index_set = 0;
4997   u32 subport;
4998   u8 subport_set = 0;
4999   u32 pipe;
5000   u8 pipe_set = 0;
5001   u32 profile;
5002   u8 profile_set = 0;
5003
5004   /* Parse args required to build the message */
5005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5006     {
5007       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5008         sw_if_index_set = 1;
5009       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5010         sw_if_index_set = 1;
5011       else if (unformat (i, "subport %u", &subport))
5012         subport_set = 1;
5013       else
5014         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5015         sw_if_index_set = 1;
5016       else if (unformat (i, "pipe %u", &pipe))
5017         pipe_set = 1;
5018       else if (unformat (i, "profile %u", &profile))
5019         profile_set = 1;
5020       else
5021         break;
5022     }
5023
5024   if (sw_if_index_set == 0)
5025     {
5026       errmsg ("missing interface name or sw_if_index");
5027       return -99;
5028     }
5029
5030   if (subport_set == 0)
5031     {
5032       errmsg ("missing subport ");
5033       return -99;
5034     }
5035
5036   if (pipe_set == 0)
5037     {
5038       errmsg ("missing pipe");
5039       return -99;
5040     }
5041
5042   if (profile_set == 0)
5043     {
5044       errmsg ("missing profile");
5045       return -99;
5046     }
5047
5048   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
5049
5050   mp->sw_if_index = ntohl (sw_if_index);
5051   mp->subport = ntohl (subport);
5052   mp->pipe = ntohl (pipe);
5053   mp->profile = ntohl (profile);
5054
5055
5056   S;
5057   W;
5058   /* NOTREACHED */
5059   return 0;
5060 }
5061
5062 static int
5063 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
5064 {
5065   unformat_input_t *i = vam->input;
5066   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
5067   f64 timeout;
5068   u32 sw_if_index;
5069   u8 sw_if_index_set = 0;
5070   u32 subport;
5071   u8 subport_set = 0;
5072   u32 tb_rate = 1250000000;     /* 10GbE */
5073   u32 tb_size = 1000000;
5074   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
5075   u32 tc_period = 10;
5076
5077   /* Parse args required to build the message */
5078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5079     {
5080       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5081         sw_if_index_set = 1;
5082       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5083         sw_if_index_set = 1;
5084       else if (unformat (i, "subport %u", &subport))
5085         subport_set = 1;
5086       else
5087         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5088         sw_if_index_set = 1;
5089       else if (unformat (i, "rate %u", &tb_rate))
5090         {
5091           u32 tc_id;
5092
5093           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
5094                tc_id++)
5095             tc_rate[tc_id] = tb_rate;
5096         }
5097       else if (unformat (i, "bktsize %u", &tb_size))
5098         ;
5099       else if (unformat (i, "tc0 %u", &tc_rate[0]))
5100         ;
5101       else if (unformat (i, "tc1 %u", &tc_rate[1]))
5102         ;
5103       else if (unformat (i, "tc2 %u", &tc_rate[2]))
5104         ;
5105       else if (unformat (i, "tc3 %u", &tc_rate[3]))
5106         ;
5107       else if (unformat (i, "period %u", &tc_period))
5108         ;
5109       else
5110         break;
5111     }
5112
5113   if (sw_if_index_set == 0)
5114     {
5115       errmsg ("missing interface name or sw_if_index");
5116       return -99;
5117     }
5118
5119   if (subport_set == 0)
5120     {
5121       errmsg ("missing subport ");
5122       return -99;
5123     }
5124
5125   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
5126
5127   mp->sw_if_index = ntohl (sw_if_index);
5128   mp->subport = ntohl (subport);
5129   mp->tb_rate = ntohl (tb_rate);
5130   mp->tb_size = ntohl (tb_size);
5131   mp->tc_rate[0] = ntohl (tc_rate[0]);
5132   mp->tc_rate[1] = ntohl (tc_rate[1]);
5133   mp->tc_rate[2] = ntohl (tc_rate[2]);
5134   mp->tc_rate[3] = ntohl (tc_rate[3]);
5135   mp->tc_period = ntohl (tc_period);
5136
5137   S;
5138   W;
5139   /* NOTREACHED */
5140   return 0;
5141 }
5142
5143 static int
5144 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
5145 {
5146   unformat_input_t *i = vam->input;
5147   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
5148   f64 timeout;
5149   u32 sw_if_index;
5150   u8 sw_if_index_set = 0;
5151   u8 entry_set = 0;
5152   u8 tc_set = 0;
5153   u8 queue_set = 0;
5154   u32 entry, tc, queue;
5155
5156   /* Parse args required to build the message */
5157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5158     {
5159       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5160         sw_if_index_set = 1;
5161       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5162         sw_if_index_set = 1;
5163       else if (unformat (i, "entry %d", &entry))
5164         entry_set = 1;
5165       else if (unformat (i, "tc %d", &tc))
5166         tc_set = 1;
5167       else if (unformat (i, "queue %d", &queue))
5168         queue_set = 1;
5169       else
5170         break;
5171     }
5172
5173   if (sw_if_index_set == 0)
5174     {
5175       errmsg ("missing interface name or sw_if_index");
5176       return -99;
5177     }
5178
5179   if (entry_set == 0)
5180     {
5181       errmsg ("missing entry ");
5182       return -99;
5183     }
5184
5185   if (tc_set == 0)
5186     {
5187       errmsg ("missing traffic class ");
5188       return -99;
5189     }
5190
5191   if (queue_set == 0)
5192     {
5193       errmsg ("missing queue ");
5194       return -99;
5195     }
5196
5197   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
5198
5199   mp->sw_if_index = ntohl (sw_if_index);
5200   mp->entry = ntohl (entry);
5201   mp->tc = ntohl (tc);
5202   mp->queue = ntohl (queue);
5203
5204   S;
5205   W;
5206   /* NOTREACHED */
5207   return 0;
5208 }
5209 #endif
5210
5211 static int
5212 api_sw_interface_add_del_address (vat_main_t * vam)
5213 {
5214   unformat_input_t *i = vam->input;
5215   vl_api_sw_interface_add_del_address_t *mp;
5216   f64 timeout;
5217   u32 sw_if_index;
5218   u8 sw_if_index_set = 0;
5219   u8 is_add = 1, del_all = 0;
5220   u32 address_length = 0;
5221   u8 v4_address_set = 0;
5222   u8 v6_address_set = 0;
5223   ip4_address_t v4address;
5224   ip6_address_t v6address;
5225
5226   /* Parse args required to build the message */
5227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5228     {
5229       if (unformat (i, "del-all"))
5230         del_all = 1;
5231       else if (unformat (i, "del"))
5232         is_add = 0;
5233       else
5234         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5235         sw_if_index_set = 1;
5236       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5237         sw_if_index_set = 1;
5238       else if (unformat (i, "%U/%d",
5239                          unformat_ip4_address, &v4address, &address_length))
5240         v4_address_set = 1;
5241       else if (unformat (i, "%U/%d",
5242                          unformat_ip6_address, &v6address, &address_length))
5243         v6_address_set = 1;
5244       else
5245         break;
5246     }
5247
5248   if (sw_if_index_set == 0)
5249     {
5250       errmsg ("missing interface name or sw_if_index");
5251       return -99;
5252     }
5253   if (v4_address_set && v6_address_set)
5254     {
5255       errmsg ("both v4 and v6 addresses set");
5256       return -99;
5257     }
5258   if (!v4_address_set && !v6_address_set && !del_all)
5259     {
5260       errmsg ("no addresses set");
5261       return -99;
5262     }
5263
5264   /* Construct the API message */
5265   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
5266
5267   mp->sw_if_index = ntohl (sw_if_index);
5268   mp->is_add = is_add;
5269   mp->del_all = del_all;
5270   if (v6_address_set)
5271     {
5272       mp->is_ipv6 = 1;
5273       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5274     }
5275   else
5276     {
5277       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5278     }
5279   mp->address_length = address_length;
5280
5281   /* send it... */
5282   S;
5283
5284   /* Wait for a reply, return good/bad news  */
5285   W;
5286 }
5287
5288 static int
5289 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5290 {
5291   unformat_input_t *i = vam->input;
5292   vl_api_sw_interface_set_mpls_enable_t *mp;
5293   f64 timeout;
5294   u32 sw_if_index;
5295   u8 sw_if_index_set = 0;
5296   u8 enable = 1;
5297
5298   /* Parse args required to build the message */
5299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5300     {
5301       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5302         sw_if_index_set = 1;
5303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5304         sw_if_index_set = 1;
5305       else if (unformat (i, "disable"))
5306         enable = 0;
5307       else if (unformat (i, "dis"))
5308         enable = 0;
5309       else
5310         break;
5311     }
5312
5313   if (sw_if_index_set == 0)
5314     {
5315       errmsg ("missing interface name or sw_if_index");
5316       return -99;
5317     }
5318
5319   /* Construct the API message */
5320   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5321
5322   mp->sw_if_index = ntohl (sw_if_index);
5323   mp->enable = enable;
5324
5325   /* send it... */
5326   S;
5327
5328   /* Wait for a reply... */
5329   W;
5330 }
5331
5332 static int
5333 api_sw_interface_set_table (vat_main_t * vam)
5334 {
5335   unformat_input_t *i = vam->input;
5336   vl_api_sw_interface_set_table_t *mp;
5337   f64 timeout;
5338   u32 sw_if_index, vrf_id = 0;
5339   u8 sw_if_index_set = 0;
5340   u8 is_ipv6 = 0;
5341
5342   /* Parse args required to build the message */
5343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5344     {
5345       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5346         sw_if_index_set = 1;
5347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5348         sw_if_index_set = 1;
5349       else if (unformat (i, "vrf %d", &vrf_id))
5350         ;
5351       else if (unformat (i, "ipv6"))
5352         is_ipv6 = 1;
5353       else
5354         break;
5355     }
5356
5357   if (sw_if_index_set == 0)
5358     {
5359       errmsg ("missing interface name or sw_if_index");
5360       return -99;
5361     }
5362
5363   /* Construct the API message */
5364   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5365
5366   mp->sw_if_index = ntohl (sw_if_index);
5367   mp->is_ipv6 = is_ipv6;
5368   mp->vrf_id = ntohl (vrf_id);
5369
5370   /* send it... */
5371   S;
5372
5373   /* Wait for a reply... */
5374   W;
5375 }
5376
5377 static void vl_api_sw_interface_get_table_reply_t_handler
5378   (vl_api_sw_interface_get_table_reply_t * mp)
5379 {
5380   vat_main_t *vam = &vat_main;
5381
5382   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5383
5384   vam->retval = ntohl (mp->retval);
5385   vam->result_ready = 1;
5386
5387 }
5388
5389 static void vl_api_sw_interface_get_table_reply_t_handler_json
5390   (vl_api_sw_interface_get_table_reply_t * mp)
5391 {
5392   vat_main_t *vam = &vat_main;
5393   vat_json_node_t node;
5394
5395   vat_json_init_object (&node);
5396   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5397   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5398
5399   vat_json_print (vam->ofp, &node);
5400   vat_json_free (&node);
5401
5402   vam->retval = ntohl (mp->retval);
5403   vam->result_ready = 1;
5404 }
5405
5406 static int
5407 api_sw_interface_get_table (vat_main_t * vam)
5408 {
5409   unformat_input_t *i = vam->input;
5410   vl_api_sw_interface_get_table_t *mp;
5411   u32 sw_if_index;
5412   u8 sw_if_index_set = 0;
5413   u8 is_ipv6 = 0;
5414   f64 timeout;
5415
5416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5417     {
5418       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5419         sw_if_index_set = 1;
5420       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5421         sw_if_index_set = 1;
5422       else if (unformat (i, "ipv6"))
5423         is_ipv6 = 1;
5424       else
5425         break;
5426     }
5427
5428   if (sw_if_index_set == 0)
5429     {
5430       errmsg ("missing interface name or sw_if_index");
5431       return -99;
5432     }
5433
5434   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5435   mp->sw_if_index = htonl (sw_if_index);
5436   mp->is_ipv6 = is_ipv6;
5437
5438   S;
5439   W;
5440 }
5441
5442 static int
5443 api_sw_interface_set_vpath (vat_main_t * vam)
5444 {
5445   unformat_input_t *i = vam->input;
5446   vl_api_sw_interface_set_vpath_t *mp;
5447   f64 timeout;
5448   u32 sw_if_index = 0;
5449   u8 sw_if_index_set = 0;
5450   u8 is_enable = 0;
5451
5452   /* Parse args required to build the message */
5453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5454     {
5455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5456         sw_if_index_set = 1;
5457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5458         sw_if_index_set = 1;
5459       else if (unformat (i, "enable"))
5460         is_enable = 1;
5461       else if (unformat (i, "disable"))
5462         is_enable = 0;
5463       else
5464         break;
5465     }
5466
5467   if (sw_if_index_set == 0)
5468     {
5469       errmsg ("missing interface name or sw_if_index");
5470       return -99;
5471     }
5472
5473   /* Construct the API message */
5474   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5475
5476   mp->sw_if_index = ntohl (sw_if_index);
5477   mp->enable = is_enable;
5478
5479   /* send it... */
5480   S;
5481
5482   /* Wait for a reply... */
5483   W;
5484 }
5485
5486 static int
5487 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5488 {
5489   unformat_input_t *i = vam->input;
5490   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5491   f64 timeout;
5492   u32 sw_if_index = 0;
5493   u8 sw_if_index_set = 0;
5494   u8 is_enable = 1;
5495   u8 is_ipv6 = 0;
5496
5497   /* Parse args required to build the message */
5498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5499     {
5500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5501         sw_if_index_set = 1;
5502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5503         sw_if_index_set = 1;
5504       else if (unformat (i, "enable"))
5505         is_enable = 1;
5506       else if (unformat (i, "disable"))
5507         is_enable = 0;
5508       else if (unformat (i, "ip4"))
5509         is_ipv6 = 0;
5510       else if (unformat (i, "ip6"))
5511         is_ipv6 = 1;
5512       else
5513         break;
5514     }
5515
5516   if (sw_if_index_set == 0)
5517     {
5518       errmsg ("missing interface name or sw_if_index");
5519       return -99;
5520     }
5521
5522   /* Construct the API message */
5523   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5524
5525   mp->sw_if_index = ntohl (sw_if_index);
5526   mp->enable = is_enable;
5527   mp->is_ipv6 = is_ipv6;
5528
5529   /* send it... */
5530   S;
5531
5532   /* Wait for a reply... */
5533   W;
5534 }
5535
5536 static int
5537 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5538 {
5539   unformat_input_t *i = vam->input;
5540   vl_api_sw_interface_set_l2_xconnect_t *mp;
5541   f64 timeout;
5542   u32 rx_sw_if_index;
5543   u8 rx_sw_if_index_set = 0;
5544   u32 tx_sw_if_index;
5545   u8 tx_sw_if_index_set = 0;
5546   u8 enable = 1;
5547
5548   /* Parse args required to build the message */
5549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5550     {
5551       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5552         rx_sw_if_index_set = 1;
5553       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5554         tx_sw_if_index_set = 1;
5555       else if (unformat (i, "rx"))
5556         {
5557           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5558             {
5559               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5560                             &rx_sw_if_index))
5561                 rx_sw_if_index_set = 1;
5562             }
5563           else
5564             break;
5565         }
5566       else if (unformat (i, "tx"))
5567         {
5568           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5569             {
5570               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5571                             &tx_sw_if_index))
5572                 tx_sw_if_index_set = 1;
5573             }
5574           else
5575             break;
5576         }
5577       else if (unformat (i, "enable"))
5578         enable = 1;
5579       else if (unformat (i, "disable"))
5580         enable = 0;
5581       else
5582         break;
5583     }
5584
5585   if (rx_sw_if_index_set == 0)
5586     {
5587       errmsg ("missing rx interface name or rx_sw_if_index");
5588       return -99;
5589     }
5590
5591   if (enable && (tx_sw_if_index_set == 0))
5592     {
5593       errmsg ("missing tx interface name or tx_sw_if_index");
5594       return -99;
5595     }
5596
5597   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5598
5599   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5600   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5601   mp->enable = enable;
5602
5603   S;
5604   W;
5605   /* NOTREACHED */
5606   return 0;
5607 }
5608
5609 static int
5610 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5611 {
5612   unformat_input_t *i = vam->input;
5613   vl_api_sw_interface_set_l2_bridge_t *mp;
5614   f64 timeout;
5615   u32 rx_sw_if_index;
5616   u8 rx_sw_if_index_set = 0;
5617   u32 bd_id;
5618   u8 bd_id_set = 0;
5619   u8 bvi = 0;
5620   u32 shg = 0;
5621   u8 enable = 1;
5622
5623   /* Parse args required to build the message */
5624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5625     {
5626       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5627         rx_sw_if_index_set = 1;
5628       else if (unformat (i, "bd_id %d", &bd_id))
5629         bd_id_set = 1;
5630       else
5631         if (unformat
5632             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5633         rx_sw_if_index_set = 1;
5634       else if (unformat (i, "shg %d", &shg))
5635         ;
5636       else if (unformat (i, "bvi"))
5637         bvi = 1;
5638       else if (unformat (i, "enable"))
5639         enable = 1;
5640       else if (unformat (i, "disable"))
5641         enable = 0;
5642       else
5643         break;
5644     }
5645
5646   if (rx_sw_if_index_set == 0)
5647     {
5648       errmsg ("missing rx interface name or sw_if_index");
5649       return -99;
5650     }
5651
5652   if (enable && (bd_id_set == 0))
5653     {
5654       errmsg ("missing bridge domain");
5655       return -99;
5656     }
5657
5658   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5659
5660   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5661   mp->bd_id = ntohl (bd_id);
5662   mp->shg = (u8) shg;
5663   mp->bvi = bvi;
5664   mp->enable = enable;
5665
5666   S;
5667   W;
5668   /* NOTREACHED */
5669   return 0;
5670 }
5671
5672 static int
5673 api_bridge_domain_dump (vat_main_t * vam)
5674 {
5675   unformat_input_t *i = vam->input;
5676   vl_api_bridge_domain_dump_t *mp;
5677   f64 timeout;
5678   u32 bd_id = ~0;
5679
5680   /* Parse args required to build the message */
5681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5682     {
5683       if (unformat (i, "bd_id %d", &bd_id))
5684         ;
5685       else
5686         break;
5687     }
5688
5689   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5690   mp->bd_id = ntohl (bd_id);
5691   S;
5692
5693   /* Use a control ping for synchronization */
5694   {
5695     vl_api_control_ping_t *mp;
5696     M (CONTROL_PING, control_ping);
5697     S;
5698   }
5699
5700   W;
5701   /* NOTREACHED */
5702   return 0;
5703 }
5704
5705 static int
5706 api_bridge_domain_add_del (vat_main_t * vam)
5707 {
5708   unformat_input_t *i = vam->input;
5709   vl_api_bridge_domain_add_del_t *mp;
5710   f64 timeout;
5711   u32 bd_id = ~0;
5712   u8 is_add = 1;
5713   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5714   u32 mac_age = 0;
5715
5716   /* Parse args required to build the message */
5717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5718     {
5719       if (unformat (i, "bd_id %d", &bd_id))
5720         ;
5721       else if (unformat (i, "flood %d", &flood))
5722         ;
5723       else if (unformat (i, "uu-flood %d", &uu_flood))
5724         ;
5725       else if (unformat (i, "forward %d", &forward))
5726         ;
5727       else if (unformat (i, "learn %d", &learn))
5728         ;
5729       else if (unformat (i, "arp-term %d", &arp_term))
5730         ;
5731       else if (unformat (i, "mac-age %d", &mac_age))
5732         ;
5733       else if (unformat (i, "del"))
5734         {
5735           is_add = 0;
5736           flood = uu_flood = forward = learn = 0;
5737         }
5738       else
5739         break;
5740     }
5741
5742   if (bd_id == ~0)
5743     {
5744       errmsg ("missing bridge domain");
5745       return -99;
5746     }
5747
5748   if (mac_age > 255)
5749     {
5750       errmsg ("mac age must be less than 256 ");
5751       return -99;
5752     }
5753
5754   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5755
5756   mp->bd_id = ntohl (bd_id);
5757   mp->flood = flood;
5758   mp->uu_flood = uu_flood;
5759   mp->forward = forward;
5760   mp->learn = learn;
5761   mp->arp_term = arp_term;
5762   mp->is_add = is_add;
5763   mp->mac_age = (u8) mac_age;
5764
5765   S;
5766   W;
5767   /* NOTREACHED */
5768   return 0;
5769 }
5770
5771 static int
5772 api_l2fib_add_del (vat_main_t * vam)
5773 {
5774   unformat_input_t *i = vam->input;
5775   vl_api_l2fib_add_del_t *mp;
5776   f64 timeout;
5777   u64 mac = 0;
5778   u8 mac_set = 0;
5779   u32 bd_id;
5780   u8 bd_id_set = 0;
5781   u32 sw_if_index = ~0;
5782   u8 sw_if_index_set = 0;
5783   u8 is_add = 1;
5784   u8 static_mac = 0;
5785   u8 filter_mac = 0;
5786   u8 bvi_mac = 0;
5787   int count = 1;
5788   f64 before = 0;
5789   int j;
5790
5791   /* Parse args required to build the message */
5792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5793     {
5794       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5795         mac_set = 1;
5796       else if (unformat (i, "bd_id %d", &bd_id))
5797         bd_id_set = 1;
5798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5799         sw_if_index_set = 1;
5800       else if (unformat (i, "sw_if"))
5801         {
5802           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5803             {
5804               if (unformat
5805                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5806                 sw_if_index_set = 1;
5807             }
5808           else
5809             break;
5810         }
5811       else if (unformat (i, "static"))
5812         static_mac = 1;
5813       else if (unformat (i, "filter"))
5814         {
5815           filter_mac = 1;
5816           static_mac = 1;
5817         }
5818       else if (unformat (i, "bvi"))
5819         {
5820           bvi_mac = 1;
5821           static_mac = 1;
5822         }
5823       else if (unformat (i, "del"))
5824         is_add = 0;
5825       else if (unformat (i, "count %d", &count))
5826         ;
5827       else
5828         break;
5829     }
5830
5831   if (mac_set == 0)
5832     {
5833       errmsg ("missing mac address");
5834       return -99;
5835     }
5836
5837   if (bd_id_set == 0)
5838     {
5839       errmsg ("missing bridge domain");
5840       return -99;
5841     }
5842
5843   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5844     {
5845       errmsg ("missing interface name or sw_if_index");
5846       return -99;
5847     }
5848
5849   if (count > 1)
5850     {
5851       /* Turn on async mode */
5852       vam->async_mode = 1;
5853       vam->async_errors = 0;
5854       before = vat_time_now (vam);
5855     }
5856
5857   for (j = 0; j < count; j++)
5858     {
5859       M (L2FIB_ADD_DEL, l2fib_add_del);
5860
5861       mp->mac = mac;
5862       mp->bd_id = ntohl (bd_id);
5863       mp->is_add = is_add;
5864
5865       if (is_add)
5866         {
5867           mp->sw_if_index = ntohl (sw_if_index);
5868           mp->static_mac = static_mac;
5869           mp->filter_mac = filter_mac;
5870           mp->bvi_mac = bvi_mac;
5871         }
5872       increment_mac_address (&mac);
5873       /* send it... */
5874       S;
5875     }
5876
5877   if (count > 1)
5878     {
5879       vl_api_control_ping_t *mp;
5880       f64 after;
5881
5882       /* Shut off async mode */
5883       vam->async_mode = 0;
5884
5885       M (CONTROL_PING, control_ping);
5886       S;
5887
5888       timeout = vat_time_now (vam) + 1.0;
5889       while (vat_time_now (vam) < timeout)
5890         if (vam->result_ready == 1)
5891           goto out;
5892       vam->retval = -99;
5893
5894     out:
5895       if (vam->retval == -99)
5896         errmsg ("timeout");
5897
5898       if (vam->async_errors > 0)
5899         {
5900           errmsg ("%d asynchronous errors", vam->async_errors);
5901           vam->retval = -98;
5902         }
5903       vam->async_errors = 0;
5904       after = vat_time_now (vam);
5905
5906       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5907              count, after - before, count / (after - before));
5908     }
5909   else
5910     {
5911       /* Wait for a reply... */
5912       W;
5913     }
5914   /* Return the good/bad news */
5915   return (vam->retval);
5916 }
5917
5918 static int
5919 api_l2_flags (vat_main_t * vam)
5920 {
5921   unformat_input_t *i = vam->input;
5922   vl_api_l2_flags_t *mp;
5923   f64 timeout;
5924   u32 sw_if_index;
5925   u32 feature_bitmap = 0;
5926   u8 sw_if_index_set = 0;
5927
5928   /* Parse args required to build the message */
5929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5930     {
5931       if (unformat (i, "sw_if_index %d", &sw_if_index))
5932         sw_if_index_set = 1;
5933       else if (unformat (i, "sw_if"))
5934         {
5935           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5936             {
5937               if (unformat
5938                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5939                 sw_if_index_set = 1;
5940             }
5941           else
5942             break;
5943         }
5944       else if (unformat (i, "learn"))
5945         feature_bitmap |= L2INPUT_FEAT_LEARN;
5946       else if (unformat (i, "forward"))
5947         feature_bitmap |= L2INPUT_FEAT_FWD;
5948       else if (unformat (i, "flood"))
5949         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5950       else if (unformat (i, "uu-flood"))
5951         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5952       else
5953         break;
5954     }
5955
5956   if (sw_if_index_set == 0)
5957     {
5958       errmsg ("missing interface name or sw_if_index");
5959       return -99;
5960     }
5961
5962   M (L2_FLAGS, l2_flags);
5963
5964   mp->sw_if_index = ntohl (sw_if_index);
5965   mp->feature_bitmap = ntohl (feature_bitmap);
5966
5967   S;
5968   W;
5969   /* NOTREACHED */
5970   return 0;
5971 }
5972
5973 static int
5974 api_bridge_flags (vat_main_t * vam)
5975 {
5976   unformat_input_t *i = vam->input;
5977   vl_api_bridge_flags_t *mp;
5978   f64 timeout;
5979   u32 bd_id;
5980   u8 bd_id_set = 0;
5981   u8 is_set = 1;
5982   u32 flags = 0;
5983
5984   /* Parse args required to build the message */
5985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5986     {
5987       if (unformat (i, "bd_id %d", &bd_id))
5988         bd_id_set = 1;
5989       else if (unformat (i, "learn"))
5990         flags |= L2_LEARN;
5991       else if (unformat (i, "forward"))
5992         flags |= L2_FWD;
5993       else if (unformat (i, "flood"))
5994         flags |= L2_FLOOD;
5995       else if (unformat (i, "uu-flood"))
5996         flags |= L2_UU_FLOOD;
5997       else if (unformat (i, "arp-term"))
5998         flags |= L2_ARP_TERM;
5999       else if (unformat (i, "off"))
6000         is_set = 0;
6001       else if (unformat (i, "disable"))
6002         is_set = 0;
6003       else
6004         break;
6005     }
6006
6007   if (bd_id_set == 0)
6008     {
6009       errmsg ("missing bridge domain");
6010       return -99;
6011     }
6012
6013   M (BRIDGE_FLAGS, bridge_flags);
6014
6015   mp->bd_id = ntohl (bd_id);
6016   mp->feature_bitmap = ntohl (flags);
6017   mp->is_set = is_set;
6018
6019   S;
6020   W;
6021   /* NOTREACHED */
6022   return 0;
6023 }
6024
6025 static int
6026 api_bd_ip_mac_add_del (vat_main_t * vam)
6027 {
6028   unformat_input_t *i = vam->input;
6029   vl_api_bd_ip_mac_add_del_t *mp;
6030   f64 timeout;
6031   u32 bd_id;
6032   u8 is_ipv6 = 0;
6033   u8 is_add = 1;
6034   u8 bd_id_set = 0;
6035   u8 ip_set = 0;
6036   u8 mac_set = 0;
6037   ip4_address_t v4addr;
6038   ip6_address_t v6addr;
6039   u8 macaddr[6];
6040
6041
6042   /* Parse args required to build the message */
6043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6044     {
6045       if (unformat (i, "bd_id %d", &bd_id))
6046         {
6047           bd_id_set++;
6048         }
6049       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6050         {
6051           ip_set++;
6052         }
6053       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6054         {
6055           ip_set++;
6056           is_ipv6++;
6057         }
6058       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6059         {
6060           mac_set++;
6061         }
6062       else if (unformat (i, "del"))
6063         is_add = 0;
6064       else
6065         break;
6066     }
6067
6068   if (bd_id_set == 0)
6069     {
6070       errmsg ("missing bridge domain");
6071       return -99;
6072     }
6073   else if (ip_set == 0)
6074     {
6075       errmsg ("missing IP address");
6076       return -99;
6077     }
6078   else if (mac_set == 0)
6079     {
6080       errmsg ("missing MAC address");
6081       return -99;
6082     }
6083
6084   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
6085
6086   mp->bd_id = ntohl (bd_id);
6087   mp->is_ipv6 = is_ipv6;
6088   mp->is_add = is_add;
6089   if (is_ipv6)
6090     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6091   else
6092     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6093   clib_memcpy (mp->mac_address, macaddr, 6);
6094   S;
6095   W;
6096   /* NOTREACHED */
6097   return 0;
6098 }
6099
6100 static int
6101 api_tap_connect (vat_main_t * vam)
6102 {
6103   unformat_input_t *i = vam->input;
6104   vl_api_tap_connect_t *mp;
6105   f64 timeout;
6106   u8 mac_address[6];
6107   u8 random_mac = 1;
6108   u8 name_set = 0;
6109   u8 *tap_name;
6110   u8 *tag = 0;
6111   ip4_address_t ip4_address;
6112   u32 ip4_mask_width;
6113   int ip4_address_set = 0;
6114   ip6_address_t ip6_address;
6115   u32 ip6_mask_width;
6116   int ip6_address_set = 0;
6117
6118   memset (mac_address, 0, sizeof (mac_address));
6119
6120   /* Parse args required to build the message */
6121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6122     {
6123       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6124         {
6125           random_mac = 0;
6126         }
6127       else if (unformat (i, "random-mac"))
6128         random_mac = 1;
6129       else if (unformat (i, "tapname %s", &tap_name))
6130         name_set = 1;
6131       else if (unformat (i, "tag %s", &tag))
6132         ;
6133       else if (unformat (i, "address %U/%d",
6134                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6135         ip4_address_set = 1;
6136       else if (unformat (i, "address %U/%d",
6137                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6138         ip6_address_set = 1;
6139       else
6140         break;
6141     }
6142
6143   if (name_set == 0)
6144     {
6145       errmsg ("missing tap name");
6146       return -99;
6147     }
6148   if (vec_len (tap_name) > 63)
6149     {
6150       errmsg ("tap name too long");
6151       return -99;
6152     }
6153   vec_add1 (tap_name, 0);
6154
6155   if (vec_len (tag) > 63)
6156     {
6157       errmsg ("tag too long");
6158       return -99;
6159     }
6160
6161   /* Construct the API message */
6162   M (TAP_CONNECT, tap_connect);
6163
6164   mp->use_random_mac = random_mac;
6165   clib_memcpy (mp->mac_address, mac_address, 6);
6166   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6167   if (tag)
6168     clib_memcpy (mp->tag, tag, vec_len (tag));
6169
6170   if (ip4_address_set)
6171     {
6172       mp->ip4_address_set = 1;
6173       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6174       mp->ip4_mask_width = ip4_mask_width;
6175     }
6176   if (ip6_address_set)
6177     {
6178       mp->ip6_address_set = 1;
6179       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6180       mp->ip6_mask_width = ip6_mask_width;
6181     }
6182
6183   vec_free (tap_name);
6184   vec_free (tag);
6185
6186   /* send it... */
6187   S;
6188
6189   /* Wait for a reply... */
6190   W;
6191 }
6192
6193 static int
6194 api_tap_modify (vat_main_t * vam)
6195 {
6196   unformat_input_t *i = vam->input;
6197   vl_api_tap_modify_t *mp;
6198   f64 timeout;
6199   u8 mac_address[6];
6200   u8 random_mac = 1;
6201   u8 name_set = 0;
6202   u8 *tap_name;
6203   u32 sw_if_index = ~0;
6204   u8 sw_if_index_set = 0;
6205
6206   memset (mac_address, 0, sizeof (mac_address));
6207
6208   /* Parse args required to build the message */
6209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6210     {
6211       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6212         sw_if_index_set = 1;
6213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6214         sw_if_index_set = 1;
6215       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6216         {
6217           random_mac = 0;
6218         }
6219       else if (unformat (i, "random-mac"))
6220         random_mac = 1;
6221       else if (unformat (i, "tapname %s", &tap_name))
6222         name_set = 1;
6223       else
6224         break;
6225     }
6226
6227   if (sw_if_index_set == 0)
6228     {
6229       errmsg ("missing vpp interface name");
6230       return -99;
6231     }
6232   if (name_set == 0)
6233     {
6234       errmsg ("missing tap name");
6235       return -99;
6236     }
6237   if (vec_len (tap_name) > 63)
6238     {
6239       errmsg ("tap name too long");
6240     }
6241   vec_add1 (tap_name, 0);
6242
6243   /* Construct the API message */
6244   M (TAP_MODIFY, tap_modify);
6245
6246   mp->use_random_mac = random_mac;
6247   mp->sw_if_index = ntohl (sw_if_index);
6248   clib_memcpy (mp->mac_address, mac_address, 6);
6249   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6250   vec_free (tap_name);
6251
6252   /* send it... */
6253   S;
6254
6255   /* Wait for a reply... */
6256   W;
6257 }
6258
6259 static int
6260 api_tap_delete (vat_main_t * vam)
6261 {
6262   unformat_input_t *i = vam->input;
6263   vl_api_tap_delete_t *mp;
6264   f64 timeout;
6265   u32 sw_if_index = ~0;
6266   u8 sw_if_index_set = 0;
6267
6268   /* Parse args required to build the message */
6269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6270     {
6271       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6272         sw_if_index_set = 1;
6273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6274         sw_if_index_set = 1;
6275       else
6276         break;
6277     }
6278
6279   if (sw_if_index_set == 0)
6280     {
6281       errmsg ("missing vpp interface name");
6282       return -99;
6283     }
6284
6285   /* Construct the API message */
6286   M (TAP_DELETE, tap_delete);
6287
6288   mp->sw_if_index = ntohl (sw_if_index);
6289
6290   /* send it... */
6291   S;
6292
6293   /* Wait for a reply... */
6294   W;
6295 }
6296
6297 static int
6298 api_ip_add_del_route (vat_main_t * vam)
6299 {
6300   unformat_input_t *i = vam->input;
6301   vl_api_ip_add_del_route_t *mp;
6302   f64 timeout;
6303   u32 sw_if_index = ~0, vrf_id = 0;
6304   u8 is_ipv6 = 0;
6305   u8 is_local = 0, is_drop = 0;
6306   u8 is_unreach = 0, is_prohibit = 0;
6307   u8 create_vrf_if_needed = 0;
6308   u8 is_add = 1;
6309   u32 next_hop_weight = 1;
6310   u8 not_last = 0;
6311   u8 is_multipath = 0;
6312   u8 address_set = 0;
6313   u8 address_length_set = 0;
6314   u32 next_hop_table_id = 0;
6315   u32 resolve_attempts = 0;
6316   u32 dst_address_length = 0;
6317   u8 next_hop_set = 0;
6318   ip4_address_t v4_dst_address, v4_next_hop_address;
6319   ip6_address_t v6_dst_address, v6_next_hop_address;
6320   int count = 1;
6321   int j;
6322   f64 before = 0;
6323   u32 random_add_del = 0;
6324   u32 *random_vector = 0;
6325   uword *random_hash;
6326   u32 random_seed = 0xdeaddabe;
6327   u32 classify_table_index = ~0;
6328   u8 is_classify = 0;
6329   u8 resolve_host = 0, resolve_attached = 0;
6330   mpls_label_t *next_hop_out_label_stack = NULL;
6331   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6332   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6333
6334   /* Parse args required to build the message */
6335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6336     {
6337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6338         ;
6339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6340         ;
6341       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6342         {
6343           address_set = 1;
6344           is_ipv6 = 0;
6345         }
6346       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6347         {
6348           address_set = 1;
6349           is_ipv6 = 1;
6350         }
6351       else if (unformat (i, "/%d", &dst_address_length))
6352         {
6353           address_length_set = 1;
6354         }
6355
6356       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6357                                          &v4_next_hop_address))
6358         {
6359           next_hop_set = 1;
6360         }
6361       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6362                                          &v6_next_hop_address))
6363         {
6364           next_hop_set = 1;
6365         }
6366       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6367         ;
6368       else if (unformat (i, "weight %d", &next_hop_weight))
6369         ;
6370       else if (unformat (i, "drop"))
6371         {
6372           is_drop = 1;
6373         }
6374       else if (unformat (i, "null-send-unreach"))
6375         {
6376           is_unreach = 1;
6377         }
6378       else if (unformat (i, "null-send-prohibit"))
6379         {
6380           is_prohibit = 1;
6381         }
6382       else if (unformat (i, "local"))
6383         {
6384           is_local = 1;
6385         }
6386       else if (unformat (i, "classify %d", &classify_table_index))
6387         {
6388           is_classify = 1;
6389         }
6390       else if (unformat (i, "del"))
6391         is_add = 0;
6392       else if (unformat (i, "add"))
6393         is_add = 1;
6394       else if (unformat (i, "not-last"))
6395         not_last = 1;
6396       else if (unformat (i, "resolve-via-host"))
6397         resolve_host = 1;
6398       else if (unformat (i, "resolve-via-attached"))
6399         resolve_attached = 1;
6400       else if (unformat (i, "multipath"))
6401         is_multipath = 1;
6402       else if (unformat (i, "vrf %d", &vrf_id))
6403         ;
6404       else if (unformat (i, "create-vrf"))
6405         create_vrf_if_needed = 1;
6406       else if (unformat (i, "count %d", &count))
6407         ;
6408       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6409         ;
6410       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6411         ;
6412       else if (unformat (i, "out-label %d", &next_hop_out_label))
6413         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6414       else if (unformat (i, "via-label %d", &next_hop_via_label))
6415         ;
6416       else if (unformat (i, "random"))
6417         random_add_del = 1;
6418       else if (unformat (i, "seed %d", &random_seed))
6419         ;
6420       else
6421         {
6422           clib_warning ("parse error '%U'", format_unformat_error, i);
6423           return -99;
6424         }
6425     }
6426
6427   if (!next_hop_set && !is_drop && !is_local &&
6428       !is_classify && !is_unreach && !is_prohibit &&
6429       MPLS_LABEL_INVALID == next_hop_via_label)
6430     {
6431       errmsg
6432         ("next hop / local / drop / unreach / prohibit / classify not set");
6433       return -99;
6434     }
6435
6436   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6437     {
6438       errmsg ("next hop and next-hop via label set");
6439       return -99;
6440     }
6441   if (address_set == 0)
6442     {
6443       errmsg ("missing addresses");
6444       return -99;
6445     }
6446
6447   if (address_length_set == 0)
6448     {
6449       errmsg ("missing address length");
6450       return -99;
6451     }
6452
6453   /* Generate a pile of unique, random routes */
6454   if (random_add_del)
6455     {
6456       u32 this_random_address;
6457       random_hash = hash_create (count, sizeof (uword));
6458
6459       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6460       for (j = 0; j <= count; j++)
6461         {
6462           do
6463             {
6464               this_random_address = random_u32 (&random_seed);
6465               this_random_address =
6466                 clib_host_to_net_u32 (this_random_address);
6467             }
6468           while (hash_get (random_hash, this_random_address));
6469           vec_add1 (random_vector, this_random_address);
6470           hash_set (random_hash, this_random_address, 1);
6471         }
6472       hash_free (random_hash);
6473       v4_dst_address.as_u32 = random_vector[0];
6474     }
6475
6476   if (count > 1)
6477     {
6478       /* Turn on async mode */
6479       vam->async_mode = 1;
6480       vam->async_errors = 0;
6481       before = vat_time_now (vam);
6482     }
6483
6484   for (j = 0; j < count; j++)
6485     {
6486       /* Construct the API message */
6487       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6488           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6489
6490       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6491       mp->table_id = ntohl (vrf_id);
6492       mp->create_vrf_if_needed = create_vrf_if_needed;
6493
6494       mp->is_add = is_add;
6495       mp->is_drop = is_drop;
6496       mp->is_unreach = is_unreach;
6497       mp->is_prohibit = is_prohibit;
6498       mp->is_ipv6 = is_ipv6;
6499       mp->is_local = is_local;
6500       mp->is_classify = is_classify;
6501       mp->is_multipath = is_multipath;
6502       mp->is_resolve_host = resolve_host;
6503       mp->is_resolve_attached = resolve_attached;
6504       mp->not_last = not_last;
6505       mp->next_hop_weight = next_hop_weight;
6506       mp->dst_address_length = dst_address_length;
6507       mp->next_hop_table_id = ntohl (next_hop_table_id);
6508       mp->classify_table_index = ntohl (classify_table_index);
6509       mp->next_hop_via_label = ntohl (next_hop_via_label);
6510       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6511       if (0 != mp->next_hop_n_out_labels)
6512         {
6513           memcpy (mp->next_hop_out_label_stack,
6514                   next_hop_out_label_stack,
6515                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6516           vec_free (next_hop_out_label_stack);
6517         }
6518
6519       if (is_ipv6)
6520         {
6521           clib_memcpy (mp->dst_address, &v6_dst_address,
6522                        sizeof (v6_dst_address));
6523           if (next_hop_set)
6524             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6525                          sizeof (v6_next_hop_address));
6526           increment_v6_address (&v6_dst_address);
6527         }
6528       else
6529         {
6530           clib_memcpy (mp->dst_address, &v4_dst_address,
6531                        sizeof (v4_dst_address));
6532           if (next_hop_set)
6533             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6534                          sizeof (v4_next_hop_address));
6535           if (random_add_del)
6536             v4_dst_address.as_u32 = random_vector[j + 1];
6537           else
6538             increment_v4_address (&v4_dst_address);
6539         }
6540       /* send it... */
6541       S;
6542       /* If we receive SIGTERM, stop now... */
6543       if (vam->do_exit)
6544         break;
6545     }
6546
6547   /* When testing multiple add/del ops, use a control-ping to sync */
6548   if (count > 1)
6549     {
6550       vl_api_control_ping_t *mp;
6551       f64 after;
6552
6553       /* Shut off async mode */
6554       vam->async_mode = 0;
6555
6556       M (CONTROL_PING, control_ping);
6557       S;
6558
6559       timeout = vat_time_now (vam) + 1.0;
6560       while (vat_time_now (vam) < timeout)
6561         if (vam->result_ready == 1)
6562           goto out;
6563       vam->retval = -99;
6564
6565     out:
6566       if (vam->retval == -99)
6567         errmsg ("timeout");
6568
6569       if (vam->async_errors > 0)
6570         {
6571           errmsg ("%d asynchronous errors", vam->async_errors);
6572           vam->retval = -98;
6573         }
6574       vam->async_errors = 0;
6575       after = vat_time_now (vam);
6576
6577       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6578       if (j > 0)
6579         count = j;
6580
6581       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6582              count, after - before, count / (after - before));
6583     }
6584   else
6585     {
6586       /* Wait for a reply... */
6587       W;
6588     }
6589
6590   /* Return the good/bad news */
6591   return (vam->retval);
6592 }
6593
6594 static int
6595 api_ip_mroute_add_del (vat_main_t * vam)
6596 {
6597   unformat_input_t *i = vam->input;
6598   vl_api_ip_mroute_add_del_t *mp;
6599   f64 timeout;
6600   u32 sw_if_index = ~0, vrf_id = 0;
6601   u8 is_ipv6 = 0;
6602   u8 is_local = 0;
6603   u8 create_vrf_if_needed = 0;
6604   u8 is_add = 1;
6605   u8 address_set = 0;
6606   u32 grp_address_length = 0;
6607   ip4_address_t v4_grp_address, v4_src_address;
6608   ip6_address_t v6_grp_address, v6_src_address;
6609   mfib_itf_flags_t iflags = 0;
6610   mfib_entry_flags_t eflags = 0;
6611
6612   /* Parse args required to build the message */
6613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6614     {
6615       if (unformat (i, "sw_if_index %d", &sw_if_index))
6616         ;
6617       else if (unformat (i, "%U %U",
6618                          unformat_ip4_address, &v4_src_address,
6619                          unformat_ip4_address, &v4_grp_address))
6620         {
6621           grp_address_length = 64;
6622           address_set = 1;
6623           is_ipv6 = 0;
6624         }
6625       else if (unformat (i, "%U %U",
6626                          unformat_ip6_address, &v6_src_address,
6627                          unformat_ip6_address, &v6_grp_address))
6628         {
6629           grp_address_length = 256;
6630           address_set = 1;
6631           is_ipv6 = 1;
6632         }
6633       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6634         {
6635           memset (&v4_src_address, 0, sizeof (v4_src_address));
6636           grp_address_length = 32;
6637           address_set = 1;
6638           is_ipv6 = 0;
6639         }
6640       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6641         {
6642           memset (&v6_src_address, 0, sizeof (v6_src_address));
6643           grp_address_length = 128;
6644           address_set = 1;
6645           is_ipv6 = 1;
6646         }
6647       else if (unformat (i, "/%d", &grp_address_length))
6648         ;
6649       else if (unformat (i, "local"))
6650         {
6651           is_local = 1;
6652         }
6653       else if (unformat (i, "del"))
6654         is_add = 0;
6655       else if (unformat (i, "add"))
6656         is_add = 1;
6657       else if (unformat (i, "vrf %d", &vrf_id))
6658         ;
6659       else if (unformat (i, "create-vrf"))
6660         create_vrf_if_needed = 1;
6661       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6662         ;
6663       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6664         ;
6665       else
6666         {
6667           clib_warning ("parse error '%U'", format_unformat_error, i);
6668           return -99;
6669         }
6670     }
6671
6672   if (address_set == 0)
6673     {
6674       errmsg ("missing addresses\n");
6675       return -99;
6676     }
6677
6678   /* Construct the API message */
6679   M (IP_MROUTE_ADD_DEL, ip_mroute_add_del);
6680
6681   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6682   mp->table_id = ntohl (vrf_id);
6683   mp->create_vrf_if_needed = create_vrf_if_needed;
6684
6685   mp->is_add = is_add;
6686   mp->is_ipv6 = is_ipv6;
6687   mp->is_local = is_local;
6688   mp->itf_flags = ntohl (iflags);
6689   mp->entry_flags = ntohl (eflags);
6690   mp->grp_address_length = grp_address_length;
6691   mp->grp_address_length = ntohs (mp->grp_address_length);
6692
6693   if (is_ipv6)
6694     {
6695       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6696       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6697     }
6698   else
6699     {
6700       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6701       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6702
6703     }
6704
6705   /* send it... */
6706   S;
6707   /* Wait for a reply... */
6708   W;
6709 }
6710
6711 static int
6712 api_mpls_route_add_del (vat_main_t * vam)
6713 {
6714   unformat_input_t *i = vam->input;
6715   vl_api_mpls_route_add_del_t *mp;
6716   f64 timeout;
6717   u32 sw_if_index = ~0, table_id = 0;
6718   u8 create_table_if_needed = 0;
6719   u8 is_add = 1;
6720   u32 next_hop_weight = 1;
6721   u8 is_multipath = 0;
6722   u32 next_hop_table_id = 0;
6723   u8 next_hop_set = 0;
6724   ip4_address_t v4_next_hop_address = {
6725     .as_u32 = 0,
6726   };
6727   ip6_address_t v6_next_hop_address = { {0} };
6728   int count = 1;
6729   int j;
6730   f64 before = 0;
6731   u32 classify_table_index = ~0;
6732   u8 is_classify = 0;
6733   u8 resolve_host = 0, resolve_attached = 0;
6734   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6735   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6736   mpls_label_t *next_hop_out_label_stack = NULL;
6737   mpls_label_t local_label = MPLS_LABEL_INVALID;
6738   u8 is_eos = 0;
6739   u8 next_hop_proto_is_ip4 = 1;
6740
6741   /* Parse args required to build the message */
6742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6743     {
6744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6745         ;
6746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6747         ;
6748       else if (unformat (i, "%d", &local_label))
6749         ;
6750       else if (unformat (i, "eos"))
6751         is_eos = 1;
6752       else if (unformat (i, "non-eos"))
6753         is_eos = 0;
6754       else if (unformat (i, "via %U", unformat_ip4_address,
6755                          &v4_next_hop_address))
6756         {
6757           next_hop_set = 1;
6758           next_hop_proto_is_ip4 = 1;
6759         }
6760       else if (unformat (i, "via %U", unformat_ip6_address,
6761                          &v6_next_hop_address))
6762         {
6763           next_hop_set = 1;
6764           next_hop_proto_is_ip4 = 0;
6765         }
6766       else if (unformat (i, "weight %d", &next_hop_weight))
6767         ;
6768       else if (unformat (i, "create-table"))
6769         create_table_if_needed = 1;
6770       else if (unformat (i, "classify %d", &classify_table_index))
6771         {
6772           is_classify = 1;
6773         }
6774       else if (unformat (i, "del"))
6775         is_add = 0;
6776       else if (unformat (i, "add"))
6777         is_add = 1;
6778       else if (unformat (i, "resolve-via-host"))
6779         resolve_host = 1;
6780       else if (unformat (i, "resolve-via-attached"))
6781         resolve_attached = 1;
6782       else if (unformat (i, "multipath"))
6783         is_multipath = 1;
6784       else if (unformat (i, "count %d", &count))
6785         ;
6786       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6787         {
6788           next_hop_set = 1;
6789           next_hop_proto_is_ip4 = 1;
6790         }
6791       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6792         {
6793           next_hop_set = 1;
6794           next_hop_proto_is_ip4 = 0;
6795         }
6796       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6797         ;
6798       else if (unformat (i, "via-label %d", &next_hop_via_label))
6799         ;
6800       else if (unformat (i, "out-label %d", &next_hop_out_label))
6801         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6802       else
6803         {
6804           clib_warning ("parse error '%U'", format_unformat_error, i);
6805           return -99;
6806         }
6807     }
6808
6809   if (!next_hop_set && !is_classify)
6810     {
6811       errmsg ("next hop / classify not set");
6812       return -99;
6813     }
6814
6815   if (MPLS_LABEL_INVALID == local_label)
6816     {
6817       errmsg ("missing label");
6818       return -99;
6819     }
6820
6821   if (count > 1)
6822     {
6823       /* Turn on async mode */
6824       vam->async_mode = 1;
6825       vam->async_errors = 0;
6826       before = vat_time_now (vam);
6827     }
6828
6829   for (j = 0; j < count; j++)
6830     {
6831       /* Construct the API message */
6832       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6833           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6834
6835       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6836       mp->mr_table_id = ntohl (table_id);
6837       mp->mr_create_table_if_needed = create_table_if_needed;
6838
6839       mp->mr_is_add = is_add;
6840       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6841       mp->mr_is_classify = is_classify;
6842       mp->mr_is_multipath = is_multipath;
6843       mp->mr_is_resolve_host = resolve_host;
6844       mp->mr_is_resolve_attached = resolve_attached;
6845       mp->mr_next_hop_weight = next_hop_weight;
6846       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6847       mp->mr_classify_table_index = ntohl (classify_table_index);
6848       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6849       mp->mr_label = ntohl (local_label);
6850       mp->mr_eos = is_eos;
6851
6852       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6853       if (0 != mp->mr_next_hop_n_out_labels)
6854         {
6855           memcpy (mp->mr_next_hop_out_label_stack,
6856                   next_hop_out_label_stack,
6857                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6858           vec_free (next_hop_out_label_stack);
6859         }
6860
6861       if (next_hop_set)
6862         {
6863           if (next_hop_proto_is_ip4)
6864             {
6865               clib_memcpy (mp->mr_next_hop,
6866                            &v4_next_hop_address,
6867                            sizeof (v4_next_hop_address));
6868             }
6869           else
6870             {
6871               clib_memcpy (mp->mr_next_hop,
6872                            &v6_next_hop_address,
6873                            sizeof (v6_next_hop_address));
6874             }
6875         }
6876       local_label++;
6877
6878       /* send it... */
6879       S;
6880       /* If we receive SIGTERM, stop now... */
6881       if (vam->do_exit)
6882         break;
6883     }
6884
6885   /* When testing multiple add/del ops, use a control-ping to sync */
6886   if (count > 1)
6887     {
6888       vl_api_control_ping_t *mp;
6889       f64 after;
6890
6891       /* Shut off async mode */
6892       vam->async_mode = 0;
6893
6894       M (CONTROL_PING, control_ping);
6895       S;
6896
6897       timeout = vat_time_now (vam) + 1.0;
6898       while (vat_time_now (vam) < timeout)
6899         if (vam->result_ready == 1)
6900           goto out;
6901       vam->retval = -99;
6902
6903     out:
6904       if (vam->retval == -99)
6905         errmsg ("timeout");
6906
6907       if (vam->async_errors > 0)
6908         {
6909           errmsg ("%d asynchronous errors", vam->async_errors);
6910           vam->retval = -98;
6911         }
6912       vam->async_errors = 0;
6913       after = vat_time_now (vam);
6914
6915       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6916       if (j > 0)
6917         count = j;
6918
6919       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6920              count, after - before, count / (after - before));
6921     }
6922   else
6923     {
6924       /* Wait for a reply... */
6925       W;
6926     }
6927
6928   /* Return the good/bad news */
6929   return (vam->retval);
6930 }
6931
6932 static int
6933 api_mpls_ip_bind_unbind (vat_main_t * vam)
6934 {
6935   unformat_input_t *i = vam->input;
6936   vl_api_mpls_ip_bind_unbind_t *mp;
6937   f64 timeout;
6938   u32 ip_table_id = 0;
6939   u8 create_table_if_needed = 0;
6940   u8 is_bind = 1;
6941   u8 is_ip4 = 1;
6942   ip4_address_t v4_address;
6943   ip6_address_t v6_address;
6944   u32 address_length;
6945   u8 address_set = 0;
6946   mpls_label_t local_label = MPLS_LABEL_INVALID;
6947
6948   /* Parse args required to build the message */
6949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6950     {
6951       if (unformat (i, "%U/%d", unformat_ip4_address,
6952                     &v4_address, &address_length))
6953         {
6954           is_ip4 = 1;
6955           address_set = 1;
6956         }
6957       else if (unformat (i, "%U/%d", unformat_ip6_address,
6958                          &v6_address, &address_length))
6959         {
6960           is_ip4 = 0;
6961           address_set = 1;
6962         }
6963       else if (unformat (i, "%d", &local_label))
6964         ;
6965       else if (unformat (i, "create-table"))
6966         create_table_if_needed = 1;
6967       else if (unformat (i, "table-id %d", &ip_table_id))
6968         ;
6969       else if (unformat (i, "unbind"))
6970         is_bind = 0;
6971       else if (unformat (i, "bind"))
6972         is_bind = 1;
6973       else
6974         {
6975           clib_warning ("parse error '%U'", format_unformat_error, i);
6976           return -99;
6977         }
6978     }
6979
6980   if (!address_set)
6981     {
6982       errmsg ("IP addres not set");
6983       return -99;
6984     }
6985
6986   if (MPLS_LABEL_INVALID == local_label)
6987     {
6988       errmsg ("missing label");
6989       return -99;
6990     }
6991
6992   /* Construct the API message */
6993   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6994
6995   mp->mb_create_table_if_needed = create_table_if_needed;
6996   mp->mb_is_bind = is_bind;
6997   mp->mb_is_ip4 = is_ip4;
6998   mp->mb_ip_table_id = ntohl (ip_table_id);
6999   mp->mb_mpls_table_id = 0;
7000   mp->mb_label = ntohl (local_label);
7001   mp->mb_address_length = address_length;
7002
7003   if (is_ip4)
7004     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7005   else
7006     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7007
7008   /* send it... */
7009   S;
7010
7011   /* Wait for a reply... */
7012   W;
7013 }
7014
7015 static int
7016 api_proxy_arp_add_del (vat_main_t * vam)
7017 {
7018   unformat_input_t *i = vam->input;
7019   vl_api_proxy_arp_add_del_t *mp;
7020   f64 timeout;
7021   u32 vrf_id = 0;
7022   u8 is_add = 1;
7023   ip4_address_t lo, hi;
7024   u8 range_set = 0;
7025
7026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7027     {
7028       if (unformat (i, "vrf %d", &vrf_id))
7029         ;
7030       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7031                          unformat_ip4_address, &hi))
7032         range_set = 1;
7033       else if (unformat (i, "del"))
7034         is_add = 0;
7035       else
7036         {
7037           clib_warning ("parse error '%U'", format_unformat_error, i);
7038           return -99;
7039         }
7040     }
7041
7042   if (range_set == 0)
7043     {
7044       errmsg ("address range not set");
7045       return -99;
7046     }
7047
7048   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
7049
7050   mp->vrf_id = ntohl (vrf_id);
7051   mp->is_add = is_add;
7052   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7053   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7054
7055   S;
7056   W;
7057   /* NOTREACHED */
7058   return 0;
7059 }
7060
7061 static int
7062 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7063 {
7064   unformat_input_t *i = vam->input;
7065   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7066   f64 timeout;
7067   u32 sw_if_index;
7068   u8 enable = 1;
7069   u8 sw_if_index_set = 0;
7070
7071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7072     {
7073       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7074         sw_if_index_set = 1;
7075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7076         sw_if_index_set = 1;
7077       else if (unformat (i, "enable"))
7078         enable = 1;
7079       else if (unformat (i, "disable"))
7080         enable = 0;
7081       else
7082         {
7083           clib_warning ("parse error '%U'", format_unformat_error, i);
7084           return -99;
7085         }
7086     }
7087
7088   if (sw_if_index_set == 0)
7089     {
7090       errmsg ("missing interface name or sw_if_index");
7091       return -99;
7092     }
7093
7094   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
7095
7096   mp->sw_if_index = ntohl (sw_if_index);
7097   mp->enable_disable = enable;
7098
7099   S;
7100   W;
7101   /* NOTREACHED */
7102   return 0;
7103 }
7104
7105 static int
7106 api_mpls_tunnel_add_del (vat_main_t * vam)
7107 {
7108   unformat_input_t *i = vam->input;
7109   vl_api_mpls_tunnel_add_del_t *mp;
7110   f64 timeout;
7111
7112   u8 is_add = 1;
7113   u8 l2_only = 0;
7114   u32 sw_if_index = ~0;
7115   u32 next_hop_sw_if_index = ~0;
7116   u32 next_hop_proto_is_ip4 = 1;
7117
7118   u32 next_hop_table_id = 0;
7119   ip4_address_t v4_next_hop_address = {
7120     .as_u32 = 0,
7121   };
7122   ip6_address_t v6_next_hop_address = { {0} };
7123   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7124
7125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7126     {
7127       if (unformat (i, "add"))
7128         is_add = 1;
7129       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7130         is_add = 0;
7131       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7132         ;
7133       else if (unformat (i, "via %U",
7134                          unformat_ip4_address, &v4_next_hop_address))
7135         {
7136           next_hop_proto_is_ip4 = 1;
7137         }
7138       else if (unformat (i, "via %U",
7139                          unformat_ip6_address, &v6_next_hop_address))
7140         {
7141           next_hop_proto_is_ip4 = 0;
7142         }
7143       else if (unformat (i, "l2-only"))
7144         l2_only = 1;
7145       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7146         ;
7147       else if (unformat (i, "out-label %d", &next_hop_out_label))
7148         vec_add1 (labels, ntohl (next_hop_out_label));
7149       else
7150         {
7151           clib_warning ("parse error '%U'", format_unformat_error, i);
7152           return -99;
7153         }
7154     }
7155
7156   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
7157       sizeof (mpls_label_t) * vec_len (labels));
7158
7159   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7160   mp->mt_sw_if_index = ntohl (sw_if_index);
7161   mp->mt_is_add = is_add;
7162   mp->mt_l2_only = l2_only;
7163   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7164   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7165
7166   mp->mt_next_hop_n_out_labels = vec_len (labels);
7167
7168   if (0 != mp->mt_next_hop_n_out_labels)
7169     {
7170       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7171                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7172       vec_free (labels);
7173     }
7174
7175   if (next_hop_proto_is_ip4)
7176     {
7177       clib_memcpy (mp->mt_next_hop,
7178                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7179     }
7180   else
7181     {
7182       clib_memcpy (mp->mt_next_hop,
7183                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7184     }
7185
7186   S;
7187   W;
7188   /* NOTREACHED */
7189   return 0;
7190 }
7191
7192 static int
7193 api_sw_interface_set_unnumbered (vat_main_t * vam)
7194 {
7195   unformat_input_t *i = vam->input;
7196   vl_api_sw_interface_set_unnumbered_t *mp;
7197   f64 timeout;
7198   u32 sw_if_index;
7199   u32 unnum_sw_index = ~0;
7200   u8 is_add = 1;
7201   u8 sw_if_index_set = 0;
7202
7203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7204     {
7205       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7206         sw_if_index_set = 1;
7207       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7208         sw_if_index_set = 1;
7209       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7210         ;
7211       else if (unformat (i, "del"))
7212         is_add = 0;
7213       else
7214         {
7215           clib_warning ("parse error '%U'", format_unformat_error, i);
7216           return -99;
7217         }
7218     }
7219
7220   if (sw_if_index_set == 0)
7221     {
7222       errmsg ("missing interface name or sw_if_index");
7223       return -99;
7224     }
7225
7226   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
7227
7228   mp->sw_if_index = ntohl (sw_if_index);
7229   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7230   mp->is_add = is_add;
7231
7232   S;
7233   W;
7234   /* NOTREACHED */
7235   return 0;
7236 }
7237
7238 static int
7239 api_ip_neighbor_add_del (vat_main_t * vam)
7240 {
7241   unformat_input_t *i = vam->input;
7242   vl_api_ip_neighbor_add_del_t *mp;
7243   f64 timeout;
7244   u32 sw_if_index;
7245   u8 sw_if_index_set = 0;
7246   u32 vrf_id = 0;
7247   u8 is_add = 1;
7248   u8 is_static = 0;
7249   u8 mac_address[6];
7250   u8 mac_set = 0;
7251   u8 v4_address_set = 0;
7252   u8 v6_address_set = 0;
7253   ip4_address_t v4address;
7254   ip6_address_t v6address;
7255
7256   memset (mac_address, 0, sizeof (mac_address));
7257
7258   /* Parse args required to build the message */
7259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7260     {
7261       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7262         {
7263           mac_set = 1;
7264         }
7265       else if (unformat (i, "del"))
7266         is_add = 0;
7267       else
7268         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7269         sw_if_index_set = 1;
7270       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7271         sw_if_index_set = 1;
7272       else if (unformat (i, "is_static"))
7273         is_static = 1;
7274       else if (unformat (i, "vrf %d", &vrf_id))
7275         ;
7276       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7277         v4_address_set = 1;
7278       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7279         v6_address_set = 1;
7280       else
7281         {
7282           clib_warning ("parse error '%U'", format_unformat_error, i);
7283           return -99;
7284         }
7285     }
7286
7287   if (sw_if_index_set == 0)
7288     {
7289       errmsg ("missing interface name or sw_if_index");
7290       return -99;
7291     }
7292   if (v4_address_set && v6_address_set)
7293     {
7294       errmsg ("both v4 and v6 addresses set");
7295       return -99;
7296     }
7297   if (!v4_address_set && !v6_address_set)
7298     {
7299       errmsg ("no address set");
7300       return -99;
7301     }
7302
7303   /* Construct the API message */
7304   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
7305
7306   mp->sw_if_index = ntohl (sw_if_index);
7307   mp->is_add = is_add;
7308   mp->vrf_id = ntohl (vrf_id);
7309   mp->is_static = is_static;
7310   if (mac_set)
7311     clib_memcpy (mp->mac_address, mac_address, 6);
7312   if (v6_address_set)
7313     {
7314       mp->is_ipv6 = 1;
7315       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7316     }
7317   else
7318     {
7319       /* mp->is_ipv6 = 0; via memset in M macro above */
7320       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7321     }
7322
7323   /* send it... */
7324   S;
7325
7326   /* Wait for a reply, return good/bad news  */
7327   W;
7328
7329   /* NOTREACHED */
7330   return 0;
7331 }
7332
7333 static int
7334 api_reset_vrf (vat_main_t * vam)
7335 {
7336   unformat_input_t *i = vam->input;
7337   vl_api_reset_vrf_t *mp;
7338   f64 timeout;
7339   u32 vrf_id = 0;
7340   u8 is_ipv6 = 0;
7341   u8 vrf_id_set = 0;
7342
7343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7344     {
7345       if (unformat (i, "vrf %d", &vrf_id))
7346         vrf_id_set = 1;
7347       else if (unformat (i, "ipv6"))
7348         is_ipv6 = 1;
7349       else
7350         {
7351           clib_warning ("parse error '%U'", format_unformat_error, i);
7352           return -99;
7353         }
7354     }
7355
7356   if (vrf_id_set == 0)
7357     {
7358       errmsg ("missing vrf id");
7359       return -99;
7360     }
7361
7362   M (RESET_VRF, reset_vrf);
7363
7364   mp->vrf_id = ntohl (vrf_id);
7365   mp->is_ipv6 = is_ipv6;
7366
7367   S;
7368   W;
7369   /* NOTREACHED */
7370   return 0;
7371 }
7372
7373 static int
7374 api_create_vlan_subif (vat_main_t * vam)
7375 {
7376   unformat_input_t *i = vam->input;
7377   vl_api_create_vlan_subif_t *mp;
7378   f64 timeout;
7379   u32 sw_if_index;
7380   u8 sw_if_index_set = 0;
7381   u32 vlan_id;
7382   u8 vlan_id_set = 0;
7383
7384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7385     {
7386       if (unformat (i, "sw_if_index %d", &sw_if_index))
7387         sw_if_index_set = 1;
7388       else
7389         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7390         sw_if_index_set = 1;
7391       else if (unformat (i, "vlan %d", &vlan_id))
7392         vlan_id_set = 1;
7393       else
7394         {
7395           clib_warning ("parse error '%U'", format_unformat_error, i);
7396           return -99;
7397         }
7398     }
7399
7400   if (sw_if_index_set == 0)
7401     {
7402       errmsg ("missing interface name or sw_if_index");
7403       return -99;
7404     }
7405
7406   if (vlan_id_set == 0)
7407     {
7408       errmsg ("missing vlan_id");
7409       return -99;
7410     }
7411   M (CREATE_VLAN_SUBIF, create_vlan_subif);
7412
7413   mp->sw_if_index = ntohl (sw_if_index);
7414   mp->vlan_id = ntohl (vlan_id);
7415
7416   S;
7417   W;
7418   /* NOTREACHED */
7419   return 0;
7420 }
7421
7422 #define foreach_create_subif_bit                \
7423 _(no_tags)                                      \
7424 _(one_tag)                                      \
7425 _(two_tags)                                     \
7426 _(dot1ad)                                       \
7427 _(exact_match)                                  \
7428 _(default_sub)                                  \
7429 _(outer_vlan_id_any)                            \
7430 _(inner_vlan_id_any)
7431
7432 static int
7433 api_create_subif (vat_main_t * vam)
7434 {
7435   unformat_input_t *i = vam->input;
7436   vl_api_create_subif_t *mp;
7437   f64 timeout;
7438   u32 sw_if_index;
7439   u8 sw_if_index_set = 0;
7440   u32 sub_id;
7441   u8 sub_id_set = 0;
7442   u32 no_tags = 0;
7443   u32 one_tag = 0;
7444   u32 two_tags = 0;
7445   u32 dot1ad = 0;
7446   u32 exact_match = 0;
7447   u32 default_sub = 0;
7448   u32 outer_vlan_id_any = 0;
7449   u32 inner_vlan_id_any = 0;
7450   u32 tmp;
7451   u16 outer_vlan_id = 0;
7452   u16 inner_vlan_id = 0;
7453
7454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7455     {
7456       if (unformat (i, "sw_if_index %d", &sw_if_index))
7457         sw_if_index_set = 1;
7458       else
7459         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7460         sw_if_index_set = 1;
7461       else if (unformat (i, "sub_id %d", &sub_id))
7462         sub_id_set = 1;
7463       else if (unformat (i, "outer_vlan_id %d", &tmp))
7464         outer_vlan_id = tmp;
7465       else if (unformat (i, "inner_vlan_id %d", &tmp))
7466         inner_vlan_id = tmp;
7467
7468 #define _(a) else if (unformat (i, #a)) a = 1 ;
7469       foreach_create_subif_bit
7470 #undef _
7471         else
7472         {
7473           clib_warning ("parse error '%U'", format_unformat_error, i);
7474           return -99;
7475         }
7476     }
7477
7478   if (sw_if_index_set == 0)
7479     {
7480       errmsg ("missing interface name or sw_if_index");
7481       return -99;
7482     }
7483
7484   if (sub_id_set == 0)
7485     {
7486       errmsg ("missing sub_id");
7487       return -99;
7488     }
7489   M (CREATE_SUBIF, create_subif);
7490
7491   mp->sw_if_index = ntohl (sw_if_index);
7492   mp->sub_id = ntohl (sub_id);
7493
7494 #define _(a) mp->a = a;
7495   foreach_create_subif_bit;
7496 #undef _
7497
7498   mp->outer_vlan_id = ntohs (outer_vlan_id);
7499   mp->inner_vlan_id = ntohs (inner_vlan_id);
7500
7501   S;
7502   W;
7503   /* NOTREACHED */
7504   return 0;
7505 }
7506
7507 static int
7508 api_oam_add_del (vat_main_t * vam)
7509 {
7510   unformat_input_t *i = vam->input;
7511   vl_api_oam_add_del_t *mp;
7512   f64 timeout;
7513   u32 vrf_id = 0;
7514   u8 is_add = 1;
7515   ip4_address_t src, dst;
7516   u8 src_set = 0;
7517   u8 dst_set = 0;
7518
7519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7520     {
7521       if (unformat (i, "vrf %d", &vrf_id))
7522         ;
7523       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7524         src_set = 1;
7525       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7526         dst_set = 1;
7527       else if (unformat (i, "del"))
7528         is_add = 0;
7529       else
7530         {
7531           clib_warning ("parse error '%U'", format_unformat_error, i);
7532           return -99;
7533         }
7534     }
7535
7536   if (src_set == 0)
7537     {
7538       errmsg ("missing src addr");
7539       return -99;
7540     }
7541
7542   if (dst_set == 0)
7543     {
7544       errmsg ("missing dst addr");
7545       return -99;
7546     }
7547
7548   M (OAM_ADD_DEL, oam_add_del);
7549
7550   mp->vrf_id = ntohl (vrf_id);
7551   mp->is_add = is_add;
7552   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7553   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7554
7555   S;
7556   W;
7557   /* NOTREACHED */
7558   return 0;
7559 }
7560
7561 static int
7562 api_reset_fib (vat_main_t * vam)
7563 {
7564   unformat_input_t *i = vam->input;
7565   vl_api_reset_fib_t *mp;
7566   f64 timeout;
7567   u32 vrf_id = 0;
7568   u8 is_ipv6 = 0;
7569   u8 vrf_id_set = 0;
7570
7571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7572     {
7573       if (unformat (i, "vrf %d", &vrf_id))
7574         vrf_id_set = 1;
7575       else if (unformat (i, "ipv6"))
7576         is_ipv6 = 1;
7577       else
7578         {
7579           clib_warning ("parse error '%U'", format_unformat_error, i);
7580           return -99;
7581         }
7582     }
7583
7584   if (vrf_id_set == 0)
7585     {
7586       errmsg ("missing vrf id");
7587       return -99;
7588     }
7589
7590   M (RESET_FIB, reset_fib);
7591
7592   mp->vrf_id = ntohl (vrf_id);
7593   mp->is_ipv6 = is_ipv6;
7594
7595   S;
7596   W;
7597   /* NOTREACHED */
7598   return 0;
7599 }
7600
7601 static int
7602 api_dhcp_proxy_config (vat_main_t * vam)
7603 {
7604   unformat_input_t *i = vam->input;
7605   vl_api_dhcp_proxy_config_t *mp;
7606   f64 timeout;
7607   u32 vrf_id = 0;
7608   u8 is_add = 1;
7609   u8 insert_cid = 1;
7610   u8 v4_address_set = 0;
7611   u8 v6_address_set = 0;
7612   ip4_address_t v4address;
7613   ip6_address_t v6address;
7614   u8 v4_src_address_set = 0;
7615   u8 v6_src_address_set = 0;
7616   ip4_address_t v4srcaddress;
7617   ip6_address_t v6srcaddress;
7618
7619   /* Parse args required to build the message */
7620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7621     {
7622       if (unformat (i, "del"))
7623         is_add = 0;
7624       else if (unformat (i, "vrf %d", &vrf_id))
7625         ;
7626       else if (unformat (i, "insert-cid %d", &insert_cid))
7627         ;
7628       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7629         v4_address_set = 1;
7630       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7631         v6_address_set = 1;
7632       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7633         v4_src_address_set = 1;
7634       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7635         v6_src_address_set = 1;
7636       else
7637         break;
7638     }
7639
7640   if (v4_address_set && v6_address_set)
7641     {
7642       errmsg ("both v4 and v6 server addresses set");
7643       return -99;
7644     }
7645   if (!v4_address_set && !v6_address_set)
7646     {
7647       errmsg ("no server addresses set");
7648       return -99;
7649     }
7650
7651   if (v4_src_address_set && v6_src_address_set)
7652     {
7653       errmsg ("both v4 and v6  src addresses set");
7654       return -99;
7655     }
7656   if (!v4_src_address_set && !v6_src_address_set)
7657     {
7658       errmsg ("no src addresses set");
7659       return -99;
7660     }
7661
7662   if (!(v4_src_address_set && v4_address_set) &&
7663       !(v6_src_address_set && v6_address_set))
7664     {
7665       errmsg ("no matching server and src addresses set");
7666       return -99;
7667     }
7668
7669   /* Construct the API message */
7670   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7671
7672   mp->insert_circuit_id = insert_cid;
7673   mp->is_add = is_add;
7674   mp->vrf_id = ntohl (vrf_id);
7675   if (v6_address_set)
7676     {
7677       mp->is_ipv6 = 1;
7678       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7679       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7680     }
7681   else
7682     {
7683       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7684       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7685     }
7686
7687   /* send it... */
7688   S;
7689
7690   /* Wait for a reply, return good/bad news  */
7691   W;
7692   /* NOTREACHED */
7693   return 0;
7694 }
7695
7696 static int
7697 api_dhcp_proxy_config_2 (vat_main_t * vam)
7698 {
7699   unformat_input_t *i = vam->input;
7700   vl_api_dhcp_proxy_config_2_t *mp;
7701   f64 timeout;
7702   u32 rx_vrf_id = 0;
7703   u32 server_vrf_id = 0;
7704   u8 is_add = 1;
7705   u8 insert_cid = 1;
7706   u8 v4_address_set = 0;
7707   u8 v6_address_set = 0;
7708   ip4_address_t v4address;
7709   ip6_address_t v6address;
7710   u8 v4_src_address_set = 0;
7711   u8 v6_src_address_set = 0;
7712   ip4_address_t v4srcaddress;
7713   ip6_address_t v6srcaddress;
7714
7715   /* Parse args required to build the message */
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "del"))
7719         is_add = 0;
7720       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7721         ;
7722       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7723         ;
7724       else if (unformat (i, "insert-cid %d", &insert_cid))
7725         ;
7726       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7727         v4_address_set = 1;
7728       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7729         v6_address_set = 1;
7730       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7731         v4_src_address_set = 1;
7732       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7733         v6_src_address_set = 1;
7734       else
7735         break;
7736     }
7737
7738   if (v4_address_set && v6_address_set)
7739     {
7740       errmsg ("both v4 and v6 server addresses set");
7741       return -99;
7742     }
7743   if (!v4_address_set && !v6_address_set)
7744     {
7745       errmsg ("no server addresses set");
7746       return -99;
7747     }
7748
7749   if (v4_src_address_set && v6_src_address_set)
7750     {
7751       errmsg ("both v4 and v6  src addresses set");
7752       return -99;
7753     }
7754   if (!v4_src_address_set && !v6_src_address_set)
7755     {
7756       errmsg ("no src addresses set");
7757       return -99;
7758     }
7759
7760   if (!(v4_src_address_set && v4_address_set) &&
7761       !(v6_src_address_set && v6_address_set))
7762     {
7763       errmsg ("no matching server and src addresses set");
7764       return -99;
7765     }
7766
7767   /* Construct the API message */
7768   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7769
7770   mp->insert_circuit_id = insert_cid;
7771   mp->is_add = is_add;
7772   mp->rx_vrf_id = ntohl (rx_vrf_id);
7773   mp->server_vrf_id = ntohl (server_vrf_id);
7774   if (v6_address_set)
7775     {
7776       mp->is_ipv6 = 1;
7777       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7778       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7779     }
7780   else
7781     {
7782       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7783       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7784     }
7785
7786   /* send it... */
7787   S;
7788
7789   /* Wait for a reply, return good/bad news  */
7790   W;
7791   /* NOTREACHED */
7792   return 0;
7793 }
7794
7795 static int
7796 api_dhcp_proxy_set_vss (vat_main_t * vam)
7797 {
7798   unformat_input_t *i = vam->input;
7799   vl_api_dhcp_proxy_set_vss_t *mp;
7800   f64 timeout;
7801   u8 is_ipv6 = 0;
7802   u8 is_add = 1;
7803   u32 tbl_id;
7804   u8 tbl_id_set = 0;
7805   u32 oui;
7806   u8 oui_set = 0;
7807   u32 fib_id;
7808   u8 fib_id_set = 0;
7809
7810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7811     {
7812       if (unformat (i, "tbl_id %d", &tbl_id))
7813         tbl_id_set = 1;
7814       if (unformat (i, "fib_id %d", &fib_id))
7815         fib_id_set = 1;
7816       if (unformat (i, "oui %d", &oui))
7817         oui_set = 1;
7818       else if (unformat (i, "ipv6"))
7819         is_ipv6 = 1;
7820       else if (unformat (i, "del"))
7821         is_add = 0;
7822       else
7823         {
7824           clib_warning ("parse error '%U'", format_unformat_error, i);
7825           return -99;
7826         }
7827     }
7828
7829   if (tbl_id_set == 0)
7830     {
7831       errmsg ("missing tbl id");
7832       return -99;
7833     }
7834
7835   if (fib_id_set == 0)
7836     {
7837       errmsg ("missing fib id");
7838       return -99;
7839     }
7840   if (oui_set == 0)
7841     {
7842       errmsg ("missing oui");
7843       return -99;
7844     }
7845
7846   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7847   mp->tbl_id = ntohl (tbl_id);
7848   mp->fib_id = ntohl (fib_id);
7849   mp->oui = ntohl (oui);
7850   mp->is_ipv6 = is_ipv6;
7851   mp->is_add = is_add;
7852
7853   S;
7854   W;
7855   /* NOTREACHED */
7856   return 0;
7857 }
7858
7859 static int
7860 api_dhcp_client_config (vat_main_t * vam)
7861 {
7862   unformat_input_t *i = vam->input;
7863   vl_api_dhcp_client_config_t *mp;
7864   f64 timeout;
7865   u32 sw_if_index;
7866   u8 sw_if_index_set = 0;
7867   u8 is_add = 1;
7868   u8 *hostname = 0;
7869   u8 disable_event = 0;
7870
7871   /* Parse args required to build the message */
7872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7873     {
7874       if (unformat (i, "del"))
7875         is_add = 0;
7876       else
7877         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7878         sw_if_index_set = 1;
7879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7880         sw_if_index_set = 1;
7881       else if (unformat (i, "hostname %s", &hostname))
7882         ;
7883       else if (unformat (i, "disable_event"))
7884         disable_event = 1;
7885       else
7886         break;
7887     }
7888
7889   if (sw_if_index_set == 0)
7890     {
7891       errmsg ("missing interface name or sw_if_index");
7892       return -99;
7893     }
7894
7895   if (vec_len (hostname) > 63)
7896     {
7897       errmsg ("hostname too long");
7898     }
7899   vec_add1 (hostname, 0);
7900
7901   /* Construct the API message */
7902   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7903
7904   mp->sw_if_index = ntohl (sw_if_index);
7905   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7906   vec_free (hostname);
7907   mp->is_add = is_add;
7908   mp->want_dhcp_event = disable_event ? 0 : 1;
7909   mp->pid = getpid ();
7910
7911   /* send it... */
7912   S;
7913
7914   /* Wait for a reply, return good/bad news  */
7915   W;
7916   /* NOTREACHED */
7917   return 0;
7918 }
7919
7920 static int
7921 api_set_ip_flow_hash (vat_main_t * vam)
7922 {
7923   unformat_input_t *i = vam->input;
7924   vl_api_set_ip_flow_hash_t *mp;
7925   f64 timeout;
7926   u32 vrf_id = 0;
7927   u8 is_ipv6 = 0;
7928   u8 vrf_id_set = 0;
7929   u8 src = 0;
7930   u8 dst = 0;
7931   u8 sport = 0;
7932   u8 dport = 0;
7933   u8 proto = 0;
7934   u8 reverse = 0;
7935
7936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7937     {
7938       if (unformat (i, "vrf %d", &vrf_id))
7939         vrf_id_set = 1;
7940       else if (unformat (i, "ipv6"))
7941         is_ipv6 = 1;
7942       else if (unformat (i, "src"))
7943         src = 1;
7944       else if (unformat (i, "dst"))
7945         dst = 1;
7946       else if (unformat (i, "sport"))
7947         sport = 1;
7948       else if (unformat (i, "dport"))
7949         dport = 1;
7950       else if (unformat (i, "proto"))
7951         proto = 1;
7952       else if (unformat (i, "reverse"))
7953         reverse = 1;
7954
7955       else
7956         {
7957           clib_warning ("parse error '%U'", format_unformat_error, i);
7958           return -99;
7959         }
7960     }
7961
7962   if (vrf_id_set == 0)
7963     {
7964       errmsg ("missing vrf id");
7965       return -99;
7966     }
7967
7968   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7969   mp->src = src;
7970   mp->dst = dst;
7971   mp->sport = sport;
7972   mp->dport = dport;
7973   mp->proto = proto;
7974   mp->reverse = reverse;
7975   mp->vrf_id = ntohl (vrf_id);
7976   mp->is_ipv6 = is_ipv6;
7977
7978   S;
7979   W;
7980   /* NOTREACHED */
7981   return 0;
7982 }
7983
7984 static int
7985 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7986 {
7987   unformat_input_t *i = vam->input;
7988   vl_api_sw_interface_ip6_enable_disable_t *mp;
7989   f64 timeout;
7990   u32 sw_if_index;
7991   u8 sw_if_index_set = 0;
7992   u8 enable = 0;
7993
7994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7995     {
7996       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7997         sw_if_index_set = 1;
7998       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7999         sw_if_index_set = 1;
8000       else if (unformat (i, "enable"))
8001         enable = 1;
8002       else if (unformat (i, "disable"))
8003         enable = 0;
8004       else
8005         {
8006           clib_warning ("parse error '%U'", format_unformat_error, i);
8007           return -99;
8008         }
8009     }
8010
8011   if (sw_if_index_set == 0)
8012     {
8013       errmsg ("missing interface name or sw_if_index");
8014       return -99;
8015     }
8016
8017   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
8018
8019   mp->sw_if_index = ntohl (sw_if_index);
8020   mp->enable = enable;
8021
8022   S;
8023   W;
8024   /* NOTREACHED */
8025   return 0;
8026 }
8027
8028 static int
8029 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8030 {
8031   unformat_input_t *i = vam->input;
8032   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8033   f64 timeout;
8034   u32 sw_if_index;
8035   u8 sw_if_index_set = 0;
8036   u8 v6_address_set = 0;
8037   ip6_address_t v6address;
8038
8039   /* Parse args required to build the message */
8040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8041     {
8042       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8043         sw_if_index_set = 1;
8044       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8045         sw_if_index_set = 1;
8046       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8047         v6_address_set = 1;
8048       else
8049         break;
8050     }
8051
8052   if (sw_if_index_set == 0)
8053     {
8054       errmsg ("missing interface name or sw_if_index");
8055       return -99;
8056     }
8057   if (!v6_address_set)
8058     {
8059       errmsg ("no address set");
8060       return -99;
8061     }
8062
8063   /* Construct the API message */
8064   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
8065      sw_interface_ip6_set_link_local_address);
8066
8067   mp->sw_if_index = ntohl (sw_if_index);
8068   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8069
8070   /* send it... */
8071   S;
8072
8073   /* Wait for a reply, return good/bad news  */
8074   W;
8075
8076   /* NOTREACHED */
8077   return 0;
8078 }
8079
8080
8081 static int
8082 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8083 {
8084   unformat_input_t *i = vam->input;
8085   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8086   f64 timeout;
8087   u32 sw_if_index;
8088   u8 sw_if_index_set = 0;
8089   u32 address_length = 0;
8090   u8 v6_address_set = 0;
8091   ip6_address_t v6address;
8092   u8 use_default = 0;
8093   u8 no_advertise = 0;
8094   u8 off_link = 0;
8095   u8 no_autoconfig = 0;
8096   u8 no_onlink = 0;
8097   u8 is_no = 0;
8098   u32 val_lifetime = 0;
8099   u32 pref_lifetime = 0;
8100
8101   /* Parse args required to build the message */
8102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8103     {
8104       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8105         sw_if_index_set = 1;
8106       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8107         sw_if_index_set = 1;
8108       else if (unformat (i, "%U/%d",
8109                          unformat_ip6_address, &v6address, &address_length))
8110         v6_address_set = 1;
8111       else if (unformat (i, "val_life %d", &val_lifetime))
8112         ;
8113       else if (unformat (i, "pref_life %d", &pref_lifetime))
8114         ;
8115       else if (unformat (i, "def"))
8116         use_default = 1;
8117       else if (unformat (i, "noadv"))
8118         no_advertise = 1;
8119       else if (unformat (i, "offl"))
8120         off_link = 1;
8121       else if (unformat (i, "noauto"))
8122         no_autoconfig = 1;
8123       else if (unformat (i, "nolink"))
8124         no_onlink = 1;
8125       else if (unformat (i, "isno"))
8126         is_no = 1;
8127       else
8128         {
8129           clib_warning ("parse error '%U'", format_unformat_error, i);
8130           return -99;
8131         }
8132     }
8133
8134   if (sw_if_index_set == 0)
8135     {
8136       errmsg ("missing interface name or sw_if_index");
8137       return -99;
8138     }
8139   if (!v6_address_set)
8140     {
8141       errmsg ("no address set");
8142       return -99;
8143     }
8144
8145   /* Construct the API message */
8146   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
8147
8148   mp->sw_if_index = ntohl (sw_if_index);
8149   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8150   mp->address_length = address_length;
8151   mp->use_default = use_default;
8152   mp->no_advertise = no_advertise;
8153   mp->off_link = off_link;
8154   mp->no_autoconfig = no_autoconfig;
8155   mp->no_onlink = no_onlink;
8156   mp->is_no = is_no;
8157   mp->val_lifetime = ntohl (val_lifetime);
8158   mp->pref_lifetime = ntohl (pref_lifetime);
8159
8160   /* send it... */
8161   S;
8162
8163   /* Wait for a reply, return good/bad news  */
8164   W;
8165
8166   /* NOTREACHED */
8167   return 0;
8168 }
8169
8170 static int
8171 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8172 {
8173   unformat_input_t *i = vam->input;
8174   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8175   f64 timeout;
8176   u32 sw_if_index;
8177   u8 sw_if_index_set = 0;
8178   u8 suppress = 0;
8179   u8 managed = 0;
8180   u8 other = 0;
8181   u8 ll_option = 0;
8182   u8 send_unicast = 0;
8183   u8 cease = 0;
8184   u8 is_no = 0;
8185   u8 default_router = 0;
8186   u32 max_interval = 0;
8187   u32 min_interval = 0;
8188   u32 lifetime = 0;
8189   u32 initial_count = 0;
8190   u32 initial_interval = 0;
8191
8192
8193   /* Parse args required to build the message */
8194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8195     {
8196       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8197         sw_if_index_set = 1;
8198       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8199         sw_if_index_set = 1;
8200       else if (unformat (i, "maxint %d", &max_interval))
8201         ;
8202       else if (unformat (i, "minint %d", &min_interval))
8203         ;
8204       else if (unformat (i, "life %d", &lifetime))
8205         ;
8206       else if (unformat (i, "count %d", &initial_count))
8207         ;
8208       else if (unformat (i, "interval %d", &initial_interval))
8209         ;
8210       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8211         suppress = 1;
8212       else if (unformat (i, "managed"))
8213         managed = 1;
8214       else if (unformat (i, "other"))
8215         other = 1;
8216       else if (unformat (i, "ll"))
8217         ll_option = 1;
8218       else if (unformat (i, "send"))
8219         send_unicast = 1;
8220       else if (unformat (i, "cease"))
8221         cease = 1;
8222       else if (unformat (i, "isno"))
8223         is_no = 1;
8224       else if (unformat (i, "def"))
8225         default_router = 1;
8226       else
8227         {
8228           clib_warning ("parse error '%U'", format_unformat_error, i);
8229           return -99;
8230         }
8231     }
8232
8233   if (sw_if_index_set == 0)
8234     {
8235       errmsg ("missing interface name or sw_if_index");
8236       return -99;
8237     }
8238
8239   /* Construct the API message */
8240   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
8241
8242   mp->sw_if_index = ntohl (sw_if_index);
8243   mp->max_interval = ntohl (max_interval);
8244   mp->min_interval = ntohl (min_interval);
8245   mp->lifetime = ntohl (lifetime);
8246   mp->initial_count = ntohl (initial_count);
8247   mp->initial_interval = ntohl (initial_interval);
8248   mp->suppress = suppress;
8249   mp->managed = managed;
8250   mp->other = other;
8251   mp->ll_option = ll_option;
8252   mp->send_unicast = send_unicast;
8253   mp->cease = cease;
8254   mp->is_no = is_no;
8255   mp->default_router = default_router;
8256
8257   /* send it... */
8258   S;
8259
8260   /* Wait for a reply, return good/bad news  */
8261   W;
8262
8263   /* NOTREACHED */
8264   return 0;
8265 }
8266
8267 static int
8268 api_set_arp_neighbor_limit (vat_main_t * vam)
8269 {
8270   unformat_input_t *i = vam->input;
8271   vl_api_set_arp_neighbor_limit_t *mp;
8272   f64 timeout;
8273   u32 arp_nbr_limit;
8274   u8 limit_set = 0;
8275   u8 is_ipv6 = 0;
8276
8277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8278     {
8279       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8280         limit_set = 1;
8281       else if (unformat (i, "ipv6"))
8282         is_ipv6 = 1;
8283       else
8284         {
8285           clib_warning ("parse error '%U'", format_unformat_error, i);
8286           return -99;
8287         }
8288     }
8289
8290   if (limit_set == 0)
8291     {
8292       errmsg ("missing limit value");
8293       return -99;
8294     }
8295
8296   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
8297
8298   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8299   mp->is_ipv6 = is_ipv6;
8300
8301   S;
8302   W;
8303   /* NOTREACHED */
8304   return 0;
8305 }
8306
8307 static int
8308 api_l2_patch_add_del (vat_main_t * vam)
8309 {
8310   unformat_input_t *i = vam->input;
8311   vl_api_l2_patch_add_del_t *mp;
8312   f64 timeout;
8313   u32 rx_sw_if_index;
8314   u8 rx_sw_if_index_set = 0;
8315   u32 tx_sw_if_index;
8316   u8 tx_sw_if_index_set = 0;
8317   u8 is_add = 1;
8318
8319   /* Parse args required to build the message */
8320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8321     {
8322       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8323         rx_sw_if_index_set = 1;
8324       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8325         tx_sw_if_index_set = 1;
8326       else if (unformat (i, "rx"))
8327         {
8328           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8329             {
8330               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8331                             &rx_sw_if_index))
8332                 rx_sw_if_index_set = 1;
8333             }
8334           else
8335             break;
8336         }
8337       else if (unformat (i, "tx"))
8338         {
8339           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8340             {
8341               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8342                             &tx_sw_if_index))
8343                 tx_sw_if_index_set = 1;
8344             }
8345           else
8346             break;
8347         }
8348       else if (unformat (i, "del"))
8349         is_add = 0;
8350       else
8351         break;
8352     }
8353
8354   if (rx_sw_if_index_set == 0)
8355     {
8356       errmsg ("missing rx interface name or rx_sw_if_index");
8357       return -99;
8358     }
8359
8360   if (tx_sw_if_index_set == 0)
8361     {
8362       errmsg ("missing tx interface name or tx_sw_if_index");
8363       return -99;
8364     }
8365
8366   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
8367
8368   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8369   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8370   mp->is_add = is_add;
8371
8372   S;
8373   W;
8374   /* NOTREACHED */
8375   return 0;
8376 }
8377
8378 static int
8379 api_ioam_enable (vat_main_t * vam)
8380 {
8381   unformat_input_t *input = vam->input;
8382   vl_api_ioam_enable_t *mp;
8383   f64 timeout;
8384   u32 id = 0;
8385   int has_trace_option = 0;
8386   int has_pot_option = 0;
8387   int has_seqno_option = 0;
8388   int has_analyse_option = 0;
8389
8390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8391     {
8392       if (unformat (input, "trace"))
8393         has_trace_option = 1;
8394       else if (unformat (input, "pot"))
8395         has_pot_option = 1;
8396       else if (unformat (input, "seqno"))
8397         has_seqno_option = 1;
8398       else if (unformat (input, "analyse"))
8399         has_analyse_option = 1;
8400       else
8401         break;
8402     }
8403   M (IOAM_ENABLE, ioam_enable);
8404   mp->id = htons (id);
8405   mp->seqno = has_seqno_option;
8406   mp->analyse = has_analyse_option;
8407   mp->pot_enable = has_pot_option;
8408   mp->trace_enable = has_trace_option;
8409
8410   S;
8411   W;
8412
8413   return (0);
8414
8415 }
8416
8417
8418 static int
8419 api_ioam_disable (vat_main_t * vam)
8420 {
8421   vl_api_ioam_disable_t *mp;
8422   f64 timeout;
8423
8424   M (IOAM_DISABLE, ioam_disable);
8425   S;
8426   W;
8427   return 0;
8428 }
8429
8430 static int
8431 api_sr_tunnel_add_del (vat_main_t * vam)
8432 {
8433   unformat_input_t *i = vam->input;
8434   vl_api_sr_tunnel_add_del_t *mp;
8435   f64 timeout;
8436   int is_del = 0;
8437   int pl_index;
8438   ip6_address_t src_address;
8439   int src_address_set = 0;
8440   ip6_address_t dst_address;
8441   u32 dst_mask_width;
8442   int dst_address_set = 0;
8443   u16 flags = 0;
8444   u32 rx_table_id = 0;
8445   u32 tx_table_id = 0;
8446   ip6_address_t *segments = 0;
8447   ip6_address_t *this_seg;
8448   ip6_address_t *tags = 0;
8449   ip6_address_t *this_tag;
8450   ip6_address_t next_address, tag;
8451   u8 *name = 0;
8452   u8 *policy_name = 0;
8453
8454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8455     {
8456       if (unformat (i, "del"))
8457         is_del = 1;
8458       else if (unformat (i, "name %s", &name))
8459         ;
8460       else if (unformat (i, "policy %s", &policy_name))
8461         ;
8462       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8463         ;
8464       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8465         ;
8466       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8467         src_address_set = 1;
8468       else if (unformat (i, "dst %U/%d",
8469                          unformat_ip6_address, &dst_address, &dst_mask_width))
8470         dst_address_set = 1;
8471       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8472         {
8473           vec_add2 (segments, this_seg, 1);
8474           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8475                        sizeof (*this_seg));
8476         }
8477       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8478         {
8479           vec_add2 (tags, this_tag, 1);
8480           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8481         }
8482       else if (unformat (i, "clean"))
8483         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8484       else if (unformat (i, "protected"))
8485         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8486       else if (unformat (i, "InPE %d", &pl_index))
8487         {
8488           if (pl_index <= 0 || pl_index > 4)
8489             {
8490             pl_index_range_error:
8491               errmsg ("pl index %d out of range", pl_index);
8492               return -99;
8493             }
8494           flags |=
8495             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8496         }
8497       else if (unformat (i, "EgPE %d", &pl_index))
8498         {
8499           if (pl_index <= 0 || pl_index > 4)
8500             goto pl_index_range_error;
8501           flags |=
8502             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8503         }
8504       else if (unformat (i, "OrgSrc %d", &pl_index))
8505         {
8506           if (pl_index <= 0 || pl_index > 4)
8507             goto pl_index_range_error;
8508           flags |=
8509             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8510         }
8511       else
8512         break;
8513     }
8514
8515   if (!src_address_set)
8516     {
8517       errmsg ("src address required");
8518       return -99;
8519     }
8520
8521   if (!dst_address_set)
8522     {
8523       errmsg ("dst address required");
8524       return -99;
8525     }
8526
8527   if (!segments)
8528     {
8529       errmsg ("at least one sr segment required");
8530       return -99;
8531     }
8532
8533   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8534       vec_len (segments) * sizeof (ip6_address_t)
8535       + vec_len (tags) * sizeof (ip6_address_t));
8536
8537   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8538   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8539   mp->dst_mask_width = dst_mask_width;
8540   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8541   mp->n_segments = vec_len (segments);
8542   mp->n_tags = vec_len (tags);
8543   mp->is_add = is_del == 0;
8544   clib_memcpy (mp->segs_and_tags, segments,
8545                vec_len (segments) * sizeof (ip6_address_t));
8546   clib_memcpy (mp->segs_and_tags +
8547                vec_len (segments) * sizeof (ip6_address_t), tags,
8548                vec_len (tags) * sizeof (ip6_address_t));
8549
8550   mp->outer_vrf_id = ntohl (rx_table_id);
8551   mp->inner_vrf_id = ntohl (tx_table_id);
8552   memcpy (mp->name, name, vec_len (name));
8553   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8554
8555   vec_free (segments);
8556   vec_free (tags);
8557
8558   S;
8559   W;
8560   /* NOTREACHED */
8561 }
8562
8563 static int
8564 api_sr_policy_add_del (vat_main_t * vam)
8565 {
8566   unformat_input_t *input = vam->input;
8567   vl_api_sr_policy_add_del_t *mp;
8568   f64 timeout;
8569   int is_del = 0;
8570   u8 *name = 0;
8571   u8 *tunnel_name = 0;
8572   u8 **tunnel_names = 0;
8573
8574   int name_set = 0;
8575   int tunnel_set = 0;
8576   int j = 0;
8577   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8578   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8579
8580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8581     {
8582       if (unformat (input, "del"))
8583         is_del = 1;
8584       else if (unformat (input, "name %s", &name))
8585         name_set = 1;
8586       else if (unformat (input, "tunnel %s", &tunnel_name))
8587         {
8588           if (tunnel_name)
8589             {
8590               vec_add1 (tunnel_names, tunnel_name);
8591               /* For serializer:
8592                  - length = #bytes to store in serial vector
8593                  - +1 = byte to store that length
8594                */
8595               tunnel_names_length += (vec_len (tunnel_name) + 1);
8596               tunnel_set = 1;
8597               tunnel_name = 0;
8598             }
8599         }
8600       else
8601         break;
8602     }
8603
8604   if (!name_set)
8605     {
8606       errmsg ("policy name required");
8607       return -99;
8608     }
8609
8610   if ((!tunnel_set) && (!is_del))
8611     {
8612       errmsg ("tunnel name required");
8613       return -99;
8614     }
8615
8616   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8617
8618
8619
8620   mp->is_add = !is_del;
8621
8622   memcpy (mp->name, name, vec_len (name));
8623   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8624   u8 *serial_orig = 0;
8625   vec_validate (serial_orig, tunnel_names_length);
8626   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8627   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8628
8629   for (j = 0; j < vec_len (tunnel_names); j++)
8630     {
8631       tun_name_len = vec_len (tunnel_names[j]);
8632       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8633       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8634       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8635       serial_orig += tun_name_len;      // Advance past the copy
8636     }
8637   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8638
8639   vec_free (tunnel_names);
8640   vec_free (tunnel_name);
8641
8642   S;
8643   W;
8644   /* NOTREACHED */
8645 }
8646
8647 static int
8648 api_sr_multicast_map_add_del (vat_main_t * vam)
8649 {
8650   unformat_input_t *input = vam->input;
8651   vl_api_sr_multicast_map_add_del_t *mp;
8652   f64 timeout;
8653   int is_del = 0;
8654   ip6_address_t multicast_address;
8655   u8 *policy_name = 0;
8656   int multicast_address_set = 0;
8657
8658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (input, "del"))
8661         is_del = 1;
8662       else
8663         if (unformat
8664             (input, "address %U", unformat_ip6_address, &multicast_address))
8665         multicast_address_set = 1;
8666       else if (unformat (input, "sr-policy %s", &policy_name))
8667         ;
8668       else
8669         break;
8670     }
8671
8672   if (!is_del && !policy_name)
8673     {
8674       errmsg ("sr-policy name required");
8675       return -99;
8676     }
8677
8678
8679   if (!multicast_address_set)
8680     {
8681       errmsg ("address required");
8682       return -99;
8683     }
8684
8685   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8686
8687   mp->is_add = !is_del;
8688   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8689   clib_memcpy (mp->multicast_address, &multicast_address,
8690                sizeof (mp->multicast_address));
8691
8692
8693   vec_free (policy_name);
8694
8695   S;
8696   W;
8697   /* NOTREACHED */
8698 }
8699
8700
8701 #define foreach_tcp_proto_field                 \
8702 _(src_port)                                     \
8703 _(dst_port)
8704
8705 #define foreach_udp_proto_field                 \
8706 _(src_port)                                     \
8707 _(dst_port)
8708
8709 #define foreach_ip4_proto_field                 \
8710 _(src_address)                                  \
8711 _(dst_address)                                  \
8712 _(tos)                                          \
8713 _(length)                                       \
8714 _(fragment_id)                                  \
8715 _(ttl)                                          \
8716 _(protocol)                                     \
8717 _(checksum)
8718
8719 uword
8720 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8721 {
8722   u8 **maskp = va_arg (*args, u8 **);
8723   u8 *mask = 0;
8724   u8 found_something = 0;
8725   tcp_header_t *tcp;
8726
8727 #define _(a) u8 a=0;
8728   foreach_tcp_proto_field;
8729 #undef _
8730
8731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8732     {
8733       if (0);
8734 #define _(a) else if (unformat (input, #a)) a=1;
8735       foreach_tcp_proto_field
8736 #undef _
8737         else
8738         break;
8739     }
8740
8741 #define _(a) found_something += a;
8742   foreach_tcp_proto_field;
8743 #undef _
8744
8745   if (found_something == 0)
8746     return 0;
8747
8748   vec_validate (mask, sizeof (*tcp) - 1);
8749
8750   tcp = (tcp_header_t *) mask;
8751
8752 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8753   foreach_tcp_proto_field;
8754 #undef _
8755
8756   *maskp = mask;
8757   return 1;
8758 }
8759
8760 uword
8761 unformat_udp_mask (unformat_input_t * input, va_list * args)
8762 {
8763   u8 **maskp = va_arg (*args, u8 **);
8764   u8 *mask = 0;
8765   u8 found_something = 0;
8766   udp_header_t *udp;
8767
8768 #define _(a) u8 a=0;
8769   foreach_udp_proto_field;
8770 #undef _
8771
8772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8773     {
8774       if (0);
8775 #define _(a) else if (unformat (input, #a)) a=1;
8776       foreach_udp_proto_field
8777 #undef _
8778         else
8779         break;
8780     }
8781
8782 #define _(a) found_something += a;
8783   foreach_udp_proto_field;
8784 #undef _
8785
8786   if (found_something == 0)
8787     return 0;
8788
8789   vec_validate (mask, sizeof (*udp) - 1);
8790
8791   udp = (udp_header_t *) mask;
8792
8793 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8794   foreach_udp_proto_field;
8795 #undef _
8796
8797   *maskp = mask;
8798   return 1;
8799 }
8800
8801 typedef struct
8802 {
8803   u16 src_port, dst_port;
8804 } tcpudp_header_t;
8805
8806 uword
8807 unformat_l4_mask (unformat_input_t * input, va_list * args)
8808 {
8809   u8 **maskp = va_arg (*args, u8 **);
8810   u16 src_port = 0, dst_port = 0;
8811   tcpudp_header_t *tcpudp;
8812
8813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8814     {
8815       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8816         return 1;
8817       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8818         return 1;
8819       else if (unformat (input, "src_port"))
8820         src_port = 0xFFFF;
8821       else if (unformat (input, "dst_port"))
8822         dst_port = 0xFFFF;
8823       else
8824         return 0;
8825     }
8826
8827   if (!src_port && !dst_port)
8828     return 0;
8829
8830   u8 *mask = 0;
8831   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8832
8833   tcpudp = (tcpudp_header_t *) mask;
8834   tcpudp->src_port = src_port;
8835   tcpudp->dst_port = dst_port;
8836
8837   *maskp = mask;
8838
8839   return 1;
8840 }
8841
8842 uword
8843 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8844 {
8845   u8 **maskp = va_arg (*args, u8 **);
8846   u8 *mask = 0;
8847   u8 found_something = 0;
8848   ip4_header_t *ip;
8849
8850 #define _(a) u8 a=0;
8851   foreach_ip4_proto_field;
8852 #undef _
8853   u8 version = 0;
8854   u8 hdr_length = 0;
8855
8856
8857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8858     {
8859       if (unformat (input, "version"))
8860         version = 1;
8861       else if (unformat (input, "hdr_length"))
8862         hdr_length = 1;
8863       else if (unformat (input, "src"))
8864         src_address = 1;
8865       else if (unformat (input, "dst"))
8866         dst_address = 1;
8867       else if (unformat (input, "proto"))
8868         protocol = 1;
8869
8870 #define _(a) else if (unformat (input, #a)) a=1;
8871       foreach_ip4_proto_field
8872 #undef _
8873         else
8874         break;
8875     }
8876
8877 #define _(a) found_something += a;
8878   foreach_ip4_proto_field;
8879 #undef _
8880
8881   if (found_something == 0)
8882     return 0;
8883
8884   vec_validate (mask, sizeof (*ip) - 1);
8885
8886   ip = (ip4_header_t *) mask;
8887
8888 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8889   foreach_ip4_proto_field;
8890 #undef _
8891
8892   ip->ip_version_and_header_length = 0;
8893
8894   if (version)
8895     ip->ip_version_and_header_length |= 0xF0;
8896
8897   if (hdr_length)
8898     ip->ip_version_and_header_length |= 0x0F;
8899
8900   *maskp = mask;
8901   return 1;
8902 }
8903
8904 #define foreach_ip6_proto_field                 \
8905 _(src_address)                                  \
8906 _(dst_address)                                  \
8907 _(payload_length)                               \
8908 _(hop_limit)                                    \
8909 _(protocol)
8910
8911 uword
8912 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8913 {
8914   u8 **maskp = va_arg (*args, u8 **);
8915   u8 *mask = 0;
8916   u8 found_something = 0;
8917   ip6_header_t *ip;
8918   u32 ip_version_traffic_class_and_flow_label;
8919
8920 #define _(a) u8 a=0;
8921   foreach_ip6_proto_field;
8922 #undef _
8923   u8 version = 0;
8924   u8 traffic_class = 0;
8925   u8 flow_label = 0;
8926
8927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8928     {
8929       if (unformat (input, "version"))
8930         version = 1;
8931       else if (unformat (input, "traffic-class"))
8932         traffic_class = 1;
8933       else if (unformat (input, "flow-label"))
8934         flow_label = 1;
8935       else if (unformat (input, "src"))
8936         src_address = 1;
8937       else if (unformat (input, "dst"))
8938         dst_address = 1;
8939       else if (unformat (input, "proto"))
8940         protocol = 1;
8941
8942 #define _(a) else if (unformat (input, #a)) a=1;
8943       foreach_ip6_proto_field
8944 #undef _
8945         else
8946         break;
8947     }
8948
8949 #define _(a) found_something += a;
8950   foreach_ip6_proto_field;
8951 #undef _
8952
8953   if (found_something == 0)
8954     return 0;
8955
8956   vec_validate (mask, sizeof (*ip) - 1);
8957
8958   ip = (ip6_header_t *) mask;
8959
8960 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8961   foreach_ip6_proto_field;
8962 #undef _
8963
8964   ip_version_traffic_class_and_flow_label = 0;
8965
8966   if (version)
8967     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8968
8969   if (traffic_class)
8970     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8971
8972   if (flow_label)
8973     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8974
8975   ip->ip_version_traffic_class_and_flow_label =
8976     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8977
8978   *maskp = mask;
8979   return 1;
8980 }
8981
8982 uword
8983 unformat_l3_mask (unformat_input_t * input, va_list * args)
8984 {
8985   u8 **maskp = va_arg (*args, u8 **);
8986
8987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8988     {
8989       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8990         return 1;
8991       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8992         return 1;
8993       else
8994         break;
8995     }
8996   return 0;
8997 }
8998
8999 uword
9000 unformat_l2_mask (unformat_input_t * input, va_list * args)
9001 {
9002   u8 **maskp = va_arg (*args, u8 **);
9003   u8 *mask = 0;
9004   u8 src = 0;
9005   u8 dst = 0;
9006   u8 proto = 0;
9007   u8 tag1 = 0;
9008   u8 tag2 = 0;
9009   u8 ignore_tag1 = 0;
9010   u8 ignore_tag2 = 0;
9011   u8 cos1 = 0;
9012   u8 cos2 = 0;
9013   u8 dot1q = 0;
9014   u8 dot1ad = 0;
9015   int len = 14;
9016
9017   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9018     {
9019       if (unformat (input, "src"))
9020         src = 1;
9021       else if (unformat (input, "dst"))
9022         dst = 1;
9023       else if (unformat (input, "proto"))
9024         proto = 1;
9025       else if (unformat (input, "tag1"))
9026         tag1 = 1;
9027       else if (unformat (input, "tag2"))
9028         tag2 = 1;
9029       else if (unformat (input, "ignore-tag1"))
9030         ignore_tag1 = 1;
9031       else if (unformat (input, "ignore-tag2"))
9032         ignore_tag2 = 1;
9033       else if (unformat (input, "cos1"))
9034         cos1 = 1;
9035       else if (unformat (input, "cos2"))
9036         cos2 = 1;
9037       else if (unformat (input, "dot1q"))
9038         dot1q = 1;
9039       else if (unformat (input, "dot1ad"))
9040         dot1ad = 1;
9041       else
9042         break;
9043     }
9044   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9045        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9046     return 0;
9047
9048   if (tag1 || ignore_tag1 || cos1 || dot1q)
9049     len = 18;
9050   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9051     len = 22;
9052
9053   vec_validate (mask, len - 1);
9054
9055   if (dst)
9056     memset (mask, 0xff, 6);
9057
9058   if (src)
9059     memset (mask + 6, 0xff, 6);
9060
9061   if (tag2 || dot1ad)
9062     {
9063       /* inner vlan tag */
9064       if (tag2)
9065         {
9066           mask[19] = 0xff;
9067           mask[18] = 0x0f;
9068         }
9069       if (cos2)
9070         mask[18] |= 0xe0;
9071       if (proto)
9072         mask[21] = mask[20] = 0xff;
9073       if (tag1)
9074         {
9075           mask[15] = 0xff;
9076           mask[14] = 0x0f;
9077         }
9078       if (cos1)
9079         mask[14] |= 0xe0;
9080       *maskp = mask;
9081       return 1;
9082     }
9083   if (tag1 | dot1q)
9084     {
9085       if (tag1)
9086         {
9087           mask[15] = 0xff;
9088           mask[14] = 0x0f;
9089         }
9090       if (cos1)
9091         mask[14] |= 0xe0;
9092       if (proto)
9093         mask[16] = mask[17] = 0xff;
9094
9095       *maskp = mask;
9096       return 1;
9097     }
9098   if (cos2)
9099     mask[18] |= 0xe0;
9100   if (cos1)
9101     mask[14] |= 0xe0;
9102   if (proto)
9103     mask[12] = mask[13] = 0xff;
9104
9105   *maskp = mask;
9106   return 1;
9107 }
9108
9109 uword
9110 unformat_classify_mask (unformat_input_t * input, va_list * args)
9111 {
9112   u8 **maskp = va_arg (*args, u8 **);
9113   u32 *skipp = va_arg (*args, u32 *);
9114   u32 *matchp = va_arg (*args, u32 *);
9115   u32 match;
9116   u8 *mask = 0;
9117   u8 *l2 = 0;
9118   u8 *l3 = 0;
9119   u8 *l4 = 0;
9120   int i;
9121
9122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9123     {
9124       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9125         ;
9126       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9127         ;
9128       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9129         ;
9130       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9131         ;
9132       else
9133         break;
9134     }
9135
9136   if (l4 && !l3)
9137     {
9138       vec_free (mask);
9139       vec_free (l2);
9140       vec_free (l4);
9141       return 0;
9142     }
9143
9144   if (mask || l2 || l3 || l4)
9145     {
9146       if (l2 || l3 || l4)
9147         {
9148           /* "With a free Ethernet header in every package" */
9149           if (l2 == 0)
9150             vec_validate (l2, 13);
9151           mask = l2;
9152           if (vec_len (l3))
9153             {
9154               vec_append (mask, l3);
9155               vec_free (l3);
9156             }
9157           if (vec_len (l4))
9158             {
9159               vec_append (mask, l4);
9160               vec_free (l4);
9161             }
9162         }
9163
9164       /* Scan forward looking for the first significant mask octet */
9165       for (i = 0; i < vec_len (mask); i++)
9166         if (mask[i])
9167           break;
9168
9169       /* compute (skip, match) params */
9170       *skipp = i / sizeof (u32x4);
9171       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9172
9173       /* Pad mask to an even multiple of the vector size */
9174       while (vec_len (mask) % sizeof (u32x4))
9175         vec_add1 (mask, 0);
9176
9177       match = vec_len (mask) / sizeof (u32x4);
9178
9179       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9180         {
9181           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9182           if (*tmp || *(tmp + 1))
9183             break;
9184           match--;
9185         }
9186       if (match == 0)
9187         clib_warning ("BUG: match 0");
9188
9189       _vec_len (mask) = match * sizeof (u32x4);
9190
9191       *matchp = match;
9192       *maskp = mask;
9193
9194       return 1;
9195     }
9196
9197   return 0;
9198 }
9199
9200 #define foreach_l2_next                         \
9201 _(drop, DROP)                                   \
9202 _(ethernet, ETHERNET_INPUT)                     \
9203 _(ip4, IP4_INPUT)                               \
9204 _(ip6, IP6_INPUT)
9205
9206 uword
9207 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9208 {
9209   u32 *miss_next_indexp = va_arg (*args, u32 *);
9210   u32 next_index = 0;
9211   u32 tmp;
9212
9213 #define _(n,N) \
9214   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9215   foreach_l2_next;
9216 #undef _
9217
9218   if (unformat (input, "%d", &tmp))
9219     {
9220       next_index = tmp;
9221       goto out;
9222     }
9223
9224   return 0;
9225
9226 out:
9227   *miss_next_indexp = next_index;
9228   return 1;
9229 }
9230
9231 #define foreach_ip_next                         \
9232 _(drop, DROP)                                   \
9233 _(local, LOCAL)                                 \
9234 _(rewrite, REWRITE)
9235
9236 uword
9237 unformat_ip_next_index (unformat_input_t * input, va_list * args)
9238 {
9239   u32 *miss_next_indexp = va_arg (*args, u32 *);
9240   u32 next_index = 0;
9241   u32 tmp;
9242
9243 #define _(n,N) \
9244   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9245   foreach_ip_next;
9246 #undef _
9247
9248   if (unformat (input, "%d", &tmp))
9249     {
9250       next_index = tmp;
9251       goto out;
9252     }
9253
9254   return 0;
9255
9256 out:
9257   *miss_next_indexp = next_index;
9258   return 1;
9259 }
9260
9261 #define foreach_acl_next                        \
9262 _(deny, DENY)
9263
9264 uword
9265 unformat_acl_next_index (unformat_input_t * input, va_list * args)
9266 {
9267   u32 *miss_next_indexp = va_arg (*args, u32 *);
9268   u32 next_index = 0;
9269   u32 tmp;
9270
9271 #define _(n,N) \
9272   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9273   foreach_acl_next;
9274 #undef _
9275
9276   if (unformat (input, "permit"))
9277     {
9278       next_index = ~0;
9279       goto out;
9280     }
9281   else if (unformat (input, "%d", &tmp))
9282     {
9283       next_index = tmp;
9284       goto out;
9285     }
9286
9287   return 0;
9288
9289 out:
9290   *miss_next_indexp = next_index;
9291   return 1;
9292 }
9293
9294 uword
9295 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9296 {
9297   u32 *r = va_arg (*args, u32 *);
9298
9299   if (unformat (input, "conform-color"))
9300     *r = POLICE_CONFORM;
9301   else if (unformat (input, "exceed-color"))
9302     *r = POLICE_EXCEED;
9303   else
9304     return 0;
9305
9306   return 1;
9307 }
9308
9309 static int
9310 api_classify_add_del_table (vat_main_t * vam)
9311 {
9312   unformat_input_t *i = vam->input;
9313   vl_api_classify_add_del_table_t *mp;
9314
9315   u32 nbuckets = 2;
9316   u32 skip = ~0;
9317   u32 match = ~0;
9318   int is_add = 1;
9319   int del_chain = 0;
9320   u32 table_index = ~0;
9321   u32 next_table_index = ~0;
9322   u32 miss_next_index = ~0;
9323   u32 memory_size = 32 << 20;
9324   u8 *mask = 0;
9325   f64 timeout;
9326   u32 current_data_flag = 0;
9327   int current_data_offset = 0;
9328
9329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9330     {
9331       if (unformat (i, "del"))
9332         is_add = 0;
9333       else if (unformat (i, "del-chain"))
9334         {
9335           is_add = 0;
9336           del_chain = 1;
9337         }
9338       else if (unformat (i, "buckets %d", &nbuckets))
9339         ;
9340       else if (unformat (i, "memory_size %d", &memory_size))
9341         ;
9342       else if (unformat (i, "skip %d", &skip))
9343         ;
9344       else if (unformat (i, "match %d", &match))
9345         ;
9346       else if (unformat (i, "table %d", &table_index))
9347         ;
9348       else if (unformat (i, "mask %U", unformat_classify_mask,
9349                          &mask, &skip, &match))
9350         ;
9351       else if (unformat (i, "next-table %d", &next_table_index))
9352         ;
9353       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
9354                          &miss_next_index))
9355         ;
9356       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9357                          &miss_next_index))
9358         ;
9359       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9360                          &miss_next_index))
9361         ;
9362       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9363         ;
9364       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9365         ;
9366       else
9367         break;
9368     }
9369
9370   if (is_add && mask == 0)
9371     {
9372       errmsg ("Mask required");
9373       return -99;
9374     }
9375
9376   if (is_add && skip == ~0)
9377     {
9378       errmsg ("skip count required");
9379       return -99;
9380     }
9381
9382   if (is_add && match == ~0)
9383     {
9384       errmsg ("match count required");
9385       return -99;
9386     }
9387
9388   if (!is_add && table_index == ~0)
9389     {
9390       errmsg ("table index required for delete");
9391       return -99;
9392     }
9393
9394   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
9395
9396   mp->is_add = is_add;
9397   mp->del_chain = del_chain;
9398   mp->table_index = ntohl (table_index);
9399   mp->nbuckets = ntohl (nbuckets);
9400   mp->memory_size = ntohl (memory_size);
9401   mp->skip_n_vectors = ntohl (skip);
9402   mp->match_n_vectors = ntohl (match);
9403   mp->next_table_index = ntohl (next_table_index);
9404   mp->miss_next_index = ntohl (miss_next_index);
9405   mp->current_data_flag = ntohl (current_data_flag);
9406   mp->current_data_offset = ntohl (current_data_offset);
9407   clib_memcpy (mp->mask, mask, vec_len (mask));
9408
9409   vec_free (mask);
9410
9411   S;
9412   W;
9413   /* NOTREACHED */
9414 }
9415
9416 uword
9417 unformat_l4_match (unformat_input_t * input, va_list * args)
9418 {
9419   u8 **matchp = va_arg (*args, u8 **);
9420
9421   u8 *proto_header = 0;
9422   int src_port = 0;
9423   int dst_port = 0;
9424
9425   tcpudp_header_t h;
9426
9427   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9428     {
9429       if (unformat (input, "src_port %d", &src_port))
9430         ;
9431       else if (unformat (input, "dst_port %d", &dst_port))
9432         ;
9433       else
9434         return 0;
9435     }
9436
9437   h.src_port = clib_host_to_net_u16 (src_port);
9438   h.dst_port = clib_host_to_net_u16 (dst_port);
9439   vec_validate (proto_header, sizeof (h) - 1);
9440   memcpy (proto_header, &h, sizeof (h));
9441
9442   *matchp = proto_header;
9443
9444   return 1;
9445 }
9446
9447 uword
9448 unformat_ip4_match (unformat_input_t * input, va_list * args)
9449 {
9450   u8 **matchp = va_arg (*args, u8 **);
9451   u8 *match = 0;
9452   ip4_header_t *ip;
9453   int version = 0;
9454   u32 version_val;
9455   int hdr_length = 0;
9456   u32 hdr_length_val;
9457   int src = 0, dst = 0;
9458   ip4_address_t src_val, dst_val;
9459   int proto = 0;
9460   u32 proto_val;
9461   int tos = 0;
9462   u32 tos_val;
9463   int length = 0;
9464   u32 length_val;
9465   int fragment_id = 0;
9466   u32 fragment_id_val;
9467   int ttl = 0;
9468   int ttl_val;
9469   int checksum = 0;
9470   u32 checksum_val;
9471
9472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9473     {
9474       if (unformat (input, "version %d", &version_val))
9475         version = 1;
9476       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9477         hdr_length = 1;
9478       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9479         src = 1;
9480       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9481         dst = 1;
9482       else if (unformat (input, "proto %d", &proto_val))
9483         proto = 1;
9484       else if (unformat (input, "tos %d", &tos_val))
9485         tos = 1;
9486       else if (unformat (input, "length %d", &length_val))
9487         length = 1;
9488       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9489         fragment_id = 1;
9490       else if (unformat (input, "ttl %d", &ttl_val))
9491         ttl = 1;
9492       else if (unformat (input, "checksum %d", &checksum_val))
9493         checksum = 1;
9494       else
9495         break;
9496     }
9497
9498   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9499       + ttl + checksum == 0)
9500     return 0;
9501
9502   /*
9503    * Aligned because we use the real comparison functions
9504    */
9505   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9506
9507   ip = (ip4_header_t *) match;
9508
9509   /* These are realistically matched in practice */
9510   if (src)
9511     ip->src_address.as_u32 = src_val.as_u32;
9512
9513   if (dst)
9514     ip->dst_address.as_u32 = dst_val.as_u32;
9515
9516   if (proto)
9517     ip->protocol = proto_val;
9518
9519
9520   /* These are not, but they're included for completeness */
9521   if (version)
9522     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9523
9524   if (hdr_length)
9525     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9526
9527   if (tos)
9528     ip->tos = tos_val;
9529
9530   if (length)
9531     ip->length = clib_host_to_net_u16 (length_val);
9532
9533   if (ttl)
9534     ip->ttl = ttl_val;
9535
9536   if (checksum)
9537     ip->checksum = clib_host_to_net_u16 (checksum_val);
9538
9539   *matchp = match;
9540   return 1;
9541 }
9542
9543 uword
9544 unformat_ip6_match (unformat_input_t * input, va_list * args)
9545 {
9546   u8 **matchp = va_arg (*args, u8 **);
9547   u8 *match = 0;
9548   ip6_header_t *ip;
9549   int version = 0;
9550   u32 version_val;
9551   u8 traffic_class = 0;
9552   u32 traffic_class_val = 0;
9553   u8 flow_label = 0;
9554   u8 flow_label_val;
9555   int src = 0, dst = 0;
9556   ip6_address_t src_val, dst_val;
9557   int proto = 0;
9558   u32 proto_val;
9559   int payload_length = 0;
9560   u32 payload_length_val;
9561   int hop_limit = 0;
9562   int hop_limit_val;
9563   u32 ip_version_traffic_class_and_flow_label;
9564
9565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9566     {
9567       if (unformat (input, "version %d", &version_val))
9568         version = 1;
9569       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9570         traffic_class = 1;
9571       else if (unformat (input, "flow_label %d", &flow_label_val))
9572         flow_label = 1;
9573       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9574         src = 1;
9575       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9576         dst = 1;
9577       else if (unformat (input, "proto %d", &proto_val))
9578         proto = 1;
9579       else if (unformat (input, "payload_length %d", &payload_length_val))
9580         payload_length = 1;
9581       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9582         hop_limit = 1;
9583       else
9584         break;
9585     }
9586
9587   if (version + traffic_class + flow_label + src + dst + proto +
9588       payload_length + hop_limit == 0)
9589     return 0;
9590
9591   /*
9592    * Aligned because we use the real comparison functions
9593    */
9594   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9595
9596   ip = (ip6_header_t *) match;
9597
9598   if (src)
9599     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9600
9601   if (dst)
9602     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9603
9604   if (proto)
9605     ip->protocol = proto_val;
9606
9607   ip_version_traffic_class_and_flow_label = 0;
9608
9609   if (version)
9610     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9611
9612   if (traffic_class)
9613     ip_version_traffic_class_and_flow_label |=
9614       (traffic_class_val & 0xFF) << 20;
9615
9616   if (flow_label)
9617     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9618
9619   ip->ip_version_traffic_class_and_flow_label =
9620     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9621
9622   if (payload_length)
9623     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9624
9625   if (hop_limit)
9626     ip->hop_limit = hop_limit_val;
9627
9628   *matchp = match;
9629   return 1;
9630 }
9631
9632 uword
9633 unformat_l3_match (unformat_input_t * input, va_list * args)
9634 {
9635   u8 **matchp = va_arg (*args, u8 **);
9636
9637   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9638     {
9639       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9640         return 1;
9641       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9642         return 1;
9643       else
9644         break;
9645     }
9646   return 0;
9647 }
9648
9649 uword
9650 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9651 {
9652   u8 *tagp = va_arg (*args, u8 *);
9653   u32 tag;
9654
9655   if (unformat (input, "%d", &tag))
9656     {
9657       tagp[0] = (tag >> 8) & 0x0F;
9658       tagp[1] = tag & 0xFF;
9659       return 1;
9660     }
9661
9662   return 0;
9663 }
9664
9665 uword
9666 unformat_l2_match (unformat_input_t * input, va_list * args)
9667 {
9668   u8 **matchp = va_arg (*args, u8 **);
9669   u8 *match = 0;
9670   u8 src = 0;
9671   u8 src_val[6];
9672   u8 dst = 0;
9673   u8 dst_val[6];
9674   u8 proto = 0;
9675   u16 proto_val;
9676   u8 tag1 = 0;
9677   u8 tag1_val[2];
9678   u8 tag2 = 0;
9679   u8 tag2_val[2];
9680   int len = 14;
9681   u8 ignore_tag1 = 0;
9682   u8 ignore_tag2 = 0;
9683   u8 cos1 = 0;
9684   u8 cos2 = 0;
9685   u32 cos1_val = 0;
9686   u32 cos2_val = 0;
9687
9688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9689     {
9690       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9691         src = 1;
9692       else
9693         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9694         dst = 1;
9695       else if (unformat (input, "proto %U",
9696                          unformat_ethernet_type_host_byte_order, &proto_val))
9697         proto = 1;
9698       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9699         tag1 = 1;
9700       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9701         tag2 = 1;
9702       else if (unformat (input, "ignore-tag1"))
9703         ignore_tag1 = 1;
9704       else if (unformat (input, "ignore-tag2"))
9705         ignore_tag2 = 1;
9706       else if (unformat (input, "cos1 %d", &cos1_val))
9707         cos1 = 1;
9708       else if (unformat (input, "cos2 %d", &cos2_val))
9709         cos2 = 1;
9710       else
9711         break;
9712     }
9713   if ((src + dst + proto + tag1 + tag2 +
9714        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9715     return 0;
9716
9717   if (tag1 || ignore_tag1 || cos1)
9718     len = 18;
9719   if (tag2 || ignore_tag2 || cos2)
9720     len = 22;
9721
9722   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9723
9724   if (dst)
9725     clib_memcpy (match, dst_val, 6);
9726
9727   if (src)
9728     clib_memcpy (match + 6, src_val, 6);
9729
9730   if (tag2)
9731     {
9732       /* inner vlan tag */
9733       match[19] = tag2_val[1];
9734       match[18] = tag2_val[0];
9735       if (cos2)
9736         match[18] |= (cos2_val & 0x7) << 5;
9737       if (proto)
9738         {
9739           match[21] = proto_val & 0xff;
9740           match[20] = proto_val >> 8;
9741         }
9742       if (tag1)
9743         {
9744           match[15] = tag1_val[1];
9745           match[14] = tag1_val[0];
9746         }
9747       if (cos1)
9748         match[14] |= (cos1_val & 0x7) << 5;
9749       *matchp = match;
9750       return 1;
9751     }
9752   if (tag1)
9753     {
9754       match[15] = tag1_val[1];
9755       match[14] = tag1_val[0];
9756       if (proto)
9757         {
9758           match[17] = proto_val & 0xff;
9759           match[16] = proto_val >> 8;
9760         }
9761       if (cos1)
9762         match[14] |= (cos1_val & 0x7) << 5;
9763
9764       *matchp = match;
9765       return 1;
9766     }
9767   if (cos2)
9768     match[18] |= (cos2_val & 0x7) << 5;
9769   if (cos1)
9770     match[14] |= (cos1_val & 0x7) << 5;
9771   if (proto)
9772     {
9773       match[13] = proto_val & 0xff;
9774       match[12] = proto_val >> 8;
9775     }
9776
9777   *matchp = match;
9778   return 1;
9779 }
9780
9781
9782 uword
9783 unformat_classify_match (unformat_input_t * input, va_list * args)
9784 {
9785   u8 **matchp = va_arg (*args, u8 **);
9786   u32 skip_n_vectors = va_arg (*args, u32);
9787   u32 match_n_vectors = va_arg (*args, u32);
9788
9789   u8 *match = 0;
9790   u8 *l2 = 0;
9791   u8 *l3 = 0;
9792   u8 *l4 = 0;
9793
9794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9795     {
9796       if (unformat (input, "hex %U", unformat_hex_string, &match))
9797         ;
9798       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9799         ;
9800       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9801         ;
9802       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9803         ;
9804       else
9805         break;
9806     }
9807
9808   if (l4 && !l3)
9809     {
9810       vec_free (match);
9811       vec_free (l2);
9812       vec_free (l4);
9813       return 0;
9814     }
9815
9816   if (match || l2 || l3 || l4)
9817     {
9818       if (l2 || l3 || l4)
9819         {
9820           /* "Win a free Ethernet header in every packet" */
9821           if (l2 == 0)
9822             vec_validate_aligned (l2, 13, sizeof (u32x4));
9823           match = l2;
9824           if (vec_len (l3))
9825             {
9826               vec_append_aligned (match, l3, sizeof (u32x4));
9827               vec_free (l3);
9828             }
9829           if (vec_len (l4))
9830             {
9831               vec_append_aligned (match, l4, sizeof (u32x4));
9832               vec_free (l4);
9833             }
9834         }
9835
9836       /* Make sure the vector is big enough even if key is all 0's */
9837       vec_validate_aligned
9838         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9839          sizeof (u32x4));
9840
9841       /* Set size, include skipped vectors */
9842       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9843
9844       *matchp = match;
9845
9846       return 1;
9847     }
9848
9849   return 0;
9850 }
9851
9852 static int
9853 api_classify_add_del_session (vat_main_t * vam)
9854 {
9855   unformat_input_t *i = vam->input;
9856   vl_api_classify_add_del_session_t *mp;
9857   int is_add = 1;
9858   u32 table_index = ~0;
9859   u32 hit_next_index = ~0;
9860   u32 opaque_index = ~0;
9861   u8 *match = 0;
9862   i32 advance = 0;
9863   f64 timeout;
9864   u32 skip_n_vectors = 0;
9865   u32 match_n_vectors = 0;
9866   u32 action = 0;
9867   u32 metadata = 0;
9868
9869   /*
9870    * Warning: you have to supply skip_n and match_n
9871    * because the API client cant simply look at the classify
9872    * table object.
9873    */
9874
9875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9876     {
9877       if (unformat (i, "del"))
9878         is_add = 0;
9879       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9880                          &hit_next_index))
9881         ;
9882       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9883                          &hit_next_index))
9884         ;
9885       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9886                          &hit_next_index))
9887         ;
9888       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9889         ;
9890       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9891         ;
9892       else if (unformat (i, "opaque-index %d", &opaque_index))
9893         ;
9894       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9895         ;
9896       else if (unformat (i, "match_n %d", &match_n_vectors))
9897         ;
9898       else if (unformat (i, "match %U", unformat_classify_match,
9899                          &match, skip_n_vectors, match_n_vectors))
9900         ;
9901       else if (unformat (i, "advance %d", &advance))
9902         ;
9903       else if (unformat (i, "table-index %d", &table_index))
9904         ;
9905       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9906         action = 1;
9907       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9908         action = 2;
9909       else if (unformat (i, "action %d", &action))
9910         ;
9911       else if (unformat (i, "metadata %d", &metadata))
9912         ;
9913       else
9914         break;
9915     }
9916
9917   if (table_index == ~0)
9918     {
9919       errmsg ("Table index required");
9920       return -99;
9921     }
9922
9923   if (is_add && match == 0)
9924     {
9925       errmsg ("Match value required");
9926       return -99;
9927     }
9928
9929   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9930
9931   mp->is_add = is_add;
9932   mp->table_index = ntohl (table_index);
9933   mp->hit_next_index = ntohl (hit_next_index);
9934   mp->opaque_index = ntohl (opaque_index);
9935   mp->advance = ntohl (advance);
9936   mp->action = action;
9937   mp->metadata = ntohl (metadata);
9938   clib_memcpy (mp->match, match, vec_len (match));
9939   vec_free (match);
9940
9941   S;
9942   W;
9943   /* NOTREACHED */
9944 }
9945
9946 static int
9947 api_classify_set_interface_ip_table (vat_main_t * vam)
9948 {
9949   unformat_input_t *i = vam->input;
9950   vl_api_classify_set_interface_ip_table_t *mp;
9951   f64 timeout;
9952   u32 sw_if_index;
9953   int sw_if_index_set;
9954   u32 table_index = ~0;
9955   u8 is_ipv6 = 0;
9956
9957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9958     {
9959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9960         sw_if_index_set = 1;
9961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9962         sw_if_index_set = 1;
9963       else if (unformat (i, "table %d", &table_index))
9964         ;
9965       else
9966         {
9967           clib_warning ("parse error '%U'", format_unformat_error, i);
9968           return -99;
9969         }
9970     }
9971
9972   if (sw_if_index_set == 0)
9973     {
9974       errmsg ("missing interface name or sw_if_index");
9975       return -99;
9976     }
9977
9978
9979   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9980
9981   mp->sw_if_index = ntohl (sw_if_index);
9982   mp->table_index = ntohl (table_index);
9983   mp->is_ipv6 = is_ipv6;
9984
9985   S;
9986   W;
9987   /* NOTREACHED */
9988   return 0;
9989 }
9990
9991 static int
9992 api_classify_set_interface_l2_tables (vat_main_t * vam)
9993 {
9994   unformat_input_t *i = vam->input;
9995   vl_api_classify_set_interface_l2_tables_t *mp;
9996   f64 timeout;
9997   u32 sw_if_index;
9998   int sw_if_index_set;
9999   u32 ip4_table_index = ~0;
10000   u32 ip6_table_index = ~0;
10001   u32 other_table_index = ~0;
10002   u32 is_input = 1;
10003
10004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10005     {
10006       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10007         sw_if_index_set = 1;
10008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10009         sw_if_index_set = 1;
10010       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10011         ;
10012       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10013         ;
10014       else if (unformat (i, "other-table %d", &other_table_index))
10015         ;
10016       else if (unformat (i, "is-input %d", &is_input))
10017         ;
10018       else
10019         {
10020           clib_warning ("parse error '%U'", format_unformat_error, i);
10021           return -99;
10022         }
10023     }
10024
10025   if (sw_if_index_set == 0)
10026     {
10027       errmsg ("missing interface name or sw_if_index");
10028       return -99;
10029     }
10030
10031
10032   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
10033
10034   mp->sw_if_index = ntohl (sw_if_index);
10035   mp->ip4_table_index = ntohl (ip4_table_index);
10036   mp->ip6_table_index = ntohl (ip6_table_index);
10037   mp->other_table_index = ntohl (other_table_index);
10038   mp->is_input = (u8) is_input;
10039
10040   S;
10041   W;
10042   /* NOTREACHED */
10043   return 0;
10044 }
10045
10046 static int
10047 api_set_ipfix_exporter (vat_main_t * vam)
10048 {
10049   unformat_input_t *i = vam->input;
10050   vl_api_set_ipfix_exporter_t *mp;
10051   ip4_address_t collector_address;
10052   u8 collector_address_set = 0;
10053   u32 collector_port = ~0;
10054   ip4_address_t src_address;
10055   u8 src_address_set = 0;
10056   u32 vrf_id = ~0;
10057   u32 path_mtu = ~0;
10058   u32 template_interval = ~0;
10059   u8 udp_checksum = 0;
10060   f64 timeout;
10061
10062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10063     {
10064       if (unformat (i, "collector_address %U", unformat_ip4_address,
10065                     &collector_address))
10066         collector_address_set = 1;
10067       else if (unformat (i, "collector_port %d", &collector_port))
10068         ;
10069       else if (unformat (i, "src_address %U", unformat_ip4_address,
10070                          &src_address))
10071         src_address_set = 1;
10072       else if (unformat (i, "vrf_id %d", &vrf_id))
10073         ;
10074       else if (unformat (i, "path_mtu %d", &path_mtu))
10075         ;
10076       else if (unformat (i, "template_interval %d", &template_interval))
10077         ;
10078       else if (unformat (i, "udp_checksum"))
10079         udp_checksum = 1;
10080       else
10081         break;
10082     }
10083
10084   if (collector_address_set == 0)
10085     {
10086       errmsg ("collector_address required");
10087       return -99;
10088     }
10089
10090   if (src_address_set == 0)
10091     {
10092       errmsg ("src_address required");
10093       return -99;
10094     }
10095
10096   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
10097
10098   memcpy (mp->collector_address, collector_address.data,
10099           sizeof (collector_address.data));
10100   mp->collector_port = htons ((u16) collector_port);
10101   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10102   mp->vrf_id = htonl (vrf_id);
10103   mp->path_mtu = htonl (path_mtu);
10104   mp->template_interval = htonl (template_interval);
10105   mp->udp_checksum = udp_checksum;
10106
10107   S;
10108   W;
10109   /* NOTREACHED */
10110 }
10111
10112 static int
10113 api_set_ipfix_classify_stream (vat_main_t * vam)
10114 {
10115   unformat_input_t *i = vam->input;
10116   vl_api_set_ipfix_classify_stream_t *mp;
10117   u32 domain_id = 0;
10118   u32 src_port = UDP_DST_PORT_ipfix;
10119   f64 timeout;
10120
10121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10122     {
10123       if (unformat (i, "domain %d", &domain_id))
10124         ;
10125       else if (unformat (i, "src_port %d", &src_port))
10126         ;
10127       else
10128         {
10129           errmsg ("unknown input `%U'", format_unformat_error, i);
10130           return -99;
10131         }
10132     }
10133
10134   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
10135
10136   mp->domain_id = htonl (domain_id);
10137   mp->src_port = htons ((u16) src_port);
10138
10139   S;
10140   W;
10141   /* NOTREACHED */
10142 }
10143
10144 static int
10145 api_ipfix_classify_table_add_del (vat_main_t * vam)
10146 {
10147   unformat_input_t *i = vam->input;
10148   vl_api_ipfix_classify_table_add_del_t *mp;
10149   int is_add = -1;
10150   u32 classify_table_index = ~0;
10151   u8 ip_version = 0;
10152   u8 transport_protocol = 255;
10153   f64 timeout;
10154
10155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10156     {
10157       if (unformat (i, "add"))
10158         is_add = 1;
10159       else if (unformat (i, "del"))
10160         is_add = 0;
10161       else if (unformat (i, "table %d", &classify_table_index))
10162         ;
10163       else if (unformat (i, "ip4"))
10164         ip_version = 4;
10165       else if (unformat (i, "ip6"))
10166         ip_version = 6;
10167       else if (unformat (i, "tcp"))
10168         transport_protocol = 6;
10169       else if (unformat (i, "udp"))
10170         transport_protocol = 17;
10171       else
10172         {
10173           errmsg ("unknown input `%U'", format_unformat_error, i);
10174           return -99;
10175         }
10176     }
10177
10178   if (is_add == -1)
10179     {
10180       errmsg ("expecting: add|del");
10181       return -99;
10182     }
10183   if (classify_table_index == ~0)
10184     {
10185       errmsg ("classifier table not specified");
10186       return -99;
10187     }
10188   if (ip_version == 0)
10189     {
10190       errmsg ("IP version not specified");
10191       return -99;
10192     }
10193
10194   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
10195
10196   mp->is_add = is_add;
10197   mp->table_id = htonl (classify_table_index);
10198   mp->ip_version = ip_version;
10199   mp->transport_protocol = transport_protocol;
10200
10201   S;
10202   W;
10203   /* NOTREACHED */
10204 }
10205
10206 static int
10207 api_get_node_index (vat_main_t * vam)
10208 {
10209   unformat_input_t *i = vam->input;
10210   vl_api_get_node_index_t *mp;
10211   f64 timeout;
10212   u8 *name = 0;
10213
10214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10215     {
10216       if (unformat (i, "node %s", &name))
10217         ;
10218       else
10219         break;
10220     }
10221   if (name == 0)
10222     {
10223       errmsg ("node name required");
10224       return -99;
10225     }
10226   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10227     {
10228       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10229       return -99;
10230     }
10231
10232   M (GET_NODE_INDEX, get_node_index);
10233   clib_memcpy (mp->node_name, name, vec_len (name));
10234   vec_free (name);
10235
10236   S;
10237   W;
10238   /* NOTREACHED */
10239   return 0;
10240 }
10241
10242 static int
10243 api_get_next_index (vat_main_t * vam)
10244 {
10245   unformat_input_t *i = vam->input;
10246   vl_api_get_next_index_t *mp;
10247   f64 timeout;
10248   u8 *node_name = 0, *next_node_name = 0;
10249
10250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10251     {
10252       if (unformat (i, "node-name %s", &node_name))
10253         ;
10254       else if (unformat (i, "next-node-name %s", &next_node_name))
10255         break;
10256     }
10257
10258   if (node_name == 0)
10259     {
10260       errmsg ("node name required");
10261       return -99;
10262     }
10263   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10264     {
10265       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10266       return -99;
10267     }
10268
10269   if (next_node_name == 0)
10270     {
10271       errmsg ("next node name required");
10272       return -99;
10273     }
10274   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10275     {
10276       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10277       return -99;
10278     }
10279
10280   M (GET_NEXT_INDEX, get_next_index);
10281   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10282   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10283   vec_free (node_name);
10284   vec_free (next_node_name);
10285
10286   S;
10287   W;
10288   /* NOTREACHED */
10289   return 0;
10290 }
10291
10292 static int
10293 api_add_node_next (vat_main_t * vam)
10294 {
10295   unformat_input_t *i = vam->input;
10296   vl_api_add_node_next_t *mp;
10297   f64 timeout;
10298   u8 *name = 0;
10299   u8 *next = 0;
10300
10301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10302     {
10303       if (unformat (i, "node %s", &name))
10304         ;
10305       else if (unformat (i, "next %s", &next))
10306         ;
10307       else
10308         break;
10309     }
10310   if (name == 0)
10311     {
10312       errmsg ("node name required");
10313       return -99;
10314     }
10315   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10316     {
10317       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10318       return -99;
10319     }
10320   if (next == 0)
10321     {
10322       errmsg ("next node required");
10323       return -99;
10324     }
10325   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10326     {
10327       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10328       return -99;
10329     }
10330
10331   M (ADD_NODE_NEXT, add_node_next);
10332   clib_memcpy (mp->node_name, name, vec_len (name));
10333   clib_memcpy (mp->next_name, next, vec_len (next));
10334   vec_free (name);
10335   vec_free (next);
10336
10337   S;
10338   W;
10339   /* NOTREACHED */
10340   return 0;
10341 }
10342
10343 static int
10344 api_l2tpv3_create_tunnel (vat_main_t * vam)
10345 {
10346   unformat_input_t *i = vam->input;
10347   ip6_address_t client_address, our_address;
10348   int client_address_set = 0;
10349   int our_address_set = 0;
10350   u32 local_session_id = 0;
10351   u32 remote_session_id = 0;
10352   u64 local_cookie = 0;
10353   u64 remote_cookie = 0;
10354   u8 l2_sublayer_present = 0;
10355   vl_api_l2tpv3_create_tunnel_t *mp;
10356   f64 timeout;
10357
10358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10359     {
10360       if (unformat (i, "client_address %U", unformat_ip6_address,
10361                     &client_address))
10362         client_address_set = 1;
10363       else if (unformat (i, "our_address %U", unformat_ip6_address,
10364                          &our_address))
10365         our_address_set = 1;
10366       else if (unformat (i, "local_session_id %d", &local_session_id))
10367         ;
10368       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10369         ;
10370       else if (unformat (i, "local_cookie %lld", &local_cookie))
10371         ;
10372       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10373         ;
10374       else if (unformat (i, "l2-sublayer-present"))
10375         l2_sublayer_present = 1;
10376       else
10377         break;
10378     }
10379
10380   if (client_address_set == 0)
10381     {
10382       errmsg ("client_address required");
10383       return -99;
10384     }
10385
10386   if (our_address_set == 0)
10387     {
10388       errmsg ("our_address required");
10389       return -99;
10390     }
10391
10392   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
10393
10394   clib_memcpy (mp->client_address, client_address.as_u8,
10395                sizeof (mp->client_address));
10396
10397   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10398
10399   mp->local_session_id = ntohl (local_session_id);
10400   mp->remote_session_id = ntohl (remote_session_id);
10401   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10402   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10403   mp->l2_sublayer_present = l2_sublayer_present;
10404   mp->is_ipv6 = 1;
10405
10406   S;
10407   W;
10408   /* NOTREACHED */
10409   return 0;
10410 }
10411
10412 static int
10413 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10414 {
10415   unformat_input_t *i = vam->input;
10416   u32 sw_if_index;
10417   u8 sw_if_index_set = 0;
10418   u64 new_local_cookie = 0;
10419   u64 new_remote_cookie = 0;
10420   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10421   f64 timeout;
10422
10423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10424     {
10425       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10426         sw_if_index_set = 1;
10427       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10428         sw_if_index_set = 1;
10429       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10430         ;
10431       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10432         ;
10433       else
10434         break;
10435     }
10436
10437   if (sw_if_index_set == 0)
10438     {
10439       errmsg ("missing interface name or sw_if_index");
10440       return -99;
10441     }
10442
10443   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10444
10445   mp->sw_if_index = ntohl (sw_if_index);
10446   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10447   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10448
10449   S;
10450   W;
10451   /* NOTREACHED */
10452   return 0;
10453 }
10454
10455 static int
10456 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10457 {
10458   unformat_input_t *i = vam->input;
10459   vl_api_l2tpv3_interface_enable_disable_t *mp;
10460   f64 timeout;
10461   u32 sw_if_index;
10462   u8 sw_if_index_set = 0;
10463   u8 enable_disable = 1;
10464
10465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10466     {
10467       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10468         sw_if_index_set = 1;
10469       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10470         sw_if_index_set = 1;
10471       else if (unformat (i, "enable"))
10472         enable_disable = 1;
10473       else if (unformat (i, "disable"))
10474         enable_disable = 0;
10475       else
10476         break;
10477     }
10478
10479   if (sw_if_index_set == 0)
10480     {
10481       errmsg ("missing interface name or sw_if_index");
10482       return -99;
10483     }
10484
10485   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10486
10487   mp->sw_if_index = ntohl (sw_if_index);
10488   mp->enable_disable = enable_disable;
10489
10490   S;
10491   W;
10492   /* NOTREACHED */
10493   return 0;
10494 }
10495
10496 static int
10497 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10498 {
10499   unformat_input_t *i = vam->input;
10500   vl_api_l2tpv3_set_lookup_key_t *mp;
10501   f64 timeout;
10502   u8 key = ~0;
10503
10504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10505     {
10506       if (unformat (i, "lookup_v6_src"))
10507         key = L2T_LOOKUP_SRC_ADDRESS;
10508       else if (unformat (i, "lookup_v6_dst"))
10509         key = L2T_LOOKUP_DST_ADDRESS;
10510       else if (unformat (i, "lookup_session_id"))
10511         key = L2T_LOOKUP_SESSION_ID;
10512       else
10513         break;
10514     }
10515
10516   if (key == (u8) ~ 0)
10517     {
10518       errmsg ("l2tp session lookup key unset");
10519       return -99;
10520     }
10521
10522   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10523
10524   mp->key = key;
10525
10526   S;
10527   W;
10528   /* NOTREACHED */
10529   return 0;
10530 }
10531
10532 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10533   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10534 {
10535   vat_main_t *vam = &vat_main;
10536
10537   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10538          format_ip6_address, mp->our_address,
10539          format_ip6_address, mp->client_address,
10540          clib_net_to_host_u32 (mp->sw_if_index));
10541
10542   print (vam->ofp,
10543          "   local cookies %016llx %016llx remote cookie %016llx",
10544          clib_net_to_host_u64 (mp->local_cookie[0]),
10545          clib_net_to_host_u64 (mp->local_cookie[1]),
10546          clib_net_to_host_u64 (mp->remote_cookie));
10547
10548   print (vam->ofp, "   local session-id %d remote session-id %d",
10549          clib_net_to_host_u32 (mp->local_session_id),
10550          clib_net_to_host_u32 (mp->remote_session_id));
10551
10552   print (vam->ofp, "   l2 specific sublayer %s\n",
10553          mp->l2_sublayer_present ? "preset" : "absent");
10554
10555 }
10556
10557 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10558   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10559 {
10560   vat_main_t *vam = &vat_main;
10561   vat_json_node_t *node = NULL;
10562   struct in6_addr addr;
10563
10564   if (VAT_JSON_ARRAY != vam->json_tree.type)
10565     {
10566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10567       vat_json_init_array (&vam->json_tree);
10568     }
10569   node = vat_json_array_add (&vam->json_tree);
10570
10571   vat_json_init_object (node);
10572
10573   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10574   vat_json_object_add_ip6 (node, "our_address", addr);
10575   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10576   vat_json_object_add_ip6 (node, "client_address", addr);
10577
10578   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10579   vat_json_init_array (lc);
10580   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10581   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10582   vat_json_object_add_uint (node, "remote_cookie",
10583                             clib_net_to_host_u64 (mp->remote_cookie));
10584
10585   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10586   vat_json_object_add_uint (node, "local_session_id",
10587                             clib_net_to_host_u32 (mp->local_session_id));
10588   vat_json_object_add_uint (node, "remote_session_id",
10589                             clib_net_to_host_u32 (mp->remote_session_id));
10590   vat_json_object_add_string_copy (node, "l2_sublayer",
10591                                    mp->l2_sublayer_present ? (u8 *) "present"
10592                                    : (u8 *) "absent");
10593 }
10594
10595 static int
10596 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10597 {
10598   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10599   f64 timeout;
10600
10601   /* Get list of l2tpv3-tunnel interfaces */
10602   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10603   S;
10604
10605   /* Use a control ping for synchronization */
10606   {
10607     vl_api_control_ping_t *mp;
10608     M (CONTROL_PING, control_ping);
10609     S;
10610   }
10611   W;
10612 }
10613
10614
10615 static void vl_api_sw_interface_tap_details_t_handler
10616   (vl_api_sw_interface_tap_details_t * mp)
10617 {
10618   vat_main_t *vam = &vat_main;
10619
10620   print (vam->ofp, "%-16s %d",
10621          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10622 }
10623
10624 static void vl_api_sw_interface_tap_details_t_handler_json
10625   (vl_api_sw_interface_tap_details_t * mp)
10626 {
10627   vat_main_t *vam = &vat_main;
10628   vat_json_node_t *node = NULL;
10629
10630   if (VAT_JSON_ARRAY != vam->json_tree.type)
10631     {
10632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10633       vat_json_init_array (&vam->json_tree);
10634     }
10635   node = vat_json_array_add (&vam->json_tree);
10636
10637   vat_json_init_object (node);
10638   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10639   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10640 }
10641
10642 static int
10643 api_sw_interface_tap_dump (vat_main_t * vam)
10644 {
10645   vl_api_sw_interface_tap_dump_t *mp;
10646   f64 timeout;
10647
10648   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10649   /* Get list of tap interfaces */
10650   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10651   S;
10652
10653   /* Use a control ping for synchronization */
10654   {
10655     vl_api_control_ping_t *mp;
10656     M (CONTROL_PING, control_ping);
10657     S;
10658   }
10659   W;
10660 }
10661
10662 static uword unformat_vxlan_decap_next
10663   (unformat_input_t * input, va_list * args)
10664 {
10665   u32 *result = va_arg (*args, u32 *);
10666   u32 tmp;
10667
10668   if (unformat (input, "l2"))
10669     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10670   else if (unformat (input, "%d", &tmp))
10671     *result = tmp;
10672   else
10673     return 0;
10674   return 1;
10675 }
10676
10677 static int
10678 api_vxlan_add_del_tunnel (vat_main_t * vam)
10679 {
10680   unformat_input_t *line_input = vam->input;
10681   vl_api_vxlan_add_del_tunnel_t *mp;
10682   f64 timeout;
10683   ip46_address_t src, dst;
10684   u8 is_add = 1;
10685   u8 ipv4_set = 0, ipv6_set = 0;
10686   u8 src_set = 0;
10687   u8 dst_set = 0;
10688   u8 grp_set = 0;
10689   u32 mcast_sw_if_index = ~0;
10690   u32 encap_vrf_id = 0;
10691   u32 decap_next_index = ~0;
10692   u32 vni = 0;
10693
10694   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10695   memset (&src, 0, sizeof src);
10696   memset (&dst, 0, sizeof dst);
10697
10698   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10699     {
10700       if (unformat (line_input, "del"))
10701         is_add = 0;
10702       else
10703         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10704         {
10705           ipv4_set = 1;
10706           src_set = 1;
10707         }
10708       else
10709         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10710         {
10711           ipv4_set = 1;
10712           dst_set = 1;
10713         }
10714       else
10715         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10716         {
10717           ipv6_set = 1;
10718           src_set = 1;
10719         }
10720       else
10721         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10722         {
10723           ipv6_set = 1;
10724           dst_set = 1;
10725         }
10726       else if (unformat (line_input, "group %U %U",
10727                          unformat_ip4_address, &dst.ip4,
10728                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10729         {
10730           grp_set = dst_set = 1;
10731           ipv4_set = 1;
10732         }
10733       else if (unformat (line_input, "group %U",
10734                          unformat_ip4_address, &dst.ip4))
10735         {
10736           grp_set = dst_set = 1;
10737           ipv4_set = 1;
10738         }
10739       else if (unformat (line_input, "group %U %U",
10740                          unformat_ip6_address, &dst.ip6,
10741                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10742         {
10743           grp_set = dst_set = 1;
10744           ipv6_set = 1;
10745         }
10746       else if (unformat (line_input, "group %U",
10747                          unformat_ip6_address, &dst.ip6))
10748         {
10749           grp_set = dst_set = 1;
10750           ipv6_set = 1;
10751         }
10752       else
10753         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10754         ;
10755       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10756         ;
10757       else if (unformat (line_input, "decap-next %U",
10758                          unformat_vxlan_decap_next, &decap_next_index))
10759         ;
10760       else if (unformat (line_input, "vni %d", &vni))
10761         ;
10762       else
10763         {
10764           errmsg ("parse error '%U'", format_unformat_error, line_input);
10765           return -99;
10766         }
10767     }
10768
10769   if (src_set == 0)
10770     {
10771       errmsg ("tunnel src address not specified");
10772       return -99;
10773     }
10774   if (dst_set == 0)
10775     {
10776       errmsg ("tunnel dst address not specified");
10777       return -99;
10778     }
10779
10780   if (grp_set && !ip46_address_is_multicast (&dst))
10781     {
10782       errmsg ("tunnel group address not multicast");
10783       return -99;
10784     }
10785   if (grp_set && mcast_sw_if_index == ~0)
10786     {
10787       errmsg ("tunnel nonexistent multicast device");
10788       return -99;
10789     }
10790   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10791     {
10792       errmsg ("tunnel dst address must be unicast");
10793       return -99;
10794     }
10795
10796
10797   if (ipv4_set && ipv6_set)
10798     {
10799       errmsg ("both IPv4 and IPv6 addresses specified");
10800       return -99;
10801     }
10802
10803   if ((vni == 0) || (vni >> 24))
10804     {
10805       errmsg ("vni not specified or out of range");
10806       return -99;
10807     }
10808
10809   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10810
10811   if (ipv6_set)
10812     {
10813       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10814       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10815     }
10816   else
10817     {
10818       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10819       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10820     }
10821   mp->encap_vrf_id = ntohl (encap_vrf_id);
10822   mp->decap_next_index = ntohl (decap_next_index);
10823   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10824   mp->vni = ntohl (vni);
10825   mp->is_add = is_add;
10826   mp->is_ipv6 = ipv6_set;
10827
10828   S;
10829   W;
10830   /* NOTREACHED */
10831   return 0;
10832 }
10833
10834 static void vl_api_vxlan_tunnel_details_t_handler
10835   (vl_api_vxlan_tunnel_details_t * mp)
10836 {
10837   vat_main_t *vam = &vat_main;
10838   ip46_address_t src, dst;
10839
10840   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10841   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10842
10843   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10844          ntohl (mp->sw_if_index),
10845          format_ip46_address, &src, IP46_TYPE_ANY,
10846          format_ip46_address, &dst, IP46_TYPE_ANY,
10847          ntohl (mp->encap_vrf_id),
10848          ntohl (mp->decap_next_index), ntohl (mp->vni),
10849          ntohl (mp->mcast_sw_if_index));
10850 }
10851
10852 static void vl_api_vxlan_tunnel_details_t_handler_json
10853   (vl_api_vxlan_tunnel_details_t * mp)
10854 {
10855   vat_main_t *vam = &vat_main;
10856   vat_json_node_t *node = NULL;
10857
10858   if (VAT_JSON_ARRAY != vam->json_tree.type)
10859     {
10860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10861       vat_json_init_array (&vam->json_tree);
10862     }
10863   node = vat_json_array_add (&vam->json_tree);
10864
10865   vat_json_init_object (node);
10866   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10867   if (mp->is_ipv6)
10868     {
10869       struct in6_addr ip6;
10870
10871       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10872       vat_json_object_add_ip6 (node, "src_address", ip6);
10873       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10874       vat_json_object_add_ip6 (node, "dst_address", ip6);
10875     }
10876   else
10877     {
10878       struct in_addr ip4;
10879
10880       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10881       vat_json_object_add_ip4 (node, "src_address", ip4);
10882       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10883       vat_json_object_add_ip4 (node, "dst_address", ip4);
10884     }
10885   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10886   vat_json_object_add_uint (node, "decap_next_index",
10887                             ntohl (mp->decap_next_index));
10888   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10889   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10890   vat_json_object_add_uint (node, "mcast_sw_if_index",
10891                             ntohl (mp->mcast_sw_if_index));
10892 }
10893
10894 static int
10895 api_vxlan_tunnel_dump (vat_main_t * vam)
10896 {
10897   unformat_input_t *i = vam->input;
10898   vl_api_vxlan_tunnel_dump_t *mp;
10899   f64 timeout;
10900   u32 sw_if_index;
10901   u8 sw_if_index_set = 0;
10902
10903   /* Parse args required to build the message */
10904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10905     {
10906       if (unformat (i, "sw_if_index %d", &sw_if_index))
10907         sw_if_index_set = 1;
10908       else
10909         break;
10910     }
10911
10912   if (sw_if_index_set == 0)
10913     {
10914       sw_if_index = ~0;
10915     }
10916
10917   if (!vam->json_output)
10918     {
10919       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10920              "sw_if_index", "src_address", "dst_address",
10921              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10922     }
10923
10924   /* Get list of vxlan-tunnel interfaces */
10925   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10926
10927   mp->sw_if_index = htonl (sw_if_index);
10928
10929   S;
10930
10931   /* Use a control ping for synchronization */
10932   {
10933     vl_api_control_ping_t *mp;
10934     M (CONTROL_PING, control_ping);
10935     S;
10936   }
10937   W;
10938 }
10939
10940 static int
10941 api_gre_add_del_tunnel (vat_main_t * vam)
10942 {
10943   unformat_input_t *line_input = vam->input;
10944   vl_api_gre_add_del_tunnel_t *mp;
10945   f64 timeout;
10946   ip4_address_t src4, dst4;
10947   u8 is_add = 1;
10948   u8 teb = 0;
10949   u8 src_set = 0;
10950   u8 dst_set = 0;
10951   u32 outer_fib_id = 0;
10952
10953   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10954     {
10955       if (unformat (line_input, "del"))
10956         is_add = 0;
10957       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10958         src_set = 1;
10959       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10960         dst_set = 1;
10961       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10962         ;
10963       else if (unformat (line_input, "teb"))
10964         teb = 1;
10965       else
10966         {
10967           errmsg ("parse error '%U'", format_unformat_error, line_input);
10968           return -99;
10969         }
10970     }
10971
10972   if (src_set == 0)
10973     {
10974       errmsg ("tunnel src address not specified");
10975       return -99;
10976     }
10977   if (dst_set == 0)
10978     {
10979       errmsg ("tunnel dst address not specified");
10980       return -99;
10981     }
10982
10983
10984   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10985
10986   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10987   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10988   mp->outer_fib_id = ntohl (outer_fib_id);
10989   mp->is_add = is_add;
10990   mp->teb = teb;
10991
10992   S;
10993   W;
10994   /* NOTREACHED */
10995   return 0;
10996 }
10997
10998 static void vl_api_gre_tunnel_details_t_handler
10999   (vl_api_gre_tunnel_details_t * mp)
11000 {
11001   vat_main_t *vam = &vat_main;
11002
11003   print (vam->ofp, "%11d%15U%15U%6d%14d",
11004          ntohl (mp->sw_if_index),
11005          format_ip4_address, &mp->src_address,
11006          format_ip4_address, &mp->dst_address,
11007          mp->teb, ntohl (mp->outer_fib_id));
11008 }
11009
11010 static void vl_api_gre_tunnel_details_t_handler_json
11011   (vl_api_gre_tunnel_details_t * mp)
11012 {
11013   vat_main_t *vam = &vat_main;
11014   vat_json_node_t *node = NULL;
11015   struct in_addr ip4;
11016
11017   if (VAT_JSON_ARRAY != vam->json_tree.type)
11018     {
11019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11020       vat_json_init_array (&vam->json_tree);
11021     }
11022   node = vat_json_array_add (&vam->json_tree);
11023
11024   vat_json_init_object (node);
11025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11026   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11027   vat_json_object_add_ip4 (node, "src_address", ip4);
11028   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11029   vat_json_object_add_ip4 (node, "dst_address", ip4);
11030   vat_json_object_add_uint (node, "teb", mp->teb);
11031   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11032 }
11033
11034 static int
11035 api_gre_tunnel_dump (vat_main_t * vam)
11036 {
11037   unformat_input_t *i = vam->input;
11038   vl_api_gre_tunnel_dump_t *mp;
11039   f64 timeout;
11040   u32 sw_if_index;
11041   u8 sw_if_index_set = 0;
11042
11043   /* Parse args required to build the message */
11044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11045     {
11046       if (unformat (i, "sw_if_index %d", &sw_if_index))
11047         sw_if_index_set = 1;
11048       else
11049         break;
11050     }
11051
11052   if (sw_if_index_set == 0)
11053     {
11054       sw_if_index = ~0;
11055     }
11056
11057   if (!vam->json_output)
11058     {
11059       print (vam->ofp, "%11s%15s%15s%6s%14s",
11060              "sw_if_index", "src_address", "dst_address", "teb",
11061              "outer_fib_id");
11062     }
11063
11064   /* Get list of gre-tunnel interfaces */
11065   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
11066
11067   mp->sw_if_index = htonl (sw_if_index);
11068
11069   S;
11070
11071   /* Use a control ping for synchronization */
11072   {
11073     vl_api_control_ping_t *mp;
11074     M (CONTROL_PING, control_ping);
11075     S;
11076   }
11077   W;
11078 }
11079
11080 static int
11081 api_l2_fib_clear_table (vat_main_t * vam)
11082 {
11083 //  unformat_input_t * i = vam->input;
11084   vl_api_l2_fib_clear_table_t *mp;
11085   f64 timeout;
11086
11087   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
11088
11089   S;
11090   W;
11091   /* NOTREACHED */
11092   return 0;
11093 }
11094
11095 static int
11096 api_l2_interface_efp_filter (vat_main_t * vam)
11097 {
11098   unformat_input_t *i = vam->input;
11099   vl_api_l2_interface_efp_filter_t *mp;
11100   f64 timeout;
11101   u32 sw_if_index;
11102   u8 enable = 1;
11103   u8 sw_if_index_set = 0;
11104
11105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11106     {
11107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11108         sw_if_index_set = 1;
11109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11110         sw_if_index_set = 1;
11111       else if (unformat (i, "enable"))
11112         enable = 1;
11113       else if (unformat (i, "disable"))
11114         enable = 0;
11115       else
11116         {
11117           clib_warning ("parse error '%U'", format_unformat_error, i);
11118           return -99;
11119         }
11120     }
11121
11122   if (sw_if_index_set == 0)
11123     {
11124       errmsg ("missing sw_if_index");
11125       return -99;
11126     }
11127
11128   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
11129
11130   mp->sw_if_index = ntohl (sw_if_index);
11131   mp->enable_disable = enable;
11132
11133   S;
11134   W;
11135   /* NOTREACHED */
11136   return 0;
11137 }
11138
11139 #define foreach_vtr_op                          \
11140 _("disable",  L2_VTR_DISABLED)                  \
11141 _("push-1",  L2_VTR_PUSH_1)                     \
11142 _("push-2",  L2_VTR_PUSH_2)                     \
11143 _("pop-1",  L2_VTR_POP_1)                       \
11144 _("pop-2",  L2_VTR_POP_2)                       \
11145 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11146 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11147 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11148 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11149
11150 static int
11151 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11152 {
11153   unformat_input_t *i = vam->input;
11154   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11155   f64 timeout;
11156   u32 sw_if_index;
11157   u8 sw_if_index_set = 0;
11158   u8 vtr_op_set = 0;
11159   u32 vtr_op = 0;
11160   u32 push_dot1q = 1;
11161   u32 tag1 = ~0;
11162   u32 tag2 = ~0;
11163
11164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11165     {
11166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11167         sw_if_index_set = 1;
11168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11169         sw_if_index_set = 1;
11170       else if (unformat (i, "vtr_op %d", &vtr_op))
11171         vtr_op_set = 1;
11172 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11173       foreach_vtr_op
11174 #undef _
11175         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11176         ;
11177       else if (unformat (i, "tag1 %d", &tag1))
11178         ;
11179       else if (unformat (i, "tag2 %d", &tag2))
11180         ;
11181       else
11182         {
11183           clib_warning ("parse error '%U'", format_unformat_error, i);
11184           return -99;
11185         }
11186     }
11187
11188   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11189     {
11190       errmsg ("missing vtr operation or sw_if_index");
11191       return -99;
11192     }
11193
11194   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
11195     mp->sw_if_index = ntohl (sw_if_index);
11196   mp->vtr_op = ntohl (vtr_op);
11197   mp->push_dot1q = ntohl (push_dot1q);
11198   mp->tag1 = ntohl (tag1);
11199   mp->tag2 = ntohl (tag2);
11200
11201   S;
11202   W;
11203   /* NOTREACHED */
11204   return 0;
11205 }
11206
11207 static int
11208 api_create_vhost_user_if (vat_main_t * vam)
11209 {
11210   unformat_input_t *i = vam->input;
11211   vl_api_create_vhost_user_if_t *mp;
11212   f64 timeout;
11213   u8 *file_name;
11214   u8 is_server = 0;
11215   u8 file_name_set = 0;
11216   u32 custom_dev_instance = ~0;
11217   u8 hwaddr[6];
11218   u8 use_custom_mac = 0;
11219   u8 *tag = 0;
11220
11221   /* Shut up coverity */
11222   memset (hwaddr, 0, sizeof (hwaddr));
11223
11224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11225     {
11226       if (unformat (i, "socket %s", &file_name))
11227         {
11228           file_name_set = 1;
11229         }
11230       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11231         ;
11232       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11233         use_custom_mac = 1;
11234       else if (unformat (i, "server"))
11235         is_server = 1;
11236       else if (unformat (i, "tag %s", &tag))
11237         ;
11238       else
11239         break;
11240     }
11241
11242   if (file_name_set == 0)
11243     {
11244       errmsg ("missing socket file name");
11245       return -99;
11246     }
11247
11248   if (vec_len (file_name) > 255)
11249     {
11250       errmsg ("socket file name too long");
11251       return -99;
11252     }
11253   vec_add1 (file_name, 0);
11254
11255   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
11256
11257   mp->is_server = is_server;
11258   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11259   vec_free (file_name);
11260   if (custom_dev_instance != ~0)
11261     {
11262       mp->renumber = 1;
11263       mp->custom_dev_instance = ntohl (custom_dev_instance);
11264     }
11265   mp->use_custom_mac = use_custom_mac;
11266   clib_memcpy (mp->mac_address, hwaddr, 6);
11267   if (tag)
11268     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11269   vec_free (tag);
11270
11271   S;
11272   W;
11273   /* NOTREACHED */
11274   return 0;
11275 }
11276
11277 static int
11278 api_modify_vhost_user_if (vat_main_t * vam)
11279 {
11280   unformat_input_t *i = vam->input;
11281   vl_api_modify_vhost_user_if_t *mp;
11282   f64 timeout;
11283   u8 *file_name;
11284   u8 is_server = 0;
11285   u8 file_name_set = 0;
11286   u32 custom_dev_instance = ~0;
11287   u8 sw_if_index_set = 0;
11288   u32 sw_if_index = (u32) ~ 0;
11289
11290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11291     {
11292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11293         sw_if_index_set = 1;
11294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11295         sw_if_index_set = 1;
11296       else if (unformat (i, "socket %s", &file_name))
11297         {
11298           file_name_set = 1;
11299         }
11300       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11301         ;
11302       else if (unformat (i, "server"))
11303         is_server = 1;
11304       else
11305         break;
11306     }
11307
11308   if (sw_if_index_set == 0)
11309     {
11310       errmsg ("missing sw_if_index or interface name");
11311       return -99;
11312     }
11313
11314   if (file_name_set == 0)
11315     {
11316       errmsg ("missing socket file name");
11317       return -99;
11318     }
11319
11320   if (vec_len (file_name) > 255)
11321     {
11322       errmsg ("socket file name too long");
11323       return -99;
11324     }
11325   vec_add1 (file_name, 0);
11326
11327   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
11328
11329   mp->sw_if_index = ntohl (sw_if_index);
11330   mp->is_server = is_server;
11331   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11332   vec_free (file_name);
11333   if (custom_dev_instance != ~0)
11334     {
11335       mp->renumber = 1;
11336       mp->custom_dev_instance = ntohl (custom_dev_instance);
11337     }
11338
11339   S;
11340   W;
11341   /* NOTREACHED */
11342   return 0;
11343 }
11344
11345 static int
11346 api_delete_vhost_user_if (vat_main_t * vam)
11347 {
11348   unformat_input_t *i = vam->input;
11349   vl_api_delete_vhost_user_if_t *mp;
11350   f64 timeout;
11351   u32 sw_if_index = ~0;
11352   u8 sw_if_index_set = 0;
11353
11354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11355     {
11356       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11357         sw_if_index_set = 1;
11358       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11359         sw_if_index_set = 1;
11360       else
11361         break;
11362     }
11363
11364   if (sw_if_index_set == 0)
11365     {
11366       errmsg ("missing sw_if_index or interface name");
11367       return -99;
11368     }
11369
11370
11371   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
11372
11373   mp->sw_if_index = ntohl (sw_if_index);
11374
11375   S;
11376   W;
11377   /* NOTREACHED */
11378   return 0;
11379 }
11380
11381 static void vl_api_sw_interface_vhost_user_details_t_handler
11382   (vl_api_sw_interface_vhost_user_details_t * mp)
11383 {
11384   vat_main_t *vam = &vat_main;
11385
11386   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11387          (char *) mp->interface_name,
11388          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11389          clib_net_to_host_u64 (mp->features), mp->is_server,
11390          ntohl (mp->num_regions), (char *) mp->sock_filename);
11391   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11392 }
11393
11394 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11395   (vl_api_sw_interface_vhost_user_details_t * mp)
11396 {
11397   vat_main_t *vam = &vat_main;
11398   vat_json_node_t *node = NULL;
11399
11400   if (VAT_JSON_ARRAY != vam->json_tree.type)
11401     {
11402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11403       vat_json_init_array (&vam->json_tree);
11404     }
11405   node = vat_json_array_add (&vam->json_tree);
11406
11407   vat_json_init_object (node);
11408   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11409   vat_json_object_add_string_copy (node, "interface_name",
11410                                    mp->interface_name);
11411   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11412                             ntohl (mp->virtio_net_hdr_sz));
11413   vat_json_object_add_uint (node, "features",
11414                             clib_net_to_host_u64 (mp->features));
11415   vat_json_object_add_uint (node, "is_server", mp->is_server);
11416   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11417   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11418   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11419 }
11420
11421 static int
11422 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11423 {
11424   vl_api_sw_interface_vhost_user_dump_t *mp;
11425   f64 timeout;
11426   print (vam->ofp,
11427          "Interface name           idx hdr_sz features server regions filename");
11428
11429   /* Get list of vhost-user interfaces */
11430   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11431   S;
11432
11433   /* Use a control ping for synchronization */
11434   {
11435     vl_api_control_ping_t *mp;
11436     M (CONTROL_PING, control_ping);
11437     S;
11438   }
11439   W;
11440 }
11441
11442 static int
11443 api_show_version (vat_main_t * vam)
11444 {
11445   vl_api_show_version_t *mp;
11446   f64 timeout;
11447
11448   M (SHOW_VERSION, show_version);
11449
11450   S;
11451   W;
11452   /* NOTREACHED */
11453   return 0;
11454 }
11455
11456
11457 static int
11458 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11459 {
11460   unformat_input_t *line_input = vam->input;
11461   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11462   f64 timeout;
11463   ip4_address_t local4, remote4;
11464   ip6_address_t local6, remote6;
11465   u8 is_add = 1;
11466   u8 ipv4_set = 0, ipv6_set = 0;
11467   u8 local_set = 0;
11468   u8 remote_set = 0;
11469   u32 encap_vrf_id = 0;
11470   u32 decap_vrf_id = 0;
11471   u8 protocol = ~0;
11472   u32 vni;
11473   u8 vni_set = 0;
11474
11475   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11476     {
11477       if (unformat (line_input, "del"))
11478         is_add = 0;
11479       else if (unformat (line_input, "local %U",
11480                          unformat_ip4_address, &local4))
11481         {
11482           local_set = 1;
11483           ipv4_set = 1;
11484         }
11485       else if (unformat (line_input, "remote %U",
11486                          unformat_ip4_address, &remote4))
11487         {
11488           remote_set = 1;
11489           ipv4_set = 1;
11490         }
11491       else if (unformat (line_input, "local %U",
11492                          unformat_ip6_address, &local6))
11493         {
11494           local_set = 1;
11495           ipv6_set = 1;
11496         }
11497       else if (unformat (line_input, "remote %U",
11498                          unformat_ip6_address, &remote6))
11499         {
11500           remote_set = 1;
11501           ipv6_set = 1;
11502         }
11503       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11504         ;
11505       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11506         ;
11507       else if (unformat (line_input, "vni %d", &vni))
11508         vni_set = 1;
11509       else if (unformat (line_input, "next-ip4"))
11510         protocol = 1;
11511       else if (unformat (line_input, "next-ip6"))
11512         protocol = 2;
11513       else if (unformat (line_input, "next-ethernet"))
11514         protocol = 3;
11515       else if (unformat (line_input, "next-nsh"))
11516         protocol = 4;
11517       else
11518         {
11519           errmsg ("parse error '%U'", format_unformat_error, line_input);
11520           return -99;
11521         }
11522     }
11523
11524   if (local_set == 0)
11525     {
11526       errmsg ("tunnel local address not specified");
11527       return -99;
11528     }
11529   if (remote_set == 0)
11530     {
11531       errmsg ("tunnel remote address not specified");
11532       return -99;
11533     }
11534   if (ipv4_set && ipv6_set)
11535     {
11536       errmsg ("both IPv4 and IPv6 addresses specified");
11537       return -99;
11538     }
11539
11540   if (vni_set == 0)
11541     {
11542       errmsg ("vni not specified");
11543       return -99;
11544     }
11545
11546   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11547
11548
11549   if (ipv6_set)
11550     {
11551       clib_memcpy (&mp->local, &local6, sizeof (local6));
11552       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11553     }
11554   else
11555     {
11556       clib_memcpy (&mp->local, &local4, sizeof (local4));
11557       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11558     }
11559
11560   mp->encap_vrf_id = ntohl (encap_vrf_id);
11561   mp->decap_vrf_id = ntohl (decap_vrf_id);
11562   mp->protocol = protocol;
11563   mp->vni = ntohl (vni);
11564   mp->is_add = is_add;
11565   mp->is_ipv6 = ipv6_set;
11566
11567   S;
11568   W;
11569   /* NOTREACHED */
11570   return 0;
11571 }
11572
11573 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11574   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11575 {
11576   vat_main_t *vam = &vat_main;
11577
11578   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11579          ntohl (mp->sw_if_index),
11580          format_ip46_address, &(mp->local[0]),
11581          format_ip46_address, &(mp->remote[0]),
11582          ntohl (mp->vni),
11583          ntohl (mp->protocol),
11584          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11585 }
11586
11587 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11588   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11589 {
11590   vat_main_t *vam = &vat_main;
11591   vat_json_node_t *node = NULL;
11592   struct in_addr ip4;
11593   struct in6_addr ip6;
11594
11595   if (VAT_JSON_ARRAY != vam->json_tree.type)
11596     {
11597       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11598       vat_json_init_array (&vam->json_tree);
11599     }
11600   node = vat_json_array_add (&vam->json_tree);
11601
11602   vat_json_init_object (node);
11603   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11604   if (mp->is_ipv6)
11605     {
11606       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11607       vat_json_object_add_ip6 (node, "local", ip6);
11608       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11609       vat_json_object_add_ip6 (node, "remote", ip6);
11610     }
11611   else
11612     {
11613       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11614       vat_json_object_add_ip4 (node, "local", ip4);
11615       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11616       vat_json_object_add_ip4 (node, "remote", ip4);
11617     }
11618   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11619   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11620   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11621   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11622   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11623 }
11624
11625 static int
11626 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11627 {
11628   unformat_input_t *i = vam->input;
11629   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11630   f64 timeout;
11631   u32 sw_if_index;
11632   u8 sw_if_index_set = 0;
11633
11634   /* Parse args required to build the message */
11635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11636     {
11637       if (unformat (i, "sw_if_index %d", &sw_if_index))
11638         sw_if_index_set = 1;
11639       else
11640         break;
11641     }
11642
11643   if (sw_if_index_set == 0)
11644     {
11645       sw_if_index = ~0;
11646     }
11647
11648   if (!vam->json_output)
11649     {
11650       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11651              "sw_if_index", "local", "remote", "vni",
11652              "protocol", "encap_vrf_id", "decap_vrf_id");
11653     }
11654
11655   /* Get list of vxlan-tunnel interfaces */
11656   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11657
11658   mp->sw_if_index = htonl (sw_if_index);
11659
11660   S;
11661
11662   /* Use a control ping for synchronization */
11663   {
11664     vl_api_control_ping_t *mp;
11665     M (CONTROL_PING, control_ping);
11666     S;
11667   }
11668   W;
11669 }
11670
11671 u8 *
11672 format_l2_fib_mac_address (u8 * s, va_list * args)
11673 {
11674   u8 *a = va_arg (*args, u8 *);
11675
11676   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11677                  a[2], a[3], a[4], a[5], a[6], a[7]);
11678 }
11679
11680 static void vl_api_l2_fib_table_entry_t_handler
11681   (vl_api_l2_fib_table_entry_t * mp)
11682 {
11683   vat_main_t *vam = &vat_main;
11684
11685   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11686          "       %d       %d     %d",
11687          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11688          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11689          mp->bvi_mac);
11690 }
11691
11692 static void vl_api_l2_fib_table_entry_t_handler_json
11693   (vl_api_l2_fib_table_entry_t * mp)
11694 {
11695   vat_main_t *vam = &vat_main;
11696   vat_json_node_t *node = NULL;
11697
11698   if (VAT_JSON_ARRAY != vam->json_tree.type)
11699     {
11700       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11701       vat_json_init_array (&vam->json_tree);
11702     }
11703   node = vat_json_array_add (&vam->json_tree);
11704
11705   vat_json_init_object (node);
11706   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11707   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11708   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11709   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11710   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11711   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11712 }
11713
11714 static int
11715 api_l2_fib_table_dump (vat_main_t * vam)
11716 {
11717   unformat_input_t *i = vam->input;
11718   vl_api_l2_fib_table_dump_t *mp;
11719   f64 timeout;
11720   u32 bd_id;
11721   u8 bd_id_set = 0;
11722
11723   /* Parse args required to build the message */
11724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11725     {
11726       if (unformat (i, "bd_id %d", &bd_id))
11727         bd_id_set = 1;
11728       else
11729         break;
11730     }
11731
11732   if (bd_id_set == 0)
11733     {
11734       errmsg ("missing bridge domain");
11735       return -99;
11736     }
11737
11738   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11739
11740   /* Get list of l2 fib entries */
11741   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11742
11743   mp->bd_id = ntohl (bd_id);
11744   S;
11745
11746   /* Use a control ping for synchronization */
11747   {
11748     vl_api_control_ping_t *mp;
11749     M (CONTROL_PING, control_ping);
11750     S;
11751   }
11752   W;
11753 }
11754
11755
11756 static int
11757 api_interface_name_renumber (vat_main_t * vam)
11758 {
11759   unformat_input_t *line_input = vam->input;
11760   vl_api_interface_name_renumber_t *mp;
11761   u32 sw_if_index = ~0;
11762   f64 timeout;
11763   u32 new_show_dev_instance = ~0;
11764
11765   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11766     {
11767       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11768                     &sw_if_index))
11769         ;
11770       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11771         ;
11772       else if (unformat (line_input, "new_show_dev_instance %d",
11773                          &new_show_dev_instance))
11774         ;
11775       else
11776         break;
11777     }
11778
11779   if (sw_if_index == ~0)
11780     {
11781       errmsg ("missing interface name or sw_if_index");
11782       return -99;
11783     }
11784
11785   if (new_show_dev_instance == ~0)
11786     {
11787       errmsg ("missing new_show_dev_instance");
11788       return -99;
11789     }
11790
11791   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11792
11793   mp->sw_if_index = ntohl (sw_if_index);
11794   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11795
11796   S;
11797   W;
11798 }
11799
11800 static int
11801 api_want_ip4_arp_events (vat_main_t * vam)
11802 {
11803   unformat_input_t *line_input = vam->input;
11804   vl_api_want_ip4_arp_events_t *mp;
11805   f64 timeout;
11806   ip4_address_t address;
11807   int address_set = 0;
11808   u32 enable_disable = 1;
11809
11810   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11811     {
11812       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11813         address_set = 1;
11814       else if (unformat (line_input, "del"))
11815         enable_disable = 0;
11816       else
11817         break;
11818     }
11819
11820   if (address_set == 0)
11821     {
11822       errmsg ("missing addresses");
11823       return -99;
11824     }
11825
11826   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11827   mp->enable_disable = enable_disable;
11828   mp->pid = getpid ();
11829   mp->address = address.as_u32;
11830
11831   S;
11832   W;
11833 }
11834
11835 static int
11836 api_want_ip6_nd_events (vat_main_t * vam)
11837 {
11838   unformat_input_t *line_input = vam->input;
11839   vl_api_want_ip6_nd_events_t *mp;
11840   f64 timeout;
11841   ip6_address_t address;
11842   int address_set = 0;
11843   u32 enable_disable = 1;
11844
11845   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11846     {
11847       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11848         address_set = 1;
11849       else if (unformat (line_input, "del"))
11850         enable_disable = 0;
11851       else
11852         break;
11853     }
11854
11855   if (address_set == 0)
11856     {
11857       errmsg ("missing addresses");
11858       return -99;
11859     }
11860
11861   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11862   mp->enable_disable = enable_disable;
11863   mp->pid = getpid ();
11864   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11865
11866   S;
11867   W;
11868 }
11869
11870 static int
11871 api_input_acl_set_interface (vat_main_t * vam)
11872 {
11873   unformat_input_t *i = vam->input;
11874   vl_api_input_acl_set_interface_t *mp;
11875   f64 timeout;
11876   u32 sw_if_index;
11877   int sw_if_index_set;
11878   u32 ip4_table_index = ~0;
11879   u32 ip6_table_index = ~0;
11880   u32 l2_table_index = ~0;
11881   u8 is_add = 1;
11882
11883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11884     {
11885       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11886         sw_if_index_set = 1;
11887       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11888         sw_if_index_set = 1;
11889       else if (unformat (i, "del"))
11890         is_add = 0;
11891       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11892         ;
11893       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11894         ;
11895       else if (unformat (i, "l2-table %d", &l2_table_index))
11896         ;
11897       else
11898         {
11899           clib_warning ("parse error '%U'", format_unformat_error, i);
11900           return -99;
11901         }
11902     }
11903
11904   if (sw_if_index_set == 0)
11905     {
11906       errmsg ("missing interface name or sw_if_index");
11907       return -99;
11908     }
11909
11910   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11911
11912   mp->sw_if_index = ntohl (sw_if_index);
11913   mp->ip4_table_index = ntohl (ip4_table_index);
11914   mp->ip6_table_index = ntohl (ip6_table_index);
11915   mp->l2_table_index = ntohl (l2_table_index);
11916   mp->is_add = is_add;
11917
11918   S;
11919   W;
11920   /* NOTREACHED */
11921   return 0;
11922 }
11923
11924 static int
11925 api_ip_address_dump (vat_main_t * vam)
11926 {
11927   unformat_input_t *i = vam->input;
11928   vl_api_ip_address_dump_t *mp;
11929   u32 sw_if_index = ~0;
11930   u8 sw_if_index_set = 0;
11931   u8 ipv4_set = 0;
11932   u8 ipv6_set = 0;
11933   f64 timeout;
11934
11935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11936     {
11937       if (unformat (i, "sw_if_index %d", &sw_if_index))
11938         sw_if_index_set = 1;
11939       else
11940         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11941         sw_if_index_set = 1;
11942       else if (unformat (i, "ipv4"))
11943         ipv4_set = 1;
11944       else if (unformat (i, "ipv6"))
11945         ipv6_set = 1;
11946       else
11947         break;
11948     }
11949
11950   if (ipv4_set && ipv6_set)
11951     {
11952       errmsg ("ipv4 and ipv6 flags cannot be both set");
11953       return -99;
11954     }
11955
11956   if ((!ipv4_set) && (!ipv6_set))
11957     {
11958       errmsg ("no ipv4 nor ipv6 flag set");
11959       return -99;
11960     }
11961
11962   if (sw_if_index_set == 0)
11963     {
11964       errmsg ("missing interface name or sw_if_index");
11965       return -99;
11966     }
11967
11968   vam->current_sw_if_index = sw_if_index;
11969   vam->is_ipv6 = ipv6_set;
11970
11971   M (IP_ADDRESS_DUMP, ip_address_dump);
11972   mp->sw_if_index = ntohl (sw_if_index);
11973   mp->is_ipv6 = ipv6_set;
11974   S;
11975
11976   /* Use a control ping for synchronization */
11977   {
11978     vl_api_control_ping_t *mp;
11979     M (CONTROL_PING, control_ping);
11980     S;
11981   }
11982   W;
11983 }
11984
11985 static int
11986 api_ip_dump (vat_main_t * vam)
11987 {
11988   vl_api_ip_dump_t *mp;
11989   unformat_input_t *in = vam->input;
11990   int ipv4_set = 0;
11991   int ipv6_set = 0;
11992   int is_ipv6;
11993   f64 timeout;
11994   int i;
11995
11996   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11997     {
11998       if (unformat (in, "ipv4"))
11999         ipv4_set = 1;
12000       else if (unformat (in, "ipv6"))
12001         ipv6_set = 1;
12002       else
12003         break;
12004     }
12005
12006   if (ipv4_set && ipv6_set)
12007     {
12008       errmsg ("ipv4 and ipv6 flags cannot be both set");
12009       return -99;
12010     }
12011
12012   if ((!ipv4_set) && (!ipv6_set))
12013     {
12014       errmsg ("no ipv4 nor ipv6 flag set");
12015       return -99;
12016     }
12017
12018   is_ipv6 = ipv6_set;
12019   vam->is_ipv6 = is_ipv6;
12020
12021   /* free old data */
12022   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12023     {
12024       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12025     }
12026   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12027
12028   M (IP_DUMP, ip_dump);
12029   mp->is_ipv6 = ipv6_set;
12030   S;
12031
12032   /* Use a control ping for synchronization */
12033   {
12034     vl_api_control_ping_t *mp;
12035     M (CONTROL_PING, control_ping);
12036     S;
12037   }
12038   W;
12039 }
12040
12041 static int
12042 api_ipsec_spd_add_del (vat_main_t * vam)
12043 {
12044   unformat_input_t *i = vam->input;
12045   vl_api_ipsec_spd_add_del_t *mp;
12046   f64 timeout;
12047   u32 spd_id = ~0;
12048   u8 is_add = 1;
12049
12050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12051     {
12052       if (unformat (i, "spd_id %d", &spd_id))
12053         ;
12054       else if (unformat (i, "del"))
12055         is_add = 0;
12056       else
12057         {
12058           clib_warning ("parse error '%U'", format_unformat_error, i);
12059           return -99;
12060         }
12061     }
12062   if (spd_id == ~0)
12063     {
12064       errmsg ("spd_id must be set");
12065       return -99;
12066     }
12067
12068   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
12069
12070   mp->spd_id = ntohl (spd_id);
12071   mp->is_add = is_add;
12072
12073   S;
12074   W;
12075   /* NOTREACHED */
12076   return 0;
12077 }
12078
12079 static int
12080 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12081 {
12082   unformat_input_t *i = vam->input;
12083   vl_api_ipsec_interface_add_del_spd_t *mp;
12084   f64 timeout;
12085   u32 sw_if_index;
12086   u8 sw_if_index_set = 0;
12087   u32 spd_id = (u32) ~ 0;
12088   u8 is_add = 1;
12089
12090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12091     {
12092       if (unformat (i, "del"))
12093         is_add = 0;
12094       else if (unformat (i, "spd_id %d", &spd_id))
12095         ;
12096       else
12097         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12098         sw_if_index_set = 1;
12099       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12100         sw_if_index_set = 1;
12101       else
12102         {
12103           clib_warning ("parse error '%U'", format_unformat_error, i);
12104           return -99;
12105         }
12106
12107     }
12108
12109   if (spd_id == (u32) ~ 0)
12110     {
12111       errmsg ("spd_id must be set");
12112       return -99;
12113     }
12114
12115   if (sw_if_index_set == 0)
12116     {
12117       errmsg ("missing interface name or sw_if_index");
12118       return -99;
12119     }
12120
12121   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
12122
12123   mp->spd_id = ntohl (spd_id);
12124   mp->sw_if_index = ntohl (sw_if_index);
12125   mp->is_add = is_add;
12126
12127   S;
12128   W;
12129   /* NOTREACHED */
12130   return 0;
12131 }
12132
12133 static int
12134 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12135 {
12136   unformat_input_t *i = vam->input;
12137   vl_api_ipsec_spd_add_del_entry_t *mp;
12138   f64 timeout;
12139   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12140   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12141   i32 priority = 0;
12142   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12143   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12144   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12145   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12146
12147   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12148   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12149   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12150   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12151   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12152   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12153
12154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12155     {
12156       if (unformat (i, "del"))
12157         is_add = 0;
12158       if (unformat (i, "outbound"))
12159         is_outbound = 1;
12160       if (unformat (i, "inbound"))
12161         is_outbound = 0;
12162       else if (unformat (i, "spd_id %d", &spd_id))
12163         ;
12164       else if (unformat (i, "sa_id %d", &sa_id))
12165         ;
12166       else if (unformat (i, "priority %d", &priority))
12167         ;
12168       else if (unformat (i, "protocol %d", &protocol))
12169         ;
12170       else if (unformat (i, "lport_start %d", &lport_start))
12171         ;
12172       else if (unformat (i, "lport_stop %d", &lport_stop))
12173         ;
12174       else if (unformat (i, "rport_start %d", &rport_start))
12175         ;
12176       else if (unformat (i, "rport_stop %d", &rport_stop))
12177         ;
12178       else
12179         if (unformat
12180             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12181         {
12182           is_ipv6 = 0;
12183           is_ip_any = 0;
12184         }
12185       else
12186         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12187         {
12188           is_ipv6 = 0;
12189           is_ip_any = 0;
12190         }
12191       else
12192         if (unformat
12193             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12194         {
12195           is_ipv6 = 0;
12196           is_ip_any = 0;
12197         }
12198       else
12199         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12200         {
12201           is_ipv6 = 0;
12202           is_ip_any = 0;
12203         }
12204       else
12205         if (unformat
12206             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12207         {
12208           is_ipv6 = 1;
12209           is_ip_any = 0;
12210         }
12211       else
12212         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12213         {
12214           is_ipv6 = 1;
12215           is_ip_any = 0;
12216         }
12217       else
12218         if (unformat
12219             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12220         {
12221           is_ipv6 = 1;
12222           is_ip_any = 0;
12223         }
12224       else
12225         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12226         {
12227           is_ipv6 = 1;
12228           is_ip_any = 0;
12229         }
12230       else
12231         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12232         {
12233           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12234             {
12235               clib_warning ("unsupported action: 'resolve'");
12236               return -99;
12237             }
12238         }
12239       else
12240         {
12241           clib_warning ("parse error '%U'", format_unformat_error, i);
12242           return -99;
12243         }
12244
12245     }
12246
12247   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
12248
12249   mp->spd_id = ntohl (spd_id);
12250   mp->priority = ntohl (priority);
12251   mp->is_outbound = is_outbound;
12252
12253   mp->is_ipv6 = is_ipv6;
12254   if (is_ipv6 || is_ip_any)
12255     {
12256       clib_memcpy (mp->remote_address_start, &raddr6_start,
12257                    sizeof (ip6_address_t));
12258       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12259                    sizeof (ip6_address_t));
12260       clib_memcpy (mp->local_address_start, &laddr6_start,
12261                    sizeof (ip6_address_t));
12262       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12263                    sizeof (ip6_address_t));
12264     }
12265   else
12266     {
12267       clib_memcpy (mp->remote_address_start, &raddr4_start,
12268                    sizeof (ip4_address_t));
12269       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12270                    sizeof (ip4_address_t));
12271       clib_memcpy (mp->local_address_start, &laddr4_start,
12272                    sizeof (ip4_address_t));
12273       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12274                    sizeof (ip4_address_t));
12275     }
12276   mp->protocol = (u8) protocol;
12277   mp->local_port_start = ntohs ((u16) lport_start);
12278   mp->local_port_stop = ntohs ((u16) lport_stop);
12279   mp->remote_port_start = ntohs ((u16) rport_start);
12280   mp->remote_port_stop = ntohs ((u16) rport_stop);
12281   mp->policy = (u8) policy;
12282   mp->sa_id = ntohl (sa_id);
12283   mp->is_add = is_add;
12284   mp->is_ip_any = is_ip_any;
12285   S;
12286   W;
12287   /* NOTREACHED */
12288   return 0;
12289 }
12290
12291 static int
12292 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12293 {
12294   unformat_input_t *i = vam->input;
12295   vl_api_ipsec_sad_add_del_entry_t *mp;
12296   f64 timeout;
12297   u32 sad_id = 0, spi = 0;
12298   u8 *ck = 0, *ik = 0;
12299   u8 is_add = 1;
12300
12301   u8 protocol = IPSEC_PROTOCOL_AH;
12302   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12303   u32 crypto_alg = 0, integ_alg = 0;
12304   ip4_address_t tun_src4;
12305   ip4_address_t tun_dst4;
12306   ip6_address_t tun_src6;
12307   ip6_address_t tun_dst6;
12308
12309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12310     {
12311       if (unformat (i, "del"))
12312         is_add = 0;
12313       else if (unformat (i, "sad_id %d", &sad_id))
12314         ;
12315       else if (unformat (i, "spi %d", &spi))
12316         ;
12317       else if (unformat (i, "esp"))
12318         protocol = IPSEC_PROTOCOL_ESP;
12319       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12320         {
12321           is_tunnel = 1;
12322           is_tunnel_ipv6 = 0;
12323         }
12324       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12325         {
12326           is_tunnel = 1;
12327           is_tunnel_ipv6 = 0;
12328         }
12329       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12330         {
12331           is_tunnel = 1;
12332           is_tunnel_ipv6 = 1;
12333         }
12334       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12335         {
12336           is_tunnel = 1;
12337           is_tunnel_ipv6 = 1;
12338         }
12339       else
12340         if (unformat
12341             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12342         {
12343           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12344               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12345             {
12346               clib_warning ("unsupported crypto-alg: '%U'",
12347                             format_ipsec_crypto_alg, crypto_alg);
12348               return -99;
12349             }
12350         }
12351       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12352         ;
12353       else
12354         if (unformat
12355             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12356         {
12357           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12358               integ_alg >= IPSEC_INTEG_N_ALG)
12359             {
12360               clib_warning ("unsupported integ-alg: '%U'",
12361                             format_ipsec_integ_alg, integ_alg);
12362               return -99;
12363             }
12364         }
12365       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12366         ;
12367       else
12368         {
12369           clib_warning ("parse error '%U'", format_unformat_error, i);
12370           return -99;
12371         }
12372
12373     }
12374
12375   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12376
12377   mp->sad_id = ntohl (sad_id);
12378   mp->is_add = is_add;
12379   mp->protocol = protocol;
12380   mp->spi = ntohl (spi);
12381   mp->is_tunnel = is_tunnel;
12382   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12383   mp->crypto_algorithm = crypto_alg;
12384   mp->integrity_algorithm = integ_alg;
12385   mp->crypto_key_length = vec_len (ck);
12386   mp->integrity_key_length = vec_len (ik);
12387
12388   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12389     mp->crypto_key_length = sizeof (mp->crypto_key);
12390
12391   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12392     mp->integrity_key_length = sizeof (mp->integrity_key);
12393
12394   if (ck)
12395     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12396   if (ik)
12397     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12398
12399   if (is_tunnel)
12400     {
12401       if (is_tunnel_ipv6)
12402         {
12403           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12404                        sizeof (ip6_address_t));
12405           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12406                        sizeof (ip6_address_t));
12407         }
12408       else
12409         {
12410           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12411                        sizeof (ip4_address_t));
12412           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12413                        sizeof (ip4_address_t));
12414         }
12415     }
12416
12417   S;
12418   W;
12419   /* NOTREACHED */
12420   return 0;
12421 }
12422
12423 static int
12424 api_ipsec_sa_set_key (vat_main_t * vam)
12425 {
12426   unformat_input_t *i = vam->input;
12427   vl_api_ipsec_sa_set_key_t *mp;
12428   f64 timeout;
12429   u32 sa_id;
12430   u8 *ck = 0, *ik = 0;
12431
12432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12433     {
12434       if (unformat (i, "sa_id %d", &sa_id))
12435         ;
12436       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12437         ;
12438       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12439         ;
12440       else
12441         {
12442           clib_warning ("parse error '%U'", format_unformat_error, i);
12443           return -99;
12444         }
12445     }
12446
12447   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12448
12449   mp->sa_id = ntohl (sa_id);
12450   mp->crypto_key_length = vec_len (ck);
12451   mp->integrity_key_length = vec_len (ik);
12452
12453   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12454     mp->crypto_key_length = sizeof (mp->crypto_key);
12455
12456   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12457     mp->integrity_key_length = sizeof (mp->integrity_key);
12458
12459   if (ck)
12460     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12461   if (ik)
12462     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12463
12464   S;
12465   W;
12466   /* NOTREACHED */
12467   return 0;
12468 }
12469
12470 static int
12471 api_ikev2_profile_add_del (vat_main_t * vam)
12472 {
12473   unformat_input_t *i = vam->input;
12474   vl_api_ikev2_profile_add_del_t *mp;
12475   f64 timeout;
12476   u8 is_add = 1;
12477   u8 *name = 0;
12478
12479   const char *valid_chars = "a-zA-Z0-9_";
12480
12481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12482     {
12483       if (unformat (i, "del"))
12484         is_add = 0;
12485       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12486         vec_add1 (name, 0);
12487       else
12488         {
12489           errmsg ("parse error '%U'", format_unformat_error, i);
12490           return -99;
12491         }
12492     }
12493
12494   if (!vec_len (name))
12495     {
12496       errmsg ("profile name must be specified");
12497       return -99;
12498     }
12499
12500   if (vec_len (name) > 64)
12501     {
12502       errmsg ("profile name too long");
12503       return -99;
12504     }
12505
12506   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12507
12508   clib_memcpy (mp->name, name, vec_len (name));
12509   mp->is_add = is_add;
12510   vec_free (name);
12511
12512   S;
12513   W;
12514   /* NOTREACHED */
12515   return 0;
12516 }
12517
12518 static int
12519 api_ikev2_profile_set_auth (vat_main_t * vam)
12520 {
12521   unformat_input_t *i = vam->input;
12522   vl_api_ikev2_profile_set_auth_t *mp;
12523   f64 timeout;
12524   u8 *name = 0;
12525   u8 *data = 0;
12526   u32 auth_method = 0;
12527   u8 is_hex = 0;
12528
12529   const char *valid_chars = "a-zA-Z0-9_";
12530
12531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12532     {
12533       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12534         vec_add1 (name, 0);
12535       else if (unformat (i, "auth_method %U",
12536                          unformat_ikev2_auth_method, &auth_method))
12537         ;
12538       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12539         is_hex = 1;
12540       else if (unformat (i, "auth_data %v", &data))
12541         ;
12542       else
12543         {
12544           errmsg ("parse error '%U'", format_unformat_error, i);
12545           return -99;
12546         }
12547     }
12548
12549   if (!vec_len (name))
12550     {
12551       errmsg ("profile name must be specified");
12552       return -99;
12553     }
12554
12555   if (vec_len (name) > 64)
12556     {
12557       errmsg ("profile name too long");
12558       return -99;
12559     }
12560
12561   if (!vec_len (data))
12562     {
12563       errmsg ("auth_data must be specified");
12564       return -99;
12565     }
12566
12567   if (!auth_method)
12568     {
12569       errmsg ("auth_method must be specified");
12570       return -99;
12571     }
12572
12573   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12574
12575   mp->is_hex = is_hex;
12576   mp->auth_method = (u8) auth_method;
12577   mp->data_len = vec_len (data);
12578   clib_memcpy (mp->name, name, vec_len (name));
12579   clib_memcpy (mp->data, data, vec_len (data));
12580   vec_free (name);
12581   vec_free (data);
12582
12583   S;
12584   W;
12585   /* NOTREACHED */
12586   return 0;
12587 }
12588
12589 static int
12590 api_ikev2_profile_set_id (vat_main_t * vam)
12591 {
12592   unformat_input_t *i = vam->input;
12593   vl_api_ikev2_profile_set_id_t *mp;
12594   f64 timeout;
12595   u8 *name = 0;
12596   u8 *data = 0;
12597   u8 is_local = 0;
12598   u32 id_type = 0;
12599   ip4_address_t ip4;
12600
12601   const char *valid_chars = "a-zA-Z0-9_";
12602
12603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12604     {
12605       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12606         vec_add1 (name, 0);
12607       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12608         ;
12609       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12610         {
12611           data = vec_new (u8, 4);
12612           clib_memcpy (data, ip4.as_u8, 4);
12613         }
12614       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12615         ;
12616       else if (unformat (i, "id_data %v", &data))
12617         ;
12618       else if (unformat (i, "local"))
12619         is_local = 1;
12620       else if (unformat (i, "remote"))
12621         is_local = 0;
12622       else
12623         {
12624           errmsg ("parse error '%U'", format_unformat_error, i);
12625           return -99;
12626         }
12627     }
12628
12629   if (!vec_len (name))
12630     {
12631       errmsg ("profile name must be specified");
12632       return -99;
12633     }
12634
12635   if (vec_len (name) > 64)
12636     {
12637       errmsg ("profile name too long");
12638       return -99;
12639     }
12640
12641   if (!vec_len (data))
12642     {
12643       errmsg ("id_data must be specified");
12644       return -99;
12645     }
12646
12647   if (!id_type)
12648     {
12649       errmsg ("id_type must be specified");
12650       return -99;
12651     }
12652
12653   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12654
12655   mp->is_local = is_local;
12656   mp->id_type = (u8) id_type;
12657   mp->data_len = vec_len (data);
12658   clib_memcpy (mp->name, name, vec_len (name));
12659   clib_memcpy (mp->data, data, vec_len (data));
12660   vec_free (name);
12661   vec_free (data);
12662
12663   S;
12664   W;
12665   /* NOTREACHED */
12666   return 0;
12667 }
12668
12669 static int
12670 api_ikev2_profile_set_ts (vat_main_t * vam)
12671 {
12672   unformat_input_t *i = vam->input;
12673   vl_api_ikev2_profile_set_ts_t *mp;
12674   f64 timeout;
12675   u8 *name = 0;
12676   u8 is_local = 0;
12677   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12678   ip4_address_t start_addr, end_addr;
12679
12680   const char *valid_chars = "a-zA-Z0-9_";
12681
12682   start_addr.as_u32 = 0;
12683   end_addr.as_u32 = (u32) ~ 0;
12684
12685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12686     {
12687       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12688         vec_add1 (name, 0);
12689       else if (unformat (i, "protocol %d", &proto))
12690         ;
12691       else if (unformat (i, "start_port %d", &start_port))
12692         ;
12693       else if (unformat (i, "end_port %d", &end_port))
12694         ;
12695       else
12696         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12697         ;
12698       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12699         ;
12700       else if (unformat (i, "local"))
12701         is_local = 1;
12702       else if (unformat (i, "remote"))
12703         is_local = 0;
12704       else
12705         {
12706           errmsg ("parse error '%U'", format_unformat_error, i);
12707           return -99;
12708         }
12709     }
12710
12711   if (!vec_len (name))
12712     {
12713       errmsg ("profile name must be specified");
12714       return -99;
12715     }
12716
12717   if (vec_len (name) > 64)
12718     {
12719       errmsg ("profile name too long");
12720       return -99;
12721     }
12722
12723   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12724
12725   mp->is_local = is_local;
12726   mp->proto = (u8) proto;
12727   mp->start_port = (u16) start_port;
12728   mp->end_port = (u16) end_port;
12729   mp->start_addr = start_addr.as_u32;
12730   mp->end_addr = end_addr.as_u32;
12731   clib_memcpy (mp->name, name, vec_len (name));
12732   vec_free (name);
12733
12734   S;
12735   W;
12736   /* NOTREACHED */
12737   return 0;
12738 }
12739
12740 static int
12741 api_ikev2_set_local_key (vat_main_t * vam)
12742 {
12743   unformat_input_t *i = vam->input;
12744   vl_api_ikev2_set_local_key_t *mp;
12745   f64 timeout;
12746   u8 *file = 0;
12747
12748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12749     {
12750       if (unformat (i, "file %v", &file))
12751         vec_add1 (file, 0);
12752       else
12753         {
12754           errmsg ("parse error '%U'", format_unformat_error, i);
12755           return -99;
12756         }
12757     }
12758
12759   if (!vec_len (file))
12760     {
12761       errmsg ("RSA key file must be specified");
12762       return -99;
12763     }
12764
12765   if (vec_len (file) > 256)
12766     {
12767       errmsg ("file name too long");
12768       return -99;
12769     }
12770
12771   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12772
12773   clib_memcpy (mp->key_file, file, vec_len (file));
12774   vec_free (file);
12775
12776   S;
12777   W;
12778   /* NOTREACHED */
12779   return 0;
12780 }
12781
12782 /*
12783  * MAP
12784  */
12785 static int
12786 api_map_add_domain (vat_main_t * vam)
12787 {
12788   unformat_input_t *i = vam->input;
12789   vl_api_map_add_domain_t *mp;
12790   f64 timeout;
12791
12792   ip4_address_t ip4_prefix;
12793   ip6_address_t ip6_prefix;
12794   ip6_address_t ip6_src;
12795   u32 num_m_args = 0;
12796   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12797     0, psid_length = 0;
12798   u8 is_translation = 0;
12799   u32 mtu = 0;
12800   u32 ip6_src_len = 128;
12801
12802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12803     {
12804       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12805                     &ip4_prefix, &ip4_prefix_len))
12806         num_m_args++;
12807       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12808                          &ip6_prefix, &ip6_prefix_len))
12809         num_m_args++;
12810       else
12811         if (unformat
12812             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12813              &ip6_src_len))
12814         num_m_args++;
12815       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12816         num_m_args++;
12817       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12818         num_m_args++;
12819       else if (unformat (i, "psid-offset %d", &psid_offset))
12820         num_m_args++;
12821       else if (unformat (i, "psid-len %d", &psid_length))
12822         num_m_args++;
12823       else if (unformat (i, "mtu %d", &mtu))
12824         num_m_args++;
12825       else if (unformat (i, "map-t"))
12826         is_translation = 1;
12827       else
12828         {
12829           clib_warning ("parse error '%U'", format_unformat_error, i);
12830           return -99;
12831         }
12832     }
12833
12834   if (num_m_args < 3)
12835     {
12836       errmsg ("mandatory argument(s) missing");
12837       return -99;
12838     }
12839
12840   /* Construct the API message */
12841   M (MAP_ADD_DOMAIN, map_add_domain);
12842
12843   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12844   mp->ip4_prefix_len = ip4_prefix_len;
12845
12846   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12847   mp->ip6_prefix_len = ip6_prefix_len;
12848
12849   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12850   mp->ip6_src_prefix_len = ip6_src_len;
12851
12852   mp->ea_bits_len = ea_bits_len;
12853   mp->psid_offset = psid_offset;
12854   mp->psid_length = psid_length;
12855   mp->is_translation = is_translation;
12856   mp->mtu = htons (mtu);
12857
12858   /* send it... */
12859   S;
12860
12861   /* Wait for a reply, return good/bad news  */
12862   W;
12863 }
12864
12865 static int
12866 api_map_del_domain (vat_main_t * vam)
12867 {
12868   unformat_input_t *i = vam->input;
12869   vl_api_map_del_domain_t *mp;
12870   f64 timeout;
12871
12872   u32 num_m_args = 0;
12873   u32 index;
12874
12875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12876     {
12877       if (unformat (i, "index %d", &index))
12878         num_m_args++;
12879       else
12880         {
12881           clib_warning ("parse error '%U'", format_unformat_error, i);
12882           return -99;
12883         }
12884     }
12885
12886   if (num_m_args != 1)
12887     {
12888       errmsg ("mandatory argument(s) missing");
12889       return -99;
12890     }
12891
12892   /* Construct the API message */
12893   M (MAP_DEL_DOMAIN, map_del_domain);
12894
12895   mp->index = ntohl (index);
12896
12897   /* send it... */
12898   S;
12899
12900   /* Wait for a reply, return good/bad news  */
12901   W;
12902 }
12903
12904 static int
12905 api_map_add_del_rule (vat_main_t * vam)
12906 {
12907   unformat_input_t *i = vam->input;
12908   vl_api_map_add_del_rule_t *mp;
12909   f64 timeout;
12910   u8 is_add = 1;
12911   ip6_address_t ip6_dst;
12912   u32 num_m_args = 0, index, psid = 0;
12913
12914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12915     {
12916       if (unformat (i, "index %d", &index))
12917         num_m_args++;
12918       else if (unformat (i, "psid %d", &psid))
12919         num_m_args++;
12920       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12921         num_m_args++;
12922       else if (unformat (i, "del"))
12923         {
12924           is_add = 0;
12925         }
12926       else
12927         {
12928           clib_warning ("parse error '%U'", format_unformat_error, i);
12929           return -99;
12930         }
12931     }
12932
12933   /* Construct the API message */
12934   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12935
12936   mp->index = ntohl (index);
12937   mp->is_add = is_add;
12938   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12939   mp->psid = ntohs (psid);
12940
12941   /* send it... */
12942   S;
12943
12944   /* Wait for a reply, return good/bad news  */
12945   W;
12946 }
12947
12948 static int
12949 api_map_domain_dump (vat_main_t * vam)
12950 {
12951   vl_api_map_domain_dump_t *mp;
12952   f64 timeout;
12953
12954   /* Construct the API message */
12955   M (MAP_DOMAIN_DUMP, map_domain_dump);
12956
12957   /* send it... */
12958   S;
12959
12960   /* Use a control ping for synchronization */
12961   {
12962     vl_api_control_ping_t *mp;
12963     M (CONTROL_PING, control_ping);
12964     S;
12965   }
12966   W;
12967 }
12968
12969 static int
12970 api_map_rule_dump (vat_main_t * vam)
12971 {
12972   unformat_input_t *i = vam->input;
12973   vl_api_map_rule_dump_t *mp;
12974   f64 timeout;
12975   u32 domain_index = ~0;
12976
12977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12978     {
12979       if (unformat (i, "index %u", &domain_index))
12980         ;
12981       else
12982         break;
12983     }
12984
12985   if (domain_index == ~0)
12986     {
12987       clib_warning ("parse error: domain index expected");
12988       return -99;
12989     }
12990
12991   /* Construct the API message */
12992   M (MAP_RULE_DUMP, map_rule_dump);
12993
12994   mp->domain_index = htonl (domain_index);
12995
12996   /* send it... */
12997   S;
12998
12999   /* Use a control ping for synchronization */
13000   {
13001     vl_api_control_ping_t *mp;
13002     M (CONTROL_PING, control_ping);
13003     S;
13004   }
13005   W;
13006 }
13007
13008 static void vl_api_map_add_domain_reply_t_handler
13009   (vl_api_map_add_domain_reply_t * mp)
13010 {
13011   vat_main_t *vam = &vat_main;
13012   i32 retval = ntohl (mp->retval);
13013
13014   if (vam->async_mode)
13015     {
13016       vam->async_errors += (retval < 0);
13017     }
13018   else
13019     {
13020       vam->retval = retval;
13021       vam->result_ready = 1;
13022     }
13023 }
13024
13025 static void vl_api_map_add_domain_reply_t_handler_json
13026   (vl_api_map_add_domain_reply_t * mp)
13027 {
13028   vat_main_t *vam = &vat_main;
13029   vat_json_node_t node;
13030
13031   vat_json_init_object (&node);
13032   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13033   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13034
13035   vat_json_print (vam->ofp, &node);
13036   vat_json_free (&node);
13037
13038   vam->retval = ntohl (mp->retval);
13039   vam->result_ready = 1;
13040 }
13041
13042 static int
13043 api_get_first_msg_id (vat_main_t * vam)
13044 {
13045   vl_api_get_first_msg_id_t *mp;
13046   f64 timeout;
13047   unformat_input_t *i = vam->input;
13048   u8 *name;
13049   u8 name_set = 0;
13050
13051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13052     {
13053       if (unformat (i, "client %s", &name))
13054         name_set = 1;
13055       else
13056         break;
13057     }
13058
13059   if (name_set == 0)
13060     {
13061       errmsg ("missing client name");
13062       return -99;
13063     }
13064   vec_add1 (name, 0);
13065
13066   if (vec_len (name) > 63)
13067     {
13068       errmsg ("client name too long");
13069       return -99;
13070     }
13071
13072   M (GET_FIRST_MSG_ID, get_first_msg_id);
13073   clib_memcpy (mp->name, name, vec_len (name));
13074   S;
13075   W;
13076   /* NOTREACHED */
13077   return 0;
13078 }
13079
13080 static int
13081 api_cop_interface_enable_disable (vat_main_t * vam)
13082 {
13083   unformat_input_t *line_input = vam->input;
13084   vl_api_cop_interface_enable_disable_t *mp;
13085   f64 timeout;
13086   u32 sw_if_index = ~0;
13087   u8 enable_disable = 1;
13088
13089   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13090     {
13091       if (unformat (line_input, "disable"))
13092         enable_disable = 0;
13093       if (unformat (line_input, "enable"))
13094         enable_disable = 1;
13095       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13096                          vam, &sw_if_index))
13097         ;
13098       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13099         ;
13100       else
13101         break;
13102     }
13103
13104   if (sw_if_index == ~0)
13105     {
13106       errmsg ("missing interface name or sw_if_index");
13107       return -99;
13108     }
13109
13110   /* Construct the API message */
13111   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
13112   mp->sw_if_index = ntohl (sw_if_index);
13113   mp->enable_disable = enable_disable;
13114
13115   /* send it... */
13116   S;
13117   /* Wait for the reply */
13118   W;
13119 }
13120
13121 static int
13122 api_cop_whitelist_enable_disable (vat_main_t * vam)
13123 {
13124   unformat_input_t *line_input = vam->input;
13125   vl_api_cop_whitelist_enable_disable_t *mp;
13126   f64 timeout;
13127   u32 sw_if_index = ~0;
13128   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13129   u32 fib_id = 0;
13130
13131   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13132     {
13133       if (unformat (line_input, "ip4"))
13134         ip4 = 1;
13135       else if (unformat (line_input, "ip6"))
13136         ip6 = 1;
13137       else if (unformat (line_input, "default"))
13138         default_cop = 1;
13139       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13140                          vam, &sw_if_index))
13141         ;
13142       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13143         ;
13144       else if (unformat (line_input, "fib-id %d", &fib_id))
13145         ;
13146       else
13147         break;
13148     }
13149
13150   if (sw_if_index == ~0)
13151     {
13152       errmsg ("missing interface name or sw_if_index");
13153       return -99;
13154     }
13155
13156   /* Construct the API message */
13157   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
13158   mp->sw_if_index = ntohl (sw_if_index);
13159   mp->fib_id = ntohl (fib_id);
13160   mp->ip4 = ip4;
13161   mp->ip6 = ip6;
13162   mp->default_cop = default_cop;
13163
13164   /* send it... */
13165   S;
13166   /* Wait for the reply */
13167   W;
13168 }
13169
13170 static int
13171 api_get_node_graph (vat_main_t * vam)
13172 {
13173   vl_api_get_node_graph_t *mp;
13174   f64 timeout;
13175
13176   M (GET_NODE_GRAPH, get_node_graph);
13177
13178   /* send it... */
13179   S;
13180   /* Wait for the reply */
13181   W;
13182 }
13183
13184 /* *INDENT-OFF* */
13185 /** Used for parsing LISP eids */
13186 typedef CLIB_PACKED(struct{
13187   u8 addr[16];   /**< eid address */
13188   u32 len;       /**< prefix length if IP */
13189   u8 type;      /**< type of eid */
13190 }) lisp_eid_vat_t;
13191 /* *INDENT-ON* */
13192
13193 static uword
13194 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13195 {
13196   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13197
13198   memset (a, 0, sizeof (a[0]));
13199
13200   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13201     {
13202       a->type = 0;              /* ipv4 type */
13203     }
13204   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13205     {
13206       a->type = 1;              /* ipv6 type */
13207     }
13208   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13209     {
13210       a->type = 2;              /* mac type */
13211     }
13212   else
13213     {
13214       return 0;
13215     }
13216
13217   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13218     {
13219       return 0;
13220     }
13221
13222   return 1;
13223 }
13224
13225 static int
13226 lisp_eid_size_vat (u8 type)
13227 {
13228   switch (type)
13229     {
13230     case 0:
13231       return 4;
13232     case 1:
13233       return 16;
13234     case 2:
13235       return 6;
13236     }
13237   return 0;
13238 }
13239
13240 static void
13241 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13242 {
13243   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13244 }
13245
13246 static int
13247 api_lisp_add_del_locator_set (vat_main_t * vam)
13248 {
13249   unformat_input_t *input = vam->input;
13250   vl_api_lisp_add_del_locator_set_t *mp;
13251   f64 timeout = ~0;
13252   u8 is_add = 1;
13253   u8 *locator_set_name = NULL;
13254   u8 locator_set_name_set = 0;
13255   vl_api_local_locator_t locator, *locators = 0;
13256   u32 sw_if_index, priority, weight;
13257   u32 data_len = 0;
13258
13259   /* Parse args required to build the message */
13260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13261     {
13262       if (unformat (input, "del"))
13263         {
13264           is_add = 0;
13265         }
13266       else if (unformat (input, "locator-set %s", &locator_set_name))
13267         {
13268           locator_set_name_set = 1;
13269         }
13270       else if (unformat (input, "sw_if_index %u p %u w %u",
13271                          &sw_if_index, &priority, &weight))
13272         {
13273           locator.sw_if_index = htonl (sw_if_index);
13274           locator.priority = priority;
13275           locator.weight = weight;
13276           vec_add1 (locators, locator);
13277         }
13278       else
13279         if (unformat
13280             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13281              &sw_if_index, &priority, &weight))
13282         {
13283           locator.sw_if_index = htonl (sw_if_index);
13284           locator.priority = priority;
13285           locator.weight = weight;
13286           vec_add1 (locators, locator);
13287         }
13288       else
13289         break;
13290     }
13291
13292   if (locator_set_name_set == 0)
13293     {
13294       errmsg ("missing locator-set name");
13295       vec_free (locators);
13296       return -99;
13297     }
13298
13299   if (vec_len (locator_set_name) > 64)
13300     {
13301       errmsg ("locator-set name too long");
13302       vec_free (locator_set_name);
13303       vec_free (locators);
13304       return -99;
13305     }
13306   vec_add1 (locator_set_name, 0);
13307
13308   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13309
13310   /* Construct the API message */
13311   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
13312
13313   mp->is_add = is_add;
13314   clib_memcpy (mp->locator_set_name, locator_set_name,
13315                vec_len (locator_set_name));
13316   vec_free (locator_set_name);
13317
13318   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13319   if (locators)
13320     clib_memcpy (mp->locators, locators, data_len);
13321   vec_free (locators);
13322
13323   /* send it... */
13324   S;
13325
13326   /* Wait for a reply... */
13327   W;
13328
13329   /* NOTREACHED */
13330   return 0;
13331 }
13332
13333 static int
13334 api_lisp_add_del_locator (vat_main_t * vam)
13335 {
13336   unformat_input_t *input = vam->input;
13337   vl_api_lisp_add_del_locator_t *mp;
13338   f64 timeout = ~0;
13339   u32 tmp_if_index = ~0;
13340   u32 sw_if_index = ~0;
13341   u8 sw_if_index_set = 0;
13342   u8 sw_if_index_if_name_set = 0;
13343   u32 priority = ~0;
13344   u8 priority_set = 0;
13345   u32 weight = ~0;
13346   u8 weight_set = 0;
13347   u8 is_add = 1;
13348   u8 *locator_set_name = NULL;
13349   u8 locator_set_name_set = 0;
13350
13351   /* Parse args required to build the message */
13352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13353     {
13354       if (unformat (input, "del"))
13355         {
13356           is_add = 0;
13357         }
13358       else if (unformat (input, "locator-set %s", &locator_set_name))
13359         {
13360           locator_set_name_set = 1;
13361         }
13362       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13363                          &tmp_if_index))
13364         {
13365           sw_if_index_if_name_set = 1;
13366           sw_if_index = tmp_if_index;
13367         }
13368       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13369         {
13370           sw_if_index_set = 1;
13371           sw_if_index = tmp_if_index;
13372         }
13373       else if (unformat (input, "p %d", &priority))
13374         {
13375           priority_set = 1;
13376         }
13377       else if (unformat (input, "w %d", &weight))
13378         {
13379           weight_set = 1;
13380         }
13381       else
13382         break;
13383     }
13384
13385   if (locator_set_name_set == 0)
13386     {
13387       errmsg ("missing locator-set name");
13388       return -99;
13389     }
13390
13391   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13392     {
13393       errmsg ("missing sw_if_index");
13394       vec_free (locator_set_name);
13395       return -99;
13396     }
13397
13398   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13399     {
13400       errmsg ("cannot use both params interface name and sw_if_index");
13401       vec_free (locator_set_name);
13402       return -99;
13403     }
13404
13405   if (priority_set == 0)
13406     {
13407       errmsg ("missing locator-set priority");
13408       vec_free (locator_set_name);
13409       return -99;
13410     }
13411
13412   if (weight_set == 0)
13413     {
13414       errmsg ("missing locator-set weight");
13415       vec_free (locator_set_name);
13416       return -99;
13417     }
13418
13419   if (vec_len (locator_set_name) > 64)
13420     {
13421       errmsg ("locator-set name too long");
13422       vec_free (locator_set_name);
13423       return -99;
13424     }
13425   vec_add1 (locator_set_name, 0);
13426
13427   /* Construct the API message */
13428   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13429
13430   mp->is_add = is_add;
13431   mp->sw_if_index = ntohl (sw_if_index);
13432   mp->priority = priority;
13433   mp->weight = weight;
13434   clib_memcpy (mp->locator_set_name, locator_set_name,
13435                vec_len (locator_set_name));
13436   vec_free (locator_set_name);
13437
13438   /* send it... */
13439   S;
13440
13441   /* Wait for a reply... */
13442   W;
13443
13444   /* NOTREACHED */
13445   return 0;
13446 }
13447
13448 uword
13449 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13450 {
13451   u32 *key_id = va_arg (*args, u32 *);
13452   u8 *s = 0;
13453
13454   if (unformat (input, "%s", &s))
13455     {
13456       if (!strcmp ((char *) s, "sha1"))
13457         key_id[0] = HMAC_SHA_1_96;
13458       else if (!strcmp ((char *) s, "sha256"))
13459         key_id[0] = HMAC_SHA_256_128;
13460       else
13461         {
13462           clib_warning ("invalid key_id: '%s'", s);
13463           key_id[0] = HMAC_NO_KEY;
13464         }
13465     }
13466   else
13467     return 0;
13468
13469   vec_free (s);
13470   return 1;
13471 }
13472
13473 static int
13474 api_lisp_add_del_local_eid (vat_main_t * vam)
13475 {
13476   unformat_input_t *input = vam->input;
13477   vl_api_lisp_add_del_local_eid_t *mp;
13478   f64 timeout = ~0;
13479   u8 is_add = 1;
13480   u8 eid_set = 0;
13481   lisp_eid_vat_t _eid, *eid = &_eid;
13482   u8 *locator_set_name = 0;
13483   u8 locator_set_name_set = 0;
13484   u32 vni = 0;
13485   u16 key_id = 0;
13486   u8 *key = 0;
13487
13488   /* Parse args required to build the message */
13489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13490     {
13491       if (unformat (input, "del"))
13492         {
13493           is_add = 0;
13494         }
13495       else if (unformat (input, "vni %d", &vni))
13496         {
13497           ;
13498         }
13499       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13500         {
13501           eid_set = 1;
13502         }
13503       else if (unformat (input, "locator-set %s", &locator_set_name))
13504         {
13505           locator_set_name_set = 1;
13506         }
13507       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13508         ;
13509       else if (unformat (input, "secret-key %_%v%_", &key))
13510         ;
13511       else
13512         break;
13513     }
13514
13515   if (locator_set_name_set == 0)
13516     {
13517       errmsg ("missing locator-set name");
13518       return -99;
13519     }
13520
13521   if (0 == eid_set)
13522     {
13523       errmsg ("EID address not set!");
13524       vec_free (locator_set_name);
13525       return -99;
13526     }
13527
13528   if (key && (0 == key_id))
13529     {
13530       errmsg ("invalid key_id!");
13531       return -99;
13532     }
13533
13534   if (vec_len (key) > 64)
13535     {
13536       errmsg ("key too long");
13537       vec_free (key);
13538       return -99;
13539     }
13540
13541   if (vec_len (locator_set_name) > 64)
13542     {
13543       errmsg ("locator-set name too long");
13544       vec_free (locator_set_name);
13545       return -99;
13546     }
13547   vec_add1 (locator_set_name, 0);
13548
13549   /* Construct the API message */
13550   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13551
13552   mp->is_add = is_add;
13553   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13554   mp->eid_type = eid->type;
13555   mp->prefix_len = eid->len;
13556   mp->vni = clib_host_to_net_u32 (vni);
13557   mp->key_id = clib_host_to_net_u16 (key_id);
13558   clib_memcpy (mp->locator_set_name, locator_set_name,
13559                vec_len (locator_set_name));
13560   clib_memcpy (mp->key, key, vec_len (key));
13561
13562   vec_free (locator_set_name);
13563   vec_free (key);
13564
13565   /* send it... */
13566   S;
13567
13568   /* Wait for a reply... */
13569   W;
13570
13571   /* NOTREACHED */
13572   return 0;
13573 }
13574
13575 /* *INDENT-OFF* */
13576 /** Used for transferring locators via VPP API */
13577 typedef CLIB_PACKED(struct
13578 {
13579   u8 is_ip4; /**< is locator an IPv4 address? */
13580   u8 priority; /**< locator priority */
13581   u8 weight;   /**< locator weight */
13582   u8 addr[16]; /**< IPv4/IPv6 address */
13583 }) rloc_t;
13584 /* *INDENT-ON* */
13585
13586 static int
13587 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13588 {
13589   u32 dp_table = 0, vni = 0;;
13590   unformat_input_t *input = vam->input;
13591   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13592   f64 timeout = ~0;
13593   u8 is_add = 1;
13594   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13595   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13596   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13597   u32 action = ~0, w;
13598   ip4_address_t rmt_rloc4, lcl_rloc4;
13599   ip6_address_t rmt_rloc6, lcl_rloc6;
13600   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13601     0;
13602
13603   memset (&rloc, 0, sizeof (rloc));
13604
13605   /* Parse args required to build the message */
13606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13607     {
13608       if (unformat (input, "del"))
13609         is_add = 0;
13610       else if (unformat (input, "add"))
13611         is_add = 1;
13612       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13613         {
13614           rmt_eid_set = 1;
13615         }
13616       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13617         {
13618           lcl_eid_set = 1;
13619         }
13620       else if (unformat (input, "vrf %d", &dp_table))
13621         ;
13622       else if (unformat (input, "bd %d", &dp_table))
13623         ;
13624       else if (unformat (input, "vni %d", &vni))
13625         ;
13626       else if (unformat (input, "w %d", &w))
13627         {
13628           if (!curr_rloc)
13629             {
13630               errmsg ("No RLOC configured for setting priority/weight!");
13631               return -99;
13632             }
13633           curr_rloc->weight = w;
13634         }
13635       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13636                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13637         {
13638           rloc.is_ip4 = 1;
13639
13640           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13641           rloc.weight = 0;
13642           vec_add1 (lcl_locs, rloc);
13643
13644           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13645           vec_add1 (rmt_locs, rloc);
13646           /* weight saved in rmt loc */
13647           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13648         }
13649       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13650                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13651         {
13652           rloc.is_ip4 = 0;
13653           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13654           rloc.weight = 0;
13655           vec_add1 (lcl_locs, rloc);
13656
13657           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13658           vec_add1 (rmt_locs, rloc);
13659           /* weight saved in rmt loc */
13660           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13661         }
13662       else if (unformat (input, "action %d", &action))
13663         {
13664           ;
13665         }
13666       else
13667         {
13668           clib_warning ("parse error '%U'", format_unformat_error, input);
13669           return -99;
13670         }
13671     }
13672
13673   if (!rmt_eid_set)
13674     {
13675       errmsg ("remote eid addresses not set");
13676       return -99;
13677     }
13678
13679   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13680     {
13681       errmsg ("eid types don't match");
13682       return -99;
13683     }
13684
13685   if (0 == rmt_locs && (u32) ~ 0 == action)
13686     {
13687       errmsg ("action not set for negative mapping");
13688       return -99;
13689     }
13690
13691   /* Construct the API message */
13692   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry,
13693       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13694
13695   mp->is_add = is_add;
13696   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13697   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13698   mp->eid_type = rmt_eid->type;
13699   mp->dp_table = clib_host_to_net_u32 (dp_table);
13700   mp->vni = clib_host_to_net_u32 (vni);
13701   mp->rmt_len = rmt_eid->len;
13702   mp->lcl_len = lcl_eid->len;
13703   mp->action = action;
13704
13705   if (0 != rmt_locs && 0 != lcl_locs)
13706     {
13707       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13708       clib_memcpy (mp->locs, lcl_locs,
13709                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13710
13711       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13712       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13713                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13714     }
13715   vec_free (lcl_locs);
13716   vec_free (rmt_locs);
13717
13718   /* send it... */
13719   S;
13720
13721   /* Wait for a reply... */
13722   W;
13723
13724   /* NOTREACHED */
13725   return 0;
13726 }
13727
13728 static int
13729 api_lisp_add_del_map_server (vat_main_t * vam)
13730 {
13731   unformat_input_t *input = vam->input;
13732   vl_api_lisp_add_del_map_server_t *mp;
13733   f64 timeout = ~0;
13734   u8 is_add = 1;
13735   u8 ipv4_set = 0;
13736   u8 ipv6_set = 0;
13737   ip4_address_t ipv4;
13738   ip6_address_t ipv6;
13739
13740   /* Parse args required to build the message */
13741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13742     {
13743       if (unformat (input, "del"))
13744         {
13745           is_add = 0;
13746         }
13747       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13748         {
13749           ipv4_set = 1;
13750         }
13751       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13752         {
13753           ipv6_set = 1;
13754         }
13755       else
13756         break;
13757     }
13758
13759   if (ipv4_set && ipv6_set)
13760     {
13761       errmsg ("both eid v4 and v6 addresses set");
13762       return -99;
13763     }
13764
13765   if (!ipv4_set && !ipv6_set)
13766     {
13767       errmsg ("eid addresses not set");
13768       return -99;
13769     }
13770
13771   /* Construct the API message */
13772   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13773
13774   mp->is_add = is_add;
13775   if (ipv6_set)
13776     {
13777       mp->is_ipv6 = 1;
13778       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13779     }
13780   else
13781     {
13782       mp->is_ipv6 = 0;
13783       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13784     }
13785
13786   /* send it... */
13787   S;
13788
13789   /* Wait for a reply... */
13790   W;
13791
13792   /* NOTREACHED */
13793   return 0;
13794 }
13795
13796 static int
13797 api_lisp_add_del_map_resolver (vat_main_t * vam)
13798 {
13799   unformat_input_t *input = vam->input;
13800   vl_api_lisp_add_del_map_resolver_t *mp;
13801   f64 timeout = ~0;
13802   u8 is_add = 1;
13803   u8 ipv4_set = 0;
13804   u8 ipv6_set = 0;
13805   ip4_address_t ipv4;
13806   ip6_address_t ipv6;
13807
13808   /* Parse args required to build the message */
13809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13810     {
13811       if (unformat (input, "del"))
13812         {
13813           is_add = 0;
13814         }
13815       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13816         {
13817           ipv4_set = 1;
13818         }
13819       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13820         {
13821           ipv6_set = 1;
13822         }
13823       else
13824         break;
13825     }
13826
13827   if (ipv4_set && ipv6_set)
13828     {
13829       errmsg ("both eid v4 and v6 addresses set");
13830       return -99;
13831     }
13832
13833   if (!ipv4_set && !ipv6_set)
13834     {
13835       errmsg ("eid addresses not set");
13836       return -99;
13837     }
13838
13839   /* Construct the API message */
13840   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13841
13842   mp->is_add = is_add;
13843   if (ipv6_set)
13844     {
13845       mp->is_ipv6 = 1;
13846       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13847     }
13848   else
13849     {
13850       mp->is_ipv6 = 0;
13851       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13852     }
13853
13854   /* send it... */
13855   S;
13856
13857   /* Wait for a reply... */
13858   W;
13859
13860   /* NOTREACHED */
13861   return 0;
13862 }
13863
13864 static int
13865 api_lisp_gpe_enable_disable (vat_main_t * vam)
13866 {
13867   unformat_input_t *input = vam->input;
13868   vl_api_lisp_gpe_enable_disable_t *mp;
13869   f64 timeout = ~0;
13870   u8 is_set = 0;
13871   u8 is_en = 1;
13872
13873   /* Parse args required to build the message */
13874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13875     {
13876       if (unformat (input, "enable"))
13877         {
13878           is_set = 1;
13879           is_en = 1;
13880         }
13881       else if (unformat (input, "disable"))
13882         {
13883           is_set = 1;
13884           is_en = 0;
13885         }
13886       else
13887         break;
13888     }
13889
13890   if (is_set == 0)
13891     {
13892       errmsg ("Value not set");
13893       return -99;
13894     }
13895
13896   /* Construct the API message */
13897   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13898
13899   mp->is_en = is_en;
13900
13901   /* send it... */
13902   S;
13903
13904   /* Wait for a reply... */
13905   W;
13906
13907   /* NOTREACHED */
13908   return 0;
13909 }
13910
13911 static int
13912 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13913 {
13914   unformat_input_t *input = vam->input;
13915   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13916   f64 timeout = ~0;
13917   u8 is_set = 0;
13918   u8 is_en = 0;
13919
13920   /* Parse args required to build the message */
13921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13922     {
13923       if (unformat (input, "enable"))
13924         {
13925           is_set = 1;
13926           is_en = 1;
13927         }
13928       else if (unformat (input, "disable"))
13929         is_set = 1;
13930       else
13931         break;
13932     }
13933
13934   if (!is_set)
13935     {
13936       errmsg ("Value not set");
13937       return -99;
13938     }
13939
13940   /* Construct the API message */
13941   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13942
13943   mp->is_enabled = is_en;
13944
13945   /* send it... */
13946   S;
13947
13948   /* Wait for a reply... */
13949   W;
13950
13951   /* NOTREACHED */
13952   return 0;
13953 }
13954
13955 static int
13956 api_lisp_map_register_enable_disable (vat_main_t * vam)
13957 {
13958   unformat_input_t *input = vam->input;
13959   vl_api_lisp_map_register_enable_disable_t *mp;
13960   f64 timeout = ~0;
13961   u8 is_set = 0;
13962   u8 is_en = 0;
13963
13964   /* Parse args required to build the message */
13965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13966     {
13967       if (unformat (input, "enable"))
13968         {
13969           is_set = 1;
13970           is_en = 1;
13971         }
13972       else if (unformat (input, "disable"))
13973         is_set = 1;
13974       else
13975         break;
13976     }
13977
13978   if (!is_set)
13979     {
13980       errmsg ("Value not set");
13981       return -99;
13982     }
13983
13984   /* Construct the API message */
13985   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13986
13987   mp->is_enabled = is_en;
13988
13989   /* send it... */
13990   S;
13991
13992   /* Wait for a reply... */
13993   W;
13994
13995   /* NOTREACHED */
13996   return 0;
13997 }
13998
13999 static int
14000 api_lisp_enable_disable (vat_main_t * vam)
14001 {
14002   unformat_input_t *input = vam->input;
14003   vl_api_lisp_enable_disable_t *mp;
14004   f64 timeout = ~0;
14005   u8 is_set = 0;
14006   u8 is_en = 0;
14007
14008   /* Parse args required to build the message */
14009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14010     {
14011       if (unformat (input, "enable"))
14012         {
14013           is_set = 1;
14014           is_en = 1;
14015         }
14016       else if (unformat (input, "disable"))
14017         {
14018           is_set = 1;
14019         }
14020       else
14021         break;
14022     }
14023
14024   if (!is_set)
14025     {
14026       errmsg ("Value not set");
14027       return -99;
14028     }
14029
14030   /* Construct the API message */
14031   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
14032
14033   mp->is_en = is_en;
14034
14035   /* send it... */
14036   S;
14037
14038   /* Wait for a reply... */
14039   W;
14040
14041   /* NOTREACHED */
14042   return 0;
14043 }
14044
14045 static int
14046 api_show_lisp_map_register_state (vat_main_t * vam)
14047 {
14048   f64 timeout = ~0;
14049   vl_api_show_lisp_map_register_state_t *mp;
14050
14051   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
14052
14053   /* send */
14054   S;
14055
14056   /* wait for reply */
14057   W;
14058
14059   return 0;
14060 }
14061
14062 static int
14063 api_show_lisp_rloc_probe_state (vat_main_t * vam)
14064 {
14065   f64 timeout = ~0;
14066   vl_api_show_lisp_rloc_probe_state_t *mp;
14067
14068   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
14069
14070   /* send */
14071   S;
14072
14073   /* wait for reply */
14074   W;
14075
14076   return 0;
14077 }
14078
14079 static int
14080 api_show_lisp_map_request_mode (vat_main_t * vam)
14081 {
14082   f64 timeout = ~0;
14083   vl_api_show_lisp_map_request_mode_t *mp;
14084
14085   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
14086
14087   /* send */
14088   S;
14089
14090   /* wait for reply */
14091   W;
14092
14093   return 0;
14094 }
14095
14096 static int
14097 api_lisp_map_request_mode (vat_main_t * vam)
14098 {
14099   f64 timeout = ~0;
14100   unformat_input_t *input = vam->input;
14101   vl_api_lisp_map_request_mode_t *mp;
14102   u8 mode = 0;
14103
14104   /* Parse args required to build the message */
14105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14106     {
14107       if (unformat (input, "dst-only"))
14108         mode = 0;
14109       else if (unformat (input, "src-dst"))
14110         mode = 1;
14111       else
14112         {
14113           errmsg ("parse error '%U'", format_unformat_error, input);
14114           return -99;
14115         }
14116     }
14117
14118   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
14119
14120   mp->mode = mode;
14121
14122   /* send */
14123   S;
14124
14125   /* wait for reply */
14126   W;
14127
14128   /* notreached */
14129   return 0;
14130 }
14131
14132 /**
14133  * Enable/disable LISP proxy ITR.
14134  *
14135  * @param vam vpp API test context
14136  * @return return code
14137  */
14138 static int
14139 api_lisp_pitr_set_locator_set (vat_main_t * vam)
14140 {
14141   f64 timeout = ~0;
14142   u8 ls_name_set = 0;
14143   unformat_input_t *input = vam->input;
14144   vl_api_lisp_pitr_set_locator_set_t *mp;
14145   u8 is_add = 1;
14146   u8 *ls_name = 0;
14147
14148   /* Parse args required to build the message */
14149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14150     {
14151       if (unformat (input, "del"))
14152         is_add = 0;
14153       else if (unformat (input, "locator-set %s", &ls_name))
14154         ls_name_set = 1;
14155       else
14156         {
14157           errmsg ("parse error '%U'", format_unformat_error, input);
14158           return -99;
14159         }
14160     }
14161
14162   if (!ls_name_set)
14163     {
14164       errmsg ("locator-set name not set!");
14165       return -99;
14166     }
14167
14168   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
14169
14170   mp->is_add = is_add;
14171   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14172   vec_free (ls_name);
14173
14174   /* send */
14175   S;
14176
14177   /* wait for reply */
14178   W;
14179
14180   /* notreached */
14181   return 0;
14182 }
14183
14184 static int
14185 api_show_lisp_pitr (vat_main_t * vam)
14186 {
14187   vl_api_show_lisp_pitr_t *mp;
14188   f64 timeout = ~0;
14189
14190   if (!vam->json_output)
14191     {
14192       print (vam->ofp, "%=20s", "lisp status:");
14193     }
14194
14195   M (SHOW_LISP_PITR, show_lisp_pitr);
14196   /* send it... */
14197   S;
14198
14199   /* Wait for a reply... */
14200   W;
14201
14202   /* NOTREACHED */
14203   return 0;
14204 }
14205
14206 /**
14207  * Add/delete mapping between vni and vrf
14208  */
14209 static int
14210 api_lisp_eid_table_add_del_map (vat_main_t * vam)
14211 {
14212   f64 timeout = ~0;
14213   unformat_input_t *input = vam->input;
14214   vl_api_lisp_eid_table_add_del_map_t *mp;
14215   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14216   u32 vni, vrf, bd_index;
14217
14218   /* Parse args required to build the message */
14219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14220     {
14221       if (unformat (input, "del"))
14222         is_add = 0;
14223       else if (unformat (input, "vrf %d", &vrf))
14224         vrf_set = 1;
14225       else if (unformat (input, "bd_index %d", &bd_index))
14226         bd_index_set = 1;
14227       else if (unformat (input, "vni %d", &vni))
14228         vni_set = 1;
14229       else
14230         break;
14231     }
14232
14233   if (!vni_set || (!vrf_set && !bd_index_set))
14234     {
14235       errmsg ("missing arguments!");
14236       return -99;
14237     }
14238
14239   if (vrf_set && bd_index_set)
14240     {
14241       errmsg ("error: both vrf and bd entered!");
14242       return -99;
14243     }
14244
14245   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
14246
14247   mp->is_add = is_add;
14248   mp->vni = htonl (vni);
14249   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14250   mp->is_l2 = bd_index_set;
14251
14252   /* send */
14253   S;
14254
14255   /* wait for reply */
14256   W;
14257
14258   /* notreached */
14259   return 0;
14260 }
14261
14262 uword
14263 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14264 {
14265   u32 *action = va_arg (*args, u32 *);
14266   u8 *s = 0;
14267
14268   if (unformat (input, "%s", &s))
14269     {
14270       if (!strcmp ((char *) s, "no-action"))
14271         action[0] = 0;
14272       else if (!strcmp ((char *) s, "natively-forward"))
14273         action[0] = 1;
14274       else if (!strcmp ((char *) s, "send-map-request"))
14275         action[0] = 2;
14276       else if (!strcmp ((char *) s, "drop"))
14277         action[0] = 3;
14278       else
14279         {
14280           clib_warning ("invalid action: '%s'", s);
14281           action[0] = 3;
14282         }
14283     }
14284   else
14285     return 0;
14286
14287   vec_free (s);
14288   return 1;
14289 }
14290
14291 /**
14292  * Add/del remote mapping to/from LISP control plane
14293  *
14294  * @param vam vpp API test context
14295  * @return return code
14296  */
14297 static int
14298 api_lisp_add_del_remote_mapping (vat_main_t * vam)
14299 {
14300   unformat_input_t *input = vam->input;
14301   vl_api_lisp_add_del_remote_mapping_t *mp;
14302   f64 timeout = ~0;
14303   u32 vni = 0;
14304   lisp_eid_vat_t _eid, *eid = &_eid;
14305   lisp_eid_vat_t _seid, *seid = &_seid;
14306   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14307   u32 action = ~0, p, w, data_len;
14308   ip4_address_t rloc4;
14309   ip6_address_t rloc6;
14310   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14311
14312   memset (&rloc, 0, sizeof (rloc));
14313
14314   /* Parse args required to build the message */
14315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14316     {
14317       if (unformat (input, "del-all"))
14318         {
14319           del_all = 1;
14320         }
14321       else if (unformat (input, "del"))
14322         {
14323           is_add = 0;
14324         }
14325       else if (unformat (input, "add"))
14326         {
14327           is_add = 1;
14328         }
14329       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14330         {
14331           eid_set = 1;
14332         }
14333       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14334         {
14335           seid_set = 1;
14336         }
14337       else if (unformat (input, "vni %d", &vni))
14338         {
14339           ;
14340         }
14341       else if (unformat (input, "p %d w %d", &p, &w))
14342         {
14343           if (!curr_rloc)
14344             {
14345               errmsg ("No RLOC configured for setting priority/weight!");
14346               return -99;
14347             }
14348           curr_rloc->priority = p;
14349           curr_rloc->weight = w;
14350         }
14351       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14352         {
14353           rloc.is_ip4 = 1;
14354           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14355           vec_add1 (rlocs, rloc);
14356           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14357         }
14358       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14359         {
14360           rloc.is_ip4 = 0;
14361           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14362           vec_add1 (rlocs, rloc);
14363           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14364         }
14365       else if (unformat (input, "action %U",
14366                          unformat_negative_mapping_action, &action))
14367         {
14368           ;
14369         }
14370       else
14371         {
14372           clib_warning ("parse error '%U'", format_unformat_error, input);
14373           return -99;
14374         }
14375     }
14376
14377   if (0 == eid_set)
14378     {
14379       errmsg ("missing params!");
14380       return -99;
14381     }
14382
14383   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14384     {
14385       errmsg ("no action set for negative map-reply!");
14386       return -99;
14387     }
14388
14389   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14390
14391   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14392   mp->is_add = is_add;
14393   mp->vni = htonl (vni);
14394   mp->action = (u8) action;
14395   mp->is_src_dst = seid_set;
14396   mp->eid_len = eid->len;
14397   mp->seid_len = seid->len;
14398   mp->del_all = del_all;
14399   mp->eid_type = eid->type;
14400   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14401   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14402
14403   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14404   clib_memcpy (mp->rlocs, rlocs, data_len);
14405   vec_free (rlocs);
14406
14407   /* send it... */
14408   S;
14409
14410   /* Wait for a reply... */
14411   W;
14412
14413   /* NOTREACHED */
14414   return 0;
14415 }
14416
14417 /**
14418  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14419  * forwarding entries in data-plane accordingly.
14420  *
14421  * @param vam vpp API test context
14422  * @return return code
14423  */
14424 static int
14425 api_lisp_add_del_adjacency (vat_main_t * vam)
14426 {
14427   unformat_input_t *input = vam->input;
14428   vl_api_lisp_add_del_adjacency_t *mp;
14429   f64 timeout = ~0;
14430   u32 vni = 0;
14431   ip4_address_t leid4, reid4;
14432   ip6_address_t leid6, reid6;
14433   u8 reid_mac[6] = { 0 };
14434   u8 leid_mac[6] = { 0 };
14435   u8 reid_type, leid_type;
14436   u32 leid_len = 0, reid_len = 0, len;
14437   u8 is_add = 1;
14438
14439   leid_type = reid_type = (u8) ~ 0;
14440
14441   /* Parse args required to build the message */
14442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14443     {
14444       if (unformat (input, "del"))
14445         {
14446           is_add = 0;
14447         }
14448       else if (unformat (input, "add"))
14449         {
14450           is_add = 1;
14451         }
14452       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14453                          &reid4, &len))
14454         {
14455           reid_type = 0;        /* ipv4 */
14456           reid_len = len;
14457         }
14458       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14459                          &reid6, &len))
14460         {
14461           reid_type = 1;        /* ipv6 */
14462           reid_len = len;
14463         }
14464       else if (unformat (input, "reid %U", unformat_ethernet_address,
14465                          reid_mac))
14466         {
14467           reid_type = 2;        /* mac */
14468         }
14469       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14470                          &leid4, &len))
14471         {
14472           leid_type = 0;        /* ipv4 */
14473           leid_len = len;
14474         }
14475       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14476                          &leid6, &len))
14477         {
14478           leid_type = 1;        /* ipv6 */
14479           leid_len = len;
14480         }
14481       else if (unformat (input, "leid %U", unformat_ethernet_address,
14482                          leid_mac))
14483         {
14484           leid_type = 2;        /* mac */
14485         }
14486       else if (unformat (input, "vni %d", &vni))
14487         {
14488           ;
14489         }
14490       else
14491         {
14492           errmsg ("parse error '%U'", format_unformat_error, input);
14493           return -99;
14494         }
14495     }
14496
14497   if ((u8) ~ 0 == reid_type)
14498     {
14499       errmsg ("missing params!");
14500       return -99;
14501     }
14502
14503   if (leid_type != reid_type)
14504     {
14505       errmsg ("remote and local EIDs are of different types!");
14506       return -99;
14507     }
14508
14509   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14510   mp->is_add = is_add;
14511   mp->vni = htonl (vni);
14512   mp->leid_len = leid_len;
14513   mp->reid_len = reid_len;
14514   mp->eid_type = reid_type;
14515
14516   switch (mp->eid_type)
14517     {
14518     case 0:
14519       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14520       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14521       break;
14522     case 1:
14523       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14524       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14525       break;
14526     case 2:
14527       clib_memcpy (mp->leid, leid_mac, 6);
14528       clib_memcpy (mp->reid, reid_mac, 6);
14529       break;
14530     default:
14531       errmsg ("unknown EID type %d!", mp->eid_type);
14532       return 0;
14533     }
14534
14535   /* send it... */
14536   S;
14537
14538   /* Wait for a reply... */
14539   W;
14540
14541   /* NOTREACHED */
14542   return 0;
14543 }
14544
14545 static int
14546 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14547 {
14548   unformat_input_t *input = vam->input;
14549   vl_api_lisp_gpe_add_del_iface_t *mp;
14550   f64 timeout = ~0;
14551   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14552   u32 dp_table = 0, vni = 0;
14553
14554   /* Parse args required to build the message */
14555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14556     {
14557       if (unformat (input, "up"))
14558         {
14559           action_set = 1;
14560           is_add = 1;
14561         }
14562       else if (unformat (input, "down"))
14563         {
14564           action_set = 1;
14565           is_add = 0;
14566         }
14567       else if (unformat (input, "table_id %d", &dp_table))
14568         {
14569           dp_table_set = 1;
14570         }
14571       else if (unformat (input, "bd_id %d", &dp_table))
14572         {
14573           dp_table_set = 1;
14574           is_l2 = 1;
14575         }
14576       else if (unformat (input, "vni %d", &vni))
14577         {
14578           vni_set = 1;
14579         }
14580       else
14581         break;
14582     }
14583
14584   if (action_set == 0)
14585     {
14586       errmsg ("Action not set");
14587       return -99;
14588     }
14589   if (dp_table_set == 0 || vni_set == 0)
14590     {
14591       errmsg ("vni and dp_table must be set");
14592       return -99;
14593     }
14594
14595   /* Construct the API message */
14596   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14597
14598   mp->is_add = is_add;
14599   mp->dp_table = dp_table;
14600   mp->is_l2 = is_l2;
14601   mp->vni = vni;
14602
14603   /* send it... */
14604   S;
14605
14606   /* Wait for a reply... */
14607   W;
14608
14609   /* NOTREACHED */
14610   return 0;
14611 }
14612
14613 /**
14614  * Add/del map request itr rlocs from LISP control plane and updates
14615  *
14616  * @param vam vpp API test context
14617  * @return return code
14618  */
14619 static int
14620 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14621 {
14622   unformat_input_t *input = vam->input;
14623   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14624   f64 timeout = ~0;
14625   u8 *locator_set_name = 0;
14626   u8 locator_set_name_set = 0;
14627   u8 is_add = 1;
14628
14629   /* Parse args required to build the message */
14630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14631     {
14632       if (unformat (input, "del"))
14633         {
14634           is_add = 0;
14635         }
14636       else if (unformat (input, "%_%v%_", &locator_set_name))
14637         {
14638           locator_set_name_set = 1;
14639         }
14640       else
14641         {
14642           clib_warning ("parse error '%U'", format_unformat_error, input);
14643           return -99;
14644         }
14645     }
14646
14647   if (is_add && !locator_set_name_set)
14648     {
14649       errmsg ("itr-rloc is not set!");
14650       return -99;
14651     }
14652
14653   if (is_add && vec_len (locator_set_name) > 64)
14654     {
14655       errmsg ("itr-rloc locator-set name too long");
14656       vec_free (locator_set_name);
14657       return -99;
14658     }
14659
14660   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14661   mp->is_add = is_add;
14662   if (is_add)
14663     {
14664       clib_memcpy (mp->locator_set_name, locator_set_name,
14665                    vec_len (locator_set_name));
14666     }
14667   else
14668     {
14669       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14670     }
14671   vec_free (locator_set_name);
14672
14673   /* send it... */
14674   S;
14675
14676   /* Wait for a reply... */
14677   W;
14678
14679   /* NOTREACHED */
14680   return 0;
14681 }
14682
14683 static int
14684 api_lisp_locator_dump (vat_main_t * vam)
14685 {
14686   unformat_input_t *input = vam->input;
14687   vl_api_lisp_locator_dump_t *mp;
14688   f64 timeout = ~0;
14689   u8 is_index_set = 0, is_name_set = 0;
14690   u8 *ls_name = 0;
14691   u32 ls_index = ~0;
14692
14693   /* Parse args required to build the message */
14694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14695     {
14696       if (unformat (input, "ls_name %_%v%_", &ls_name))
14697         {
14698           is_name_set = 1;
14699         }
14700       else if (unformat (input, "ls_index %d", &ls_index))
14701         {
14702           is_index_set = 1;
14703         }
14704       else
14705         {
14706           errmsg ("parse error '%U'", format_unformat_error, input);
14707           return -99;
14708         }
14709     }
14710
14711   if (!is_index_set && !is_name_set)
14712     {
14713       errmsg ("error: expected one of index or name!");
14714       return -99;
14715     }
14716
14717   if (is_index_set && is_name_set)
14718     {
14719       errmsg ("error: only one param expected!");
14720       return -99;
14721     }
14722
14723   if (vec_len (ls_name) > 62)
14724     {
14725       errmsg ("error: locator set name too long!");
14726       return -99;
14727     }
14728
14729   if (!vam->json_output)
14730     {
14731       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14732     }
14733
14734   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14735   mp->is_index_set = is_index_set;
14736
14737   if (is_index_set)
14738     mp->ls_index = clib_host_to_net_u32 (ls_index);
14739   else
14740     {
14741       vec_add1 (ls_name, 0);
14742       strncpy ((char *) mp->ls_name, (char *) ls_name,
14743                sizeof (mp->ls_name) - 1);
14744     }
14745
14746   /* send it... */
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   /* Wait for a reply... */
14756   W;
14757
14758   /* NOTREACHED */
14759   return 0;
14760 }
14761
14762 static int
14763 api_lisp_locator_set_dump (vat_main_t * vam)
14764 {
14765   vl_api_lisp_locator_set_dump_t *mp;
14766   unformat_input_t *input = vam->input;
14767   f64 timeout = ~0;
14768   u8 filter = 0;
14769
14770   /* Parse args required to build the message */
14771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14772     {
14773       if (unformat (input, "local"))
14774         {
14775           filter = 1;
14776         }
14777       else if (unformat (input, "remote"))
14778         {
14779           filter = 2;
14780         }
14781       else
14782         {
14783           errmsg ("parse error '%U'", format_unformat_error, input);
14784           return -99;
14785         }
14786     }
14787
14788   if (!vam->json_output)
14789     {
14790       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14791     }
14792
14793   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14794
14795   mp->filter = filter;
14796
14797   /* send it... */
14798   S;
14799
14800   /* Use a control ping for synchronization */
14801   {
14802     vl_api_control_ping_t *mp;
14803     M (CONTROL_PING, control_ping);
14804     S;
14805   }
14806   /* Wait for a reply... */
14807   W;
14808
14809   /* NOTREACHED */
14810   return 0;
14811 }
14812
14813 static int
14814 api_lisp_eid_table_map_dump (vat_main_t * vam)
14815 {
14816   u8 is_l2 = 0;
14817   u8 mode_set = 0;
14818   unformat_input_t *input = vam->input;
14819   vl_api_lisp_eid_table_map_dump_t *mp;
14820   f64 timeout = ~0;
14821
14822   /* Parse args required to build the message */
14823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14824     {
14825       if (unformat (input, "l2"))
14826         {
14827           is_l2 = 1;
14828           mode_set = 1;
14829         }
14830       else if (unformat (input, "l3"))
14831         {
14832           is_l2 = 0;
14833           mode_set = 1;
14834         }
14835       else
14836         {
14837           errmsg ("parse error '%U'", format_unformat_error, input);
14838           return -99;
14839         }
14840     }
14841
14842   if (!mode_set)
14843     {
14844       errmsg ("expected one of 'l2' or 'l3' parameter!");
14845       return -99;
14846     }
14847
14848   if (!vam->json_output)
14849     {
14850       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14851     }
14852
14853   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14854   mp->is_l2 = is_l2;
14855
14856   /* send it... */
14857   S;
14858
14859   /* Use a control ping for synchronization */
14860   {
14861     vl_api_control_ping_t *mp;
14862     M (CONTROL_PING, control_ping);
14863     S;
14864   }
14865   /* Wait for a reply... */
14866   W;
14867
14868   /* NOTREACHED */
14869   return 0;
14870 }
14871
14872 static int
14873 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14874 {
14875   vl_api_lisp_eid_table_vni_dump_t *mp;
14876   f64 timeout = ~0;
14877
14878   if (!vam->json_output)
14879     {
14880       print (vam->ofp, "VNI");
14881     }
14882
14883   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14884
14885   /* send it... */
14886   S;
14887
14888   /* Use a control ping for synchronization */
14889   {
14890     vl_api_control_ping_t *mp;
14891     M (CONTROL_PING, control_ping);
14892     S;
14893   }
14894   /* Wait for a reply... */
14895   W;
14896
14897   /* NOTREACHED */
14898   return 0;
14899 }
14900
14901 static int
14902 api_lisp_eid_table_dump (vat_main_t * vam)
14903 {
14904   unformat_input_t *i = vam->input;
14905   vl_api_lisp_eid_table_dump_t *mp;
14906   f64 timeout = ~0;
14907   struct in_addr ip4;
14908   struct in6_addr ip6;
14909   u8 mac[6];
14910   u8 eid_type = ~0, eid_set = 0;
14911   u32 prefix_length = ~0, t, vni = 0;
14912   u8 filter = 0;
14913
14914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14915     {
14916       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14917         {
14918           eid_set = 1;
14919           eid_type = 0;
14920           prefix_length = t;
14921         }
14922       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14923         {
14924           eid_set = 1;
14925           eid_type = 1;
14926           prefix_length = t;
14927         }
14928       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14929         {
14930           eid_set = 1;
14931           eid_type = 2;
14932         }
14933       else if (unformat (i, "vni %d", &t))
14934         {
14935           vni = t;
14936         }
14937       else if (unformat (i, "local"))
14938         {
14939           filter = 1;
14940         }
14941       else if (unformat (i, "remote"))
14942         {
14943           filter = 2;
14944         }
14945       else
14946         {
14947           errmsg ("parse error '%U'", format_unformat_error, i);
14948           return -99;
14949         }
14950     }
14951
14952   if (!vam->json_output)
14953     {
14954       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14955              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14956     }
14957
14958   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14959
14960   mp->filter = filter;
14961   if (eid_set)
14962     {
14963       mp->eid_set = 1;
14964       mp->vni = htonl (vni);
14965       mp->eid_type = eid_type;
14966       switch (eid_type)
14967         {
14968         case 0:
14969           mp->prefix_length = prefix_length;
14970           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14971           break;
14972         case 1:
14973           mp->prefix_length = prefix_length;
14974           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14975           break;
14976         case 2:
14977           clib_memcpy (mp->eid, mac, sizeof (mac));
14978           break;
14979         default:
14980           errmsg ("unknown EID type %d!", eid_type);
14981           return -99;
14982         }
14983     }
14984
14985   /* send it... */
14986   S;
14987
14988   /* Use a control ping for synchronization */
14989   {
14990     vl_api_control_ping_t *mp;
14991     M (CONTROL_PING, control_ping);
14992     S;
14993   }
14994
14995   /* Wait for a reply... */
14996   W;
14997
14998   /* NOTREACHED */
14999   return 0;
15000 }
15001
15002 static int
15003 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15004 {
15005   unformat_input_t *i = vam->input;
15006   vl_api_lisp_gpe_fwd_entries_get_t *mp;
15007   f64 timeout = ~0;
15008   u8 vni_set = 0;
15009   u32 vni = ~0;
15010
15011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15012     {
15013       if (unformat (i, "vni %d", &vni))
15014         {
15015           vni_set = 1;
15016         }
15017       else
15018         {
15019           errmsg ("parse error '%U'", format_unformat_error, i);
15020           return -99;
15021         }
15022     }
15023
15024   if (!vni_set)
15025     {
15026       errmsg ("vni not set!");
15027       return -99;
15028     }
15029
15030   if (!vam->json_output)
15031     {
15032       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15033              "leid", "reid");
15034     }
15035
15036   M (LISP_GPE_FWD_ENTRIES_GET, lisp_gpe_fwd_entries_get);
15037   mp->vni = clib_host_to_net_u32 (vni);
15038
15039   /* send it... */
15040   S;
15041
15042   /* Wait for a reply... */
15043   W;
15044
15045   /* NOTREACHED */
15046   return 0;
15047 }
15048
15049 #define vl_api_lisp_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15050 #define vl_api_lisp_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15051 #define vl_api_lisp_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15052 #define vl_api_lisp_gpe_fwd_entry_path_details_t_print vl_noop_handler
15053
15054 static int
15055 api_lisp_adjacencies_get (vat_main_t * vam)
15056 {
15057   unformat_input_t *i = vam->input;
15058   vl_api_lisp_adjacencies_get_t *mp;
15059   f64 timeout = ~0;
15060   u8 vni_set = 0;
15061   u32 vni = ~0;
15062
15063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15064     {
15065       if (unformat (i, "vni %d", &vni))
15066         {
15067           vni_set = 1;
15068         }
15069       else
15070         {
15071           errmsg ("parse error '%U'", format_unformat_error, i);
15072           return -99;
15073         }
15074     }
15075
15076   if (!vni_set)
15077     {
15078       errmsg ("vni not set!");
15079       return -99;
15080     }
15081
15082   if (!vam->json_output)
15083     {
15084       print (vam->ofp, "%s %40s", "leid", "reid");
15085     }
15086
15087   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
15088   mp->vni = clib_host_to_net_u32 (vni);
15089
15090   /* send it... */
15091   S;
15092
15093   /* Wait for a reply... */
15094   W;
15095
15096   /* NOTREACHED */
15097   return 0;
15098 }
15099
15100 static int
15101 api_lisp_map_server_dump (vat_main_t * vam)
15102 {
15103   vl_api_lisp_map_server_dump_t *mp;
15104   f64 timeout = ~0;
15105
15106   if (!vam->json_output)
15107     {
15108       print (vam->ofp, "%=20s", "Map server");
15109     }
15110
15111   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
15112   /* send it... */
15113   S;
15114
15115   /* Use a control ping for synchronization */
15116   {
15117     vl_api_control_ping_t *mp;
15118     M (CONTROL_PING, control_ping);
15119     S;
15120   }
15121   /* Wait for a reply... */
15122   W;
15123
15124   /* NOTREACHED */
15125   return 0;
15126 }
15127
15128 static int
15129 api_lisp_map_resolver_dump (vat_main_t * vam)
15130 {
15131   vl_api_lisp_map_resolver_dump_t *mp;
15132   f64 timeout = ~0;
15133
15134   if (!vam->json_output)
15135     {
15136       print (vam->ofp, "%=20s", "Map resolver");
15137     }
15138
15139   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
15140   /* send it... */
15141   S;
15142
15143   /* Use a control ping for synchronization */
15144   {
15145     vl_api_control_ping_t *mp;
15146     M (CONTROL_PING, control_ping);
15147     S;
15148   }
15149   /* Wait for a reply... */
15150   W;
15151
15152   /* NOTREACHED */
15153   return 0;
15154 }
15155
15156 static int
15157 api_show_lisp_status (vat_main_t * vam)
15158 {
15159   vl_api_show_lisp_status_t *mp;
15160   f64 timeout = ~0;
15161
15162   if (!vam->json_output)
15163     {
15164       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
15165     }
15166
15167   M (SHOW_LISP_STATUS, show_lisp_status);
15168   /* send it... */
15169   S;
15170   /* Wait for a reply... */
15171   W;
15172
15173   /* NOTREACHED */
15174   return 0;
15175 }
15176
15177 static int
15178 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15179 {
15180   vl_api_lisp_gpe_fwd_entry_path_dump_t *mp;
15181   f64 timeout = ~0;
15182   unformat_input_t *i = vam->input;
15183   u32 fwd_entry_index = ~0;
15184
15185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15186     {
15187       if (unformat (i, "index %d", &fwd_entry_index))
15188         ;
15189       else
15190         break;
15191     }
15192
15193   if (~0 == fwd_entry_index)
15194     {
15195       errmsg ("no index specified!");
15196       return -99;
15197     }
15198
15199   if (!vam->json_output)
15200     {
15201       print (vam->ofp, "first line");
15202     }
15203
15204   M (LISP_GPE_FWD_ENTRY_PATH_DUMP, lisp_gpe_fwd_entry_path_dump);
15205
15206   /* send it... */
15207   S;
15208   /* Use a control ping for synchronization */
15209   {
15210     vl_api_control_ping_t *mp;
15211     M (CONTROL_PING, control_ping);
15212     S;
15213   }
15214   /* Wait for a reply... */
15215   W;
15216
15217   /* NOTREACHED */
15218   return 0;
15219 }
15220
15221 static int
15222 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
15223 {
15224   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
15225   f64 timeout = ~0;
15226
15227   if (!vam->json_output)
15228     {
15229       print (vam->ofp, "%=20s", "itr-rlocs:");
15230     }
15231
15232   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
15233   /* send it... */
15234   S;
15235   /* Wait for a reply... */
15236   W;
15237
15238   /* NOTREACHED */
15239   return 0;
15240 }
15241
15242 static int
15243 api_af_packet_create (vat_main_t * vam)
15244 {
15245   unformat_input_t *i = vam->input;
15246   vl_api_af_packet_create_t *mp;
15247   f64 timeout;
15248   u8 *host_if_name = 0;
15249   u8 hw_addr[6];
15250   u8 random_hw_addr = 1;
15251
15252   memset (hw_addr, 0, sizeof (hw_addr));
15253
15254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15255     {
15256       if (unformat (i, "name %s", &host_if_name))
15257         vec_add1 (host_if_name, 0);
15258       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15259         random_hw_addr = 0;
15260       else
15261         break;
15262     }
15263
15264   if (!vec_len (host_if_name))
15265     {
15266       errmsg ("host-interface name must be specified");
15267       return -99;
15268     }
15269
15270   if (vec_len (host_if_name) > 64)
15271     {
15272       errmsg ("host-interface name too long");
15273       return -99;
15274     }
15275
15276   M (AF_PACKET_CREATE, af_packet_create);
15277
15278   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15279   clib_memcpy (mp->hw_addr, hw_addr, 6);
15280   mp->use_random_hw_addr = random_hw_addr;
15281   vec_free (host_if_name);
15282
15283   S;
15284   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15285   /* NOTREACHED */
15286   return 0;
15287 }
15288
15289 static int
15290 api_af_packet_delete (vat_main_t * vam)
15291 {
15292   unformat_input_t *i = vam->input;
15293   vl_api_af_packet_delete_t *mp;
15294   f64 timeout;
15295   u8 *host_if_name = 0;
15296
15297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15298     {
15299       if (unformat (i, "name %s", &host_if_name))
15300         vec_add1 (host_if_name, 0);
15301       else
15302         break;
15303     }
15304
15305   if (!vec_len (host_if_name))
15306     {
15307       errmsg ("host-interface name must be specified");
15308       return -99;
15309     }
15310
15311   if (vec_len (host_if_name) > 64)
15312     {
15313       errmsg ("host-interface name too long");
15314       return -99;
15315     }
15316
15317   M (AF_PACKET_DELETE, af_packet_delete);
15318
15319   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15320   vec_free (host_if_name);
15321
15322   S;
15323   W;
15324   /* NOTREACHED */
15325   return 0;
15326 }
15327
15328 static int
15329 api_policer_add_del (vat_main_t * vam)
15330 {
15331   unformat_input_t *i = vam->input;
15332   vl_api_policer_add_del_t *mp;
15333   f64 timeout;
15334   u8 is_add = 1;
15335   u8 *name = 0;
15336   u32 cir = 0;
15337   u32 eir = 0;
15338   u64 cb = 0;
15339   u64 eb = 0;
15340   u8 rate_type = 0;
15341   u8 round_type = 0;
15342   u8 type = 0;
15343   u8 color_aware = 0;
15344   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15345
15346   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15347   conform_action.dscp = 0;
15348   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15349   exceed_action.dscp = 0;
15350   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15351   violate_action.dscp = 0;
15352
15353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15354     {
15355       if (unformat (i, "del"))
15356         is_add = 0;
15357       else if (unformat (i, "name %s", &name))
15358         vec_add1 (name, 0);
15359       else if (unformat (i, "cir %u", &cir))
15360         ;
15361       else if (unformat (i, "eir %u", &eir))
15362         ;
15363       else if (unformat (i, "cb %u", &cb))
15364         ;
15365       else if (unformat (i, "eb %u", &eb))
15366         ;
15367       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15368                          &rate_type))
15369         ;
15370       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15371                          &round_type))
15372         ;
15373       else if (unformat (i, "type %U", unformat_policer_type, &type))
15374         ;
15375       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15376                          &conform_action))
15377         ;
15378       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15379                          &exceed_action))
15380         ;
15381       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15382                          &violate_action))
15383         ;
15384       else if (unformat (i, "color-aware"))
15385         color_aware = 1;
15386       else
15387         break;
15388     }
15389
15390   if (!vec_len (name))
15391     {
15392       errmsg ("policer name must be specified");
15393       return -99;
15394     }
15395
15396   if (vec_len (name) > 64)
15397     {
15398       errmsg ("policer name too long");
15399       return -99;
15400     }
15401
15402   M (POLICER_ADD_DEL, policer_add_del);
15403
15404   clib_memcpy (mp->name, name, vec_len (name));
15405   vec_free (name);
15406   mp->is_add = is_add;
15407   mp->cir = cir;
15408   mp->eir = eir;
15409   mp->cb = cb;
15410   mp->eb = eb;
15411   mp->rate_type = rate_type;
15412   mp->round_type = round_type;
15413   mp->type = type;
15414   mp->conform_action_type = conform_action.action_type;
15415   mp->conform_dscp = conform_action.dscp;
15416   mp->exceed_action_type = exceed_action.action_type;
15417   mp->exceed_dscp = exceed_action.dscp;
15418   mp->violate_action_type = violate_action.action_type;
15419   mp->violate_dscp = violate_action.dscp;
15420   mp->color_aware = color_aware;
15421
15422   S;
15423   W;
15424   /* NOTREACHED */
15425   return 0;
15426 }
15427
15428 static int
15429 api_policer_dump (vat_main_t * vam)
15430 {
15431   unformat_input_t *i = vam->input;
15432   vl_api_policer_dump_t *mp;
15433   f64 timeout = ~0;
15434   u8 *match_name = 0;
15435   u8 match_name_valid = 0;
15436
15437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15438     {
15439       if (unformat (i, "name %s", &match_name))
15440         {
15441           vec_add1 (match_name, 0);
15442           match_name_valid = 1;
15443         }
15444       else
15445         break;
15446     }
15447
15448   M (POLICER_DUMP, policer_dump);
15449   mp->match_name_valid = match_name_valid;
15450   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15451   vec_free (match_name);
15452   /* send it... */
15453   S;
15454
15455   /* Use a control ping for synchronization */
15456   {
15457     vl_api_control_ping_t *mp;
15458     M (CONTROL_PING, control_ping);
15459     S;
15460   }
15461   /* Wait for a reply... */
15462   W;
15463
15464   /* NOTREACHED */
15465   return 0;
15466 }
15467
15468 static int
15469 api_policer_classify_set_interface (vat_main_t * vam)
15470 {
15471   unformat_input_t *i = vam->input;
15472   vl_api_policer_classify_set_interface_t *mp;
15473   f64 timeout;
15474   u32 sw_if_index;
15475   int sw_if_index_set;
15476   u32 ip4_table_index = ~0;
15477   u32 ip6_table_index = ~0;
15478   u32 l2_table_index = ~0;
15479   u8 is_add = 1;
15480
15481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15482     {
15483       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15484         sw_if_index_set = 1;
15485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15486         sw_if_index_set = 1;
15487       else if (unformat (i, "del"))
15488         is_add = 0;
15489       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15490         ;
15491       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15492         ;
15493       else if (unformat (i, "l2-table %d", &l2_table_index))
15494         ;
15495       else
15496         {
15497           clib_warning ("parse error '%U'", format_unformat_error, i);
15498           return -99;
15499         }
15500     }
15501
15502   if (sw_if_index_set == 0)
15503     {
15504       errmsg ("missing interface name or sw_if_index");
15505       return -99;
15506     }
15507
15508   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15509
15510   mp->sw_if_index = ntohl (sw_if_index);
15511   mp->ip4_table_index = ntohl (ip4_table_index);
15512   mp->ip6_table_index = ntohl (ip6_table_index);
15513   mp->l2_table_index = ntohl (l2_table_index);
15514   mp->is_add = is_add;
15515
15516   S;
15517   W;
15518   /* NOTREACHED */
15519   return 0;
15520 }
15521
15522 static int
15523 api_policer_classify_dump (vat_main_t * vam)
15524 {
15525   unformat_input_t *i = vam->input;
15526   vl_api_policer_classify_dump_t *mp;
15527   f64 timeout = ~0;
15528   u8 type = POLICER_CLASSIFY_N_TABLES;
15529
15530   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15531     ;
15532   else
15533     {
15534       errmsg ("classify table type must be specified");
15535       return -99;
15536     }
15537
15538   if (!vam->json_output)
15539     {
15540       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15541     }
15542
15543   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15544   mp->type = type;
15545   /* send it... */
15546   S;
15547
15548   /* Use a control ping for synchronization */
15549   {
15550     vl_api_control_ping_t *mp;
15551     M (CONTROL_PING, control_ping);
15552     S;
15553   }
15554   /* Wait for a reply... */
15555   W;
15556
15557   /* NOTREACHED */
15558   return 0;
15559 }
15560
15561 static int
15562 api_netmap_create (vat_main_t * vam)
15563 {
15564   unformat_input_t *i = vam->input;
15565   vl_api_netmap_create_t *mp;
15566   f64 timeout;
15567   u8 *if_name = 0;
15568   u8 hw_addr[6];
15569   u8 random_hw_addr = 1;
15570   u8 is_pipe = 0;
15571   u8 is_master = 0;
15572
15573   memset (hw_addr, 0, sizeof (hw_addr));
15574
15575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15576     {
15577       if (unformat (i, "name %s", &if_name))
15578         vec_add1 (if_name, 0);
15579       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15580         random_hw_addr = 0;
15581       else if (unformat (i, "pipe"))
15582         is_pipe = 1;
15583       else if (unformat (i, "master"))
15584         is_master = 1;
15585       else if (unformat (i, "slave"))
15586         is_master = 0;
15587       else
15588         break;
15589     }
15590
15591   if (!vec_len (if_name))
15592     {
15593       errmsg ("interface name must be specified");
15594       return -99;
15595     }
15596
15597   if (vec_len (if_name) > 64)
15598     {
15599       errmsg ("interface name too long");
15600       return -99;
15601     }
15602
15603   M (NETMAP_CREATE, netmap_create);
15604
15605   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15606   clib_memcpy (mp->hw_addr, hw_addr, 6);
15607   mp->use_random_hw_addr = random_hw_addr;
15608   mp->is_pipe = is_pipe;
15609   mp->is_master = is_master;
15610   vec_free (if_name);
15611
15612   S;
15613   W;
15614   /* NOTREACHED */
15615   return 0;
15616 }
15617
15618 static int
15619 api_netmap_delete (vat_main_t * vam)
15620 {
15621   unformat_input_t *i = vam->input;
15622   vl_api_netmap_delete_t *mp;
15623   f64 timeout;
15624   u8 *if_name = 0;
15625
15626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15627     {
15628       if (unformat (i, "name %s", &if_name))
15629         vec_add1 (if_name, 0);
15630       else
15631         break;
15632     }
15633
15634   if (!vec_len (if_name))
15635     {
15636       errmsg ("interface name must be specified");
15637       return -99;
15638     }
15639
15640   if (vec_len (if_name) > 64)
15641     {
15642       errmsg ("interface name too long");
15643       return -99;
15644     }
15645
15646   M (NETMAP_DELETE, netmap_delete);
15647
15648   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15649   vec_free (if_name);
15650
15651   S;
15652   W;
15653   /* NOTREACHED */
15654   return 0;
15655 }
15656
15657 static void vl_api_mpls_tunnel_details_t_handler
15658   (vl_api_mpls_tunnel_details_t * mp)
15659 {
15660   vat_main_t *vam = &vat_main;
15661   i32 len = mp->mt_next_hop_n_labels;
15662   i32 i;
15663
15664   print (vam->ofp, "[%d]: via %U %d labels ",
15665          mp->tunnel_index,
15666          format_ip4_address, mp->mt_next_hop,
15667          ntohl (mp->mt_next_hop_sw_if_index));
15668   for (i = 0; i < len; i++)
15669     {
15670       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15671     }
15672   print (vam->ofp, "");
15673 }
15674
15675 static void vl_api_mpls_tunnel_details_t_handler_json
15676   (vl_api_mpls_tunnel_details_t * mp)
15677 {
15678   vat_main_t *vam = &vat_main;
15679   vat_json_node_t *node = NULL;
15680   struct in_addr ip4;
15681   i32 i;
15682   i32 len = mp->mt_next_hop_n_labels;
15683
15684   if (VAT_JSON_ARRAY != vam->json_tree.type)
15685     {
15686       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15687       vat_json_init_array (&vam->json_tree);
15688     }
15689   node = vat_json_array_add (&vam->json_tree);
15690
15691   vat_json_init_object (node);
15692   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15693   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15694   vat_json_object_add_ip4 (node, "next_hop", ip4);
15695   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15696                             ntohl (mp->mt_next_hop_sw_if_index));
15697   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15698   vat_json_object_add_uint (node, "label_count", len);
15699   for (i = 0; i < len; i++)
15700     {
15701       vat_json_object_add_uint (node, "label",
15702                                 ntohl (mp->mt_next_hop_out_labels[i]));
15703     }
15704 }
15705
15706 static int
15707 api_mpls_tunnel_dump (vat_main_t * vam)
15708 {
15709   vl_api_mpls_tunnel_dump_t *mp;
15710   f64 timeout;
15711   i32 index = -1;
15712
15713   /* Parse args required to build the message */
15714   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15715     {
15716       if (!unformat (vam->input, "tunnel_index %d", &index))
15717         {
15718           index = -1;
15719           break;
15720         }
15721     }
15722
15723   print (vam->ofp, "  tunnel_index %d", index);
15724
15725   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15726   mp->tunnel_index = htonl (index);
15727   S;
15728
15729   /* Use a control ping for synchronization */
15730   {
15731     vl_api_control_ping_t *mp;
15732     M (CONTROL_PING, control_ping);
15733     S;
15734   }
15735   W;
15736 }
15737
15738 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15739 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15740
15741 static void
15742 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15743 {
15744   vat_main_t *vam = &vat_main;
15745   int count = ntohl (mp->count);
15746   vl_api_fib_path2_t *fp;
15747   int i;
15748
15749   print (vam->ofp,
15750          "table-id %d, label %u, ess_bit %u",
15751          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15752   fp = mp->path;
15753   for (i = 0; i < count; i++)
15754     {
15755       if (fp->afi == IP46_TYPE_IP6)
15756         print (vam->ofp,
15757                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15758                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15759                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15760                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15761                format_ip6_address, fp->next_hop);
15762       else if (fp->afi == IP46_TYPE_IP4)
15763         print (vam->ofp,
15764                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15765                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15766                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15767                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15768                format_ip4_address, fp->next_hop);
15769       fp++;
15770     }
15771 }
15772
15773 static void vl_api_mpls_fib_details_t_handler_json
15774   (vl_api_mpls_fib_details_t * mp)
15775 {
15776   vat_main_t *vam = &vat_main;
15777   int count = ntohl (mp->count);
15778   vat_json_node_t *node = NULL;
15779   struct in_addr ip4;
15780   struct in6_addr ip6;
15781   vl_api_fib_path2_t *fp;
15782   int i;
15783
15784   if (VAT_JSON_ARRAY != vam->json_tree.type)
15785     {
15786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15787       vat_json_init_array (&vam->json_tree);
15788     }
15789   node = vat_json_array_add (&vam->json_tree);
15790
15791   vat_json_init_object (node);
15792   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15793   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15794   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15795   vat_json_object_add_uint (node, "path_count", count);
15796   fp = mp->path;
15797   for (i = 0; i < count; i++)
15798     {
15799       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15800       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15801       vat_json_object_add_uint (node, "is_local", fp->is_local);
15802       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15803       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15804       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15805       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15806       if (fp->afi == IP46_TYPE_IP4)
15807         {
15808           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15809           vat_json_object_add_ip4 (node, "next_hop", ip4);
15810         }
15811       else if (fp->afi == IP46_TYPE_IP6)
15812         {
15813           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15814           vat_json_object_add_ip6 (node, "next_hop", ip6);
15815         }
15816     }
15817 }
15818
15819 static int
15820 api_mpls_fib_dump (vat_main_t * vam)
15821 {
15822   vl_api_mpls_fib_dump_t *mp;
15823   f64 timeout;
15824
15825   M (MPLS_FIB_DUMP, mpls_fib_dump);
15826   S;
15827
15828   /* Use a control ping for synchronization */
15829   {
15830     vl_api_control_ping_t *mp;
15831     M (CONTROL_PING, control_ping);
15832     S;
15833   }
15834   W;
15835 }
15836
15837 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15838 #define vl_api_ip_fib_details_t_print vl_noop_handler
15839
15840 static void
15841 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15842 {
15843   vat_main_t *vam = &vat_main;
15844   int count = ntohl (mp->count);
15845   vl_api_fib_path_t *fp;
15846   int i;
15847
15848   print (vam->ofp,
15849          "table-id %d, prefix %U/%d",
15850          ntohl (mp->table_id), format_ip4_address, mp->address,
15851          mp->address_length);
15852   fp = mp->path;
15853   for (i = 0; i < count; i++)
15854     {
15855       if (fp->afi == IP46_TYPE_IP6)
15856         print (vam->ofp,
15857                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15858                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15859                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15860                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15861                format_ip6_address, fp->next_hop);
15862       else if (fp->afi == IP46_TYPE_IP4)
15863         print (vam->ofp,
15864                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15865                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15866                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15867                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15868                format_ip4_address, fp->next_hop);
15869       fp++;
15870     }
15871 }
15872
15873 static void vl_api_ip_fib_details_t_handler_json
15874   (vl_api_ip_fib_details_t * mp)
15875 {
15876   vat_main_t *vam = &vat_main;
15877   int count = ntohl (mp->count);
15878   vat_json_node_t *node = NULL;
15879   struct in_addr ip4;
15880   struct in6_addr ip6;
15881   vl_api_fib_path_t *fp;
15882   int i;
15883
15884   if (VAT_JSON_ARRAY != vam->json_tree.type)
15885     {
15886       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15887       vat_json_init_array (&vam->json_tree);
15888     }
15889   node = vat_json_array_add (&vam->json_tree);
15890
15891   vat_json_init_object (node);
15892   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15893   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15894   vat_json_object_add_ip4 (node, "prefix", ip4);
15895   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15896   vat_json_object_add_uint (node, "path_count", count);
15897   fp = mp->path;
15898   for (i = 0; i < count; i++)
15899     {
15900       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15901       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15902       vat_json_object_add_uint (node, "is_local", fp->is_local);
15903       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15904       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15905       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15906       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15907       if (fp->afi == IP46_TYPE_IP4)
15908         {
15909           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15910           vat_json_object_add_ip4 (node, "next_hop", ip4);
15911         }
15912       else if (fp->afi == IP46_TYPE_IP6)
15913         {
15914           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15915           vat_json_object_add_ip6 (node, "next_hop", ip6);
15916         }
15917     }
15918 }
15919
15920 static int
15921 api_ip_fib_dump (vat_main_t * vam)
15922 {
15923   vl_api_ip_fib_dump_t *mp;
15924   f64 timeout;
15925
15926   M (IP_FIB_DUMP, ip_fib_dump);
15927   S;
15928
15929   /* Use a control ping for synchronization */
15930   {
15931     vl_api_control_ping_t *mp;
15932     M (CONTROL_PING, control_ping);
15933     S;
15934   }
15935   W;
15936 }
15937
15938 static void vl_api_ip_neighbor_details_t_handler
15939   (vl_api_ip_neighbor_details_t * mp)
15940 {
15941   vat_main_t *vam = &vat_main;
15942
15943   print (vam->ofp, "%c %U %U",
15944          (mp->is_static) ? 'S' : 'D',
15945          format_ethernet_address, &mp->mac_address,
15946          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15947          &mp->ip_address);
15948 }
15949
15950 static void vl_api_ip_neighbor_details_t_handler_json
15951   (vl_api_ip_neighbor_details_t * mp)
15952 {
15953
15954   vat_main_t *vam = &vat_main;
15955   vat_json_node_t *node;
15956   struct in_addr ip4;
15957   struct in6_addr ip6;
15958
15959   if (VAT_JSON_ARRAY != vam->json_tree.type)
15960     {
15961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15962       vat_json_init_array (&vam->json_tree);
15963     }
15964   node = vat_json_array_add (&vam->json_tree);
15965
15966   vat_json_init_object (node);
15967   vat_json_object_add_string_copy (node, "flag",
15968                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15969                                    "dynamic");
15970
15971   vat_json_object_add_string_copy (node, "link_layer",
15972                                    format (0, "%U", format_ethernet_address,
15973                                            &mp->mac_address));
15974
15975   if (mp->is_ipv6)
15976     {
15977       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15978       vat_json_object_add_ip6 (node, "ip_address", ip6);
15979     }
15980   else
15981     {
15982       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15983       vat_json_object_add_ip4 (node, "ip_address", ip4);
15984     }
15985 }
15986
15987 static int
15988 api_ip_neighbor_dump (vat_main_t * vam)
15989 {
15990   unformat_input_t *i = vam->input;
15991   vl_api_ip_neighbor_dump_t *mp;
15992   f64 timeout;
15993   u8 is_ipv6 = 0;
15994   u32 sw_if_index = ~0;
15995
15996   /* Parse args required to build the message */
15997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15998     {
15999       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16000         ;
16001       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16002         ;
16003       else if (unformat (i, "ip6"))
16004         is_ipv6 = 1;
16005       else
16006         break;
16007     }
16008
16009   if (sw_if_index == ~0)
16010     {
16011       errmsg ("missing interface name or sw_if_index");
16012       return -99;
16013     }
16014
16015   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
16016   mp->is_ipv6 = (u8) is_ipv6;
16017   mp->sw_if_index = ntohl (sw_if_index);
16018   S;
16019
16020   /* Use a control ping for synchronization */
16021   {
16022     vl_api_control_ping_t *mp;
16023     M (CONTROL_PING, control_ping);
16024     S;
16025   }
16026   W;
16027 }
16028
16029 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16030 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16031
16032 static void
16033 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16034 {
16035   vat_main_t *vam = &vat_main;
16036   int count = ntohl (mp->count);
16037   vl_api_fib_path_t *fp;
16038   int i;
16039
16040   print (vam->ofp,
16041          "table-id %d, prefix %U/%d",
16042          ntohl (mp->table_id), format_ip6_address, mp->address,
16043          mp->address_length);
16044   fp = mp->path;
16045   for (i = 0; i < count; i++)
16046     {
16047       if (fp->afi == IP46_TYPE_IP6)
16048         print (vam->ofp,
16049                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16050                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16051                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16052                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16053                format_ip6_address, fp->next_hop);
16054       else if (fp->afi == IP46_TYPE_IP4)
16055         print (vam->ofp,
16056                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16057                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16058                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16059                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16060                format_ip4_address, fp->next_hop);
16061       fp++;
16062     }
16063 }
16064
16065 static void vl_api_ip6_fib_details_t_handler_json
16066   (vl_api_ip6_fib_details_t * mp)
16067 {
16068   vat_main_t *vam = &vat_main;
16069   int count = ntohl (mp->count);
16070   vat_json_node_t *node = NULL;
16071   struct in_addr ip4;
16072   struct in6_addr ip6;
16073   vl_api_fib_path_t *fp;
16074   int i;
16075
16076   if (VAT_JSON_ARRAY != vam->json_tree.type)
16077     {
16078       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16079       vat_json_init_array (&vam->json_tree);
16080     }
16081   node = vat_json_array_add (&vam->json_tree);
16082
16083   vat_json_init_object (node);
16084   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16085   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16086   vat_json_object_add_ip6 (node, "prefix", ip6);
16087   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16088   vat_json_object_add_uint (node, "path_count", count);
16089   fp = mp->path;
16090   for (i = 0; i < count; i++)
16091     {
16092       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16093       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16094       vat_json_object_add_uint (node, "is_local", fp->is_local);
16095       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16096       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16097       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16098       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16099       if (fp->afi == IP46_TYPE_IP4)
16100         {
16101           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16102           vat_json_object_add_ip4 (node, "next_hop", ip4);
16103         }
16104       else if (fp->afi == IP46_TYPE_IP6)
16105         {
16106           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16107           vat_json_object_add_ip6 (node, "next_hop", ip6);
16108         }
16109     }
16110 }
16111
16112 static int
16113 api_ip6_fib_dump (vat_main_t * vam)
16114 {
16115   vl_api_ip6_fib_dump_t *mp;
16116   f64 timeout;
16117
16118   M (IP6_FIB_DUMP, ip6_fib_dump);
16119   S;
16120
16121   /* Use a control ping for synchronization */
16122   {
16123     vl_api_control_ping_t *mp;
16124     M (CONTROL_PING, control_ping);
16125     S;
16126   }
16127   W;
16128 }
16129
16130 int
16131 api_classify_table_ids (vat_main_t * vam)
16132 {
16133   vl_api_classify_table_ids_t *mp;
16134   f64 timeout;
16135
16136   /* Construct the API message */
16137   M (CLASSIFY_TABLE_IDS, classify_table_ids);
16138   mp->context = 0;
16139
16140   S;
16141   W;
16142   /* NOTREACHED */
16143   return 0;
16144 }
16145
16146 int
16147 api_classify_table_by_interface (vat_main_t * vam)
16148 {
16149   unformat_input_t *input = vam->input;
16150   vl_api_classify_table_by_interface_t *mp;
16151   f64 timeout;
16152
16153   u32 sw_if_index = ~0;
16154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16155     {
16156       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16157         ;
16158       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16159         ;
16160       else
16161         break;
16162     }
16163   if (sw_if_index == ~0)
16164     {
16165       errmsg ("missing interface name or sw_if_index");
16166       return -99;
16167     }
16168
16169   /* Construct the API message */
16170   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
16171   mp->context = 0;
16172   mp->sw_if_index = ntohl (sw_if_index);
16173
16174   S;
16175   W;
16176   /* NOTREACHED */
16177   return 0;
16178 }
16179
16180 int
16181 api_classify_table_info (vat_main_t * vam)
16182 {
16183   unformat_input_t *input = vam->input;
16184   vl_api_classify_table_info_t *mp;
16185   f64 timeout;
16186
16187   u32 table_id = ~0;
16188   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16189     {
16190       if (unformat (input, "table_id %d", &table_id))
16191         ;
16192       else
16193         break;
16194     }
16195   if (table_id == ~0)
16196     {
16197       errmsg ("missing table id");
16198       return -99;
16199     }
16200
16201   /* Construct the API message */
16202   M (CLASSIFY_TABLE_INFO, classify_table_info);
16203   mp->context = 0;
16204   mp->table_id = ntohl (table_id);
16205
16206   S;
16207   W;
16208   /* NOTREACHED */
16209   return 0;
16210 }
16211
16212 int
16213 api_classify_session_dump (vat_main_t * vam)
16214 {
16215   unformat_input_t *input = vam->input;
16216   vl_api_classify_session_dump_t *mp;
16217   f64 timeout;
16218
16219   u32 table_id = ~0;
16220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16221     {
16222       if (unformat (input, "table_id %d", &table_id))
16223         ;
16224       else
16225         break;
16226     }
16227   if (table_id == ~0)
16228     {
16229       errmsg ("missing table id");
16230       return -99;
16231     }
16232
16233   /* Construct the API message */
16234   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
16235   mp->context = 0;
16236   mp->table_id = ntohl (table_id);
16237   S;
16238
16239   /* Use a control ping for synchronization */
16240   {
16241     vl_api_control_ping_t *mp;
16242     M (CONTROL_PING, control_ping);
16243     S;
16244   }
16245   W;
16246   /* NOTREACHED */
16247   return 0;
16248 }
16249
16250 static void
16251 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16252 {
16253   vat_main_t *vam = &vat_main;
16254
16255   print (vam->ofp, "collector_address %U, collector_port %d, "
16256          "src_address %U, vrf_id %d, path_mtu %u, "
16257          "template_interval %u, udp_checksum %d",
16258          format_ip4_address, mp->collector_address,
16259          ntohs (mp->collector_port),
16260          format_ip4_address, mp->src_address,
16261          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16262          ntohl (mp->template_interval), mp->udp_checksum);
16263
16264   vam->retval = 0;
16265   vam->result_ready = 1;
16266 }
16267
16268 static void
16269   vl_api_ipfix_exporter_details_t_handler_json
16270   (vl_api_ipfix_exporter_details_t * mp)
16271 {
16272   vat_main_t *vam = &vat_main;
16273   vat_json_node_t node;
16274   struct in_addr collector_address;
16275   struct in_addr src_address;
16276
16277   vat_json_init_object (&node);
16278   clib_memcpy (&collector_address, &mp->collector_address,
16279                sizeof (collector_address));
16280   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16281   vat_json_object_add_uint (&node, "collector_port",
16282                             ntohs (mp->collector_port));
16283   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16284   vat_json_object_add_ip4 (&node, "src_address", src_address);
16285   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16286   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16287   vat_json_object_add_uint (&node, "template_interval",
16288                             ntohl (mp->template_interval));
16289   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16290
16291   vat_json_print (vam->ofp, &node);
16292   vat_json_free (&node);
16293   vam->retval = 0;
16294   vam->result_ready = 1;
16295 }
16296
16297 int
16298 api_ipfix_exporter_dump (vat_main_t * vam)
16299 {
16300   vl_api_ipfix_exporter_dump_t *mp;
16301   f64 timeout;
16302
16303   /* Construct the API message */
16304   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
16305   mp->context = 0;
16306
16307   S;
16308   W;
16309   /* NOTREACHED */
16310   return 0;
16311 }
16312
16313 static int
16314 api_ipfix_classify_stream_dump (vat_main_t * vam)
16315 {
16316   vl_api_ipfix_classify_stream_dump_t *mp;
16317   f64 timeout;
16318
16319   /* Construct the API message */
16320   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
16321   mp->context = 0;
16322
16323   S;
16324   W;
16325   /* NOTREACHED */
16326   return 0;
16327 }
16328
16329 static void
16330   vl_api_ipfix_classify_stream_details_t_handler
16331   (vl_api_ipfix_classify_stream_details_t * mp)
16332 {
16333   vat_main_t *vam = &vat_main;
16334   print (vam->ofp, "domain_id %d, src_port %d",
16335          ntohl (mp->domain_id), ntohs (mp->src_port));
16336   vam->retval = 0;
16337   vam->result_ready = 1;
16338 }
16339
16340 static void
16341   vl_api_ipfix_classify_stream_details_t_handler_json
16342   (vl_api_ipfix_classify_stream_details_t * mp)
16343 {
16344   vat_main_t *vam = &vat_main;
16345   vat_json_node_t node;
16346
16347   vat_json_init_object (&node);
16348   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16349   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16350
16351   vat_json_print (vam->ofp, &node);
16352   vat_json_free (&node);
16353   vam->retval = 0;
16354   vam->result_ready = 1;
16355 }
16356
16357 static int
16358 api_ipfix_classify_table_dump (vat_main_t * vam)
16359 {
16360   vl_api_ipfix_classify_table_dump_t *mp;
16361   f64 timeout;
16362
16363   if (!vam->json_output)
16364     {
16365       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16366              "transport_protocol");
16367     }
16368
16369   /* Construct the API message */
16370   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
16371
16372   /* send it... */
16373   S;
16374
16375   /* Use a control ping for synchronization */
16376   {
16377     vl_api_control_ping_t *mp;
16378     M (CONTROL_PING, control_ping);
16379     S;
16380   }
16381   W;
16382 }
16383
16384 static void
16385   vl_api_ipfix_classify_table_details_t_handler
16386   (vl_api_ipfix_classify_table_details_t * mp)
16387 {
16388   vat_main_t *vam = &vat_main;
16389   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16390          mp->transport_protocol);
16391 }
16392
16393 static void
16394   vl_api_ipfix_classify_table_details_t_handler_json
16395   (vl_api_ipfix_classify_table_details_t * mp)
16396 {
16397   vat_json_node_t *node = NULL;
16398   vat_main_t *vam = &vat_main;
16399
16400   if (VAT_JSON_ARRAY != vam->json_tree.type)
16401     {
16402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16403       vat_json_init_array (&vam->json_tree);
16404     }
16405
16406   node = vat_json_array_add (&vam->json_tree);
16407   vat_json_init_object (node);
16408
16409   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16410   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16411   vat_json_object_add_uint (node, "transport_protocol",
16412                             mp->transport_protocol);
16413 }
16414
16415 static int
16416 api_sw_interface_span_enable_disable (vat_main_t * vam)
16417 {
16418   unformat_input_t *i = vam->input;
16419   vl_api_sw_interface_span_enable_disable_t *mp;
16420   f64 timeout;
16421   u32 src_sw_if_index = ~0;
16422   u32 dst_sw_if_index = ~0;
16423   u8 state = 3;
16424
16425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16426     {
16427       if (unformat
16428           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16429         ;
16430       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16431         ;
16432       else
16433         if (unformat
16434             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16435         ;
16436       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16437         ;
16438       else if (unformat (i, "disable"))
16439         state = 0;
16440       else if (unformat (i, "rx"))
16441         state = 1;
16442       else if (unformat (i, "tx"))
16443         state = 2;
16444       else if (unformat (i, "both"))
16445         state = 3;
16446       else
16447         break;
16448     }
16449
16450   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16451
16452   mp->sw_if_index_from = htonl (src_sw_if_index);
16453   mp->sw_if_index_to = htonl (dst_sw_if_index);
16454   mp->state = state;
16455
16456   S;
16457   W;
16458   /* NOTREACHED */
16459   return 0;
16460 }
16461
16462 static void
16463 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16464                                             * mp)
16465 {
16466   vat_main_t *vam = &vat_main;
16467   u8 *sw_if_from_name = 0;
16468   u8 *sw_if_to_name = 0;
16469   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16470   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16471   char *states[] = { "none", "rx", "tx", "both" };
16472   hash_pair_t *p;
16473
16474   /* *INDENT-OFF* */
16475   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16476   ({
16477     if ((u32) p->value[0] == sw_if_index_from)
16478       {
16479         sw_if_from_name = (u8 *)(p->key);
16480         if (sw_if_to_name)
16481           break;
16482       }
16483     if ((u32) p->value[0] == sw_if_index_to)
16484       {
16485         sw_if_to_name = (u8 *)(p->key);
16486         if (sw_if_from_name)
16487           break;
16488       }
16489   }));
16490   /* *INDENT-ON* */
16491   print (vam->ofp, "%20s => %20s (%s)",
16492          sw_if_from_name, sw_if_to_name, states[mp->state]);
16493 }
16494
16495 static void
16496   vl_api_sw_interface_span_details_t_handler_json
16497   (vl_api_sw_interface_span_details_t * mp)
16498 {
16499   vat_main_t *vam = &vat_main;
16500   vat_json_node_t *node = NULL;
16501   u8 *sw_if_from_name = 0;
16502   u8 *sw_if_to_name = 0;
16503   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16504   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16505   hash_pair_t *p;
16506
16507   /* *INDENT-OFF* */
16508   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16509   ({
16510     if ((u32) p->value[0] == sw_if_index_from)
16511       {
16512         sw_if_from_name = (u8 *)(p->key);
16513         if (sw_if_to_name)
16514           break;
16515       }
16516     if ((u32) p->value[0] == sw_if_index_to)
16517       {
16518         sw_if_to_name = (u8 *)(p->key);
16519         if (sw_if_from_name)
16520           break;
16521       }
16522   }));
16523   /* *INDENT-ON* */
16524
16525   if (VAT_JSON_ARRAY != vam->json_tree.type)
16526     {
16527       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16528       vat_json_init_array (&vam->json_tree);
16529     }
16530   node = vat_json_array_add (&vam->json_tree);
16531
16532   vat_json_init_object (node);
16533   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16534   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16535   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16536   if (0 != sw_if_to_name)
16537     {
16538       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16539     }
16540   vat_json_object_add_uint (node, "state", mp->state);
16541 }
16542
16543 static int
16544 api_sw_interface_span_dump (vat_main_t * vam)
16545 {
16546   vl_api_sw_interface_span_dump_t *mp;
16547   f64 timeout;
16548
16549   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16550   S;
16551
16552   /* Use a control ping for synchronization */
16553   {
16554     vl_api_control_ping_t *mp;
16555     M (CONTROL_PING, control_ping);
16556     S;
16557   }
16558   W;
16559 }
16560
16561 int
16562 api_pg_create_interface (vat_main_t * vam)
16563 {
16564   unformat_input_t *input = vam->input;
16565   vl_api_pg_create_interface_t *mp;
16566   f64 timeout;
16567
16568   u32 if_id = ~0;
16569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16570     {
16571       if (unformat (input, "if_id %d", &if_id))
16572         ;
16573       else
16574         break;
16575     }
16576   if (if_id == ~0)
16577     {
16578       errmsg ("missing pg interface index");
16579       return -99;
16580     }
16581
16582   /* Construct the API message */
16583   M (PG_CREATE_INTERFACE, pg_create_interface);
16584   mp->context = 0;
16585   mp->interface_id = ntohl (if_id);
16586
16587   S;
16588   W;
16589   /* NOTREACHED */
16590   return 0;
16591 }
16592
16593 int
16594 api_pg_capture (vat_main_t * vam)
16595 {
16596   unformat_input_t *input = vam->input;
16597   vl_api_pg_capture_t *mp;
16598   f64 timeout;
16599
16600   u32 if_id = ~0;
16601   u8 enable = 1;
16602   u32 count = 1;
16603   u8 pcap_file_set = 0;
16604   u8 *pcap_file = 0;
16605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16606     {
16607       if (unformat (input, "if_id %d", &if_id))
16608         ;
16609       else if (unformat (input, "pcap %s", &pcap_file))
16610         pcap_file_set = 1;
16611       else if (unformat (input, "count %d", &count))
16612         ;
16613       else if (unformat (input, "disable"))
16614         enable = 0;
16615       else
16616         break;
16617     }
16618   if (if_id == ~0)
16619     {
16620       errmsg ("missing pg interface index");
16621       return -99;
16622     }
16623   if (pcap_file_set > 0)
16624     {
16625       if (vec_len (pcap_file) > 255)
16626         {
16627           errmsg ("pcap file name is too long");
16628           return -99;
16629         }
16630     }
16631
16632   u32 name_len = vec_len (pcap_file);
16633   /* Construct the API message */
16634   M (PG_CAPTURE, pg_capture);
16635   mp->context = 0;
16636   mp->interface_id = ntohl (if_id);
16637   mp->is_enabled = enable;
16638   mp->count = ntohl (count);
16639   mp->pcap_name_length = ntohl (name_len);
16640   if (pcap_file_set != 0)
16641     {
16642       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16643     }
16644   vec_free (pcap_file);
16645
16646   S;
16647   W;
16648   /* NOTREACHED */
16649   return 0;
16650 }
16651
16652 int
16653 api_pg_enable_disable (vat_main_t * vam)
16654 {
16655   unformat_input_t *input = vam->input;
16656   vl_api_pg_enable_disable_t *mp;
16657   f64 timeout;
16658
16659   u8 enable = 1;
16660   u8 stream_name_set = 0;
16661   u8 *stream_name = 0;
16662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16663     {
16664       if (unformat (input, "stream %s", &stream_name))
16665         stream_name_set = 1;
16666       else if (unformat (input, "disable"))
16667         enable = 0;
16668       else
16669         break;
16670     }
16671
16672   if (stream_name_set > 0)
16673     {
16674       if (vec_len (stream_name) > 255)
16675         {
16676           errmsg ("stream name too long");
16677           return -99;
16678         }
16679     }
16680
16681   u32 name_len = vec_len (stream_name);
16682   /* Construct the API message */
16683   M (PG_ENABLE_DISABLE, pg_enable_disable);
16684   mp->context = 0;
16685   mp->is_enabled = enable;
16686   if (stream_name_set != 0)
16687     {
16688       mp->stream_name_length = ntohl (name_len);
16689       clib_memcpy (mp->stream_name, stream_name, name_len);
16690     }
16691   vec_free (stream_name);
16692
16693   S;
16694   W;
16695   /* NOTREACHED */
16696   return 0;
16697 }
16698
16699 int
16700 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16701 {
16702   unformat_input_t *input = vam->input;
16703   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16704   f64 timeout;
16705
16706   u16 *low_ports = 0;
16707   u16 *high_ports = 0;
16708   u16 this_low;
16709   u16 this_hi;
16710   ip4_address_t ip4_addr;
16711   ip6_address_t ip6_addr;
16712   u32 length;
16713   u32 tmp, tmp2;
16714   u8 prefix_set = 0;
16715   u32 vrf_id = ~0;
16716   u8 is_add = 1;
16717   u8 is_ipv6 = 0;
16718
16719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16720     {
16721       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16722         {
16723           prefix_set = 1;
16724         }
16725       else
16726         if (unformat
16727             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16728         {
16729           prefix_set = 1;
16730           is_ipv6 = 1;
16731         }
16732       else if (unformat (input, "vrf %d", &vrf_id))
16733         ;
16734       else if (unformat (input, "del"))
16735         is_add = 0;
16736       else if (unformat (input, "port %d", &tmp))
16737         {
16738           if (tmp == 0 || tmp > 65535)
16739             {
16740               errmsg ("port %d out of range", tmp);
16741               return -99;
16742             }
16743           this_low = tmp;
16744           this_hi = this_low + 1;
16745           vec_add1 (low_ports, this_low);
16746           vec_add1 (high_ports, this_hi);
16747         }
16748       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16749         {
16750           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16751             {
16752               errmsg ("incorrect range parameters");
16753               return -99;
16754             }
16755           this_low = tmp;
16756           /* Note: in debug CLI +1 is added to high before
16757              passing to real fn that does "the work"
16758              (ip_source_and_port_range_check_add_del).
16759              This fn is a wrapper around the binary API fn a
16760              control plane will call, which expects this increment
16761              to have occurred. Hence letting the binary API control
16762              plane fn do the increment for consistency between VAT
16763              and other control planes.
16764            */
16765           this_hi = tmp2;
16766           vec_add1 (low_ports, this_low);
16767           vec_add1 (high_ports, this_hi);
16768         }
16769       else
16770         break;
16771     }
16772
16773   if (prefix_set == 0)
16774     {
16775       errmsg ("<address>/<mask> not specified");
16776       return -99;
16777     }
16778
16779   if (vrf_id == ~0)
16780     {
16781       errmsg ("VRF ID required, not specified");
16782       return -99;
16783     }
16784
16785   if (vrf_id == 0)
16786     {
16787       errmsg
16788         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16789       return -99;
16790     }
16791
16792   if (vec_len (low_ports) == 0)
16793     {
16794       errmsg ("At least one port or port range required");
16795       return -99;
16796     }
16797
16798   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16799      ip_source_and_port_range_check_add_del);
16800
16801   mp->is_add = is_add;
16802
16803   if (is_ipv6)
16804     {
16805       mp->is_ipv6 = 1;
16806       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16807     }
16808   else
16809     {
16810       mp->is_ipv6 = 0;
16811       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16812     }
16813
16814   mp->mask_length = length;
16815   mp->number_of_ranges = vec_len (low_ports);
16816
16817   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16818   vec_free (low_ports);
16819
16820   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16821   vec_free (high_ports);
16822
16823   mp->vrf_id = ntohl (vrf_id);
16824
16825   S;
16826   W;
16827   /* NOTREACHED */
16828   return 0;
16829 }
16830
16831 int
16832 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16833 {
16834   unformat_input_t *input = vam->input;
16835   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16836   f64 timeout;
16837   u32 sw_if_index = ~0;
16838   int vrf_set = 0;
16839   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16840   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16841   u8 is_add = 1;
16842
16843   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16844     {
16845       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16846         ;
16847       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16848         ;
16849       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16850         vrf_set = 1;
16851       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16852         vrf_set = 1;
16853       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16854         vrf_set = 1;
16855       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16856         vrf_set = 1;
16857       else if (unformat (input, "del"))
16858         is_add = 0;
16859       else
16860         break;
16861     }
16862
16863   if (sw_if_index == ~0)
16864     {
16865       errmsg ("Interface required but not specified");
16866       return -99;
16867     }
16868
16869   if (vrf_set == 0)
16870     {
16871       errmsg ("VRF ID required but not specified");
16872       return -99;
16873     }
16874
16875   if (tcp_out_vrf_id == 0
16876       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16877     {
16878       errmsg
16879         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16880       return -99;
16881     }
16882
16883   /* Construct the API message */
16884   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16885      ip_source_and_port_range_check_interface_add_del);
16886
16887   mp->sw_if_index = ntohl (sw_if_index);
16888   mp->is_add = is_add;
16889   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16890   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16891   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16892   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16893
16894   /* send it... */
16895   S;
16896
16897   /* Wait for a reply... */
16898   W;
16899 }
16900
16901 static int
16902 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16903 {
16904   unformat_input_t *i = vam->input;
16905   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16906   f64 timeout;
16907   u32 local_sa_id = 0;
16908   u32 remote_sa_id = 0;
16909   ip4_address_t src_address;
16910   ip4_address_t dst_address;
16911   u8 is_add = 1;
16912
16913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16914     {
16915       if (unformat (i, "local_sa %d", &local_sa_id))
16916         ;
16917       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16918         ;
16919       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16920         ;
16921       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16922         ;
16923       else if (unformat (i, "del"))
16924         is_add = 0;
16925       else
16926         {
16927           clib_warning ("parse error '%U'", format_unformat_error, i);
16928           return -99;
16929         }
16930     }
16931
16932   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16933
16934   mp->local_sa_id = ntohl (local_sa_id);
16935   mp->remote_sa_id = ntohl (remote_sa_id);
16936   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16937   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16938   mp->is_add = is_add;
16939
16940   S;
16941   W;
16942   /* NOTREACHED */
16943   return 0;
16944 }
16945
16946 static int
16947 api_punt (vat_main_t * vam)
16948 {
16949   unformat_input_t *i = vam->input;
16950   vl_api_punt_t *mp;
16951   f64 timeout;
16952   u32 ipv = ~0;
16953   u32 protocol = ~0;
16954   u32 port = ~0;
16955   int is_add = 1;
16956
16957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16958     {
16959       if (unformat (i, "ip %d", &ipv))
16960         ;
16961       else if (unformat (i, "protocol %d", &protocol))
16962         ;
16963       else if (unformat (i, "port %d", &port))
16964         ;
16965       else if (unformat (i, "del"))
16966         is_add = 0;
16967       else
16968         {
16969           clib_warning ("parse error '%U'", format_unformat_error, i);
16970           return -99;
16971         }
16972     }
16973
16974   M (PUNT, punt);
16975
16976   mp->is_add = (u8) is_add;
16977   mp->ipv = (u8) ipv;
16978   mp->l4_protocol = (u8) protocol;
16979   mp->l4_port = htons ((u16) port);
16980
16981   S;
16982   W;
16983   /* NOTREACHED */
16984   return 0;
16985 }
16986
16987 static void vl_api_ipsec_gre_tunnel_details_t_handler
16988   (vl_api_ipsec_gre_tunnel_details_t * mp)
16989 {
16990   vat_main_t *vam = &vat_main;
16991
16992   print (vam->ofp, "%11d%15U%15U%14d%14d",
16993          ntohl (mp->sw_if_index),
16994          format_ip4_address, &mp->src_address,
16995          format_ip4_address, &mp->dst_address,
16996          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16997 }
16998
16999 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17000   (vl_api_ipsec_gre_tunnel_details_t * mp)
17001 {
17002   vat_main_t *vam = &vat_main;
17003   vat_json_node_t *node = NULL;
17004   struct in_addr ip4;
17005
17006   if (VAT_JSON_ARRAY != vam->json_tree.type)
17007     {
17008       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17009       vat_json_init_array (&vam->json_tree);
17010     }
17011   node = vat_json_array_add (&vam->json_tree);
17012
17013   vat_json_init_object (node);
17014   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17015   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17016   vat_json_object_add_ip4 (node, "src_address", ip4);
17017   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17018   vat_json_object_add_ip4 (node, "dst_address", ip4);
17019   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17020   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17021 }
17022
17023 static int
17024 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17025 {
17026   unformat_input_t *i = vam->input;
17027   vl_api_ipsec_gre_tunnel_dump_t *mp;
17028   f64 timeout;
17029   u32 sw_if_index;
17030   u8 sw_if_index_set = 0;
17031
17032   /* Parse args required to build the message */
17033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17034     {
17035       if (unformat (i, "sw_if_index %d", &sw_if_index))
17036         sw_if_index_set = 1;
17037       else
17038         break;
17039     }
17040
17041   if (sw_if_index_set == 0)
17042     {
17043       sw_if_index = ~0;
17044     }
17045
17046   if (!vam->json_output)
17047     {
17048       print (vam->ofp, "%11s%15s%15s%14s%14s",
17049              "sw_if_index", "src_address", "dst_address",
17050              "local_sa_id", "remote_sa_id");
17051     }
17052
17053   /* Get list of gre-tunnel interfaces */
17054   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
17055
17056   mp->sw_if_index = htonl (sw_if_index);
17057
17058   S;
17059
17060   /* Use a control ping for synchronization */
17061   {
17062     vl_api_control_ping_t *mp;
17063     M (CONTROL_PING, control_ping);
17064     S;
17065   }
17066   W;
17067 }
17068
17069 static int
17070 api_delete_subif (vat_main_t * vam)
17071 {
17072   unformat_input_t *i = vam->input;
17073   vl_api_delete_subif_t *mp;
17074   f64 timeout;
17075   u32 sw_if_index = ~0;
17076
17077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17078     {
17079       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17080         ;
17081       if (unformat (i, "sw_if_index %d", &sw_if_index))
17082         ;
17083       else
17084         break;
17085     }
17086
17087   if (sw_if_index == ~0)
17088     {
17089       errmsg ("missing sw_if_index");
17090       return -99;
17091     }
17092
17093   /* Construct the API message */
17094   M (DELETE_SUBIF, delete_subif);
17095   mp->sw_if_index = ntohl (sw_if_index);
17096
17097   S;
17098   W;
17099 }
17100
17101 #define foreach_pbb_vtr_op      \
17102 _("disable",  L2_VTR_DISABLED)  \
17103 _("pop",  L2_VTR_POP_2)         \
17104 _("push",  L2_VTR_PUSH_2)
17105
17106 static int
17107 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17108 {
17109   unformat_input_t *i = vam->input;
17110   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17111   f64 timeout;
17112   u32 sw_if_index = ~0, vtr_op = ~0;
17113   u16 outer_tag = ~0;
17114   u8 dmac[6], smac[6];
17115   u8 dmac_set = 0, smac_set = 0;
17116   u16 vlanid = 0;
17117   u32 sid = ~0;
17118   u32 tmp;
17119
17120   /* Shut up coverity */
17121   memset (dmac, 0, sizeof (dmac));
17122   memset (smac, 0, sizeof (smac));
17123
17124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17125     {
17126       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17127         ;
17128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17129         ;
17130       else if (unformat (i, "vtr_op %d", &vtr_op))
17131         ;
17132 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17133       foreach_pbb_vtr_op
17134 #undef _
17135         else if (unformat (i, "translate_pbb_stag"))
17136         {
17137           if (unformat (i, "%d", &tmp))
17138             {
17139               vtr_op = L2_VTR_TRANSLATE_2_1;
17140               outer_tag = tmp;
17141             }
17142           else
17143             {
17144               errmsg
17145                 ("translate_pbb_stag operation requires outer tag definition");
17146               return -99;
17147             }
17148         }
17149       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17150         dmac_set++;
17151       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17152         smac_set++;
17153       else if (unformat (i, "sid %d", &sid))
17154         ;
17155       else if (unformat (i, "vlanid %d", &tmp))
17156         vlanid = tmp;
17157       else
17158         {
17159           clib_warning ("parse error '%U'", format_unformat_error, i);
17160           return -99;
17161         }
17162     }
17163
17164   if ((sw_if_index == ~0) || (vtr_op == ~0))
17165     {
17166       errmsg ("missing sw_if_index or vtr operation");
17167       return -99;
17168     }
17169   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17170       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17171     {
17172       errmsg
17173         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17174       return -99;
17175     }
17176
17177   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
17178   mp->sw_if_index = ntohl (sw_if_index);
17179   mp->vtr_op = ntohl (vtr_op);
17180   mp->outer_tag = ntohs (outer_tag);
17181   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17182   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17183   mp->b_vlanid = ntohs (vlanid);
17184   mp->i_sid = ntohl (sid);
17185
17186   S;
17187   W;
17188   /* NOTREACHED */
17189   return 0;
17190 }
17191
17192 static int
17193 api_flow_classify_set_interface (vat_main_t * vam)
17194 {
17195   unformat_input_t *i = vam->input;
17196   vl_api_flow_classify_set_interface_t *mp;
17197   f64 timeout;
17198   u32 sw_if_index;
17199   int sw_if_index_set;
17200   u32 ip4_table_index = ~0;
17201   u32 ip6_table_index = ~0;
17202   u8 is_add = 1;
17203
17204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17205     {
17206       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17207         sw_if_index_set = 1;
17208       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17209         sw_if_index_set = 1;
17210       else if (unformat (i, "del"))
17211         is_add = 0;
17212       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17213         ;
17214       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17215         ;
17216       else
17217         {
17218           clib_warning ("parse error '%U'", format_unformat_error, i);
17219           return -99;
17220         }
17221     }
17222
17223   if (sw_if_index_set == 0)
17224     {
17225       errmsg ("missing interface name or sw_if_index");
17226       return -99;
17227     }
17228
17229   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
17230
17231   mp->sw_if_index = ntohl (sw_if_index);
17232   mp->ip4_table_index = ntohl (ip4_table_index);
17233   mp->ip6_table_index = ntohl (ip6_table_index);
17234   mp->is_add = is_add;
17235
17236   S;
17237   W;
17238   /* NOTREACHED */
17239   return 0;
17240 }
17241
17242 static int
17243 api_flow_classify_dump (vat_main_t * vam)
17244 {
17245   unformat_input_t *i = vam->input;
17246   vl_api_flow_classify_dump_t *mp;
17247   f64 timeout = ~0;
17248   u8 type = FLOW_CLASSIFY_N_TABLES;
17249
17250   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17251     ;
17252   else
17253     {
17254       errmsg ("classify table type must be specified");
17255       return -99;
17256     }
17257
17258   if (!vam->json_output)
17259     {
17260       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17261     }
17262
17263   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
17264   mp->type = type;
17265   /* send it... */
17266   S;
17267
17268   /* Use a control ping for synchronization */
17269   {
17270     vl_api_control_ping_t *mp;
17271     M (CONTROL_PING, control_ping);
17272     S;
17273   }
17274   /* Wait for a reply... */
17275   W;
17276
17277   /* NOTREACHED */
17278   return 0;
17279 }
17280
17281 static int
17282 api_feature_enable_disable (vat_main_t * vam)
17283 {
17284   unformat_input_t *i = vam->input;
17285   vl_api_feature_enable_disable_t *mp;
17286   f64 timeout;
17287   u8 *arc_name = 0;
17288   u8 *feature_name = 0;
17289   u32 sw_if_index = ~0;
17290   u8 enable = 1;
17291
17292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17293     {
17294       if (unformat (i, "arc_name %s", &arc_name))
17295         ;
17296       else if (unformat (i, "feature_name %s", &feature_name))
17297         ;
17298       else
17299         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17300         ;
17301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17302         ;
17303       else if (unformat (i, "disable"))
17304         enable = 0;
17305       else
17306         break;
17307     }
17308
17309   if (arc_name == 0)
17310     {
17311       errmsg ("missing arc name");
17312       return -99;
17313     }
17314   if (vec_len (arc_name) > 63)
17315     {
17316       errmsg ("arc name too long");
17317     }
17318
17319   if (feature_name == 0)
17320     {
17321       errmsg ("missing feature name");
17322       return -99;
17323     }
17324   if (vec_len (feature_name) > 63)
17325     {
17326       errmsg ("feature name too long");
17327     }
17328
17329   if (sw_if_index == ~0)
17330     {
17331       errmsg ("missing interface name or sw_if_index");
17332       return -99;
17333     }
17334
17335   /* Construct the API message */
17336   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
17337   mp->sw_if_index = ntohl (sw_if_index);
17338   mp->enable = enable;
17339   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17340   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17341   vec_free (arc_name);
17342   vec_free (feature_name);
17343
17344   S;
17345   W;
17346 }
17347
17348 static int
17349 api_sw_interface_tag_add_del (vat_main_t * vam)
17350 {
17351   unformat_input_t *i = vam->input;
17352   vl_api_sw_interface_tag_add_del_t *mp;
17353   f64 timeout;
17354   u32 sw_if_index = ~0;
17355   u8 *tag = 0;
17356   u8 enable = 1;
17357
17358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17359     {
17360       if (unformat (i, "tag %s", &tag))
17361         ;
17362       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17363         ;
17364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17365         ;
17366       else if (unformat (i, "del"))
17367         enable = 0;
17368       else
17369         break;
17370     }
17371
17372   if (sw_if_index == ~0)
17373     {
17374       errmsg ("missing interface name or sw_if_index");
17375       return -99;
17376     }
17377
17378   if (enable && (tag == 0))
17379     {
17380       errmsg ("no tag specified");
17381       return -99;
17382     }
17383
17384   /* Construct the API message */
17385   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
17386   mp->sw_if_index = ntohl (sw_if_index);
17387   mp->is_add = enable;
17388   if (enable)
17389     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17390   vec_free (tag);
17391
17392   S;
17393   W;
17394 }
17395
17396 static void vl_api_l2_xconnect_details_t_handler
17397   (vl_api_l2_xconnect_details_t * mp)
17398 {
17399   vat_main_t *vam = &vat_main;
17400
17401   print (vam->ofp, "%15d%15d",
17402          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17403 }
17404
17405 static void vl_api_l2_xconnect_details_t_handler_json
17406   (vl_api_l2_xconnect_details_t * mp)
17407 {
17408   vat_main_t *vam = &vat_main;
17409   vat_json_node_t *node = NULL;
17410
17411   if (VAT_JSON_ARRAY != vam->json_tree.type)
17412     {
17413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17414       vat_json_init_array (&vam->json_tree);
17415     }
17416   node = vat_json_array_add (&vam->json_tree);
17417
17418   vat_json_init_object (node);
17419   vat_json_object_add_uint (node, "rx_sw_if_index",
17420                             ntohl (mp->rx_sw_if_index));
17421   vat_json_object_add_uint (node, "tx_sw_if_index",
17422                             ntohl (mp->tx_sw_if_index));
17423 }
17424
17425 static int
17426 api_l2_xconnect_dump (vat_main_t * vam)
17427 {
17428   vl_api_l2_xconnect_dump_t *mp;
17429   f64 timeout;
17430
17431   if (!vam->json_output)
17432     {
17433       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17434     }
17435
17436   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
17437
17438   S;
17439
17440   /* Use a control ping for synchronization */
17441   {
17442     vl_api_control_ping_t *mp;
17443     M (CONTROL_PING, control_ping);
17444     S;
17445   }
17446   W;
17447 }
17448
17449 static int
17450 api_sw_interface_set_mtu (vat_main_t * vam)
17451 {
17452   unformat_input_t *i = vam->input;
17453   vl_api_sw_interface_set_mtu_t *mp;
17454   f64 timeout;
17455   u32 sw_if_index = ~0;
17456   u32 mtu = 0;
17457
17458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17459     {
17460       if (unformat (i, "mtu %d", &mtu))
17461         ;
17462       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17463         ;
17464       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17465         ;
17466       else
17467         break;
17468     }
17469
17470   if (sw_if_index == ~0)
17471     {
17472       errmsg ("missing interface name or sw_if_index");
17473       return -99;
17474     }
17475
17476   if (mtu == 0)
17477     {
17478       errmsg ("no mtu specified");
17479       return -99;
17480     }
17481
17482   /* Construct the API message */
17483   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17484   mp->sw_if_index = ntohl (sw_if_index);
17485   mp->mtu = ntohs ((u16) mtu);
17486
17487   S;
17488   W;
17489 }
17490
17491
17492 static int
17493 q_or_quit (vat_main_t * vam)
17494 {
17495   longjmp (vam->jump_buf, 1);
17496   return 0;                     /* not so much */
17497 }
17498
17499 static int
17500 q (vat_main_t * vam)
17501 {
17502   return q_or_quit (vam);
17503 }
17504
17505 static int
17506 quit (vat_main_t * vam)
17507 {
17508   return q_or_quit (vam);
17509 }
17510
17511 static int
17512 comment (vat_main_t * vam)
17513 {
17514   return 0;
17515 }
17516
17517 static int
17518 cmd_cmp (void *a1, void *a2)
17519 {
17520   u8 **c1 = a1;
17521   u8 **c2 = a2;
17522
17523   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17524 }
17525
17526 static int
17527 help (vat_main_t * vam)
17528 {
17529   u8 **cmds = 0;
17530   u8 *name = 0;
17531   hash_pair_t *p;
17532   unformat_input_t *i = vam->input;
17533   int j;
17534
17535   if (unformat (i, "%s", &name))
17536     {
17537       uword *hs;
17538
17539       vec_add1 (name, 0);
17540
17541       hs = hash_get_mem (vam->help_by_name, name);
17542       if (hs)
17543         print (vam->ofp, "usage: %s %s", name, hs[0]);
17544       else
17545         print (vam->ofp, "No such msg / command '%s'", name);
17546       vec_free (name);
17547       return 0;
17548     }
17549
17550   print (vam->ofp, "Help is available for the following:");
17551
17552     /* *INDENT-OFF* */
17553     hash_foreach_pair (p, vam->function_by_name,
17554     ({
17555       vec_add1 (cmds, (u8 *)(p->key));
17556     }));
17557     /* *INDENT-ON* */
17558
17559   vec_sort_with_function (cmds, cmd_cmp);
17560
17561   for (j = 0; j < vec_len (cmds); j++)
17562     print (vam->ofp, "%s", cmds[j]);
17563
17564   vec_free (cmds);
17565   return 0;
17566 }
17567
17568 static int
17569 set (vat_main_t * vam)
17570 {
17571   u8 *name = 0, *value = 0;
17572   unformat_input_t *i = vam->input;
17573
17574   if (unformat (i, "%s", &name))
17575     {
17576       /* The input buffer is a vector, not a string. */
17577       value = vec_dup (i->buffer);
17578       vec_delete (value, i->index, 0);
17579       /* Almost certainly has a trailing newline */
17580       if (value[vec_len (value) - 1] == '\n')
17581         value[vec_len (value) - 1] = 0;
17582       /* Make sure it's a proper string, one way or the other */
17583       vec_add1 (value, 0);
17584       (void) clib_macro_set_value (&vam->macro_main,
17585                                    (char *) name, (char *) value);
17586     }
17587   else
17588     errmsg ("usage: set <name> <value>");
17589
17590   vec_free (name);
17591   vec_free (value);
17592   return 0;
17593 }
17594
17595 static int
17596 unset (vat_main_t * vam)
17597 {
17598   u8 *name = 0;
17599
17600   if (unformat (vam->input, "%s", &name))
17601     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17602       errmsg ("unset: %s wasn't set", name);
17603   vec_free (name);
17604   return 0;
17605 }
17606
17607 typedef struct
17608 {
17609   u8 *name;
17610   u8 *value;
17611 } macro_sort_t;
17612
17613
17614 static int
17615 macro_sort_cmp (void *a1, void *a2)
17616 {
17617   macro_sort_t *s1 = a1;
17618   macro_sort_t *s2 = a2;
17619
17620   return strcmp ((char *) (s1->name), (char *) (s2->name));
17621 }
17622
17623 static int
17624 dump_macro_table (vat_main_t * vam)
17625 {
17626   macro_sort_t *sort_me = 0, *sm;
17627   int i;
17628   hash_pair_t *p;
17629
17630     /* *INDENT-OFF* */
17631     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17632     ({
17633       vec_add2 (sort_me, sm, 1);
17634       sm->name = (u8 *)(p->key);
17635       sm->value = (u8 *) (p->value[0]);
17636     }));
17637     /* *INDENT-ON* */
17638
17639   vec_sort_with_function (sort_me, macro_sort_cmp);
17640
17641   if (vec_len (sort_me))
17642     print (vam->ofp, "%-15s%s", "Name", "Value");
17643   else
17644     print (vam->ofp, "The macro table is empty...");
17645
17646   for (i = 0; i < vec_len (sort_me); i++)
17647     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17648   return 0;
17649 }
17650
17651 static int
17652 dump_node_table (vat_main_t * vam)
17653 {
17654   int i, j;
17655   vlib_node_t *node, *next_node;
17656
17657   if (vec_len (vam->graph_nodes) == 0)
17658     {
17659       print (vam->ofp, "Node table empty, issue get_node_graph...");
17660       return 0;
17661     }
17662
17663   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17664     {
17665       node = vam->graph_nodes[i];
17666       print (vam->ofp, "[%d] %s", i, node->name);
17667       for (j = 0; j < vec_len (node->next_nodes); j++)
17668         {
17669           if (node->next_nodes[j] != ~0)
17670             {
17671               next_node = vam->graph_nodes[node->next_nodes[j]];
17672               print (vam->ofp, "  [%d] %s", j, next_node->name);
17673             }
17674         }
17675     }
17676   return 0;
17677 }
17678
17679 static int
17680 value_sort_cmp (void *a1, void *a2)
17681 {
17682   name_sort_t *n1 = a1;
17683   name_sort_t *n2 = a2;
17684
17685   if (n1->value < n2->value)
17686     return -1;
17687   if (n1->value > n2->value)
17688     return 1;
17689   return 0;
17690 }
17691
17692
17693 static int
17694 dump_msg_api_table (vat_main_t * vam)
17695 {
17696   api_main_t *am = &api_main;
17697   name_sort_t *nses = 0, *ns;
17698   hash_pair_t *hp;
17699   int i;
17700
17701   /* *INDENT-OFF* */
17702   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17703   ({
17704     vec_add2 (nses, ns, 1);
17705     ns->name = (u8 *)(hp->key);
17706     ns->value = (u32) hp->value[0];
17707   }));
17708   /* *INDENT-ON* */
17709
17710   vec_sort_with_function (nses, value_sort_cmp);
17711
17712   for (i = 0; i < vec_len (nses); i++)
17713     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17714   vec_free (nses);
17715   return 0;
17716 }
17717
17718 static int
17719 get_msg_id (vat_main_t * vam)
17720 {
17721   u8 *name_and_crc;
17722   u32 message_index;
17723
17724   if (unformat (vam->input, "%s", &name_and_crc))
17725     {
17726       message_index = vl_api_get_msg_index (name_and_crc);
17727       if (message_index == ~0)
17728         {
17729           print (vam->ofp, " '%s' not found", name_and_crc);
17730           return 0;
17731         }
17732       print (vam->ofp, " '%s' has message index %d",
17733              name_and_crc, message_index);
17734       return 0;
17735     }
17736   errmsg ("name_and_crc required...");
17737   return 0;
17738 }
17739
17740 static int
17741 search_node_table (vat_main_t * vam)
17742 {
17743   unformat_input_t *line_input = vam->input;
17744   u8 *node_to_find;
17745   int j;
17746   vlib_node_t *node, *next_node;
17747   uword *p;
17748
17749   if (vam->graph_node_index_by_name == 0)
17750     {
17751       print (vam->ofp, "Node table empty, issue get_node_graph...");
17752       return 0;
17753     }
17754
17755   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17756     {
17757       if (unformat (line_input, "%s", &node_to_find))
17758         {
17759           vec_add1 (node_to_find, 0);
17760           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17761           if (p == 0)
17762             {
17763               print (vam->ofp, "%s not found...", node_to_find);
17764               goto out;
17765             }
17766           node = vam->graph_nodes[p[0]];
17767           print (vam->ofp, "[%d] %s", p[0], node->name);
17768           for (j = 0; j < vec_len (node->next_nodes); j++)
17769             {
17770               if (node->next_nodes[j] != ~0)
17771                 {
17772                   next_node = vam->graph_nodes[node->next_nodes[j]];
17773                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17774                 }
17775             }
17776         }
17777
17778       else
17779         {
17780           clib_warning ("parse error '%U'", format_unformat_error,
17781                         line_input);
17782           return -99;
17783         }
17784
17785     out:
17786       vec_free (node_to_find);
17787
17788     }
17789
17790   return 0;
17791 }
17792
17793
17794 static int
17795 script (vat_main_t * vam)
17796 {
17797 #if (VPP_API_TEST_BUILTIN==0)
17798   u8 *s = 0;
17799   char *save_current_file;
17800   unformat_input_t save_input;
17801   jmp_buf save_jump_buf;
17802   u32 save_line_number;
17803
17804   FILE *new_fp, *save_ifp;
17805
17806   if (unformat (vam->input, "%s", &s))
17807     {
17808       new_fp = fopen ((char *) s, "r");
17809       if (new_fp == 0)
17810         {
17811           errmsg ("Couldn't open script file %s", s);
17812           vec_free (s);
17813           return -99;
17814         }
17815     }
17816   else
17817     {
17818       errmsg ("Missing script name");
17819       return -99;
17820     }
17821
17822   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17823   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17824   save_ifp = vam->ifp;
17825   save_line_number = vam->input_line_number;
17826   save_current_file = (char *) vam->current_file;
17827
17828   vam->input_line_number = 0;
17829   vam->ifp = new_fp;
17830   vam->current_file = s;
17831   do_one_file (vam);
17832
17833   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17834   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17835   vam->ifp = save_ifp;
17836   vam->input_line_number = save_line_number;
17837   vam->current_file = (u8 *) save_current_file;
17838   vec_free (s);
17839
17840   return 0;
17841 #else
17842   clib_warning ("use the exec command...");
17843   return -99;
17844 #endif
17845 }
17846
17847 static int
17848 echo (vat_main_t * vam)
17849 {
17850   print (vam->ofp, "%v", vam->input->buffer);
17851   return 0;
17852 }
17853
17854 /* List of API message constructors, CLI names map to api_xxx */
17855 #define foreach_vpe_api_msg                                             \
17856 _(create_loopback,"[mac <mac-addr>]")                                   \
17857 _(sw_interface_dump,"")                                                 \
17858 _(sw_interface_set_flags,                                               \
17859   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17860 _(sw_interface_add_del_address,                                         \
17861   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17862 _(sw_interface_set_table,                                               \
17863   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17864 _(sw_interface_set_mpls_enable,                                         \
17865   "<intfc> | sw_if_index [disable | dis]")                              \
17866 _(sw_interface_set_vpath,                                               \
17867   "<intfc> | sw_if_index <id> enable | disable")                        \
17868 _(sw_interface_set_vxlan_bypass,                                        \
17869   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
17870 _(sw_interface_set_l2_xconnect,                                         \
17871   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17872   "enable | disable")                                                   \
17873 _(sw_interface_set_l2_bridge,                                           \
17874   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17875   "[shg <split-horizon-group>] [bvi]\n"                                 \
17876   "enable | disable")                                                   \
17877 _(bridge_domain_add_del,                                                \
17878   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17879 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17880 _(l2fib_add_del,                                                        \
17881   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17882 _(l2_flags,                                                             \
17883   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17884 _(bridge_flags,                                                         \
17885   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17886 _(tap_connect,                                                          \
17887   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17888 _(tap_modify,                                                           \
17889   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17890 _(tap_delete,                                                           \
17891   "<vpp-if-name> | sw_if_index <id>")                                   \
17892 _(sw_interface_tap_dump, "")                                            \
17893 _(ip_add_del_route,                                                     \
17894   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17895   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17896   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17897   "[multipath] [count <n>]")                                            \
17898 _(ip_mroute_add_del,                                                    \
17899   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
17900   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
17901 _(mpls_route_add_del,                                                   \
17902   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17903   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17904   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17905   "[multipath] [count <n>]")                                            \
17906 _(mpls_ip_bind_unbind,                                                  \
17907   "<label> <addr/len>")                                                 \
17908 _(mpls_tunnel_add_del,                                                  \
17909   " via <addr> [table-id <n>]\n"                                        \
17910   "sw_if_index <id>] [l2]  [del]")                                      \
17911 _(proxy_arp_add_del,                                                    \
17912   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17913 _(proxy_arp_intfc_enable_disable,                                       \
17914   "<intfc> | sw_if_index <id> enable | disable")                        \
17915 _(sw_interface_set_unnumbered,                                          \
17916   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17917 _(ip_neighbor_add_del,                                                  \
17918   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17919   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17920 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17921 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17922 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17923   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17924   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17925   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17926 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17927 _(reset_fib, "vrf <n> [ipv6]")                                          \
17928 _(dhcp_proxy_config,                                                    \
17929   "svr <v46-address> src <v46-address>\n"                               \
17930    "insert-cid <n> [del]")                                              \
17931 _(dhcp_proxy_config_2,                                                  \
17932   "svr <v46-address> src <v46-address>\n"                               \
17933    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17934 _(dhcp_proxy_set_vss,                                                   \
17935   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17936 _(dhcp_client_config,                                                   \
17937   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17938 _(set_ip_flow_hash,                                                     \
17939   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17940 _(sw_interface_ip6_enable_disable,                                      \
17941   "<intfc> | sw_if_index <id> enable | disable")                        \
17942 _(sw_interface_ip6_set_link_local_address,                              \
17943   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17944 _(sw_interface_ip6nd_ra_prefix,                                         \
17945   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17946   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17947   "[nolink] [isno]")                                                    \
17948 _(sw_interface_ip6nd_ra_config,                                         \
17949   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17950   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17951   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17952 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17953 _(l2_patch_add_del,                                                     \
17954   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17955   "enable | disable")                                                   \
17956 _(sr_tunnel_add_del,                                                    \
17957   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17958   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17959   "[policy <policy_name>]")                                             \
17960 _(sr_policy_add_del,                                                    \
17961   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17962 _(sr_multicast_map_add_del,                                             \
17963   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17964 _(classify_add_del_table,                                               \
17965   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17966   " [del] [del-chain] mask <mask-value>\n"                              \
17967   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17968   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17969 _(classify_add_del_session,                                             \
17970   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17971   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17972   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17973   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17974 _(classify_set_interface_ip_table,                                      \
17975   "<intfc> | sw_if_index <nn> table <nn>")                              \
17976 _(classify_set_interface_l2_tables,                                     \
17977   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17978   "  [other-table <nn>]")                                               \
17979 _(get_node_index, "node <node-name")                                    \
17980 _(add_node_next, "node <node-name> next <next-node-name>")              \
17981 _(l2tpv3_create_tunnel,                                                 \
17982   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17983   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17984   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17985 _(l2tpv3_set_tunnel_cookies,                                            \
17986   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17987   "[new_remote_cookie <nn>]\n")                                         \
17988 _(l2tpv3_interface_enable_disable,                                      \
17989   "<intfc> | sw_if_index <nn> enable | disable")                        \
17990 _(l2tpv3_set_lookup_key,                                                \
17991   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17992 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17993 _(vxlan_add_del_tunnel,                                                 \
17994   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17995   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17996   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17997 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17998 _(gre_add_del_tunnel,                                                   \
17999   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18000 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18001 _(l2_fib_clear_table, "")                                               \
18002 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18003 _(l2_interface_vlan_tag_rewrite,                                        \
18004   "<intfc> | sw_if_index <nn> \n"                                       \
18005   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18006   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18007 _(create_vhost_user_if,                                                 \
18008         "socket <filename> [server] [renumber <dev_instance>] "         \
18009         "[mac <mac_address>]")                                          \
18010 _(modify_vhost_user_if,                                                 \
18011         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18012         "[server] [renumber <dev_instance>]")                           \
18013 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18014 _(sw_interface_vhost_user_dump, "")                                     \
18015 _(show_version, "")                                                     \
18016 _(vxlan_gpe_add_del_tunnel,                                             \
18017   "local <addr> remote <addr> vni <nn>\n"                               \
18018     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18019   "[next-ethernet] [next-nsh]\n")                                       \
18020 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18021 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18022 _(interface_name_renumber,                                              \
18023   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18024 _(input_acl_set_interface,                                              \
18025   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18026   "  [l2-table <nn>] [del]")                                            \
18027 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18028 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18029 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18030 _(ip_dump, "ipv4 | ipv6")                                               \
18031 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18032 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18033   "  spid_id <n> ")                                                     \
18034 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18035   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18036   "  integ_alg <alg> integ_key <hex>")                                  \
18037 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18038   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18039   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18040   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18041 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18042 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18043 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18044   "(auth_data 0x<data> | auth_data <data>)")                            \
18045 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18046   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18047 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18048   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18049   "(local|remote)")                                                     \
18050 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18051 _(delete_loopback,"sw_if_index <nn>")                                   \
18052 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18053 _(map_add_domain,                                                       \
18054   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18055   "ip6-src <ip6addr> "                                                  \
18056   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18057 _(map_del_domain, "index <n>")                                          \
18058 _(map_add_del_rule,                                                     \
18059   "index <n> psid <n> dst <ip6addr> [del]")                             \
18060 _(map_domain_dump, "")                                                  \
18061 _(map_rule_dump, "index <map-domain>")                                  \
18062 _(want_interface_events,  "enable|disable")                             \
18063 _(want_stats,"enable|disable")                                          \
18064 _(get_first_msg_id, "client <name>")                                    \
18065 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18066 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18067   "fib-id <nn> [ip4][ip6][default]")                                    \
18068 _(get_node_graph, " ")                                                  \
18069 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18070 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18071 _(ioam_disable, "")                                                     \
18072 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18073                             " sw_if_index <sw_if_index> p <priority> "  \
18074                             "w <weight>] [del]")                        \
18075 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18076                         "iface <intf> | sw_if_index <sw_if_index> "     \
18077                         "p <priority> w <weight> [del]")                \
18078 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18079                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18080                          "locator-set <locator_name> [del]"             \
18081                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18082 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18083   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18084 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18085 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18086 _(lisp_gpe_enable_disable, "enable|disable")                            \
18087 _(lisp_enable_disable, "enable|disable")                                \
18088 _(lisp_map_register_enable_disable, "enable|disable")                   \
18089 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18090 _(lisp_gpe_add_del_iface, "up|down")                                    \
18091 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18092                                "[seid <seid>] "                         \
18093                                "rloc <locator> p <prio> "               \
18094                                "w <weight> [rloc <loc> ... ] "          \
18095                                "action <action> [del-all]")             \
18096 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18097                           "<local-eid>")                                \
18098 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18099 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18100 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18101 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18102 _(lisp_locator_set_dump, "[local | remote]")                            \
18103 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18104 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18105                        "[local] | [remote]")                            \
18106 _(lisp_eid_table_vni_dump, "")                                          \
18107 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18108 _(lisp_map_resolver_dump, "")                                           \
18109 _(lisp_map_server_dump, "")                                             \
18110 _(lisp_adjacencies_get, "vni <vni>")                                    \
18111 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18112 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18113 _(show_lisp_rloc_probe_state, "")                                       \
18114 _(show_lisp_map_register_state, "")                                     \
18115 _(show_lisp_status, "")                                                 \
18116 _(lisp_get_map_request_itr_rlocs, "")                                   \
18117 _(show_lisp_pitr, "")                                                   \
18118 _(show_lisp_map_request_mode, "")                                       \
18119 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18120 _(af_packet_delete, "name <host interface name>")                       \
18121 _(policer_add_del, "name <policer name> <params> [del]")                \
18122 _(policer_dump, "[name <policer name>]")                                \
18123 _(policer_classify_set_interface,                                       \
18124   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18125   "  [l2-table <nn>] [del]")                                            \
18126 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18127 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18128     "[master|slave]")                                                   \
18129 _(netmap_delete, "name <interface name>")                               \
18130 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18131 _(mpls_fib_dump, "")                                                    \
18132 _(classify_table_ids, "")                                               \
18133 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18134 _(classify_table_info, "table_id <nn>")                                 \
18135 _(classify_session_dump, "table_id <nn>")                               \
18136 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18137     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18138     "[template_interval <nn>] [udp_checksum]")                          \
18139 _(ipfix_exporter_dump, "")                                              \
18140 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18141 _(ipfix_classify_stream_dump, "")                                       \
18142 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18143 _(ipfix_classify_table_dump, "")                                        \
18144 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18145 _(sw_interface_span_dump, "")                                           \
18146 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18147 _(pg_create_interface, "if_id <nn>")                                    \
18148 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18149 _(pg_enable_disable, "[stream <id>] disable")                           \
18150 _(ip_source_and_port_range_check_add_del,                               \
18151   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18152 _(ip_source_and_port_range_check_interface_add_del,                     \
18153   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18154   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18155 _(ipsec_gre_add_del_tunnel,                                             \
18156   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18157 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18158 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18159 _(l2_interface_pbb_tag_rewrite,                                         \
18160   "<intfc> | sw_if_index <nn> \n"                                       \
18161   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18162   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18163 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18164 _(flow_classify_set_interface,                                          \
18165   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18166 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18167 _(ip_fib_dump, "")                                                      \
18168 _(ip6_fib_dump, "")                                                     \
18169 _(feature_enable_disable, "arc_name <arc_name> "                        \
18170   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18171 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18172 "[disable]")                                                            \
18173 _(l2_xconnect_dump, "")                                                 \
18174 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18175 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18176 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18177
18178 #if DPDK > 0
18179 #define foreach_vpe_dpdk_api_msg                                        \
18180 _(sw_interface_set_dpdk_hqos_pipe,                                      \
18181   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
18182   "profile <profile-id>\n")                                             \
18183 _(sw_interface_set_dpdk_hqos_subport,                                   \
18184   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
18185   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
18186 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
18187   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
18188 #endif
18189
18190 /* List of command functions, CLI names map directly to functions */
18191 #define foreach_cli_function                                    \
18192 _(comment, "usage: comment <ignore-rest-of-line>")              \
18193 _(dump_interface_table, "usage: dump_interface_table")          \
18194 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18195 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18196 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18197 _(dump_stats_table, "usage: dump_stats_table")                  \
18198 _(dump_macro_table, "usage: dump_macro_table ")                 \
18199 _(dump_node_table, "usage: dump_node_table")                    \
18200 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18201 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18202 _(echo, "usage: echo <message>")                                \
18203 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18204 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18205 _(help, "usage: help")                                          \
18206 _(q, "usage: quit")                                             \
18207 _(quit, "usage: quit")                                          \
18208 _(search_node_table, "usage: search_node_table <name>...")      \
18209 _(set, "usage: set <variable-name> <value>")                    \
18210 _(script, "usage: script <file-name>")                          \
18211 _(unset, "usage: unset <variable-name>")
18212
18213 #define _(N,n)                                  \
18214     static void vl_api_##n##_t_handler_uni      \
18215     (vl_api_##n##_t * mp)                       \
18216     {                                           \
18217         vat_main_t * vam = &vat_main;           \
18218         if (vam->json_output) {                 \
18219             vl_api_##n##_t_handler_json(mp);    \
18220         } else {                                \
18221             vl_api_##n##_t_handler(mp);         \
18222         }                                       \
18223     }
18224 foreach_vpe_api_reply_msg;
18225 #undef _
18226
18227 #if DPDK > 0
18228 #define _(N,n)                                  \
18229     static void vl_api_##n##_t_handler_uni      \
18230     (vl_api_##n##_t * mp)                       \
18231     {                                           \
18232         vat_main_t * vam = &vat_main;           \
18233         if (vam->json_output) {                 \
18234             vl_api_##n##_t_handler_json(mp);    \
18235         } else {                                \
18236             vl_api_##n##_t_handler(mp);         \
18237         }                                       \
18238     }
18239 foreach_vpe_dpdk_api_reply_msg;
18240 #undef _
18241 #endif
18242
18243 void
18244 vat_api_hookup (vat_main_t * vam)
18245 {
18246 #define _(N,n)                                                  \
18247     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18248                            vl_api_##n##_t_handler_uni,          \
18249                            vl_noop_handler,                     \
18250                            vl_api_##n##_t_endian,               \
18251                            vl_api_##n##_t_print,                \
18252                            sizeof(vl_api_##n##_t), 1);
18253   foreach_vpe_api_reply_msg;
18254 #undef _
18255
18256 #if DPDK > 0
18257 #define _(N,n)                                                  \
18258     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18259                            vl_api_##n##_t_handler_uni,          \
18260                            vl_noop_handler,                     \
18261                            vl_api_##n##_t_endian,               \
18262                            vl_api_##n##_t_print,                \
18263                            sizeof(vl_api_##n##_t), 1);
18264   foreach_vpe_dpdk_api_reply_msg;
18265 #undef _
18266 #endif
18267
18268 #if (VPP_API_TEST_BUILTIN==0)
18269   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18270 #endif
18271
18272   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18273
18274   vam->function_by_name = hash_create_string (0, sizeof (uword));
18275
18276   vam->help_by_name = hash_create_string (0, sizeof (uword));
18277
18278   /* API messages we can send */
18279 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18280   foreach_vpe_api_msg;
18281 #undef _
18282 #if DPDK >0
18283 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18284   foreach_vpe_dpdk_api_msg;
18285 #undef _
18286 #endif
18287
18288   /* Help strings */
18289 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18290   foreach_vpe_api_msg;
18291 #undef _
18292 #if DPDK >0
18293 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18294   foreach_vpe_dpdk_api_msg;
18295 #undef _
18296 #endif
18297
18298   /* CLI functions */
18299 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18300   foreach_cli_function;
18301 #undef _
18302
18303   /* Help strings */
18304 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18305   foreach_cli_function;
18306 #undef _
18307 }
18308
18309 /*
18310  * fd.io coding-style-patch-verification: ON
18311  *
18312  * Local Variables:
18313  * eval: (c-set-style "gnu")
18314  * End:
18315  */