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