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