Refactor fragile msg macro W and W2 to not burry return control flow.
[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, mp);
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 (mp);
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   unformat_input_t *i = vam->input;
4644   int ret;
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, mp, len);
4667   clib_memcpy (mp->cmd, vam->input->buffer, len);
4668   mp->length = htonl (len);
4669
4670   S (mp);
4671   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4672   return ret;
4673 }
4674
4675 static int
4676 api_create_loopback (vat_main_t * vam)
4677 {
4678   unformat_input_t *i = vam->input;
4679   vl_api_create_loopback_t *mp;
4680   u8 mac_address[6];
4681   u8 mac_set = 0;
4682   int ret;
4683
4684   memset (mac_address, 0, sizeof (mac_address));
4685
4686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4687     {
4688       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4689         mac_set = 1;
4690       else
4691         break;
4692     }
4693
4694   /* Construct the API message */
4695   M (CREATE_LOOPBACK, mp);
4696   if (mac_set)
4697     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4698
4699   S (mp);
4700   W (ret);
4701   return ret;
4702 }
4703
4704 static int
4705 api_delete_loopback (vat_main_t * vam)
4706 {
4707   unformat_input_t *i = vam->input;
4708   vl_api_delete_loopback_t *mp;
4709   u32 sw_if_index = ~0;
4710   int ret;
4711
4712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4713     {
4714       if (unformat (i, "sw_if_index %d", &sw_if_index))
4715         ;
4716       else
4717         break;
4718     }
4719
4720   if (sw_if_index == ~0)
4721     {
4722       errmsg ("missing sw_if_index");
4723       return -99;
4724     }
4725
4726   /* Construct the API message */
4727   M (DELETE_LOOPBACK, mp);
4728   mp->sw_if_index = ntohl (sw_if_index);
4729
4730   S (mp);
4731   W (ret);
4732   return ret;
4733 }
4734
4735 static int
4736 api_want_stats (vat_main_t * vam)
4737 {
4738   unformat_input_t *i = vam->input;
4739   vl_api_want_stats_t *mp;
4740   int enable = -1;
4741   int ret;
4742
4743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4744     {
4745       if (unformat (i, "enable"))
4746         enable = 1;
4747       else if (unformat (i, "disable"))
4748         enable = 0;
4749       else
4750         break;
4751     }
4752
4753   if (enable == -1)
4754     {
4755       errmsg ("missing enable|disable");
4756       return -99;
4757     }
4758
4759   M (WANT_STATS, mp);
4760   mp->enable_disable = enable;
4761
4762   S (mp);
4763   W (ret);
4764   return ret;
4765 }
4766
4767 static int
4768 api_want_interface_events (vat_main_t * vam)
4769 {
4770   unformat_input_t *i = vam->input;
4771   vl_api_want_interface_events_t *mp;
4772   int enable = -1;
4773   int ret;
4774
4775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4776     {
4777       if (unformat (i, "enable"))
4778         enable = 1;
4779       else if (unformat (i, "disable"))
4780         enable = 0;
4781       else
4782         break;
4783     }
4784
4785   if (enable == -1)
4786     {
4787       errmsg ("missing enable|disable");
4788       return -99;
4789     }
4790
4791   M (WANT_INTERFACE_EVENTS, mp);
4792   mp->enable_disable = enable;
4793
4794   vam->interface_event_display = enable;
4795
4796   S (mp);
4797   W (ret);
4798   return ret;
4799 }
4800
4801
4802 /* Note: non-static, called once to set up the initial intfc table */
4803 int
4804 api_sw_interface_dump (vat_main_t * vam)
4805 {
4806   vl_api_sw_interface_dump_t *mp;
4807   hash_pair_t *p;
4808   name_sort_t *nses = 0, *ns;
4809   sw_interface_subif_t *sub = NULL;
4810   int ret;
4811
4812   /* Toss the old name table */
4813   /* *INDENT-OFF* */
4814   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4815   ({
4816     vec_add2 (nses, ns, 1);
4817     ns->name = (u8 *)(p->key);
4818     ns->value = (u32) p->value[0];
4819   }));
4820   /* *INDENT-ON* */
4821
4822   hash_free (vam->sw_if_index_by_interface_name);
4823
4824   vec_foreach (ns, nses) vec_free (ns->name);
4825
4826   vec_free (nses);
4827
4828   vec_foreach (sub, vam->sw_if_subif_table)
4829   {
4830     vec_free (sub->interface_name);
4831   }
4832   vec_free (vam->sw_if_subif_table);
4833
4834   /* recreate the interface name hash table */
4835   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4836
4837   /* Get list of ethernets */
4838   M (SW_INTERFACE_DUMP, mp);
4839   mp->name_filter_valid = 1;
4840   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4841   S (mp);
4842
4843   /* and local / loopback interfaces */
4844   M (SW_INTERFACE_DUMP, mp);
4845   mp->name_filter_valid = 1;
4846   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4847   S (mp);
4848
4849   /* and packet-generator interfaces */
4850   M (SW_INTERFACE_DUMP, mp);
4851   mp->name_filter_valid = 1;
4852   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4853   S (mp);
4854
4855   /* and vxlan-gpe tunnel interfaces */
4856   M (SW_INTERFACE_DUMP, mp);
4857   mp->name_filter_valid = 1;
4858   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4859            sizeof (mp->name_filter) - 1);
4860   S (mp);
4861
4862   /* and vxlan tunnel interfaces */
4863   M (SW_INTERFACE_DUMP, mp);
4864   mp->name_filter_valid = 1;
4865   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4866   S (mp);
4867
4868   /* and host (af_packet) interfaces */
4869   M (SW_INTERFACE_DUMP, mp);
4870   mp->name_filter_valid = 1;
4871   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4872   S (mp);
4873
4874   /* and l2tpv3 tunnel interfaces */
4875   M (SW_INTERFACE_DUMP, mp);
4876   mp->name_filter_valid = 1;
4877   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4878            sizeof (mp->name_filter) - 1);
4879   S (mp);
4880
4881   /* and GRE tunnel interfaces */
4882   M (SW_INTERFACE_DUMP, mp);
4883   mp->name_filter_valid = 1;
4884   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4885   S (mp);
4886
4887   /* and LISP-GPE interfaces */
4888   M (SW_INTERFACE_DUMP, mp);
4889   mp->name_filter_valid = 1;
4890   strncpy ((char *) mp->name_filter, "lisp_gpe",
4891            sizeof (mp->name_filter) - 1);
4892   S (mp);
4893
4894   /* and IPSEC tunnel interfaces */
4895   M (SW_INTERFACE_DUMP, mp);
4896   mp->name_filter_valid = 1;
4897   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4898   S (mp);
4899
4900   /* Use a control ping for synchronization */
4901   {
4902     vl_api_control_ping_t *mp;
4903     M (CONTROL_PING, mp);
4904     S (mp);
4905   }
4906   W (ret);
4907   return ret;
4908 }
4909
4910 static int
4911 api_sw_interface_set_flags (vat_main_t * vam)
4912 {
4913   unformat_input_t *i = vam->input;
4914   vl_api_sw_interface_set_flags_t *mp;
4915   u32 sw_if_index;
4916   u8 sw_if_index_set = 0;
4917   u8 admin_up = 0, link_up = 0;
4918   int ret;
4919
4920   /* Parse args required to build the message */
4921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4922     {
4923       if (unformat (i, "admin-up"))
4924         admin_up = 1;
4925       else if (unformat (i, "admin-down"))
4926         admin_up = 0;
4927       else if (unformat (i, "link-up"))
4928         link_up = 1;
4929       else if (unformat (i, "link-down"))
4930         link_up = 0;
4931       else
4932         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4933         sw_if_index_set = 1;
4934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4935         sw_if_index_set = 1;
4936       else
4937         break;
4938     }
4939
4940   if (sw_if_index_set == 0)
4941     {
4942       errmsg ("missing interface name or sw_if_index");
4943       return -99;
4944     }
4945
4946   /* Construct the API message */
4947   M (SW_INTERFACE_SET_FLAGS, mp);
4948   mp->sw_if_index = ntohl (sw_if_index);
4949   mp->admin_up_down = admin_up;
4950   mp->link_up_down = link_up;
4951
4952   /* send it... */
4953   S (mp);
4954
4955   /* Wait for a reply, return the good/bad news... */
4956   W (ret);
4957   return ret;
4958 }
4959
4960 static int
4961 api_sw_interface_clear_stats (vat_main_t * vam)
4962 {
4963   unformat_input_t *i = vam->input;
4964   vl_api_sw_interface_clear_stats_t *mp;
4965   u32 sw_if_index;
4966   u8 sw_if_index_set = 0;
4967   int ret;
4968
4969   /* Parse args required to build the message */
4970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4971     {
4972       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4973         sw_if_index_set = 1;
4974       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4975         sw_if_index_set = 1;
4976       else
4977         break;
4978     }
4979
4980   /* Construct the API message */
4981   M (SW_INTERFACE_CLEAR_STATS, mp);
4982
4983   if (sw_if_index_set == 1)
4984     mp->sw_if_index = ntohl (sw_if_index);
4985   else
4986     mp->sw_if_index = ~0;
4987
4988   /* send it... */
4989   S (mp);
4990
4991   /* Wait for a reply, return the good/bad news... */
4992   W (ret);
4993   return ret;
4994 }
4995
4996 #if DPDK >0
4997 static int
4998 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4999 {
5000   unformat_input_t *i = vam->input;
5001   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
5002   u32 sw_if_index;
5003   u8 sw_if_index_set = 0;
5004   u32 subport;
5005   u8 subport_set = 0;
5006   u32 pipe;
5007   u8 pipe_set = 0;
5008   u32 profile;
5009   u8 profile_set = 0;
5010   int ret;
5011
5012   /* Parse args required to build the message */
5013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5014     {
5015       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5016         sw_if_index_set = 1;
5017       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5018         sw_if_index_set = 1;
5019       else if (unformat (i, "subport %u", &subport))
5020         subport_set = 1;
5021       else
5022         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5023         sw_if_index_set = 1;
5024       else if (unformat (i, "pipe %u", &pipe))
5025         pipe_set = 1;
5026       else if (unformat (i, "profile %u", &profile))
5027         profile_set = 1;
5028       else
5029         break;
5030     }
5031
5032   if (sw_if_index_set == 0)
5033     {
5034       errmsg ("missing interface name or sw_if_index");
5035       return -99;
5036     }
5037
5038   if (subport_set == 0)
5039     {
5040       errmsg ("missing subport ");
5041       return -99;
5042     }
5043
5044   if (pipe_set == 0)
5045     {
5046       errmsg ("missing pipe");
5047       return -99;
5048     }
5049
5050   if (profile_set == 0)
5051     {
5052       errmsg ("missing profile");
5053       return -99;
5054     }
5055
5056   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, mp);
5057
5058   mp->sw_if_index = ntohl (sw_if_index);
5059   mp->subport = ntohl (subport);
5060   mp->pipe = ntohl (pipe);
5061   mp->profile = ntohl (profile);
5062
5063
5064   S (mp);
5065   W (ret);
5066   return ret;
5067 }
5068
5069 static int
5070 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
5071 {
5072   unformat_input_t *i = vam->input;
5073   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
5074   u32 sw_if_index;
5075   u8 sw_if_index_set = 0;
5076   u32 subport;
5077   u8 subport_set = 0;
5078   u32 tb_rate = 1250000000;     /* 10GbE */
5079   u32 tb_size = 1000000;
5080   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
5081   u32 tc_period = 10;
5082   int ret;
5083
5084   /* Parse args required to build the message */
5085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5086     {
5087       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5088         sw_if_index_set = 1;
5089       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5090         sw_if_index_set = 1;
5091       else if (unformat (i, "subport %u", &subport))
5092         subport_set = 1;
5093       else
5094         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5095         sw_if_index_set = 1;
5096       else if (unformat (i, "rate %u", &tb_rate))
5097         {
5098           u32 tc_id;
5099
5100           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
5101                tc_id++)
5102             tc_rate[tc_id] = tb_rate;
5103         }
5104       else if (unformat (i, "bktsize %u", &tb_size))
5105         ;
5106       else if (unformat (i, "tc0 %u", &tc_rate[0]))
5107         ;
5108       else if (unformat (i, "tc1 %u", &tc_rate[1]))
5109         ;
5110       else if (unformat (i, "tc2 %u", &tc_rate[2]))
5111         ;
5112       else if (unformat (i, "tc3 %u", &tc_rate[3]))
5113         ;
5114       else if (unformat (i, "period %u", &tc_period))
5115         ;
5116       else
5117         break;
5118     }
5119
5120   if (sw_if_index_set == 0)
5121     {
5122       errmsg ("missing interface name or sw_if_index");
5123       return -99;
5124     }
5125
5126   if (subport_set == 0)
5127     {
5128       errmsg ("missing subport ");
5129       return -99;
5130     }
5131
5132   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, mp);
5133
5134   mp->sw_if_index = ntohl (sw_if_index);
5135   mp->subport = ntohl (subport);
5136   mp->tb_rate = ntohl (tb_rate);
5137   mp->tb_size = ntohl (tb_size);
5138   mp->tc_rate[0] = ntohl (tc_rate[0]);
5139   mp->tc_rate[1] = ntohl (tc_rate[1]);
5140   mp->tc_rate[2] = ntohl (tc_rate[2]);
5141   mp->tc_rate[3] = ntohl (tc_rate[3]);
5142   mp->tc_period = ntohl (tc_period);
5143
5144   S (mp);
5145   W (ret);
5146   return ret;
5147 }
5148
5149 static int
5150 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
5151 {
5152   unformat_input_t *i = vam->input;
5153   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
5154   u32 sw_if_index;
5155   u8 sw_if_index_set = 0;
5156   u8 entry_set = 0;
5157   u8 tc_set = 0;
5158   u8 queue_set = 0;
5159   u32 entry, tc, queue;
5160   int ret;
5161
5162   /* Parse args required to build the message */
5163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5164     {
5165       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5166         sw_if_index_set = 1;
5167       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5168         sw_if_index_set = 1;
5169       else if (unformat (i, "entry %d", &entry))
5170         entry_set = 1;
5171       else if (unformat (i, "tc %d", &tc))
5172         tc_set = 1;
5173       else if (unformat (i, "queue %d", &queue))
5174         queue_set = 1;
5175       else
5176         break;
5177     }
5178
5179   if (sw_if_index_set == 0)
5180     {
5181       errmsg ("missing interface name or sw_if_index");
5182       return -99;
5183     }
5184
5185   if (entry_set == 0)
5186     {
5187       errmsg ("missing entry ");
5188       return -99;
5189     }
5190
5191   if (tc_set == 0)
5192     {
5193       errmsg ("missing traffic class ");
5194       return -99;
5195     }
5196
5197   if (queue_set == 0)
5198     {
5199       errmsg ("missing queue ");
5200       return -99;
5201     }
5202
5203   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, mp);
5204
5205   mp->sw_if_index = ntohl (sw_if_index);
5206   mp->entry = ntohl (entry);
5207   mp->tc = ntohl (tc);
5208   mp->queue = ntohl (queue);
5209
5210   S (mp);
5211   W (ret);
5212   return ret;
5213 }
5214 #endif
5215
5216 static int
5217 api_sw_interface_add_del_address (vat_main_t * vam)
5218 {
5219   unformat_input_t *i = vam->input;
5220   vl_api_sw_interface_add_del_address_t *mp;
5221   u32 sw_if_index;
5222   u8 sw_if_index_set = 0;
5223   u8 is_add = 1, del_all = 0;
5224   u32 address_length = 0;
5225   u8 v4_address_set = 0;
5226   u8 v6_address_set = 0;
5227   ip4_address_t v4address;
5228   ip6_address_t v6address;
5229   int ret;
5230
5231   /* Parse args required to build the message */
5232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5233     {
5234       if (unformat (i, "del-all"))
5235         del_all = 1;
5236       else if (unformat (i, "del"))
5237         is_add = 0;
5238       else
5239         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5240         sw_if_index_set = 1;
5241       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5242         sw_if_index_set = 1;
5243       else if (unformat (i, "%U/%d",
5244                          unformat_ip4_address, &v4address, &address_length))
5245         v4_address_set = 1;
5246       else if (unformat (i, "%U/%d",
5247                          unformat_ip6_address, &v6address, &address_length))
5248         v6_address_set = 1;
5249       else
5250         break;
5251     }
5252
5253   if (sw_if_index_set == 0)
5254     {
5255       errmsg ("missing interface name or sw_if_index");
5256       return -99;
5257     }
5258   if (v4_address_set && v6_address_set)
5259     {
5260       errmsg ("both v4 and v6 addresses set");
5261       return -99;
5262     }
5263   if (!v4_address_set && !v6_address_set && !del_all)
5264     {
5265       errmsg ("no addresses set");
5266       return -99;
5267     }
5268
5269   /* Construct the API message */
5270   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5271
5272   mp->sw_if_index = ntohl (sw_if_index);
5273   mp->is_add = is_add;
5274   mp->del_all = del_all;
5275   if (v6_address_set)
5276     {
5277       mp->is_ipv6 = 1;
5278       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5279     }
5280   else
5281     {
5282       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5283     }
5284   mp->address_length = address_length;
5285
5286   /* send it... */
5287   S (mp);
5288
5289   /* Wait for a reply, return good/bad news  */
5290   W (ret);
5291   return ret;
5292 }
5293
5294 static int
5295 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5296 {
5297   unformat_input_t *i = vam->input;
5298   vl_api_sw_interface_set_mpls_enable_t *mp;
5299   u32 sw_if_index;
5300   u8 sw_if_index_set = 0;
5301   u8 enable = 1;
5302   int ret;
5303
5304   /* Parse args required to build the message */
5305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5306     {
5307       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5308         sw_if_index_set = 1;
5309       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5310         sw_if_index_set = 1;
5311       else if (unformat (i, "disable"))
5312         enable = 0;
5313       else if (unformat (i, "dis"))
5314         enable = 0;
5315       else
5316         break;
5317     }
5318
5319   if (sw_if_index_set == 0)
5320     {
5321       errmsg ("missing interface name or sw_if_index");
5322       return -99;
5323     }
5324
5325   /* Construct the API message */
5326   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5327
5328   mp->sw_if_index = ntohl (sw_if_index);
5329   mp->enable = enable;
5330
5331   /* send it... */
5332   S (mp);
5333
5334   /* Wait for a reply... */
5335   W (ret);
5336   return ret;
5337 }
5338
5339 static int
5340 api_sw_interface_set_table (vat_main_t * vam)
5341 {
5342   unformat_input_t *i = vam->input;
5343   vl_api_sw_interface_set_table_t *mp;
5344   u32 sw_if_index, vrf_id = 0;
5345   u8 sw_if_index_set = 0;
5346   u8 is_ipv6 = 0;
5347   int ret;
5348
5349   /* Parse args required to build the message */
5350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5351     {
5352       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5353         sw_if_index_set = 1;
5354       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5355         sw_if_index_set = 1;
5356       else if (unformat (i, "vrf %d", &vrf_id))
5357         ;
5358       else if (unformat (i, "ipv6"))
5359         is_ipv6 = 1;
5360       else
5361         break;
5362     }
5363
5364   if (sw_if_index_set == 0)
5365     {
5366       errmsg ("missing interface name or sw_if_index");
5367       return -99;
5368     }
5369
5370   /* Construct the API message */
5371   M (SW_INTERFACE_SET_TABLE, mp);
5372
5373   mp->sw_if_index = ntohl (sw_if_index);
5374   mp->is_ipv6 = is_ipv6;
5375   mp->vrf_id = ntohl (vrf_id);
5376
5377   /* send it... */
5378   S (mp);
5379
5380   /* Wait for a reply... */
5381   W (ret);
5382   return ret;
5383 }
5384
5385 static void vl_api_sw_interface_get_table_reply_t_handler
5386   (vl_api_sw_interface_get_table_reply_t * mp)
5387 {
5388   vat_main_t *vam = &vat_main;
5389
5390   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5391
5392   vam->retval = ntohl (mp->retval);
5393   vam->result_ready = 1;
5394
5395 }
5396
5397 static void vl_api_sw_interface_get_table_reply_t_handler_json
5398   (vl_api_sw_interface_get_table_reply_t * mp)
5399 {
5400   vat_main_t *vam = &vat_main;
5401   vat_json_node_t node;
5402
5403   vat_json_init_object (&node);
5404   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5405   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5406
5407   vat_json_print (vam->ofp, &node);
5408   vat_json_free (&node);
5409
5410   vam->retval = ntohl (mp->retval);
5411   vam->result_ready = 1;
5412 }
5413
5414 static int
5415 api_sw_interface_get_table (vat_main_t * vam)
5416 {
5417   unformat_input_t *i = vam->input;
5418   vl_api_sw_interface_get_table_t *mp;
5419   u32 sw_if_index;
5420   u8 sw_if_index_set = 0;
5421   u8 is_ipv6 = 0;
5422   int ret;
5423
5424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5425     {
5426       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5427         sw_if_index_set = 1;
5428       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5429         sw_if_index_set = 1;
5430       else if (unformat (i, "ipv6"))
5431         is_ipv6 = 1;
5432       else
5433         break;
5434     }
5435
5436   if (sw_if_index_set == 0)
5437     {
5438       errmsg ("missing interface name or sw_if_index");
5439       return -99;
5440     }
5441
5442   M (SW_INTERFACE_GET_TABLE, mp);
5443   mp->sw_if_index = htonl (sw_if_index);
5444   mp->is_ipv6 = is_ipv6;
5445
5446   S (mp);
5447   W (ret);
5448   return ret;
5449 }
5450
5451 static int
5452 api_sw_interface_set_vpath (vat_main_t * vam)
5453 {
5454   unformat_input_t *i = vam->input;
5455   vl_api_sw_interface_set_vpath_t *mp;
5456   u32 sw_if_index = 0;
5457   u8 sw_if_index_set = 0;
5458   u8 is_enable = 0;
5459   int ret;
5460
5461   /* Parse args required to build the message */
5462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5463     {
5464       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5465         sw_if_index_set = 1;
5466       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5467         sw_if_index_set = 1;
5468       else if (unformat (i, "enable"))
5469         is_enable = 1;
5470       else if (unformat (i, "disable"))
5471         is_enable = 0;
5472       else
5473         break;
5474     }
5475
5476   if (sw_if_index_set == 0)
5477     {
5478       errmsg ("missing interface name or sw_if_index");
5479       return -99;
5480     }
5481
5482   /* Construct the API message */
5483   M (SW_INTERFACE_SET_VPATH, mp);
5484
5485   mp->sw_if_index = ntohl (sw_if_index);
5486   mp->enable = is_enable;
5487
5488   /* send it... */
5489   S (mp);
5490
5491   /* Wait for a reply... */
5492   W (ret);
5493   return ret;
5494 }
5495
5496 static int
5497 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5498 {
5499   unformat_input_t *i = vam->input;
5500   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5501   u32 sw_if_index = 0;
5502   u8 sw_if_index_set = 0;
5503   u8 is_enable = 1;
5504   u8 is_ipv6 = 0;
5505   int ret;
5506
5507   /* Parse args required to build the message */
5508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5509     {
5510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5511         sw_if_index_set = 1;
5512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5513         sw_if_index_set = 1;
5514       else if (unformat (i, "enable"))
5515         is_enable = 1;
5516       else if (unformat (i, "disable"))
5517         is_enable = 0;
5518       else if (unformat (i, "ip4"))
5519         is_ipv6 = 0;
5520       else if (unformat (i, "ip6"))
5521         is_ipv6 = 1;
5522       else
5523         break;
5524     }
5525
5526   if (sw_if_index_set == 0)
5527     {
5528       errmsg ("missing interface name or sw_if_index");
5529       return -99;
5530     }
5531
5532   /* Construct the API message */
5533   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5534
5535   mp->sw_if_index = ntohl (sw_if_index);
5536   mp->enable = is_enable;
5537   mp->is_ipv6 = is_ipv6;
5538
5539   /* send it... */
5540   S (mp);
5541
5542   /* Wait for a reply... */
5543   W (ret);
5544   return ret;
5545 }
5546
5547 static int
5548 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5549 {
5550   unformat_input_t *i = vam->input;
5551   vl_api_sw_interface_set_l2_xconnect_t *mp;
5552   u32 rx_sw_if_index;
5553   u8 rx_sw_if_index_set = 0;
5554   u32 tx_sw_if_index;
5555   u8 tx_sw_if_index_set = 0;
5556   u8 enable = 1;
5557   int ret;
5558
5559   /* Parse args required to build the message */
5560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5561     {
5562       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5563         rx_sw_if_index_set = 1;
5564       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5565         tx_sw_if_index_set = 1;
5566       else if (unformat (i, "rx"))
5567         {
5568           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5569             {
5570               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5571                             &rx_sw_if_index))
5572                 rx_sw_if_index_set = 1;
5573             }
5574           else
5575             break;
5576         }
5577       else if (unformat (i, "tx"))
5578         {
5579           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5580             {
5581               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5582                             &tx_sw_if_index))
5583                 tx_sw_if_index_set = 1;
5584             }
5585           else
5586             break;
5587         }
5588       else if (unformat (i, "enable"))
5589         enable = 1;
5590       else if (unformat (i, "disable"))
5591         enable = 0;
5592       else
5593         break;
5594     }
5595
5596   if (rx_sw_if_index_set == 0)
5597     {
5598       errmsg ("missing rx interface name or rx_sw_if_index");
5599       return -99;
5600     }
5601
5602   if (enable && (tx_sw_if_index_set == 0))
5603     {
5604       errmsg ("missing tx interface name or tx_sw_if_index");
5605       return -99;
5606     }
5607
5608   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5609
5610   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5611   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5612   mp->enable = enable;
5613
5614   S (mp);
5615   W (ret);
5616   return ret;
5617 }
5618
5619 static int
5620 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5621 {
5622   unformat_input_t *i = vam->input;
5623   vl_api_sw_interface_set_l2_bridge_t *mp;
5624   u32 rx_sw_if_index;
5625   u8 rx_sw_if_index_set = 0;
5626   u32 bd_id;
5627   u8 bd_id_set = 0;
5628   u8 bvi = 0;
5629   u32 shg = 0;
5630   u8 enable = 1;
5631   int ret;
5632
5633   /* Parse args required to build the message */
5634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5635     {
5636       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5637         rx_sw_if_index_set = 1;
5638       else if (unformat (i, "bd_id %d", &bd_id))
5639         bd_id_set = 1;
5640       else
5641         if (unformat
5642             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5643         rx_sw_if_index_set = 1;
5644       else if (unformat (i, "shg %d", &shg))
5645         ;
5646       else if (unformat (i, "bvi"))
5647         bvi = 1;
5648       else if (unformat (i, "enable"))
5649         enable = 1;
5650       else if (unformat (i, "disable"))
5651         enable = 0;
5652       else
5653         break;
5654     }
5655
5656   if (rx_sw_if_index_set == 0)
5657     {
5658       errmsg ("missing rx interface name or sw_if_index");
5659       return -99;
5660     }
5661
5662   if (enable && (bd_id_set == 0))
5663     {
5664       errmsg ("missing bridge domain");
5665       return -99;
5666     }
5667
5668   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5669
5670   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5671   mp->bd_id = ntohl (bd_id);
5672   mp->shg = (u8) shg;
5673   mp->bvi = bvi;
5674   mp->enable = enable;
5675
5676   S (mp);
5677   W (ret);
5678   return ret;
5679 }
5680
5681 static int
5682 api_bridge_domain_dump (vat_main_t * vam)
5683 {
5684   unformat_input_t *i = vam->input;
5685   vl_api_bridge_domain_dump_t *mp;
5686   u32 bd_id = ~0;
5687   int ret;
5688
5689   /* Parse args required to build the message */
5690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5691     {
5692       if (unformat (i, "bd_id %d", &bd_id))
5693         ;
5694       else
5695         break;
5696     }
5697
5698   M (BRIDGE_DOMAIN_DUMP, mp);
5699   mp->bd_id = ntohl (bd_id);
5700   S (mp);
5701
5702   /* Use a control ping for synchronization */
5703   {
5704     vl_api_control_ping_t *mp;
5705     M (CONTROL_PING, mp);
5706     S (mp);
5707   }
5708
5709   W (ret);
5710   return ret;
5711 }
5712
5713 static int
5714 api_bridge_domain_add_del (vat_main_t * vam)
5715 {
5716   unformat_input_t *i = vam->input;
5717   vl_api_bridge_domain_add_del_t *mp;
5718   u32 bd_id = ~0;
5719   u8 is_add = 1;
5720   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5721   u32 mac_age = 0;
5722   int ret;
5723
5724   /* Parse args required to build the message */
5725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5726     {
5727       if (unformat (i, "bd_id %d", &bd_id))
5728         ;
5729       else if (unformat (i, "flood %d", &flood))
5730         ;
5731       else if (unformat (i, "uu-flood %d", &uu_flood))
5732         ;
5733       else if (unformat (i, "forward %d", &forward))
5734         ;
5735       else if (unformat (i, "learn %d", &learn))
5736         ;
5737       else if (unformat (i, "arp-term %d", &arp_term))
5738         ;
5739       else if (unformat (i, "mac-age %d", &mac_age))
5740         ;
5741       else if (unformat (i, "del"))
5742         {
5743           is_add = 0;
5744           flood = uu_flood = forward = learn = 0;
5745         }
5746       else
5747         break;
5748     }
5749
5750   if (bd_id == ~0)
5751     {
5752       errmsg ("missing bridge domain");
5753       return -99;
5754     }
5755
5756   if (mac_age > 255)
5757     {
5758       errmsg ("mac age must be less than 256 ");
5759       return -99;
5760     }
5761
5762   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5763
5764   mp->bd_id = ntohl (bd_id);
5765   mp->flood = flood;
5766   mp->uu_flood = uu_flood;
5767   mp->forward = forward;
5768   mp->learn = learn;
5769   mp->arp_term = arp_term;
5770   mp->is_add = is_add;
5771   mp->mac_age = (u8) mac_age;
5772
5773   S (mp);
5774   W (ret);
5775   return ret;
5776 }
5777
5778 static int
5779 api_l2fib_add_del (vat_main_t * vam)
5780 {
5781   unformat_input_t *i = vam->input;
5782   vl_api_l2fib_add_del_t *mp;
5783   f64 timeout;
5784   u64 mac = 0;
5785   u8 mac_set = 0;
5786   u32 bd_id;
5787   u8 bd_id_set = 0;
5788   u32 sw_if_index = ~0;
5789   u8 sw_if_index_set = 0;
5790   u8 is_add = 1;
5791   u8 static_mac = 0;
5792   u8 filter_mac = 0;
5793   u8 bvi_mac = 0;
5794   int count = 1;
5795   f64 before = 0;
5796   int j;
5797
5798   /* Parse args required to build the message */
5799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5800     {
5801       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5802         mac_set = 1;
5803       else if (unformat (i, "bd_id %d", &bd_id))
5804         bd_id_set = 1;
5805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5806         sw_if_index_set = 1;
5807       else if (unformat (i, "sw_if"))
5808         {
5809           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5810             {
5811               if (unformat
5812                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5813                 sw_if_index_set = 1;
5814             }
5815           else
5816             break;
5817         }
5818       else if (unformat (i, "static"))
5819         static_mac = 1;
5820       else if (unformat (i, "filter"))
5821         {
5822           filter_mac = 1;
5823           static_mac = 1;
5824         }
5825       else if (unformat (i, "bvi"))
5826         {
5827           bvi_mac = 1;
5828           static_mac = 1;
5829         }
5830       else if (unformat (i, "del"))
5831         is_add = 0;
5832       else if (unformat (i, "count %d", &count))
5833         ;
5834       else
5835         break;
5836     }
5837
5838   if (mac_set == 0)
5839     {
5840       errmsg ("missing mac address");
5841       return -99;
5842     }
5843
5844   if (bd_id_set == 0)
5845     {
5846       errmsg ("missing bridge domain");
5847       return -99;
5848     }
5849
5850   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5851     {
5852       errmsg ("missing interface name or sw_if_index");
5853       return -99;
5854     }
5855
5856   if (count > 1)
5857     {
5858       /* Turn on async mode */
5859       vam->async_mode = 1;
5860       vam->async_errors = 0;
5861       before = vat_time_now (vam);
5862     }
5863
5864   for (j = 0; j < count; j++)
5865     {
5866       M (L2FIB_ADD_DEL, mp);
5867
5868       mp->mac = mac;
5869       mp->bd_id = ntohl (bd_id);
5870       mp->is_add = is_add;
5871
5872       if (is_add)
5873         {
5874           mp->sw_if_index = ntohl (sw_if_index);
5875           mp->static_mac = static_mac;
5876           mp->filter_mac = filter_mac;
5877           mp->bvi_mac = bvi_mac;
5878         }
5879       increment_mac_address (&mac);
5880       /* send it... */
5881       S (mp);
5882     }
5883
5884   if (count > 1)
5885     {
5886       vl_api_control_ping_t *mp;
5887       f64 after;
5888
5889       /* Shut off async mode */
5890       vam->async_mode = 0;
5891
5892       M (CONTROL_PING, mp);
5893       S (mp);
5894
5895       timeout = vat_time_now (vam) + 1.0;
5896       while (vat_time_now (vam) < timeout)
5897         if (vam->result_ready == 1)
5898           goto out;
5899       vam->retval = -99;
5900
5901     out:
5902       if (vam->retval == -99)
5903         errmsg ("timeout");
5904
5905       if (vam->async_errors > 0)
5906         {
5907           errmsg ("%d asynchronous errors", vam->async_errors);
5908           vam->retval = -98;
5909         }
5910       vam->async_errors = 0;
5911       after = vat_time_now (vam);
5912
5913       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5914              count, after - before, count / (after - before));
5915     }
5916   else
5917     {
5918       int ret;
5919
5920       /* Wait for a reply... */
5921       W (ret);
5922       return ret;
5923     }
5924   /* Return the good/bad news */
5925   return (vam->retval);
5926 }
5927
5928 static int
5929 api_l2_flags (vat_main_t * vam)
5930 {
5931   unformat_input_t *i = vam->input;
5932   vl_api_l2_flags_t *mp;
5933   u32 sw_if_index;
5934   u32 feature_bitmap = 0;
5935   u8 sw_if_index_set = 0;
5936   int ret;
5937
5938   /* Parse args required to build the message */
5939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5940     {
5941       if (unformat (i, "sw_if_index %d", &sw_if_index))
5942         sw_if_index_set = 1;
5943       else if (unformat (i, "sw_if"))
5944         {
5945           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5946             {
5947               if (unformat
5948                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5949                 sw_if_index_set = 1;
5950             }
5951           else
5952             break;
5953         }
5954       else if (unformat (i, "learn"))
5955         feature_bitmap |= L2INPUT_FEAT_LEARN;
5956       else if (unformat (i, "forward"))
5957         feature_bitmap |= L2INPUT_FEAT_FWD;
5958       else if (unformat (i, "flood"))
5959         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5960       else if (unformat (i, "uu-flood"))
5961         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5962       else
5963         break;
5964     }
5965
5966   if (sw_if_index_set == 0)
5967     {
5968       errmsg ("missing interface name or sw_if_index");
5969       return -99;
5970     }
5971
5972   M (L2_FLAGS, mp);
5973
5974   mp->sw_if_index = ntohl (sw_if_index);
5975   mp->feature_bitmap = ntohl (feature_bitmap);
5976
5977   S (mp);
5978   W (ret);
5979   return ret;
5980 }
5981
5982 static int
5983 api_bridge_flags (vat_main_t * vam)
5984 {
5985   unformat_input_t *i = vam->input;
5986   vl_api_bridge_flags_t *mp;
5987   u32 bd_id;
5988   u8 bd_id_set = 0;
5989   u8 is_set = 1;
5990   u32 flags = 0;
5991   int ret;
5992
5993   /* Parse args required to build the message */
5994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5995     {
5996       if (unformat (i, "bd_id %d", &bd_id))
5997         bd_id_set = 1;
5998       else if (unformat (i, "learn"))
5999         flags |= L2_LEARN;
6000       else if (unformat (i, "forward"))
6001         flags |= L2_FWD;
6002       else if (unformat (i, "flood"))
6003         flags |= L2_FLOOD;
6004       else if (unformat (i, "uu-flood"))
6005         flags |= L2_UU_FLOOD;
6006       else if (unformat (i, "arp-term"))
6007         flags |= L2_ARP_TERM;
6008       else if (unformat (i, "off"))
6009         is_set = 0;
6010       else if (unformat (i, "disable"))
6011         is_set = 0;
6012       else
6013         break;
6014     }
6015
6016   if (bd_id_set == 0)
6017     {
6018       errmsg ("missing bridge domain");
6019       return -99;
6020     }
6021
6022   M (BRIDGE_FLAGS, mp);
6023
6024   mp->bd_id = ntohl (bd_id);
6025   mp->feature_bitmap = ntohl (flags);
6026   mp->is_set = is_set;
6027
6028   S (mp);
6029   W (ret);
6030   return ret;
6031 }
6032
6033 static int
6034 api_bd_ip_mac_add_del (vat_main_t * vam)
6035 {
6036   unformat_input_t *i = vam->input;
6037   vl_api_bd_ip_mac_add_del_t *mp;
6038   u32 bd_id;
6039   u8 is_ipv6 = 0;
6040   u8 is_add = 1;
6041   u8 bd_id_set = 0;
6042   u8 ip_set = 0;
6043   u8 mac_set = 0;
6044   ip4_address_t v4addr;
6045   ip6_address_t v6addr;
6046   u8 macaddr[6];
6047   int ret;
6048
6049
6050   /* Parse args required to build the message */
6051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6052     {
6053       if (unformat (i, "bd_id %d", &bd_id))
6054         {
6055           bd_id_set++;
6056         }
6057       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6058         {
6059           ip_set++;
6060         }
6061       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6062         {
6063           ip_set++;
6064           is_ipv6++;
6065         }
6066       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6067         {
6068           mac_set++;
6069         }
6070       else if (unformat (i, "del"))
6071         is_add = 0;
6072       else
6073         break;
6074     }
6075
6076   if (bd_id_set == 0)
6077     {
6078       errmsg ("missing bridge domain");
6079       return -99;
6080     }
6081   else if (ip_set == 0)
6082     {
6083       errmsg ("missing IP address");
6084       return -99;
6085     }
6086   else if (mac_set == 0)
6087     {
6088       errmsg ("missing MAC address");
6089       return -99;
6090     }
6091
6092   M (BD_IP_MAC_ADD_DEL, mp);
6093
6094   mp->bd_id = ntohl (bd_id);
6095   mp->is_ipv6 = is_ipv6;
6096   mp->is_add = is_add;
6097   if (is_ipv6)
6098     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6099   else
6100     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6101   clib_memcpy (mp->mac_address, macaddr, 6);
6102   S (mp);
6103   W (ret);
6104   return ret;
6105 }
6106
6107 static int
6108 api_tap_connect (vat_main_t * vam)
6109 {
6110   unformat_input_t *i = vam->input;
6111   vl_api_tap_connect_t *mp;
6112   u8 mac_address[6];
6113   u8 random_mac = 1;
6114   u8 name_set = 0;
6115   u8 *tap_name;
6116   u8 *tag = 0;
6117   ip4_address_t ip4_address;
6118   u32 ip4_mask_width;
6119   int ip4_address_set = 0;
6120   ip6_address_t ip6_address;
6121   u32 ip6_mask_width;
6122   int ip6_address_set = 0;
6123   int ret;
6124
6125   memset (mac_address, 0, sizeof (mac_address));
6126
6127   /* Parse args required to build the message */
6128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6129     {
6130       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6131         {
6132           random_mac = 0;
6133         }
6134       else if (unformat (i, "random-mac"))
6135         random_mac = 1;
6136       else if (unformat (i, "tapname %s", &tap_name))
6137         name_set = 1;
6138       else if (unformat (i, "tag %s", &tag))
6139         ;
6140       else if (unformat (i, "address %U/%d",
6141                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6142         ip4_address_set = 1;
6143       else if (unformat (i, "address %U/%d",
6144                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6145         ip6_address_set = 1;
6146       else
6147         break;
6148     }
6149
6150   if (name_set == 0)
6151     {
6152       errmsg ("missing tap name");
6153       return -99;
6154     }
6155   if (vec_len (tap_name) > 63)
6156     {
6157       errmsg ("tap name too long");
6158       return -99;
6159     }
6160   vec_add1 (tap_name, 0);
6161
6162   if (vec_len (tag) > 63)
6163     {
6164       errmsg ("tag too long");
6165       return -99;
6166     }
6167
6168   /* Construct the API message */
6169   M (TAP_CONNECT, mp);
6170
6171   mp->use_random_mac = random_mac;
6172   clib_memcpy (mp->mac_address, mac_address, 6);
6173   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6174   if (tag)
6175     clib_memcpy (mp->tag, tag, vec_len (tag));
6176
6177   if (ip4_address_set)
6178     {
6179       mp->ip4_address_set = 1;
6180       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6181       mp->ip4_mask_width = ip4_mask_width;
6182     }
6183   if (ip6_address_set)
6184     {
6185       mp->ip6_address_set = 1;
6186       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6187       mp->ip6_mask_width = ip6_mask_width;
6188     }
6189
6190   vec_free (tap_name);
6191   vec_free (tag);
6192
6193   /* send it... */
6194   S (mp);
6195
6196   /* Wait for a reply... */
6197   W (ret);
6198   return ret;
6199 }
6200
6201 static int
6202 api_tap_modify (vat_main_t * vam)
6203 {
6204   unformat_input_t *i = vam->input;
6205   vl_api_tap_modify_t *mp;
6206   u8 mac_address[6];
6207   u8 random_mac = 1;
6208   u8 name_set = 0;
6209   u8 *tap_name;
6210   u32 sw_if_index = ~0;
6211   u8 sw_if_index_set = 0;
6212   int ret;
6213
6214   memset (mac_address, 0, sizeof (mac_address));
6215
6216   /* Parse args required to build the message */
6217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6218     {
6219       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6220         sw_if_index_set = 1;
6221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6222         sw_if_index_set = 1;
6223       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6224         {
6225           random_mac = 0;
6226         }
6227       else if (unformat (i, "random-mac"))
6228         random_mac = 1;
6229       else if (unformat (i, "tapname %s", &tap_name))
6230         name_set = 1;
6231       else
6232         break;
6233     }
6234
6235   if (sw_if_index_set == 0)
6236     {
6237       errmsg ("missing vpp interface name");
6238       return -99;
6239     }
6240   if (name_set == 0)
6241     {
6242       errmsg ("missing tap name");
6243       return -99;
6244     }
6245   if (vec_len (tap_name) > 63)
6246     {
6247       errmsg ("tap name too long");
6248     }
6249   vec_add1 (tap_name, 0);
6250
6251   /* Construct the API message */
6252   M (TAP_MODIFY, mp);
6253
6254   mp->use_random_mac = random_mac;
6255   mp->sw_if_index = ntohl (sw_if_index);
6256   clib_memcpy (mp->mac_address, mac_address, 6);
6257   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6258   vec_free (tap_name);
6259
6260   /* send it... */
6261   S (mp);
6262
6263   /* Wait for a reply... */
6264   W (ret);
6265   return ret;
6266 }
6267
6268 static int
6269 api_tap_delete (vat_main_t * vam)
6270 {
6271   unformat_input_t *i = vam->input;
6272   vl_api_tap_delete_t *mp;
6273   u32 sw_if_index = ~0;
6274   u8 sw_if_index_set = 0;
6275   int ret;
6276
6277   /* Parse args required to build the message */
6278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6279     {
6280       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6281         sw_if_index_set = 1;
6282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6283         sw_if_index_set = 1;
6284       else
6285         break;
6286     }
6287
6288   if (sw_if_index_set == 0)
6289     {
6290       errmsg ("missing vpp interface name");
6291       return -99;
6292     }
6293
6294   /* Construct the API message */
6295   M (TAP_DELETE, mp);
6296
6297   mp->sw_if_index = ntohl (sw_if_index);
6298
6299   /* send it... */
6300   S (mp);
6301
6302   /* Wait for a reply... */
6303   W (ret);
6304   return ret;
6305 }
6306
6307 static int
6308 api_ip_add_del_route (vat_main_t * vam)
6309 {
6310   unformat_input_t *i = vam->input;
6311   vl_api_ip_add_del_route_t *mp;
6312   u32 sw_if_index = ~0, vrf_id = 0;
6313   u8 is_ipv6 = 0;
6314   u8 is_local = 0, is_drop = 0;
6315   u8 is_unreach = 0, is_prohibit = 0;
6316   u8 create_vrf_if_needed = 0;
6317   u8 is_add = 1;
6318   u32 next_hop_weight = 1;
6319   u8 not_last = 0;
6320   u8 is_multipath = 0;
6321   u8 address_set = 0;
6322   u8 address_length_set = 0;
6323   u32 next_hop_table_id = 0;
6324   u32 resolve_attempts = 0;
6325   u32 dst_address_length = 0;
6326   u8 next_hop_set = 0;
6327   ip4_address_t v4_dst_address, v4_next_hop_address;
6328   ip6_address_t v6_dst_address, v6_next_hop_address;
6329   int count = 1;
6330   int j;
6331   f64 before = 0;
6332   u32 random_add_del = 0;
6333   u32 *random_vector = 0;
6334   uword *random_hash;
6335   u32 random_seed = 0xdeaddabe;
6336   u32 classify_table_index = ~0;
6337   u8 is_classify = 0;
6338   u8 resolve_host = 0, resolve_attached = 0;
6339   mpls_label_t *next_hop_out_label_stack = NULL;
6340   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6341   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6342
6343   /* Parse args required to build the message */
6344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6345     {
6346       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6347         ;
6348       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6349         ;
6350       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6351         {
6352           address_set = 1;
6353           is_ipv6 = 0;
6354         }
6355       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6356         {
6357           address_set = 1;
6358           is_ipv6 = 1;
6359         }
6360       else if (unformat (i, "/%d", &dst_address_length))
6361         {
6362           address_length_set = 1;
6363         }
6364
6365       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6366                                          &v4_next_hop_address))
6367         {
6368           next_hop_set = 1;
6369         }
6370       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6371                                          &v6_next_hop_address))
6372         {
6373           next_hop_set = 1;
6374         }
6375       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6376         ;
6377       else if (unformat (i, "weight %d", &next_hop_weight))
6378         ;
6379       else if (unformat (i, "drop"))
6380         {
6381           is_drop = 1;
6382         }
6383       else if (unformat (i, "null-send-unreach"))
6384         {
6385           is_unreach = 1;
6386         }
6387       else if (unformat (i, "null-send-prohibit"))
6388         {
6389           is_prohibit = 1;
6390         }
6391       else if (unformat (i, "local"))
6392         {
6393           is_local = 1;
6394         }
6395       else if (unformat (i, "classify %d", &classify_table_index))
6396         {
6397           is_classify = 1;
6398         }
6399       else if (unformat (i, "del"))
6400         is_add = 0;
6401       else if (unformat (i, "add"))
6402         is_add = 1;
6403       else if (unformat (i, "not-last"))
6404         not_last = 1;
6405       else if (unformat (i, "resolve-via-host"))
6406         resolve_host = 1;
6407       else if (unformat (i, "resolve-via-attached"))
6408         resolve_attached = 1;
6409       else if (unformat (i, "multipath"))
6410         is_multipath = 1;
6411       else if (unformat (i, "vrf %d", &vrf_id))
6412         ;
6413       else if (unformat (i, "create-vrf"))
6414         create_vrf_if_needed = 1;
6415       else if (unformat (i, "count %d", &count))
6416         ;
6417       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6418         ;
6419       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6420         ;
6421       else if (unformat (i, "out-label %d", &next_hop_out_label))
6422         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6423       else if (unformat (i, "via-label %d", &next_hop_via_label))
6424         ;
6425       else if (unformat (i, "random"))
6426         random_add_del = 1;
6427       else if (unformat (i, "seed %d", &random_seed))
6428         ;
6429       else
6430         {
6431           clib_warning ("parse error '%U'", format_unformat_error, i);
6432           return -99;
6433         }
6434     }
6435
6436   if (!next_hop_set && !is_drop && !is_local &&
6437       !is_classify && !is_unreach && !is_prohibit &&
6438       MPLS_LABEL_INVALID == next_hop_via_label)
6439     {
6440       errmsg
6441         ("next hop / local / drop / unreach / prohibit / classify not set");
6442       return -99;
6443     }
6444
6445   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6446     {
6447       errmsg ("next hop and next-hop via label set");
6448       return -99;
6449     }
6450   if (address_set == 0)
6451     {
6452       errmsg ("missing addresses");
6453       return -99;
6454     }
6455
6456   if (address_length_set == 0)
6457     {
6458       errmsg ("missing address length");
6459       return -99;
6460     }
6461
6462   /* Generate a pile of unique, random routes */
6463   if (random_add_del)
6464     {
6465       u32 this_random_address;
6466       random_hash = hash_create (count, sizeof (uword));
6467
6468       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6469       for (j = 0; j <= count; j++)
6470         {
6471           do
6472             {
6473               this_random_address = random_u32 (&random_seed);
6474               this_random_address =
6475                 clib_host_to_net_u32 (this_random_address);
6476             }
6477           while (hash_get (random_hash, this_random_address));
6478           vec_add1 (random_vector, this_random_address);
6479           hash_set (random_hash, this_random_address, 1);
6480         }
6481       hash_free (random_hash);
6482       v4_dst_address.as_u32 = random_vector[0];
6483     }
6484
6485   if (count > 1)
6486     {
6487       /* Turn on async mode */
6488       vam->async_mode = 1;
6489       vam->async_errors = 0;
6490       before = vat_time_now (vam);
6491     }
6492
6493   for (j = 0; j < count; j++)
6494     {
6495       /* Construct the API message */
6496       M2 (IP_ADD_DEL_ROUTE, mp,
6497           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6498
6499       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6500       mp->table_id = ntohl (vrf_id);
6501       mp->create_vrf_if_needed = create_vrf_if_needed;
6502
6503       mp->is_add = is_add;
6504       mp->is_drop = is_drop;
6505       mp->is_unreach = is_unreach;
6506       mp->is_prohibit = is_prohibit;
6507       mp->is_ipv6 = is_ipv6;
6508       mp->is_local = is_local;
6509       mp->is_classify = is_classify;
6510       mp->is_multipath = is_multipath;
6511       mp->is_resolve_host = resolve_host;
6512       mp->is_resolve_attached = resolve_attached;
6513       mp->not_last = not_last;
6514       mp->next_hop_weight = next_hop_weight;
6515       mp->dst_address_length = dst_address_length;
6516       mp->next_hop_table_id = ntohl (next_hop_table_id);
6517       mp->classify_table_index = ntohl (classify_table_index);
6518       mp->next_hop_via_label = ntohl (next_hop_via_label);
6519       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6520       if (0 != mp->next_hop_n_out_labels)
6521         {
6522           memcpy (mp->next_hop_out_label_stack,
6523                   next_hop_out_label_stack,
6524                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6525           vec_free (next_hop_out_label_stack);
6526         }
6527
6528       if (is_ipv6)
6529         {
6530           clib_memcpy (mp->dst_address, &v6_dst_address,
6531                        sizeof (v6_dst_address));
6532           if (next_hop_set)
6533             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6534                          sizeof (v6_next_hop_address));
6535           increment_v6_address (&v6_dst_address);
6536         }
6537       else
6538         {
6539           clib_memcpy (mp->dst_address, &v4_dst_address,
6540                        sizeof (v4_dst_address));
6541           if (next_hop_set)
6542             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6543                          sizeof (v4_next_hop_address));
6544           if (random_add_del)
6545             v4_dst_address.as_u32 = random_vector[j + 1];
6546           else
6547             increment_v4_address (&v4_dst_address);
6548         }
6549       /* send it... */
6550       S (mp);
6551       /* If we receive SIGTERM, stop now... */
6552       if (vam->do_exit)
6553         break;
6554     }
6555
6556   /* When testing multiple add/del ops, use a control-ping to sync */
6557   if (count > 1)
6558     {
6559       vl_api_control_ping_t *mp;
6560       f64 after;
6561       f64 timeout;
6562
6563       /* Shut off async mode */
6564       vam->async_mode = 0;
6565
6566       M (CONTROL_PING, mp);
6567       S (mp);
6568
6569       timeout = vat_time_now (vam) + 1.0;
6570       while (vat_time_now (vam) < timeout)
6571         if (vam->result_ready == 1)
6572           goto out;
6573       vam->retval = -99;
6574
6575     out:
6576       if (vam->retval == -99)
6577         errmsg ("timeout");
6578
6579       if (vam->async_errors > 0)
6580         {
6581           errmsg ("%d asynchronous errors", vam->async_errors);
6582           vam->retval = -98;
6583         }
6584       vam->async_errors = 0;
6585       after = vat_time_now (vam);
6586
6587       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6588       if (j > 0)
6589         count = j;
6590
6591       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6592              count, after - before, count / (after - before));
6593     }
6594   else
6595     {
6596       int ret;
6597
6598       /* Wait for a reply... */
6599       W (ret);
6600       return ret;
6601     }
6602
6603   /* Return the good/bad news */
6604   return (vam->retval);
6605 }
6606
6607 static int
6608 api_ip_mroute_add_del (vat_main_t * vam)
6609 {
6610   unformat_input_t *i = vam->input;
6611   vl_api_ip_mroute_add_del_t *mp;
6612   u32 sw_if_index = ~0, vrf_id = 0;
6613   u8 is_ipv6 = 0;
6614   u8 is_local = 0;
6615   u8 create_vrf_if_needed = 0;
6616   u8 is_add = 1;
6617   u8 address_set = 0;
6618   u32 grp_address_length = 0;
6619   ip4_address_t v4_grp_address, v4_src_address;
6620   ip6_address_t v6_grp_address, v6_src_address;
6621   mfib_itf_flags_t iflags = 0;
6622   mfib_entry_flags_t eflags = 0;
6623   int ret;
6624
6625   /* Parse args required to build the message */
6626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6627     {
6628       if (unformat (i, "sw_if_index %d", &sw_if_index))
6629         ;
6630       else if (unformat (i, "%U %U",
6631                          unformat_ip4_address, &v4_src_address,
6632                          unformat_ip4_address, &v4_grp_address))
6633         {
6634           grp_address_length = 64;
6635           address_set = 1;
6636           is_ipv6 = 0;
6637         }
6638       else if (unformat (i, "%U %U",
6639                          unformat_ip6_address, &v6_src_address,
6640                          unformat_ip6_address, &v6_grp_address))
6641         {
6642           grp_address_length = 256;
6643           address_set = 1;
6644           is_ipv6 = 1;
6645         }
6646       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6647         {
6648           memset (&v4_src_address, 0, sizeof (v4_src_address));
6649           grp_address_length = 32;
6650           address_set = 1;
6651           is_ipv6 = 0;
6652         }
6653       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6654         {
6655           memset (&v6_src_address, 0, sizeof (v6_src_address));
6656           grp_address_length = 128;
6657           address_set = 1;
6658           is_ipv6 = 1;
6659         }
6660       else if (unformat (i, "/%d", &grp_address_length))
6661         ;
6662       else if (unformat (i, "local"))
6663         {
6664           is_local = 1;
6665         }
6666       else if (unformat (i, "del"))
6667         is_add = 0;
6668       else if (unformat (i, "add"))
6669         is_add = 1;
6670       else if (unformat (i, "vrf %d", &vrf_id))
6671         ;
6672       else if (unformat (i, "create-vrf"))
6673         create_vrf_if_needed = 1;
6674       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6675         ;
6676       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6677         ;
6678       else
6679         {
6680           clib_warning ("parse error '%U'", format_unformat_error, i);
6681           return -99;
6682         }
6683     }
6684
6685   if (address_set == 0)
6686     {
6687       errmsg ("missing addresses\n");
6688       return -99;
6689     }
6690
6691   /* Construct the API message */
6692   M (IP_MROUTE_ADD_DEL, mp);
6693
6694   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6695   mp->table_id = ntohl (vrf_id);
6696   mp->create_vrf_if_needed = create_vrf_if_needed;
6697
6698   mp->is_add = is_add;
6699   mp->is_ipv6 = is_ipv6;
6700   mp->is_local = is_local;
6701   mp->itf_flags = ntohl (iflags);
6702   mp->entry_flags = ntohl (eflags);
6703   mp->grp_address_length = grp_address_length;
6704   mp->grp_address_length = ntohs (mp->grp_address_length);
6705
6706   if (is_ipv6)
6707     {
6708       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6709       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6710     }
6711   else
6712     {
6713       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6714       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6715
6716     }
6717
6718   /* send it... */
6719   S (mp);
6720   /* Wait for a reply... */
6721   W (ret);
6722   return ret;
6723 }
6724
6725 static int
6726 api_mpls_route_add_del (vat_main_t * vam)
6727 {
6728   unformat_input_t *i = vam->input;
6729   vl_api_mpls_route_add_del_t *mp;
6730   u32 sw_if_index = ~0, table_id = 0;
6731   u8 create_table_if_needed = 0;
6732   u8 is_add = 1;
6733   u32 next_hop_weight = 1;
6734   u8 is_multipath = 0;
6735   u32 next_hop_table_id = 0;
6736   u8 next_hop_set = 0;
6737   ip4_address_t v4_next_hop_address = {
6738     .as_u32 = 0,
6739   };
6740   ip6_address_t v6_next_hop_address = { {0} };
6741   int count = 1;
6742   int j;
6743   f64 before = 0;
6744   u32 classify_table_index = ~0;
6745   u8 is_classify = 0;
6746   u8 resolve_host = 0, resolve_attached = 0;
6747   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6748   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6749   mpls_label_t *next_hop_out_label_stack = NULL;
6750   mpls_label_t local_label = MPLS_LABEL_INVALID;
6751   u8 is_eos = 0;
6752   u8 next_hop_proto_is_ip4 = 1;
6753
6754   /* Parse args required to build the message */
6755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6756     {
6757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6758         ;
6759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6760         ;
6761       else if (unformat (i, "%d", &local_label))
6762         ;
6763       else if (unformat (i, "eos"))
6764         is_eos = 1;
6765       else if (unformat (i, "non-eos"))
6766         is_eos = 0;
6767       else if (unformat (i, "via %U", unformat_ip4_address,
6768                          &v4_next_hop_address))
6769         {
6770           next_hop_set = 1;
6771           next_hop_proto_is_ip4 = 1;
6772         }
6773       else if (unformat (i, "via %U", unformat_ip6_address,
6774                          &v6_next_hop_address))
6775         {
6776           next_hop_set = 1;
6777           next_hop_proto_is_ip4 = 0;
6778         }
6779       else if (unformat (i, "weight %d", &next_hop_weight))
6780         ;
6781       else if (unformat (i, "create-table"))
6782         create_table_if_needed = 1;
6783       else if (unformat (i, "classify %d", &classify_table_index))
6784         {
6785           is_classify = 1;
6786         }
6787       else if (unformat (i, "del"))
6788         is_add = 0;
6789       else if (unformat (i, "add"))
6790         is_add = 1;
6791       else if (unformat (i, "resolve-via-host"))
6792         resolve_host = 1;
6793       else if (unformat (i, "resolve-via-attached"))
6794         resolve_attached = 1;
6795       else if (unformat (i, "multipath"))
6796         is_multipath = 1;
6797       else if (unformat (i, "count %d", &count))
6798         ;
6799       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6800         {
6801           next_hop_set = 1;
6802           next_hop_proto_is_ip4 = 1;
6803         }
6804       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6805         {
6806           next_hop_set = 1;
6807           next_hop_proto_is_ip4 = 0;
6808         }
6809       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6810         ;
6811       else if (unformat (i, "via-label %d", &next_hop_via_label))
6812         ;
6813       else if (unformat (i, "out-label %d", &next_hop_out_label))
6814         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6815       else
6816         {
6817           clib_warning ("parse error '%U'", format_unformat_error, i);
6818           return -99;
6819         }
6820     }
6821
6822   if (!next_hop_set && !is_classify)
6823     {
6824       errmsg ("next hop / classify not set");
6825       return -99;
6826     }
6827
6828   if (MPLS_LABEL_INVALID == local_label)
6829     {
6830       errmsg ("missing label");
6831       return -99;
6832     }
6833
6834   if (count > 1)
6835     {
6836       /* Turn on async mode */
6837       vam->async_mode = 1;
6838       vam->async_errors = 0;
6839       before = vat_time_now (vam);
6840     }
6841
6842   for (j = 0; j < count; j++)
6843     {
6844       /* Construct the API message */
6845       M2 (MPLS_ROUTE_ADD_DEL, mp,
6846           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6847
6848       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6849       mp->mr_table_id = ntohl (table_id);
6850       mp->mr_create_table_if_needed = create_table_if_needed;
6851
6852       mp->mr_is_add = is_add;
6853       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6854       mp->mr_is_classify = is_classify;
6855       mp->mr_is_multipath = is_multipath;
6856       mp->mr_is_resolve_host = resolve_host;
6857       mp->mr_is_resolve_attached = resolve_attached;
6858       mp->mr_next_hop_weight = next_hop_weight;
6859       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6860       mp->mr_classify_table_index = ntohl (classify_table_index);
6861       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6862       mp->mr_label = ntohl (local_label);
6863       mp->mr_eos = is_eos;
6864
6865       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6866       if (0 != mp->mr_next_hop_n_out_labels)
6867         {
6868           memcpy (mp->mr_next_hop_out_label_stack,
6869                   next_hop_out_label_stack,
6870                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6871           vec_free (next_hop_out_label_stack);
6872         }
6873
6874       if (next_hop_set)
6875         {
6876           if (next_hop_proto_is_ip4)
6877             {
6878               clib_memcpy (mp->mr_next_hop,
6879                            &v4_next_hop_address,
6880                            sizeof (v4_next_hop_address));
6881             }
6882           else
6883             {
6884               clib_memcpy (mp->mr_next_hop,
6885                            &v6_next_hop_address,
6886                            sizeof (v6_next_hop_address));
6887             }
6888         }
6889       local_label++;
6890
6891       /* send it... */
6892       S (mp);
6893       /* If we receive SIGTERM, stop now... */
6894       if (vam->do_exit)
6895         break;
6896     }
6897
6898   /* When testing multiple add/del ops, use a control-ping to sync */
6899   if (count > 1)
6900     {
6901       vl_api_control_ping_t *mp;
6902       f64 after;
6903       f64 timeout;
6904
6905       /* Shut off async mode */
6906       vam->async_mode = 0;
6907
6908       M (CONTROL_PING, mp);
6909       S (mp);
6910
6911       timeout = vat_time_now (vam) + 1.0;
6912       while (vat_time_now (vam) < timeout)
6913         if (vam->result_ready == 1)
6914           goto out;
6915       vam->retval = -99;
6916
6917     out:
6918       if (vam->retval == -99)
6919         errmsg ("timeout");
6920
6921       if (vam->async_errors > 0)
6922         {
6923           errmsg ("%d asynchronous errors", vam->async_errors);
6924           vam->retval = -98;
6925         }
6926       vam->async_errors = 0;
6927       after = vat_time_now (vam);
6928
6929       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6930       if (j > 0)
6931         count = j;
6932
6933       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6934              count, after - before, count / (after - before));
6935     }
6936   else
6937     {
6938       int ret;
6939
6940       /* Wait for a reply... */
6941       W (ret);
6942       return ret;
6943     }
6944
6945   /* Return the good/bad news */
6946   return (vam->retval);
6947 }
6948
6949 static int
6950 api_mpls_ip_bind_unbind (vat_main_t * vam)
6951 {
6952   unformat_input_t *i = vam->input;
6953   vl_api_mpls_ip_bind_unbind_t *mp;
6954   u32 ip_table_id = 0;
6955   u8 create_table_if_needed = 0;
6956   u8 is_bind = 1;
6957   u8 is_ip4 = 1;
6958   ip4_address_t v4_address;
6959   ip6_address_t v6_address;
6960   u32 address_length;
6961   u8 address_set = 0;
6962   mpls_label_t local_label = MPLS_LABEL_INVALID;
6963   int ret;
6964
6965   /* Parse args required to build the message */
6966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6967     {
6968       if (unformat (i, "%U/%d", unformat_ip4_address,
6969                     &v4_address, &address_length))
6970         {
6971           is_ip4 = 1;
6972           address_set = 1;
6973         }
6974       else if (unformat (i, "%U/%d", unformat_ip6_address,
6975                          &v6_address, &address_length))
6976         {
6977           is_ip4 = 0;
6978           address_set = 1;
6979         }
6980       else if (unformat (i, "%d", &local_label))
6981         ;
6982       else if (unformat (i, "create-table"))
6983         create_table_if_needed = 1;
6984       else if (unformat (i, "table-id %d", &ip_table_id))
6985         ;
6986       else if (unformat (i, "unbind"))
6987         is_bind = 0;
6988       else if (unformat (i, "bind"))
6989         is_bind = 1;
6990       else
6991         {
6992           clib_warning ("parse error '%U'", format_unformat_error, i);
6993           return -99;
6994         }
6995     }
6996
6997   if (!address_set)
6998     {
6999       errmsg ("IP addres not set");
7000       return -99;
7001     }
7002
7003   if (MPLS_LABEL_INVALID == local_label)
7004     {
7005       errmsg ("missing label");
7006       return -99;
7007     }
7008
7009   /* Construct the API message */
7010   M (MPLS_IP_BIND_UNBIND, mp);
7011
7012   mp->mb_create_table_if_needed = create_table_if_needed;
7013   mp->mb_is_bind = is_bind;
7014   mp->mb_is_ip4 = is_ip4;
7015   mp->mb_ip_table_id = ntohl (ip_table_id);
7016   mp->mb_mpls_table_id = 0;
7017   mp->mb_label = ntohl (local_label);
7018   mp->mb_address_length = address_length;
7019
7020   if (is_ip4)
7021     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7022   else
7023     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7024
7025   /* send it... */
7026   S (mp);
7027
7028   /* Wait for a reply... */
7029   W (ret);
7030   return ret;
7031 }
7032
7033 static int
7034 api_proxy_arp_add_del (vat_main_t * vam)
7035 {
7036   unformat_input_t *i = vam->input;
7037   vl_api_proxy_arp_add_del_t *mp;
7038   u32 vrf_id = 0;
7039   u8 is_add = 1;
7040   ip4_address_t lo, hi;
7041   u8 range_set = 0;
7042   int ret;
7043
7044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7045     {
7046       if (unformat (i, "vrf %d", &vrf_id))
7047         ;
7048       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7049                          unformat_ip4_address, &hi))
7050         range_set = 1;
7051       else if (unformat (i, "del"))
7052         is_add = 0;
7053       else
7054         {
7055           clib_warning ("parse error '%U'", format_unformat_error, i);
7056           return -99;
7057         }
7058     }
7059
7060   if (range_set == 0)
7061     {
7062       errmsg ("address range not set");
7063       return -99;
7064     }
7065
7066   M (PROXY_ARP_ADD_DEL, mp);
7067
7068   mp->vrf_id = ntohl (vrf_id);
7069   mp->is_add = is_add;
7070   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7071   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7072
7073   S (mp);
7074   W (ret);
7075   return ret;
7076 }
7077
7078 static int
7079 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7080 {
7081   unformat_input_t *i = vam->input;
7082   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7083   u32 sw_if_index;
7084   u8 enable = 1;
7085   u8 sw_if_index_set = 0;
7086   int ret;
7087
7088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7089     {
7090       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7091         sw_if_index_set = 1;
7092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7093         sw_if_index_set = 1;
7094       else if (unformat (i, "enable"))
7095         enable = 1;
7096       else if (unformat (i, "disable"))
7097         enable = 0;
7098       else
7099         {
7100           clib_warning ("parse error '%U'", format_unformat_error, i);
7101           return -99;
7102         }
7103     }
7104
7105   if (sw_if_index_set == 0)
7106     {
7107       errmsg ("missing interface name or sw_if_index");
7108       return -99;
7109     }
7110
7111   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7112
7113   mp->sw_if_index = ntohl (sw_if_index);
7114   mp->enable_disable = enable;
7115
7116   S (mp);
7117   W (ret);
7118   return ret;
7119 }
7120
7121 static int
7122 api_mpls_tunnel_add_del (vat_main_t * vam)
7123 {
7124   unformat_input_t *i = vam->input;
7125   vl_api_mpls_tunnel_add_del_t *mp;
7126
7127   u8 is_add = 1;
7128   u8 l2_only = 0;
7129   u32 sw_if_index = ~0;
7130   u32 next_hop_sw_if_index = ~0;
7131   u32 next_hop_proto_is_ip4 = 1;
7132
7133   u32 next_hop_table_id = 0;
7134   ip4_address_t v4_next_hop_address = {
7135     .as_u32 = 0,
7136   };
7137   ip6_address_t v6_next_hop_address = { {0} };
7138   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7139   int ret;
7140
7141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7142     {
7143       if (unformat (i, "add"))
7144         is_add = 1;
7145       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7146         is_add = 0;
7147       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7148         ;
7149       else if (unformat (i, "via %U",
7150                          unformat_ip4_address, &v4_next_hop_address))
7151         {
7152           next_hop_proto_is_ip4 = 1;
7153         }
7154       else if (unformat (i, "via %U",
7155                          unformat_ip6_address, &v6_next_hop_address))
7156         {
7157           next_hop_proto_is_ip4 = 0;
7158         }
7159       else if (unformat (i, "l2-only"))
7160         l2_only = 1;
7161       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7162         ;
7163       else if (unformat (i, "out-label %d", &next_hop_out_label))
7164         vec_add1 (labels, ntohl (next_hop_out_label));
7165       else
7166         {
7167           clib_warning ("parse error '%U'", format_unformat_error, i);
7168           return -99;
7169         }
7170     }
7171
7172   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7173
7174   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7175   mp->mt_sw_if_index = ntohl (sw_if_index);
7176   mp->mt_is_add = is_add;
7177   mp->mt_l2_only = l2_only;
7178   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7179   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7180
7181   mp->mt_next_hop_n_out_labels = vec_len (labels);
7182
7183   if (0 != mp->mt_next_hop_n_out_labels)
7184     {
7185       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7186                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7187       vec_free (labels);
7188     }
7189
7190   if (next_hop_proto_is_ip4)
7191     {
7192       clib_memcpy (mp->mt_next_hop,
7193                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7194     }
7195   else
7196     {
7197       clib_memcpy (mp->mt_next_hop,
7198                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7199     }
7200
7201   S (mp);
7202   W (ret);
7203   return ret;
7204 }
7205
7206 static int
7207 api_sw_interface_set_unnumbered (vat_main_t * vam)
7208 {
7209   unformat_input_t *i = vam->input;
7210   vl_api_sw_interface_set_unnumbered_t *mp;
7211   u32 sw_if_index;
7212   u32 unnum_sw_index = ~0;
7213   u8 is_add = 1;
7214   u8 sw_if_index_set = 0;
7215   int ret;
7216
7217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218     {
7219       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7220         sw_if_index_set = 1;
7221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7222         sw_if_index_set = 1;
7223       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7224         ;
7225       else if (unformat (i, "del"))
7226         is_add = 0;
7227       else
7228         {
7229           clib_warning ("parse error '%U'", format_unformat_error, i);
7230           return -99;
7231         }
7232     }
7233
7234   if (sw_if_index_set == 0)
7235     {
7236       errmsg ("missing interface name or sw_if_index");
7237       return -99;
7238     }
7239
7240   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7241
7242   mp->sw_if_index = ntohl (sw_if_index);
7243   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7244   mp->is_add = is_add;
7245
7246   S (mp);
7247   W (ret);
7248   return ret;
7249 }
7250
7251 static int
7252 api_ip_neighbor_add_del (vat_main_t * vam)
7253 {
7254   unformat_input_t *i = vam->input;
7255   vl_api_ip_neighbor_add_del_t *mp;
7256   u32 sw_if_index;
7257   u8 sw_if_index_set = 0;
7258   u32 vrf_id = 0;
7259   u8 is_add = 1;
7260   u8 is_static = 0;
7261   u8 mac_address[6];
7262   u8 mac_set = 0;
7263   u8 v4_address_set = 0;
7264   u8 v6_address_set = 0;
7265   ip4_address_t v4address;
7266   ip6_address_t v6address;
7267   int ret;
7268
7269   memset (mac_address, 0, sizeof (mac_address));
7270
7271   /* Parse args required to build the message */
7272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7273     {
7274       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7275         {
7276           mac_set = 1;
7277         }
7278       else if (unformat (i, "del"))
7279         is_add = 0;
7280       else
7281         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7282         sw_if_index_set = 1;
7283       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7284         sw_if_index_set = 1;
7285       else if (unformat (i, "is_static"))
7286         is_static = 1;
7287       else if (unformat (i, "vrf %d", &vrf_id))
7288         ;
7289       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7290         v4_address_set = 1;
7291       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7292         v6_address_set = 1;
7293       else
7294         {
7295           clib_warning ("parse error '%U'", format_unformat_error, i);
7296           return -99;
7297         }
7298     }
7299
7300   if (sw_if_index_set == 0)
7301     {
7302       errmsg ("missing interface name or sw_if_index");
7303       return -99;
7304     }
7305   if (v4_address_set && v6_address_set)
7306     {
7307       errmsg ("both v4 and v6 addresses set");
7308       return -99;
7309     }
7310   if (!v4_address_set && !v6_address_set)
7311     {
7312       errmsg ("no address set");
7313       return -99;
7314     }
7315
7316   /* Construct the API message */
7317   M (IP_NEIGHBOR_ADD_DEL, mp);
7318
7319   mp->sw_if_index = ntohl (sw_if_index);
7320   mp->is_add = is_add;
7321   mp->vrf_id = ntohl (vrf_id);
7322   mp->is_static = is_static;
7323   if (mac_set)
7324     clib_memcpy (mp->mac_address, mac_address, 6);
7325   if (v6_address_set)
7326     {
7327       mp->is_ipv6 = 1;
7328       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7329     }
7330   else
7331     {
7332       /* mp->is_ipv6 = 0; via memset in M macro above */
7333       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7334     }
7335
7336   /* send it... */
7337   S (mp);
7338
7339   /* Wait for a reply, return good/bad news  */
7340   W (ret);
7341   return ret;
7342 }
7343
7344 static int
7345 api_reset_vrf (vat_main_t * vam)
7346 {
7347   unformat_input_t *i = vam->input;
7348   vl_api_reset_vrf_t *mp;
7349   u32 vrf_id = 0;
7350   u8 is_ipv6 = 0;
7351   u8 vrf_id_set = 0;
7352   int ret;
7353
7354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7355     {
7356       if (unformat (i, "vrf %d", &vrf_id))
7357         vrf_id_set = 1;
7358       else if (unformat (i, "ipv6"))
7359         is_ipv6 = 1;
7360       else
7361         {
7362           clib_warning ("parse error '%U'", format_unformat_error, i);
7363           return -99;
7364         }
7365     }
7366
7367   if (vrf_id_set == 0)
7368     {
7369       errmsg ("missing vrf id");
7370       return -99;
7371     }
7372
7373   M (RESET_VRF, mp);
7374
7375   mp->vrf_id = ntohl (vrf_id);
7376   mp->is_ipv6 = is_ipv6;
7377
7378   S (mp);
7379   W (ret);
7380   return ret;
7381 }
7382
7383 static int
7384 api_create_vlan_subif (vat_main_t * vam)
7385 {
7386   unformat_input_t *i = vam->input;
7387   vl_api_create_vlan_subif_t *mp;
7388   u32 sw_if_index;
7389   u8 sw_if_index_set = 0;
7390   u32 vlan_id;
7391   u8 vlan_id_set = 0;
7392   int ret;
7393
7394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7395     {
7396       if (unformat (i, "sw_if_index %d", &sw_if_index))
7397         sw_if_index_set = 1;
7398       else
7399         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7400         sw_if_index_set = 1;
7401       else if (unformat (i, "vlan %d", &vlan_id))
7402         vlan_id_set = 1;
7403       else
7404         {
7405           clib_warning ("parse error '%U'", format_unformat_error, i);
7406           return -99;
7407         }
7408     }
7409
7410   if (sw_if_index_set == 0)
7411     {
7412       errmsg ("missing interface name or sw_if_index");
7413       return -99;
7414     }
7415
7416   if (vlan_id_set == 0)
7417     {
7418       errmsg ("missing vlan_id");
7419       return -99;
7420     }
7421   M (CREATE_VLAN_SUBIF, mp);
7422
7423   mp->sw_if_index = ntohl (sw_if_index);
7424   mp->vlan_id = ntohl (vlan_id);
7425
7426   S (mp);
7427   W (ret);
7428   return ret;
7429 }
7430
7431 #define foreach_create_subif_bit                \
7432 _(no_tags)                                      \
7433 _(one_tag)                                      \
7434 _(two_tags)                                     \
7435 _(dot1ad)                                       \
7436 _(exact_match)                                  \
7437 _(default_sub)                                  \
7438 _(outer_vlan_id_any)                            \
7439 _(inner_vlan_id_any)
7440
7441 static int
7442 api_create_subif (vat_main_t * vam)
7443 {
7444   unformat_input_t *i = vam->input;
7445   vl_api_create_subif_t *mp;
7446   u32 sw_if_index;
7447   u8 sw_if_index_set = 0;
7448   u32 sub_id;
7449   u8 sub_id_set = 0;
7450   u32 no_tags = 0;
7451   u32 one_tag = 0;
7452   u32 two_tags = 0;
7453   u32 dot1ad = 0;
7454   u32 exact_match = 0;
7455   u32 default_sub = 0;
7456   u32 outer_vlan_id_any = 0;
7457   u32 inner_vlan_id_any = 0;
7458   u32 tmp;
7459   u16 outer_vlan_id = 0;
7460   u16 inner_vlan_id = 0;
7461   int ret;
7462
7463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7464     {
7465       if (unformat (i, "sw_if_index %d", &sw_if_index))
7466         sw_if_index_set = 1;
7467       else
7468         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7469         sw_if_index_set = 1;
7470       else if (unformat (i, "sub_id %d", &sub_id))
7471         sub_id_set = 1;
7472       else if (unformat (i, "outer_vlan_id %d", &tmp))
7473         outer_vlan_id = tmp;
7474       else if (unformat (i, "inner_vlan_id %d", &tmp))
7475         inner_vlan_id = tmp;
7476
7477 #define _(a) else if (unformat (i, #a)) a = 1 ;
7478       foreach_create_subif_bit
7479 #undef _
7480         else
7481         {
7482           clib_warning ("parse error '%U'", format_unformat_error, i);
7483           return -99;
7484         }
7485     }
7486
7487   if (sw_if_index_set == 0)
7488     {
7489       errmsg ("missing interface name or sw_if_index");
7490       return -99;
7491     }
7492
7493   if (sub_id_set == 0)
7494     {
7495       errmsg ("missing sub_id");
7496       return -99;
7497     }
7498   M (CREATE_SUBIF, mp);
7499
7500   mp->sw_if_index = ntohl (sw_if_index);
7501   mp->sub_id = ntohl (sub_id);
7502
7503 #define _(a) mp->a = a;
7504   foreach_create_subif_bit;
7505 #undef _
7506
7507   mp->outer_vlan_id = ntohs (outer_vlan_id);
7508   mp->inner_vlan_id = ntohs (inner_vlan_id);
7509
7510   S (mp);
7511   W (ret);
7512   return ret;
7513 }
7514
7515 static int
7516 api_oam_add_del (vat_main_t * vam)
7517 {
7518   unformat_input_t *i = vam->input;
7519   vl_api_oam_add_del_t *mp;
7520   u32 vrf_id = 0;
7521   u8 is_add = 1;
7522   ip4_address_t src, dst;
7523   u8 src_set = 0;
7524   u8 dst_set = 0;
7525   int ret;
7526
7527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7528     {
7529       if (unformat (i, "vrf %d", &vrf_id))
7530         ;
7531       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7532         src_set = 1;
7533       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7534         dst_set = 1;
7535       else if (unformat (i, "del"))
7536         is_add = 0;
7537       else
7538         {
7539           clib_warning ("parse error '%U'", format_unformat_error, i);
7540           return -99;
7541         }
7542     }
7543
7544   if (src_set == 0)
7545     {
7546       errmsg ("missing src addr");
7547       return -99;
7548     }
7549
7550   if (dst_set == 0)
7551     {
7552       errmsg ("missing dst addr");
7553       return -99;
7554     }
7555
7556   M (OAM_ADD_DEL, mp);
7557
7558   mp->vrf_id = ntohl (vrf_id);
7559   mp->is_add = is_add;
7560   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7561   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7562
7563   S (mp);
7564   W (ret);
7565   return ret;
7566 }
7567
7568 static int
7569 api_reset_fib (vat_main_t * vam)
7570 {
7571   unformat_input_t *i = vam->input;
7572   vl_api_reset_fib_t *mp;
7573   u32 vrf_id = 0;
7574   u8 is_ipv6 = 0;
7575   u8 vrf_id_set = 0;
7576
7577   int ret;
7578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7579     {
7580       if (unformat (i, "vrf %d", &vrf_id))
7581         vrf_id_set = 1;
7582       else if (unformat (i, "ipv6"))
7583         is_ipv6 = 1;
7584       else
7585         {
7586           clib_warning ("parse error '%U'", format_unformat_error, i);
7587           return -99;
7588         }
7589     }
7590
7591   if (vrf_id_set == 0)
7592     {
7593       errmsg ("missing vrf id");
7594       return -99;
7595     }
7596
7597   M (RESET_FIB, mp);
7598
7599   mp->vrf_id = ntohl (vrf_id);
7600   mp->is_ipv6 = is_ipv6;
7601
7602   S (mp);
7603   W (ret);
7604   return ret;
7605 }
7606
7607 static int
7608 api_dhcp_proxy_config (vat_main_t * vam)
7609 {
7610   unformat_input_t *i = vam->input;
7611   vl_api_dhcp_proxy_config_t *mp;
7612   u32 vrf_id = 0;
7613   u8 is_add = 1;
7614   u8 insert_cid = 1;
7615   u8 v4_address_set = 0;
7616   u8 v6_address_set = 0;
7617   ip4_address_t v4address;
7618   ip6_address_t v6address;
7619   u8 v4_src_address_set = 0;
7620   u8 v6_src_address_set = 0;
7621   ip4_address_t v4srcaddress;
7622   ip6_address_t v6srcaddress;
7623   int ret;
7624
7625   /* Parse args required to build the message */
7626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7627     {
7628       if (unformat (i, "del"))
7629         is_add = 0;
7630       else if (unformat (i, "vrf %d", &vrf_id))
7631         ;
7632       else if (unformat (i, "insert-cid %d", &insert_cid))
7633         ;
7634       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7635         v4_address_set = 1;
7636       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7637         v6_address_set = 1;
7638       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7639         v4_src_address_set = 1;
7640       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7641         v6_src_address_set = 1;
7642       else
7643         break;
7644     }
7645
7646   if (v4_address_set && v6_address_set)
7647     {
7648       errmsg ("both v4 and v6 server addresses set");
7649       return -99;
7650     }
7651   if (!v4_address_set && !v6_address_set)
7652     {
7653       errmsg ("no server addresses set");
7654       return -99;
7655     }
7656
7657   if (v4_src_address_set && v6_src_address_set)
7658     {
7659       errmsg ("both v4 and v6  src addresses set");
7660       return -99;
7661     }
7662   if (!v4_src_address_set && !v6_src_address_set)
7663     {
7664       errmsg ("no src addresses set");
7665       return -99;
7666     }
7667
7668   if (!(v4_src_address_set && v4_address_set) &&
7669       !(v6_src_address_set && v6_address_set))
7670     {
7671       errmsg ("no matching server and src addresses set");
7672       return -99;
7673     }
7674
7675   /* Construct the API message */
7676   M (DHCP_PROXY_CONFIG, mp);
7677
7678   mp->insert_circuit_id = insert_cid;
7679   mp->is_add = is_add;
7680   mp->vrf_id = ntohl (vrf_id);
7681   if (v6_address_set)
7682     {
7683       mp->is_ipv6 = 1;
7684       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7685       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7686     }
7687   else
7688     {
7689       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7690       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7691     }
7692
7693   /* send it... */
7694   S (mp);
7695
7696   /* Wait for a reply, return good/bad news  */
7697   W (ret);
7698   return ret;
7699 }
7700
7701 static int
7702 api_dhcp_proxy_config_2 (vat_main_t * vam)
7703 {
7704   unformat_input_t *i = vam->input;
7705   vl_api_dhcp_proxy_config_2_t *mp;
7706   u32 rx_vrf_id = 0;
7707   u32 server_vrf_id = 0;
7708   u8 is_add = 1;
7709   u8 insert_cid = 1;
7710   u8 v4_address_set = 0;
7711   u8 v6_address_set = 0;
7712   ip4_address_t v4address;
7713   ip6_address_t v6address;
7714   u8 v4_src_address_set = 0;
7715   u8 v6_src_address_set = 0;
7716   ip4_address_t v4srcaddress;
7717   ip6_address_t v6srcaddress;
7718   int ret;
7719
7720   /* Parse args required to build the message */
7721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7722     {
7723       if (unformat (i, "del"))
7724         is_add = 0;
7725       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7726         ;
7727       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7728         ;
7729       else if (unformat (i, "insert-cid %d", &insert_cid))
7730         ;
7731       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7732         v4_address_set = 1;
7733       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7734         v6_address_set = 1;
7735       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7736         v4_src_address_set = 1;
7737       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7738         v6_src_address_set = 1;
7739       else
7740         break;
7741     }
7742
7743   if (v4_address_set && v6_address_set)
7744     {
7745       errmsg ("both v4 and v6 server addresses set");
7746       return -99;
7747     }
7748   if (!v4_address_set && !v6_address_set)
7749     {
7750       errmsg ("no server addresses set");
7751       return -99;
7752     }
7753
7754   if (v4_src_address_set && v6_src_address_set)
7755     {
7756       errmsg ("both v4 and v6  src addresses set");
7757       return -99;
7758     }
7759   if (!v4_src_address_set && !v6_src_address_set)
7760     {
7761       errmsg ("no src addresses set");
7762       return -99;
7763     }
7764
7765   if (!(v4_src_address_set && v4_address_set) &&
7766       !(v6_src_address_set && v6_address_set))
7767     {
7768       errmsg ("no matching server and src addresses set");
7769       return -99;
7770     }
7771
7772   /* Construct the API message */
7773   M (DHCP_PROXY_CONFIG_2, mp);
7774
7775   mp->insert_circuit_id = insert_cid;
7776   mp->is_add = is_add;
7777   mp->rx_vrf_id = ntohl (rx_vrf_id);
7778   mp->server_vrf_id = ntohl (server_vrf_id);
7779   if (v6_address_set)
7780     {
7781       mp->is_ipv6 = 1;
7782       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7783       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7784     }
7785   else
7786     {
7787       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7788       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7789     }
7790
7791   /* send it... */
7792   S (mp);
7793
7794   /* Wait for a reply, return good/bad news  */
7795   W (ret);
7796   return ret;
7797 }
7798
7799 static int
7800 api_dhcp_proxy_set_vss (vat_main_t * vam)
7801 {
7802   unformat_input_t *i = vam->input;
7803   vl_api_dhcp_proxy_set_vss_t *mp;
7804   u8 is_ipv6 = 0;
7805   u8 is_add = 1;
7806   u32 tbl_id;
7807   u8 tbl_id_set = 0;
7808   u32 oui;
7809   u8 oui_set = 0;
7810   u32 fib_id;
7811   u8 fib_id_set = 0;
7812   int ret;
7813
7814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7815     {
7816       if (unformat (i, "tbl_id %d", &tbl_id))
7817         tbl_id_set = 1;
7818       if (unformat (i, "fib_id %d", &fib_id))
7819         fib_id_set = 1;
7820       if (unformat (i, "oui %d", &oui))
7821         oui_set = 1;
7822       else if (unformat (i, "ipv6"))
7823         is_ipv6 = 1;
7824       else if (unformat (i, "del"))
7825         is_add = 0;
7826       else
7827         {
7828           clib_warning ("parse error '%U'", format_unformat_error, i);
7829           return -99;
7830         }
7831     }
7832
7833   if (tbl_id_set == 0)
7834     {
7835       errmsg ("missing tbl id");
7836       return -99;
7837     }
7838
7839   if (fib_id_set == 0)
7840     {
7841       errmsg ("missing fib id");
7842       return -99;
7843     }
7844   if (oui_set == 0)
7845     {
7846       errmsg ("missing oui");
7847       return -99;
7848     }
7849
7850   M (DHCP_PROXY_SET_VSS, mp);
7851   mp->tbl_id = ntohl (tbl_id);
7852   mp->fib_id = ntohl (fib_id);
7853   mp->oui = ntohl (oui);
7854   mp->is_ipv6 = is_ipv6;
7855   mp->is_add = is_add;
7856
7857   S (mp);
7858   W (ret);
7859   return ret;
7860 }
7861
7862 static int
7863 api_dhcp_client_config (vat_main_t * vam)
7864 {
7865   unformat_input_t *i = vam->input;
7866   vl_api_dhcp_client_config_t *mp;
7867   u32 sw_if_index;
7868   u8 sw_if_index_set = 0;
7869   u8 is_add = 1;
7870   u8 *hostname = 0;
7871   u8 disable_event = 0;
7872   int ret;
7873
7874   /* Parse args required to build the message */
7875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7876     {
7877       if (unformat (i, "del"))
7878         is_add = 0;
7879       else
7880         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7881         sw_if_index_set = 1;
7882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7883         sw_if_index_set = 1;
7884       else if (unformat (i, "hostname %s", &hostname))
7885         ;
7886       else if (unformat (i, "disable_event"))
7887         disable_event = 1;
7888       else
7889         break;
7890     }
7891
7892   if (sw_if_index_set == 0)
7893     {
7894       errmsg ("missing interface name or sw_if_index");
7895       return -99;
7896     }
7897
7898   if (vec_len (hostname) > 63)
7899     {
7900       errmsg ("hostname too long");
7901     }
7902   vec_add1 (hostname, 0);
7903
7904   /* Construct the API message */
7905   M (DHCP_CLIENT_CONFIG, mp);
7906
7907   mp->sw_if_index = ntohl (sw_if_index);
7908   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7909   vec_free (hostname);
7910   mp->is_add = is_add;
7911   mp->want_dhcp_event = disable_event ? 0 : 1;
7912   mp->pid = getpid ();
7913
7914   /* send it... */
7915   S (mp);
7916
7917   /* Wait for a reply, return good/bad news  */
7918   W (ret);
7919   return ret;
7920 }
7921
7922 static int
7923 api_set_ip_flow_hash (vat_main_t * vam)
7924 {
7925   unformat_input_t *i = vam->input;
7926   vl_api_set_ip_flow_hash_t *mp;
7927   u32 vrf_id = 0;
7928   u8 is_ipv6 = 0;
7929   u8 vrf_id_set = 0;
7930   u8 src = 0;
7931   u8 dst = 0;
7932   u8 sport = 0;
7933   u8 dport = 0;
7934   u8 proto = 0;
7935   u8 reverse = 0;
7936   int ret;
7937
7938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7939     {
7940       if (unformat (i, "vrf %d", &vrf_id))
7941         vrf_id_set = 1;
7942       else if (unformat (i, "ipv6"))
7943         is_ipv6 = 1;
7944       else if (unformat (i, "src"))
7945         src = 1;
7946       else if (unformat (i, "dst"))
7947         dst = 1;
7948       else if (unformat (i, "sport"))
7949         sport = 1;
7950       else if (unformat (i, "dport"))
7951         dport = 1;
7952       else if (unformat (i, "proto"))
7953         proto = 1;
7954       else if (unformat (i, "reverse"))
7955         reverse = 1;
7956
7957       else
7958         {
7959           clib_warning ("parse error '%U'", format_unformat_error, i);
7960           return -99;
7961         }
7962     }
7963
7964   if (vrf_id_set == 0)
7965     {
7966       errmsg ("missing vrf id");
7967       return -99;
7968     }
7969
7970   M (SET_IP_FLOW_HASH, mp);
7971   mp->src = src;
7972   mp->dst = dst;
7973   mp->sport = sport;
7974   mp->dport = dport;
7975   mp->proto = proto;
7976   mp->reverse = reverse;
7977   mp->vrf_id = ntohl (vrf_id);
7978   mp->is_ipv6 = is_ipv6;
7979
7980   S (mp);
7981   W (ret);
7982   return ret;
7983 }
7984
7985 static int
7986 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7987 {
7988   unformat_input_t *i = vam->input;
7989   vl_api_sw_interface_ip6_enable_disable_t *mp;
7990   u32 sw_if_index;
7991   u8 sw_if_index_set = 0;
7992   u8 enable = 0;
7993   int ret;
7994
7995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7996     {
7997       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7998         sw_if_index_set = 1;
7999       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8000         sw_if_index_set = 1;
8001       else if (unformat (i, "enable"))
8002         enable = 1;
8003       else if (unformat (i, "disable"))
8004         enable = 0;
8005       else
8006         {
8007           clib_warning ("parse error '%U'", format_unformat_error, i);
8008           return -99;
8009         }
8010     }
8011
8012   if (sw_if_index_set == 0)
8013     {
8014       errmsg ("missing interface name or sw_if_index");
8015       return -99;
8016     }
8017
8018   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8019
8020   mp->sw_if_index = ntohl (sw_if_index);
8021   mp->enable = enable;
8022
8023   S (mp);
8024   W (ret);
8025   return ret;
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   u32 sw_if_index;
8034   u8 sw_if_index_set = 0;
8035   u8 v6_address_set = 0;
8036   ip6_address_t v6address;
8037   int ret;
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, mp);
8065
8066   mp->sw_if_index = ntohl (sw_if_index);
8067   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8068
8069   /* send it... */
8070   S (mp);
8071
8072   /* Wait for a reply, return good/bad news  */
8073   W (ret);
8074   return ret;
8075 }
8076
8077
8078 static int
8079 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8080 {
8081   unformat_input_t *i = vam->input;
8082   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8083   u32 sw_if_index;
8084   u8 sw_if_index_set = 0;
8085   u32 address_length = 0;
8086   u8 v6_address_set = 0;
8087   ip6_address_t v6address;
8088   u8 use_default = 0;
8089   u8 no_advertise = 0;
8090   u8 off_link = 0;
8091   u8 no_autoconfig = 0;
8092   u8 no_onlink = 0;
8093   u8 is_no = 0;
8094   u32 val_lifetime = 0;
8095   u32 pref_lifetime = 0;
8096   int ret;
8097
8098   /* Parse args required to build the message */
8099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8100     {
8101       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8102         sw_if_index_set = 1;
8103       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8104         sw_if_index_set = 1;
8105       else if (unformat (i, "%U/%d",
8106                          unformat_ip6_address, &v6address, &address_length))
8107         v6_address_set = 1;
8108       else if (unformat (i, "val_life %d", &val_lifetime))
8109         ;
8110       else if (unformat (i, "pref_life %d", &pref_lifetime))
8111         ;
8112       else if (unformat (i, "def"))
8113         use_default = 1;
8114       else if (unformat (i, "noadv"))
8115         no_advertise = 1;
8116       else if (unformat (i, "offl"))
8117         off_link = 1;
8118       else if (unformat (i, "noauto"))
8119         no_autoconfig = 1;
8120       else if (unformat (i, "nolink"))
8121         no_onlink = 1;
8122       else if (unformat (i, "isno"))
8123         is_no = 1;
8124       else
8125         {
8126           clib_warning ("parse error '%U'", format_unformat_error, i);
8127           return -99;
8128         }
8129     }
8130
8131   if (sw_if_index_set == 0)
8132     {
8133       errmsg ("missing interface name or sw_if_index");
8134       return -99;
8135     }
8136   if (!v6_address_set)
8137     {
8138       errmsg ("no address set");
8139       return -99;
8140     }
8141
8142   /* Construct the API message */
8143   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8144
8145   mp->sw_if_index = ntohl (sw_if_index);
8146   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8147   mp->address_length = address_length;
8148   mp->use_default = use_default;
8149   mp->no_advertise = no_advertise;
8150   mp->off_link = off_link;
8151   mp->no_autoconfig = no_autoconfig;
8152   mp->no_onlink = no_onlink;
8153   mp->is_no = is_no;
8154   mp->val_lifetime = ntohl (val_lifetime);
8155   mp->pref_lifetime = ntohl (pref_lifetime);
8156
8157   /* send it... */
8158   S (mp);
8159
8160   /* Wait for a reply, return good/bad news  */
8161   W (ret);
8162   return ret;
8163 }
8164
8165 static int
8166 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8167 {
8168   unformat_input_t *i = vam->input;
8169   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8170   u32 sw_if_index;
8171   u8 sw_if_index_set = 0;
8172   u8 suppress = 0;
8173   u8 managed = 0;
8174   u8 other = 0;
8175   u8 ll_option = 0;
8176   u8 send_unicast = 0;
8177   u8 cease = 0;
8178   u8 is_no = 0;
8179   u8 default_router = 0;
8180   u32 max_interval = 0;
8181   u32 min_interval = 0;
8182   u32 lifetime = 0;
8183   u32 initial_count = 0;
8184   u32 initial_interval = 0;
8185   int ret;
8186
8187
8188   /* Parse args required to build the message */
8189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8190     {
8191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8192         sw_if_index_set = 1;
8193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8194         sw_if_index_set = 1;
8195       else if (unformat (i, "maxint %d", &max_interval))
8196         ;
8197       else if (unformat (i, "minint %d", &min_interval))
8198         ;
8199       else if (unformat (i, "life %d", &lifetime))
8200         ;
8201       else if (unformat (i, "count %d", &initial_count))
8202         ;
8203       else if (unformat (i, "interval %d", &initial_interval))
8204         ;
8205       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8206         suppress = 1;
8207       else if (unformat (i, "managed"))
8208         managed = 1;
8209       else if (unformat (i, "other"))
8210         other = 1;
8211       else if (unformat (i, "ll"))
8212         ll_option = 1;
8213       else if (unformat (i, "send"))
8214         send_unicast = 1;
8215       else if (unformat (i, "cease"))
8216         cease = 1;
8217       else if (unformat (i, "isno"))
8218         is_no = 1;
8219       else if (unformat (i, "def"))
8220         default_router = 1;
8221       else
8222         {
8223           clib_warning ("parse error '%U'", format_unformat_error, i);
8224           return -99;
8225         }
8226     }
8227
8228   if (sw_if_index_set == 0)
8229     {
8230       errmsg ("missing interface name or sw_if_index");
8231       return -99;
8232     }
8233
8234   /* Construct the API message */
8235   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8236
8237   mp->sw_if_index = ntohl (sw_if_index);
8238   mp->max_interval = ntohl (max_interval);
8239   mp->min_interval = ntohl (min_interval);
8240   mp->lifetime = ntohl (lifetime);
8241   mp->initial_count = ntohl (initial_count);
8242   mp->initial_interval = ntohl (initial_interval);
8243   mp->suppress = suppress;
8244   mp->managed = managed;
8245   mp->other = other;
8246   mp->ll_option = ll_option;
8247   mp->send_unicast = send_unicast;
8248   mp->cease = cease;
8249   mp->is_no = is_no;
8250   mp->default_router = default_router;
8251
8252   /* send it... */
8253   S (mp);
8254
8255   /* Wait for a reply, return good/bad news  */
8256   W (ret);
8257   return ret;
8258 }
8259
8260 static int
8261 api_set_arp_neighbor_limit (vat_main_t * vam)
8262 {
8263   unformat_input_t *i = vam->input;
8264   vl_api_set_arp_neighbor_limit_t *mp;
8265   u32 arp_nbr_limit;
8266   u8 limit_set = 0;
8267   u8 is_ipv6 = 0;
8268   int ret;
8269
8270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8271     {
8272       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8273         limit_set = 1;
8274       else if (unformat (i, "ipv6"))
8275         is_ipv6 = 1;
8276       else
8277         {
8278           clib_warning ("parse error '%U'", format_unformat_error, i);
8279           return -99;
8280         }
8281     }
8282
8283   if (limit_set == 0)
8284     {
8285       errmsg ("missing limit value");
8286       return -99;
8287     }
8288
8289   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8290
8291   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8292   mp->is_ipv6 = is_ipv6;
8293
8294   S (mp);
8295   W (ret);
8296   return ret;
8297 }
8298
8299 static int
8300 api_l2_patch_add_del (vat_main_t * vam)
8301 {
8302   unformat_input_t *i = vam->input;
8303   vl_api_l2_patch_add_del_t *mp;
8304   u32 rx_sw_if_index;
8305   u8 rx_sw_if_index_set = 0;
8306   u32 tx_sw_if_index;
8307   u8 tx_sw_if_index_set = 0;
8308   u8 is_add = 1;
8309   int ret;
8310
8311   /* Parse args required to build the message */
8312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8313     {
8314       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8315         rx_sw_if_index_set = 1;
8316       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8317         tx_sw_if_index_set = 1;
8318       else if (unformat (i, "rx"))
8319         {
8320           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8321             {
8322               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8323                             &rx_sw_if_index))
8324                 rx_sw_if_index_set = 1;
8325             }
8326           else
8327             break;
8328         }
8329       else if (unformat (i, "tx"))
8330         {
8331           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8332             {
8333               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8334                             &tx_sw_if_index))
8335                 tx_sw_if_index_set = 1;
8336             }
8337           else
8338             break;
8339         }
8340       else if (unformat (i, "del"))
8341         is_add = 0;
8342       else
8343         break;
8344     }
8345
8346   if (rx_sw_if_index_set == 0)
8347     {
8348       errmsg ("missing rx interface name or rx_sw_if_index");
8349       return -99;
8350     }
8351
8352   if (tx_sw_if_index_set == 0)
8353     {
8354       errmsg ("missing tx interface name or tx_sw_if_index");
8355       return -99;
8356     }
8357
8358   M (L2_PATCH_ADD_DEL, mp);
8359
8360   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8361   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8362   mp->is_add = is_add;
8363
8364   S (mp);
8365   W (ret);
8366   return ret;
8367 }
8368
8369 static int
8370 api_ioam_enable (vat_main_t * vam)
8371 {
8372   unformat_input_t *input = vam->input;
8373   vl_api_ioam_enable_t *mp;
8374   u32 id = 0;
8375   int has_trace_option = 0;
8376   int has_pot_option = 0;
8377   int has_seqno_option = 0;
8378   int has_analyse_option = 0;
8379   int ret;
8380
8381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8382     {
8383       if (unformat (input, "trace"))
8384         has_trace_option = 1;
8385       else if (unformat (input, "pot"))
8386         has_pot_option = 1;
8387       else if (unformat (input, "seqno"))
8388         has_seqno_option = 1;
8389       else if (unformat (input, "analyse"))
8390         has_analyse_option = 1;
8391       else
8392         break;
8393     }
8394   M (IOAM_ENABLE, mp);
8395   mp->id = htons (id);
8396   mp->seqno = has_seqno_option;
8397   mp->analyse = has_analyse_option;
8398   mp->pot_enable = has_pot_option;
8399   mp->trace_enable = has_trace_option;
8400
8401   S (mp);
8402   W (ret);
8403   return ret;
8404 }
8405
8406
8407 static int
8408 api_ioam_disable (vat_main_t * vam)
8409 {
8410   vl_api_ioam_disable_t *mp;
8411   int ret;
8412
8413   M (IOAM_DISABLE, mp);
8414   S (mp);
8415   W (ret);
8416   return ret;
8417 }
8418
8419 static int
8420 api_sr_tunnel_add_del (vat_main_t * vam)
8421 {
8422   unformat_input_t *i = vam->input;
8423   vl_api_sr_tunnel_add_del_t *mp;
8424   int is_del = 0;
8425   int pl_index;
8426   ip6_address_t src_address;
8427   int src_address_set = 0;
8428   ip6_address_t dst_address;
8429   u32 dst_mask_width;
8430   int dst_address_set = 0;
8431   u16 flags = 0;
8432   u32 rx_table_id = 0;
8433   u32 tx_table_id = 0;
8434   ip6_address_t *segments = 0;
8435   ip6_address_t *this_seg;
8436   ip6_address_t *tags = 0;
8437   ip6_address_t *this_tag;
8438   ip6_address_t next_address, tag;
8439   u8 *name = 0;
8440   u8 *policy_name = 0;
8441   int ret;
8442
8443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8444     {
8445       if (unformat (i, "del"))
8446         is_del = 1;
8447       else if (unformat (i, "name %s", &name))
8448         ;
8449       else if (unformat (i, "policy %s", &policy_name))
8450         ;
8451       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8452         ;
8453       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8454         ;
8455       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8456         src_address_set = 1;
8457       else if (unformat (i, "dst %U/%d",
8458                          unformat_ip6_address, &dst_address, &dst_mask_width))
8459         dst_address_set = 1;
8460       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8461         {
8462           vec_add2 (segments, this_seg, 1);
8463           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8464                        sizeof (*this_seg));
8465         }
8466       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8467         {
8468           vec_add2 (tags, this_tag, 1);
8469           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8470         }
8471       else if (unformat (i, "clean"))
8472         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8473       else if (unformat (i, "protected"))
8474         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8475       else if (unformat (i, "InPE %d", &pl_index))
8476         {
8477           if (pl_index <= 0 || pl_index > 4)
8478             {
8479             pl_index_range_error:
8480               errmsg ("pl index %d out of range", pl_index);
8481               return -99;
8482             }
8483           flags |=
8484             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8485         }
8486       else if (unformat (i, "EgPE %d", &pl_index))
8487         {
8488           if (pl_index <= 0 || pl_index > 4)
8489             goto pl_index_range_error;
8490           flags |=
8491             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8492         }
8493       else if (unformat (i, "OrgSrc %d", &pl_index))
8494         {
8495           if (pl_index <= 0 || pl_index > 4)
8496             goto pl_index_range_error;
8497           flags |=
8498             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8499         }
8500       else
8501         break;
8502     }
8503
8504   if (!src_address_set)
8505     {
8506       errmsg ("src address required");
8507       return -99;
8508     }
8509
8510   if (!dst_address_set)
8511     {
8512       errmsg ("dst address required");
8513       return -99;
8514     }
8515
8516   if (!segments)
8517     {
8518       errmsg ("at least one sr segment required");
8519       return -99;
8520     }
8521
8522   M2 (SR_TUNNEL_ADD_DEL, mp,
8523       vec_len (segments) * sizeof (ip6_address_t)
8524       + vec_len (tags) * sizeof (ip6_address_t));
8525
8526   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8527   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8528   mp->dst_mask_width = dst_mask_width;
8529   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8530   mp->n_segments = vec_len (segments);
8531   mp->n_tags = vec_len (tags);
8532   mp->is_add = is_del == 0;
8533   clib_memcpy (mp->segs_and_tags, segments,
8534                vec_len (segments) * sizeof (ip6_address_t));
8535   clib_memcpy (mp->segs_and_tags +
8536                vec_len (segments) * sizeof (ip6_address_t), tags,
8537                vec_len (tags) * sizeof (ip6_address_t));
8538
8539   mp->outer_vrf_id = ntohl (rx_table_id);
8540   mp->inner_vrf_id = ntohl (tx_table_id);
8541   memcpy (mp->name, name, vec_len (name));
8542   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8543
8544   vec_free (segments);
8545   vec_free (tags);
8546
8547   S (mp);
8548   W (ret);
8549   return ret;
8550 }
8551
8552 static int
8553 api_sr_policy_add_del (vat_main_t * vam)
8554 {
8555   unformat_input_t *input = vam->input;
8556   vl_api_sr_policy_add_del_t *mp;
8557   int is_del = 0;
8558   u8 *name = 0;
8559   u8 *tunnel_name = 0;
8560   u8 **tunnel_names = 0;
8561
8562   int name_set = 0;
8563   int tunnel_set = 0;
8564   int j = 0;
8565   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8566   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8567   int ret;
8568
8569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8570     {
8571       if (unformat (input, "del"))
8572         is_del = 1;
8573       else if (unformat (input, "name %s", &name))
8574         name_set = 1;
8575       else if (unformat (input, "tunnel %s", &tunnel_name))
8576         {
8577           if (tunnel_name)
8578             {
8579               vec_add1 (tunnel_names, tunnel_name);
8580               /* For serializer:
8581                  - length = #bytes to store in serial vector
8582                  - +1 = byte to store that length
8583                */
8584               tunnel_names_length += (vec_len (tunnel_name) + 1);
8585               tunnel_set = 1;
8586               tunnel_name = 0;
8587             }
8588         }
8589       else
8590         break;
8591     }
8592
8593   if (!name_set)
8594     {
8595       errmsg ("policy name required");
8596       return -99;
8597     }
8598
8599   if ((!tunnel_set) && (!is_del))
8600     {
8601       errmsg ("tunnel name required");
8602       return -99;
8603     }
8604
8605   M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
8606
8607
8608
8609   mp->is_add = !is_del;
8610
8611   memcpy (mp->name, name, vec_len (name));
8612   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8613   u8 *serial_orig = 0;
8614   vec_validate (serial_orig, tunnel_names_length);
8615   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8616   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8617
8618   for (j = 0; j < vec_len (tunnel_names); j++)
8619     {
8620       tun_name_len = vec_len (tunnel_names[j]);
8621       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8622       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8623       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8624       serial_orig += tun_name_len;      // Advance past the copy
8625     }
8626   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8627
8628   vec_free (tunnel_names);
8629   vec_free (tunnel_name);
8630
8631   S (mp);
8632   W (ret);
8633   return ret;
8634 }
8635
8636 static int
8637 api_sr_multicast_map_add_del (vat_main_t * vam)
8638 {
8639   unformat_input_t *input = vam->input;
8640   vl_api_sr_multicast_map_add_del_t *mp;
8641   int is_del = 0;
8642   ip6_address_t multicast_address;
8643   u8 *policy_name = 0;
8644   int multicast_address_set = 0;
8645   int ret;
8646
8647   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8648     {
8649       if (unformat (input, "del"))
8650         is_del = 1;
8651       else
8652         if (unformat
8653             (input, "address %U", unformat_ip6_address, &multicast_address))
8654         multicast_address_set = 1;
8655       else if (unformat (input, "sr-policy %s", &policy_name))
8656         ;
8657       else
8658         break;
8659     }
8660
8661   if (!is_del && !policy_name)
8662     {
8663       errmsg ("sr-policy name required");
8664       return -99;
8665     }
8666
8667
8668   if (!multicast_address_set)
8669     {
8670       errmsg ("address required");
8671       return -99;
8672     }
8673
8674   M (SR_MULTICAST_MAP_ADD_DEL, mp);
8675
8676   mp->is_add = !is_del;
8677   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8678   clib_memcpy (mp->multicast_address, &multicast_address,
8679                sizeof (mp->multicast_address));
8680
8681
8682   vec_free (policy_name);
8683
8684   S (mp);
8685   W (ret);
8686   return ret;
8687 }
8688
8689
8690 #define foreach_tcp_proto_field                 \
8691 _(src_port)                                     \
8692 _(dst_port)
8693
8694 #define foreach_udp_proto_field                 \
8695 _(src_port)                                     \
8696 _(dst_port)
8697
8698 #define foreach_ip4_proto_field                 \
8699 _(src_address)                                  \
8700 _(dst_address)                                  \
8701 _(tos)                                          \
8702 _(length)                                       \
8703 _(fragment_id)                                  \
8704 _(ttl)                                          \
8705 _(protocol)                                     \
8706 _(checksum)
8707
8708 uword
8709 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8710 {
8711   u8 **maskp = va_arg (*args, u8 **);
8712   u8 *mask = 0;
8713   u8 found_something = 0;
8714   tcp_header_t *tcp;
8715
8716 #define _(a) u8 a=0;
8717   foreach_tcp_proto_field;
8718 #undef _
8719
8720   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8721     {
8722       if (0);
8723 #define _(a) else if (unformat (input, #a)) a=1;
8724       foreach_tcp_proto_field
8725 #undef _
8726         else
8727         break;
8728     }
8729
8730 #define _(a) found_something += a;
8731   foreach_tcp_proto_field;
8732 #undef _
8733
8734   if (found_something == 0)
8735     return 0;
8736
8737   vec_validate (mask, sizeof (*tcp) - 1);
8738
8739   tcp = (tcp_header_t *) mask;
8740
8741 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8742   foreach_tcp_proto_field;
8743 #undef _
8744
8745   *maskp = mask;
8746   return 1;
8747 }
8748
8749 uword
8750 unformat_udp_mask (unformat_input_t * input, va_list * args)
8751 {
8752   u8 **maskp = va_arg (*args, u8 **);
8753   u8 *mask = 0;
8754   u8 found_something = 0;
8755   udp_header_t *udp;
8756
8757 #define _(a) u8 a=0;
8758   foreach_udp_proto_field;
8759 #undef _
8760
8761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8762     {
8763       if (0);
8764 #define _(a) else if (unformat (input, #a)) a=1;
8765       foreach_udp_proto_field
8766 #undef _
8767         else
8768         break;
8769     }
8770
8771 #define _(a) found_something += a;
8772   foreach_udp_proto_field;
8773 #undef _
8774
8775   if (found_something == 0)
8776     return 0;
8777
8778   vec_validate (mask, sizeof (*udp) - 1);
8779
8780   udp = (udp_header_t *) mask;
8781
8782 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8783   foreach_udp_proto_field;
8784 #undef _
8785
8786   *maskp = mask;
8787   return 1;
8788 }
8789
8790 typedef struct
8791 {
8792   u16 src_port, dst_port;
8793 } tcpudp_header_t;
8794
8795 uword
8796 unformat_l4_mask (unformat_input_t * input, va_list * args)
8797 {
8798   u8 **maskp = va_arg (*args, u8 **);
8799   u16 src_port = 0, dst_port = 0;
8800   tcpudp_header_t *tcpudp;
8801
8802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8803     {
8804       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8805         return 1;
8806       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8807         return 1;
8808       else if (unformat (input, "src_port"))
8809         src_port = 0xFFFF;
8810       else if (unformat (input, "dst_port"))
8811         dst_port = 0xFFFF;
8812       else
8813         return 0;
8814     }
8815
8816   if (!src_port && !dst_port)
8817     return 0;
8818
8819   u8 *mask = 0;
8820   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8821
8822   tcpudp = (tcpudp_header_t *) mask;
8823   tcpudp->src_port = src_port;
8824   tcpudp->dst_port = dst_port;
8825
8826   *maskp = mask;
8827
8828   return 1;
8829 }
8830
8831 uword
8832 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8833 {
8834   u8 **maskp = va_arg (*args, u8 **);
8835   u8 *mask = 0;
8836   u8 found_something = 0;
8837   ip4_header_t *ip;
8838
8839 #define _(a) u8 a=0;
8840   foreach_ip4_proto_field;
8841 #undef _
8842   u8 version = 0;
8843   u8 hdr_length = 0;
8844
8845
8846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8847     {
8848       if (unformat (input, "version"))
8849         version = 1;
8850       else if (unformat (input, "hdr_length"))
8851         hdr_length = 1;
8852       else if (unformat (input, "src"))
8853         src_address = 1;
8854       else if (unformat (input, "dst"))
8855         dst_address = 1;
8856       else if (unformat (input, "proto"))
8857         protocol = 1;
8858
8859 #define _(a) else if (unformat (input, #a)) a=1;
8860       foreach_ip4_proto_field
8861 #undef _
8862         else
8863         break;
8864     }
8865
8866 #define _(a) found_something += a;
8867   foreach_ip4_proto_field;
8868 #undef _
8869
8870   if (found_something == 0)
8871     return 0;
8872
8873   vec_validate (mask, sizeof (*ip) - 1);
8874
8875   ip = (ip4_header_t *) mask;
8876
8877 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8878   foreach_ip4_proto_field;
8879 #undef _
8880
8881   ip->ip_version_and_header_length = 0;
8882
8883   if (version)
8884     ip->ip_version_and_header_length |= 0xF0;
8885
8886   if (hdr_length)
8887     ip->ip_version_and_header_length |= 0x0F;
8888
8889   *maskp = mask;
8890   return 1;
8891 }
8892
8893 #define foreach_ip6_proto_field                 \
8894 _(src_address)                                  \
8895 _(dst_address)                                  \
8896 _(payload_length)                               \
8897 _(hop_limit)                                    \
8898 _(protocol)
8899
8900 uword
8901 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8902 {
8903   u8 **maskp = va_arg (*args, u8 **);
8904   u8 *mask = 0;
8905   u8 found_something = 0;
8906   ip6_header_t *ip;
8907   u32 ip_version_traffic_class_and_flow_label;
8908
8909 #define _(a) u8 a=0;
8910   foreach_ip6_proto_field;
8911 #undef _
8912   u8 version = 0;
8913   u8 traffic_class = 0;
8914   u8 flow_label = 0;
8915
8916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8917     {
8918       if (unformat (input, "version"))
8919         version = 1;
8920       else if (unformat (input, "traffic-class"))
8921         traffic_class = 1;
8922       else if (unformat (input, "flow-label"))
8923         flow_label = 1;
8924       else if (unformat (input, "src"))
8925         src_address = 1;
8926       else if (unformat (input, "dst"))
8927         dst_address = 1;
8928       else if (unformat (input, "proto"))
8929         protocol = 1;
8930
8931 #define _(a) else if (unformat (input, #a)) a=1;
8932       foreach_ip6_proto_field
8933 #undef _
8934         else
8935         break;
8936     }
8937
8938 #define _(a) found_something += a;
8939   foreach_ip6_proto_field;
8940 #undef _
8941
8942   if (found_something == 0)
8943     return 0;
8944
8945   vec_validate (mask, sizeof (*ip) - 1);
8946
8947   ip = (ip6_header_t *) mask;
8948
8949 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8950   foreach_ip6_proto_field;
8951 #undef _
8952
8953   ip_version_traffic_class_and_flow_label = 0;
8954
8955   if (version)
8956     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8957
8958   if (traffic_class)
8959     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8960
8961   if (flow_label)
8962     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8963
8964   ip->ip_version_traffic_class_and_flow_label =
8965     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8966
8967   *maskp = mask;
8968   return 1;
8969 }
8970
8971 uword
8972 unformat_l3_mask (unformat_input_t * input, va_list * args)
8973 {
8974   u8 **maskp = va_arg (*args, u8 **);
8975
8976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8977     {
8978       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8979         return 1;
8980       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8981         return 1;
8982       else
8983         break;
8984     }
8985   return 0;
8986 }
8987
8988 uword
8989 unformat_l2_mask (unformat_input_t * input, va_list * args)
8990 {
8991   u8 **maskp = va_arg (*args, u8 **);
8992   u8 *mask = 0;
8993   u8 src = 0;
8994   u8 dst = 0;
8995   u8 proto = 0;
8996   u8 tag1 = 0;
8997   u8 tag2 = 0;
8998   u8 ignore_tag1 = 0;
8999   u8 ignore_tag2 = 0;
9000   u8 cos1 = 0;
9001   u8 cos2 = 0;
9002   u8 dot1q = 0;
9003   u8 dot1ad = 0;
9004   int len = 14;
9005
9006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9007     {
9008       if (unformat (input, "src"))
9009         src = 1;
9010       else if (unformat (input, "dst"))
9011         dst = 1;
9012       else if (unformat (input, "proto"))
9013         proto = 1;
9014       else if (unformat (input, "tag1"))
9015         tag1 = 1;
9016       else if (unformat (input, "tag2"))
9017         tag2 = 1;
9018       else if (unformat (input, "ignore-tag1"))
9019         ignore_tag1 = 1;
9020       else if (unformat (input, "ignore-tag2"))
9021         ignore_tag2 = 1;
9022       else if (unformat (input, "cos1"))
9023         cos1 = 1;
9024       else if (unformat (input, "cos2"))
9025         cos2 = 1;
9026       else if (unformat (input, "dot1q"))
9027         dot1q = 1;
9028       else if (unformat (input, "dot1ad"))
9029         dot1ad = 1;
9030       else
9031         break;
9032     }
9033   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9034        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9035     return 0;
9036
9037   if (tag1 || ignore_tag1 || cos1 || dot1q)
9038     len = 18;
9039   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9040     len = 22;
9041
9042   vec_validate (mask, len - 1);
9043
9044   if (dst)
9045     memset (mask, 0xff, 6);
9046
9047   if (src)
9048     memset (mask + 6, 0xff, 6);
9049
9050   if (tag2 || dot1ad)
9051     {
9052       /* inner vlan tag */
9053       if (tag2)
9054         {
9055           mask[19] = 0xff;
9056           mask[18] = 0x0f;
9057         }
9058       if (cos2)
9059         mask[18] |= 0xe0;
9060       if (proto)
9061         mask[21] = mask[20] = 0xff;
9062       if (tag1)
9063         {
9064           mask[15] = 0xff;
9065           mask[14] = 0x0f;
9066         }
9067       if (cos1)
9068         mask[14] |= 0xe0;
9069       *maskp = mask;
9070       return 1;
9071     }
9072   if (tag1 | dot1q)
9073     {
9074       if (tag1)
9075         {
9076           mask[15] = 0xff;
9077           mask[14] = 0x0f;
9078         }
9079       if (cos1)
9080         mask[14] |= 0xe0;
9081       if (proto)
9082         mask[16] = mask[17] = 0xff;
9083
9084       *maskp = mask;
9085       return 1;
9086     }
9087   if (cos2)
9088     mask[18] |= 0xe0;
9089   if (cos1)
9090     mask[14] |= 0xe0;
9091   if (proto)
9092     mask[12] = mask[13] = 0xff;
9093
9094   *maskp = mask;
9095   return 1;
9096 }
9097
9098 uword
9099 unformat_classify_mask (unformat_input_t * input, va_list * args)
9100 {
9101   u8 **maskp = va_arg (*args, u8 **);
9102   u32 *skipp = va_arg (*args, u32 *);
9103   u32 *matchp = va_arg (*args, u32 *);
9104   u32 match;
9105   u8 *mask = 0;
9106   u8 *l2 = 0;
9107   u8 *l3 = 0;
9108   u8 *l4 = 0;
9109   int i;
9110
9111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9112     {
9113       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9114         ;
9115       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9116         ;
9117       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9118         ;
9119       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9120         ;
9121       else
9122         break;
9123     }
9124
9125   if (l4 && !l3)
9126     {
9127       vec_free (mask);
9128       vec_free (l2);
9129       vec_free (l4);
9130       return 0;
9131     }
9132
9133   if (mask || l2 || l3 || l4)
9134     {
9135       if (l2 || l3 || l4)
9136         {
9137           /* "With a free Ethernet header in every package" */
9138           if (l2 == 0)
9139             vec_validate (l2, 13);
9140           mask = l2;
9141           if (vec_len (l3))
9142             {
9143               vec_append (mask, l3);
9144               vec_free (l3);
9145             }
9146           if (vec_len (l4))
9147             {
9148               vec_append (mask, l4);
9149               vec_free (l4);
9150             }
9151         }
9152
9153       /* Scan forward looking for the first significant mask octet */
9154       for (i = 0; i < vec_len (mask); i++)
9155         if (mask[i])
9156           break;
9157
9158       /* compute (skip, match) params */
9159       *skipp = i / sizeof (u32x4);
9160       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9161
9162       /* Pad mask to an even multiple of the vector size */
9163       while (vec_len (mask) % sizeof (u32x4))
9164         vec_add1 (mask, 0);
9165
9166       match = vec_len (mask) / sizeof (u32x4);
9167
9168       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9169         {
9170           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9171           if (*tmp || *(tmp + 1))
9172             break;
9173           match--;
9174         }
9175       if (match == 0)
9176         clib_warning ("BUG: match 0");
9177
9178       _vec_len (mask) = match * sizeof (u32x4);
9179
9180       *matchp = match;
9181       *maskp = mask;
9182
9183       return 1;
9184     }
9185
9186   return 0;
9187 }
9188
9189 #define foreach_l2_next                         \
9190 _(drop, DROP)                                   \
9191 _(ethernet, ETHERNET_INPUT)                     \
9192 _(ip4, IP4_INPUT)                               \
9193 _(ip6, IP6_INPUT)
9194
9195 uword
9196 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9197 {
9198   u32 *miss_next_indexp = va_arg (*args, u32 *);
9199   u32 next_index = 0;
9200   u32 tmp;
9201
9202 #define _(n,N) \
9203   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9204   foreach_l2_next;
9205 #undef _
9206
9207   if (unformat (input, "%d", &tmp))
9208     {
9209       next_index = tmp;
9210       goto out;
9211     }
9212
9213   return 0;
9214
9215 out:
9216   *miss_next_indexp = next_index;
9217   return 1;
9218 }
9219
9220 #define foreach_ip_next                         \
9221 _(drop, DROP)                                   \
9222 _(local, LOCAL)                                 \
9223 _(rewrite, REWRITE)
9224
9225 uword
9226 unformat_ip_next_index (unformat_input_t * input, va_list * args)
9227 {
9228   u32 *miss_next_indexp = va_arg (*args, u32 *);
9229   u32 next_index = 0;
9230   u32 tmp;
9231
9232 #define _(n,N) \
9233   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9234   foreach_ip_next;
9235 #undef _
9236
9237   if (unformat (input, "%d", &tmp))
9238     {
9239       next_index = tmp;
9240       goto out;
9241     }
9242
9243   return 0;
9244
9245 out:
9246   *miss_next_indexp = next_index;
9247   return 1;
9248 }
9249
9250 #define foreach_acl_next                        \
9251 _(deny, DENY)
9252
9253 uword
9254 unformat_acl_next_index (unformat_input_t * input, va_list * args)
9255 {
9256   u32 *miss_next_indexp = va_arg (*args, u32 *);
9257   u32 next_index = 0;
9258   u32 tmp;
9259
9260 #define _(n,N) \
9261   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9262   foreach_acl_next;
9263 #undef _
9264
9265   if (unformat (input, "permit"))
9266     {
9267       next_index = ~0;
9268       goto out;
9269     }
9270   else if (unformat (input, "%d", &tmp))
9271     {
9272       next_index = tmp;
9273       goto out;
9274     }
9275
9276   return 0;
9277
9278 out:
9279   *miss_next_indexp = next_index;
9280   return 1;
9281 }
9282
9283 uword
9284 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9285 {
9286   u32 *r = va_arg (*args, u32 *);
9287
9288   if (unformat (input, "conform-color"))
9289     *r = POLICE_CONFORM;
9290   else if (unformat (input, "exceed-color"))
9291     *r = POLICE_EXCEED;
9292   else
9293     return 0;
9294
9295   return 1;
9296 }
9297
9298 static int
9299 api_classify_add_del_table (vat_main_t * vam)
9300 {
9301   unformat_input_t *i = vam->input;
9302   vl_api_classify_add_del_table_t *mp;
9303
9304   u32 nbuckets = 2;
9305   u32 skip = ~0;
9306   u32 match = ~0;
9307   int is_add = 1;
9308   int del_chain = 0;
9309   u32 table_index = ~0;
9310   u32 next_table_index = ~0;
9311   u32 miss_next_index = ~0;
9312   u32 memory_size = 32 << 20;
9313   u8 *mask = 0;
9314   u32 current_data_flag = 0;
9315   int current_data_offset = 0;
9316   int ret;
9317
9318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9319     {
9320       if (unformat (i, "del"))
9321         is_add = 0;
9322       else if (unformat (i, "del-chain"))
9323         {
9324           is_add = 0;
9325           del_chain = 1;
9326         }
9327       else if (unformat (i, "buckets %d", &nbuckets))
9328         ;
9329       else if (unformat (i, "memory_size %d", &memory_size))
9330         ;
9331       else if (unformat (i, "skip %d", &skip))
9332         ;
9333       else if (unformat (i, "match %d", &match))
9334         ;
9335       else if (unformat (i, "table %d", &table_index))
9336         ;
9337       else if (unformat (i, "mask %U", unformat_classify_mask,
9338                          &mask, &skip, &match))
9339         ;
9340       else if (unformat (i, "next-table %d", &next_table_index))
9341         ;
9342       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
9343                          &miss_next_index))
9344         ;
9345       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9346                          &miss_next_index))
9347         ;
9348       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9349                          &miss_next_index))
9350         ;
9351       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9352         ;
9353       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9354         ;
9355       else
9356         break;
9357     }
9358
9359   if (is_add && mask == 0)
9360     {
9361       errmsg ("Mask required");
9362       return -99;
9363     }
9364
9365   if (is_add && skip == ~0)
9366     {
9367       errmsg ("skip count required");
9368       return -99;
9369     }
9370
9371   if (is_add && match == ~0)
9372     {
9373       errmsg ("match count required");
9374       return -99;
9375     }
9376
9377   if (!is_add && table_index == ~0)
9378     {
9379       errmsg ("table index required for delete");
9380       return -99;
9381     }
9382
9383   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9384
9385   mp->is_add = is_add;
9386   mp->del_chain = del_chain;
9387   mp->table_index = ntohl (table_index);
9388   mp->nbuckets = ntohl (nbuckets);
9389   mp->memory_size = ntohl (memory_size);
9390   mp->skip_n_vectors = ntohl (skip);
9391   mp->match_n_vectors = ntohl (match);
9392   mp->next_table_index = ntohl (next_table_index);
9393   mp->miss_next_index = ntohl (miss_next_index);
9394   mp->current_data_flag = ntohl (current_data_flag);
9395   mp->current_data_offset = ntohl (current_data_offset);
9396   clib_memcpy (mp->mask, mask, vec_len (mask));
9397
9398   vec_free (mask);
9399
9400   S (mp);
9401   W (ret);
9402   return ret;
9403 }
9404
9405 uword
9406 unformat_l4_match (unformat_input_t * input, va_list * args)
9407 {
9408   u8 **matchp = va_arg (*args, u8 **);
9409
9410   u8 *proto_header = 0;
9411   int src_port = 0;
9412   int dst_port = 0;
9413
9414   tcpudp_header_t h;
9415
9416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9417     {
9418       if (unformat (input, "src_port %d", &src_port))
9419         ;
9420       else if (unformat (input, "dst_port %d", &dst_port))
9421         ;
9422       else
9423         return 0;
9424     }
9425
9426   h.src_port = clib_host_to_net_u16 (src_port);
9427   h.dst_port = clib_host_to_net_u16 (dst_port);
9428   vec_validate (proto_header, sizeof (h) - 1);
9429   memcpy (proto_header, &h, sizeof (h));
9430
9431   *matchp = proto_header;
9432
9433   return 1;
9434 }
9435
9436 uword
9437 unformat_ip4_match (unformat_input_t * input, va_list * args)
9438 {
9439   u8 **matchp = va_arg (*args, u8 **);
9440   u8 *match = 0;
9441   ip4_header_t *ip;
9442   int version = 0;
9443   u32 version_val;
9444   int hdr_length = 0;
9445   u32 hdr_length_val;
9446   int src = 0, dst = 0;
9447   ip4_address_t src_val, dst_val;
9448   int proto = 0;
9449   u32 proto_val;
9450   int tos = 0;
9451   u32 tos_val;
9452   int length = 0;
9453   u32 length_val;
9454   int fragment_id = 0;
9455   u32 fragment_id_val;
9456   int ttl = 0;
9457   int ttl_val;
9458   int checksum = 0;
9459   u32 checksum_val;
9460
9461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9462     {
9463       if (unformat (input, "version %d", &version_val))
9464         version = 1;
9465       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9466         hdr_length = 1;
9467       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9468         src = 1;
9469       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9470         dst = 1;
9471       else if (unformat (input, "proto %d", &proto_val))
9472         proto = 1;
9473       else if (unformat (input, "tos %d", &tos_val))
9474         tos = 1;
9475       else if (unformat (input, "length %d", &length_val))
9476         length = 1;
9477       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9478         fragment_id = 1;
9479       else if (unformat (input, "ttl %d", &ttl_val))
9480         ttl = 1;
9481       else if (unformat (input, "checksum %d", &checksum_val))
9482         checksum = 1;
9483       else
9484         break;
9485     }
9486
9487   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9488       + ttl + checksum == 0)
9489     return 0;
9490
9491   /*
9492    * Aligned because we use the real comparison functions
9493    */
9494   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9495
9496   ip = (ip4_header_t *) match;
9497
9498   /* These are realistically matched in practice */
9499   if (src)
9500     ip->src_address.as_u32 = src_val.as_u32;
9501
9502   if (dst)
9503     ip->dst_address.as_u32 = dst_val.as_u32;
9504
9505   if (proto)
9506     ip->protocol = proto_val;
9507
9508
9509   /* These are not, but they're included for completeness */
9510   if (version)
9511     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9512
9513   if (hdr_length)
9514     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9515
9516   if (tos)
9517     ip->tos = tos_val;
9518
9519   if (length)
9520     ip->length = clib_host_to_net_u16 (length_val);
9521
9522   if (ttl)
9523     ip->ttl = ttl_val;
9524
9525   if (checksum)
9526     ip->checksum = clib_host_to_net_u16 (checksum_val);
9527
9528   *matchp = match;
9529   return 1;
9530 }
9531
9532 uword
9533 unformat_ip6_match (unformat_input_t * input, va_list * args)
9534 {
9535   u8 **matchp = va_arg (*args, u8 **);
9536   u8 *match = 0;
9537   ip6_header_t *ip;
9538   int version = 0;
9539   u32 version_val;
9540   u8 traffic_class = 0;
9541   u32 traffic_class_val = 0;
9542   u8 flow_label = 0;
9543   u8 flow_label_val;
9544   int src = 0, dst = 0;
9545   ip6_address_t src_val, dst_val;
9546   int proto = 0;
9547   u32 proto_val;
9548   int payload_length = 0;
9549   u32 payload_length_val;
9550   int hop_limit = 0;
9551   int hop_limit_val;
9552   u32 ip_version_traffic_class_and_flow_label;
9553
9554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9555     {
9556       if (unformat (input, "version %d", &version_val))
9557         version = 1;
9558       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9559         traffic_class = 1;
9560       else if (unformat (input, "flow_label %d", &flow_label_val))
9561         flow_label = 1;
9562       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9563         src = 1;
9564       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9565         dst = 1;
9566       else if (unformat (input, "proto %d", &proto_val))
9567         proto = 1;
9568       else if (unformat (input, "payload_length %d", &payload_length_val))
9569         payload_length = 1;
9570       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9571         hop_limit = 1;
9572       else
9573         break;
9574     }
9575
9576   if (version + traffic_class + flow_label + src + dst + proto +
9577       payload_length + hop_limit == 0)
9578     return 0;
9579
9580   /*
9581    * Aligned because we use the real comparison functions
9582    */
9583   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9584
9585   ip = (ip6_header_t *) match;
9586
9587   if (src)
9588     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9589
9590   if (dst)
9591     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9592
9593   if (proto)
9594     ip->protocol = proto_val;
9595
9596   ip_version_traffic_class_and_flow_label = 0;
9597
9598   if (version)
9599     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9600
9601   if (traffic_class)
9602     ip_version_traffic_class_and_flow_label |=
9603       (traffic_class_val & 0xFF) << 20;
9604
9605   if (flow_label)
9606     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9607
9608   ip->ip_version_traffic_class_and_flow_label =
9609     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9610
9611   if (payload_length)
9612     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9613
9614   if (hop_limit)
9615     ip->hop_limit = hop_limit_val;
9616
9617   *matchp = match;
9618   return 1;
9619 }
9620
9621 uword
9622 unformat_l3_match (unformat_input_t * input, va_list * args)
9623 {
9624   u8 **matchp = va_arg (*args, u8 **);
9625
9626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9627     {
9628       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9629         return 1;
9630       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9631         return 1;
9632       else
9633         break;
9634     }
9635   return 0;
9636 }
9637
9638 uword
9639 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9640 {
9641   u8 *tagp = va_arg (*args, u8 *);
9642   u32 tag;
9643
9644   if (unformat (input, "%d", &tag))
9645     {
9646       tagp[0] = (tag >> 8) & 0x0F;
9647       tagp[1] = tag & 0xFF;
9648       return 1;
9649     }
9650
9651   return 0;
9652 }
9653
9654 uword
9655 unformat_l2_match (unformat_input_t * input, va_list * args)
9656 {
9657   u8 **matchp = va_arg (*args, u8 **);
9658   u8 *match = 0;
9659   u8 src = 0;
9660   u8 src_val[6];
9661   u8 dst = 0;
9662   u8 dst_val[6];
9663   u8 proto = 0;
9664   u16 proto_val;
9665   u8 tag1 = 0;
9666   u8 tag1_val[2];
9667   u8 tag2 = 0;
9668   u8 tag2_val[2];
9669   int len = 14;
9670   u8 ignore_tag1 = 0;
9671   u8 ignore_tag2 = 0;
9672   u8 cos1 = 0;
9673   u8 cos2 = 0;
9674   u32 cos1_val = 0;
9675   u32 cos2_val = 0;
9676
9677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9678     {
9679       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9680         src = 1;
9681       else
9682         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9683         dst = 1;
9684       else if (unformat (input, "proto %U",
9685                          unformat_ethernet_type_host_byte_order, &proto_val))
9686         proto = 1;
9687       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9688         tag1 = 1;
9689       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9690         tag2 = 1;
9691       else if (unformat (input, "ignore-tag1"))
9692         ignore_tag1 = 1;
9693       else if (unformat (input, "ignore-tag2"))
9694         ignore_tag2 = 1;
9695       else if (unformat (input, "cos1 %d", &cos1_val))
9696         cos1 = 1;
9697       else if (unformat (input, "cos2 %d", &cos2_val))
9698         cos2 = 1;
9699       else
9700         break;
9701     }
9702   if ((src + dst + proto + tag1 + tag2 +
9703        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9704     return 0;
9705
9706   if (tag1 || ignore_tag1 || cos1)
9707     len = 18;
9708   if (tag2 || ignore_tag2 || cos2)
9709     len = 22;
9710
9711   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9712
9713   if (dst)
9714     clib_memcpy (match, dst_val, 6);
9715
9716   if (src)
9717     clib_memcpy (match + 6, src_val, 6);
9718
9719   if (tag2)
9720     {
9721       /* inner vlan tag */
9722       match[19] = tag2_val[1];
9723       match[18] = tag2_val[0];
9724       if (cos2)
9725         match[18] |= (cos2_val & 0x7) << 5;
9726       if (proto)
9727         {
9728           match[21] = proto_val & 0xff;
9729           match[20] = proto_val >> 8;
9730         }
9731       if (tag1)
9732         {
9733           match[15] = tag1_val[1];
9734           match[14] = tag1_val[0];
9735         }
9736       if (cos1)
9737         match[14] |= (cos1_val & 0x7) << 5;
9738       *matchp = match;
9739       return 1;
9740     }
9741   if (tag1)
9742     {
9743       match[15] = tag1_val[1];
9744       match[14] = tag1_val[0];
9745       if (proto)
9746         {
9747           match[17] = proto_val & 0xff;
9748           match[16] = proto_val >> 8;
9749         }
9750       if (cos1)
9751         match[14] |= (cos1_val & 0x7) << 5;
9752
9753       *matchp = match;
9754       return 1;
9755     }
9756   if (cos2)
9757     match[18] |= (cos2_val & 0x7) << 5;
9758   if (cos1)
9759     match[14] |= (cos1_val & 0x7) << 5;
9760   if (proto)
9761     {
9762       match[13] = proto_val & 0xff;
9763       match[12] = proto_val >> 8;
9764     }
9765
9766   *matchp = match;
9767   return 1;
9768 }
9769
9770
9771 uword
9772 unformat_classify_match (unformat_input_t * input, va_list * args)
9773 {
9774   u8 **matchp = va_arg (*args, u8 **);
9775   u32 skip_n_vectors = va_arg (*args, u32);
9776   u32 match_n_vectors = va_arg (*args, u32);
9777
9778   u8 *match = 0;
9779   u8 *l2 = 0;
9780   u8 *l3 = 0;
9781   u8 *l4 = 0;
9782
9783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9784     {
9785       if (unformat (input, "hex %U", unformat_hex_string, &match))
9786         ;
9787       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9788         ;
9789       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9790         ;
9791       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9792         ;
9793       else
9794         break;
9795     }
9796
9797   if (l4 && !l3)
9798     {
9799       vec_free (match);
9800       vec_free (l2);
9801       vec_free (l4);
9802       return 0;
9803     }
9804
9805   if (match || l2 || l3 || l4)
9806     {
9807       if (l2 || l3 || l4)
9808         {
9809           /* "Win a free Ethernet header in every packet" */
9810           if (l2 == 0)
9811             vec_validate_aligned (l2, 13, sizeof (u32x4));
9812           match = l2;
9813           if (vec_len (l3))
9814             {
9815               vec_append_aligned (match, l3, sizeof (u32x4));
9816               vec_free (l3);
9817             }
9818           if (vec_len (l4))
9819             {
9820               vec_append_aligned (match, l4, sizeof (u32x4));
9821               vec_free (l4);
9822             }
9823         }
9824
9825       /* Make sure the vector is big enough even if key is all 0's */
9826       vec_validate_aligned
9827         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9828          sizeof (u32x4));
9829
9830       /* Set size, include skipped vectors */
9831       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9832
9833       *matchp = match;
9834
9835       return 1;
9836     }
9837
9838   return 0;
9839 }
9840
9841 static int
9842 api_classify_add_del_session (vat_main_t * vam)
9843 {
9844   unformat_input_t *i = vam->input;
9845   vl_api_classify_add_del_session_t *mp;
9846   int is_add = 1;
9847   u32 table_index = ~0;
9848   u32 hit_next_index = ~0;
9849   u32 opaque_index = ~0;
9850   u8 *match = 0;
9851   i32 advance = 0;
9852   u32 skip_n_vectors = 0;
9853   u32 match_n_vectors = 0;
9854   u32 action = 0;
9855   u32 metadata = 0;
9856   int ret;
9857
9858   /*
9859    * Warning: you have to supply skip_n and match_n
9860    * because the API client cant simply look at the classify
9861    * table object.
9862    */
9863
9864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9865     {
9866       if (unformat (i, "del"))
9867         is_add = 0;
9868       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9869                          &hit_next_index))
9870         ;
9871       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9872                          &hit_next_index))
9873         ;
9874       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9875                          &hit_next_index))
9876         ;
9877       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9878         ;
9879       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9880         ;
9881       else if (unformat (i, "opaque-index %d", &opaque_index))
9882         ;
9883       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9884         ;
9885       else if (unformat (i, "match_n %d", &match_n_vectors))
9886         ;
9887       else if (unformat (i, "match %U", unformat_classify_match,
9888                          &match, skip_n_vectors, match_n_vectors))
9889         ;
9890       else if (unformat (i, "advance %d", &advance))
9891         ;
9892       else if (unformat (i, "table-index %d", &table_index))
9893         ;
9894       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9895         action = 1;
9896       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9897         action = 2;
9898       else if (unformat (i, "action %d", &action))
9899         ;
9900       else if (unformat (i, "metadata %d", &metadata))
9901         ;
9902       else
9903         break;
9904     }
9905
9906   if (table_index == ~0)
9907     {
9908       errmsg ("Table index required");
9909       return -99;
9910     }
9911
9912   if (is_add && match == 0)
9913     {
9914       errmsg ("Match value required");
9915       return -99;
9916     }
9917
9918   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9919
9920   mp->is_add = is_add;
9921   mp->table_index = ntohl (table_index);
9922   mp->hit_next_index = ntohl (hit_next_index);
9923   mp->opaque_index = ntohl (opaque_index);
9924   mp->advance = ntohl (advance);
9925   mp->action = action;
9926   mp->metadata = ntohl (metadata);
9927   clib_memcpy (mp->match, match, vec_len (match));
9928   vec_free (match);
9929
9930   S (mp);
9931   W (ret);
9932   return ret;
9933 }
9934
9935 static int
9936 api_classify_set_interface_ip_table (vat_main_t * vam)
9937 {
9938   unformat_input_t *i = vam->input;
9939   vl_api_classify_set_interface_ip_table_t *mp;
9940   u32 sw_if_index;
9941   int sw_if_index_set;
9942   u32 table_index = ~0;
9943   u8 is_ipv6 = 0;
9944   int ret;
9945
9946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9947     {
9948       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9949         sw_if_index_set = 1;
9950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9951         sw_if_index_set = 1;
9952       else if (unformat (i, "table %d", &table_index))
9953         ;
9954       else
9955         {
9956           clib_warning ("parse error '%U'", format_unformat_error, i);
9957           return -99;
9958         }
9959     }
9960
9961   if (sw_if_index_set == 0)
9962     {
9963       errmsg ("missing interface name or sw_if_index");
9964       return -99;
9965     }
9966
9967
9968   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9969
9970   mp->sw_if_index = ntohl (sw_if_index);
9971   mp->table_index = ntohl (table_index);
9972   mp->is_ipv6 = is_ipv6;
9973
9974   S (mp);
9975   W (ret);
9976   return ret;
9977 }
9978
9979 static int
9980 api_classify_set_interface_l2_tables (vat_main_t * vam)
9981 {
9982   unformat_input_t *i = vam->input;
9983   vl_api_classify_set_interface_l2_tables_t *mp;
9984   u32 sw_if_index;
9985   int sw_if_index_set;
9986   u32 ip4_table_index = ~0;
9987   u32 ip6_table_index = ~0;
9988   u32 other_table_index = ~0;
9989   u32 is_input = 1;
9990   int ret;
9991
9992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9993     {
9994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9995         sw_if_index_set = 1;
9996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9997         sw_if_index_set = 1;
9998       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9999         ;
10000       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10001         ;
10002       else if (unformat (i, "other-table %d", &other_table_index))
10003         ;
10004       else if (unformat (i, "is-input %d", &is_input))
10005         ;
10006       else
10007         {
10008           clib_warning ("parse error '%U'", format_unformat_error, i);
10009           return -99;
10010         }
10011     }
10012
10013   if (sw_if_index_set == 0)
10014     {
10015       errmsg ("missing interface name or sw_if_index");
10016       return -99;
10017     }
10018
10019
10020   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10021
10022   mp->sw_if_index = ntohl (sw_if_index);
10023   mp->ip4_table_index = ntohl (ip4_table_index);
10024   mp->ip6_table_index = ntohl (ip6_table_index);
10025   mp->other_table_index = ntohl (other_table_index);
10026   mp->is_input = (u8) is_input;
10027
10028   S (mp);
10029   W (ret);
10030   return ret;
10031 }
10032
10033 static int
10034 api_set_ipfix_exporter (vat_main_t * vam)
10035 {
10036   unformat_input_t *i = vam->input;
10037   vl_api_set_ipfix_exporter_t *mp;
10038   ip4_address_t collector_address;
10039   u8 collector_address_set = 0;
10040   u32 collector_port = ~0;
10041   ip4_address_t src_address;
10042   u8 src_address_set = 0;
10043   u32 vrf_id = ~0;
10044   u32 path_mtu = ~0;
10045   u32 template_interval = ~0;
10046   u8 udp_checksum = 0;
10047   int ret;
10048
10049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10050     {
10051       if (unformat (i, "collector_address %U", unformat_ip4_address,
10052                     &collector_address))
10053         collector_address_set = 1;
10054       else if (unformat (i, "collector_port %d", &collector_port))
10055         ;
10056       else if (unformat (i, "src_address %U", unformat_ip4_address,
10057                          &src_address))
10058         src_address_set = 1;
10059       else if (unformat (i, "vrf_id %d", &vrf_id))
10060         ;
10061       else if (unformat (i, "path_mtu %d", &path_mtu))
10062         ;
10063       else if (unformat (i, "template_interval %d", &template_interval))
10064         ;
10065       else if (unformat (i, "udp_checksum"))
10066         udp_checksum = 1;
10067       else
10068         break;
10069     }
10070
10071   if (collector_address_set == 0)
10072     {
10073       errmsg ("collector_address required");
10074       return -99;
10075     }
10076
10077   if (src_address_set == 0)
10078     {
10079       errmsg ("src_address required");
10080       return -99;
10081     }
10082
10083   M (SET_IPFIX_EXPORTER, mp);
10084
10085   memcpy (mp->collector_address, collector_address.data,
10086           sizeof (collector_address.data));
10087   mp->collector_port = htons ((u16) collector_port);
10088   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10089   mp->vrf_id = htonl (vrf_id);
10090   mp->path_mtu = htonl (path_mtu);
10091   mp->template_interval = htonl (template_interval);
10092   mp->udp_checksum = udp_checksum;
10093
10094   S (mp);
10095   W (ret);
10096   return ret;
10097 }
10098
10099 static int
10100 api_set_ipfix_classify_stream (vat_main_t * vam)
10101 {
10102   unformat_input_t *i = vam->input;
10103   vl_api_set_ipfix_classify_stream_t *mp;
10104   u32 domain_id = 0;
10105   u32 src_port = UDP_DST_PORT_ipfix;
10106   int ret;
10107
10108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10109     {
10110       if (unformat (i, "domain %d", &domain_id))
10111         ;
10112       else if (unformat (i, "src_port %d", &src_port))
10113         ;
10114       else
10115         {
10116           errmsg ("unknown input `%U'", format_unformat_error, i);
10117           return -99;
10118         }
10119     }
10120
10121   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10122
10123   mp->domain_id = htonl (domain_id);
10124   mp->src_port = htons ((u16) src_port);
10125
10126   S (mp);
10127   W (ret);
10128   return ret;
10129 }
10130
10131 static int
10132 api_ipfix_classify_table_add_del (vat_main_t * vam)
10133 {
10134   unformat_input_t *i = vam->input;
10135   vl_api_ipfix_classify_table_add_del_t *mp;
10136   int is_add = -1;
10137   u32 classify_table_index = ~0;
10138   u8 ip_version = 0;
10139   u8 transport_protocol = 255;
10140   int ret;
10141
10142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10143     {
10144       if (unformat (i, "add"))
10145         is_add = 1;
10146       else if (unformat (i, "del"))
10147         is_add = 0;
10148       else if (unformat (i, "table %d", &classify_table_index))
10149         ;
10150       else if (unformat (i, "ip4"))
10151         ip_version = 4;
10152       else if (unformat (i, "ip6"))
10153         ip_version = 6;
10154       else if (unformat (i, "tcp"))
10155         transport_protocol = 6;
10156       else if (unformat (i, "udp"))
10157         transport_protocol = 17;
10158       else
10159         {
10160           errmsg ("unknown input `%U'", format_unformat_error, i);
10161           return -99;
10162         }
10163     }
10164
10165   if (is_add == -1)
10166     {
10167       errmsg ("expecting: add|del");
10168       return -99;
10169     }
10170   if (classify_table_index == ~0)
10171     {
10172       errmsg ("classifier table not specified");
10173       return -99;
10174     }
10175   if (ip_version == 0)
10176     {
10177       errmsg ("IP version not specified");
10178       return -99;
10179     }
10180
10181   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10182
10183   mp->is_add = is_add;
10184   mp->table_id = htonl (classify_table_index);
10185   mp->ip_version = ip_version;
10186   mp->transport_protocol = transport_protocol;
10187
10188   S (mp);
10189   W (ret);
10190   return ret;
10191 }
10192
10193 static int
10194 api_get_node_index (vat_main_t * vam)
10195 {
10196   unformat_input_t *i = vam->input;
10197   vl_api_get_node_index_t *mp;
10198   u8 *name = 0;
10199   int ret;
10200
10201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10202     {
10203       if (unformat (i, "node %s", &name))
10204         ;
10205       else
10206         break;
10207     }
10208   if (name == 0)
10209     {
10210       errmsg ("node name required");
10211       return -99;
10212     }
10213   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10214     {
10215       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10216       return -99;
10217     }
10218
10219   M (GET_NODE_INDEX, mp);
10220   clib_memcpy (mp->node_name, name, vec_len (name));
10221   vec_free (name);
10222
10223   S (mp);
10224   W (ret);
10225   return ret;
10226 }
10227
10228 static int
10229 api_get_next_index (vat_main_t * vam)
10230 {
10231   unformat_input_t *i = vam->input;
10232   vl_api_get_next_index_t *mp;
10233   u8 *node_name = 0, *next_node_name = 0;
10234   int ret;
10235
10236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10237     {
10238       if (unformat (i, "node-name %s", &node_name))
10239         ;
10240       else if (unformat (i, "next-node-name %s", &next_node_name))
10241         break;
10242     }
10243
10244   if (node_name == 0)
10245     {
10246       errmsg ("node name required");
10247       return -99;
10248     }
10249   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10250     {
10251       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10252       return -99;
10253     }
10254
10255   if (next_node_name == 0)
10256     {
10257       errmsg ("next node name required");
10258       return -99;
10259     }
10260   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10261     {
10262       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10263       return -99;
10264     }
10265
10266   M (GET_NEXT_INDEX, mp);
10267   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10268   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10269   vec_free (node_name);
10270   vec_free (next_node_name);
10271
10272   S (mp);
10273   W (ret);
10274   return ret;
10275 }
10276
10277 static int
10278 api_add_node_next (vat_main_t * vam)
10279 {
10280   unformat_input_t *i = vam->input;
10281   vl_api_add_node_next_t *mp;
10282   u8 *name = 0;
10283   u8 *next = 0;
10284   int ret;
10285
10286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10287     {
10288       if (unformat (i, "node %s", &name))
10289         ;
10290       else if (unformat (i, "next %s", &next))
10291         ;
10292       else
10293         break;
10294     }
10295   if (name == 0)
10296     {
10297       errmsg ("node name required");
10298       return -99;
10299     }
10300   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10301     {
10302       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10303       return -99;
10304     }
10305   if (next == 0)
10306     {
10307       errmsg ("next node required");
10308       return -99;
10309     }
10310   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10311     {
10312       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10313       return -99;
10314     }
10315
10316   M (ADD_NODE_NEXT, mp);
10317   clib_memcpy (mp->node_name, name, vec_len (name));
10318   clib_memcpy (mp->next_name, next, vec_len (next));
10319   vec_free (name);
10320   vec_free (next);
10321
10322   S (mp);
10323   W (ret);
10324   return ret;
10325 }
10326
10327 static int
10328 api_l2tpv3_create_tunnel (vat_main_t * vam)
10329 {
10330   unformat_input_t *i = vam->input;
10331   ip6_address_t client_address, our_address;
10332   int client_address_set = 0;
10333   int our_address_set = 0;
10334   u32 local_session_id = 0;
10335   u32 remote_session_id = 0;
10336   u64 local_cookie = 0;
10337   u64 remote_cookie = 0;
10338   u8 l2_sublayer_present = 0;
10339   vl_api_l2tpv3_create_tunnel_t *mp;
10340   int ret;
10341
10342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10343     {
10344       if (unformat (i, "client_address %U", unformat_ip6_address,
10345                     &client_address))
10346         client_address_set = 1;
10347       else if (unformat (i, "our_address %U", unformat_ip6_address,
10348                          &our_address))
10349         our_address_set = 1;
10350       else if (unformat (i, "local_session_id %d", &local_session_id))
10351         ;
10352       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10353         ;
10354       else if (unformat (i, "local_cookie %lld", &local_cookie))
10355         ;
10356       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10357         ;
10358       else if (unformat (i, "l2-sublayer-present"))
10359         l2_sublayer_present = 1;
10360       else
10361         break;
10362     }
10363
10364   if (client_address_set == 0)
10365     {
10366       errmsg ("client_address required");
10367       return -99;
10368     }
10369
10370   if (our_address_set == 0)
10371     {
10372       errmsg ("our_address required");
10373       return -99;
10374     }
10375
10376   M (L2TPV3_CREATE_TUNNEL, mp);
10377
10378   clib_memcpy (mp->client_address, client_address.as_u8,
10379                sizeof (mp->client_address));
10380
10381   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10382
10383   mp->local_session_id = ntohl (local_session_id);
10384   mp->remote_session_id = ntohl (remote_session_id);
10385   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10386   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10387   mp->l2_sublayer_present = l2_sublayer_present;
10388   mp->is_ipv6 = 1;
10389
10390   S (mp);
10391   W (ret);
10392   return ret;
10393 }
10394
10395 static int
10396 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10397 {
10398   unformat_input_t *i = vam->input;
10399   u32 sw_if_index;
10400   u8 sw_if_index_set = 0;
10401   u64 new_local_cookie = 0;
10402   u64 new_remote_cookie = 0;
10403   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10404   int ret;
10405
10406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10407     {
10408       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10409         sw_if_index_set = 1;
10410       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10411         sw_if_index_set = 1;
10412       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10413         ;
10414       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10415         ;
10416       else
10417         break;
10418     }
10419
10420   if (sw_if_index_set == 0)
10421     {
10422       errmsg ("missing interface name or sw_if_index");
10423       return -99;
10424     }
10425
10426   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10427
10428   mp->sw_if_index = ntohl (sw_if_index);
10429   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10430   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10431
10432   S (mp);
10433   W (ret);
10434   return ret;
10435 }
10436
10437 static int
10438 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10439 {
10440   unformat_input_t *i = vam->input;
10441   vl_api_l2tpv3_interface_enable_disable_t *mp;
10442   u32 sw_if_index;
10443   u8 sw_if_index_set = 0;
10444   u8 enable_disable = 1;
10445   int ret;
10446
10447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10448     {
10449       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10450         sw_if_index_set = 1;
10451       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10452         sw_if_index_set = 1;
10453       else if (unformat (i, "enable"))
10454         enable_disable = 1;
10455       else if (unformat (i, "disable"))
10456         enable_disable = 0;
10457       else
10458         break;
10459     }
10460
10461   if (sw_if_index_set == 0)
10462     {
10463       errmsg ("missing interface name or sw_if_index");
10464       return -99;
10465     }
10466
10467   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10468
10469   mp->sw_if_index = ntohl (sw_if_index);
10470   mp->enable_disable = enable_disable;
10471
10472   S (mp);
10473   W (ret);
10474   return ret;
10475 }
10476
10477 static int
10478 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10479 {
10480   unformat_input_t *i = vam->input;
10481   vl_api_l2tpv3_set_lookup_key_t *mp;
10482   u8 key = ~0;
10483   int ret;
10484
10485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10486     {
10487       if (unformat (i, "lookup_v6_src"))
10488         key = L2T_LOOKUP_SRC_ADDRESS;
10489       else if (unformat (i, "lookup_v6_dst"))
10490         key = L2T_LOOKUP_DST_ADDRESS;
10491       else if (unformat (i, "lookup_session_id"))
10492         key = L2T_LOOKUP_SESSION_ID;
10493       else
10494         break;
10495     }
10496
10497   if (key == (u8) ~ 0)
10498     {
10499       errmsg ("l2tp session lookup key unset");
10500       return -99;
10501     }
10502
10503   M (L2TPV3_SET_LOOKUP_KEY, mp);
10504
10505   mp->key = key;
10506
10507   S (mp);
10508   W (ret);
10509   return ret;
10510 }
10511
10512 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10513   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10514 {
10515   vat_main_t *vam = &vat_main;
10516
10517   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10518          format_ip6_address, mp->our_address,
10519          format_ip6_address, mp->client_address,
10520          clib_net_to_host_u32 (mp->sw_if_index));
10521
10522   print (vam->ofp,
10523          "   local cookies %016llx %016llx remote cookie %016llx",
10524          clib_net_to_host_u64 (mp->local_cookie[0]),
10525          clib_net_to_host_u64 (mp->local_cookie[1]),
10526          clib_net_to_host_u64 (mp->remote_cookie));
10527
10528   print (vam->ofp, "   local session-id %d remote session-id %d",
10529          clib_net_to_host_u32 (mp->local_session_id),
10530          clib_net_to_host_u32 (mp->remote_session_id));
10531
10532   print (vam->ofp, "   l2 specific sublayer %s\n",
10533          mp->l2_sublayer_present ? "preset" : "absent");
10534
10535 }
10536
10537 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10538   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10539 {
10540   vat_main_t *vam = &vat_main;
10541   vat_json_node_t *node = NULL;
10542   struct in6_addr addr;
10543
10544   if (VAT_JSON_ARRAY != vam->json_tree.type)
10545     {
10546       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10547       vat_json_init_array (&vam->json_tree);
10548     }
10549   node = vat_json_array_add (&vam->json_tree);
10550
10551   vat_json_init_object (node);
10552
10553   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10554   vat_json_object_add_ip6 (node, "our_address", addr);
10555   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10556   vat_json_object_add_ip6 (node, "client_address", addr);
10557
10558   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10559   vat_json_init_array (lc);
10560   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10561   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10562   vat_json_object_add_uint (node, "remote_cookie",
10563                             clib_net_to_host_u64 (mp->remote_cookie));
10564
10565   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10566   vat_json_object_add_uint (node, "local_session_id",
10567                             clib_net_to_host_u32 (mp->local_session_id));
10568   vat_json_object_add_uint (node, "remote_session_id",
10569                             clib_net_to_host_u32 (mp->remote_session_id));
10570   vat_json_object_add_string_copy (node, "l2_sublayer",
10571                                    mp->l2_sublayer_present ? (u8 *) "present"
10572                                    : (u8 *) "absent");
10573 }
10574
10575 static int
10576 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10577 {
10578   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10579   int ret;
10580
10581   /* Get list of l2tpv3-tunnel interfaces */
10582   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10583   S (mp);
10584
10585   /* Use a control ping for synchronization */
10586   {
10587     vl_api_control_ping_t *mp;
10588     M (CONTROL_PING, mp);
10589     S (mp);
10590   }
10591   W (ret);
10592   return ret;
10593 }
10594
10595
10596 static void vl_api_sw_interface_tap_details_t_handler
10597   (vl_api_sw_interface_tap_details_t * mp)
10598 {
10599   vat_main_t *vam = &vat_main;
10600
10601   print (vam->ofp, "%-16s %d",
10602          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10603 }
10604
10605 static void vl_api_sw_interface_tap_details_t_handler_json
10606   (vl_api_sw_interface_tap_details_t * mp)
10607 {
10608   vat_main_t *vam = &vat_main;
10609   vat_json_node_t *node = NULL;
10610
10611   if (VAT_JSON_ARRAY != vam->json_tree.type)
10612     {
10613       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10614       vat_json_init_array (&vam->json_tree);
10615     }
10616   node = vat_json_array_add (&vam->json_tree);
10617
10618   vat_json_init_object (node);
10619   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10620   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10621 }
10622
10623 static int
10624 api_sw_interface_tap_dump (vat_main_t * vam)
10625 {
10626   vl_api_sw_interface_tap_dump_t *mp;
10627   int ret;
10628
10629   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10630   /* Get list of tap interfaces */
10631   M (SW_INTERFACE_TAP_DUMP, mp);
10632   S (mp);
10633
10634   /* Use a control ping for synchronization */
10635   {
10636     vl_api_control_ping_t *mp;
10637     M (CONTROL_PING, mp);
10638     S (mp);
10639   }
10640   W (ret);
10641   return ret;
10642 }
10643
10644 static uword unformat_vxlan_decap_next
10645   (unformat_input_t * input, va_list * args)
10646 {
10647   u32 *result = va_arg (*args, u32 *);
10648   u32 tmp;
10649
10650   if (unformat (input, "l2"))
10651     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10652   else if (unformat (input, "%d", &tmp))
10653     *result = tmp;
10654   else
10655     return 0;
10656   return 1;
10657 }
10658
10659 static int
10660 api_vxlan_add_del_tunnel (vat_main_t * vam)
10661 {
10662   unformat_input_t *line_input = vam->input;
10663   vl_api_vxlan_add_del_tunnel_t *mp;
10664   ip46_address_t src, dst;
10665   u8 is_add = 1;
10666   u8 ipv4_set = 0, ipv6_set = 0;
10667   u8 src_set = 0;
10668   u8 dst_set = 0;
10669   u8 grp_set = 0;
10670   u32 mcast_sw_if_index = ~0;
10671   u32 encap_vrf_id = 0;
10672   u32 decap_next_index = ~0;
10673   u32 vni = 0;
10674   int ret;
10675
10676   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10677   memset (&src, 0, sizeof src);
10678   memset (&dst, 0, sizeof dst);
10679
10680   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10681     {
10682       if (unformat (line_input, "del"))
10683         is_add = 0;
10684       else
10685         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10686         {
10687           ipv4_set = 1;
10688           src_set = 1;
10689         }
10690       else
10691         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10692         {
10693           ipv4_set = 1;
10694           dst_set = 1;
10695         }
10696       else
10697         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10698         {
10699           ipv6_set = 1;
10700           src_set = 1;
10701         }
10702       else
10703         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10704         {
10705           ipv6_set = 1;
10706           dst_set = 1;
10707         }
10708       else if (unformat (line_input, "group %U %U",
10709                          unformat_ip4_address, &dst.ip4,
10710                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10711         {
10712           grp_set = dst_set = 1;
10713           ipv4_set = 1;
10714         }
10715       else if (unformat (line_input, "group %U",
10716                          unformat_ip4_address, &dst.ip4))
10717         {
10718           grp_set = dst_set = 1;
10719           ipv4_set = 1;
10720         }
10721       else if (unformat (line_input, "group %U %U",
10722                          unformat_ip6_address, &dst.ip6,
10723                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10724         {
10725           grp_set = dst_set = 1;
10726           ipv6_set = 1;
10727         }
10728       else if (unformat (line_input, "group %U",
10729                          unformat_ip6_address, &dst.ip6))
10730         {
10731           grp_set = dst_set = 1;
10732           ipv6_set = 1;
10733         }
10734       else
10735         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10736         ;
10737       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10738         ;
10739       else if (unformat (line_input, "decap-next %U",
10740                          unformat_vxlan_decap_next, &decap_next_index))
10741         ;
10742       else if (unformat (line_input, "vni %d", &vni))
10743         ;
10744       else
10745         {
10746           errmsg ("parse error '%U'", format_unformat_error, line_input);
10747           return -99;
10748         }
10749     }
10750
10751   if (src_set == 0)
10752     {
10753       errmsg ("tunnel src address not specified");
10754       return -99;
10755     }
10756   if (dst_set == 0)
10757     {
10758       errmsg ("tunnel dst address not specified");
10759       return -99;
10760     }
10761
10762   if (grp_set && !ip46_address_is_multicast (&dst))
10763     {
10764       errmsg ("tunnel group address not multicast");
10765       return -99;
10766     }
10767   if (grp_set && mcast_sw_if_index == ~0)
10768     {
10769       errmsg ("tunnel nonexistent multicast device");
10770       return -99;
10771     }
10772   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10773     {
10774       errmsg ("tunnel dst address must be unicast");
10775       return -99;
10776     }
10777
10778
10779   if (ipv4_set && ipv6_set)
10780     {
10781       errmsg ("both IPv4 and IPv6 addresses specified");
10782       return -99;
10783     }
10784
10785   if ((vni == 0) || (vni >> 24))
10786     {
10787       errmsg ("vni not specified or out of range");
10788       return -99;
10789     }
10790
10791   M (VXLAN_ADD_DEL_TUNNEL, mp);
10792
10793   if (ipv6_set)
10794     {
10795       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10796       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10797     }
10798   else
10799     {
10800       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10801       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10802     }
10803   mp->encap_vrf_id = ntohl (encap_vrf_id);
10804   mp->decap_next_index = ntohl (decap_next_index);
10805   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10806   mp->vni = ntohl (vni);
10807   mp->is_add = is_add;
10808   mp->is_ipv6 = ipv6_set;
10809
10810   S (mp);
10811   W (ret);
10812   return ret;
10813 }
10814
10815 static void vl_api_vxlan_tunnel_details_t_handler
10816   (vl_api_vxlan_tunnel_details_t * mp)
10817 {
10818   vat_main_t *vam = &vat_main;
10819   ip46_address_t src, dst;
10820
10821   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10822   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10823
10824   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10825          ntohl (mp->sw_if_index),
10826          format_ip46_address, &src, IP46_TYPE_ANY,
10827          format_ip46_address, &dst, IP46_TYPE_ANY,
10828          ntohl (mp->encap_vrf_id),
10829          ntohl (mp->decap_next_index), ntohl (mp->vni),
10830          ntohl (mp->mcast_sw_if_index));
10831 }
10832
10833 static void vl_api_vxlan_tunnel_details_t_handler_json
10834   (vl_api_vxlan_tunnel_details_t * mp)
10835 {
10836   vat_main_t *vam = &vat_main;
10837   vat_json_node_t *node = NULL;
10838
10839   if (VAT_JSON_ARRAY != vam->json_tree.type)
10840     {
10841       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10842       vat_json_init_array (&vam->json_tree);
10843     }
10844   node = vat_json_array_add (&vam->json_tree);
10845
10846   vat_json_init_object (node);
10847   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10848   if (mp->is_ipv6)
10849     {
10850       struct in6_addr ip6;
10851
10852       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10853       vat_json_object_add_ip6 (node, "src_address", ip6);
10854       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10855       vat_json_object_add_ip6 (node, "dst_address", ip6);
10856     }
10857   else
10858     {
10859       struct in_addr ip4;
10860
10861       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10862       vat_json_object_add_ip4 (node, "src_address", ip4);
10863       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10864       vat_json_object_add_ip4 (node, "dst_address", ip4);
10865     }
10866   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10867   vat_json_object_add_uint (node, "decap_next_index",
10868                             ntohl (mp->decap_next_index));
10869   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10870   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10871   vat_json_object_add_uint (node, "mcast_sw_if_index",
10872                             ntohl (mp->mcast_sw_if_index));
10873 }
10874
10875 static int
10876 api_vxlan_tunnel_dump (vat_main_t * vam)
10877 {
10878   unformat_input_t *i = vam->input;
10879   vl_api_vxlan_tunnel_dump_t *mp;
10880   u32 sw_if_index;
10881   u8 sw_if_index_set = 0;
10882   int ret;
10883
10884   /* Parse args required to build the message */
10885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10886     {
10887       if (unformat (i, "sw_if_index %d", &sw_if_index))
10888         sw_if_index_set = 1;
10889       else
10890         break;
10891     }
10892
10893   if (sw_if_index_set == 0)
10894     {
10895       sw_if_index = ~0;
10896     }
10897
10898   if (!vam->json_output)
10899     {
10900       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10901              "sw_if_index", "src_address", "dst_address",
10902              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10903     }
10904
10905   /* Get list of vxlan-tunnel interfaces */
10906   M (VXLAN_TUNNEL_DUMP, mp);
10907
10908   mp->sw_if_index = htonl (sw_if_index);
10909
10910   S (mp);
10911
10912   /* Use a control ping for synchronization */
10913   {
10914     vl_api_control_ping_t *mp;
10915     M (CONTROL_PING, mp);
10916     S (mp);
10917   }
10918   W (ret);
10919   return ret;
10920 }
10921
10922 static int
10923 api_gre_add_del_tunnel (vat_main_t * vam)
10924 {
10925   unformat_input_t *line_input = vam->input;
10926   vl_api_gre_add_del_tunnel_t *mp;
10927   ip4_address_t src4, dst4;
10928   u8 is_add = 1;
10929   u8 teb = 0;
10930   u8 src_set = 0;
10931   u8 dst_set = 0;
10932   u32 outer_fib_id = 0;
10933   int ret;
10934
10935   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10936     {
10937       if (unformat (line_input, "del"))
10938         is_add = 0;
10939       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10940         src_set = 1;
10941       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10942         dst_set = 1;
10943       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10944         ;
10945       else if (unformat (line_input, "teb"))
10946         teb = 1;
10947       else
10948         {
10949           errmsg ("parse error '%U'", format_unformat_error, line_input);
10950           return -99;
10951         }
10952     }
10953
10954   if (src_set == 0)
10955     {
10956       errmsg ("tunnel src address not specified");
10957       return -99;
10958     }
10959   if (dst_set == 0)
10960     {
10961       errmsg ("tunnel dst address not specified");
10962       return -99;
10963     }
10964
10965
10966   M (GRE_ADD_DEL_TUNNEL, mp);
10967
10968   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10969   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10970   mp->outer_fib_id = ntohl (outer_fib_id);
10971   mp->is_add = is_add;
10972   mp->teb = teb;
10973
10974   S (mp);
10975   W (ret);
10976   return ret;
10977 }
10978
10979 static void vl_api_gre_tunnel_details_t_handler
10980   (vl_api_gre_tunnel_details_t * mp)
10981 {
10982   vat_main_t *vam = &vat_main;
10983
10984   print (vam->ofp, "%11d%15U%15U%6d%14d",
10985          ntohl (mp->sw_if_index),
10986          format_ip4_address, &mp->src_address,
10987          format_ip4_address, &mp->dst_address,
10988          mp->teb, ntohl (mp->outer_fib_id));
10989 }
10990
10991 static void vl_api_gre_tunnel_details_t_handler_json
10992   (vl_api_gre_tunnel_details_t * mp)
10993 {
10994   vat_main_t *vam = &vat_main;
10995   vat_json_node_t *node = NULL;
10996   struct in_addr ip4;
10997
10998   if (VAT_JSON_ARRAY != vam->json_tree.type)
10999     {
11000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11001       vat_json_init_array (&vam->json_tree);
11002     }
11003   node = vat_json_array_add (&vam->json_tree);
11004
11005   vat_json_init_object (node);
11006   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11007   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11008   vat_json_object_add_ip4 (node, "src_address", ip4);
11009   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11010   vat_json_object_add_ip4 (node, "dst_address", ip4);
11011   vat_json_object_add_uint (node, "teb", mp->teb);
11012   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11013 }
11014
11015 static int
11016 api_gre_tunnel_dump (vat_main_t * vam)
11017 {
11018   unformat_input_t *i = vam->input;
11019   vl_api_gre_tunnel_dump_t *mp;
11020   u32 sw_if_index;
11021   u8 sw_if_index_set = 0;
11022   int ret;
11023
11024   /* Parse args required to build the message */
11025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11026     {
11027       if (unformat (i, "sw_if_index %d", &sw_if_index))
11028         sw_if_index_set = 1;
11029       else
11030         break;
11031     }
11032
11033   if (sw_if_index_set == 0)
11034     {
11035       sw_if_index = ~0;
11036     }
11037
11038   if (!vam->json_output)
11039     {
11040       print (vam->ofp, "%11s%15s%15s%6s%14s",
11041              "sw_if_index", "src_address", "dst_address", "teb",
11042              "outer_fib_id");
11043     }
11044
11045   /* Get list of gre-tunnel interfaces */
11046   M (GRE_TUNNEL_DUMP, mp);
11047
11048   mp->sw_if_index = htonl (sw_if_index);
11049
11050   S (mp);
11051
11052   /* Use a control ping for synchronization */
11053   {
11054     vl_api_control_ping_t *mp;
11055     M (CONTROL_PING, mp);
11056     S (mp);
11057   }
11058   W (ret);
11059   return ret;
11060 }
11061
11062 static int
11063 api_l2_fib_clear_table (vat_main_t * vam)
11064 {
11065 //  unformat_input_t * i = vam->input;
11066   vl_api_l2_fib_clear_table_t *mp;
11067   int ret;
11068
11069   M (L2_FIB_CLEAR_TABLE, mp);
11070
11071   S (mp);
11072   W (ret);
11073   return ret;
11074 }
11075
11076 static int
11077 api_l2_interface_efp_filter (vat_main_t * vam)
11078 {
11079   unformat_input_t *i = vam->input;
11080   vl_api_l2_interface_efp_filter_t *mp;
11081   u32 sw_if_index;
11082   u8 enable = 1;
11083   u8 sw_if_index_set = 0;
11084   int ret;
11085
11086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11087     {
11088       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11089         sw_if_index_set = 1;
11090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11091         sw_if_index_set = 1;
11092       else if (unformat (i, "enable"))
11093         enable = 1;
11094       else if (unformat (i, "disable"))
11095         enable = 0;
11096       else
11097         {
11098           clib_warning ("parse error '%U'", format_unformat_error, i);
11099           return -99;
11100         }
11101     }
11102
11103   if (sw_if_index_set == 0)
11104     {
11105       errmsg ("missing sw_if_index");
11106       return -99;
11107     }
11108
11109   M (L2_INTERFACE_EFP_FILTER, mp);
11110
11111   mp->sw_if_index = ntohl (sw_if_index);
11112   mp->enable_disable = enable;
11113
11114   S (mp);
11115   W (ret);
11116   return ret;
11117 }
11118
11119 #define foreach_vtr_op                          \
11120 _("disable",  L2_VTR_DISABLED)                  \
11121 _("push-1",  L2_VTR_PUSH_1)                     \
11122 _("push-2",  L2_VTR_PUSH_2)                     \
11123 _("pop-1",  L2_VTR_POP_1)                       \
11124 _("pop-2",  L2_VTR_POP_2)                       \
11125 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11126 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11127 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11128 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11129
11130 static int
11131 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11132 {
11133   unformat_input_t *i = vam->input;
11134   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11135   u32 sw_if_index;
11136   u8 sw_if_index_set = 0;
11137   u8 vtr_op_set = 0;
11138   u32 vtr_op = 0;
11139   u32 push_dot1q = 1;
11140   u32 tag1 = ~0;
11141   u32 tag2 = ~0;
11142   int ret;
11143
11144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11145     {
11146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11147         sw_if_index_set = 1;
11148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11149         sw_if_index_set = 1;
11150       else if (unformat (i, "vtr_op %d", &vtr_op))
11151         vtr_op_set = 1;
11152 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11153       foreach_vtr_op
11154 #undef _
11155         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11156         ;
11157       else if (unformat (i, "tag1 %d", &tag1))
11158         ;
11159       else if (unformat (i, "tag2 %d", &tag2))
11160         ;
11161       else
11162         {
11163           clib_warning ("parse error '%U'", format_unformat_error, i);
11164           return -99;
11165         }
11166     }
11167
11168   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11169     {
11170       errmsg ("missing vtr operation or sw_if_index");
11171       return -99;
11172     }
11173
11174   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11175   mp->sw_if_index = ntohl (sw_if_index);
11176   mp->vtr_op = ntohl (vtr_op);
11177   mp->push_dot1q = ntohl (push_dot1q);
11178   mp->tag1 = ntohl (tag1);
11179   mp->tag2 = ntohl (tag2);
11180
11181   S (mp);
11182   W (ret);
11183   return ret;
11184 }
11185
11186 static int
11187 api_create_vhost_user_if (vat_main_t * vam)
11188 {
11189   unformat_input_t *i = vam->input;
11190   vl_api_create_vhost_user_if_t *mp;
11191   u8 *file_name;
11192   u8 is_server = 0;
11193   u8 file_name_set = 0;
11194   u32 custom_dev_instance = ~0;
11195   u8 hwaddr[6];
11196   u8 use_custom_mac = 0;
11197   u8 *tag = 0;
11198   int ret;
11199
11200   /* Shut up coverity */
11201   memset (hwaddr, 0, sizeof (hwaddr));
11202
11203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11204     {
11205       if (unformat (i, "socket %s", &file_name))
11206         {
11207           file_name_set = 1;
11208         }
11209       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11210         ;
11211       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11212         use_custom_mac = 1;
11213       else if (unformat (i, "server"))
11214         is_server = 1;
11215       else if (unformat (i, "tag %s", &tag))
11216         ;
11217       else
11218         break;
11219     }
11220
11221   if (file_name_set == 0)
11222     {
11223       errmsg ("missing socket file name");
11224       return -99;
11225     }
11226
11227   if (vec_len (file_name) > 255)
11228     {
11229       errmsg ("socket file name too long");
11230       return -99;
11231     }
11232   vec_add1 (file_name, 0);
11233
11234   M (CREATE_VHOST_USER_IF, mp);
11235
11236   mp->is_server = is_server;
11237   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11238   vec_free (file_name);
11239   if (custom_dev_instance != ~0)
11240     {
11241       mp->renumber = 1;
11242       mp->custom_dev_instance = ntohl (custom_dev_instance);
11243     }
11244   mp->use_custom_mac = use_custom_mac;
11245   clib_memcpy (mp->mac_address, hwaddr, 6);
11246   if (tag)
11247     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11248   vec_free (tag);
11249
11250   S (mp);
11251   W (ret);
11252   return ret;
11253 }
11254
11255 static int
11256 api_modify_vhost_user_if (vat_main_t * vam)
11257 {
11258   unformat_input_t *i = vam->input;
11259   vl_api_modify_vhost_user_if_t *mp;
11260   u8 *file_name;
11261   u8 is_server = 0;
11262   u8 file_name_set = 0;
11263   u32 custom_dev_instance = ~0;
11264   u8 sw_if_index_set = 0;
11265   u32 sw_if_index = (u32) ~ 0;
11266   int ret;
11267
11268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11269     {
11270       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11271         sw_if_index_set = 1;
11272       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11273         sw_if_index_set = 1;
11274       else if (unformat (i, "socket %s", &file_name))
11275         {
11276           file_name_set = 1;
11277         }
11278       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11279         ;
11280       else if (unformat (i, "server"))
11281         is_server = 1;
11282       else
11283         break;
11284     }
11285
11286   if (sw_if_index_set == 0)
11287     {
11288       errmsg ("missing sw_if_index or interface name");
11289       return -99;
11290     }
11291
11292   if (file_name_set == 0)
11293     {
11294       errmsg ("missing socket file name");
11295       return -99;
11296     }
11297
11298   if (vec_len (file_name) > 255)
11299     {
11300       errmsg ("socket file name too long");
11301       return -99;
11302     }
11303   vec_add1 (file_name, 0);
11304
11305   M (MODIFY_VHOST_USER_IF, mp);
11306
11307   mp->sw_if_index = ntohl (sw_if_index);
11308   mp->is_server = is_server;
11309   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11310   vec_free (file_name);
11311   if (custom_dev_instance != ~0)
11312     {
11313       mp->renumber = 1;
11314       mp->custom_dev_instance = ntohl (custom_dev_instance);
11315     }
11316
11317   S (mp);
11318   W (ret);
11319   return ret;
11320 }
11321
11322 static int
11323 api_delete_vhost_user_if (vat_main_t * vam)
11324 {
11325   unformat_input_t *i = vam->input;
11326   vl_api_delete_vhost_user_if_t *mp;
11327   u32 sw_if_index = ~0;
11328   u8 sw_if_index_set = 0;
11329   int ret;
11330
11331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11332     {
11333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11334         sw_if_index_set = 1;
11335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11336         sw_if_index_set = 1;
11337       else
11338         break;
11339     }
11340
11341   if (sw_if_index_set == 0)
11342     {
11343       errmsg ("missing sw_if_index or interface name");
11344       return -99;
11345     }
11346
11347
11348   M (DELETE_VHOST_USER_IF, mp);
11349
11350   mp->sw_if_index = ntohl (sw_if_index);
11351
11352   S (mp);
11353   W (ret);
11354   return ret;
11355 }
11356
11357 static void vl_api_sw_interface_vhost_user_details_t_handler
11358   (vl_api_sw_interface_vhost_user_details_t * mp)
11359 {
11360   vat_main_t *vam = &vat_main;
11361
11362   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11363          (char *) mp->interface_name,
11364          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11365          clib_net_to_host_u64 (mp->features), mp->is_server,
11366          ntohl (mp->num_regions), (char *) mp->sock_filename);
11367   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11368 }
11369
11370 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11371   (vl_api_sw_interface_vhost_user_details_t * mp)
11372 {
11373   vat_main_t *vam = &vat_main;
11374   vat_json_node_t *node = NULL;
11375
11376   if (VAT_JSON_ARRAY != vam->json_tree.type)
11377     {
11378       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11379       vat_json_init_array (&vam->json_tree);
11380     }
11381   node = vat_json_array_add (&vam->json_tree);
11382
11383   vat_json_init_object (node);
11384   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11385   vat_json_object_add_string_copy (node, "interface_name",
11386                                    mp->interface_name);
11387   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11388                             ntohl (mp->virtio_net_hdr_sz));
11389   vat_json_object_add_uint (node, "features",
11390                             clib_net_to_host_u64 (mp->features));
11391   vat_json_object_add_uint (node, "is_server", mp->is_server);
11392   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11393   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11394   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11395 }
11396
11397 static int
11398 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11399 {
11400   vl_api_sw_interface_vhost_user_dump_t *mp;
11401   int ret;
11402   print (vam->ofp,
11403          "Interface name           idx hdr_sz features server regions filename");
11404
11405   /* Get list of vhost-user interfaces */
11406   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11407   S (mp);
11408
11409   /* Use a control ping for synchronization */
11410   {
11411     vl_api_control_ping_t *mp;
11412     M (CONTROL_PING, mp);
11413     S (mp);
11414   }
11415   W (ret);
11416   return ret;
11417 }
11418
11419 static int
11420 api_show_version (vat_main_t * vam)
11421 {
11422   vl_api_show_version_t *mp;
11423   int ret;
11424
11425   M (SHOW_VERSION, mp);
11426
11427   S (mp);
11428   W (ret);
11429   return ret;
11430 }
11431
11432
11433 static int
11434 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11435 {
11436   unformat_input_t *line_input = vam->input;
11437   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11438   ip4_address_t local4, remote4;
11439   ip6_address_t local6, remote6;
11440   u8 is_add = 1;
11441   u8 ipv4_set = 0, ipv6_set = 0;
11442   u8 local_set = 0;
11443   u8 remote_set = 0;
11444   u32 encap_vrf_id = 0;
11445   u32 decap_vrf_id = 0;
11446   u8 protocol = ~0;
11447   u32 vni;
11448   u8 vni_set = 0;
11449   int ret;
11450
11451   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11452     {
11453       if (unformat (line_input, "del"))
11454         is_add = 0;
11455       else if (unformat (line_input, "local %U",
11456                          unformat_ip4_address, &local4))
11457         {
11458           local_set = 1;
11459           ipv4_set = 1;
11460         }
11461       else if (unformat (line_input, "remote %U",
11462                          unformat_ip4_address, &remote4))
11463         {
11464           remote_set = 1;
11465           ipv4_set = 1;
11466         }
11467       else if (unformat (line_input, "local %U",
11468                          unformat_ip6_address, &local6))
11469         {
11470           local_set = 1;
11471           ipv6_set = 1;
11472         }
11473       else if (unformat (line_input, "remote %U",
11474                          unformat_ip6_address, &remote6))
11475         {
11476           remote_set = 1;
11477           ipv6_set = 1;
11478         }
11479       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11480         ;
11481       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11482         ;
11483       else if (unformat (line_input, "vni %d", &vni))
11484         vni_set = 1;
11485       else if (unformat (line_input, "next-ip4"))
11486         protocol = 1;
11487       else if (unformat (line_input, "next-ip6"))
11488         protocol = 2;
11489       else if (unformat (line_input, "next-ethernet"))
11490         protocol = 3;
11491       else if (unformat (line_input, "next-nsh"))
11492         protocol = 4;
11493       else
11494         {
11495           errmsg ("parse error '%U'", format_unformat_error, line_input);
11496           return -99;
11497         }
11498     }
11499
11500   if (local_set == 0)
11501     {
11502       errmsg ("tunnel local address not specified");
11503       return -99;
11504     }
11505   if (remote_set == 0)
11506     {
11507       errmsg ("tunnel remote address not specified");
11508       return -99;
11509     }
11510   if (ipv4_set && ipv6_set)
11511     {
11512       errmsg ("both IPv4 and IPv6 addresses specified");
11513       return -99;
11514     }
11515
11516   if (vni_set == 0)
11517     {
11518       errmsg ("vni not specified");
11519       return -99;
11520     }
11521
11522   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11523
11524
11525   if (ipv6_set)
11526     {
11527       clib_memcpy (&mp->local, &local6, sizeof (local6));
11528       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11529     }
11530   else
11531     {
11532       clib_memcpy (&mp->local, &local4, sizeof (local4));
11533       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11534     }
11535
11536   mp->encap_vrf_id = ntohl (encap_vrf_id);
11537   mp->decap_vrf_id = ntohl (decap_vrf_id);
11538   mp->protocol = protocol;
11539   mp->vni = ntohl (vni);
11540   mp->is_add = is_add;
11541   mp->is_ipv6 = ipv6_set;
11542
11543   S (mp);
11544   W (ret);
11545   return ret;
11546 }
11547
11548 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11549   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11550 {
11551   vat_main_t *vam = &vat_main;
11552
11553   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11554          ntohl (mp->sw_if_index),
11555          format_ip46_address, &(mp->local[0]),
11556          format_ip46_address, &(mp->remote[0]),
11557          ntohl (mp->vni),
11558          ntohl (mp->protocol),
11559          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11560 }
11561
11562 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11563   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11564 {
11565   vat_main_t *vam = &vat_main;
11566   vat_json_node_t *node = NULL;
11567   struct in_addr ip4;
11568   struct in6_addr ip6;
11569
11570   if (VAT_JSON_ARRAY != vam->json_tree.type)
11571     {
11572       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11573       vat_json_init_array (&vam->json_tree);
11574     }
11575   node = vat_json_array_add (&vam->json_tree);
11576
11577   vat_json_init_object (node);
11578   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11579   if (mp->is_ipv6)
11580     {
11581       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11582       vat_json_object_add_ip6 (node, "local", ip6);
11583       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11584       vat_json_object_add_ip6 (node, "remote", ip6);
11585     }
11586   else
11587     {
11588       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11589       vat_json_object_add_ip4 (node, "local", ip4);
11590       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11591       vat_json_object_add_ip4 (node, "remote", ip4);
11592     }
11593   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11594   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11595   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11596   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11597   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11598 }
11599
11600 static int
11601 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11602 {
11603   unformat_input_t *i = vam->input;
11604   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11605   u32 sw_if_index;
11606   u8 sw_if_index_set = 0;
11607   int ret;
11608
11609   /* Parse args required to build the message */
11610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11611     {
11612       if (unformat (i, "sw_if_index %d", &sw_if_index))
11613         sw_if_index_set = 1;
11614       else
11615         break;
11616     }
11617
11618   if (sw_if_index_set == 0)
11619     {
11620       sw_if_index = ~0;
11621     }
11622
11623   if (!vam->json_output)
11624     {
11625       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11626              "sw_if_index", "local", "remote", "vni",
11627              "protocol", "encap_vrf_id", "decap_vrf_id");
11628     }
11629
11630   /* Get list of vxlan-tunnel interfaces */
11631   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11632
11633   mp->sw_if_index = htonl (sw_if_index);
11634
11635   S (mp);
11636
11637   /* Use a control ping for synchronization */
11638   {
11639     vl_api_control_ping_t *mp;
11640     M (CONTROL_PING, mp);
11641     S (mp);
11642   }
11643   W (ret);
11644   return ret;
11645 }
11646
11647 u8 *
11648 format_l2_fib_mac_address (u8 * s, va_list * args)
11649 {
11650   u8 *a = va_arg (*args, u8 *);
11651
11652   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11653                  a[2], a[3], a[4], a[5], a[6], a[7]);
11654 }
11655
11656 static void vl_api_l2_fib_table_entry_t_handler
11657   (vl_api_l2_fib_table_entry_t * mp)
11658 {
11659   vat_main_t *vam = &vat_main;
11660
11661   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11662          "       %d       %d     %d",
11663          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11664          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11665          mp->bvi_mac);
11666 }
11667
11668 static void vl_api_l2_fib_table_entry_t_handler_json
11669   (vl_api_l2_fib_table_entry_t * mp)
11670 {
11671   vat_main_t *vam = &vat_main;
11672   vat_json_node_t *node = NULL;
11673
11674   if (VAT_JSON_ARRAY != vam->json_tree.type)
11675     {
11676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11677       vat_json_init_array (&vam->json_tree);
11678     }
11679   node = vat_json_array_add (&vam->json_tree);
11680
11681   vat_json_init_object (node);
11682   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11683   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11684   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11685   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11686   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11687   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11688 }
11689
11690 static int
11691 api_l2_fib_table_dump (vat_main_t * vam)
11692 {
11693   unformat_input_t *i = vam->input;
11694   vl_api_l2_fib_table_dump_t *mp;
11695   u32 bd_id;
11696   u8 bd_id_set = 0;
11697   int ret;
11698
11699   /* Parse args required to build the message */
11700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11701     {
11702       if (unformat (i, "bd_id %d", &bd_id))
11703         bd_id_set = 1;
11704       else
11705         break;
11706     }
11707
11708   if (bd_id_set == 0)
11709     {
11710       errmsg ("missing bridge domain");
11711       return -99;
11712     }
11713
11714   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11715
11716   /* Get list of l2 fib entries */
11717   M (L2_FIB_TABLE_DUMP, mp);
11718
11719   mp->bd_id = ntohl (bd_id);
11720   S (mp);
11721
11722   /* Use a control ping for synchronization */
11723   {
11724     vl_api_control_ping_t *mp;
11725     M (CONTROL_PING, mp);
11726     S (mp);
11727   }
11728   W (ret);
11729   return ret;
11730 }
11731
11732
11733 static int
11734 api_interface_name_renumber (vat_main_t * vam)
11735 {
11736   unformat_input_t *line_input = vam->input;
11737   vl_api_interface_name_renumber_t *mp;
11738   u32 sw_if_index = ~0;
11739   u32 new_show_dev_instance = ~0;
11740   int ret;
11741
11742   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11743     {
11744       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11745                     &sw_if_index))
11746         ;
11747       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11748         ;
11749       else if (unformat (line_input, "new_show_dev_instance %d",
11750                          &new_show_dev_instance))
11751         ;
11752       else
11753         break;
11754     }
11755
11756   if (sw_if_index == ~0)
11757     {
11758       errmsg ("missing interface name or sw_if_index");
11759       return -99;
11760     }
11761
11762   if (new_show_dev_instance == ~0)
11763     {
11764       errmsg ("missing new_show_dev_instance");
11765       return -99;
11766     }
11767
11768   M (INTERFACE_NAME_RENUMBER, mp);
11769
11770   mp->sw_if_index = ntohl (sw_if_index);
11771   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11772
11773   S (mp);
11774   W (ret);
11775   return ret;
11776 }
11777
11778 static int
11779 api_want_ip4_arp_events (vat_main_t * vam)
11780 {
11781   unformat_input_t *line_input = vam->input;
11782   vl_api_want_ip4_arp_events_t *mp;
11783   ip4_address_t address;
11784   int address_set = 0;
11785   u32 enable_disable = 1;
11786   int ret;
11787
11788   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11789     {
11790       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11791         address_set = 1;
11792       else if (unformat (line_input, "del"))
11793         enable_disable = 0;
11794       else
11795         break;
11796     }
11797
11798   if (address_set == 0)
11799     {
11800       errmsg ("missing addresses");
11801       return -99;
11802     }
11803
11804   M (WANT_IP4_ARP_EVENTS, mp);
11805   mp->enable_disable = enable_disable;
11806   mp->pid = getpid ();
11807   mp->address = address.as_u32;
11808
11809   S (mp);
11810   W (ret);
11811   return ret;
11812 }
11813
11814 static int
11815 api_want_ip6_nd_events (vat_main_t * vam)
11816 {
11817   unformat_input_t *line_input = vam->input;
11818   vl_api_want_ip6_nd_events_t *mp;
11819   ip6_address_t address;
11820   int address_set = 0;
11821   u32 enable_disable = 1;
11822   int ret;
11823
11824   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11825     {
11826       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11827         address_set = 1;
11828       else if (unformat (line_input, "del"))
11829         enable_disable = 0;
11830       else
11831         break;
11832     }
11833
11834   if (address_set == 0)
11835     {
11836       errmsg ("missing addresses");
11837       return -99;
11838     }
11839
11840   M (WANT_IP6_ND_EVENTS, mp);
11841   mp->enable_disable = enable_disable;
11842   mp->pid = getpid ();
11843   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11844
11845   S (mp);
11846   W (ret);
11847   return ret;
11848 }
11849
11850 static int
11851 api_input_acl_set_interface (vat_main_t * vam)
11852 {
11853   unformat_input_t *i = vam->input;
11854   vl_api_input_acl_set_interface_t *mp;
11855   u32 sw_if_index;
11856   int sw_if_index_set;
11857   u32 ip4_table_index = ~0;
11858   u32 ip6_table_index = ~0;
11859   u32 l2_table_index = ~0;
11860   u8 is_add = 1;
11861   int ret;
11862
11863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11864     {
11865       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11866         sw_if_index_set = 1;
11867       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11868         sw_if_index_set = 1;
11869       else if (unformat (i, "del"))
11870         is_add = 0;
11871       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11872         ;
11873       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11874         ;
11875       else if (unformat (i, "l2-table %d", &l2_table_index))
11876         ;
11877       else
11878         {
11879           clib_warning ("parse error '%U'", format_unformat_error, i);
11880           return -99;
11881         }
11882     }
11883
11884   if (sw_if_index_set == 0)
11885     {
11886       errmsg ("missing interface name or sw_if_index");
11887       return -99;
11888     }
11889
11890   M (INPUT_ACL_SET_INTERFACE, mp);
11891
11892   mp->sw_if_index = ntohl (sw_if_index);
11893   mp->ip4_table_index = ntohl (ip4_table_index);
11894   mp->ip6_table_index = ntohl (ip6_table_index);
11895   mp->l2_table_index = ntohl (l2_table_index);
11896   mp->is_add = is_add;
11897
11898   S (mp);
11899   W (ret);
11900   return ret;
11901 }
11902
11903 static int
11904 api_ip_address_dump (vat_main_t * vam)
11905 {
11906   unformat_input_t *i = vam->input;
11907   vl_api_ip_address_dump_t *mp;
11908   u32 sw_if_index = ~0;
11909   u8 sw_if_index_set = 0;
11910   u8 ipv4_set = 0;
11911   u8 ipv6_set = 0;
11912   int ret;
11913
11914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11915     {
11916       if (unformat (i, "sw_if_index %d", &sw_if_index))
11917         sw_if_index_set = 1;
11918       else
11919         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11920         sw_if_index_set = 1;
11921       else if (unformat (i, "ipv4"))
11922         ipv4_set = 1;
11923       else if (unformat (i, "ipv6"))
11924         ipv6_set = 1;
11925       else
11926         break;
11927     }
11928
11929   if (ipv4_set && ipv6_set)
11930     {
11931       errmsg ("ipv4 and ipv6 flags cannot be both set");
11932       return -99;
11933     }
11934
11935   if ((!ipv4_set) && (!ipv6_set))
11936     {
11937       errmsg ("no ipv4 nor ipv6 flag set");
11938       return -99;
11939     }
11940
11941   if (sw_if_index_set == 0)
11942     {
11943       errmsg ("missing interface name or sw_if_index");
11944       return -99;
11945     }
11946
11947   vam->current_sw_if_index = sw_if_index;
11948   vam->is_ipv6 = ipv6_set;
11949
11950   M (IP_ADDRESS_DUMP, mp);
11951   mp->sw_if_index = ntohl (sw_if_index);
11952   mp->is_ipv6 = ipv6_set;
11953   S (mp);
11954
11955   /* Use a control ping for synchronization */
11956   {
11957     vl_api_control_ping_t *mp;
11958     M (CONTROL_PING, mp);
11959     S (mp);
11960   }
11961   W (ret);
11962   return ret;
11963 }
11964
11965 static int
11966 api_ip_dump (vat_main_t * vam)
11967 {
11968   vl_api_ip_dump_t *mp;
11969   unformat_input_t *in = vam->input;
11970   int ipv4_set = 0;
11971   int ipv6_set = 0;
11972   int is_ipv6;
11973   int i;
11974   int ret;
11975
11976   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11977     {
11978       if (unformat (in, "ipv4"))
11979         ipv4_set = 1;
11980       else if (unformat (in, "ipv6"))
11981         ipv6_set = 1;
11982       else
11983         break;
11984     }
11985
11986   if (ipv4_set && ipv6_set)
11987     {
11988       errmsg ("ipv4 and ipv6 flags cannot be both set");
11989       return -99;
11990     }
11991
11992   if ((!ipv4_set) && (!ipv6_set))
11993     {
11994       errmsg ("no ipv4 nor ipv6 flag set");
11995       return -99;
11996     }
11997
11998   is_ipv6 = ipv6_set;
11999   vam->is_ipv6 = is_ipv6;
12000
12001   /* free old data */
12002   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12003     {
12004       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12005     }
12006   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12007
12008   M (IP_DUMP, mp);
12009   mp->is_ipv6 = ipv6_set;
12010   S (mp);
12011
12012   /* Use a control ping for synchronization */
12013   {
12014     vl_api_control_ping_t *mp;
12015     M (CONTROL_PING, mp);
12016     S (mp);
12017   }
12018   W (ret);
12019   return ret;
12020 }
12021
12022 static int
12023 api_ipsec_spd_add_del (vat_main_t * vam)
12024 {
12025   unformat_input_t *i = vam->input;
12026   vl_api_ipsec_spd_add_del_t *mp;
12027   u32 spd_id = ~0;
12028   u8 is_add = 1;
12029   int ret;
12030
12031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12032     {
12033       if (unformat (i, "spd_id %d", &spd_id))
12034         ;
12035       else if (unformat (i, "del"))
12036         is_add = 0;
12037       else
12038         {
12039           clib_warning ("parse error '%U'", format_unformat_error, i);
12040           return -99;
12041         }
12042     }
12043   if (spd_id == ~0)
12044     {
12045       errmsg ("spd_id must be set");
12046       return -99;
12047     }
12048
12049   M (IPSEC_SPD_ADD_DEL, mp);
12050
12051   mp->spd_id = ntohl (spd_id);
12052   mp->is_add = is_add;
12053
12054   S (mp);
12055   W (ret);
12056   return ret;
12057 }
12058
12059 static int
12060 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12061 {
12062   unformat_input_t *i = vam->input;
12063   vl_api_ipsec_interface_add_del_spd_t *mp;
12064   u32 sw_if_index;
12065   u8 sw_if_index_set = 0;
12066   u32 spd_id = (u32) ~ 0;
12067   u8 is_add = 1;
12068   int ret;
12069
12070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12071     {
12072       if (unformat (i, "del"))
12073         is_add = 0;
12074       else if (unformat (i, "spd_id %d", &spd_id))
12075         ;
12076       else
12077         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12078         sw_if_index_set = 1;
12079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12080         sw_if_index_set = 1;
12081       else
12082         {
12083           clib_warning ("parse error '%U'", format_unformat_error, i);
12084           return -99;
12085         }
12086
12087     }
12088
12089   if (spd_id == (u32) ~ 0)
12090     {
12091       errmsg ("spd_id must be set");
12092       return -99;
12093     }
12094
12095   if (sw_if_index_set == 0)
12096     {
12097       errmsg ("missing interface name or sw_if_index");
12098       return -99;
12099     }
12100
12101   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12102
12103   mp->spd_id = ntohl (spd_id);
12104   mp->sw_if_index = ntohl (sw_if_index);
12105   mp->is_add = is_add;
12106
12107   S (mp);
12108   W (ret);
12109   return ret;
12110 }
12111
12112 static int
12113 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12114 {
12115   unformat_input_t *i = vam->input;
12116   vl_api_ipsec_spd_add_del_entry_t *mp;
12117   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12118   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12119   i32 priority = 0;
12120   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12121   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12122   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12123   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12124   int ret;
12125
12126   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12127   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12128   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12129   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12130   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12131   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12132
12133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12134     {
12135       if (unformat (i, "del"))
12136         is_add = 0;
12137       if (unformat (i, "outbound"))
12138         is_outbound = 1;
12139       if (unformat (i, "inbound"))
12140         is_outbound = 0;
12141       else if (unformat (i, "spd_id %d", &spd_id))
12142         ;
12143       else if (unformat (i, "sa_id %d", &sa_id))
12144         ;
12145       else if (unformat (i, "priority %d", &priority))
12146         ;
12147       else if (unformat (i, "protocol %d", &protocol))
12148         ;
12149       else if (unformat (i, "lport_start %d", &lport_start))
12150         ;
12151       else if (unformat (i, "lport_stop %d", &lport_stop))
12152         ;
12153       else if (unformat (i, "rport_start %d", &rport_start))
12154         ;
12155       else if (unformat (i, "rport_stop %d", &rport_stop))
12156         ;
12157       else
12158         if (unformat
12159             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12160         {
12161           is_ipv6 = 0;
12162           is_ip_any = 0;
12163         }
12164       else
12165         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12166         {
12167           is_ipv6 = 0;
12168           is_ip_any = 0;
12169         }
12170       else
12171         if (unformat
12172             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12173         {
12174           is_ipv6 = 0;
12175           is_ip_any = 0;
12176         }
12177       else
12178         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12179         {
12180           is_ipv6 = 0;
12181           is_ip_any = 0;
12182         }
12183       else
12184         if (unformat
12185             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12186         {
12187           is_ipv6 = 1;
12188           is_ip_any = 0;
12189         }
12190       else
12191         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12192         {
12193           is_ipv6 = 1;
12194           is_ip_any = 0;
12195         }
12196       else
12197         if (unformat
12198             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12199         {
12200           is_ipv6 = 1;
12201           is_ip_any = 0;
12202         }
12203       else
12204         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12205         {
12206           is_ipv6 = 1;
12207           is_ip_any = 0;
12208         }
12209       else
12210         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12211         {
12212           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12213             {
12214               clib_warning ("unsupported action: 'resolve'");
12215               return -99;
12216             }
12217         }
12218       else
12219         {
12220           clib_warning ("parse error '%U'", format_unformat_error, i);
12221           return -99;
12222         }
12223
12224     }
12225
12226   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12227
12228   mp->spd_id = ntohl (spd_id);
12229   mp->priority = ntohl (priority);
12230   mp->is_outbound = is_outbound;
12231
12232   mp->is_ipv6 = is_ipv6;
12233   if (is_ipv6 || is_ip_any)
12234     {
12235       clib_memcpy (mp->remote_address_start, &raddr6_start,
12236                    sizeof (ip6_address_t));
12237       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12238                    sizeof (ip6_address_t));
12239       clib_memcpy (mp->local_address_start, &laddr6_start,
12240                    sizeof (ip6_address_t));
12241       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12242                    sizeof (ip6_address_t));
12243     }
12244   else
12245     {
12246       clib_memcpy (mp->remote_address_start, &raddr4_start,
12247                    sizeof (ip4_address_t));
12248       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12249                    sizeof (ip4_address_t));
12250       clib_memcpy (mp->local_address_start, &laddr4_start,
12251                    sizeof (ip4_address_t));
12252       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12253                    sizeof (ip4_address_t));
12254     }
12255   mp->protocol = (u8) protocol;
12256   mp->local_port_start = ntohs ((u16) lport_start);
12257   mp->local_port_stop = ntohs ((u16) lport_stop);
12258   mp->remote_port_start = ntohs ((u16) rport_start);
12259   mp->remote_port_stop = ntohs ((u16) rport_stop);
12260   mp->policy = (u8) policy;
12261   mp->sa_id = ntohl (sa_id);
12262   mp->is_add = is_add;
12263   mp->is_ip_any = is_ip_any;
12264   S (mp);
12265   W (ret);
12266   return ret;
12267 }
12268
12269 static int
12270 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12271 {
12272   unformat_input_t *i = vam->input;
12273   vl_api_ipsec_sad_add_del_entry_t *mp;
12274   u32 sad_id = 0, spi = 0;
12275   u8 *ck = 0, *ik = 0;
12276   u8 is_add = 1;
12277
12278   u8 protocol = IPSEC_PROTOCOL_AH;
12279   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12280   u32 crypto_alg = 0, integ_alg = 0;
12281   ip4_address_t tun_src4;
12282   ip4_address_t tun_dst4;
12283   ip6_address_t tun_src6;
12284   ip6_address_t tun_dst6;
12285   int ret;
12286
12287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12288     {
12289       if (unformat (i, "del"))
12290         is_add = 0;
12291       else if (unformat (i, "sad_id %d", &sad_id))
12292         ;
12293       else if (unformat (i, "spi %d", &spi))
12294         ;
12295       else if (unformat (i, "esp"))
12296         protocol = IPSEC_PROTOCOL_ESP;
12297       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12298         {
12299           is_tunnel = 1;
12300           is_tunnel_ipv6 = 0;
12301         }
12302       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12303         {
12304           is_tunnel = 1;
12305           is_tunnel_ipv6 = 0;
12306         }
12307       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12308         {
12309           is_tunnel = 1;
12310           is_tunnel_ipv6 = 1;
12311         }
12312       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12313         {
12314           is_tunnel = 1;
12315           is_tunnel_ipv6 = 1;
12316         }
12317       else
12318         if (unformat
12319             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12320         {
12321           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12322               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12323             {
12324               clib_warning ("unsupported crypto-alg: '%U'",
12325                             format_ipsec_crypto_alg, crypto_alg);
12326               return -99;
12327             }
12328         }
12329       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12330         ;
12331       else
12332         if (unformat
12333             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12334         {
12335           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12336               integ_alg >= IPSEC_INTEG_N_ALG)
12337             {
12338               clib_warning ("unsupported integ-alg: '%U'",
12339                             format_ipsec_integ_alg, integ_alg);
12340               return -99;
12341             }
12342         }
12343       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12344         ;
12345       else
12346         {
12347           clib_warning ("parse error '%U'", format_unformat_error, i);
12348           return -99;
12349         }
12350
12351     }
12352
12353   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12354
12355   mp->sad_id = ntohl (sad_id);
12356   mp->is_add = is_add;
12357   mp->protocol = protocol;
12358   mp->spi = ntohl (spi);
12359   mp->is_tunnel = is_tunnel;
12360   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12361   mp->crypto_algorithm = crypto_alg;
12362   mp->integrity_algorithm = integ_alg;
12363   mp->crypto_key_length = vec_len (ck);
12364   mp->integrity_key_length = vec_len (ik);
12365
12366   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12367     mp->crypto_key_length = sizeof (mp->crypto_key);
12368
12369   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12370     mp->integrity_key_length = sizeof (mp->integrity_key);
12371
12372   if (ck)
12373     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12374   if (ik)
12375     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12376
12377   if (is_tunnel)
12378     {
12379       if (is_tunnel_ipv6)
12380         {
12381           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12382                        sizeof (ip6_address_t));
12383           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12384                        sizeof (ip6_address_t));
12385         }
12386       else
12387         {
12388           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12389                        sizeof (ip4_address_t));
12390           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12391                        sizeof (ip4_address_t));
12392         }
12393     }
12394
12395   S (mp);
12396   W (ret);
12397   return ret;
12398 }
12399
12400 static int
12401 api_ipsec_sa_set_key (vat_main_t * vam)
12402 {
12403   unformat_input_t *i = vam->input;
12404   vl_api_ipsec_sa_set_key_t *mp;
12405   u32 sa_id;
12406   u8 *ck = 0, *ik = 0;
12407   int ret;
12408
12409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12410     {
12411       if (unformat (i, "sa_id %d", &sa_id))
12412         ;
12413       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12414         ;
12415       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12416         ;
12417       else
12418         {
12419           clib_warning ("parse error '%U'", format_unformat_error, i);
12420           return -99;
12421         }
12422     }
12423
12424   M (IPSEC_SA_SET_KEY, mp);
12425
12426   mp->sa_id = ntohl (sa_id);
12427   mp->crypto_key_length = vec_len (ck);
12428   mp->integrity_key_length = vec_len (ik);
12429
12430   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12431     mp->crypto_key_length = sizeof (mp->crypto_key);
12432
12433   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12434     mp->integrity_key_length = sizeof (mp->integrity_key);
12435
12436   if (ck)
12437     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12438   if (ik)
12439     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12440
12441   S (mp);
12442   W (ret);
12443   return ret;
12444 }
12445
12446 static int
12447 api_ikev2_profile_add_del (vat_main_t * vam)
12448 {
12449   unformat_input_t *i = vam->input;
12450   vl_api_ikev2_profile_add_del_t *mp;
12451   u8 is_add = 1;
12452   u8 *name = 0;
12453   int ret;
12454
12455   const char *valid_chars = "a-zA-Z0-9_";
12456
12457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12458     {
12459       if (unformat (i, "del"))
12460         is_add = 0;
12461       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12462         vec_add1 (name, 0);
12463       else
12464         {
12465           errmsg ("parse error '%U'", format_unformat_error, i);
12466           return -99;
12467         }
12468     }
12469
12470   if (!vec_len (name))
12471     {
12472       errmsg ("profile name must be specified");
12473       return -99;
12474     }
12475
12476   if (vec_len (name) > 64)
12477     {
12478       errmsg ("profile name too long");
12479       return -99;
12480     }
12481
12482   M (IKEV2_PROFILE_ADD_DEL, mp);
12483
12484   clib_memcpy (mp->name, name, vec_len (name));
12485   mp->is_add = is_add;
12486   vec_free (name);
12487
12488   S (mp);
12489   W (ret);
12490   return ret;
12491 }
12492
12493 static int
12494 api_ikev2_profile_set_auth (vat_main_t * vam)
12495 {
12496   unformat_input_t *i = vam->input;
12497   vl_api_ikev2_profile_set_auth_t *mp;
12498   u8 *name = 0;
12499   u8 *data = 0;
12500   u32 auth_method = 0;
12501   u8 is_hex = 0;
12502   int ret;
12503
12504   const char *valid_chars = "a-zA-Z0-9_";
12505
12506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12507     {
12508       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12509         vec_add1 (name, 0);
12510       else if (unformat (i, "auth_method %U",
12511                          unformat_ikev2_auth_method, &auth_method))
12512         ;
12513       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12514         is_hex = 1;
12515       else if (unformat (i, "auth_data %v", &data))
12516         ;
12517       else
12518         {
12519           errmsg ("parse error '%U'", format_unformat_error, i);
12520           return -99;
12521         }
12522     }
12523
12524   if (!vec_len (name))
12525     {
12526       errmsg ("profile name must be specified");
12527       return -99;
12528     }
12529
12530   if (vec_len (name) > 64)
12531     {
12532       errmsg ("profile name too long");
12533       return -99;
12534     }
12535
12536   if (!vec_len (data))
12537     {
12538       errmsg ("auth_data must be specified");
12539       return -99;
12540     }
12541
12542   if (!auth_method)
12543     {
12544       errmsg ("auth_method must be specified");
12545       return -99;
12546     }
12547
12548   M (IKEV2_PROFILE_SET_AUTH, mp);
12549
12550   mp->is_hex = is_hex;
12551   mp->auth_method = (u8) auth_method;
12552   mp->data_len = vec_len (data);
12553   clib_memcpy (mp->name, name, vec_len (name));
12554   clib_memcpy (mp->data, data, vec_len (data));
12555   vec_free (name);
12556   vec_free (data);
12557
12558   S (mp);
12559   W (ret);
12560   return ret;
12561 }
12562
12563 static int
12564 api_ikev2_profile_set_id (vat_main_t * vam)
12565 {
12566   unformat_input_t *i = vam->input;
12567   vl_api_ikev2_profile_set_id_t *mp;
12568   u8 *name = 0;
12569   u8 *data = 0;
12570   u8 is_local = 0;
12571   u32 id_type = 0;
12572   ip4_address_t ip4;
12573   int ret;
12574
12575   const char *valid_chars = "a-zA-Z0-9_";
12576
12577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12578     {
12579       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12580         vec_add1 (name, 0);
12581       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12582         ;
12583       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12584         {
12585           data = vec_new (u8, 4);
12586           clib_memcpy (data, ip4.as_u8, 4);
12587         }
12588       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12589         ;
12590       else if (unformat (i, "id_data %v", &data))
12591         ;
12592       else if (unformat (i, "local"))
12593         is_local = 1;
12594       else if (unformat (i, "remote"))
12595         is_local = 0;
12596       else
12597         {
12598           errmsg ("parse error '%U'", format_unformat_error, i);
12599           return -99;
12600         }
12601     }
12602
12603   if (!vec_len (name))
12604     {
12605       errmsg ("profile name must be specified");
12606       return -99;
12607     }
12608
12609   if (vec_len (name) > 64)
12610     {
12611       errmsg ("profile name too long");
12612       return -99;
12613     }
12614
12615   if (!vec_len (data))
12616     {
12617       errmsg ("id_data must be specified");
12618       return -99;
12619     }
12620
12621   if (!id_type)
12622     {
12623       errmsg ("id_type must be specified");
12624       return -99;
12625     }
12626
12627   M (IKEV2_PROFILE_SET_ID, mp);
12628
12629   mp->is_local = is_local;
12630   mp->id_type = (u8) id_type;
12631   mp->data_len = vec_len (data);
12632   clib_memcpy (mp->name, name, vec_len (name));
12633   clib_memcpy (mp->data, data, vec_len (data));
12634   vec_free (name);
12635   vec_free (data);
12636
12637   S (mp);
12638   W (ret);
12639   return ret;
12640 }
12641
12642 static int
12643 api_ikev2_profile_set_ts (vat_main_t * vam)
12644 {
12645   unformat_input_t *i = vam->input;
12646   vl_api_ikev2_profile_set_ts_t *mp;
12647   u8 *name = 0;
12648   u8 is_local = 0;
12649   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12650   ip4_address_t start_addr, end_addr;
12651
12652   const char *valid_chars = "a-zA-Z0-9_";
12653   int ret;
12654
12655   start_addr.as_u32 = 0;
12656   end_addr.as_u32 = (u32) ~ 0;
12657
12658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12659     {
12660       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12661         vec_add1 (name, 0);
12662       else if (unformat (i, "protocol %d", &proto))
12663         ;
12664       else if (unformat (i, "start_port %d", &start_port))
12665         ;
12666       else if (unformat (i, "end_port %d", &end_port))
12667         ;
12668       else
12669         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12670         ;
12671       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12672         ;
12673       else if (unformat (i, "local"))
12674         is_local = 1;
12675       else if (unformat (i, "remote"))
12676         is_local = 0;
12677       else
12678         {
12679           errmsg ("parse error '%U'", format_unformat_error, i);
12680           return -99;
12681         }
12682     }
12683
12684   if (!vec_len (name))
12685     {
12686       errmsg ("profile name must be specified");
12687       return -99;
12688     }
12689
12690   if (vec_len (name) > 64)
12691     {
12692       errmsg ("profile name too long");
12693       return -99;
12694     }
12695
12696   M (IKEV2_PROFILE_SET_TS, mp);
12697
12698   mp->is_local = is_local;
12699   mp->proto = (u8) proto;
12700   mp->start_port = (u16) start_port;
12701   mp->end_port = (u16) end_port;
12702   mp->start_addr = start_addr.as_u32;
12703   mp->end_addr = end_addr.as_u32;
12704   clib_memcpy (mp->name, name, vec_len (name));
12705   vec_free (name);
12706
12707   S (mp);
12708   W (ret);
12709   return ret;
12710 }
12711
12712 static int
12713 api_ikev2_set_local_key (vat_main_t * vam)
12714 {
12715   unformat_input_t *i = vam->input;
12716   vl_api_ikev2_set_local_key_t *mp;
12717   u8 *file = 0;
12718   int ret;
12719
12720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12721     {
12722       if (unformat (i, "file %v", &file))
12723         vec_add1 (file, 0);
12724       else
12725         {
12726           errmsg ("parse error '%U'", format_unformat_error, i);
12727           return -99;
12728         }
12729     }
12730
12731   if (!vec_len (file))
12732     {
12733       errmsg ("RSA key file must be specified");
12734       return -99;
12735     }
12736
12737   if (vec_len (file) > 256)
12738     {
12739       errmsg ("file name too long");
12740       return -99;
12741     }
12742
12743   M (IKEV2_SET_LOCAL_KEY, mp);
12744
12745   clib_memcpy (mp->key_file, file, vec_len (file));
12746   vec_free (file);
12747
12748   S (mp);
12749   W (ret);
12750   return ret;
12751 }
12752
12753 /*
12754  * MAP
12755  */
12756 static int
12757 api_map_add_domain (vat_main_t * vam)
12758 {
12759   unformat_input_t *i = vam->input;
12760   vl_api_map_add_domain_t *mp;
12761
12762   ip4_address_t ip4_prefix;
12763   ip6_address_t ip6_prefix;
12764   ip6_address_t ip6_src;
12765   u32 num_m_args = 0;
12766   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12767     0, psid_length = 0;
12768   u8 is_translation = 0;
12769   u32 mtu = 0;
12770   u32 ip6_src_len = 128;
12771   int ret;
12772
12773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12774     {
12775       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12776                     &ip4_prefix, &ip4_prefix_len))
12777         num_m_args++;
12778       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12779                          &ip6_prefix, &ip6_prefix_len))
12780         num_m_args++;
12781       else
12782         if (unformat
12783             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12784              &ip6_src_len))
12785         num_m_args++;
12786       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12787         num_m_args++;
12788       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12789         num_m_args++;
12790       else if (unformat (i, "psid-offset %d", &psid_offset))
12791         num_m_args++;
12792       else if (unformat (i, "psid-len %d", &psid_length))
12793         num_m_args++;
12794       else if (unformat (i, "mtu %d", &mtu))
12795         num_m_args++;
12796       else if (unformat (i, "map-t"))
12797         is_translation = 1;
12798       else
12799         {
12800           clib_warning ("parse error '%U'", format_unformat_error, i);
12801           return -99;
12802         }
12803     }
12804
12805   if (num_m_args < 3)
12806     {
12807       errmsg ("mandatory argument(s) missing");
12808       return -99;
12809     }
12810
12811   /* Construct the API message */
12812   M (MAP_ADD_DOMAIN, mp);
12813
12814   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12815   mp->ip4_prefix_len = ip4_prefix_len;
12816
12817   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12818   mp->ip6_prefix_len = ip6_prefix_len;
12819
12820   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12821   mp->ip6_src_prefix_len = ip6_src_len;
12822
12823   mp->ea_bits_len = ea_bits_len;
12824   mp->psid_offset = psid_offset;
12825   mp->psid_length = psid_length;
12826   mp->is_translation = is_translation;
12827   mp->mtu = htons (mtu);
12828
12829   /* send it... */
12830   S (mp);
12831
12832   /* Wait for a reply, return good/bad news  */
12833   W (ret);
12834   return ret;
12835 }
12836
12837 static int
12838 api_map_del_domain (vat_main_t * vam)
12839 {
12840   unformat_input_t *i = vam->input;
12841   vl_api_map_del_domain_t *mp;
12842
12843   u32 num_m_args = 0;
12844   u32 index;
12845   int ret;
12846
12847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12848     {
12849       if (unformat (i, "index %d", &index))
12850         num_m_args++;
12851       else
12852         {
12853           clib_warning ("parse error '%U'", format_unformat_error, i);
12854           return -99;
12855         }
12856     }
12857
12858   if (num_m_args != 1)
12859     {
12860       errmsg ("mandatory argument(s) missing");
12861       return -99;
12862     }
12863
12864   /* Construct the API message */
12865   M (MAP_DEL_DOMAIN, mp);
12866
12867   mp->index = ntohl (index);
12868
12869   /* send it... */
12870   S (mp);
12871
12872   /* Wait for a reply, return good/bad news  */
12873   W (ret);
12874   return ret;
12875 }
12876
12877 static int
12878 api_map_add_del_rule (vat_main_t * vam)
12879 {
12880   unformat_input_t *i = vam->input;
12881   vl_api_map_add_del_rule_t *mp;
12882   u8 is_add = 1;
12883   ip6_address_t ip6_dst;
12884   u32 num_m_args = 0, index, psid = 0;
12885   int ret;
12886
12887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12888     {
12889       if (unformat (i, "index %d", &index))
12890         num_m_args++;
12891       else if (unformat (i, "psid %d", &psid))
12892         num_m_args++;
12893       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12894         num_m_args++;
12895       else if (unformat (i, "del"))
12896         {
12897           is_add = 0;
12898         }
12899       else
12900         {
12901           clib_warning ("parse error '%U'", format_unformat_error, i);
12902           return -99;
12903         }
12904     }
12905
12906   /* Construct the API message */
12907   M (MAP_ADD_DEL_RULE, mp);
12908
12909   mp->index = ntohl (index);
12910   mp->is_add = is_add;
12911   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12912   mp->psid = ntohs (psid);
12913
12914   /* send it... */
12915   S (mp);
12916
12917   /* Wait for a reply, return good/bad news  */
12918   W (ret);
12919   return ret;
12920 }
12921
12922 static int
12923 api_map_domain_dump (vat_main_t * vam)
12924 {
12925   vl_api_map_domain_dump_t *mp;
12926   int ret;
12927
12928   /* Construct the API message */
12929   M (MAP_DOMAIN_DUMP, mp);
12930
12931   /* send it... */
12932   S (mp);
12933
12934   /* Use a control ping for synchronization */
12935   {
12936     vl_api_control_ping_t *mp;
12937     M (CONTROL_PING, mp);
12938     S (mp);
12939   }
12940   W (ret);
12941   return ret;
12942 }
12943
12944 static int
12945 api_map_rule_dump (vat_main_t * vam)
12946 {
12947   unformat_input_t *i = vam->input;
12948   vl_api_map_rule_dump_t *mp;
12949   u32 domain_index = ~0;
12950   int ret;
12951
12952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12953     {
12954       if (unformat (i, "index %u", &domain_index))
12955         ;
12956       else
12957         break;
12958     }
12959
12960   if (domain_index == ~0)
12961     {
12962       clib_warning ("parse error: domain index expected");
12963       return -99;
12964     }
12965
12966   /* Construct the API message */
12967   M (MAP_RULE_DUMP, mp);
12968
12969   mp->domain_index = htonl (domain_index);
12970
12971   /* send it... */
12972   S (mp);
12973
12974   /* Use a control ping for synchronization */
12975   {
12976     vl_api_control_ping_t *mp;
12977     M (CONTROL_PING, mp);
12978     S (mp);
12979   }
12980   W (ret);
12981   return ret;
12982 }
12983
12984 static void vl_api_map_add_domain_reply_t_handler
12985   (vl_api_map_add_domain_reply_t * mp)
12986 {
12987   vat_main_t *vam = &vat_main;
12988   i32 retval = ntohl (mp->retval);
12989
12990   if (vam->async_mode)
12991     {
12992       vam->async_errors += (retval < 0);
12993     }
12994   else
12995     {
12996       vam->retval = retval;
12997       vam->result_ready = 1;
12998     }
12999 }
13000
13001 static void vl_api_map_add_domain_reply_t_handler_json
13002   (vl_api_map_add_domain_reply_t * mp)
13003 {
13004   vat_main_t *vam = &vat_main;
13005   vat_json_node_t node;
13006
13007   vat_json_init_object (&node);
13008   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13009   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13010
13011   vat_json_print (vam->ofp, &node);
13012   vat_json_free (&node);
13013
13014   vam->retval = ntohl (mp->retval);
13015   vam->result_ready = 1;
13016 }
13017
13018 static int
13019 api_get_first_msg_id (vat_main_t * vam)
13020 {
13021   vl_api_get_first_msg_id_t *mp;
13022   unformat_input_t *i = vam->input;
13023   u8 *name;
13024   u8 name_set = 0;
13025   int ret;
13026
13027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13028     {
13029       if (unformat (i, "client %s", &name))
13030         name_set = 1;
13031       else
13032         break;
13033     }
13034
13035   if (name_set == 0)
13036     {
13037       errmsg ("missing client name");
13038       return -99;
13039     }
13040   vec_add1 (name, 0);
13041
13042   if (vec_len (name) > 63)
13043     {
13044       errmsg ("client name too long");
13045       return -99;
13046     }
13047
13048   M (GET_FIRST_MSG_ID, mp);
13049   clib_memcpy (mp->name, name, vec_len (name));
13050   S (mp);
13051   W (ret);
13052   return ret;
13053 }
13054
13055 static int
13056 api_cop_interface_enable_disable (vat_main_t * vam)
13057 {
13058   unformat_input_t *line_input = vam->input;
13059   vl_api_cop_interface_enable_disable_t *mp;
13060   u32 sw_if_index = ~0;
13061   u8 enable_disable = 1;
13062   int ret;
13063
13064   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13065     {
13066       if (unformat (line_input, "disable"))
13067         enable_disable = 0;
13068       if (unformat (line_input, "enable"))
13069         enable_disable = 1;
13070       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13071                          vam, &sw_if_index))
13072         ;
13073       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13074         ;
13075       else
13076         break;
13077     }
13078
13079   if (sw_if_index == ~0)
13080     {
13081       errmsg ("missing interface name or sw_if_index");
13082       return -99;
13083     }
13084
13085   /* Construct the API message */
13086   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13087   mp->sw_if_index = ntohl (sw_if_index);
13088   mp->enable_disable = enable_disable;
13089
13090   /* send it... */
13091   S (mp);
13092   /* Wait for the reply */
13093   W (ret);
13094   return ret;
13095 }
13096
13097 static int
13098 api_cop_whitelist_enable_disable (vat_main_t * vam)
13099 {
13100   unformat_input_t *line_input = vam->input;
13101   vl_api_cop_whitelist_enable_disable_t *mp;
13102   u32 sw_if_index = ~0;
13103   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13104   u32 fib_id = 0;
13105   int ret;
13106
13107   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13108     {
13109       if (unformat (line_input, "ip4"))
13110         ip4 = 1;
13111       else if (unformat (line_input, "ip6"))
13112         ip6 = 1;
13113       else if (unformat (line_input, "default"))
13114         default_cop = 1;
13115       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13116                          vam, &sw_if_index))
13117         ;
13118       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13119         ;
13120       else if (unformat (line_input, "fib-id %d", &fib_id))
13121         ;
13122       else
13123         break;
13124     }
13125
13126   if (sw_if_index == ~0)
13127     {
13128       errmsg ("missing interface name or sw_if_index");
13129       return -99;
13130     }
13131
13132   /* Construct the API message */
13133   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13134   mp->sw_if_index = ntohl (sw_if_index);
13135   mp->fib_id = ntohl (fib_id);
13136   mp->ip4 = ip4;
13137   mp->ip6 = ip6;
13138   mp->default_cop = default_cop;
13139
13140   /* send it... */
13141   S (mp);
13142   /* Wait for the reply */
13143   W (ret);
13144   return ret;
13145 }
13146
13147 static int
13148 api_get_node_graph (vat_main_t * vam)
13149 {
13150   vl_api_get_node_graph_t *mp;
13151   int ret;
13152
13153   M (GET_NODE_GRAPH, mp);
13154
13155   /* send it... */
13156   S (mp);
13157   /* Wait for the reply */
13158   W (ret);
13159   return ret;
13160 }
13161
13162 /* *INDENT-OFF* */
13163 /** Used for parsing LISP eids */
13164 typedef CLIB_PACKED(struct{
13165   u8 addr[16];   /**< eid address */
13166   u32 len;       /**< prefix length if IP */
13167   u8 type;      /**< type of eid */
13168 }) lisp_eid_vat_t;
13169 /* *INDENT-ON* */
13170
13171 static uword
13172 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13173 {
13174   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13175
13176   memset (a, 0, sizeof (a[0]));
13177
13178   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13179     {
13180       a->type = 0;              /* ipv4 type */
13181     }
13182   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13183     {
13184       a->type = 1;              /* ipv6 type */
13185     }
13186   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13187     {
13188       a->type = 2;              /* mac type */
13189     }
13190   else
13191     {
13192       return 0;
13193     }
13194
13195   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13196     {
13197       return 0;
13198     }
13199
13200   return 1;
13201 }
13202
13203 static int
13204 lisp_eid_size_vat (u8 type)
13205 {
13206   switch (type)
13207     {
13208     case 0:
13209       return 4;
13210     case 1:
13211       return 16;
13212     case 2:
13213       return 6;
13214     }
13215   return 0;
13216 }
13217
13218 static void
13219 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13220 {
13221   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13222 }
13223
13224 static int
13225 api_lisp_add_del_locator_set (vat_main_t * vam)
13226 {
13227   unformat_input_t *input = vam->input;
13228   vl_api_lisp_add_del_locator_set_t *mp;
13229   u8 is_add = 1;
13230   u8 *locator_set_name = NULL;
13231   u8 locator_set_name_set = 0;
13232   vl_api_local_locator_t locator, *locators = 0;
13233   u32 sw_if_index, priority, weight;
13234   u32 data_len = 0;
13235
13236   int ret;
13237   /* Parse args required to build the message */
13238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13239     {
13240       if (unformat (input, "del"))
13241         {
13242           is_add = 0;
13243         }
13244       else if (unformat (input, "locator-set %s", &locator_set_name))
13245         {
13246           locator_set_name_set = 1;
13247         }
13248       else if (unformat (input, "sw_if_index %u p %u w %u",
13249                          &sw_if_index, &priority, &weight))
13250         {
13251           locator.sw_if_index = htonl (sw_if_index);
13252           locator.priority = priority;
13253           locator.weight = weight;
13254           vec_add1 (locators, locator);
13255         }
13256       else
13257         if (unformat
13258             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13259              &sw_if_index, &priority, &weight))
13260         {
13261           locator.sw_if_index = htonl (sw_if_index);
13262           locator.priority = priority;
13263           locator.weight = weight;
13264           vec_add1 (locators, locator);
13265         }
13266       else
13267         break;
13268     }
13269
13270   if (locator_set_name_set == 0)
13271     {
13272       errmsg ("missing locator-set name");
13273       vec_free (locators);
13274       return -99;
13275     }
13276
13277   if (vec_len (locator_set_name) > 64)
13278     {
13279       errmsg ("locator-set name too long");
13280       vec_free (locator_set_name);
13281       vec_free (locators);
13282       return -99;
13283     }
13284   vec_add1 (locator_set_name, 0);
13285
13286   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13287
13288   /* Construct the API message */
13289   M2 (LISP_ADD_DEL_LOCATOR_SET, mp, data_len);
13290
13291   mp->is_add = is_add;
13292   clib_memcpy (mp->locator_set_name, locator_set_name,
13293                vec_len (locator_set_name));
13294   vec_free (locator_set_name);
13295
13296   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13297   if (locators)
13298     clib_memcpy (mp->locators, locators, data_len);
13299   vec_free (locators);
13300
13301   /* send it... */
13302   S (mp);
13303
13304   /* Wait for a reply... */
13305   W (ret);
13306   return ret;
13307 }
13308
13309 static int
13310 api_lisp_add_del_locator (vat_main_t * vam)
13311 {
13312   unformat_input_t *input = vam->input;
13313   vl_api_lisp_add_del_locator_t *mp;
13314   u32 tmp_if_index = ~0;
13315   u32 sw_if_index = ~0;
13316   u8 sw_if_index_set = 0;
13317   u8 sw_if_index_if_name_set = 0;
13318   u32 priority = ~0;
13319   u8 priority_set = 0;
13320   u32 weight = ~0;
13321   u8 weight_set = 0;
13322   u8 is_add = 1;
13323   u8 *locator_set_name = NULL;
13324   u8 locator_set_name_set = 0;
13325   int ret;
13326
13327   /* Parse args required to build the message */
13328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13329     {
13330       if (unformat (input, "del"))
13331         {
13332           is_add = 0;
13333         }
13334       else if (unformat (input, "locator-set %s", &locator_set_name))
13335         {
13336           locator_set_name_set = 1;
13337         }
13338       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13339                          &tmp_if_index))
13340         {
13341           sw_if_index_if_name_set = 1;
13342           sw_if_index = tmp_if_index;
13343         }
13344       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13345         {
13346           sw_if_index_set = 1;
13347           sw_if_index = tmp_if_index;
13348         }
13349       else if (unformat (input, "p %d", &priority))
13350         {
13351           priority_set = 1;
13352         }
13353       else if (unformat (input, "w %d", &weight))
13354         {
13355           weight_set = 1;
13356         }
13357       else
13358         break;
13359     }
13360
13361   if (locator_set_name_set == 0)
13362     {
13363       errmsg ("missing locator-set name");
13364       return -99;
13365     }
13366
13367   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13368     {
13369       errmsg ("missing sw_if_index");
13370       vec_free (locator_set_name);
13371       return -99;
13372     }
13373
13374   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13375     {
13376       errmsg ("cannot use both params interface name and sw_if_index");
13377       vec_free (locator_set_name);
13378       return -99;
13379     }
13380
13381   if (priority_set == 0)
13382     {
13383       errmsg ("missing locator-set priority");
13384       vec_free (locator_set_name);
13385       return -99;
13386     }
13387
13388   if (weight_set == 0)
13389     {
13390       errmsg ("missing locator-set weight");
13391       vec_free (locator_set_name);
13392       return -99;
13393     }
13394
13395   if (vec_len (locator_set_name) > 64)
13396     {
13397       errmsg ("locator-set name too long");
13398       vec_free (locator_set_name);
13399       return -99;
13400     }
13401   vec_add1 (locator_set_name, 0);
13402
13403   /* Construct the API message */
13404   M (LISP_ADD_DEL_LOCATOR, mp);
13405
13406   mp->is_add = is_add;
13407   mp->sw_if_index = ntohl (sw_if_index);
13408   mp->priority = priority;
13409   mp->weight = weight;
13410   clib_memcpy (mp->locator_set_name, locator_set_name,
13411                vec_len (locator_set_name));
13412   vec_free (locator_set_name);
13413
13414   /* send it... */
13415   S (mp);
13416
13417   /* Wait for a reply... */
13418   W (ret);
13419   return ret;
13420 }
13421
13422 uword
13423 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13424 {
13425   u32 *key_id = va_arg (*args, u32 *);
13426   u8 *s = 0;
13427
13428   if (unformat (input, "%s", &s))
13429     {
13430       if (!strcmp ((char *) s, "sha1"))
13431         key_id[0] = HMAC_SHA_1_96;
13432       else if (!strcmp ((char *) s, "sha256"))
13433         key_id[0] = HMAC_SHA_256_128;
13434       else
13435         {
13436           clib_warning ("invalid key_id: '%s'", s);
13437           key_id[0] = HMAC_NO_KEY;
13438         }
13439     }
13440   else
13441     return 0;
13442
13443   vec_free (s);
13444   return 1;
13445 }
13446
13447 static int
13448 api_lisp_add_del_local_eid (vat_main_t * vam)
13449 {
13450   unformat_input_t *input = vam->input;
13451   vl_api_lisp_add_del_local_eid_t *mp;
13452   u8 is_add = 1;
13453   u8 eid_set = 0;
13454   lisp_eid_vat_t _eid, *eid = &_eid;
13455   u8 *locator_set_name = 0;
13456   u8 locator_set_name_set = 0;
13457   u32 vni = 0;
13458   u16 key_id = 0;
13459   u8 *key = 0;
13460   int ret;
13461
13462   /* Parse args required to build the message */
13463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13464     {
13465       if (unformat (input, "del"))
13466         {
13467           is_add = 0;
13468         }
13469       else if (unformat (input, "vni %d", &vni))
13470         {
13471           ;
13472         }
13473       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13474         {
13475           eid_set = 1;
13476         }
13477       else if (unformat (input, "locator-set %s", &locator_set_name))
13478         {
13479           locator_set_name_set = 1;
13480         }
13481       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13482         ;
13483       else if (unformat (input, "secret-key %_%v%_", &key))
13484         ;
13485       else
13486         break;
13487     }
13488
13489   if (locator_set_name_set == 0)
13490     {
13491       errmsg ("missing locator-set name");
13492       return -99;
13493     }
13494
13495   if (0 == eid_set)
13496     {
13497       errmsg ("EID address not set!");
13498       vec_free (locator_set_name);
13499       return -99;
13500     }
13501
13502   if (key && (0 == key_id))
13503     {
13504       errmsg ("invalid key_id!");
13505       return -99;
13506     }
13507
13508   if (vec_len (key) > 64)
13509     {
13510       errmsg ("key too long");
13511       vec_free (key);
13512       return -99;
13513     }
13514
13515   if (vec_len (locator_set_name) > 64)
13516     {
13517       errmsg ("locator-set name too long");
13518       vec_free (locator_set_name);
13519       return -99;
13520     }
13521   vec_add1 (locator_set_name, 0);
13522
13523   /* Construct the API message */
13524   M (LISP_ADD_DEL_LOCAL_EID, mp);
13525
13526   mp->is_add = is_add;
13527   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13528   mp->eid_type = eid->type;
13529   mp->prefix_len = eid->len;
13530   mp->vni = clib_host_to_net_u32 (vni);
13531   mp->key_id = clib_host_to_net_u16 (key_id);
13532   clib_memcpy (mp->locator_set_name, locator_set_name,
13533                vec_len (locator_set_name));
13534   clib_memcpy (mp->key, key, vec_len (key));
13535
13536   vec_free (locator_set_name);
13537   vec_free (key);
13538
13539   /* send it... */
13540   S (mp);
13541
13542   /* Wait for a reply... */
13543   W (ret);
13544   return ret;
13545 }
13546
13547 /* *INDENT-OFF* */
13548 /** Used for transferring locators via VPP API */
13549 typedef CLIB_PACKED(struct
13550 {
13551   u8 is_ip4; /**< is locator an IPv4 address? */
13552   u8 priority; /**< locator priority */
13553   u8 weight;   /**< locator weight */
13554   u8 addr[16]; /**< IPv4/IPv6 address */
13555 }) rloc_t;
13556 /* *INDENT-ON* */
13557
13558 static int
13559 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13560 {
13561   u32 dp_table = 0, vni = 0;;
13562   unformat_input_t *input = vam->input;
13563   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13564   u8 is_add = 1;
13565   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13566   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13567   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13568   u32 action = ~0, w;
13569   ip4_address_t rmt_rloc4, lcl_rloc4;
13570   ip6_address_t rmt_rloc6, lcl_rloc6;
13571   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13572     0;
13573   int ret;
13574
13575   memset (&rloc, 0, sizeof (rloc));
13576
13577   /* Parse args required to build the message */
13578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13579     {
13580       if (unformat (input, "del"))
13581         is_add = 0;
13582       else if (unformat (input, "add"))
13583         is_add = 1;
13584       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13585         {
13586           rmt_eid_set = 1;
13587         }
13588       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13589         {
13590           lcl_eid_set = 1;
13591         }
13592       else if (unformat (input, "vrf %d", &dp_table))
13593         ;
13594       else if (unformat (input, "bd %d", &dp_table))
13595         ;
13596       else if (unformat (input, "vni %d", &vni))
13597         ;
13598       else if (unformat (input, "w %d", &w))
13599         {
13600           if (!curr_rloc)
13601             {
13602               errmsg ("No RLOC configured for setting priority/weight!");
13603               return -99;
13604             }
13605           curr_rloc->weight = w;
13606         }
13607       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13608                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13609         {
13610           rloc.is_ip4 = 1;
13611
13612           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13613           rloc.weight = 0;
13614           vec_add1 (lcl_locs, rloc);
13615
13616           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13617           vec_add1 (rmt_locs, rloc);
13618           /* weight saved in rmt loc */
13619           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13620         }
13621       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13622                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13623         {
13624           rloc.is_ip4 = 0;
13625           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13626           rloc.weight = 0;
13627           vec_add1 (lcl_locs, rloc);
13628
13629           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13630           vec_add1 (rmt_locs, rloc);
13631           /* weight saved in rmt loc */
13632           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13633         }
13634       else if (unformat (input, "action %d", &action))
13635         {
13636           ;
13637         }
13638       else
13639         {
13640           clib_warning ("parse error '%U'", format_unformat_error, input);
13641           return -99;
13642         }
13643     }
13644
13645   if (!rmt_eid_set)
13646     {
13647       errmsg ("remote eid addresses not set");
13648       return -99;
13649     }
13650
13651   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13652     {
13653       errmsg ("eid types don't match");
13654       return -99;
13655     }
13656
13657   if (0 == rmt_locs && (u32) ~ 0 == action)
13658     {
13659       errmsg ("action not set for negative mapping");
13660       return -99;
13661     }
13662
13663   /* Construct the API message */
13664   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, mp,
13665       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13666
13667   mp->is_add = is_add;
13668   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13669   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13670   mp->eid_type = rmt_eid->type;
13671   mp->dp_table = clib_host_to_net_u32 (dp_table);
13672   mp->vni = clib_host_to_net_u32 (vni);
13673   mp->rmt_len = rmt_eid->len;
13674   mp->lcl_len = lcl_eid->len;
13675   mp->action = action;
13676
13677   if (0 != rmt_locs && 0 != lcl_locs)
13678     {
13679       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13680       clib_memcpy (mp->locs, lcl_locs,
13681                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13682
13683       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13684       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13685                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13686     }
13687   vec_free (lcl_locs);
13688   vec_free (rmt_locs);
13689
13690   /* send it... */
13691   S (mp);
13692
13693   /* Wait for a reply... */
13694   W (ret);
13695   return ret;
13696 }
13697
13698 static int
13699 api_lisp_add_del_map_server (vat_main_t * vam)
13700 {
13701   unformat_input_t *input = vam->input;
13702   vl_api_lisp_add_del_map_server_t *mp;
13703   u8 is_add = 1;
13704   u8 ipv4_set = 0;
13705   u8 ipv6_set = 0;
13706   ip4_address_t ipv4;
13707   ip6_address_t ipv6;
13708   int ret;
13709
13710   /* Parse args required to build the message */
13711   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13712     {
13713       if (unformat (input, "del"))
13714         {
13715           is_add = 0;
13716         }
13717       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13718         {
13719           ipv4_set = 1;
13720         }
13721       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13722         {
13723           ipv6_set = 1;
13724         }
13725       else
13726         break;
13727     }
13728
13729   if (ipv4_set && ipv6_set)
13730     {
13731       errmsg ("both eid v4 and v6 addresses set");
13732       return -99;
13733     }
13734
13735   if (!ipv4_set && !ipv6_set)
13736     {
13737       errmsg ("eid addresses not set");
13738       return -99;
13739     }
13740
13741   /* Construct the API message */
13742   M (LISP_ADD_DEL_MAP_SERVER, mp);
13743
13744   mp->is_add = is_add;
13745   if (ipv6_set)
13746     {
13747       mp->is_ipv6 = 1;
13748       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13749     }
13750   else
13751     {
13752       mp->is_ipv6 = 0;
13753       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13754     }
13755
13756   /* send it... */
13757   S (mp);
13758
13759   /* Wait for a reply... */
13760   W (ret);
13761   return ret;
13762 }
13763
13764 static int
13765 api_lisp_add_del_map_resolver (vat_main_t * vam)
13766 {
13767   unformat_input_t *input = vam->input;
13768   vl_api_lisp_add_del_map_resolver_t *mp;
13769   u8 is_add = 1;
13770   u8 ipv4_set = 0;
13771   u8 ipv6_set = 0;
13772   ip4_address_t ipv4;
13773   ip6_address_t ipv6;
13774   int ret;
13775
13776   /* Parse args required to build the message */
13777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13778     {
13779       if (unformat (input, "del"))
13780         {
13781           is_add = 0;
13782         }
13783       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13784         {
13785           ipv4_set = 1;
13786         }
13787       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13788         {
13789           ipv6_set = 1;
13790         }
13791       else
13792         break;
13793     }
13794
13795   if (ipv4_set && ipv6_set)
13796     {
13797       errmsg ("both eid v4 and v6 addresses set");
13798       return -99;
13799     }
13800
13801   if (!ipv4_set && !ipv6_set)
13802     {
13803       errmsg ("eid addresses not set");
13804       return -99;
13805     }
13806
13807   /* Construct the API message */
13808   M (LISP_ADD_DEL_MAP_RESOLVER, mp);
13809
13810   mp->is_add = is_add;
13811   if (ipv6_set)
13812     {
13813       mp->is_ipv6 = 1;
13814       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13815     }
13816   else
13817     {
13818       mp->is_ipv6 = 0;
13819       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13820     }
13821
13822   /* send it... */
13823   S (mp);
13824
13825   /* Wait for a reply... */
13826   W (ret);
13827   return ret;
13828 }
13829
13830 static int
13831 api_lisp_gpe_enable_disable (vat_main_t * vam)
13832 {
13833   unformat_input_t *input = vam->input;
13834   vl_api_lisp_gpe_enable_disable_t *mp;
13835   u8 is_set = 0;
13836   u8 is_en = 1;
13837   int ret;
13838
13839   /* Parse args required to build the message */
13840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13841     {
13842       if (unformat (input, "enable"))
13843         {
13844           is_set = 1;
13845           is_en = 1;
13846         }
13847       else if (unformat (input, "disable"))
13848         {
13849           is_set = 1;
13850           is_en = 0;
13851         }
13852       else
13853         break;
13854     }
13855
13856   if (is_set == 0)
13857     {
13858       errmsg ("Value not set");
13859       return -99;
13860     }
13861
13862   /* Construct the API message */
13863   M (LISP_GPE_ENABLE_DISABLE, mp);
13864
13865   mp->is_en = is_en;
13866
13867   /* send it... */
13868   S (mp);
13869
13870   /* Wait for a reply... */
13871   W (ret);
13872   return ret;
13873 }
13874
13875 static int
13876 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13877 {
13878   unformat_input_t *input = vam->input;
13879   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13880   u8 is_set = 0;
13881   u8 is_en = 0;
13882   int ret;
13883
13884   /* Parse args required to build the message */
13885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13886     {
13887       if (unformat (input, "enable"))
13888         {
13889           is_set = 1;
13890           is_en = 1;
13891         }
13892       else if (unformat (input, "disable"))
13893         is_set = 1;
13894       else
13895         break;
13896     }
13897
13898   if (!is_set)
13899     {
13900       errmsg ("Value not set");
13901       return -99;
13902     }
13903
13904   /* Construct the API message */
13905   M (LISP_RLOC_PROBE_ENABLE_DISABLE, mp);
13906
13907   mp->is_enabled = is_en;
13908
13909   /* send it... */
13910   S (mp);
13911
13912   /* Wait for a reply... */
13913   W (ret);
13914   return ret;
13915 }
13916
13917 static int
13918 api_lisp_map_register_enable_disable (vat_main_t * vam)
13919 {
13920   unformat_input_t *input = vam->input;
13921   vl_api_lisp_map_register_enable_disable_t *mp;
13922   u8 is_set = 0;
13923   u8 is_en = 0;
13924   int ret;
13925
13926   /* Parse args required to build the message */
13927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13928     {
13929       if (unformat (input, "enable"))
13930         {
13931           is_set = 1;
13932           is_en = 1;
13933         }
13934       else if (unformat (input, "disable"))
13935         is_set = 1;
13936       else
13937         break;
13938     }
13939
13940   if (!is_set)
13941     {
13942       errmsg ("Value not set");
13943       return -99;
13944     }
13945
13946   /* Construct the API message */
13947   M (LISP_MAP_REGISTER_ENABLE_DISABLE, mp);
13948
13949   mp->is_enabled = is_en;
13950
13951   /* send it... */
13952   S (mp);
13953
13954   /* Wait for a reply... */
13955   W (ret);
13956   return ret;
13957 }
13958
13959 static int
13960 api_lisp_enable_disable (vat_main_t * vam)
13961 {
13962   unformat_input_t *input = vam->input;
13963   vl_api_lisp_enable_disable_t *mp;
13964   u8 is_set = 0;
13965   u8 is_en = 0;
13966   int ret;
13967
13968   /* Parse args required to build the message */
13969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13970     {
13971       if (unformat (input, "enable"))
13972         {
13973           is_set = 1;
13974           is_en = 1;
13975         }
13976       else if (unformat (input, "disable"))
13977         {
13978           is_set = 1;
13979         }
13980       else
13981         break;
13982     }
13983
13984   if (!is_set)
13985     {
13986       errmsg ("Value not set");
13987       return -99;
13988     }
13989
13990   /* Construct the API message */
13991   M (LISP_ENABLE_DISABLE, mp);
13992
13993   mp->is_en = is_en;
13994
13995   /* send it... */
13996   S (mp);
13997
13998   /* Wait for a reply... */
13999   W (ret);
14000   return ret;
14001 }
14002
14003 static int
14004 api_show_lisp_map_register_state (vat_main_t * vam)
14005 {
14006   vl_api_show_lisp_map_register_state_t *mp;
14007   int ret;
14008
14009   M (SHOW_LISP_MAP_REGISTER_STATE, mp);
14010
14011   /* send */
14012   S (mp);
14013
14014   /* wait for reply */
14015   W (ret);
14016   return ret;
14017 }
14018
14019 static int
14020 api_show_lisp_rloc_probe_state (vat_main_t * vam)
14021 {
14022   vl_api_show_lisp_rloc_probe_state_t *mp;
14023   int ret;
14024
14025   M (SHOW_LISP_RLOC_PROBE_STATE, mp);
14026
14027   /* send */
14028   S (mp);
14029
14030   /* wait for reply */
14031   W (ret);
14032   return ret;
14033 }
14034
14035 static int
14036 api_show_lisp_map_request_mode (vat_main_t * vam)
14037 {
14038   vl_api_show_lisp_map_request_mode_t *mp;
14039   int ret;
14040
14041   M (SHOW_LISP_MAP_REQUEST_MODE, mp);
14042
14043   /* send */
14044   S (mp);
14045
14046   /* wait for reply */
14047   W (ret);
14048   return ret;
14049 }
14050
14051 static int
14052 api_lisp_map_request_mode (vat_main_t * vam)
14053 {
14054   unformat_input_t *input = vam->input;
14055   vl_api_lisp_map_request_mode_t *mp;
14056   u8 mode = 0;
14057   int ret;
14058
14059   /* Parse args required to build the message */
14060   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14061     {
14062       if (unformat (input, "dst-only"))
14063         mode = 0;
14064       else if (unformat (input, "src-dst"))
14065         mode = 1;
14066       else
14067         {
14068           errmsg ("parse error '%U'", format_unformat_error, input);
14069           return -99;
14070         }
14071     }
14072
14073   M (LISP_MAP_REQUEST_MODE, mp);
14074
14075   mp->mode = mode;
14076
14077   /* send */
14078   S (mp);
14079
14080   /* wait for reply */
14081   W (ret);
14082   return ret;
14083 }
14084
14085 /**
14086  * Enable/disable LISP proxy ITR.
14087  *
14088  * @param vam vpp API test context
14089  * @return return code
14090  */
14091 static int
14092 api_lisp_pitr_set_locator_set (vat_main_t * vam)
14093 {
14094   u8 ls_name_set = 0;
14095   unformat_input_t *input = vam->input;
14096   vl_api_lisp_pitr_set_locator_set_t *mp;
14097   u8 is_add = 1;
14098   u8 *ls_name = 0;
14099   int ret;
14100
14101   /* Parse args required to build the message */
14102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14103     {
14104       if (unformat (input, "del"))
14105         is_add = 0;
14106       else if (unformat (input, "locator-set %s", &ls_name))
14107         ls_name_set = 1;
14108       else
14109         {
14110           errmsg ("parse error '%U'", format_unformat_error, input);
14111           return -99;
14112         }
14113     }
14114
14115   if (!ls_name_set)
14116     {
14117       errmsg ("locator-set name not set!");
14118       return -99;
14119     }
14120
14121   M (LISP_PITR_SET_LOCATOR_SET, mp);
14122
14123   mp->is_add = is_add;
14124   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14125   vec_free (ls_name);
14126
14127   /* send */
14128   S (mp);
14129
14130   /* wait for reply */
14131   W (ret);
14132   return ret;
14133 }
14134
14135 static int
14136 api_show_lisp_pitr (vat_main_t * vam)
14137 {
14138   vl_api_show_lisp_pitr_t *mp;
14139   int ret;
14140
14141   if (!vam->json_output)
14142     {
14143       print (vam->ofp, "%=20s", "lisp status:");
14144     }
14145
14146   M (SHOW_LISP_PITR, mp);
14147   /* send it... */
14148   S (mp);
14149
14150   /* Wait for a reply... */
14151   W (ret);
14152   return ret;
14153 }
14154
14155 /**
14156  * Add/delete mapping between vni and vrf
14157  */
14158 static int
14159 api_lisp_eid_table_add_del_map (vat_main_t * vam)
14160 {
14161   unformat_input_t *input = vam->input;
14162   vl_api_lisp_eid_table_add_del_map_t *mp;
14163   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14164   u32 vni, vrf, bd_index;
14165   int ret;
14166
14167   /* Parse args required to build the message */
14168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14169     {
14170       if (unformat (input, "del"))
14171         is_add = 0;
14172       else if (unformat (input, "vrf %d", &vrf))
14173         vrf_set = 1;
14174       else if (unformat (input, "bd_index %d", &bd_index))
14175         bd_index_set = 1;
14176       else if (unformat (input, "vni %d", &vni))
14177         vni_set = 1;
14178       else
14179         break;
14180     }
14181
14182   if (!vni_set || (!vrf_set && !bd_index_set))
14183     {
14184       errmsg ("missing arguments!");
14185       return -99;
14186     }
14187
14188   if (vrf_set && bd_index_set)
14189     {
14190       errmsg ("error: both vrf and bd entered!");
14191       return -99;
14192     }
14193
14194   M (LISP_EID_TABLE_ADD_DEL_MAP, mp);
14195
14196   mp->is_add = is_add;
14197   mp->vni = htonl (vni);
14198   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14199   mp->is_l2 = bd_index_set;
14200
14201   /* send */
14202   S (mp);
14203
14204   /* wait for reply */
14205   W (ret);
14206   return ret;
14207 }
14208
14209 uword
14210 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14211 {
14212   u32 *action = va_arg (*args, u32 *);
14213   u8 *s = 0;
14214
14215   if (unformat (input, "%s", &s))
14216     {
14217       if (!strcmp ((char *) s, "no-action"))
14218         action[0] = 0;
14219       else if (!strcmp ((char *) s, "natively-forward"))
14220         action[0] = 1;
14221       else if (!strcmp ((char *) s, "send-map-request"))
14222         action[0] = 2;
14223       else if (!strcmp ((char *) s, "drop"))
14224         action[0] = 3;
14225       else
14226         {
14227           clib_warning ("invalid action: '%s'", s);
14228           action[0] = 3;
14229         }
14230     }
14231   else
14232     return 0;
14233
14234   vec_free (s);
14235   return 1;
14236 }
14237
14238 /**
14239  * Add/del remote mapping to/from LISP control plane
14240  *
14241  * @param vam vpp API test context
14242  * @return return code
14243  */
14244 static int
14245 api_lisp_add_del_remote_mapping (vat_main_t * vam)
14246 {
14247   unformat_input_t *input = vam->input;
14248   vl_api_lisp_add_del_remote_mapping_t *mp;
14249   u32 vni = 0;
14250   lisp_eid_vat_t _eid, *eid = &_eid;
14251   lisp_eid_vat_t _seid, *seid = &_seid;
14252   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14253   u32 action = ~0, p, w, data_len;
14254   ip4_address_t rloc4;
14255   ip6_address_t rloc6;
14256   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14257   int ret;
14258
14259   memset (&rloc, 0, sizeof (rloc));
14260
14261   /* Parse args required to build the message */
14262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14263     {
14264       if (unformat (input, "del-all"))
14265         {
14266           del_all = 1;
14267         }
14268       else if (unformat (input, "del"))
14269         {
14270           is_add = 0;
14271         }
14272       else if (unformat (input, "add"))
14273         {
14274           is_add = 1;
14275         }
14276       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14277         {
14278           eid_set = 1;
14279         }
14280       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14281         {
14282           seid_set = 1;
14283         }
14284       else if (unformat (input, "vni %d", &vni))
14285         {
14286           ;
14287         }
14288       else if (unformat (input, "p %d w %d", &p, &w))
14289         {
14290           if (!curr_rloc)
14291             {
14292               errmsg ("No RLOC configured for setting priority/weight!");
14293               return -99;
14294             }
14295           curr_rloc->priority = p;
14296           curr_rloc->weight = w;
14297         }
14298       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14299         {
14300           rloc.is_ip4 = 1;
14301           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14302           vec_add1 (rlocs, rloc);
14303           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14304         }
14305       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14306         {
14307           rloc.is_ip4 = 0;
14308           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14309           vec_add1 (rlocs, rloc);
14310           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14311         }
14312       else if (unformat (input, "action %U",
14313                          unformat_negative_mapping_action, &action))
14314         {
14315           ;
14316         }
14317       else
14318         {
14319           clib_warning ("parse error '%U'", format_unformat_error, input);
14320           return -99;
14321         }
14322     }
14323
14324   if (0 == eid_set)
14325     {
14326       errmsg ("missing params!");
14327       return -99;
14328     }
14329
14330   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14331     {
14332       errmsg ("no action set for negative map-reply!");
14333       return -99;
14334     }
14335
14336   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14337
14338   M2 (LISP_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14339   mp->is_add = is_add;
14340   mp->vni = htonl (vni);
14341   mp->action = (u8) action;
14342   mp->is_src_dst = seid_set;
14343   mp->eid_len = eid->len;
14344   mp->seid_len = seid->len;
14345   mp->del_all = del_all;
14346   mp->eid_type = eid->type;
14347   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14348   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14349
14350   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14351   clib_memcpy (mp->rlocs, rlocs, data_len);
14352   vec_free (rlocs);
14353
14354   /* send it... */
14355   S (mp);
14356
14357   /* Wait for a reply... */
14358   W (ret);
14359   return ret;
14360 }
14361
14362 /**
14363  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14364  * forwarding entries in data-plane accordingly.
14365  *
14366  * @param vam vpp API test context
14367  * @return return code
14368  */
14369 static int
14370 api_lisp_add_del_adjacency (vat_main_t * vam)
14371 {
14372   unformat_input_t *input = vam->input;
14373   vl_api_lisp_add_del_adjacency_t *mp;
14374   u32 vni = 0;
14375   ip4_address_t leid4, reid4;
14376   ip6_address_t leid6, reid6;
14377   u8 reid_mac[6] = { 0 };
14378   u8 leid_mac[6] = { 0 };
14379   u8 reid_type, leid_type;
14380   u32 leid_len = 0, reid_len = 0, len;
14381   u8 is_add = 1;
14382   int ret;
14383
14384   leid_type = reid_type = (u8) ~ 0;
14385
14386   /* Parse args required to build the message */
14387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14388     {
14389       if (unformat (input, "del"))
14390         {
14391           is_add = 0;
14392         }
14393       else if (unformat (input, "add"))
14394         {
14395           is_add = 1;
14396         }
14397       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14398                          &reid4, &len))
14399         {
14400           reid_type = 0;        /* ipv4 */
14401           reid_len = len;
14402         }
14403       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14404                          &reid6, &len))
14405         {
14406           reid_type = 1;        /* ipv6 */
14407           reid_len = len;
14408         }
14409       else if (unformat (input, "reid %U", unformat_ethernet_address,
14410                          reid_mac))
14411         {
14412           reid_type = 2;        /* mac */
14413         }
14414       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14415                          &leid4, &len))
14416         {
14417           leid_type = 0;        /* ipv4 */
14418           leid_len = len;
14419         }
14420       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14421                          &leid6, &len))
14422         {
14423           leid_type = 1;        /* ipv6 */
14424           leid_len = len;
14425         }
14426       else if (unformat (input, "leid %U", unformat_ethernet_address,
14427                          leid_mac))
14428         {
14429           leid_type = 2;        /* mac */
14430         }
14431       else if (unformat (input, "vni %d", &vni))
14432         {
14433           ;
14434         }
14435       else
14436         {
14437           errmsg ("parse error '%U'", format_unformat_error, input);
14438           return -99;
14439         }
14440     }
14441
14442   if ((u8) ~ 0 == reid_type)
14443     {
14444       errmsg ("missing params!");
14445       return -99;
14446     }
14447
14448   if (leid_type != reid_type)
14449     {
14450       errmsg ("remote and local EIDs are of different types!");
14451       return -99;
14452     }
14453
14454   M (LISP_ADD_DEL_ADJACENCY, mp);
14455   mp->is_add = is_add;
14456   mp->vni = htonl (vni);
14457   mp->leid_len = leid_len;
14458   mp->reid_len = reid_len;
14459   mp->eid_type = reid_type;
14460
14461   switch (mp->eid_type)
14462     {
14463     case 0:
14464       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14465       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14466       break;
14467     case 1:
14468       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14469       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14470       break;
14471     case 2:
14472       clib_memcpy (mp->leid, leid_mac, 6);
14473       clib_memcpy (mp->reid, reid_mac, 6);
14474       break;
14475     default:
14476       errmsg ("unknown EID type %d!", mp->eid_type);
14477       return 0;
14478     }
14479
14480   /* send it... */
14481   S (mp);
14482
14483   /* Wait for a reply... */
14484   W (ret);
14485   return ret;
14486 }
14487
14488 static int
14489 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14490 {
14491   unformat_input_t *input = vam->input;
14492   vl_api_lisp_gpe_add_del_iface_t *mp;
14493   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14494   u32 dp_table = 0, vni = 0;
14495   int ret;
14496
14497   /* Parse args required to build the message */
14498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14499     {
14500       if (unformat (input, "up"))
14501         {
14502           action_set = 1;
14503           is_add = 1;
14504         }
14505       else if (unformat (input, "down"))
14506         {
14507           action_set = 1;
14508           is_add = 0;
14509         }
14510       else if (unformat (input, "table_id %d", &dp_table))
14511         {
14512           dp_table_set = 1;
14513         }
14514       else if (unformat (input, "bd_id %d", &dp_table))
14515         {
14516           dp_table_set = 1;
14517           is_l2 = 1;
14518         }
14519       else if (unformat (input, "vni %d", &vni))
14520         {
14521           vni_set = 1;
14522         }
14523       else
14524         break;
14525     }
14526
14527   if (action_set == 0)
14528     {
14529       errmsg ("Action not set");
14530       return -99;
14531     }
14532   if (dp_table_set == 0 || vni_set == 0)
14533     {
14534       errmsg ("vni and dp_table must be set");
14535       return -99;
14536     }
14537
14538   /* Construct the API message */
14539   M (LISP_GPE_ADD_DEL_IFACE, mp);
14540
14541   mp->is_add = is_add;
14542   mp->dp_table = dp_table;
14543   mp->is_l2 = is_l2;
14544   mp->vni = vni;
14545
14546   /* send it... */
14547   S (mp);
14548
14549   /* Wait for a reply... */
14550   W (ret);
14551   return ret;
14552 }
14553
14554 /**
14555  * Add/del map request itr rlocs from LISP control plane and updates
14556  *
14557  * @param vam vpp API test context
14558  * @return return code
14559  */
14560 static int
14561 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14562 {
14563   unformat_input_t *input = vam->input;
14564   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14565   u8 *locator_set_name = 0;
14566   u8 locator_set_name_set = 0;
14567   u8 is_add = 1;
14568   int ret;
14569
14570   /* Parse args required to build the message */
14571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14572     {
14573       if (unformat (input, "del"))
14574         {
14575           is_add = 0;
14576         }
14577       else if (unformat (input, "%_%v%_", &locator_set_name))
14578         {
14579           locator_set_name_set = 1;
14580         }
14581       else
14582         {
14583           clib_warning ("parse error '%U'", format_unformat_error, input);
14584           return -99;
14585         }
14586     }
14587
14588   if (is_add && !locator_set_name_set)
14589     {
14590       errmsg ("itr-rloc is not set!");
14591       return -99;
14592     }
14593
14594   if (is_add && vec_len (locator_set_name) > 64)
14595     {
14596       errmsg ("itr-rloc locator-set name too long");
14597       vec_free (locator_set_name);
14598       return -99;
14599     }
14600
14601   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14602   mp->is_add = is_add;
14603   if (is_add)
14604     {
14605       clib_memcpy (mp->locator_set_name, locator_set_name,
14606                    vec_len (locator_set_name));
14607     }
14608   else
14609     {
14610       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14611     }
14612   vec_free (locator_set_name);
14613
14614   /* send it... */
14615   S (mp);
14616
14617   /* Wait for a reply... */
14618   W (ret);
14619   return ret;
14620 }
14621
14622 static int
14623 api_lisp_locator_dump (vat_main_t * vam)
14624 {
14625   unformat_input_t *input = vam->input;
14626   vl_api_lisp_locator_dump_t *mp;
14627   u8 is_index_set = 0, is_name_set = 0;
14628   u8 *ls_name = 0;
14629   u32 ls_index = ~0;
14630   int ret;
14631
14632   /* Parse args required to build the message */
14633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14634     {
14635       if (unformat (input, "ls_name %_%v%_", &ls_name))
14636         {
14637           is_name_set = 1;
14638         }
14639       else if (unformat (input, "ls_index %d", &ls_index))
14640         {
14641           is_index_set = 1;
14642         }
14643       else
14644         {
14645           errmsg ("parse error '%U'", format_unformat_error, input);
14646           return -99;
14647         }
14648     }
14649
14650   if (!is_index_set && !is_name_set)
14651     {
14652       errmsg ("error: expected one of index or name!");
14653       return -99;
14654     }
14655
14656   if (is_index_set && is_name_set)
14657     {
14658       errmsg ("error: only one param expected!");
14659       return -99;
14660     }
14661
14662   if (vec_len (ls_name) > 62)
14663     {
14664       errmsg ("error: locator set name too long!");
14665       return -99;
14666     }
14667
14668   if (!vam->json_output)
14669     {
14670       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14671     }
14672
14673   M (LISP_LOCATOR_DUMP, mp);
14674   mp->is_index_set = is_index_set;
14675
14676   if (is_index_set)
14677     mp->ls_index = clib_host_to_net_u32 (ls_index);
14678   else
14679     {
14680       vec_add1 (ls_name, 0);
14681       strncpy ((char *) mp->ls_name, (char *) ls_name,
14682                sizeof (mp->ls_name) - 1);
14683     }
14684
14685   /* send it... */
14686   S (mp);
14687
14688   /* Use a control ping for synchronization */
14689   {
14690     vl_api_control_ping_t *mp;
14691     M (CONTROL_PING, mp);
14692     S (mp);
14693   }
14694   /* Wait for a reply... */
14695   W (ret);
14696   return ret;
14697 }
14698
14699 static int
14700 api_lisp_locator_set_dump (vat_main_t * vam)
14701 {
14702   vl_api_lisp_locator_set_dump_t *mp;
14703   unformat_input_t *input = vam->input;
14704   u8 filter = 0;
14705   int ret;
14706
14707   /* Parse args required to build the message */
14708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14709     {
14710       if (unformat (input, "local"))
14711         {
14712           filter = 1;
14713         }
14714       else if (unformat (input, "remote"))
14715         {
14716           filter = 2;
14717         }
14718       else
14719         {
14720           errmsg ("parse error '%U'", format_unformat_error, input);
14721           return -99;
14722         }
14723     }
14724
14725   if (!vam->json_output)
14726     {
14727       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14728     }
14729
14730   M (LISP_LOCATOR_SET_DUMP, mp);
14731
14732   mp->filter = filter;
14733
14734   /* send it... */
14735   S (mp);
14736
14737   /* Use a control ping for synchronization */
14738   {
14739     vl_api_control_ping_t *mp;
14740     M (CONTROL_PING, mp);
14741     S (mp);
14742   }
14743   /* Wait for a reply... */
14744   W (ret);
14745   return ret;
14746 }
14747
14748 static int
14749 api_lisp_eid_table_map_dump (vat_main_t * vam)
14750 {
14751   u8 is_l2 = 0;
14752   u8 mode_set = 0;
14753   unformat_input_t *input = vam->input;
14754   vl_api_lisp_eid_table_map_dump_t *mp;
14755   int ret;
14756
14757   /* Parse args required to build the message */
14758   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14759     {
14760       if (unformat (input, "l2"))
14761         {
14762           is_l2 = 1;
14763           mode_set = 1;
14764         }
14765       else if (unformat (input, "l3"))
14766         {
14767           is_l2 = 0;
14768           mode_set = 1;
14769         }
14770       else
14771         {
14772           errmsg ("parse error '%U'", format_unformat_error, input);
14773           return -99;
14774         }
14775     }
14776
14777   if (!mode_set)
14778     {
14779       errmsg ("expected one of 'l2' or 'l3' parameter!");
14780       return -99;
14781     }
14782
14783   if (!vam->json_output)
14784     {
14785       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14786     }
14787
14788   M (LISP_EID_TABLE_MAP_DUMP, mp);
14789   mp->is_l2 = is_l2;
14790
14791   /* send it... */
14792   S (mp);
14793
14794   /* Use a control ping for synchronization */
14795   {
14796     vl_api_control_ping_t *mp;
14797     M (CONTROL_PING, mp);
14798     S (mp);
14799   }
14800   /* Wait for a reply... */
14801   W (ret);
14802   return ret;
14803 }
14804
14805 static int
14806 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14807 {
14808   vl_api_lisp_eid_table_vni_dump_t *mp;
14809   int ret;
14810
14811   if (!vam->json_output)
14812     {
14813       print (vam->ofp, "VNI");
14814     }
14815
14816   M (LISP_EID_TABLE_VNI_DUMP, mp);
14817
14818   /* send it... */
14819   S (mp);
14820
14821   /* Use a control ping for synchronization */
14822   {
14823     vl_api_control_ping_t *mp;
14824     M (CONTROL_PING, mp);
14825     S (mp);
14826   }
14827   /* Wait for a reply... */
14828   W (ret);
14829   return ret;
14830 }
14831
14832 static int
14833 api_lisp_eid_table_dump (vat_main_t * vam)
14834 {
14835   unformat_input_t *i = vam->input;
14836   vl_api_lisp_eid_table_dump_t *mp;
14837   struct in_addr ip4;
14838   struct in6_addr ip6;
14839   u8 mac[6];
14840   u8 eid_type = ~0, eid_set = 0;
14841   u32 prefix_length = ~0, t, vni = 0;
14842   u8 filter = 0;
14843   int ret;
14844
14845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14846     {
14847       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14848         {
14849           eid_set = 1;
14850           eid_type = 0;
14851           prefix_length = t;
14852         }
14853       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14854         {
14855           eid_set = 1;
14856           eid_type = 1;
14857           prefix_length = t;
14858         }
14859       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14860         {
14861           eid_set = 1;
14862           eid_type = 2;
14863         }
14864       else if (unformat (i, "vni %d", &t))
14865         {
14866           vni = t;
14867         }
14868       else if (unformat (i, "local"))
14869         {
14870           filter = 1;
14871         }
14872       else if (unformat (i, "remote"))
14873         {
14874           filter = 2;
14875         }
14876       else
14877         {
14878           errmsg ("parse error '%U'", format_unformat_error, i);
14879           return -99;
14880         }
14881     }
14882
14883   if (!vam->json_output)
14884     {
14885       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14886              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14887     }
14888
14889   M (LISP_EID_TABLE_DUMP, mp);
14890
14891   mp->filter = filter;
14892   if (eid_set)
14893     {
14894       mp->eid_set = 1;
14895       mp->vni = htonl (vni);
14896       mp->eid_type = eid_type;
14897       switch (eid_type)
14898         {
14899         case 0:
14900           mp->prefix_length = prefix_length;
14901           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14902           break;
14903         case 1:
14904           mp->prefix_length = prefix_length;
14905           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14906           break;
14907         case 2:
14908           clib_memcpy (mp->eid, mac, sizeof (mac));
14909           break;
14910         default:
14911           errmsg ("unknown EID type %d!", eid_type);
14912           return -99;
14913         }
14914     }
14915
14916   /* send it... */
14917   S (mp);
14918
14919   /* Use a control ping for synchronization */
14920   {
14921     vl_api_control_ping_t *mp;
14922     M (CONTROL_PING, mp);
14923     S (mp);
14924   }
14925
14926   /* Wait for a reply... */
14927   W (ret);
14928   return ret;
14929 }
14930
14931 static int
14932 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
14933 {
14934   unformat_input_t *i = vam->input;
14935   vl_api_lisp_gpe_fwd_entries_get_t *mp;
14936   u8 vni_set = 0;
14937   u32 vni = ~0;
14938   int ret;
14939
14940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14941     {
14942       if (unformat (i, "vni %d", &vni))
14943         {
14944           vni_set = 1;
14945         }
14946       else
14947         {
14948           errmsg ("parse error '%U'", format_unformat_error, i);
14949           return -99;
14950         }
14951     }
14952
14953   if (!vni_set)
14954     {
14955       errmsg ("vni not set!");
14956       return -99;
14957     }
14958
14959   if (!vam->json_output)
14960     {
14961       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
14962              "leid", "reid");
14963     }
14964
14965   M (LISP_GPE_FWD_ENTRIES_GET, mp);
14966   mp->vni = clib_host_to_net_u32 (vni);
14967
14968   /* send it... */
14969   S (mp);
14970
14971   /* Wait for a reply... */
14972   W (ret);
14973   return ret;
14974 }
14975
14976 #define vl_api_lisp_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
14977 #define vl_api_lisp_gpe_fwd_entries_get_reply_t_print vl_noop_handler
14978 #define vl_api_lisp_gpe_fwd_entry_path_details_t_endian vl_noop_handler
14979 #define vl_api_lisp_gpe_fwd_entry_path_details_t_print vl_noop_handler
14980
14981 static int
14982 api_lisp_adjacencies_get (vat_main_t * vam)
14983 {
14984   unformat_input_t *i = vam->input;
14985   vl_api_lisp_adjacencies_get_t *mp;
14986   u8 vni_set = 0;
14987   u32 vni = ~0;
14988   int ret;
14989
14990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14991     {
14992       if (unformat (i, "vni %d", &vni))
14993         {
14994           vni_set = 1;
14995         }
14996       else
14997         {
14998           errmsg ("parse error '%U'", format_unformat_error, i);
14999           return -99;
15000         }
15001     }
15002
15003   if (!vni_set)
15004     {
15005       errmsg ("vni not set!");
15006       return -99;
15007     }
15008
15009   if (!vam->json_output)
15010     {
15011       print (vam->ofp, "%s %40s", "leid", "reid");
15012     }
15013
15014   M (LISP_ADJACENCIES_GET, mp);
15015   mp->vni = clib_host_to_net_u32 (vni);
15016
15017   /* send it... */
15018   S (mp);
15019
15020   /* Wait for a reply... */
15021   W (ret);
15022   return ret;
15023 }
15024
15025 static int
15026 api_lisp_map_server_dump (vat_main_t * vam)
15027 {
15028   vl_api_lisp_map_server_dump_t *mp;
15029   int ret;
15030
15031   if (!vam->json_output)
15032     {
15033       print (vam->ofp, "%=20s", "Map server");
15034     }
15035
15036   M (LISP_MAP_SERVER_DUMP, mp);
15037   /* send it... */
15038   S (mp);
15039
15040   /* Use a control ping for synchronization */
15041   {
15042     vl_api_control_ping_t *mp;
15043     M (CONTROL_PING, mp);
15044     S (mp);
15045   }
15046   /* Wait for a reply... */
15047   W (ret);
15048   return ret;
15049 }
15050
15051 static int
15052 api_lisp_map_resolver_dump (vat_main_t * vam)
15053 {
15054   vl_api_lisp_map_resolver_dump_t *mp;
15055   int ret;
15056
15057   if (!vam->json_output)
15058     {
15059       print (vam->ofp, "%=20s", "Map resolver");
15060     }
15061
15062   M (LISP_MAP_RESOLVER_DUMP, mp);
15063   /* send it... */
15064   S (mp);
15065
15066   /* Use a control ping for synchronization */
15067   {
15068     vl_api_control_ping_t *mp;
15069     M (CONTROL_PING, mp);
15070     S (mp);
15071   }
15072   /* Wait for a reply... */
15073   W (ret);
15074   return ret;
15075 }
15076
15077 static int
15078 api_show_lisp_status (vat_main_t * vam)
15079 {
15080   vl_api_show_lisp_status_t *mp;
15081   int ret;
15082
15083   if (!vam->json_output)
15084     {
15085       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
15086     }
15087
15088   M (SHOW_LISP_STATUS, mp);
15089   /* send it... */
15090   S (mp);
15091   /* Wait for a reply... */
15092   W (ret);
15093   return ret;
15094 }
15095
15096 static int
15097 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15098 {
15099   vl_api_lisp_gpe_fwd_entry_path_dump_t *mp;
15100   unformat_input_t *i = vam->input;
15101   u32 fwd_entry_index = ~0;
15102   int ret;
15103
15104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15105     {
15106       if (unformat (i, "index %d", &fwd_entry_index))
15107         ;
15108       else
15109         break;
15110     }
15111
15112   if (~0 == fwd_entry_index)
15113     {
15114       errmsg ("no index specified!");
15115       return -99;
15116     }
15117
15118   if (!vam->json_output)
15119     {
15120       print (vam->ofp, "first line");
15121     }
15122
15123   M (LISP_GPE_FWD_ENTRY_PATH_DUMP, mp);
15124
15125   /* send it... */
15126   S (mp);
15127   /* Use a control ping for synchronization */
15128   {
15129     vl_api_control_ping_t *mp;
15130     M (CONTROL_PING, mp);
15131     S (mp);
15132   }
15133   /* Wait for a reply... */
15134   W (ret);
15135   return ret;
15136 }
15137
15138 static int
15139 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
15140 {
15141   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
15142   int ret;
15143
15144   if (!vam->json_output)
15145     {
15146       print (vam->ofp, "%=20s", "itr-rlocs:");
15147     }
15148
15149   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, mp);
15150   /* send it... */
15151   S (mp);
15152   /* Wait for a reply... */
15153   W (ret);
15154   return ret;
15155 }
15156
15157 static int
15158 api_af_packet_create (vat_main_t * vam)
15159 {
15160   unformat_input_t *i = vam->input;
15161   vl_api_af_packet_create_t *mp;
15162   u8 *host_if_name = 0;
15163   u8 hw_addr[6];
15164   u8 random_hw_addr = 1;
15165   int ret;
15166
15167   memset (hw_addr, 0, sizeof (hw_addr));
15168
15169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15170     {
15171       if (unformat (i, "name %s", &host_if_name))
15172         vec_add1 (host_if_name, 0);
15173       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15174         random_hw_addr = 0;
15175       else
15176         break;
15177     }
15178
15179   if (!vec_len (host_if_name))
15180     {
15181       errmsg ("host-interface name must be specified");
15182       return -99;
15183     }
15184
15185   if (vec_len (host_if_name) > 64)
15186     {
15187       errmsg ("host-interface name too long");
15188       return -99;
15189     }
15190
15191   M (AF_PACKET_CREATE, mp);
15192
15193   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15194   clib_memcpy (mp->hw_addr, hw_addr, 6);
15195   mp->use_random_hw_addr = random_hw_addr;
15196   vec_free (host_if_name);
15197
15198   S (mp);
15199   W2 (ret, fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15200   return ret;
15201 }
15202
15203 static int
15204 api_af_packet_delete (vat_main_t * vam)
15205 {
15206   unformat_input_t *i = vam->input;
15207   vl_api_af_packet_delete_t *mp;
15208   u8 *host_if_name = 0;
15209   int ret;
15210
15211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15212     {
15213       if (unformat (i, "name %s", &host_if_name))
15214         vec_add1 (host_if_name, 0);
15215       else
15216         break;
15217     }
15218
15219   if (!vec_len (host_if_name))
15220     {
15221       errmsg ("host-interface name must be specified");
15222       return -99;
15223     }
15224
15225   if (vec_len (host_if_name) > 64)
15226     {
15227       errmsg ("host-interface name too long");
15228       return -99;
15229     }
15230
15231   M (AF_PACKET_DELETE, mp);
15232
15233   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15234   vec_free (host_if_name);
15235
15236   S (mp);
15237   W (ret);
15238   return ret;
15239 }
15240
15241 static int
15242 api_policer_add_del (vat_main_t * vam)
15243 {
15244   unformat_input_t *i = vam->input;
15245   vl_api_policer_add_del_t *mp;
15246   u8 is_add = 1;
15247   u8 *name = 0;
15248   u32 cir = 0;
15249   u32 eir = 0;
15250   u64 cb = 0;
15251   u64 eb = 0;
15252   u8 rate_type = 0;
15253   u8 round_type = 0;
15254   u8 type = 0;
15255   u8 color_aware = 0;
15256   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15257   int ret;
15258
15259   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15260   conform_action.dscp = 0;
15261   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15262   exceed_action.dscp = 0;
15263   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15264   violate_action.dscp = 0;
15265
15266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15267     {
15268       if (unformat (i, "del"))
15269         is_add = 0;
15270       else if (unformat (i, "name %s", &name))
15271         vec_add1 (name, 0);
15272       else if (unformat (i, "cir %u", &cir))
15273         ;
15274       else if (unformat (i, "eir %u", &eir))
15275         ;
15276       else if (unformat (i, "cb %u", &cb))
15277         ;
15278       else if (unformat (i, "eb %u", &eb))
15279         ;
15280       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15281                          &rate_type))
15282         ;
15283       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15284                          &round_type))
15285         ;
15286       else if (unformat (i, "type %U", unformat_policer_type, &type))
15287         ;
15288       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15289                          &conform_action))
15290         ;
15291       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15292                          &exceed_action))
15293         ;
15294       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15295                          &violate_action))
15296         ;
15297       else if (unformat (i, "color-aware"))
15298         color_aware = 1;
15299       else
15300         break;
15301     }
15302
15303   if (!vec_len (name))
15304     {
15305       errmsg ("policer name must be specified");
15306       return -99;
15307     }
15308
15309   if (vec_len (name) > 64)
15310     {
15311       errmsg ("policer name too long");
15312       return -99;
15313     }
15314
15315   M (POLICER_ADD_DEL, mp);
15316
15317   clib_memcpy (mp->name, name, vec_len (name));
15318   vec_free (name);
15319   mp->is_add = is_add;
15320   mp->cir = cir;
15321   mp->eir = eir;
15322   mp->cb = cb;
15323   mp->eb = eb;
15324   mp->rate_type = rate_type;
15325   mp->round_type = round_type;
15326   mp->type = type;
15327   mp->conform_action_type = conform_action.action_type;
15328   mp->conform_dscp = conform_action.dscp;
15329   mp->exceed_action_type = exceed_action.action_type;
15330   mp->exceed_dscp = exceed_action.dscp;
15331   mp->violate_action_type = violate_action.action_type;
15332   mp->violate_dscp = violate_action.dscp;
15333   mp->color_aware = color_aware;
15334
15335   S (mp);
15336   W (ret);
15337   return ret;
15338 }
15339
15340 static int
15341 api_policer_dump (vat_main_t * vam)
15342 {
15343   unformat_input_t *i = vam->input;
15344   vl_api_policer_dump_t *mp;
15345   u8 *match_name = 0;
15346   u8 match_name_valid = 0;
15347   int ret;
15348
15349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15350     {
15351       if (unformat (i, "name %s", &match_name))
15352         {
15353           vec_add1 (match_name, 0);
15354           match_name_valid = 1;
15355         }
15356       else
15357         break;
15358     }
15359
15360   M (POLICER_DUMP, mp);
15361   mp->match_name_valid = match_name_valid;
15362   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15363   vec_free (match_name);
15364   /* send it... */
15365   S (mp);
15366
15367   /* Use a control ping for synchronization */
15368   {
15369     vl_api_control_ping_t *mp;
15370     M (CONTROL_PING, mp);
15371     S (mp);
15372   }
15373   /* Wait for a reply... */
15374   W (ret);
15375   return ret;
15376 }
15377
15378 static int
15379 api_policer_classify_set_interface (vat_main_t * vam)
15380 {
15381   unformat_input_t *i = vam->input;
15382   vl_api_policer_classify_set_interface_t *mp;
15383   u32 sw_if_index;
15384   int sw_if_index_set;
15385   u32 ip4_table_index = ~0;
15386   u32 ip6_table_index = ~0;
15387   u32 l2_table_index = ~0;
15388   u8 is_add = 1;
15389   int ret;
15390
15391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15392     {
15393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15394         sw_if_index_set = 1;
15395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15396         sw_if_index_set = 1;
15397       else if (unformat (i, "del"))
15398         is_add = 0;
15399       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15400         ;
15401       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15402         ;
15403       else if (unformat (i, "l2-table %d", &l2_table_index))
15404         ;
15405       else
15406         {
15407           clib_warning ("parse error '%U'", format_unformat_error, i);
15408           return -99;
15409         }
15410     }
15411
15412   if (sw_if_index_set == 0)
15413     {
15414       errmsg ("missing interface name or sw_if_index");
15415       return -99;
15416     }
15417
15418   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15419
15420   mp->sw_if_index = ntohl (sw_if_index);
15421   mp->ip4_table_index = ntohl (ip4_table_index);
15422   mp->ip6_table_index = ntohl (ip6_table_index);
15423   mp->l2_table_index = ntohl (l2_table_index);
15424   mp->is_add = is_add;
15425
15426   S (mp);
15427   W (ret);
15428   return ret;
15429 }
15430
15431 static int
15432 api_policer_classify_dump (vat_main_t * vam)
15433 {
15434   unformat_input_t *i = vam->input;
15435   vl_api_policer_classify_dump_t *mp;
15436   u8 type = POLICER_CLASSIFY_N_TABLES;
15437   int ret;
15438
15439   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15440     ;
15441   else
15442     {
15443       errmsg ("classify table type must be specified");
15444       return -99;
15445     }
15446
15447   if (!vam->json_output)
15448     {
15449       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15450     }
15451
15452   M (POLICER_CLASSIFY_DUMP, mp);
15453   mp->type = type;
15454   /* send it... */
15455   S (mp);
15456
15457   /* Use a control ping for synchronization */
15458   {
15459     vl_api_control_ping_t *mp;
15460     M (CONTROL_PING, mp);
15461     S (mp);
15462   }
15463   /* Wait for a reply... */
15464   W (ret);
15465   return ret;
15466 }
15467
15468 static int
15469 api_netmap_create (vat_main_t * vam)
15470 {
15471   unformat_input_t *i = vam->input;
15472   vl_api_netmap_create_t *mp;
15473   u8 *if_name = 0;
15474   u8 hw_addr[6];
15475   u8 random_hw_addr = 1;
15476   u8 is_pipe = 0;
15477   u8 is_master = 0;
15478   int ret;
15479
15480   memset (hw_addr, 0, sizeof (hw_addr));
15481
15482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15483     {
15484       if (unformat (i, "name %s", &if_name))
15485         vec_add1 (if_name, 0);
15486       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15487         random_hw_addr = 0;
15488       else if (unformat (i, "pipe"))
15489         is_pipe = 1;
15490       else if (unformat (i, "master"))
15491         is_master = 1;
15492       else if (unformat (i, "slave"))
15493         is_master = 0;
15494       else
15495         break;
15496     }
15497
15498   if (!vec_len (if_name))
15499     {
15500       errmsg ("interface name must be specified");
15501       return -99;
15502     }
15503
15504   if (vec_len (if_name) > 64)
15505     {
15506       errmsg ("interface name too long");
15507       return -99;
15508     }
15509
15510   M (NETMAP_CREATE, mp);
15511
15512   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15513   clib_memcpy (mp->hw_addr, hw_addr, 6);
15514   mp->use_random_hw_addr = random_hw_addr;
15515   mp->is_pipe = is_pipe;
15516   mp->is_master = is_master;
15517   vec_free (if_name);
15518
15519   S (mp);
15520   W (ret);
15521   return ret;
15522 }
15523
15524 static int
15525 api_netmap_delete (vat_main_t * vam)
15526 {
15527   unformat_input_t *i = vam->input;
15528   vl_api_netmap_delete_t *mp;
15529   u8 *if_name = 0;
15530   int ret;
15531
15532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15533     {
15534       if (unformat (i, "name %s", &if_name))
15535         vec_add1 (if_name, 0);
15536       else
15537         break;
15538     }
15539
15540   if (!vec_len (if_name))
15541     {
15542       errmsg ("interface name must be specified");
15543       return -99;
15544     }
15545
15546   if (vec_len (if_name) > 64)
15547     {
15548       errmsg ("interface name too long");
15549       return -99;
15550     }
15551
15552   M (NETMAP_DELETE, mp);
15553
15554   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15555   vec_free (if_name);
15556
15557   S (mp);
15558   W (ret);
15559   return ret;
15560 }
15561
15562 static void vl_api_mpls_tunnel_details_t_handler
15563   (vl_api_mpls_tunnel_details_t * mp)
15564 {
15565   vat_main_t *vam = &vat_main;
15566   i32 len = mp->mt_next_hop_n_labels;
15567   i32 i;
15568
15569   print (vam->ofp, "[%d]: via %U %d labels ",
15570          mp->tunnel_index,
15571          format_ip4_address, mp->mt_next_hop,
15572          ntohl (mp->mt_next_hop_sw_if_index));
15573   for (i = 0; i < len; i++)
15574     {
15575       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15576     }
15577   print (vam->ofp, "");
15578 }
15579
15580 static void vl_api_mpls_tunnel_details_t_handler_json
15581   (vl_api_mpls_tunnel_details_t * mp)
15582 {
15583   vat_main_t *vam = &vat_main;
15584   vat_json_node_t *node = NULL;
15585   struct in_addr ip4;
15586   i32 i;
15587   i32 len = mp->mt_next_hop_n_labels;
15588
15589   if (VAT_JSON_ARRAY != vam->json_tree.type)
15590     {
15591       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15592       vat_json_init_array (&vam->json_tree);
15593     }
15594   node = vat_json_array_add (&vam->json_tree);
15595
15596   vat_json_init_object (node);
15597   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15598   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15599   vat_json_object_add_ip4 (node, "next_hop", ip4);
15600   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15601                             ntohl (mp->mt_next_hop_sw_if_index));
15602   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15603   vat_json_object_add_uint (node, "label_count", len);
15604   for (i = 0; i < len; i++)
15605     {
15606       vat_json_object_add_uint (node, "label",
15607                                 ntohl (mp->mt_next_hop_out_labels[i]));
15608     }
15609 }
15610
15611 static int
15612 api_mpls_tunnel_dump (vat_main_t * vam)
15613 {
15614   vl_api_mpls_tunnel_dump_t *mp;
15615   i32 index = -1;
15616   int ret;
15617
15618   /* Parse args required to build the message */
15619   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15620     {
15621       if (!unformat (vam->input, "tunnel_index %d", &index))
15622         {
15623           index = -1;
15624           break;
15625         }
15626     }
15627
15628   print (vam->ofp, "  tunnel_index %d", index);
15629
15630   M (MPLS_TUNNEL_DUMP, mp);
15631   mp->tunnel_index = htonl (index);
15632   S (mp);
15633
15634   /* Use a control ping for synchronization */
15635   {
15636     vl_api_control_ping_t *mp;
15637     M (CONTROL_PING, mp);
15638     S (mp);
15639   }
15640   W (ret);
15641   return ret;
15642 }
15643
15644 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15645 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15646
15647 static void
15648 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15649 {
15650   vat_main_t *vam = &vat_main;
15651   int count = ntohl (mp->count);
15652   vl_api_fib_path2_t *fp;
15653   int i;
15654
15655   print (vam->ofp,
15656          "table-id %d, label %u, ess_bit %u",
15657          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15658   fp = mp->path;
15659   for (i = 0; i < count; i++)
15660     {
15661       if (fp->afi == IP46_TYPE_IP6)
15662         print (vam->ofp,
15663                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15664                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15665                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15666                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15667                format_ip6_address, fp->next_hop);
15668       else if (fp->afi == IP46_TYPE_IP4)
15669         print (vam->ofp,
15670                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15671                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15672                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15673                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15674                format_ip4_address, fp->next_hop);
15675       fp++;
15676     }
15677 }
15678
15679 static void vl_api_mpls_fib_details_t_handler_json
15680   (vl_api_mpls_fib_details_t * mp)
15681 {
15682   vat_main_t *vam = &vat_main;
15683   int count = ntohl (mp->count);
15684   vat_json_node_t *node = NULL;
15685   struct in_addr ip4;
15686   struct in6_addr ip6;
15687   vl_api_fib_path2_t *fp;
15688   int i;
15689
15690   if (VAT_JSON_ARRAY != vam->json_tree.type)
15691     {
15692       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15693       vat_json_init_array (&vam->json_tree);
15694     }
15695   node = vat_json_array_add (&vam->json_tree);
15696
15697   vat_json_init_object (node);
15698   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15699   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15700   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15701   vat_json_object_add_uint (node, "path_count", count);
15702   fp = mp->path;
15703   for (i = 0; i < count; i++)
15704     {
15705       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15706       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15707       vat_json_object_add_uint (node, "is_local", fp->is_local);
15708       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15709       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15710       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15711       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15712       if (fp->afi == IP46_TYPE_IP4)
15713         {
15714           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15715           vat_json_object_add_ip4 (node, "next_hop", ip4);
15716         }
15717       else if (fp->afi == IP46_TYPE_IP6)
15718         {
15719           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15720           vat_json_object_add_ip6 (node, "next_hop", ip6);
15721         }
15722     }
15723 }
15724
15725 static int
15726 api_mpls_fib_dump (vat_main_t * vam)
15727 {
15728   vl_api_mpls_fib_dump_t *mp;
15729   int ret;
15730
15731   M (MPLS_FIB_DUMP, mp);
15732   S (mp);
15733
15734   /* Use a control ping for synchronization */
15735   {
15736     vl_api_control_ping_t *mp;
15737     M (CONTROL_PING, mp);
15738     S (mp);
15739   }
15740   W (ret);
15741   return ret;
15742 }
15743
15744 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15745 #define vl_api_ip_fib_details_t_print vl_noop_handler
15746
15747 static void
15748 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15749 {
15750   vat_main_t *vam = &vat_main;
15751   int count = ntohl (mp->count);
15752   vl_api_fib_path_t *fp;
15753   int i;
15754
15755   print (vam->ofp,
15756          "table-id %d, prefix %U/%d",
15757          ntohl (mp->table_id), format_ip4_address, mp->address,
15758          mp->address_length);
15759   fp = mp->path;
15760   for (i = 0; i < count; i++)
15761     {
15762       if (fp->afi == IP46_TYPE_IP6)
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_ip6_address, fp->next_hop);
15769       else if (fp->afi == IP46_TYPE_IP4)
15770         print (vam->ofp,
15771                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15772                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15773                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15774                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15775                format_ip4_address, fp->next_hop);
15776       fp++;
15777     }
15778 }
15779
15780 static void vl_api_ip_fib_details_t_handler_json
15781   (vl_api_ip_fib_details_t * mp)
15782 {
15783   vat_main_t *vam = &vat_main;
15784   int count = ntohl (mp->count);
15785   vat_json_node_t *node = NULL;
15786   struct in_addr ip4;
15787   struct in6_addr ip6;
15788   vl_api_fib_path_t *fp;
15789   int i;
15790
15791   if (VAT_JSON_ARRAY != vam->json_tree.type)
15792     {
15793       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15794       vat_json_init_array (&vam->json_tree);
15795     }
15796   node = vat_json_array_add (&vam->json_tree);
15797
15798   vat_json_init_object (node);
15799   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15800   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15801   vat_json_object_add_ip4 (node, "prefix", ip4);
15802   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15803   vat_json_object_add_uint (node, "path_count", count);
15804   fp = mp->path;
15805   for (i = 0; i < count; i++)
15806     {
15807       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15808       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15809       vat_json_object_add_uint (node, "is_local", fp->is_local);
15810       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15811       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15812       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15813       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15814       if (fp->afi == IP46_TYPE_IP4)
15815         {
15816           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15817           vat_json_object_add_ip4 (node, "next_hop", ip4);
15818         }
15819       else if (fp->afi == IP46_TYPE_IP6)
15820         {
15821           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15822           vat_json_object_add_ip6 (node, "next_hop", ip6);
15823         }
15824     }
15825 }
15826
15827 static int
15828 api_ip_fib_dump (vat_main_t * vam)
15829 {
15830   vl_api_ip_fib_dump_t *mp;
15831   int ret;
15832
15833   M (IP_FIB_DUMP, mp);
15834   S (mp);
15835
15836   /* Use a control ping for synchronization */
15837   {
15838     vl_api_control_ping_t *mp;
15839     M (CONTROL_PING, mp);
15840     S (mp);
15841   }
15842   W (ret);
15843   return ret;
15844 }
15845
15846 static void vl_api_ip_neighbor_details_t_handler
15847   (vl_api_ip_neighbor_details_t * mp)
15848 {
15849   vat_main_t *vam = &vat_main;
15850
15851   print (vam->ofp, "%c %U %U",
15852          (mp->is_static) ? 'S' : 'D',
15853          format_ethernet_address, &mp->mac_address,
15854          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15855          &mp->ip_address);
15856 }
15857
15858 static void vl_api_ip_neighbor_details_t_handler_json
15859   (vl_api_ip_neighbor_details_t * mp)
15860 {
15861
15862   vat_main_t *vam = &vat_main;
15863   vat_json_node_t *node;
15864   struct in_addr ip4;
15865   struct in6_addr ip6;
15866
15867   if (VAT_JSON_ARRAY != vam->json_tree.type)
15868     {
15869       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15870       vat_json_init_array (&vam->json_tree);
15871     }
15872   node = vat_json_array_add (&vam->json_tree);
15873
15874   vat_json_init_object (node);
15875   vat_json_object_add_string_copy (node, "flag",
15876                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15877                                    "dynamic");
15878
15879   vat_json_object_add_string_copy (node, "link_layer",
15880                                    format (0, "%U", format_ethernet_address,
15881                                            &mp->mac_address));
15882
15883   if (mp->is_ipv6)
15884     {
15885       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15886       vat_json_object_add_ip6 (node, "ip_address", ip6);
15887     }
15888   else
15889     {
15890       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15891       vat_json_object_add_ip4 (node, "ip_address", ip4);
15892     }
15893 }
15894
15895 static int
15896 api_ip_neighbor_dump (vat_main_t * vam)
15897 {
15898   unformat_input_t *i = vam->input;
15899   vl_api_ip_neighbor_dump_t *mp;
15900   u8 is_ipv6 = 0;
15901   u32 sw_if_index = ~0;
15902   int ret;
15903
15904   /* Parse args required to build the message */
15905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15906     {
15907       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15908         ;
15909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15910         ;
15911       else if (unformat (i, "ip6"))
15912         is_ipv6 = 1;
15913       else
15914         break;
15915     }
15916
15917   if (sw_if_index == ~0)
15918     {
15919       errmsg ("missing interface name or sw_if_index");
15920       return -99;
15921     }
15922
15923   M (IP_NEIGHBOR_DUMP, mp);
15924   mp->is_ipv6 = (u8) is_ipv6;
15925   mp->sw_if_index = ntohl (sw_if_index);
15926   S (mp);
15927
15928   /* Use a control ping for synchronization */
15929   {
15930     vl_api_control_ping_t *mp;
15931     M (CONTROL_PING, mp);
15932     S (mp);
15933   }
15934   W (ret);
15935   return ret;
15936 }
15937
15938 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15939 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15940
15941 static void
15942 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15943 {
15944   vat_main_t *vam = &vat_main;
15945   int count = ntohl (mp->count);
15946   vl_api_fib_path_t *fp;
15947   int i;
15948
15949   print (vam->ofp,
15950          "table-id %d, prefix %U/%d",
15951          ntohl (mp->table_id), format_ip6_address, mp->address,
15952          mp->address_length);
15953   fp = mp->path;
15954   for (i = 0; i < count; i++)
15955     {
15956       if (fp->afi == IP46_TYPE_IP6)
15957         print (vam->ofp,
15958                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15959                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15960                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15961                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15962                format_ip6_address, fp->next_hop);
15963       else if (fp->afi == IP46_TYPE_IP4)
15964         print (vam->ofp,
15965                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15966                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15967                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15968                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15969                format_ip4_address, fp->next_hop);
15970       fp++;
15971     }
15972 }
15973
15974 static void vl_api_ip6_fib_details_t_handler_json
15975   (vl_api_ip6_fib_details_t * mp)
15976 {
15977   vat_main_t *vam = &vat_main;
15978   int count = ntohl (mp->count);
15979   vat_json_node_t *node = NULL;
15980   struct in_addr ip4;
15981   struct in6_addr ip6;
15982   vl_api_fib_path_t *fp;
15983   int i;
15984
15985   if (VAT_JSON_ARRAY != vam->json_tree.type)
15986     {
15987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15988       vat_json_init_array (&vam->json_tree);
15989     }
15990   node = vat_json_array_add (&vam->json_tree);
15991
15992   vat_json_init_object (node);
15993   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15994   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15995   vat_json_object_add_ip6 (node, "prefix", ip6);
15996   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15997   vat_json_object_add_uint (node, "path_count", count);
15998   fp = mp->path;
15999   for (i = 0; i < count; i++)
16000     {
16001       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16002       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16003       vat_json_object_add_uint (node, "is_local", fp->is_local);
16004       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16005       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16006       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16007       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16008       if (fp->afi == IP46_TYPE_IP4)
16009         {
16010           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16011           vat_json_object_add_ip4 (node, "next_hop", ip4);
16012         }
16013       else if (fp->afi == IP46_TYPE_IP6)
16014         {
16015           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16016           vat_json_object_add_ip6 (node, "next_hop", ip6);
16017         }
16018     }
16019 }
16020
16021 static int
16022 api_ip6_fib_dump (vat_main_t * vam)
16023 {
16024   vl_api_ip6_fib_dump_t *mp;
16025   int ret;
16026
16027   M (IP6_FIB_DUMP, mp);
16028   S (mp);
16029
16030   /* Use a control ping for synchronization */
16031   {
16032     vl_api_control_ping_t *mp;
16033     M (CONTROL_PING, mp);
16034     S (mp);
16035   }
16036   W (ret);
16037   return ret;
16038 }
16039
16040 int
16041 api_classify_table_ids (vat_main_t * vam)
16042 {
16043   vl_api_classify_table_ids_t *mp;
16044   int ret;
16045
16046   /* Construct the API message */
16047   M (CLASSIFY_TABLE_IDS, mp);
16048   mp->context = 0;
16049
16050   S (mp);
16051   W (ret);
16052   return ret;
16053 }
16054
16055 int
16056 api_classify_table_by_interface (vat_main_t * vam)
16057 {
16058   unformat_input_t *input = vam->input;
16059   vl_api_classify_table_by_interface_t *mp;
16060
16061   u32 sw_if_index = ~0;
16062   int ret;
16063   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16064     {
16065       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16066         ;
16067       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16068         ;
16069       else
16070         break;
16071     }
16072   if (sw_if_index == ~0)
16073     {
16074       errmsg ("missing interface name or sw_if_index");
16075       return -99;
16076     }
16077
16078   /* Construct the API message */
16079   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16080   mp->context = 0;
16081   mp->sw_if_index = ntohl (sw_if_index);
16082
16083   S (mp);
16084   W (ret);
16085   return ret;
16086 }
16087
16088 int
16089 api_classify_table_info (vat_main_t * vam)
16090 {
16091   unformat_input_t *input = vam->input;
16092   vl_api_classify_table_info_t *mp;
16093
16094   u32 table_id = ~0;
16095   int ret;
16096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16097     {
16098       if (unformat (input, "table_id %d", &table_id))
16099         ;
16100       else
16101         break;
16102     }
16103   if (table_id == ~0)
16104     {
16105       errmsg ("missing table id");
16106       return -99;
16107     }
16108
16109   /* Construct the API message */
16110   M (CLASSIFY_TABLE_INFO, mp);
16111   mp->context = 0;
16112   mp->table_id = ntohl (table_id);
16113
16114   S (mp);
16115   W (ret);
16116   return ret;
16117 }
16118
16119 int
16120 api_classify_session_dump (vat_main_t * vam)
16121 {
16122   unformat_input_t *input = vam->input;
16123   vl_api_classify_session_dump_t *mp;
16124
16125   u32 table_id = ~0;
16126   int ret;
16127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16128     {
16129       if (unformat (input, "table_id %d", &table_id))
16130         ;
16131       else
16132         break;
16133     }
16134   if (table_id == ~0)
16135     {
16136       errmsg ("missing table id");
16137       return -99;
16138     }
16139
16140   /* Construct the API message */
16141   M (CLASSIFY_SESSION_DUMP, mp);
16142   mp->context = 0;
16143   mp->table_id = ntohl (table_id);
16144   S (mp);
16145
16146   /* Use a control ping for synchronization */
16147   {
16148     vl_api_control_ping_t *mp;
16149     M (CONTROL_PING, mp);
16150     S (mp);
16151   }
16152   W (ret);
16153   return ret;
16154 }
16155
16156 static void
16157 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16158 {
16159   vat_main_t *vam = &vat_main;
16160
16161   print (vam->ofp, "collector_address %U, collector_port %d, "
16162          "src_address %U, vrf_id %d, path_mtu %u, "
16163          "template_interval %u, udp_checksum %d",
16164          format_ip4_address, mp->collector_address,
16165          ntohs (mp->collector_port),
16166          format_ip4_address, mp->src_address,
16167          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16168          ntohl (mp->template_interval), mp->udp_checksum);
16169
16170   vam->retval = 0;
16171   vam->result_ready = 1;
16172 }
16173
16174 static void
16175   vl_api_ipfix_exporter_details_t_handler_json
16176   (vl_api_ipfix_exporter_details_t * mp)
16177 {
16178   vat_main_t *vam = &vat_main;
16179   vat_json_node_t node;
16180   struct in_addr collector_address;
16181   struct in_addr src_address;
16182
16183   vat_json_init_object (&node);
16184   clib_memcpy (&collector_address, &mp->collector_address,
16185                sizeof (collector_address));
16186   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16187   vat_json_object_add_uint (&node, "collector_port",
16188                             ntohs (mp->collector_port));
16189   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16190   vat_json_object_add_ip4 (&node, "src_address", src_address);
16191   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16192   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16193   vat_json_object_add_uint (&node, "template_interval",
16194                             ntohl (mp->template_interval));
16195   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16196
16197   vat_json_print (vam->ofp, &node);
16198   vat_json_free (&node);
16199   vam->retval = 0;
16200   vam->result_ready = 1;
16201 }
16202
16203 int
16204 api_ipfix_exporter_dump (vat_main_t * vam)
16205 {
16206   vl_api_ipfix_exporter_dump_t *mp;
16207   int ret;
16208
16209   /* Construct the API message */
16210   M (IPFIX_EXPORTER_DUMP, mp);
16211   mp->context = 0;
16212
16213   S (mp);
16214   W (ret);
16215   return ret;
16216 }
16217
16218 static int
16219 api_ipfix_classify_stream_dump (vat_main_t * vam)
16220 {
16221   vl_api_ipfix_classify_stream_dump_t *mp;
16222   int ret;
16223
16224   /* Construct the API message */
16225   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16226   mp->context = 0;
16227
16228   S (mp);
16229   W (ret);
16230   return ret;
16231   /* NOTREACHED */
16232   return 0;
16233 }
16234
16235 static void
16236   vl_api_ipfix_classify_stream_details_t_handler
16237   (vl_api_ipfix_classify_stream_details_t * mp)
16238 {
16239   vat_main_t *vam = &vat_main;
16240   print (vam->ofp, "domain_id %d, src_port %d",
16241          ntohl (mp->domain_id), ntohs (mp->src_port));
16242   vam->retval = 0;
16243   vam->result_ready = 1;
16244 }
16245
16246 static void
16247   vl_api_ipfix_classify_stream_details_t_handler_json
16248   (vl_api_ipfix_classify_stream_details_t * mp)
16249 {
16250   vat_main_t *vam = &vat_main;
16251   vat_json_node_t node;
16252
16253   vat_json_init_object (&node);
16254   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16255   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16256
16257   vat_json_print (vam->ofp, &node);
16258   vat_json_free (&node);
16259   vam->retval = 0;
16260   vam->result_ready = 1;
16261 }
16262
16263 static int
16264 api_ipfix_classify_table_dump (vat_main_t * vam)
16265 {
16266   vl_api_ipfix_classify_table_dump_t *mp;
16267   int ret;
16268
16269   if (!vam->json_output)
16270     {
16271       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16272              "transport_protocol");
16273     }
16274
16275   /* Construct the API message */
16276   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16277
16278   /* send it... */
16279   S (mp);
16280
16281   /* Use a control ping for synchronization */
16282   {
16283     vl_api_control_ping_t *mp;
16284     M (CONTROL_PING, mp);
16285     S (mp);
16286   }
16287   W (ret);
16288   return ret;
16289 }
16290
16291 static void
16292   vl_api_ipfix_classify_table_details_t_handler
16293   (vl_api_ipfix_classify_table_details_t * mp)
16294 {
16295   vat_main_t *vam = &vat_main;
16296   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16297          mp->transport_protocol);
16298 }
16299
16300 static void
16301   vl_api_ipfix_classify_table_details_t_handler_json
16302   (vl_api_ipfix_classify_table_details_t * mp)
16303 {
16304   vat_json_node_t *node = NULL;
16305   vat_main_t *vam = &vat_main;
16306
16307   if (VAT_JSON_ARRAY != vam->json_tree.type)
16308     {
16309       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16310       vat_json_init_array (&vam->json_tree);
16311     }
16312
16313   node = vat_json_array_add (&vam->json_tree);
16314   vat_json_init_object (node);
16315
16316   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16317   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16318   vat_json_object_add_uint (node, "transport_protocol",
16319                             mp->transport_protocol);
16320 }
16321
16322 static int
16323 api_sw_interface_span_enable_disable (vat_main_t * vam)
16324 {
16325   unformat_input_t *i = vam->input;
16326   vl_api_sw_interface_span_enable_disable_t *mp;
16327   u32 src_sw_if_index = ~0;
16328   u32 dst_sw_if_index = ~0;
16329   u8 state = 3;
16330   int ret;
16331
16332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16333     {
16334       if (unformat
16335           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16336         ;
16337       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16338         ;
16339       else
16340         if (unformat
16341             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16342         ;
16343       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16344         ;
16345       else if (unformat (i, "disable"))
16346         state = 0;
16347       else if (unformat (i, "rx"))
16348         state = 1;
16349       else if (unformat (i, "tx"))
16350         state = 2;
16351       else if (unformat (i, "both"))
16352         state = 3;
16353       else
16354         break;
16355     }
16356
16357   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16358
16359   mp->sw_if_index_from = htonl (src_sw_if_index);
16360   mp->sw_if_index_to = htonl (dst_sw_if_index);
16361   mp->state = state;
16362
16363   S (mp);
16364   W (ret);
16365   return ret;
16366 }
16367
16368 static void
16369 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16370                                             * mp)
16371 {
16372   vat_main_t *vam = &vat_main;
16373   u8 *sw_if_from_name = 0;
16374   u8 *sw_if_to_name = 0;
16375   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16376   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16377   char *states[] = { "none", "rx", "tx", "both" };
16378   hash_pair_t *p;
16379
16380   /* *INDENT-OFF* */
16381   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16382   ({
16383     if ((u32) p->value[0] == sw_if_index_from)
16384       {
16385         sw_if_from_name = (u8 *)(p->key);
16386         if (sw_if_to_name)
16387           break;
16388       }
16389     if ((u32) p->value[0] == sw_if_index_to)
16390       {
16391         sw_if_to_name = (u8 *)(p->key);
16392         if (sw_if_from_name)
16393           break;
16394       }
16395   }));
16396   /* *INDENT-ON* */
16397   print (vam->ofp, "%20s => %20s (%s)",
16398          sw_if_from_name, sw_if_to_name, states[mp->state]);
16399 }
16400
16401 static void
16402   vl_api_sw_interface_span_details_t_handler_json
16403   (vl_api_sw_interface_span_details_t * mp)
16404 {
16405   vat_main_t *vam = &vat_main;
16406   vat_json_node_t *node = NULL;
16407   u8 *sw_if_from_name = 0;
16408   u8 *sw_if_to_name = 0;
16409   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16410   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16411   hash_pair_t *p;
16412
16413   /* *INDENT-OFF* */
16414   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16415   ({
16416     if ((u32) p->value[0] == sw_if_index_from)
16417       {
16418         sw_if_from_name = (u8 *)(p->key);
16419         if (sw_if_to_name)
16420           break;
16421       }
16422     if ((u32) p->value[0] == sw_if_index_to)
16423       {
16424         sw_if_to_name = (u8 *)(p->key);
16425         if (sw_if_from_name)
16426           break;
16427       }
16428   }));
16429   /* *INDENT-ON* */
16430
16431   if (VAT_JSON_ARRAY != vam->json_tree.type)
16432     {
16433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16434       vat_json_init_array (&vam->json_tree);
16435     }
16436   node = vat_json_array_add (&vam->json_tree);
16437
16438   vat_json_init_object (node);
16439   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16440   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16441   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16442   if (0 != sw_if_to_name)
16443     {
16444       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16445     }
16446   vat_json_object_add_uint (node, "state", mp->state);
16447 }
16448
16449 static int
16450 api_sw_interface_span_dump (vat_main_t * vam)
16451 {
16452   vl_api_sw_interface_span_dump_t *mp;
16453   int ret;
16454
16455   M (SW_INTERFACE_SPAN_DUMP, mp);
16456   S (mp);
16457
16458   /* Use a control ping for synchronization */
16459   {
16460     vl_api_control_ping_t *mp;
16461     M (CONTROL_PING, mp);
16462     S (mp);
16463   }
16464   W (ret);
16465   return ret;
16466 }
16467
16468 int
16469 api_pg_create_interface (vat_main_t * vam)
16470 {
16471   unformat_input_t *input = vam->input;
16472   vl_api_pg_create_interface_t *mp;
16473
16474   u32 if_id = ~0;
16475   int ret;
16476   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16477     {
16478       if (unformat (input, "if_id %d", &if_id))
16479         ;
16480       else
16481         break;
16482     }
16483   if (if_id == ~0)
16484     {
16485       errmsg ("missing pg interface index");
16486       return -99;
16487     }
16488
16489   /* Construct the API message */
16490   M (PG_CREATE_INTERFACE, mp);
16491   mp->context = 0;
16492   mp->interface_id = ntohl (if_id);
16493
16494   S (mp);
16495   W (ret);
16496   return ret;
16497 }
16498
16499 int
16500 api_pg_capture (vat_main_t * vam)
16501 {
16502   unformat_input_t *input = vam->input;
16503   vl_api_pg_capture_t *mp;
16504
16505   u32 if_id = ~0;
16506   u8 enable = 1;
16507   u32 count = 1;
16508   u8 pcap_file_set = 0;
16509   u8 *pcap_file = 0;
16510   int ret;
16511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16512     {
16513       if (unformat (input, "if_id %d", &if_id))
16514         ;
16515       else if (unformat (input, "pcap %s", &pcap_file))
16516         pcap_file_set = 1;
16517       else if (unformat (input, "count %d", &count))
16518         ;
16519       else if (unformat (input, "disable"))
16520         enable = 0;
16521       else
16522         break;
16523     }
16524   if (if_id == ~0)
16525     {
16526       errmsg ("missing pg interface index");
16527       return -99;
16528     }
16529   if (pcap_file_set > 0)
16530     {
16531       if (vec_len (pcap_file) > 255)
16532         {
16533           errmsg ("pcap file name is too long");
16534           return -99;
16535         }
16536     }
16537
16538   u32 name_len = vec_len (pcap_file);
16539   /* Construct the API message */
16540   M (PG_CAPTURE, mp);
16541   mp->context = 0;
16542   mp->interface_id = ntohl (if_id);
16543   mp->is_enabled = enable;
16544   mp->count = ntohl (count);
16545   mp->pcap_name_length = ntohl (name_len);
16546   if (pcap_file_set != 0)
16547     {
16548       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16549     }
16550   vec_free (pcap_file);
16551
16552   S (mp);
16553   W (ret);
16554   return ret;
16555 }
16556
16557 int
16558 api_pg_enable_disable (vat_main_t * vam)
16559 {
16560   unformat_input_t *input = vam->input;
16561   vl_api_pg_enable_disable_t *mp;
16562
16563   u8 enable = 1;
16564   u8 stream_name_set = 0;
16565   u8 *stream_name = 0;
16566   int ret;
16567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16568     {
16569       if (unformat (input, "stream %s", &stream_name))
16570         stream_name_set = 1;
16571       else if (unformat (input, "disable"))
16572         enable = 0;
16573       else
16574         break;
16575     }
16576
16577   if (stream_name_set > 0)
16578     {
16579       if (vec_len (stream_name) > 255)
16580         {
16581           errmsg ("stream name too long");
16582           return -99;
16583         }
16584     }
16585
16586   u32 name_len = vec_len (stream_name);
16587   /* Construct the API message */
16588   M (PG_ENABLE_DISABLE, mp);
16589   mp->context = 0;
16590   mp->is_enabled = enable;
16591   if (stream_name_set != 0)
16592     {
16593       mp->stream_name_length = ntohl (name_len);
16594       clib_memcpy (mp->stream_name, stream_name, name_len);
16595     }
16596   vec_free (stream_name);
16597
16598   S (mp);
16599   W (ret);
16600   return ret;
16601 }
16602
16603 int
16604 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16605 {
16606   unformat_input_t *input = vam->input;
16607   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16608
16609   u16 *low_ports = 0;
16610   u16 *high_ports = 0;
16611   u16 this_low;
16612   u16 this_hi;
16613   ip4_address_t ip4_addr;
16614   ip6_address_t ip6_addr;
16615   u32 length;
16616   u32 tmp, tmp2;
16617   u8 prefix_set = 0;
16618   u32 vrf_id = ~0;
16619   u8 is_add = 1;
16620   u8 is_ipv6 = 0;
16621   int ret;
16622
16623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16624     {
16625       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16626         {
16627           prefix_set = 1;
16628         }
16629       else
16630         if (unformat
16631             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16632         {
16633           prefix_set = 1;
16634           is_ipv6 = 1;
16635         }
16636       else if (unformat (input, "vrf %d", &vrf_id))
16637         ;
16638       else if (unformat (input, "del"))
16639         is_add = 0;
16640       else if (unformat (input, "port %d", &tmp))
16641         {
16642           if (tmp == 0 || tmp > 65535)
16643             {
16644               errmsg ("port %d out of range", tmp);
16645               return -99;
16646             }
16647           this_low = tmp;
16648           this_hi = this_low + 1;
16649           vec_add1 (low_ports, this_low);
16650           vec_add1 (high_ports, this_hi);
16651         }
16652       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16653         {
16654           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16655             {
16656               errmsg ("incorrect range parameters");
16657               return -99;
16658             }
16659           this_low = tmp;
16660           /* Note: in debug CLI +1 is added to high before
16661              passing to real fn that does "the work"
16662              (ip_source_and_port_range_check_add_del).
16663              This fn is a wrapper around the binary API fn a
16664              control plane will call, which expects this increment
16665              to have occurred. Hence letting the binary API control
16666              plane fn do the increment for consistency between VAT
16667              and other control planes.
16668            */
16669           this_hi = tmp2;
16670           vec_add1 (low_ports, this_low);
16671           vec_add1 (high_ports, this_hi);
16672         }
16673       else
16674         break;
16675     }
16676
16677   if (prefix_set == 0)
16678     {
16679       errmsg ("<address>/<mask> not specified");
16680       return -99;
16681     }
16682
16683   if (vrf_id == ~0)
16684     {
16685       errmsg ("VRF ID required, not specified");
16686       return -99;
16687     }
16688
16689   if (vrf_id == 0)
16690     {
16691       errmsg
16692         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16693       return -99;
16694     }
16695
16696   if (vec_len (low_ports) == 0)
16697     {
16698       errmsg ("At least one port or port range required");
16699       return -99;
16700     }
16701
16702   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
16703
16704   mp->is_add = is_add;
16705
16706   if (is_ipv6)
16707     {
16708       mp->is_ipv6 = 1;
16709       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16710     }
16711   else
16712     {
16713       mp->is_ipv6 = 0;
16714       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16715     }
16716
16717   mp->mask_length = length;
16718   mp->number_of_ranges = vec_len (low_ports);
16719
16720   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16721   vec_free (low_ports);
16722
16723   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16724   vec_free (high_ports);
16725
16726   mp->vrf_id = ntohl (vrf_id);
16727
16728   S (mp);
16729   W (ret);
16730   return ret;
16731 }
16732
16733 int
16734 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16735 {
16736   unformat_input_t *input = vam->input;
16737   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16738   u32 sw_if_index = ~0;
16739   int vrf_set = 0;
16740   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16741   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16742   u8 is_add = 1;
16743   int ret;
16744
16745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16746     {
16747       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16748         ;
16749       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16750         ;
16751       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16752         vrf_set = 1;
16753       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16754         vrf_set = 1;
16755       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16756         vrf_set = 1;
16757       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16758         vrf_set = 1;
16759       else if (unformat (input, "del"))
16760         is_add = 0;
16761       else
16762         break;
16763     }
16764
16765   if (sw_if_index == ~0)
16766     {
16767       errmsg ("Interface required but not specified");
16768       return -99;
16769     }
16770
16771   if (vrf_set == 0)
16772     {
16773       errmsg ("VRF ID required but not specified");
16774       return -99;
16775     }
16776
16777   if (tcp_out_vrf_id == 0
16778       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16779     {
16780       errmsg
16781         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16782       return -99;
16783     }
16784
16785   /* Construct the API message */
16786   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
16787
16788   mp->sw_if_index = ntohl (sw_if_index);
16789   mp->is_add = is_add;
16790   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16791   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16792   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16793   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16794
16795   /* send it... */
16796   S (mp);
16797
16798   /* Wait for a reply... */
16799   W (ret);
16800   return ret;
16801 }
16802
16803 static int
16804 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16805 {
16806   unformat_input_t *i = vam->input;
16807   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16808   u32 local_sa_id = 0;
16809   u32 remote_sa_id = 0;
16810   ip4_address_t src_address;
16811   ip4_address_t dst_address;
16812   u8 is_add = 1;
16813   int ret;
16814
16815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16816     {
16817       if (unformat (i, "local_sa %d", &local_sa_id))
16818         ;
16819       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16820         ;
16821       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16822         ;
16823       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16824         ;
16825       else if (unformat (i, "del"))
16826         is_add = 0;
16827       else
16828         {
16829           clib_warning ("parse error '%U'", format_unformat_error, i);
16830           return -99;
16831         }
16832     }
16833
16834   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
16835
16836   mp->local_sa_id = ntohl (local_sa_id);
16837   mp->remote_sa_id = ntohl (remote_sa_id);
16838   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16839   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16840   mp->is_add = is_add;
16841
16842   S (mp);
16843   W (ret);
16844   return ret;
16845 }
16846
16847 static int
16848 api_punt (vat_main_t * vam)
16849 {
16850   unformat_input_t *i = vam->input;
16851   vl_api_punt_t *mp;
16852   u32 ipv = ~0;
16853   u32 protocol = ~0;
16854   u32 port = ~0;
16855   int is_add = 1;
16856   int ret;
16857
16858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16859     {
16860       if (unformat (i, "ip %d", &ipv))
16861         ;
16862       else if (unformat (i, "protocol %d", &protocol))
16863         ;
16864       else if (unformat (i, "port %d", &port))
16865         ;
16866       else if (unformat (i, "del"))
16867         is_add = 0;
16868       else
16869         {
16870           clib_warning ("parse error '%U'", format_unformat_error, i);
16871           return -99;
16872         }
16873     }
16874
16875   M (PUNT, mp);
16876
16877   mp->is_add = (u8) is_add;
16878   mp->ipv = (u8) ipv;
16879   mp->l4_protocol = (u8) protocol;
16880   mp->l4_port = htons ((u16) port);
16881
16882   S (mp);
16883   W (ret);
16884   return ret;
16885 }
16886
16887 static void vl_api_ipsec_gre_tunnel_details_t_handler
16888   (vl_api_ipsec_gre_tunnel_details_t * mp)
16889 {
16890   vat_main_t *vam = &vat_main;
16891
16892   print (vam->ofp, "%11d%15U%15U%14d%14d",
16893          ntohl (mp->sw_if_index),
16894          format_ip4_address, &mp->src_address,
16895          format_ip4_address, &mp->dst_address,
16896          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16897 }
16898
16899 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16900   (vl_api_ipsec_gre_tunnel_details_t * mp)
16901 {
16902   vat_main_t *vam = &vat_main;
16903   vat_json_node_t *node = NULL;
16904   struct in_addr ip4;
16905
16906   if (VAT_JSON_ARRAY != vam->json_tree.type)
16907     {
16908       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16909       vat_json_init_array (&vam->json_tree);
16910     }
16911   node = vat_json_array_add (&vam->json_tree);
16912
16913   vat_json_init_object (node);
16914   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16915   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16916   vat_json_object_add_ip4 (node, "src_address", ip4);
16917   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16918   vat_json_object_add_ip4 (node, "dst_address", ip4);
16919   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16920   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16921 }
16922
16923 static int
16924 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16925 {
16926   unformat_input_t *i = vam->input;
16927   vl_api_ipsec_gre_tunnel_dump_t *mp;
16928   u32 sw_if_index;
16929   u8 sw_if_index_set = 0;
16930   int ret;
16931
16932   /* Parse args required to build the message */
16933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16934     {
16935       if (unformat (i, "sw_if_index %d", &sw_if_index))
16936         sw_if_index_set = 1;
16937       else
16938         break;
16939     }
16940
16941   if (sw_if_index_set == 0)
16942     {
16943       sw_if_index = ~0;
16944     }
16945
16946   if (!vam->json_output)
16947     {
16948       print (vam->ofp, "%11s%15s%15s%14s%14s",
16949              "sw_if_index", "src_address", "dst_address",
16950              "local_sa_id", "remote_sa_id");
16951     }
16952
16953   /* Get list of gre-tunnel interfaces */
16954   M (IPSEC_GRE_TUNNEL_DUMP, mp);
16955
16956   mp->sw_if_index = htonl (sw_if_index);
16957
16958   S (mp);
16959
16960   /* Use a control ping for synchronization */
16961   {
16962     vl_api_control_ping_t *mp;
16963     M (CONTROL_PING, mp);
16964     S (mp);
16965   }
16966   W (ret);
16967   return ret;
16968 }
16969
16970 static int
16971 api_delete_subif (vat_main_t * vam)
16972 {
16973   unformat_input_t *i = vam->input;
16974   vl_api_delete_subif_t *mp;
16975   u32 sw_if_index = ~0;
16976   int ret;
16977
16978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16979     {
16980       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16981         ;
16982       if (unformat (i, "sw_if_index %d", &sw_if_index))
16983         ;
16984       else
16985         break;
16986     }
16987
16988   if (sw_if_index == ~0)
16989     {
16990       errmsg ("missing sw_if_index");
16991       return -99;
16992     }
16993
16994   /* Construct the API message */
16995   M (DELETE_SUBIF, mp);
16996   mp->sw_if_index = ntohl (sw_if_index);
16997
16998   S (mp);
16999   W (ret);
17000   return ret;
17001 }
17002
17003 #define foreach_pbb_vtr_op      \
17004 _("disable",  L2_VTR_DISABLED)  \
17005 _("pop",  L2_VTR_POP_2)         \
17006 _("push",  L2_VTR_PUSH_2)
17007
17008 static int
17009 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17010 {
17011   unformat_input_t *i = vam->input;
17012   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17013   u32 sw_if_index = ~0, vtr_op = ~0;
17014   u16 outer_tag = ~0;
17015   u8 dmac[6], smac[6];
17016   u8 dmac_set = 0, smac_set = 0;
17017   u16 vlanid = 0;
17018   u32 sid = ~0;
17019   u32 tmp;
17020   int ret;
17021
17022   /* Shut up coverity */
17023   memset (dmac, 0, sizeof (dmac));
17024   memset (smac, 0, sizeof (smac));
17025
17026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17027     {
17028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17029         ;
17030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17031         ;
17032       else if (unformat (i, "vtr_op %d", &vtr_op))
17033         ;
17034 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17035       foreach_pbb_vtr_op
17036 #undef _
17037         else if (unformat (i, "translate_pbb_stag"))
17038         {
17039           if (unformat (i, "%d", &tmp))
17040             {
17041               vtr_op = L2_VTR_TRANSLATE_2_1;
17042               outer_tag = tmp;
17043             }
17044           else
17045             {
17046               errmsg
17047                 ("translate_pbb_stag operation requires outer tag definition");
17048               return -99;
17049             }
17050         }
17051       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17052         dmac_set++;
17053       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17054         smac_set++;
17055       else if (unformat (i, "sid %d", &sid))
17056         ;
17057       else if (unformat (i, "vlanid %d", &tmp))
17058         vlanid = tmp;
17059       else
17060         {
17061           clib_warning ("parse error '%U'", format_unformat_error, i);
17062           return -99;
17063         }
17064     }
17065
17066   if ((sw_if_index == ~0) || (vtr_op == ~0))
17067     {
17068       errmsg ("missing sw_if_index or vtr operation");
17069       return -99;
17070     }
17071   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17072       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17073     {
17074       errmsg
17075         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17076       return -99;
17077     }
17078
17079   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17080   mp->sw_if_index = ntohl (sw_if_index);
17081   mp->vtr_op = ntohl (vtr_op);
17082   mp->outer_tag = ntohs (outer_tag);
17083   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17084   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17085   mp->b_vlanid = ntohs (vlanid);
17086   mp->i_sid = ntohl (sid);
17087
17088   S (mp);
17089   W (ret);
17090   return ret;
17091 }
17092
17093 static int
17094 api_flow_classify_set_interface (vat_main_t * vam)
17095 {
17096   unformat_input_t *i = vam->input;
17097   vl_api_flow_classify_set_interface_t *mp;
17098   u32 sw_if_index;
17099   int sw_if_index_set;
17100   u32 ip4_table_index = ~0;
17101   u32 ip6_table_index = ~0;
17102   u8 is_add = 1;
17103   int ret;
17104
17105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17106     {
17107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17108         sw_if_index_set = 1;
17109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17110         sw_if_index_set = 1;
17111       else if (unformat (i, "del"))
17112         is_add = 0;
17113       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17114         ;
17115       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17116         ;
17117       else
17118         {
17119           clib_warning ("parse error '%U'", format_unformat_error, i);
17120           return -99;
17121         }
17122     }
17123
17124   if (sw_if_index_set == 0)
17125     {
17126       errmsg ("missing interface name or sw_if_index");
17127       return -99;
17128     }
17129
17130   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17131
17132   mp->sw_if_index = ntohl (sw_if_index);
17133   mp->ip4_table_index = ntohl (ip4_table_index);
17134   mp->ip6_table_index = ntohl (ip6_table_index);
17135   mp->is_add = is_add;
17136
17137   S (mp);
17138   W (ret);
17139   return ret;
17140 }
17141
17142 static int
17143 api_flow_classify_dump (vat_main_t * vam)
17144 {
17145   unformat_input_t *i = vam->input;
17146   vl_api_flow_classify_dump_t *mp;
17147   u8 type = FLOW_CLASSIFY_N_TABLES;
17148   int ret;
17149
17150   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17151     ;
17152   else
17153     {
17154       errmsg ("classify table type must be specified");
17155       return -99;
17156     }
17157
17158   if (!vam->json_output)
17159     {
17160       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17161     }
17162
17163   M (FLOW_CLASSIFY_DUMP, mp);
17164   mp->type = type;
17165   /* send it... */
17166   S (mp);
17167
17168   /* Use a control ping for synchronization */
17169   {
17170     vl_api_control_ping_t *mp;
17171     M (CONTROL_PING, mp);
17172     S (mp);
17173   }
17174   /* Wait for a reply... */
17175   W (ret);
17176   return ret;
17177 }
17178
17179 static int
17180 api_feature_enable_disable (vat_main_t * vam)
17181 {
17182   unformat_input_t *i = vam->input;
17183   vl_api_feature_enable_disable_t *mp;
17184   u8 *arc_name = 0;
17185   u8 *feature_name = 0;
17186   u32 sw_if_index = ~0;
17187   u8 enable = 1;
17188   int ret;
17189
17190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17191     {
17192       if (unformat (i, "arc_name %s", &arc_name))
17193         ;
17194       else if (unformat (i, "feature_name %s", &feature_name))
17195         ;
17196       else
17197         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17198         ;
17199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17200         ;
17201       else if (unformat (i, "disable"))
17202         enable = 0;
17203       else
17204         break;
17205     }
17206
17207   if (arc_name == 0)
17208     {
17209       errmsg ("missing arc name");
17210       return -99;
17211     }
17212   if (vec_len (arc_name) > 63)
17213     {
17214       errmsg ("arc name too long");
17215     }
17216
17217   if (feature_name == 0)
17218     {
17219       errmsg ("missing feature name");
17220       return -99;
17221     }
17222   if (vec_len (feature_name) > 63)
17223     {
17224       errmsg ("feature name too long");
17225     }
17226
17227   if (sw_if_index == ~0)
17228     {
17229       errmsg ("missing interface name or sw_if_index");
17230       return -99;
17231     }
17232
17233   /* Construct the API message */
17234   M (FEATURE_ENABLE_DISABLE, mp);
17235   mp->sw_if_index = ntohl (sw_if_index);
17236   mp->enable = enable;
17237   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17238   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17239   vec_free (arc_name);
17240   vec_free (feature_name);
17241
17242   S (mp);
17243   W (ret);
17244   return ret;
17245 }
17246
17247 static int
17248 api_sw_interface_tag_add_del (vat_main_t * vam)
17249 {
17250   unformat_input_t *i = vam->input;
17251   vl_api_sw_interface_tag_add_del_t *mp;
17252   u32 sw_if_index = ~0;
17253   u8 *tag = 0;
17254   u8 enable = 1;
17255   int ret;
17256
17257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17258     {
17259       if (unformat (i, "tag %s", &tag))
17260         ;
17261       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17262         ;
17263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17264         ;
17265       else if (unformat (i, "del"))
17266         enable = 0;
17267       else
17268         break;
17269     }
17270
17271   if (sw_if_index == ~0)
17272     {
17273       errmsg ("missing interface name or sw_if_index");
17274       return -99;
17275     }
17276
17277   if (enable && (tag == 0))
17278     {
17279       errmsg ("no tag specified");
17280       return -99;
17281     }
17282
17283   /* Construct the API message */
17284   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17285   mp->sw_if_index = ntohl (sw_if_index);
17286   mp->is_add = enable;
17287   if (enable)
17288     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17289   vec_free (tag);
17290
17291   S (mp);
17292   W (ret);
17293   return ret;
17294 }
17295
17296 static void vl_api_l2_xconnect_details_t_handler
17297   (vl_api_l2_xconnect_details_t * mp)
17298 {
17299   vat_main_t *vam = &vat_main;
17300
17301   print (vam->ofp, "%15d%15d",
17302          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17303 }
17304
17305 static void vl_api_l2_xconnect_details_t_handler_json
17306   (vl_api_l2_xconnect_details_t * mp)
17307 {
17308   vat_main_t *vam = &vat_main;
17309   vat_json_node_t *node = NULL;
17310
17311   if (VAT_JSON_ARRAY != vam->json_tree.type)
17312     {
17313       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17314       vat_json_init_array (&vam->json_tree);
17315     }
17316   node = vat_json_array_add (&vam->json_tree);
17317
17318   vat_json_init_object (node);
17319   vat_json_object_add_uint (node, "rx_sw_if_index",
17320                             ntohl (mp->rx_sw_if_index));
17321   vat_json_object_add_uint (node, "tx_sw_if_index",
17322                             ntohl (mp->tx_sw_if_index));
17323 }
17324
17325 static int
17326 api_l2_xconnect_dump (vat_main_t * vam)
17327 {
17328   vl_api_l2_xconnect_dump_t *mp;
17329   int ret;
17330
17331   if (!vam->json_output)
17332     {
17333       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17334     }
17335
17336   M (L2_XCONNECT_DUMP, mp);
17337
17338   S (mp);
17339
17340   /* Use a control ping for synchronization */
17341   {
17342     vl_api_control_ping_t *mp;
17343     M (CONTROL_PING, mp);
17344     S (mp);
17345   }
17346   W (ret);
17347   return ret;
17348 }
17349
17350 static int
17351 api_sw_interface_set_mtu (vat_main_t * vam)
17352 {
17353   unformat_input_t *i = vam->input;
17354   vl_api_sw_interface_set_mtu_t *mp;
17355   u32 sw_if_index = ~0;
17356   u32 mtu = 0;
17357   int ret;
17358
17359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17360     {
17361       if (unformat (i, "mtu %d", &mtu))
17362         ;
17363       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17364         ;
17365       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17366         ;
17367       else
17368         break;
17369     }
17370
17371   if (sw_if_index == ~0)
17372     {
17373       errmsg ("missing interface name or sw_if_index");
17374       return -99;
17375     }
17376
17377   if (mtu == 0)
17378     {
17379       errmsg ("no mtu specified");
17380       return -99;
17381     }
17382
17383   /* Construct the API message */
17384   M (SW_INTERFACE_SET_MTU, mp);
17385   mp->sw_if_index = ntohl (sw_if_index);
17386   mp->mtu = ntohs ((u16) mtu);
17387
17388   S (mp);
17389   W (ret);
17390   return ret;
17391 }
17392
17393
17394 static int
17395 q_or_quit (vat_main_t * vam)
17396 {
17397   longjmp (vam->jump_buf, 1);
17398   return 0;                     /* not so much */
17399 }
17400
17401 static int
17402 q (vat_main_t * vam)
17403 {
17404   return q_or_quit (vam);
17405 }
17406
17407 static int
17408 quit (vat_main_t * vam)
17409 {
17410   return q_or_quit (vam);
17411 }
17412
17413 static int
17414 comment (vat_main_t * vam)
17415 {
17416   return 0;
17417 }
17418
17419 static int
17420 cmd_cmp (void *a1, void *a2)
17421 {
17422   u8 **c1 = a1;
17423   u8 **c2 = a2;
17424
17425   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17426 }
17427
17428 static int
17429 help (vat_main_t * vam)
17430 {
17431   u8 **cmds = 0;
17432   u8 *name = 0;
17433   hash_pair_t *p;
17434   unformat_input_t *i = vam->input;
17435   int j;
17436
17437   if (unformat (i, "%s", &name))
17438     {
17439       uword *hs;
17440
17441       vec_add1 (name, 0);
17442
17443       hs = hash_get_mem (vam->help_by_name, name);
17444       if (hs)
17445         print (vam->ofp, "usage: %s %s", name, hs[0]);
17446       else
17447         print (vam->ofp, "No such msg / command '%s'", name);
17448       vec_free (name);
17449       return 0;
17450     }
17451
17452   print (vam->ofp, "Help is available for the following:");
17453
17454     /* *INDENT-OFF* */
17455     hash_foreach_pair (p, vam->function_by_name,
17456     ({
17457       vec_add1 (cmds, (u8 *)(p->key));
17458     }));
17459     /* *INDENT-ON* */
17460
17461   vec_sort_with_function (cmds, cmd_cmp);
17462
17463   for (j = 0; j < vec_len (cmds); j++)
17464     print (vam->ofp, "%s", cmds[j]);
17465
17466   vec_free (cmds);
17467   return 0;
17468 }
17469
17470 static int
17471 set (vat_main_t * vam)
17472 {
17473   u8 *name = 0, *value = 0;
17474   unformat_input_t *i = vam->input;
17475
17476   if (unformat (i, "%s", &name))
17477     {
17478       /* The input buffer is a vector, not a string. */
17479       value = vec_dup (i->buffer);
17480       vec_delete (value, i->index, 0);
17481       /* Almost certainly has a trailing newline */
17482       if (value[vec_len (value) - 1] == '\n')
17483         value[vec_len (value) - 1] = 0;
17484       /* Make sure it's a proper string, one way or the other */
17485       vec_add1 (value, 0);
17486       (void) clib_macro_set_value (&vam->macro_main,
17487                                    (char *) name, (char *) value);
17488     }
17489   else
17490     errmsg ("usage: set <name> <value>");
17491
17492   vec_free (name);
17493   vec_free (value);
17494   return 0;
17495 }
17496
17497 static int
17498 unset (vat_main_t * vam)
17499 {
17500   u8 *name = 0;
17501
17502   if (unformat (vam->input, "%s", &name))
17503     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17504       errmsg ("unset: %s wasn't set", name);
17505   vec_free (name);
17506   return 0;
17507 }
17508
17509 typedef struct
17510 {
17511   u8 *name;
17512   u8 *value;
17513 } macro_sort_t;
17514
17515
17516 static int
17517 macro_sort_cmp (void *a1, void *a2)
17518 {
17519   macro_sort_t *s1 = a1;
17520   macro_sort_t *s2 = a2;
17521
17522   return strcmp ((char *) (s1->name), (char *) (s2->name));
17523 }
17524
17525 static int
17526 dump_macro_table (vat_main_t * vam)
17527 {
17528   macro_sort_t *sort_me = 0, *sm;
17529   int i;
17530   hash_pair_t *p;
17531
17532     /* *INDENT-OFF* */
17533     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17534     ({
17535       vec_add2 (sort_me, sm, 1);
17536       sm->name = (u8 *)(p->key);
17537       sm->value = (u8 *) (p->value[0]);
17538     }));
17539     /* *INDENT-ON* */
17540
17541   vec_sort_with_function (sort_me, macro_sort_cmp);
17542
17543   if (vec_len (sort_me))
17544     print (vam->ofp, "%-15s%s", "Name", "Value");
17545   else
17546     print (vam->ofp, "The macro table is empty...");
17547
17548   for (i = 0; i < vec_len (sort_me); i++)
17549     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17550   return 0;
17551 }
17552
17553 static int
17554 dump_node_table (vat_main_t * vam)
17555 {
17556   int i, j;
17557   vlib_node_t *node, *next_node;
17558
17559   if (vec_len (vam->graph_nodes) == 0)
17560     {
17561       print (vam->ofp, "Node table empty, issue get_node_graph...");
17562       return 0;
17563     }
17564
17565   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17566     {
17567       node = vam->graph_nodes[i];
17568       print (vam->ofp, "[%d] %s", i, node->name);
17569       for (j = 0; j < vec_len (node->next_nodes); j++)
17570         {
17571           if (node->next_nodes[j] != ~0)
17572             {
17573               next_node = vam->graph_nodes[node->next_nodes[j]];
17574               print (vam->ofp, "  [%d] %s", j, next_node->name);
17575             }
17576         }
17577     }
17578   return 0;
17579 }
17580
17581 static int
17582 value_sort_cmp (void *a1, void *a2)
17583 {
17584   name_sort_t *n1 = a1;
17585   name_sort_t *n2 = a2;
17586
17587   if (n1->value < n2->value)
17588     return -1;
17589   if (n1->value > n2->value)
17590     return 1;
17591   return 0;
17592 }
17593
17594
17595 static int
17596 dump_msg_api_table (vat_main_t * vam)
17597 {
17598   api_main_t *am = &api_main;
17599   name_sort_t *nses = 0, *ns;
17600   hash_pair_t *hp;
17601   int i;
17602
17603   /* *INDENT-OFF* */
17604   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17605   ({
17606     vec_add2 (nses, ns, 1);
17607     ns->name = (u8 *)(hp->key);
17608     ns->value = (u32) hp->value[0];
17609   }));
17610   /* *INDENT-ON* */
17611
17612   vec_sort_with_function (nses, value_sort_cmp);
17613
17614   for (i = 0; i < vec_len (nses); i++)
17615     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17616   vec_free (nses);
17617   return 0;
17618 }
17619
17620 static int
17621 get_msg_id (vat_main_t * vam)
17622 {
17623   u8 *name_and_crc;
17624   u32 message_index;
17625
17626   if (unformat (vam->input, "%s", &name_and_crc))
17627     {
17628       message_index = vl_api_get_msg_index (name_and_crc);
17629       if (message_index == ~0)
17630         {
17631           print (vam->ofp, " '%s' not found", name_and_crc);
17632           return 0;
17633         }
17634       print (vam->ofp, " '%s' has message index %d",
17635              name_and_crc, message_index);
17636       return 0;
17637     }
17638   errmsg ("name_and_crc required...");
17639   return 0;
17640 }
17641
17642 static int
17643 search_node_table (vat_main_t * vam)
17644 {
17645   unformat_input_t *line_input = vam->input;
17646   u8 *node_to_find;
17647   int j;
17648   vlib_node_t *node, *next_node;
17649   uword *p;
17650
17651   if (vam->graph_node_index_by_name == 0)
17652     {
17653       print (vam->ofp, "Node table empty, issue get_node_graph...");
17654       return 0;
17655     }
17656
17657   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17658     {
17659       if (unformat (line_input, "%s", &node_to_find))
17660         {
17661           vec_add1 (node_to_find, 0);
17662           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17663           if (p == 0)
17664             {
17665               print (vam->ofp, "%s not found...", node_to_find);
17666               goto out;
17667             }
17668           node = vam->graph_nodes[p[0]];
17669           print (vam->ofp, "[%d] %s", p[0], node->name);
17670           for (j = 0; j < vec_len (node->next_nodes); j++)
17671             {
17672               if (node->next_nodes[j] != ~0)
17673                 {
17674                   next_node = vam->graph_nodes[node->next_nodes[j]];
17675                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17676                 }
17677             }
17678         }
17679
17680       else
17681         {
17682           clib_warning ("parse error '%U'", format_unformat_error,
17683                         line_input);
17684           return -99;
17685         }
17686
17687     out:
17688       vec_free (node_to_find);
17689
17690     }
17691
17692   return 0;
17693 }
17694
17695
17696 static int
17697 script (vat_main_t * vam)
17698 {
17699 #if (VPP_API_TEST_BUILTIN==0)
17700   u8 *s = 0;
17701   char *save_current_file;
17702   unformat_input_t save_input;
17703   jmp_buf save_jump_buf;
17704   u32 save_line_number;
17705
17706   FILE *new_fp, *save_ifp;
17707
17708   if (unformat (vam->input, "%s", &s))
17709     {
17710       new_fp = fopen ((char *) s, "r");
17711       if (new_fp == 0)
17712         {
17713           errmsg ("Couldn't open script file %s", s);
17714           vec_free (s);
17715           return -99;
17716         }
17717     }
17718   else
17719     {
17720       errmsg ("Missing script name");
17721       return -99;
17722     }
17723
17724   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17725   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17726   save_ifp = vam->ifp;
17727   save_line_number = vam->input_line_number;
17728   save_current_file = (char *) vam->current_file;
17729
17730   vam->input_line_number = 0;
17731   vam->ifp = new_fp;
17732   vam->current_file = s;
17733   do_one_file (vam);
17734
17735   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17736   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17737   vam->ifp = save_ifp;
17738   vam->input_line_number = save_line_number;
17739   vam->current_file = (u8 *) save_current_file;
17740   vec_free (s);
17741
17742   return 0;
17743 #else
17744   clib_warning ("use the exec command...");
17745   return -99;
17746 #endif
17747 }
17748
17749 static int
17750 echo (vat_main_t * vam)
17751 {
17752   print (vam->ofp, "%v", vam->input->buffer);
17753   return 0;
17754 }
17755
17756 /* List of API message constructors, CLI names map to api_xxx */
17757 #define foreach_vpe_api_msg                                             \
17758 _(create_loopback,"[mac <mac-addr>]")                                   \
17759 _(sw_interface_dump,"")                                                 \
17760 _(sw_interface_set_flags,                                               \
17761   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17762 _(sw_interface_add_del_address,                                         \
17763   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17764 _(sw_interface_set_table,                                               \
17765   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17766 _(sw_interface_set_mpls_enable,                                         \
17767   "<intfc> | sw_if_index [disable | dis]")                              \
17768 _(sw_interface_set_vpath,                                               \
17769   "<intfc> | sw_if_index <id> enable | disable")                        \
17770 _(sw_interface_set_vxlan_bypass,                                        \
17771   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
17772 _(sw_interface_set_l2_xconnect,                                         \
17773   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17774   "enable | disable")                                                   \
17775 _(sw_interface_set_l2_bridge,                                           \
17776   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17777   "[shg <split-horizon-group>] [bvi]\n"                                 \
17778   "enable | disable")                                                   \
17779 _(bridge_domain_add_del,                                                \
17780   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17781 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17782 _(l2fib_add_del,                                                        \
17783   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17784 _(l2_flags,                                                             \
17785   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17786 _(bridge_flags,                                                         \
17787   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17788 _(tap_connect,                                                          \
17789   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17790 _(tap_modify,                                                           \
17791   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17792 _(tap_delete,                                                           \
17793   "<vpp-if-name> | sw_if_index <id>")                                   \
17794 _(sw_interface_tap_dump, "")                                            \
17795 _(ip_add_del_route,                                                     \
17796   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17797   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17798   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17799   "[multipath] [count <n>]")                                            \
17800 _(ip_mroute_add_del,                                                    \
17801   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
17802   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
17803 _(mpls_route_add_del,                                                   \
17804   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17805   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17806   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17807   "[multipath] [count <n>]")                                            \
17808 _(mpls_ip_bind_unbind,                                                  \
17809   "<label> <addr/len>")                                                 \
17810 _(mpls_tunnel_add_del,                                                  \
17811   " via <addr> [table-id <n>]\n"                                        \
17812   "sw_if_index <id>] [l2]  [del]")                                      \
17813 _(proxy_arp_add_del,                                                    \
17814   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17815 _(proxy_arp_intfc_enable_disable,                                       \
17816   "<intfc> | sw_if_index <id> enable | disable")                        \
17817 _(sw_interface_set_unnumbered,                                          \
17818   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17819 _(ip_neighbor_add_del,                                                  \
17820   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17821   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17822 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17823 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17824 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17825   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17826   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17827   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17828 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17829 _(reset_fib, "vrf <n> [ipv6]")                                          \
17830 _(dhcp_proxy_config,                                                    \
17831   "svr <v46-address> src <v46-address>\n"                               \
17832    "insert-cid <n> [del]")                                              \
17833 _(dhcp_proxy_config_2,                                                  \
17834   "svr <v46-address> src <v46-address>\n"                               \
17835    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17836 _(dhcp_proxy_set_vss,                                                   \
17837   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17838 _(dhcp_client_config,                                                   \
17839   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17840 _(set_ip_flow_hash,                                                     \
17841   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17842 _(sw_interface_ip6_enable_disable,                                      \
17843   "<intfc> | sw_if_index <id> enable | disable")                        \
17844 _(sw_interface_ip6_set_link_local_address,                              \
17845   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17846 _(sw_interface_ip6nd_ra_prefix,                                         \
17847   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17848   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17849   "[nolink] [isno]")                                                    \
17850 _(sw_interface_ip6nd_ra_config,                                         \
17851   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17852   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17853   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17854 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17855 _(l2_patch_add_del,                                                     \
17856   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17857   "enable | disable")                                                   \
17858 _(sr_tunnel_add_del,                                                    \
17859   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17860   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17861   "[policy <policy_name>]")                                             \
17862 _(sr_policy_add_del,                                                    \
17863   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17864 _(sr_multicast_map_add_del,                                             \
17865   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17866 _(classify_add_del_table,                                               \
17867   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17868   " [del] [del-chain] mask <mask-value>\n"                              \
17869   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17870   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17871 _(classify_add_del_session,                                             \
17872   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17873   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17874   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17875   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17876 _(classify_set_interface_ip_table,                                      \
17877   "<intfc> | sw_if_index <nn> table <nn>")                              \
17878 _(classify_set_interface_l2_tables,                                     \
17879   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17880   "  [other-table <nn>]")                                               \
17881 _(get_node_index, "node <node-name")                                    \
17882 _(add_node_next, "node <node-name> next <next-node-name>")              \
17883 _(l2tpv3_create_tunnel,                                                 \
17884   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17885   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17886   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17887 _(l2tpv3_set_tunnel_cookies,                                            \
17888   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17889   "[new_remote_cookie <nn>]\n")                                         \
17890 _(l2tpv3_interface_enable_disable,                                      \
17891   "<intfc> | sw_if_index <nn> enable | disable")                        \
17892 _(l2tpv3_set_lookup_key,                                                \
17893   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17894 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17895 _(vxlan_add_del_tunnel,                                                 \
17896   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17897   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17898   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17899 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17900 _(gre_add_del_tunnel,                                                   \
17901   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17902 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17903 _(l2_fib_clear_table, "")                                               \
17904 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17905 _(l2_interface_vlan_tag_rewrite,                                        \
17906   "<intfc> | sw_if_index <nn> \n"                                       \
17907   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17908   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17909 _(create_vhost_user_if,                                                 \
17910         "socket <filename> [server] [renumber <dev_instance>] "         \
17911         "[mac <mac_address>]")                                          \
17912 _(modify_vhost_user_if,                                                 \
17913         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17914         "[server] [renumber <dev_instance>]")                           \
17915 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17916 _(sw_interface_vhost_user_dump, "")                                     \
17917 _(show_version, "")                                                     \
17918 _(vxlan_gpe_add_del_tunnel,                                             \
17919   "local <addr> remote <addr> vni <nn>\n"                               \
17920     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17921   "[next-ethernet] [next-nsh]\n")                                       \
17922 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17923 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17924 _(interface_name_renumber,                                              \
17925   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17926 _(input_acl_set_interface,                                              \
17927   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17928   "  [l2-table <nn>] [del]")                                            \
17929 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17930 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17931 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17932 _(ip_dump, "ipv4 | ipv6")                                               \
17933 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17934 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17935   "  spid_id <n> ")                                                     \
17936 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17937   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17938   "  integ_alg <alg> integ_key <hex>")                                  \
17939 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17940   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17941   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17942   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17943 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17944 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17945 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17946   "(auth_data 0x<data> | auth_data <data>)")                            \
17947 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17948   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17949 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17950   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17951   "(local|remote)")                                                     \
17952 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17953 _(delete_loopback,"sw_if_index <nn>")                                   \
17954 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17955 _(map_add_domain,                                                       \
17956   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17957   "ip6-src <ip6addr> "                                                  \
17958   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17959 _(map_del_domain, "index <n>")                                          \
17960 _(map_add_del_rule,                                                     \
17961   "index <n> psid <n> dst <ip6addr> [del]")                             \
17962 _(map_domain_dump, "")                                                  \
17963 _(map_rule_dump, "index <map-domain>")                                  \
17964 _(want_interface_events,  "enable|disable")                             \
17965 _(want_stats,"enable|disable")                                          \
17966 _(get_first_msg_id, "client <name>")                                    \
17967 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17968 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17969   "fib-id <nn> [ip4][ip6][default]")                                    \
17970 _(get_node_graph, " ")                                                  \
17971 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17972 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17973 _(ioam_disable, "")                                                     \
17974 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17975                             " sw_if_index <sw_if_index> p <priority> "  \
17976                             "w <weight>] [del]")                        \
17977 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17978                         "iface <intf> | sw_if_index <sw_if_index> "     \
17979                         "p <priority> w <weight> [del]")                \
17980 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17981                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17982                          "locator-set <locator_name> [del]"             \
17983                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17984 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
17985   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
17986 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17987 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17988 _(lisp_gpe_enable_disable, "enable|disable")                            \
17989 _(lisp_enable_disable, "enable|disable")                                \
17990 _(lisp_map_register_enable_disable, "enable|disable")                   \
17991 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17992 _(lisp_gpe_add_del_iface, "up|down")                                    \
17993 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17994                                "[seid <seid>] "                         \
17995                                "rloc <locator> p <prio> "               \
17996                                "w <weight> [rloc <loc> ... ] "          \
17997                                "action <action> [del-all]")             \
17998 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17999                           "<local-eid>")                                \
18000 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18001 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18002 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18003 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18004 _(lisp_locator_set_dump, "[local | remote]")                            \
18005 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18006 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18007                        "[local] | [remote]")                            \
18008 _(lisp_eid_table_vni_dump, "")                                          \
18009 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18010 _(lisp_map_resolver_dump, "")                                           \
18011 _(lisp_map_server_dump, "")                                             \
18012 _(lisp_adjacencies_get, "vni <vni>")                                    \
18013 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18014 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18015 _(show_lisp_rloc_probe_state, "")                                       \
18016 _(show_lisp_map_register_state, "")                                     \
18017 _(show_lisp_status, "")                                                 \
18018 _(lisp_get_map_request_itr_rlocs, "")                                   \
18019 _(show_lisp_pitr, "")                                                   \
18020 _(show_lisp_map_request_mode, "")                                       \
18021 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18022 _(af_packet_delete, "name <host interface name>")                       \
18023 _(policer_add_del, "name <policer name> <params> [del]")                \
18024 _(policer_dump, "[name <policer name>]")                                \
18025 _(policer_classify_set_interface,                                       \
18026   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18027   "  [l2-table <nn>] [del]")                                            \
18028 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18029 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18030     "[master|slave]")                                                   \
18031 _(netmap_delete, "name <interface name>")                               \
18032 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18033 _(mpls_fib_dump, "")                                                    \
18034 _(classify_table_ids, "")                                               \
18035 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18036 _(classify_table_info, "table_id <nn>")                                 \
18037 _(classify_session_dump, "table_id <nn>")                               \
18038 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18039     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18040     "[template_interval <nn>] [udp_checksum]")                          \
18041 _(ipfix_exporter_dump, "")                                              \
18042 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18043 _(ipfix_classify_stream_dump, "")                                       \
18044 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18045 _(ipfix_classify_table_dump, "")                                        \
18046 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18047 _(sw_interface_span_dump, "")                                           \
18048 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18049 _(pg_create_interface, "if_id <nn>")                                    \
18050 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18051 _(pg_enable_disable, "[stream <id>] disable")                           \
18052 _(ip_source_and_port_range_check_add_del,                               \
18053   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18054 _(ip_source_and_port_range_check_interface_add_del,                     \
18055   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18056   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18057 _(ipsec_gre_add_del_tunnel,                                             \
18058   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18059 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18060 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18061 _(l2_interface_pbb_tag_rewrite,                                         \
18062   "<intfc> | sw_if_index <nn> \n"                                       \
18063   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18064   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18065 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18066 _(flow_classify_set_interface,                                          \
18067   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18068 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18069 _(ip_fib_dump, "")                                                      \
18070 _(ip6_fib_dump, "")                                                     \
18071 _(feature_enable_disable, "arc_name <arc_name> "                        \
18072   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18073 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18074 "[disable]")                                                            \
18075 _(l2_xconnect_dump, "")                                                 \
18076 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18077 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18078 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18079
18080 #if DPDK > 0
18081 #define foreach_vpe_dpdk_api_msg                                        \
18082 _(sw_interface_set_dpdk_hqos_pipe,                                      \
18083   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
18084   "profile <profile-id>\n")                                             \
18085 _(sw_interface_set_dpdk_hqos_subport,                                   \
18086   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
18087   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
18088 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
18089   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
18090 #endif
18091
18092 /* List of command functions, CLI names map directly to functions */
18093 #define foreach_cli_function                                    \
18094 _(comment, "usage: comment <ignore-rest-of-line>")              \
18095 _(dump_interface_table, "usage: dump_interface_table")          \
18096 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18097 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18098 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18099 _(dump_stats_table, "usage: dump_stats_table")                  \
18100 _(dump_macro_table, "usage: dump_macro_table ")                 \
18101 _(dump_node_table, "usage: dump_node_table")                    \
18102 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18103 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18104 _(echo, "usage: echo <message>")                                \
18105 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18106 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18107 _(help, "usage: help")                                          \
18108 _(q, "usage: quit")                                             \
18109 _(quit, "usage: quit")                                          \
18110 _(search_node_table, "usage: search_node_table <name>...")      \
18111 _(set, "usage: set <variable-name> <value>")                    \
18112 _(script, "usage: script <file-name>")                          \
18113 _(unset, "usage: unset <variable-name>")
18114
18115 #define _(N,n)                                  \
18116     static void vl_api_##n##_t_handler_uni      \
18117     (vl_api_##n##_t * mp)                       \
18118     {                                           \
18119         vat_main_t * vam = &vat_main;           \
18120         if (vam->json_output) {                 \
18121             vl_api_##n##_t_handler_json(mp);    \
18122         } else {                                \
18123             vl_api_##n##_t_handler(mp);         \
18124         }                                       \
18125     }
18126 foreach_vpe_api_reply_msg;
18127 #undef _
18128
18129 #if DPDK > 0
18130 #define _(N,n)                                  \
18131     static void vl_api_##n##_t_handler_uni      \
18132     (vl_api_##n##_t * mp)                       \
18133     {                                           \
18134         vat_main_t * vam = &vat_main;           \
18135         if (vam->json_output) {                 \
18136             vl_api_##n##_t_handler_json(mp);    \
18137         } else {                                \
18138             vl_api_##n##_t_handler(mp);         \
18139         }                                       \
18140     }
18141 foreach_vpe_dpdk_api_reply_msg;
18142 #undef _
18143 #endif
18144
18145 void
18146 vat_api_hookup (vat_main_t * vam)
18147 {
18148 #define _(N,n)                                                  \
18149     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18150                            vl_api_##n##_t_handler_uni,          \
18151                            vl_noop_handler,                     \
18152                            vl_api_##n##_t_endian,               \
18153                            vl_api_##n##_t_print,                \
18154                            sizeof(vl_api_##n##_t), 1);
18155   foreach_vpe_api_reply_msg;
18156 #undef _
18157
18158 #if DPDK > 0
18159 #define _(N,n)                                                  \
18160     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18161                            vl_api_##n##_t_handler_uni,          \
18162                            vl_noop_handler,                     \
18163                            vl_api_##n##_t_endian,               \
18164                            vl_api_##n##_t_print,                \
18165                            sizeof(vl_api_##n##_t), 1);
18166   foreach_vpe_dpdk_api_reply_msg;
18167 #undef _
18168 #endif
18169
18170 #if (VPP_API_TEST_BUILTIN==0)
18171   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18172 #endif
18173
18174   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18175
18176   vam->function_by_name = hash_create_string (0, sizeof (uword));
18177
18178   vam->help_by_name = hash_create_string (0, sizeof (uword));
18179
18180   /* API messages we can send */
18181 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18182   foreach_vpe_api_msg;
18183 #undef _
18184 #if DPDK >0
18185 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18186   foreach_vpe_dpdk_api_msg;
18187 #undef _
18188 #endif
18189
18190   /* Help strings */
18191 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18192   foreach_vpe_api_msg;
18193 #undef _
18194 #if DPDK >0
18195 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18196   foreach_vpe_dpdk_api_msg;
18197 #undef _
18198 #endif
18199
18200   /* CLI functions */
18201 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18202   foreach_cli_function;
18203 #undef _
18204
18205   /* Help strings */
18206 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18207   foreach_cli_function;
18208 #undef _
18209 }
18210
18211 /*
18212  * fd.io coding-style-patch-verification: ON
18213  *
18214  * Local Variables:
18215  * eval: (c-set-style "gnu")
18216  * End:
18217  */