6a450993f138cafb4ca7ad9eb4665888133f0b08
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52
53 #include "vat/json_format.h"
54
55 #include <inttypes.h>
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp/api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp/api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp/api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 #define __plugin_msg_base 0
75 #include <vlibapi/vat_helper_macros.h>
76
77 f64
78 vat_time_now (vat_main_t * vam)
79 {
80 #if VPP_API_TEST_BUILTIN
81   return vlib_time_now (vam->vlib_main);
82 #else
83   return clib_time_now (&vam->clib_time);
84 #endif
85 }
86
87 void
88 errmsg (char *fmt, ...)
89 {
90   vat_main_t *vam = &vat_main;
91   va_list va;
92   u8 *s;
93
94   va_start (va, fmt);
95   s = va_format (0, fmt, &va);
96   va_end (va);
97
98   vec_add1 (s, 0);
99
100 #if VPP_API_TEST_BUILTIN
101   vlib_cli_output (vam->vlib_main, (char *) s);
102 #else
103   {
104     if (vam->ifp != stdin)
105       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
106                vam->input_line_number);
107     fformat (vam->ofp, (char *) s);
108     fflush (vam->ofp);
109   }
110 #endif
111
112   vec_free (s);
113 }
114
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 #if VPP_API_TEST_BUILTIN == 0
134 /* Parse an IP4 address %d.%d.%d.%d. */
135 uword
136 unformat_ip4_address (unformat_input_t * input, va_list * args)
137 {
138   u8 *result = va_arg (*args, u8 *);
139   unsigned a[4];
140
141   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
142     return 0;
143
144   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
145     return 0;
146
147   result[0] = a[0];
148   result[1] = a[1];
149   result[2] = a[2];
150   result[3] = a[3];
151
152   return 1;
153 }
154
155 uword
156 unformat_ethernet_address (unformat_input_t * input, va_list * args)
157 {
158   u8 *result = va_arg (*args, u8 *);
159   u32 i, a[6];
160
161   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
162                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
163     return 0;
164
165   /* Check range. */
166   for (i = 0; i < 6; i++)
167     if (a[i] >= (1 << 8))
168       return 0;
169
170   for (i = 0; i < 6; i++)
171     result[i] = a[i];
172
173   return 1;
174 }
175
176 /* Returns ethernet type as an int in host byte order. */
177 uword
178 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
179                                         va_list * args)
180 {
181   u16 *result = va_arg (*args, u16 *);
182   int type;
183
184   /* Numeric type. */
185   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
186     {
187       if (type >= (1 << 16))
188         return 0;
189       *result = type;
190       return 1;
191     }
192   return 0;
193 }
194
195 /* Parse an IP6 address. */
196 uword
197 unformat_ip6_address (unformat_input_t * input, va_list * args)
198 {
199   ip6_address_t *result = va_arg (*args, ip6_address_t *);
200   u16 hex_quads[8];
201   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
202   uword c, n_colon, double_colon_index;
203
204   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
205   double_colon_index = ARRAY_LEN (hex_quads);
206   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
207     {
208       hex_digit = 16;
209       if (c >= '0' && c <= '9')
210         hex_digit = c - '0';
211       else if (c >= 'a' && c <= 'f')
212         hex_digit = c + 10 - 'a';
213       else if (c >= 'A' && c <= 'F')
214         hex_digit = c + 10 - 'A';
215       else if (c == ':' && n_colon < 2)
216         n_colon++;
217       else
218         {
219           unformat_put_input (input);
220           break;
221         }
222
223       /* Too many hex quads. */
224       if (n_hex_quads >= ARRAY_LEN (hex_quads))
225         return 0;
226
227       if (hex_digit < 16)
228         {
229           hex_quad = (hex_quad << 4) | hex_digit;
230
231           /* Hex quad must fit in 16 bits. */
232           if (n_hex_digits >= 4)
233             return 0;
234
235           n_colon = 0;
236           n_hex_digits++;
237         }
238
239       /* Save position of :: */
240       if (n_colon == 2)
241         {
242           /* More than one :: ? */
243           if (double_colon_index < ARRAY_LEN (hex_quads))
244             return 0;
245           double_colon_index = n_hex_quads;
246         }
247
248       if (n_colon > 0 && n_hex_digits > 0)
249         {
250           hex_quads[n_hex_quads++] = hex_quad;
251           hex_quad = 0;
252           n_hex_digits = 0;
253         }
254     }
255
256   if (n_hex_digits > 0)
257     hex_quads[n_hex_quads++] = hex_quad;
258
259   {
260     word i;
261
262     /* Expand :: to appropriate number of zero hex quads. */
263     if (double_colon_index < ARRAY_LEN (hex_quads))
264       {
265         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
266
267         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
268           hex_quads[n_zero + i] = hex_quads[i];
269
270         for (i = 0; i < n_zero; i++)
271           hex_quads[double_colon_index + i] = 0;
272
273         n_hex_quads = ARRAY_LEN (hex_quads);
274       }
275
276     /* Too few hex quads given. */
277     if (n_hex_quads < ARRAY_LEN (hex_quads))
278       return 0;
279
280     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
281       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
282
283     return 1;
284   }
285 }
286
287 uword
288 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
289 {
290   u32 *r = va_arg (*args, u32 *);
291
292   if (0);
293 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
294   foreach_ipsec_policy_action
295 #undef _
296     else
297     return 0;
298   return 1;
299 }
300
301 uword
302 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
303 {
304   u32 *r = va_arg (*args, u32 *);
305
306   if (0);
307 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
308   foreach_ipsec_crypto_alg
309 #undef _
310     else
311     return 0;
312   return 1;
313 }
314
315 u8 *
316 format_ipsec_crypto_alg (u8 * s, va_list * args)
317 {
318   u32 i = va_arg (*args, u32);
319   u8 *t = 0;
320
321   switch (i)
322     {
323 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
324       foreach_ipsec_crypto_alg
325 #undef _
326     default:
327       return format (s, "unknown");
328     }
329   return format (s, "%s", t);
330 }
331
332 uword
333 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
334 {
335   u32 *r = va_arg (*args, u32 *);
336
337   if (0);
338 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
339   foreach_ipsec_integ_alg
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 u8 *
347 format_ipsec_integ_alg (u8 * s, va_list * args)
348 {
349   u32 i = va_arg (*args, u32);
350   u8 *t = 0;
351
352   switch (i)
353     {
354 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
355       foreach_ipsec_integ_alg
356 #undef _
357     default:
358       return format (s, "unknown");
359     }
360   return format (s, "%s", t);
361 }
362
363 uword
364 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
370   foreach_ikev2_auth_method
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 uword
378 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
379 {
380   u32 *r = va_arg (*args, u32 *);
381
382   if (0);
383 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
384   foreach_ikev2_id_type
385 #undef _
386     else
387     return 0;
388   return 1;
389 }
390 #endif /* VPP_API_TEST_BUILTIN */
391
392 static uword
393 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "kbps"))
398     *r = SSE2_QOS_RATE_KBPS;
399   else if (unformat (input, "pps"))
400     *r = SSE2_QOS_RATE_PPS;
401   else
402     return 0;
403   return 1;
404 }
405
406 static uword
407 unformat_policer_round_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "closest"))
412     *r = SSE2_QOS_ROUND_TO_CLOSEST;
413   else if (unformat (input, "up"))
414     *r = SSE2_QOS_ROUND_TO_UP;
415   else if (unformat (input, "down"))
416     *r = SSE2_QOS_ROUND_TO_DOWN;
417   else
418     return 0;
419   return 1;
420 }
421
422 static uword
423 unformat_policer_type (unformat_input_t * input, va_list * args)
424 {
425   u8 *r = va_arg (*args, u8 *);
426
427   if (unformat (input, "1r2c"))
428     *r = SSE2_QOS_POLICER_TYPE_1R2C;
429   else if (unformat (input, "1r3c"))
430     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
431   else if (unformat (input, "2r3c-2698"))
432     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
433   else if (unformat (input, "2r3c-4115"))
434     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
435   else if (unformat (input, "2r3c-mef5cf1"))
436     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
437   else
438     return 0;
439   return 1;
440 }
441
442 static uword
443 unformat_dscp (unformat_input_t * input, va_list * va)
444 {
445   u8 *r = va_arg (*va, u8 *);
446
447   if (0);
448 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
449   foreach_vnet_dscp
450 #undef _
451     else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_policer_action_type (unformat_input_t * input, va_list * va)
458 {
459   sse2_qos_pol_action_params_st *a
460     = va_arg (*va, sse2_qos_pol_action_params_st *);
461
462   if (unformat (input, "drop"))
463     a->action_type = SSE2_QOS_ACTION_DROP;
464   else if (unformat (input, "transmit"))
465     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
466   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
467     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
468   else
469     return 0;
470   return 1;
471 }
472
473 static uword
474 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
475 {
476   u32 *r = va_arg (*va, u32 *);
477   u32 tid;
478
479   if (unformat (input, "ip4"))
480     tid = POLICER_CLASSIFY_TABLE_IP4;
481   else if (unformat (input, "ip6"))
482     tid = POLICER_CLASSIFY_TABLE_IP6;
483   else if (unformat (input, "l2"))
484     tid = POLICER_CLASSIFY_TABLE_L2;
485   else
486     return 0;
487
488   *r = tid;
489   return 1;
490 }
491
492 static uword
493 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
494 {
495   u32 *r = va_arg (*va, u32 *);
496   u32 tid;
497
498   if (unformat (input, "ip4"))
499     tid = FLOW_CLASSIFY_TABLE_IP4;
500   else if (unformat (input, "ip6"))
501     tid = FLOW_CLASSIFY_TABLE_IP6;
502   else
503     return 0;
504
505   *r = tid;
506   return 1;
507 }
508
509 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
510 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
511 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
512 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
513
514 uword
515 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
516 {
517   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
518   mfib_itf_attribute_t attr;
519
520   old = *iflags;
521   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
522   {
523     if (unformat (input, mfib_itf_flag_long_names[attr]))
524       *iflags |= (1 << attr);
525   }
526   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
527   {
528     if (unformat (input, mfib_itf_flag_names[attr]))
529       *iflags |= (1 << attr);
530   }
531
532   return (old == *iflags ? 0 : 1);
533 }
534
535 uword
536 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
537 {
538   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
539   mfib_entry_attribute_t attr;
540
541   old = *eflags;
542   FOR_EACH_MFIB_ATTRIBUTE (attr)
543   {
544     if (unformat (input, mfib_flag_long_names[attr]))
545       *eflags |= (1 << attr);
546   }
547   FOR_EACH_MFIB_ATTRIBUTE (attr)
548   {
549     if (unformat (input, mfib_flag_names[attr]))
550       *eflags |= (1 << attr);
551   }
552
553   return (old == *eflags ? 0 : 1);
554 }
555
556 #if (VPP_API_TEST_BUILTIN==0)
557 u8 *
558 format_ip4_address (u8 * s, va_list * args)
559 {
560   u8 *a = va_arg (*args, u8 *);
561   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
562 }
563
564 u8 *
565 format_ip6_address (u8 * s, va_list * args)
566 {
567   ip6_address_t *a = va_arg (*args, ip6_address_t *);
568   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
569
570   i_max_n_zero = ARRAY_LEN (a->as_u16);
571   max_n_zeros = 0;
572   i_first_zero = i_max_n_zero;
573   n_zeros = 0;
574   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
575     {
576       u32 is_zero = a->as_u16[i] == 0;
577       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
578         {
579           i_first_zero = i;
580           n_zeros = 0;
581         }
582       n_zeros += is_zero;
583       if ((!is_zero && n_zeros > max_n_zeros)
584           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
585         {
586           i_max_n_zero = i_first_zero;
587           max_n_zeros = n_zeros;
588           i_first_zero = ARRAY_LEN (a->as_u16);
589           n_zeros = 0;
590         }
591     }
592
593   last_double_colon = 0;
594   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
595     {
596       if (i == i_max_n_zero && max_n_zeros > 1)
597         {
598           s = format (s, "::");
599           i += max_n_zeros - 1;
600           last_double_colon = 1;
601         }
602       else
603         {
604           s = format (s, "%s%x",
605                       (last_double_colon || i == 0) ? "" : ":",
606                       clib_net_to_host_u16 (a->as_u16[i]));
607           last_double_colon = 0;
608         }
609     }
610
611   return s;
612 }
613
614 /* Format an IP46 address. */
615 u8 *
616 format_ip46_address (u8 * s, va_list * args)
617 {
618   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
619   ip46_type_t type = va_arg (*args, ip46_type_t);
620   int is_ip4 = 1;
621
622   switch (type)
623     {
624     case IP46_TYPE_ANY:
625       is_ip4 = ip46_address_is_ip4 (ip46);
626       break;
627     case IP46_TYPE_IP4:
628       is_ip4 = 1;
629       break;
630     case IP46_TYPE_IP6:
631       is_ip4 = 0;
632       break;
633     }
634
635   return is_ip4 ?
636     format (s, "%U", format_ip4_address, &ip46->ip4) :
637     format (s, "%U", format_ip6_address, &ip46->ip6);
638 }
639
640 u8 *
641 format_ethernet_address (u8 * s, va_list * args)
642 {
643   u8 *a = va_arg (*args, u8 *);
644
645   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
646                  a[0], a[1], a[2], a[3], a[4], a[5]);
647 }
648 #endif
649
650 static void
651 increment_v4_address (ip4_address_t * a)
652 {
653   u32 v;
654
655   v = ntohl (a->as_u32) + 1;
656   a->as_u32 = ntohl (v);
657 }
658
659 static void
660 increment_v6_address (ip6_address_t * a)
661 {
662   u64 v0, v1;
663
664   v0 = clib_net_to_host_u64 (a->as_u64[0]);
665   v1 = clib_net_to_host_u64 (a->as_u64[1]);
666
667   v1 += 1;
668   if (v1 == 0)
669     v0 += 1;
670   a->as_u64[0] = clib_net_to_host_u64 (v0);
671   a->as_u64[1] = clib_net_to_host_u64 (v1);
672 }
673
674 static void
675 increment_mac_address (u64 * mac)
676 {
677   u64 tmp = *mac;
678
679   tmp = clib_net_to_host_u64 (tmp);
680   tmp += 1 << 16;               /* skip unused (least significant) octets */
681   tmp = clib_host_to_net_u64 (tmp);
682   *mac = tmp;
683 }
684
685 static void vl_api_create_loopback_reply_t_handler
686   (vl_api_create_loopback_reply_t * mp)
687 {
688   vat_main_t *vam = &vat_main;
689   i32 retval = ntohl (mp->retval);
690
691   vam->retval = retval;
692   vam->regenerate_interface_table = 1;
693   vam->sw_if_index = ntohl (mp->sw_if_index);
694   vam->result_ready = 1;
695 }
696
697 static void vl_api_create_loopback_reply_t_handler_json
698   (vl_api_create_loopback_reply_t * mp)
699 {
700   vat_main_t *vam = &vat_main;
701   vat_json_node_t node;
702
703   vat_json_init_object (&node);
704   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
705   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
706
707   vat_json_print (vam->ofp, &node);
708   vat_json_free (&node);
709   vam->retval = ntohl (mp->retval);
710   vam->result_ready = 1;
711 }
712
713 static void vl_api_af_packet_create_reply_t_handler
714   (vl_api_af_packet_create_reply_t * mp)
715 {
716   vat_main_t *vam = &vat_main;
717   i32 retval = ntohl (mp->retval);
718
719   vam->retval = retval;
720   vam->regenerate_interface_table = 1;
721   vam->sw_if_index = ntohl (mp->sw_if_index);
722   vam->result_ready = 1;
723 }
724
725 static void vl_api_af_packet_create_reply_t_handler_json
726   (vl_api_af_packet_create_reply_t * mp)
727 {
728   vat_main_t *vam = &vat_main;
729   vat_json_node_t node;
730
731   vat_json_init_object (&node);
732   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
733   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
734
735   vat_json_print (vam->ofp, &node);
736   vat_json_free (&node);
737
738   vam->retval = ntohl (mp->retval);
739   vam->result_ready = 1;
740 }
741
742 static void vl_api_create_vlan_subif_reply_t_handler
743   (vl_api_create_vlan_subif_reply_t * mp)
744 {
745   vat_main_t *vam = &vat_main;
746   i32 retval = ntohl (mp->retval);
747
748   vam->retval = retval;
749   vam->regenerate_interface_table = 1;
750   vam->sw_if_index = ntohl (mp->sw_if_index);
751   vam->result_ready = 1;
752 }
753
754 static void vl_api_create_vlan_subif_reply_t_handler_json
755   (vl_api_create_vlan_subif_reply_t * mp)
756 {
757   vat_main_t *vam = &vat_main;
758   vat_json_node_t node;
759
760   vat_json_init_object (&node);
761   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
762   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
763
764   vat_json_print (vam->ofp, &node);
765   vat_json_free (&node);
766
767   vam->retval = ntohl (mp->retval);
768   vam->result_ready = 1;
769 }
770
771 static void vl_api_create_subif_reply_t_handler
772   (vl_api_create_subif_reply_t * mp)
773 {
774   vat_main_t *vam = &vat_main;
775   i32 retval = ntohl (mp->retval);
776
777   vam->retval = retval;
778   vam->regenerate_interface_table = 1;
779   vam->sw_if_index = ntohl (mp->sw_if_index);
780   vam->result_ready = 1;
781 }
782
783 static void vl_api_create_subif_reply_t_handler_json
784   (vl_api_create_subif_reply_t * mp)
785 {
786   vat_main_t *vam = &vat_main;
787   vat_json_node_t node;
788
789   vat_json_init_object (&node);
790   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
791   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
792
793   vat_json_print (vam->ofp, &node);
794   vat_json_free (&node);
795
796   vam->retval = ntohl (mp->retval);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_interface_name_renumber_reply_t_handler
801   (vl_api_interface_name_renumber_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   i32 retval = ntohl (mp->retval);
805
806   vam->retval = retval;
807   vam->regenerate_interface_table = 1;
808   vam->result_ready = 1;
809 }
810
811 static void vl_api_interface_name_renumber_reply_t_handler_json
812   (vl_api_interface_name_renumber_reply_t * mp)
813 {
814   vat_main_t *vam = &vat_main;
815   vat_json_node_t node;
816
817   vat_json_init_object (&node);
818   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
819
820   vat_json_print (vam->ofp, &node);
821   vat_json_free (&node);
822
823   vam->retval = ntohl (mp->retval);
824   vam->result_ready = 1;
825 }
826
827 /*
828  * Special-case: build the interface table, maintain
829  * the next loopback sw_if_index vbl.
830  */
831 static void vl_api_sw_interface_details_t_handler
832   (vl_api_sw_interface_details_t * mp)
833 {
834   vat_main_t *vam = &vat_main;
835   u8 *s = format (0, "%s%c", mp->interface_name, 0);
836
837   hash_set_mem (vam->sw_if_index_by_interface_name, s,
838                 ntohl (mp->sw_if_index));
839
840   /* In sub interface case, fill the sub interface table entry */
841   if (mp->sw_if_index != mp->sup_sw_if_index)
842     {
843       sw_interface_subif_t *sub = NULL;
844
845       vec_add2 (vam->sw_if_subif_table, sub, 1);
846
847       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
848       strncpy ((char *) sub->interface_name, (char *) s,
849                vec_len (sub->interface_name));
850       sub->sw_if_index = ntohl (mp->sw_if_index);
851       sub->sub_id = ntohl (mp->sub_id);
852
853       sub->sub_dot1ad = mp->sub_dot1ad;
854       sub->sub_number_of_tags = mp->sub_number_of_tags;
855       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
856       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
857       sub->sub_exact_match = mp->sub_exact_match;
858       sub->sub_default = mp->sub_default;
859       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
860       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
861
862       /* vlan tag rewrite */
863       sub->vtr_op = ntohl (mp->vtr_op);
864       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
865       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
866       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
867     }
868 }
869
870 static void vl_api_sw_interface_details_t_handler_json
871   (vl_api_sw_interface_details_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t *node = NULL;
875
876   if (VAT_JSON_ARRAY != vam->json_tree.type)
877     {
878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
879       vat_json_init_array (&vam->json_tree);
880     }
881   node = vat_json_array_add (&vam->json_tree);
882
883   vat_json_init_object (node);
884   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
885   vat_json_object_add_uint (node, "sup_sw_if_index",
886                             ntohl (mp->sup_sw_if_index));
887   vat_json_object_add_uint (node, "l2_address_length",
888                             ntohl (mp->l2_address_length));
889   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
890                              sizeof (mp->l2_address));
891   vat_json_object_add_string_copy (node, "interface_name",
892                                    mp->interface_name);
893   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
894   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
895   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
896   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
897   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
898   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
899   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
900   vat_json_object_add_uint (node, "sub_number_of_tags",
901                             mp->sub_number_of_tags);
902   vat_json_object_add_uint (node, "sub_outer_vlan_id",
903                             ntohs (mp->sub_outer_vlan_id));
904   vat_json_object_add_uint (node, "sub_inner_vlan_id",
905                             ntohs (mp->sub_inner_vlan_id));
906   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
907   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
908   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
909                             mp->sub_outer_vlan_id_any);
910   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
911                             mp->sub_inner_vlan_id_any);
912   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
913   vat_json_object_add_uint (node, "vtr_push_dot1q",
914                             ntohl (mp->vtr_push_dot1q));
915   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
916   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
917 }
918
919 static void vl_api_sw_interface_set_flags_t_handler
920   (vl_api_sw_interface_set_flags_t * mp)
921 {
922   vat_main_t *vam = &vat_main;
923   if (vam->interface_event_display)
924     errmsg ("interface flags: sw_if_index %d %s %s",
925             ntohl (mp->sw_if_index),
926             mp->admin_up_down ? "admin-up" : "admin-down",
927             mp->link_up_down ? "link-up" : "link-down");
928 }
929
930 static void vl_api_sw_interface_set_flags_t_handler_json
931   (vl_api_sw_interface_set_flags_t * mp)
932 {
933   /* JSON output not supported */
934 }
935
936 static void
937 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
938 {
939   vat_main_t *vam = &vat_main;
940   i32 retval = ntohl (mp->retval);
941
942   vam->retval = retval;
943   vam->shmem_result = (u8 *) mp->reply_in_shmem;
944   vam->result_ready = 1;
945 }
946
947 static void
948 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
949 {
950   vat_main_t *vam = &vat_main;
951   vat_json_node_t node;
952   api_main_t *am = &api_main;
953   void *oldheap;
954   u8 *reply;
955
956   vat_json_init_object (&node);
957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
958   vat_json_object_add_uint (&node, "reply_in_shmem",
959                             ntohl (mp->reply_in_shmem));
960   /* Toss the shared-memory original... */
961   pthread_mutex_lock (&am->vlib_rp->mutex);
962   oldheap = svm_push_data_heap (am->vlib_rp);
963
964   reply = (u8 *) (mp->reply_in_shmem);
965   vec_free (reply);
966
967   svm_pop_heap (oldheap);
968   pthread_mutex_unlock (&am->vlib_rp->mutex);
969
970   vat_json_print (vam->ofp, &node);
971   vat_json_free (&node);
972
973   vam->retval = ntohl (mp->retval);
974   vam->result_ready = 1;
975 }
976
977 static void
978 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
979 {
980   vat_main_t *vam = &vat_main;
981   i32 retval = ntohl (mp->retval);
982
983   vam->retval = retval;
984   vam->cmd_reply = mp->reply;
985   vam->result_ready = 1;
986 }
987
988 static void
989 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
990 {
991   vat_main_t *vam = &vat_main;
992   vat_json_node_t node;
993
994   vat_json_init_object (&node);
995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
996   vat_json_object_add_string_copy (&node, "reply", mp->reply);
997
998   vat_json_print (vam->ofp, &node);
999   vat_json_free (&node);
1000
1001   vam->retval = ntohl (mp->retval);
1002   vam->result_ready = 1;
1003 }
1004
1005 static void vl_api_classify_add_del_table_reply_t_handler
1006   (vl_api_classify_add_del_table_reply_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   i32 retval = ntohl (mp->retval);
1010   if (vam->async_mode)
1011     {
1012       vam->async_errors += (retval < 0);
1013     }
1014   else
1015     {
1016       vam->retval = retval;
1017       if (retval == 0 &&
1018           ((mp->new_table_index != 0xFFFFFFFF) ||
1019            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1020            (mp->match_n_vectors != 0xFFFFFFFF)))
1021         /*
1022          * Note: this is just barely thread-safe, depends on
1023          * the main thread spinning waiting for an answer...
1024          */
1025         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1026                 ntohl (mp->new_table_index),
1027                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1028       vam->result_ready = 1;
1029     }
1030 }
1031
1032 static void vl_api_classify_add_del_table_reply_t_handler_json
1033   (vl_api_classify_add_del_table_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   vat_json_node_t node;
1037
1038   vat_json_init_object (&node);
1039   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1040   vat_json_object_add_uint (&node, "new_table_index",
1041                             ntohl (mp->new_table_index));
1042   vat_json_object_add_uint (&node, "skip_n_vectors",
1043                             ntohl (mp->skip_n_vectors));
1044   vat_json_object_add_uint (&node, "match_n_vectors",
1045                             ntohl (mp->match_n_vectors));
1046
1047   vat_json_print (vam->ofp, &node);
1048   vat_json_free (&node);
1049
1050   vam->retval = ntohl (mp->retval);
1051   vam->result_ready = 1;
1052 }
1053
1054 static void vl_api_get_node_index_reply_t_handler
1055   (vl_api_get_node_index_reply_t * mp)
1056 {
1057   vat_main_t *vam = &vat_main;
1058   i32 retval = ntohl (mp->retval);
1059   if (vam->async_mode)
1060     {
1061       vam->async_errors += (retval < 0);
1062     }
1063   else
1064     {
1065       vam->retval = retval;
1066       if (retval == 0)
1067         errmsg ("node index %d", ntohl (mp->node_index));
1068       vam->result_ready = 1;
1069     }
1070 }
1071
1072 static void vl_api_get_node_index_reply_t_handler_json
1073   (vl_api_get_node_index_reply_t * mp)
1074 {
1075   vat_main_t *vam = &vat_main;
1076   vat_json_node_t node;
1077
1078   vat_json_init_object (&node);
1079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1080   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1081
1082   vat_json_print (vam->ofp, &node);
1083   vat_json_free (&node);
1084
1085   vam->retval = ntohl (mp->retval);
1086   vam->result_ready = 1;
1087 }
1088
1089 static void vl_api_get_next_index_reply_t_handler
1090   (vl_api_get_next_index_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   i32 retval = ntohl (mp->retval);
1094   if (vam->async_mode)
1095     {
1096       vam->async_errors += (retval < 0);
1097     }
1098   else
1099     {
1100       vam->retval = retval;
1101       if (retval == 0)
1102         errmsg ("next node index %d", ntohl (mp->next_index));
1103       vam->result_ready = 1;
1104     }
1105 }
1106
1107 static void vl_api_get_next_index_reply_t_handler_json
1108   (vl_api_get_next_index_reply_t * mp)
1109 {
1110   vat_main_t *vam = &vat_main;
1111   vat_json_node_t node;
1112
1113   vat_json_init_object (&node);
1114   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1115   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1116
1117   vat_json_print (vam->ofp, &node);
1118   vat_json_free (&node);
1119
1120   vam->retval = ntohl (mp->retval);
1121   vam->result_ready = 1;
1122 }
1123
1124 static void vl_api_add_node_next_reply_t_handler
1125   (vl_api_add_node_next_reply_t * mp)
1126 {
1127   vat_main_t *vam = &vat_main;
1128   i32 retval = ntohl (mp->retval);
1129   if (vam->async_mode)
1130     {
1131       vam->async_errors += (retval < 0);
1132     }
1133   else
1134     {
1135       vam->retval = retval;
1136       if (retval == 0)
1137         errmsg ("next index %d", ntohl (mp->next_index));
1138       vam->result_ready = 1;
1139     }
1140 }
1141
1142 static void vl_api_add_node_next_reply_t_handler_json
1143   (vl_api_add_node_next_reply_t * mp)
1144 {
1145   vat_main_t *vam = &vat_main;
1146   vat_json_node_t node;
1147
1148   vat_json_init_object (&node);
1149   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1150   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1151
1152   vat_json_print (vam->ofp, &node);
1153   vat_json_free (&node);
1154
1155   vam->retval = ntohl (mp->retval);
1156   vam->result_ready = 1;
1157 }
1158
1159 static void vl_api_show_version_reply_t_handler
1160   (vl_api_show_version_reply_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   i32 retval = ntohl (mp->retval);
1164
1165   if (retval >= 0)
1166     {
1167       errmsg ("        program: %s", mp->program);
1168       errmsg ("        version: %s", mp->version);
1169       errmsg ("     build date: %s", mp->build_date);
1170       errmsg ("build directory: %s", mp->build_directory);
1171     }
1172   vam->retval = retval;
1173   vam->result_ready = 1;
1174 }
1175
1176 static void vl_api_show_version_reply_t_handler_json
1177   (vl_api_show_version_reply_t * mp)
1178 {
1179   vat_main_t *vam = &vat_main;
1180   vat_json_node_t node;
1181
1182   vat_json_init_object (&node);
1183   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1184   vat_json_object_add_string_copy (&node, "program", mp->program);
1185   vat_json_object_add_string_copy (&node, "version", mp->version);
1186   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1187   vat_json_object_add_string_copy (&node, "build_directory",
1188                                    mp->build_directory);
1189
1190   vat_json_print (vam->ofp, &node);
1191   vat_json_free (&node);
1192
1193   vam->retval = ntohl (mp->retval);
1194   vam->result_ready = 1;
1195 }
1196
1197 static void
1198 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1199 {
1200   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1201           mp->mac_ip ? "mac/ip binding" : "address resolution",
1202           format_ip4_address, &mp->address,
1203           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1204 }
1205
1206 static void
1207 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1208 {
1209   /* JSON output not supported */
1210 }
1211
1212 static void
1213 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1214 {
1215   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1216           mp->mac_ip ? "mac/ip binding" : "address resolution",
1217           format_ip6_address, mp->address,
1218           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1219 }
1220
1221 static void
1222 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1223 {
1224   /* JSON output not supported */
1225 }
1226
1227 /*
1228  * Special-case: build the bridge domain table, maintain
1229  * the next bd id vbl.
1230  */
1231 static void vl_api_bridge_domain_details_t_handler
1232   (vl_api_bridge_domain_details_t * mp)
1233 {
1234   vat_main_t *vam = &vat_main;
1235   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1236
1237   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1238          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1239
1240   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1241          ntohl (mp->bd_id), mp->learn, mp->forward,
1242          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1243
1244   if (n_sw_ifs)
1245     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1246 }
1247
1248 static void vl_api_bridge_domain_details_t_handler_json
1249   (vl_api_bridge_domain_details_t * mp)
1250 {
1251   vat_main_t *vam = &vat_main;
1252   vat_json_node_t *node, *array = NULL;
1253
1254   if (VAT_JSON_ARRAY != vam->json_tree.type)
1255     {
1256       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1257       vat_json_init_array (&vam->json_tree);
1258     }
1259   node = vat_json_array_add (&vam->json_tree);
1260
1261   vat_json_init_object (node);
1262   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1263   vat_json_object_add_uint (node, "flood", mp->flood);
1264   vat_json_object_add_uint (node, "forward", mp->forward);
1265   vat_json_object_add_uint (node, "learn", mp->learn);
1266   vat_json_object_add_uint (node, "bvi_sw_if_index",
1267                             ntohl (mp->bvi_sw_if_index));
1268   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1269   array = vat_json_object_add (node, "sw_if");
1270   vat_json_init_array (array);
1271 }
1272
1273 /*
1274  * Special-case: build the bridge domain sw if table.
1275  */
1276 static void vl_api_bridge_domain_sw_if_details_t_handler
1277   (vl_api_bridge_domain_sw_if_details_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   hash_pair_t *p;
1281   u8 *sw_if_name = 0;
1282   u32 sw_if_index;
1283
1284   sw_if_index = ntohl (mp->sw_if_index);
1285   /* *INDENT-OFF* */
1286   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1287   ({
1288     if ((u32) p->value[0] == sw_if_index)
1289       {
1290         sw_if_name = (u8 *)(p->key);
1291         break;
1292       }
1293   }));
1294   /* *INDENT-ON* */
1295
1296   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1297          mp->shg, sw_if_name ? (char *) sw_if_name :
1298          "sw_if_index not found!");
1299 }
1300
1301 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1302   (vl_api_bridge_domain_sw_if_details_t * mp)
1303 {
1304   vat_main_t *vam = &vat_main;
1305   vat_json_node_t *node = NULL;
1306   uword last_index = 0;
1307
1308   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1309   ASSERT (vec_len (vam->json_tree.array) >= 1);
1310   last_index = vec_len (vam->json_tree.array) - 1;
1311   node = &vam->json_tree.array[last_index];
1312   node = vat_json_object_get_element (node, "sw_if");
1313   ASSERT (NULL != node);
1314   node = vat_json_array_add (node);
1315
1316   vat_json_init_object (node);
1317   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1318   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1319   vat_json_object_add_uint (node, "shg", mp->shg);
1320 }
1321
1322 static void vl_api_control_ping_reply_t_handler
1323   (vl_api_control_ping_reply_t * mp)
1324 {
1325   vat_main_t *vam = &vat_main;
1326   i32 retval = ntohl (mp->retval);
1327   if (vam->async_mode)
1328     {
1329       vam->async_errors += (retval < 0);
1330     }
1331   else
1332     {
1333       vam->retval = retval;
1334       vam->result_ready = 1;
1335     }
1336 }
1337
1338 static void vl_api_control_ping_reply_t_handler_json
1339   (vl_api_control_ping_reply_t * mp)
1340 {
1341   vat_main_t *vam = &vat_main;
1342   i32 retval = ntohl (mp->retval);
1343
1344   if (VAT_JSON_NONE != vam->json_tree.type)
1345     {
1346       vat_json_print (vam->ofp, &vam->json_tree);
1347       vat_json_free (&vam->json_tree);
1348       vam->json_tree.type = VAT_JSON_NONE;
1349     }
1350   else
1351     {
1352       /* just print [] */
1353       vat_json_init_array (&vam->json_tree);
1354       vat_json_print (vam->ofp, &vam->json_tree);
1355       vam->json_tree.type = VAT_JSON_NONE;
1356     }
1357
1358   vam->retval = retval;
1359   vam->result_ready = 1;
1360 }
1361
1362 static void
1363 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1364 {
1365   vat_main_t *vam = &vat_main;
1366   i32 retval = ntohl (mp->retval);
1367   if (vam->async_mode)
1368     {
1369       vam->async_errors += (retval < 0);
1370     }
1371   else
1372     {
1373       vam->retval = retval;
1374       vam->result_ready = 1;
1375     }
1376 }
1377
1378 static void vl_api_l2_flags_reply_t_handler_json
1379   (vl_api_l2_flags_reply_t * mp)
1380 {
1381   vat_main_t *vam = &vat_main;
1382   vat_json_node_t node;
1383
1384   vat_json_init_object (&node);
1385   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1386   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1387                             ntohl (mp->resulting_feature_bitmap));
1388
1389   vat_json_print (vam->ofp, &node);
1390   vat_json_free (&node);
1391
1392   vam->retval = ntohl (mp->retval);
1393   vam->result_ready = 1;
1394 }
1395
1396 static void vl_api_bridge_flags_reply_t_handler
1397   (vl_api_bridge_flags_reply_t * mp)
1398 {
1399   vat_main_t *vam = &vat_main;
1400   i32 retval = ntohl (mp->retval);
1401   if (vam->async_mode)
1402     {
1403       vam->async_errors += (retval < 0);
1404     }
1405   else
1406     {
1407       vam->retval = retval;
1408       vam->result_ready = 1;
1409     }
1410 }
1411
1412 static void vl_api_bridge_flags_reply_t_handler_json
1413   (vl_api_bridge_flags_reply_t * mp)
1414 {
1415   vat_main_t *vam = &vat_main;
1416   vat_json_node_t node;
1417
1418   vat_json_init_object (&node);
1419   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1420   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1421                             ntohl (mp->resulting_feature_bitmap));
1422
1423   vat_json_print (vam->ofp, &node);
1424   vat_json_free (&node);
1425
1426   vam->retval = ntohl (mp->retval);
1427   vam->result_ready = 1;
1428 }
1429
1430 static void vl_api_tap_connect_reply_t_handler
1431   (vl_api_tap_connect_reply_t * mp)
1432 {
1433   vat_main_t *vam = &vat_main;
1434   i32 retval = ntohl (mp->retval);
1435   if (vam->async_mode)
1436     {
1437       vam->async_errors += (retval < 0);
1438     }
1439   else
1440     {
1441       vam->retval = retval;
1442       vam->sw_if_index = ntohl (mp->sw_if_index);
1443       vam->result_ready = 1;
1444     }
1445
1446 }
1447
1448 static void vl_api_tap_connect_reply_t_handler_json
1449   (vl_api_tap_connect_reply_t * mp)
1450 {
1451   vat_main_t *vam = &vat_main;
1452   vat_json_node_t node;
1453
1454   vat_json_init_object (&node);
1455   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1456   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1457
1458   vat_json_print (vam->ofp, &node);
1459   vat_json_free (&node);
1460
1461   vam->retval = ntohl (mp->retval);
1462   vam->result_ready = 1;
1463
1464 }
1465
1466 static void
1467 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1468 {
1469   vat_main_t *vam = &vat_main;
1470   i32 retval = ntohl (mp->retval);
1471   if (vam->async_mode)
1472     {
1473       vam->async_errors += (retval < 0);
1474     }
1475   else
1476     {
1477       vam->retval = retval;
1478       vam->sw_if_index = ntohl (mp->sw_if_index);
1479       vam->result_ready = 1;
1480     }
1481 }
1482
1483 static void vl_api_tap_modify_reply_t_handler_json
1484   (vl_api_tap_modify_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   vat_json_node_t node;
1488
1489   vat_json_init_object (&node);
1490   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1491   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1492
1493   vat_json_print (vam->ofp, &node);
1494   vat_json_free (&node);
1495
1496   vam->retval = ntohl (mp->retval);
1497   vam->result_ready = 1;
1498 }
1499
1500 static void
1501 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1502 {
1503   vat_main_t *vam = &vat_main;
1504   i32 retval = ntohl (mp->retval);
1505   if (vam->async_mode)
1506     {
1507       vam->async_errors += (retval < 0);
1508     }
1509   else
1510     {
1511       vam->retval = retval;
1512       vam->result_ready = 1;
1513     }
1514 }
1515
1516 static void vl_api_tap_delete_reply_t_handler_json
1517   (vl_api_tap_delete_reply_t * mp)
1518 {
1519   vat_main_t *vam = &vat_main;
1520   vat_json_node_t node;
1521
1522   vat_json_init_object (&node);
1523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1524
1525   vat_json_print (vam->ofp, &node);
1526   vat_json_free (&node);
1527
1528   vam->retval = ntohl (mp->retval);
1529   vam->result_ready = 1;
1530 }
1531
1532 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1533   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1534 {
1535   vat_main_t *vam = &vat_main;
1536   i32 retval = ntohl (mp->retval);
1537   if (vam->async_mode)
1538     {
1539       vam->async_errors += (retval < 0);
1540     }
1541   else
1542     {
1543       vam->retval = retval;
1544       vam->result_ready = 1;
1545     }
1546 }
1547
1548 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1549   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1550 {
1551   vat_main_t *vam = &vat_main;
1552   vat_json_node_t node;
1553
1554   vat_json_init_object (&node);
1555   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1556   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1557                             ntohl (mp->sw_if_index));
1558
1559   vat_json_print (vam->ofp, &node);
1560   vat_json_free (&node);
1561
1562   vam->retval = ntohl (mp->retval);
1563   vam->result_ready = 1;
1564 }
1565
1566 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1567   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1568 {
1569   vat_main_t *vam = &vat_main;
1570   i32 retval = ntohl (mp->retval);
1571   if (vam->async_mode)
1572     {
1573       vam->async_errors += (retval < 0);
1574     }
1575   else
1576     {
1577       vam->retval = retval;
1578       vam->sw_if_index = ntohl (mp->sw_if_index);
1579       vam->result_ready = 1;
1580     }
1581 }
1582
1583 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1584   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1585 {
1586   vat_main_t *vam = &vat_main;
1587   vat_json_node_t node;
1588
1589   vat_json_init_object (&node);
1590   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1591   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1592
1593   vat_json_print (vam->ofp, &node);
1594   vat_json_free (&node);
1595
1596   vam->retval = ntohl (mp->retval);
1597   vam->result_ready = 1;
1598 }
1599
1600
1601 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1602   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1603 {
1604   vat_main_t *vam = &vat_main;
1605   i32 retval = ntohl (mp->retval);
1606   if (vam->async_mode)
1607     {
1608       vam->async_errors += (retval < 0);
1609     }
1610   else
1611     {
1612       vam->retval = retval;
1613       vam->result_ready = 1;
1614     }
1615 }
1616
1617 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1618   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1619 {
1620   vat_main_t *vam = &vat_main;
1621   vat_json_node_t node;
1622
1623   vat_json_init_object (&node);
1624   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1625   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1626
1627   vat_json_print (vam->ofp, &node);
1628   vat_json_free (&node);
1629
1630   vam->retval = ntohl (mp->retval);
1631   vam->result_ready = 1;
1632 }
1633
1634 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1635   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1636 {
1637   vat_main_t *vam = &vat_main;
1638   i32 retval = ntohl (mp->retval);
1639   if (vam->async_mode)
1640     {
1641       vam->async_errors += (retval < 0);
1642     }
1643   else
1644     {
1645       vam->retval = retval;
1646       vam->sw_if_index = ntohl (mp->sw_if_index);
1647       vam->result_ready = 1;
1648     }
1649 }
1650
1651 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1652   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1653 {
1654   vat_main_t *vam = &vat_main;
1655   vat_json_node_t node;
1656
1657   vat_json_init_object (&node);
1658   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1659   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1660
1661   vat_json_print (vam->ofp, &node);
1662   vat_json_free (&node);
1663
1664   vam->retval = ntohl (mp->retval);
1665   vam->result_ready = 1;
1666 }
1667
1668 static void vl_api_gre_add_del_tunnel_reply_t_handler
1669   (vl_api_gre_add_del_tunnel_reply_t * mp)
1670 {
1671   vat_main_t *vam = &vat_main;
1672   i32 retval = ntohl (mp->retval);
1673   if (vam->async_mode)
1674     {
1675       vam->async_errors += (retval < 0);
1676     }
1677   else
1678     {
1679       vam->retval = retval;
1680       vam->sw_if_index = ntohl (mp->sw_if_index);
1681       vam->result_ready = 1;
1682     }
1683 }
1684
1685 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1686   (vl_api_gre_add_del_tunnel_reply_t * mp)
1687 {
1688   vat_main_t *vam = &vat_main;
1689   vat_json_node_t node;
1690
1691   vat_json_init_object (&node);
1692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1694
1695   vat_json_print (vam->ofp, &node);
1696   vat_json_free (&node);
1697
1698   vam->retval = ntohl (mp->retval);
1699   vam->result_ready = 1;
1700 }
1701
1702 static void vl_api_create_vhost_user_if_reply_t_handler
1703   (vl_api_create_vhost_user_if_reply_t * mp)
1704 {
1705   vat_main_t *vam = &vat_main;
1706   i32 retval = ntohl (mp->retval);
1707   if (vam->async_mode)
1708     {
1709       vam->async_errors += (retval < 0);
1710     }
1711   else
1712     {
1713       vam->retval = retval;
1714       vam->sw_if_index = ntohl (mp->sw_if_index);
1715       vam->result_ready = 1;
1716     }
1717 }
1718
1719 static void vl_api_create_vhost_user_if_reply_t_handler_json
1720   (vl_api_create_vhost_user_if_reply_t * mp)
1721 {
1722   vat_main_t *vam = &vat_main;
1723   vat_json_node_t node;
1724
1725   vat_json_init_object (&node);
1726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1727   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1728
1729   vat_json_print (vam->ofp, &node);
1730   vat_json_free (&node);
1731
1732   vam->retval = ntohl (mp->retval);
1733   vam->result_ready = 1;
1734 }
1735
1736 static void vl_api_ip_address_details_t_handler
1737   (vl_api_ip_address_details_t * mp)
1738 {
1739   vat_main_t *vam = &vat_main;
1740   static ip_address_details_t empty_ip_address_details = { {0} };
1741   ip_address_details_t *address = NULL;
1742   ip_details_t *current_ip_details = NULL;
1743   ip_details_t *details = NULL;
1744
1745   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1746
1747   if (!details || vam->current_sw_if_index >= vec_len (details)
1748       || !details[vam->current_sw_if_index].present)
1749     {
1750       errmsg ("ip address details arrived but not stored");
1751       errmsg ("ip_dump should be called first");
1752       return;
1753     }
1754
1755   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1756
1757 #define addresses (current_ip_details->addr)
1758
1759   vec_validate_init_empty (addresses, vec_len (addresses),
1760                            empty_ip_address_details);
1761
1762   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1763
1764   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1765   address->prefix_length = mp->prefix_length;
1766 #undef addresses
1767 }
1768
1769 static void vl_api_ip_address_details_t_handler_json
1770   (vl_api_ip_address_details_t * mp)
1771 {
1772   vat_main_t *vam = &vat_main;
1773   vat_json_node_t *node = NULL;
1774   struct in6_addr ip6;
1775   struct in_addr ip4;
1776
1777   if (VAT_JSON_ARRAY != vam->json_tree.type)
1778     {
1779       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1780       vat_json_init_array (&vam->json_tree);
1781     }
1782   node = vat_json_array_add (&vam->json_tree);
1783
1784   vat_json_init_object (node);
1785   if (vam->is_ipv6)
1786     {
1787       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1788       vat_json_object_add_ip6 (node, "ip", ip6);
1789     }
1790   else
1791     {
1792       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1793       vat_json_object_add_ip4 (node, "ip", ip4);
1794     }
1795   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1796 }
1797
1798 static void
1799 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   static ip_details_t empty_ip_details = { 0 };
1803   ip_details_t *ip = NULL;
1804   u32 sw_if_index = ~0;
1805
1806   sw_if_index = ntohl (mp->sw_if_index);
1807
1808   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1809                            sw_if_index, empty_ip_details);
1810
1811   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1812                          sw_if_index);
1813
1814   ip->present = 1;
1815 }
1816
1817 static void
1818 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1819 {
1820   vat_main_t *vam = &vat_main;
1821
1822   if (VAT_JSON_ARRAY != vam->json_tree.type)
1823     {
1824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1825       vat_json_init_array (&vam->json_tree);
1826     }
1827   vat_json_array_add_uint (&vam->json_tree,
1828                            clib_net_to_host_u32 (mp->sw_if_index));
1829 }
1830
1831 static void vl_api_map_domain_details_t_handler_json
1832   (vl_api_map_domain_details_t * mp)
1833 {
1834   vat_json_node_t *node = NULL;
1835   vat_main_t *vam = &vat_main;
1836   struct in6_addr ip6;
1837   struct in_addr ip4;
1838
1839   if (VAT_JSON_ARRAY != vam->json_tree.type)
1840     {
1841       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1842       vat_json_init_array (&vam->json_tree);
1843     }
1844
1845   node = vat_json_array_add (&vam->json_tree);
1846   vat_json_init_object (node);
1847
1848   vat_json_object_add_uint (node, "domain_index",
1849                             clib_net_to_host_u32 (mp->domain_index));
1850   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1851   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1852   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1853   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1854   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1855   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1856   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1857   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1858   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1859   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1860   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1861   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1862   vat_json_object_add_uint (node, "flags", mp->flags);
1863   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1864   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1865 }
1866
1867 static void vl_api_map_domain_details_t_handler
1868   (vl_api_map_domain_details_t * mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871
1872   if (mp->is_translation)
1873     {
1874       print (vam->ofp,
1875              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1876              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1877              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1878              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1879              clib_net_to_host_u32 (mp->domain_index));
1880     }
1881   else
1882     {
1883       print (vam->ofp,
1884              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1885              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1886              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1887              format_ip6_address, mp->ip6_src,
1888              clib_net_to_host_u32 (mp->domain_index));
1889     }
1890   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1891          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1892          mp->is_translation ? "map-t" : "");
1893 }
1894
1895 static void vl_api_map_rule_details_t_handler_json
1896   (vl_api_map_rule_details_t * mp)
1897 {
1898   struct in6_addr ip6;
1899   vat_json_node_t *node = NULL;
1900   vat_main_t *vam = &vat_main;
1901
1902   if (VAT_JSON_ARRAY != vam->json_tree.type)
1903     {
1904       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1905       vat_json_init_array (&vam->json_tree);
1906     }
1907
1908   node = vat_json_array_add (&vam->json_tree);
1909   vat_json_init_object (node);
1910
1911   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1912   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1913   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1914 }
1915
1916 static void
1917 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1921          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1922 }
1923
1924 static void
1925 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1926 {
1927   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1928           "router_addr %U host_mac %U",
1929           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1930           format_ip4_address, &mp->host_address,
1931           format_ip4_address, &mp->router_address,
1932           format_ethernet_address, mp->host_mac);
1933 }
1934
1935 static void vl_api_dhcp_compl_event_t_handler_json
1936   (vl_api_dhcp_compl_event_t * mp)
1937 {
1938   /* JSON output not supported */
1939 }
1940
1941 static void
1942 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1943                               u32 counter)
1944 {
1945   vat_main_t *vam = &vat_main;
1946   static u64 default_counter = 0;
1947
1948   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1949                            NULL);
1950   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1951                            sw_if_index, default_counter);
1952   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1953 }
1954
1955 static void
1956 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1957                                 interface_counter_t counter)
1958 {
1959   vat_main_t *vam = &vat_main;
1960   static interface_counter_t default_counter = { 0, };
1961
1962   vec_validate_init_empty (vam->combined_interface_counters,
1963                            vnet_counter_type, NULL);
1964   vec_validate_init_empty (vam->combined_interface_counters
1965                            [vnet_counter_type], sw_if_index, default_counter);
1966   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1967 }
1968
1969 static void vl_api_vnet_interface_counters_t_handler
1970   (vl_api_vnet_interface_counters_t * mp)
1971 {
1972   /* not supported */
1973 }
1974
1975 static void vl_api_vnet_interface_counters_t_handler_json
1976   (vl_api_vnet_interface_counters_t * mp)
1977 {
1978   interface_counter_t counter;
1979   vlib_counter_t *v;
1980   u64 *v_packets;
1981   u64 packets;
1982   u32 count;
1983   u32 first_sw_if_index;
1984   int i;
1985
1986   count = ntohl (mp->count);
1987   first_sw_if_index = ntohl (mp->first_sw_if_index);
1988
1989   if (!mp->is_combined)
1990     {
1991       v_packets = (u64 *) & mp->data;
1992       for (i = 0; i < count; i++)
1993         {
1994           packets =
1995             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1996           set_simple_interface_counter (mp->vnet_counter_type,
1997                                         first_sw_if_index + i, packets);
1998           v_packets++;
1999         }
2000     }
2001   else
2002     {
2003       v = (vlib_counter_t *) & mp->data;
2004       for (i = 0; i < count; i++)
2005         {
2006           counter.packets =
2007             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2008           counter.bytes =
2009             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2010           set_combined_interface_counter (mp->vnet_counter_type,
2011                                           first_sw_if_index + i, counter);
2012           v++;
2013         }
2014     }
2015 }
2016
2017 static u32
2018 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2019 {
2020   vat_main_t *vam = &vat_main;
2021   u32 i;
2022
2023   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2024     {
2025       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2026         {
2027           return i;
2028         }
2029     }
2030   return ~0;
2031 }
2032
2033 static u32
2034 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2035 {
2036   vat_main_t *vam = &vat_main;
2037   u32 i;
2038
2039   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2040     {
2041       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2042         {
2043           return i;
2044         }
2045     }
2046   return ~0;
2047 }
2048
2049 static void vl_api_vnet_ip4_fib_counters_t_handler
2050   (vl_api_vnet_ip4_fib_counters_t * mp)
2051 {
2052   /* not supported */
2053 }
2054
2055 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2056   (vl_api_vnet_ip4_fib_counters_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vl_api_ip4_fib_counter_t *v;
2060   ip4_fib_counter_t *counter;
2061   struct in_addr ip4;
2062   u32 vrf_id;
2063   u32 vrf_index;
2064   u32 count;
2065   int i;
2066
2067   vrf_id = ntohl (mp->vrf_id);
2068   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2069   if (~0 == vrf_index)
2070     {
2071       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2072       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2073       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2074       vec_validate (vam->ip4_fib_counters, vrf_index);
2075       vam->ip4_fib_counters[vrf_index] = NULL;
2076     }
2077
2078   vec_free (vam->ip4_fib_counters[vrf_index]);
2079   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2080   count = ntohl (mp->count);
2081   for (i = 0; i < count; i++)
2082     {
2083       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2084       counter = &vam->ip4_fib_counters[vrf_index][i];
2085       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2086       counter->address = ip4;
2087       counter->address_length = v->address_length;
2088       counter->packets = clib_net_to_host_u64 (v->packets);
2089       counter->bytes = clib_net_to_host_u64 (v->bytes);
2090       v++;
2091     }
2092 }
2093
2094 static void vl_api_vnet_ip4_nbr_counters_t_handler
2095   (vl_api_vnet_ip4_nbr_counters_t * mp)
2096 {
2097   /* not supported */
2098 }
2099
2100 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2101   (vl_api_vnet_ip4_nbr_counters_t * mp)
2102 {
2103   vat_main_t *vam = &vat_main;
2104   vl_api_ip4_nbr_counter_t *v;
2105   ip4_nbr_counter_t *counter;
2106   u32 sw_if_index;
2107   u32 count;
2108   int i;
2109
2110   sw_if_index = ntohl (mp->sw_if_index);
2111   count = ntohl (mp->count);
2112   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2113
2114   if (mp->begin)
2115     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2116
2117   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2118   for (i = 0; i < count; i++)
2119     {
2120       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2121       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2122       counter->address.s_addr = v->address;
2123       counter->packets = clib_net_to_host_u64 (v->packets);
2124       counter->bytes = clib_net_to_host_u64 (v->bytes);
2125       counter->linkt = v->link_type;
2126       v++;
2127     }
2128 }
2129
2130 static void vl_api_vnet_ip6_fib_counters_t_handler
2131   (vl_api_vnet_ip6_fib_counters_t * mp)
2132 {
2133   /* not supported */
2134 }
2135
2136 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2137   (vl_api_vnet_ip6_fib_counters_t * mp)
2138 {
2139   vat_main_t *vam = &vat_main;
2140   vl_api_ip6_fib_counter_t *v;
2141   ip6_fib_counter_t *counter;
2142   struct in6_addr ip6;
2143   u32 vrf_id;
2144   u32 vrf_index;
2145   u32 count;
2146   int i;
2147
2148   vrf_id = ntohl (mp->vrf_id);
2149   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2150   if (~0 == vrf_index)
2151     {
2152       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2153       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2154       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2155       vec_validate (vam->ip6_fib_counters, vrf_index);
2156       vam->ip6_fib_counters[vrf_index] = NULL;
2157     }
2158
2159   vec_free (vam->ip6_fib_counters[vrf_index]);
2160   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2161   count = ntohl (mp->count);
2162   for (i = 0; i < count; i++)
2163     {
2164       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2165       counter = &vam->ip6_fib_counters[vrf_index][i];
2166       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2167       counter->address = ip6;
2168       counter->address_length = v->address_length;
2169       counter->packets = clib_net_to_host_u64 (v->packets);
2170       counter->bytes = clib_net_to_host_u64 (v->bytes);
2171       v++;
2172     }
2173 }
2174
2175 static void vl_api_vnet_ip6_nbr_counters_t_handler
2176   (vl_api_vnet_ip6_nbr_counters_t * mp)
2177 {
2178   /* not supported */
2179 }
2180
2181 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2182   (vl_api_vnet_ip6_nbr_counters_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   vl_api_ip6_nbr_counter_t *v;
2186   ip6_nbr_counter_t *counter;
2187   struct in6_addr ip6;
2188   u32 sw_if_index;
2189   u32 count;
2190   int i;
2191
2192   sw_if_index = ntohl (mp->sw_if_index);
2193   count = ntohl (mp->count);
2194   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2195
2196   if (mp->begin)
2197     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2198
2199   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2200   for (i = 0; i < count; i++)
2201     {
2202       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2203       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2204       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2205       counter->address = ip6;
2206       counter->packets = clib_net_to_host_u64 (v->packets);
2207       counter->bytes = clib_net_to_host_u64 (v->bytes);
2208       v++;
2209     }
2210 }
2211
2212 static void vl_api_get_first_msg_id_reply_t_handler
2213   (vl_api_get_first_msg_id_reply_t * mp)
2214 {
2215   vat_main_t *vam = &vat_main;
2216   i32 retval = ntohl (mp->retval);
2217
2218   if (vam->async_mode)
2219     {
2220       vam->async_errors += (retval < 0);
2221     }
2222   else
2223     {
2224       vam->retval = retval;
2225       vam->result_ready = 1;
2226     }
2227   if (retval >= 0)
2228     {
2229       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2230     }
2231 }
2232
2233 static void vl_api_get_first_msg_id_reply_t_handler_json
2234   (vl_api_get_first_msg_id_reply_t * mp)
2235 {
2236   vat_main_t *vam = &vat_main;
2237   vat_json_node_t node;
2238
2239   vat_json_init_object (&node);
2240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2241   vat_json_object_add_uint (&node, "first_msg_id",
2242                             (uint) ntohs (mp->first_msg_id));
2243
2244   vat_json_print (vam->ofp, &node);
2245   vat_json_free (&node);
2246
2247   vam->retval = ntohl (mp->retval);
2248   vam->result_ready = 1;
2249 }
2250
2251 static void vl_api_get_node_graph_reply_t_handler
2252   (vl_api_get_node_graph_reply_t * mp)
2253 {
2254   vat_main_t *vam = &vat_main;
2255   api_main_t *am = &api_main;
2256   i32 retval = ntohl (mp->retval);
2257   u8 *pvt_copy, *reply;
2258   void *oldheap;
2259   vlib_node_t *node;
2260   int i;
2261
2262   if (vam->async_mode)
2263     {
2264       vam->async_errors += (retval < 0);
2265     }
2266   else
2267     {
2268       vam->retval = retval;
2269       vam->result_ready = 1;
2270     }
2271
2272   /* "Should never happen..." */
2273   if (retval != 0)
2274     return;
2275
2276   reply = (u8 *) (mp->reply_in_shmem);
2277   pvt_copy = vec_dup (reply);
2278
2279   /* Toss the shared-memory original... */
2280   pthread_mutex_lock (&am->vlib_rp->mutex);
2281   oldheap = svm_push_data_heap (am->vlib_rp);
2282
2283   vec_free (reply);
2284
2285   svm_pop_heap (oldheap);
2286   pthread_mutex_unlock (&am->vlib_rp->mutex);
2287
2288   if (vam->graph_nodes)
2289     {
2290       hash_free (vam->graph_node_index_by_name);
2291
2292       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2293         {
2294           node = vam->graph_nodes[i];
2295           vec_free (node->name);
2296           vec_free (node->next_nodes);
2297           vec_free (node);
2298         }
2299       vec_free (vam->graph_nodes);
2300     }
2301
2302   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2303   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2304   vec_free (pvt_copy);
2305
2306   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2307     {
2308       node = vam->graph_nodes[i];
2309       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2310     }
2311 }
2312
2313 static void vl_api_get_node_graph_reply_t_handler_json
2314   (vl_api_get_node_graph_reply_t * mp)
2315 {
2316   vat_main_t *vam = &vat_main;
2317   api_main_t *am = &api_main;
2318   void *oldheap;
2319   vat_json_node_t node;
2320   u8 *reply;
2321
2322   /* $$$$ make this real? */
2323   vat_json_init_object (&node);
2324   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2325   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2326
2327   reply = (u8 *) (mp->reply_in_shmem);
2328
2329   /* Toss the shared-memory original... */
2330   pthread_mutex_lock (&am->vlib_rp->mutex);
2331   oldheap = svm_push_data_heap (am->vlib_rp);
2332
2333   vec_free (reply);
2334
2335   svm_pop_heap (oldheap);
2336   pthread_mutex_unlock (&am->vlib_rp->mutex);
2337
2338   vat_json_print (vam->ofp, &node);
2339   vat_json_free (&node);
2340
2341   vam->retval = ntohl (mp->retval);
2342   vam->result_ready = 1;
2343 }
2344
2345 static void
2346 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2347 {
2348   vat_main_t *vam = &vat_main;
2349   u8 *s = 0;
2350
2351   if (mp->local)
2352     {
2353       s = format (s, "%=16d%=16d%=16d",
2354                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2355     }
2356   else
2357     {
2358       s = format (s, "%=16U%=16d%=16d",
2359                   mp->is_ipv6 ? format_ip6_address :
2360                   format_ip4_address,
2361                   mp->ip_address, mp->priority, mp->weight);
2362     }
2363
2364   print (vam->ofp, "%v", s);
2365   vec_free (s);
2366 }
2367
2368 static void
2369 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2370                                             mp)
2371 {
2372   vat_main_t *vam = &vat_main;
2373   vat_json_node_t *node = NULL;
2374   struct in6_addr ip6;
2375   struct in_addr ip4;
2376
2377   if (VAT_JSON_ARRAY != vam->json_tree.type)
2378     {
2379       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2380       vat_json_init_array (&vam->json_tree);
2381     }
2382   node = vat_json_array_add (&vam->json_tree);
2383   vat_json_init_object (node);
2384
2385   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2386   vat_json_object_add_uint (node, "priority", mp->priority);
2387   vat_json_object_add_uint (node, "weight", mp->weight);
2388
2389   if (mp->local)
2390     vat_json_object_add_uint (node, "sw_if_index",
2391                               clib_net_to_host_u32 (mp->sw_if_index));
2392   else
2393     {
2394       if (mp->is_ipv6)
2395         {
2396           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2397           vat_json_object_add_ip6 (node, "address", ip6);
2398         }
2399       else
2400         {
2401           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2402           vat_json_object_add_ip4 (node, "address", ip4);
2403         }
2404     }
2405 }
2406
2407 static void
2408 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2409                                            mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   u8 *ls_name = 0;
2413
2414   ls_name = format (0, "%s", mp->ls_name);
2415
2416   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2417          ls_name);
2418   vec_free (ls_name);
2419 }
2420
2421 static void
2422   vl_api_lisp_locator_set_details_t_handler_json
2423   (vl_api_lisp_locator_set_details_t * mp)
2424 {
2425   vat_main_t *vam = &vat_main;
2426   vat_json_node_t *node = 0;
2427   u8 *ls_name = 0;
2428
2429   ls_name = format (0, "%s", mp->ls_name);
2430   vec_add1 (ls_name, 0);
2431
2432   if (VAT_JSON_ARRAY != vam->json_tree.type)
2433     {
2434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2435       vat_json_init_array (&vam->json_tree);
2436     }
2437   node = vat_json_array_add (&vam->json_tree);
2438
2439   vat_json_init_object (node);
2440   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2441   vat_json_object_add_uint (node, "ls_index",
2442                             clib_net_to_host_u32 (mp->ls_index));
2443   vec_free (ls_name);
2444 }
2445
2446 static u8 *
2447 format_lisp_flat_eid (u8 * s, va_list * args)
2448 {
2449   u32 type = va_arg (*args, u32);
2450   u8 *eid = va_arg (*args, u8 *);
2451   u32 eid_len = va_arg (*args, u32);
2452
2453   switch (type)
2454     {
2455     case 0:
2456       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2457     case 1:
2458       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2459     case 2:
2460       return format (s, "%U", format_ethernet_address, eid);
2461     }
2462   return 0;
2463 }
2464
2465 static u8 *
2466 format_lisp_eid_vat (u8 * s, va_list * args)
2467 {
2468   u32 type = va_arg (*args, u32);
2469   u8 *eid = va_arg (*args, u8 *);
2470   u32 eid_len = va_arg (*args, u32);
2471   u8 *seid = va_arg (*args, u8 *);
2472   u32 seid_len = va_arg (*args, u32);
2473   u32 is_src_dst = va_arg (*args, u32);
2474
2475   if (is_src_dst)
2476     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2477
2478   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2479
2480   return s;
2481 }
2482
2483 static void
2484 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2485 {
2486   vat_main_t *vam = &vat_main;
2487   u8 *s = 0, *eid = 0;
2488
2489   if (~0 == mp->locator_set_index)
2490     s = format (0, "action: %d", mp->action);
2491   else
2492     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2493
2494   eid = format (0, "%U", format_lisp_eid_vat,
2495                 mp->eid_type,
2496                 mp->eid,
2497                 mp->eid_prefix_len,
2498                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2499   vec_add1 (eid, 0);
2500
2501   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2502          clib_net_to_host_u32 (mp->vni),
2503          eid,
2504          mp->is_local ? "local" : "remote",
2505          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2506          clib_net_to_host_u16 (mp->key_id), mp->key);
2507
2508   vec_free (s);
2509   vec_free (eid);
2510 }
2511
2512 static void
2513 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2514                                               * mp)
2515 {
2516   vat_main_t *vam = &vat_main;
2517   vat_json_node_t *node = 0;
2518   u8 *eid = 0;
2519
2520   if (VAT_JSON_ARRAY != vam->json_tree.type)
2521     {
2522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2523       vat_json_init_array (&vam->json_tree);
2524     }
2525   node = vat_json_array_add (&vam->json_tree);
2526
2527   vat_json_init_object (node);
2528   if (~0 == mp->locator_set_index)
2529     vat_json_object_add_uint (node, "action", mp->action);
2530   else
2531     vat_json_object_add_uint (node, "locator_set_index",
2532                               clib_net_to_host_u32 (mp->locator_set_index));
2533
2534   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2535   eid = format (0, "%U", format_lisp_eid_vat,
2536                 mp->eid_type,
2537                 mp->eid,
2538                 mp->eid_prefix_len,
2539                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2540   vec_add1 (eid, 0);
2541   vat_json_object_add_string_copy (node, "eid", eid);
2542   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2543   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2544   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2545
2546   if (mp->key_id)
2547     {
2548       vat_json_object_add_uint (node, "key_id",
2549                                 clib_net_to_host_u16 (mp->key_id));
2550       vat_json_object_add_string_copy (node, "key", mp->key);
2551     }
2552   vec_free (eid);
2553 }
2554
2555 static void
2556   vl_api_lisp_eid_table_map_details_t_handler
2557   (vl_api_lisp_eid_table_map_details_t * mp)
2558 {
2559   vat_main_t *vam = &vat_main;
2560
2561   u8 *line = format (0, "%=10d%=10d",
2562                      clib_net_to_host_u32 (mp->vni),
2563                      clib_net_to_host_u32 (mp->dp_table));
2564   print (vam->ofp, "%v", line);
2565   vec_free (line);
2566 }
2567
2568 static void
2569   vl_api_lisp_eid_table_map_details_t_handler_json
2570   (vl_api_lisp_eid_table_map_details_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   vat_json_node_t *node = NULL;
2574
2575   if (VAT_JSON_ARRAY != vam->json_tree.type)
2576     {
2577       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2578       vat_json_init_array (&vam->json_tree);
2579     }
2580   node = vat_json_array_add (&vam->json_tree);
2581   vat_json_init_object (node);
2582   vat_json_object_add_uint (node, "dp_table",
2583                             clib_net_to_host_u32 (mp->dp_table));
2584   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2585 }
2586
2587 static void
2588   vl_api_lisp_eid_table_vni_details_t_handler
2589   (vl_api_lisp_eid_table_vni_details_t * mp)
2590 {
2591   vat_main_t *vam = &vat_main;
2592
2593   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2594   print (vam->ofp, "%v", line);
2595   vec_free (line);
2596 }
2597
2598 static void
2599   vl_api_lisp_eid_table_vni_details_t_handler_json
2600   (vl_api_lisp_eid_table_vni_details_t * mp)
2601 {
2602   vat_main_t *vam = &vat_main;
2603   vat_json_node_t *node = NULL;
2604
2605   if (VAT_JSON_ARRAY != vam->json_tree.type)
2606     {
2607       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2608       vat_json_init_array (&vam->json_tree);
2609     }
2610   node = vat_json_array_add (&vam->json_tree);
2611   vat_json_init_object (node);
2612   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2613 }
2614
2615 static void
2616   vl_api_show_lisp_map_register_state_reply_t_handler
2617   (vl_api_show_lisp_map_register_state_reply_t * mp)
2618 {
2619   vat_main_t *vam = &vat_main;
2620   int retval = clib_net_to_host_u32 (mp->retval);
2621
2622   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2623
2624   vam->retval = retval;
2625   vam->result_ready = 1;
2626 }
2627
2628 static void
2629   vl_api_show_lisp_map_register_state_reply_t_handler_json
2630   (vl_api_show_lisp_map_register_state_reply_t * mp)
2631 {
2632   vat_main_t *vam = &vat_main;
2633   vat_json_node_t _node, *node = &_node;
2634   int retval = clib_net_to_host_u32 (mp->retval);
2635
2636   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2637
2638   vat_json_init_object (node);
2639   vat_json_object_add_string_copy (node, "state", s);
2640
2641   vat_json_print (vam->ofp, node);
2642   vat_json_free (node);
2643
2644   vam->retval = retval;
2645   vam->result_ready = 1;
2646   vec_free (s);
2647 }
2648
2649 static void
2650   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2651   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2652 {
2653   vat_main_t *vam = &vat_main;
2654   int retval = clib_net_to_host_u32 (mp->retval);
2655
2656   if (retval)
2657     goto end;
2658
2659   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2660 end:
2661   vam->retval = retval;
2662   vam->result_ready = 1;
2663 }
2664
2665 static void
2666   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2667   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2668 {
2669   vat_main_t *vam = &vat_main;
2670   vat_json_node_t _node, *node = &_node;
2671   int retval = clib_net_to_host_u32 (mp->retval);
2672
2673   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2674   vat_json_init_object (node);
2675   vat_json_object_add_string_copy (node, "state", s);
2676
2677   vat_json_print (vam->ofp, node);
2678   vat_json_free (node);
2679
2680   vam->retval = retval;
2681   vam->result_ready = 1;
2682   vec_free (s);
2683 }
2684
2685 static void
2686 api_lisp_gpe_fwd_entry_net_to_host (vl_api_lisp_gpe_fwd_entry_t * e)
2687 {
2688   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2689   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2690 }
2691
2692 static void
2693   lisp_gpe_fwd_entries_get_reply_t_net_to_host
2694   (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2695 {
2696   u32 i;
2697
2698   mp->count = clib_net_to_host_u32 (mp->count);
2699   for (i = 0; i < mp->count; i++)
2700     {
2701       api_lisp_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2702     }
2703 }
2704
2705 static void
2706   vl_api_lisp_gpe_fwd_entry_path_details_t_handler
2707   (vl_api_lisp_gpe_fwd_entry_path_details_t * mp)
2708 {
2709   vat_main_t *vam = &vat_main;
2710   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2711
2712   if (mp->lcl_loc.is_ip4)
2713     format_ip_address_fcn = format_ip4_address;
2714   else
2715     format_ip_address_fcn = format_ip6_address;
2716
2717   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2718          format_ip_address_fcn, &mp->lcl_loc,
2719          format_ip_address_fcn, &mp->rmt_loc);
2720 }
2721
2722 static void
2723 lisp_fill_locator_node (vat_json_node_t * n, vl_api_lisp_gpe_locator_t * loc)
2724 {
2725   struct in6_addr ip6;
2726   struct in_addr ip4;
2727
2728   if (loc->is_ip4)
2729     {
2730       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2731       vat_json_object_add_ip4 (n, "address", ip4);
2732     }
2733   else
2734     {
2735       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2736       vat_json_object_add_ip6 (n, "address", ip6);
2737     }
2738   vat_json_object_add_uint (n, "weight", loc->weight);
2739 }
2740
2741 static void
2742   vl_api_lisp_gpe_fwd_entry_path_details_t_handler_json
2743   (vl_api_lisp_gpe_fwd_entry_path_details_t * mp)
2744 {
2745   vat_main_t *vam = &vat_main;
2746   vat_json_node_t *node = NULL;
2747   vat_json_node_t *loc_node;
2748
2749   if (VAT_JSON_ARRAY != vam->json_tree.type)
2750     {
2751       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2752       vat_json_init_array (&vam->json_tree);
2753     }
2754   node = vat_json_array_add (&vam->json_tree);
2755   vat_json_init_object (node);
2756
2757   loc_node = vat_json_object_add (node, "local_locator");
2758   vat_json_init_object (loc_node);
2759   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2760
2761   loc_node = vat_json_object_add (node, "remote_locator");
2762   vat_json_init_object (loc_node);
2763   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2764 }
2765
2766 static void
2767   vl_api_lisp_gpe_fwd_entries_get_reply_t_handler
2768   (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2769 {
2770   vat_main_t *vam = &vat_main;
2771   u32 i;
2772   int retval = clib_net_to_host_u32 (mp->retval);
2773   vl_api_lisp_gpe_fwd_entry_t *e;
2774
2775   if (retval)
2776     goto end;
2777
2778   lisp_gpe_fwd_entries_get_reply_t_net_to_host (mp);
2779
2780   for (i = 0; i < mp->count; i++)
2781     {
2782       e = &mp->entries[i];
2783       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2784              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2785              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2786     }
2787
2788 end:
2789   vam->retval = retval;
2790   vam->result_ready = 1;
2791 }
2792
2793 static void
2794   vl_api_lisp_gpe_fwd_entries_get_reply_t_handler_json
2795   (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2796 {
2797   u8 *s = 0;
2798   vat_main_t *vam = &vat_main;
2799   vat_json_node_t *e = 0, root;
2800   u32 i;
2801   int retval = clib_net_to_host_u32 (mp->retval);
2802   vl_api_lisp_gpe_fwd_entry_t *fwd;
2803
2804   if (retval)
2805     goto end;
2806
2807   lisp_gpe_fwd_entries_get_reply_t_net_to_host (mp);
2808   vat_json_init_array (&root);
2809
2810   for (i = 0; i < mp->count; i++)
2811     {
2812       e = vat_json_array_add (&root);
2813       fwd = &mp->entries[i];
2814
2815       vat_json_init_object (e);
2816       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2817       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2818
2819       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2820                   fwd->leid_prefix_len);
2821       vec_add1 (s, 0);
2822       vat_json_object_add_string_copy (e, "leid", s);
2823       vec_free (s);
2824
2825       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2826                   fwd->reid_prefix_len);
2827       vec_add1 (s, 0);
2828       vat_json_object_add_string_copy (e, "reid", s);
2829       vec_free (s);
2830     }
2831
2832   vat_json_print (vam->ofp, &root);
2833   vat_json_free (&root);
2834
2835 end:
2836   vam->retval = retval;
2837   vam->result_ready = 1;
2838 }
2839
2840 static void
2841   vl_api_lisp_adjacencies_get_reply_t_handler
2842   (vl_api_lisp_adjacencies_get_reply_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   u32 i, n;
2846   int retval = clib_net_to_host_u32 (mp->retval);
2847   vl_api_lisp_adjacency_t *a;
2848
2849   if (retval)
2850     goto end;
2851
2852   n = clib_net_to_host_u32 (mp->count);
2853
2854   for (i = 0; i < n; i++)
2855     {
2856       a = &mp->adjacencies[i];
2857       print (vam->ofp, "%U %40U",
2858              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2859              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2860     }
2861
2862 end:
2863   vam->retval = retval;
2864   vam->result_ready = 1;
2865 }
2866
2867 static void
2868   vl_api_lisp_adjacencies_get_reply_t_handler_json
2869   (vl_api_lisp_adjacencies_get_reply_t * mp)
2870 {
2871   u8 *s = 0;
2872   vat_main_t *vam = &vat_main;
2873   vat_json_node_t *e = 0, root;
2874   u32 i, n;
2875   int retval = clib_net_to_host_u32 (mp->retval);
2876   vl_api_lisp_adjacency_t *a;
2877
2878   if (retval)
2879     goto end;
2880
2881   n = clib_net_to_host_u32 (mp->count);
2882   vat_json_init_array (&root);
2883
2884   for (i = 0; i < n; i++)
2885     {
2886       e = vat_json_array_add (&root);
2887       a = &mp->adjacencies[i];
2888
2889       vat_json_init_object (e);
2890       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2891                   a->leid_prefix_len);
2892       vec_add1 (s, 0);
2893       vat_json_object_add_string_copy (e, "leid", s);
2894       vec_free (s);
2895
2896       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2897                   a->reid_prefix_len);
2898       vec_add1 (s, 0);
2899       vat_json_object_add_string_copy (e, "reid", s);
2900       vec_free (s);
2901     }
2902
2903   vat_json_print (vam->ofp, &root);
2904   vat_json_free (&root);
2905
2906 end:
2907   vam->retval = retval;
2908   vam->result_ready = 1;
2909 }
2910
2911 static void
2912 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2913                                           * mp)
2914 {
2915   vat_main_t *vam = &vat_main;
2916
2917   print (vam->ofp, "%=20U",
2918          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2919          mp->ip_address);
2920 }
2921
2922 static void
2923   vl_api_lisp_map_server_details_t_handler_json
2924   (vl_api_lisp_map_server_details_t * mp)
2925 {
2926   vat_main_t *vam = &vat_main;
2927   vat_json_node_t *node = NULL;
2928   struct in6_addr ip6;
2929   struct in_addr ip4;
2930
2931   if (VAT_JSON_ARRAY != vam->json_tree.type)
2932     {
2933       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2934       vat_json_init_array (&vam->json_tree);
2935     }
2936   node = vat_json_array_add (&vam->json_tree);
2937
2938   vat_json_init_object (node);
2939   if (mp->is_ipv6)
2940     {
2941       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2942       vat_json_object_add_ip6 (node, "map-server", ip6);
2943     }
2944   else
2945     {
2946       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2947       vat_json_object_add_ip4 (node, "map-server", ip4);
2948     }
2949 }
2950
2951 static void
2952 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2953                                             * mp)
2954 {
2955   vat_main_t *vam = &vat_main;
2956
2957   print (vam->ofp, "%=20U",
2958          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2959          mp->ip_address);
2960 }
2961
2962 static void
2963   vl_api_lisp_map_resolver_details_t_handler_json
2964   (vl_api_lisp_map_resolver_details_t * mp)
2965 {
2966   vat_main_t *vam = &vat_main;
2967   vat_json_node_t *node = NULL;
2968   struct in6_addr ip6;
2969   struct in_addr ip4;
2970
2971   if (VAT_JSON_ARRAY != vam->json_tree.type)
2972     {
2973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2974       vat_json_init_array (&vam->json_tree);
2975     }
2976   node = vat_json_array_add (&vam->json_tree);
2977
2978   vat_json_init_object (node);
2979   if (mp->is_ipv6)
2980     {
2981       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2982       vat_json_object_add_ip6 (node, "map resolver", ip6);
2983     }
2984   else
2985     {
2986       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2987       vat_json_object_add_ip4 (node, "map resolver", ip4);
2988     }
2989 }
2990
2991 static void
2992   vl_api_show_lisp_status_reply_t_handler
2993   (vl_api_show_lisp_status_reply_t * mp)
2994 {
2995   vat_main_t *vam = &vat_main;
2996   i32 retval = ntohl (mp->retval);
2997
2998   if (0 <= retval)
2999     {
3000       print (vam->ofp, "feature: %s\ngpe: %s",
3001              mp->feature_status ? "enabled" : "disabled",
3002              mp->gpe_status ? "enabled" : "disabled");
3003     }
3004
3005   vam->retval = retval;
3006   vam->result_ready = 1;
3007 }
3008
3009 static void
3010   vl_api_show_lisp_status_reply_t_handler_json
3011   (vl_api_show_lisp_status_reply_t * mp)
3012 {
3013   vat_main_t *vam = &vat_main;
3014   vat_json_node_t node;
3015   u8 *gpe_status = NULL;
3016   u8 *feature_status = NULL;
3017
3018   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3019   feature_status = format (0, "%s",
3020                            mp->feature_status ? "enabled" : "disabled");
3021   vec_add1 (gpe_status, 0);
3022   vec_add1 (feature_status, 0);
3023
3024   vat_json_init_object (&node);
3025   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3026   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3027
3028   vec_free (gpe_status);
3029   vec_free (feature_status);
3030
3031   vat_json_print (vam->ofp, &node);
3032   vat_json_free (&node);
3033
3034   vam->retval = ntohl (mp->retval);
3035   vam->result_ready = 1;
3036 }
3037
3038 static void
3039   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
3040   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
3041 {
3042   vat_main_t *vam = &vat_main;
3043   i32 retval = ntohl (mp->retval);
3044
3045   if (retval >= 0)
3046     {
3047       print (vam->ofp, "%=20s", mp->locator_set_name);
3048     }
3049
3050   vam->retval = retval;
3051   vam->result_ready = 1;
3052 }
3053
3054 static void
3055   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
3056   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
3057 {
3058   vat_main_t *vam = &vat_main;
3059   vat_json_node_t *node = NULL;
3060
3061   if (VAT_JSON_ARRAY != vam->json_tree.type)
3062     {
3063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3064       vat_json_init_array (&vam->json_tree);
3065     }
3066   node = vat_json_array_add (&vam->json_tree);
3067
3068   vat_json_init_object (node);
3069   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3070
3071   vat_json_print (vam->ofp, node);
3072   vat_json_free (node);
3073
3074   vam->retval = ntohl (mp->retval);
3075   vam->result_ready = 1;
3076 }
3077
3078 static u8 *
3079 format_lisp_map_request_mode (u8 * s, va_list * args)
3080 {
3081   u32 mode = va_arg (*args, u32);
3082
3083   switch (mode)
3084     {
3085     case 0:
3086       return format (0, "dst-only");
3087     case 1:
3088       return format (0, "src-dst");
3089     }
3090   return 0;
3091 }
3092
3093 static void
3094   vl_api_show_lisp_map_request_mode_reply_t_handler
3095   (vl_api_show_lisp_map_request_mode_reply_t * mp)
3096 {
3097   vat_main_t *vam = &vat_main;
3098   i32 retval = ntohl (mp->retval);
3099
3100   if (0 <= retval)
3101     {
3102       u32 mode = mp->mode;
3103       print (vam->ofp, "map_request_mode: %U",
3104              format_lisp_map_request_mode, mode);
3105     }
3106
3107   vam->retval = retval;
3108   vam->result_ready = 1;
3109 }
3110
3111 static void
3112   vl_api_show_lisp_map_request_mode_reply_t_handler_json
3113   (vl_api_show_lisp_map_request_mode_reply_t * mp)
3114 {
3115   vat_main_t *vam = &vat_main;
3116   vat_json_node_t node;
3117   u8 *s = 0;
3118   u32 mode;
3119
3120   mode = mp->mode;
3121   s = format (0, "%U", format_lisp_map_request_mode, mode);
3122   vec_add1 (s, 0);
3123
3124   vat_json_init_object (&node);
3125   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3126   vat_json_print (vam->ofp, &node);
3127   vat_json_free (&node);
3128
3129   vec_free (s);
3130   vam->retval = ntohl (mp->retval);
3131   vam->result_ready = 1;
3132 }
3133
3134 static void
3135 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
3136 {
3137   vat_main_t *vam = &vat_main;
3138   i32 retval = ntohl (mp->retval);
3139
3140   if (0 <= retval)
3141     {
3142       print (vam->ofp, "%-20s%-16s",
3143              mp->status ? "enabled" : "disabled",
3144              mp->status ? (char *) mp->locator_set_name : "");
3145     }
3146
3147   vam->retval = retval;
3148   vam->result_ready = 1;
3149 }
3150
3151 static void
3152 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
3153                                             mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   vat_json_node_t node;
3157   u8 *status = 0;
3158
3159   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3160   vec_add1 (status, 0);
3161
3162   vat_json_init_object (&node);
3163   vat_json_object_add_string_copy (&node, "status", status);
3164   if (mp->status)
3165     {
3166       vat_json_object_add_string_copy (&node, "locator_set",
3167                                        mp->locator_set_name);
3168     }
3169
3170   vec_free (status);
3171
3172   vat_json_print (vam->ofp, &node);
3173   vat_json_free (&node);
3174
3175   vam->retval = ntohl (mp->retval);
3176   vam->result_ready = 1;
3177 }
3178
3179 static u8 *
3180 format_policer_type (u8 * s, va_list * va)
3181 {
3182   u32 i = va_arg (*va, u32);
3183
3184   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3185     s = format (s, "1r2c");
3186   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3187     s = format (s, "1r3c");
3188   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3189     s = format (s, "2r3c-2698");
3190   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3191     s = format (s, "2r3c-4115");
3192   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3193     s = format (s, "2r3c-mef5cf1");
3194   else
3195     s = format (s, "ILLEGAL");
3196   return s;
3197 }
3198
3199 static u8 *
3200 format_policer_rate_type (u8 * s, va_list * va)
3201 {
3202   u32 i = va_arg (*va, u32);
3203
3204   if (i == SSE2_QOS_RATE_KBPS)
3205     s = format (s, "kbps");
3206   else if (i == SSE2_QOS_RATE_PPS)
3207     s = format (s, "pps");
3208   else
3209     s = format (s, "ILLEGAL");
3210   return s;
3211 }
3212
3213 static u8 *
3214 format_policer_round_type (u8 * s, va_list * va)
3215 {
3216   u32 i = va_arg (*va, u32);
3217
3218   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3219     s = format (s, "closest");
3220   else if (i == SSE2_QOS_ROUND_TO_UP)
3221     s = format (s, "up");
3222   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3223     s = format (s, "down");
3224   else
3225     s = format (s, "ILLEGAL");
3226   return s;
3227 }
3228
3229 static u8 *
3230 format_policer_action_type (u8 * s, va_list * va)
3231 {
3232   u32 i = va_arg (*va, u32);
3233
3234   if (i == SSE2_QOS_ACTION_DROP)
3235     s = format (s, "drop");
3236   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3237     s = format (s, "transmit");
3238   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3239     s = format (s, "mark-and-transmit");
3240   else
3241     s = format (s, "ILLEGAL");
3242   return s;
3243 }
3244
3245 static u8 *
3246 format_dscp (u8 * s, va_list * va)
3247 {
3248   u32 i = va_arg (*va, u32);
3249   char *t = 0;
3250
3251   switch (i)
3252     {
3253 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3254       foreach_vnet_dscp
3255 #undef _
3256     default:
3257       return format (s, "ILLEGAL");
3258     }
3259   s = format (s, "%s", t);
3260   return s;
3261 }
3262
3263 static void
3264 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3265 {
3266   vat_main_t *vam = &vat_main;
3267   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3268
3269   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3270     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3271   else
3272     conform_dscp_str = format (0, "");
3273
3274   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3275     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3276   else
3277     exceed_dscp_str = format (0, "");
3278
3279   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3280     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3281   else
3282     violate_dscp_str = format (0, "");
3283
3284   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3285          "rate type %U, round type %U, %s rate, %s color-aware, "
3286          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3287          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3288          "conform action %U%s, exceed action %U%s, violate action %U%s",
3289          mp->name,
3290          format_policer_type, mp->type,
3291          ntohl (mp->cir),
3292          ntohl (mp->eir),
3293          clib_net_to_host_u64 (mp->cb),
3294          clib_net_to_host_u64 (mp->eb),
3295          format_policer_rate_type, mp->rate_type,
3296          format_policer_round_type, mp->round_type,
3297          mp->single_rate ? "single" : "dual",
3298          mp->color_aware ? "is" : "not",
3299          ntohl (mp->cir_tokens_per_period),
3300          ntohl (mp->pir_tokens_per_period),
3301          ntohl (mp->scale),
3302          ntohl (mp->current_limit),
3303          ntohl (mp->current_bucket),
3304          ntohl (mp->extended_limit),
3305          ntohl (mp->extended_bucket),
3306          clib_net_to_host_u64 (mp->last_update_time),
3307          format_policer_action_type, mp->conform_action_type,
3308          conform_dscp_str,
3309          format_policer_action_type, mp->exceed_action_type,
3310          exceed_dscp_str,
3311          format_policer_action_type, mp->violate_action_type,
3312          violate_dscp_str);
3313
3314   vec_free (conform_dscp_str);
3315   vec_free (exceed_dscp_str);
3316   vec_free (violate_dscp_str);
3317 }
3318
3319 static void vl_api_policer_details_t_handler_json
3320   (vl_api_policer_details_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t *node;
3324   u8 *rate_type_str, *round_type_str, *type_str;
3325   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3326
3327   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3328   round_type_str =
3329     format (0, "%U", format_policer_round_type, mp->round_type);
3330   type_str = format (0, "%U", format_policer_type, mp->type);
3331   conform_action_str = format (0, "%U", format_policer_action_type,
3332                                mp->conform_action_type);
3333   exceed_action_str = format (0, "%U", format_policer_action_type,
3334                               mp->exceed_action_type);
3335   violate_action_str = format (0, "%U", format_policer_action_type,
3336                                mp->violate_action_type);
3337
3338   if (VAT_JSON_ARRAY != vam->json_tree.type)
3339     {
3340       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3341       vat_json_init_array (&vam->json_tree);
3342     }
3343   node = vat_json_array_add (&vam->json_tree);
3344
3345   vat_json_init_object (node);
3346   vat_json_object_add_string_copy (node, "name", mp->name);
3347   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3348   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3349   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3350   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3351   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3352   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3353   vat_json_object_add_string_copy (node, "type", type_str);
3354   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3355   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3356   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3357   vat_json_object_add_uint (node, "cir_tokens_per_period",
3358                             ntohl (mp->cir_tokens_per_period));
3359   vat_json_object_add_uint (node, "eir_tokens_per_period",
3360                             ntohl (mp->pir_tokens_per_period));
3361   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3362   vat_json_object_add_uint (node, "current_bucket",
3363                             ntohl (mp->current_bucket));
3364   vat_json_object_add_uint (node, "extended_limit",
3365                             ntohl (mp->extended_limit));
3366   vat_json_object_add_uint (node, "extended_bucket",
3367                             ntohl (mp->extended_bucket));
3368   vat_json_object_add_uint (node, "last_update_time",
3369                             ntohl (mp->last_update_time));
3370   vat_json_object_add_string_copy (node, "conform_action",
3371                                    conform_action_str);
3372   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3373     {
3374       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3375       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3376       vec_free (dscp_str);
3377     }
3378   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3379   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3380     {
3381       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3382       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3383       vec_free (dscp_str);
3384     }
3385   vat_json_object_add_string_copy (node, "violate_action",
3386                                    violate_action_str);
3387   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3388     {
3389       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3390       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3391       vec_free (dscp_str);
3392     }
3393
3394   vec_free (rate_type_str);
3395   vec_free (round_type_str);
3396   vec_free (type_str);
3397   vec_free (conform_action_str);
3398   vec_free (exceed_action_str);
3399   vec_free (violate_action_str);
3400 }
3401
3402 static void
3403 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3404                                            mp)
3405 {
3406   vat_main_t *vam = &vat_main;
3407   int i, count = ntohl (mp->count);
3408
3409   if (count > 0)
3410     print (vam->ofp, "classify table ids (%d) : ", count);
3411   for (i = 0; i < count; i++)
3412     {
3413       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3414       print (vam->ofp, (i < count - 1) ? "," : "");
3415     }
3416   vam->retval = ntohl (mp->retval);
3417   vam->result_ready = 1;
3418 }
3419
3420 static void
3421   vl_api_classify_table_ids_reply_t_handler_json
3422   (vl_api_classify_table_ids_reply_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   int i, count = ntohl (mp->count);
3426
3427   if (count > 0)
3428     {
3429       vat_json_node_t node;
3430
3431       vat_json_init_object (&node);
3432       for (i = 0; i < count; i++)
3433         {
3434           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3435         }
3436       vat_json_print (vam->ofp, &node);
3437       vat_json_free (&node);
3438     }
3439   vam->retval = ntohl (mp->retval);
3440   vam->result_ready = 1;
3441 }
3442
3443 static void
3444   vl_api_classify_table_by_interface_reply_t_handler
3445   (vl_api_classify_table_by_interface_reply_t * mp)
3446 {
3447   vat_main_t *vam = &vat_main;
3448   u32 table_id;
3449
3450   table_id = ntohl (mp->l2_table_id);
3451   if (table_id != ~0)
3452     print (vam->ofp, "l2 table id : %d", table_id);
3453   else
3454     print (vam->ofp, "l2 table id : No input ACL tables configured");
3455   table_id = ntohl (mp->ip4_table_id);
3456   if (table_id != ~0)
3457     print (vam->ofp, "ip4 table id : %d", table_id);
3458   else
3459     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3460   table_id = ntohl (mp->ip6_table_id);
3461   if (table_id != ~0)
3462     print (vam->ofp, "ip6 table id : %d", table_id);
3463   else
3464     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3465   vam->retval = ntohl (mp->retval);
3466   vam->result_ready = 1;
3467 }
3468
3469 static void
3470   vl_api_classify_table_by_interface_reply_t_handler_json
3471   (vl_api_classify_table_by_interface_reply_t * mp)
3472 {
3473   vat_main_t *vam = &vat_main;
3474   vat_json_node_t node;
3475
3476   vat_json_init_object (&node);
3477
3478   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3479   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3480   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3481
3482   vat_json_print (vam->ofp, &node);
3483   vat_json_free (&node);
3484
3485   vam->retval = ntohl (mp->retval);
3486   vam->result_ready = 1;
3487 }
3488
3489 static void vl_api_policer_add_del_reply_t_handler
3490   (vl_api_policer_add_del_reply_t * mp)
3491 {
3492   vat_main_t *vam = &vat_main;
3493   i32 retval = ntohl (mp->retval);
3494   if (vam->async_mode)
3495     {
3496       vam->async_errors += (retval < 0);
3497     }
3498   else
3499     {
3500       vam->retval = retval;
3501       vam->result_ready = 1;
3502       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3503         /*
3504          * Note: this is just barely thread-safe, depends on
3505          * the main thread spinning waiting for an answer...
3506          */
3507         errmsg ("policer index %d", ntohl (mp->policer_index));
3508     }
3509 }
3510
3511 static void vl_api_policer_add_del_reply_t_handler_json
3512   (vl_api_policer_add_del_reply_t * mp)
3513 {
3514   vat_main_t *vam = &vat_main;
3515   vat_json_node_t node;
3516
3517   vat_json_init_object (&node);
3518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3519   vat_json_object_add_uint (&node, "policer_index",
3520                             ntohl (mp->policer_index));
3521
3522   vat_json_print (vam->ofp, &node);
3523   vat_json_free (&node);
3524
3525   vam->retval = ntohl (mp->retval);
3526   vam->result_ready = 1;
3527 }
3528
3529 /* Format hex dump. */
3530 u8 *
3531 format_hex_bytes (u8 * s, va_list * va)
3532 {
3533   u8 *bytes = va_arg (*va, u8 *);
3534   int n_bytes = va_arg (*va, int);
3535   uword i;
3536
3537   /* Print short or long form depending on byte count. */
3538   uword short_form = n_bytes <= 32;
3539   uword indent = format_get_indent (s);
3540
3541   if (n_bytes == 0)
3542     return s;
3543
3544   for (i = 0; i < n_bytes; i++)
3545     {
3546       if (!short_form && (i % 32) == 0)
3547         s = format (s, "%08x: ", i);
3548       s = format (s, "%02x", bytes[i]);
3549       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3550         s = format (s, "\n%U", format_white_space, indent);
3551     }
3552
3553   return s;
3554 }
3555
3556 static void
3557 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3558                                             * mp)
3559 {
3560   vat_main_t *vam = &vat_main;
3561   i32 retval = ntohl (mp->retval);
3562   if (retval == 0)
3563     {
3564       print (vam->ofp, "classify table info :");
3565       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3566              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3567              ntohl (mp->miss_next_index));
3568       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3569              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3570              ntohl (mp->match_n_vectors));
3571       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3572              ntohl (mp->mask_length));
3573     }
3574   vam->retval = retval;
3575   vam->result_ready = 1;
3576 }
3577
3578 static void
3579   vl_api_classify_table_info_reply_t_handler_json
3580   (vl_api_classify_table_info_reply_t * mp)
3581 {
3582   vat_main_t *vam = &vat_main;
3583   vat_json_node_t node;
3584
3585   i32 retval = ntohl (mp->retval);
3586   if (retval == 0)
3587     {
3588       vat_json_init_object (&node);
3589
3590       vat_json_object_add_int (&node, "sessions",
3591                                ntohl (mp->active_sessions));
3592       vat_json_object_add_int (&node, "nexttbl",
3593                                ntohl (mp->next_table_index));
3594       vat_json_object_add_int (&node, "nextnode",
3595                                ntohl (mp->miss_next_index));
3596       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3597       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3598       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3599       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3600                       ntohl (mp->mask_length), 0);
3601       vat_json_object_add_string_copy (&node, "mask", s);
3602
3603       vat_json_print (vam->ofp, &node);
3604       vat_json_free (&node);
3605     }
3606   vam->retval = ntohl (mp->retval);
3607   vam->result_ready = 1;
3608 }
3609
3610 static void
3611 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3612                                            mp)
3613 {
3614   vat_main_t *vam = &vat_main;
3615
3616   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3617          ntohl (mp->hit_next_index), ntohl (mp->advance),
3618          ntohl (mp->opaque_index));
3619   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3620          ntohl (mp->match_length));
3621 }
3622
3623 static void
3624   vl_api_classify_session_details_t_handler_json
3625   (vl_api_classify_session_details_t * mp)
3626 {
3627   vat_main_t *vam = &vat_main;
3628   vat_json_node_t *node = NULL;
3629
3630   if (VAT_JSON_ARRAY != vam->json_tree.type)
3631     {
3632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3633       vat_json_init_array (&vam->json_tree);
3634     }
3635   node = vat_json_array_add (&vam->json_tree);
3636
3637   vat_json_init_object (node);
3638   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3639   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3640   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3641   u8 *s =
3642     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3643             0);
3644   vat_json_object_add_string_copy (node, "match", s);
3645 }
3646
3647 static void vl_api_pg_create_interface_reply_t_handler
3648   (vl_api_pg_create_interface_reply_t * mp)
3649 {
3650   vat_main_t *vam = &vat_main;
3651
3652   vam->retval = ntohl (mp->retval);
3653   vam->result_ready = 1;
3654 }
3655
3656 static void vl_api_pg_create_interface_reply_t_handler_json
3657   (vl_api_pg_create_interface_reply_t * mp)
3658 {
3659   vat_main_t *vam = &vat_main;
3660   vat_json_node_t node;
3661
3662   i32 retval = ntohl (mp->retval);
3663   if (retval == 0)
3664     {
3665       vat_json_init_object (&node);
3666
3667       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3668
3669       vat_json_print (vam->ofp, &node);
3670       vat_json_free (&node);
3671     }
3672   vam->retval = ntohl (mp->retval);
3673   vam->result_ready = 1;
3674 }
3675
3676 static void vl_api_policer_classify_details_t_handler
3677   (vl_api_policer_classify_details_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680
3681   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3682          ntohl (mp->table_index));
3683 }
3684
3685 static void vl_api_policer_classify_details_t_handler_json
3686   (vl_api_policer_classify_details_t * mp)
3687 {
3688   vat_main_t *vam = &vat_main;
3689   vat_json_node_t *node;
3690
3691   if (VAT_JSON_ARRAY != vam->json_tree.type)
3692     {
3693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3694       vat_json_init_array (&vam->json_tree);
3695     }
3696   node = vat_json_array_add (&vam->json_tree);
3697
3698   vat_json_init_object (node);
3699   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3700   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3701 }
3702
3703 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3704   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3705 {
3706   vat_main_t *vam = &vat_main;
3707   i32 retval = ntohl (mp->retval);
3708   if (vam->async_mode)
3709     {
3710       vam->async_errors += (retval < 0);
3711     }
3712   else
3713     {
3714       vam->retval = retval;
3715       vam->sw_if_index = ntohl (mp->sw_if_index);
3716       vam->result_ready = 1;
3717     }
3718 }
3719
3720 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3721   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3722 {
3723   vat_main_t *vam = &vat_main;
3724   vat_json_node_t node;
3725
3726   vat_json_init_object (&node);
3727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3729
3730   vat_json_print (vam->ofp, &node);
3731   vat_json_free (&node);
3732
3733   vam->retval = ntohl (mp->retval);
3734   vam->result_ready = 1;
3735 }
3736
3737 static void vl_api_flow_classify_details_t_handler
3738   (vl_api_flow_classify_details_t * mp)
3739 {
3740   vat_main_t *vam = &vat_main;
3741
3742   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3743          ntohl (mp->table_index));
3744 }
3745
3746 static void vl_api_flow_classify_details_t_handler_json
3747   (vl_api_flow_classify_details_t * mp)
3748 {
3749   vat_main_t *vam = &vat_main;
3750   vat_json_node_t *node;
3751
3752   if (VAT_JSON_ARRAY != vam->json_tree.type)
3753     {
3754       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3755       vat_json_init_array (&vam->json_tree);
3756     }
3757   node = vat_json_array_add (&vam->json_tree);
3758
3759   vat_json_init_object (node);
3760   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3761   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3762 }
3763
3764
3765
3766 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3767 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3768 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3769 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3770 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3771 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3772 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3773 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3774 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3775 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3776
3777 /*
3778  * Generate boilerplate reply handlers, which
3779  * dig the return value out of the xxx_reply_t API message,
3780  * stick it into vam->retval, and set vam->result_ready
3781  *
3782  * Could also do this by pointing N message decode slots at
3783  * a single function, but that could break in subtle ways.
3784  */
3785
3786 #define foreach_standard_reply_retval_handler           \
3787 _(sw_interface_set_flags_reply)                         \
3788 _(sw_interface_add_del_address_reply)                   \
3789 _(sw_interface_set_table_reply)                         \
3790 _(sw_interface_set_mpls_enable_reply)                   \
3791 _(sw_interface_set_vpath_reply)                         \
3792 _(sw_interface_set_vxlan_bypass_reply)                  \
3793 _(sw_interface_set_l2_bridge_reply)                     \
3794 _(bridge_domain_add_del_reply)                          \
3795 _(sw_interface_set_l2_xconnect_reply)                   \
3796 _(l2fib_add_del_reply)                                  \
3797 _(ip_add_del_route_reply)                               \
3798 _(ip_mroute_add_del_reply)                              \
3799 _(mpls_route_add_del_reply)                             \
3800 _(mpls_ip_bind_unbind_reply)                            \
3801 _(proxy_arp_add_del_reply)                              \
3802 _(proxy_arp_intfc_enable_disable_reply)                 \
3803 _(sw_interface_set_unnumbered_reply)                    \
3804 _(ip_neighbor_add_del_reply)                            \
3805 _(reset_vrf_reply)                                      \
3806 _(oam_add_del_reply)                                    \
3807 _(reset_fib_reply)                                      \
3808 _(dhcp_proxy_config_reply)                              \
3809 _(dhcp_proxy_config_2_reply)                            \
3810 _(dhcp_proxy_set_vss_reply)                             \
3811 _(dhcp_client_config_reply)                             \
3812 _(set_ip_flow_hash_reply)                               \
3813 _(sw_interface_ip6_enable_disable_reply)                \
3814 _(sw_interface_ip6_set_link_local_address_reply)        \
3815 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3816 _(sw_interface_ip6nd_ra_config_reply)                   \
3817 _(set_arp_neighbor_limit_reply)                         \
3818 _(l2_patch_add_del_reply)                               \
3819 _(sr_tunnel_add_del_reply)                              \
3820 _(sr_policy_add_del_reply)                              \
3821 _(sr_multicast_map_add_del_reply)                       \
3822 _(classify_add_del_session_reply)                       \
3823 _(classify_set_interface_ip_table_reply)                \
3824 _(classify_set_interface_l2_tables_reply)               \
3825 _(l2tpv3_set_tunnel_cookies_reply)                      \
3826 _(l2tpv3_interface_enable_disable_reply)                \
3827 _(l2tpv3_set_lookup_key_reply)                          \
3828 _(l2_fib_clear_table_reply)                             \
3829 _(l2_interface_efp_filter_reply)                        \
3830 _(l2_interface_vlan_tag_rewrite_reply)                  \
3831 _(modify_vhost_user_if_reply)                           \
3832 _(delete_vhost_user_if_reply)                           \
3833 _(want_ip4_arp_events_reply)                            \
3834 _(want_ip6_nd_events_reply)                             \
3835 _(input_acl_set_interface_reply)                        \
3836 _(ipsec_spd_add_del_reply)                              \
3837 _(ipsec_interface_add_del_spd_reply)                    \
3838 _(ipsec_spd_add_del_entry_reply)                        \
3839 _(ipsec_sad_add_del_entry_reply)                        \
3840 _(ipsec_sa_set_key_reply)                               \
3841 _(ikev2_profile_add_del_reply)                          \
3842 _(ikev2_profile_set_auth_reply)                         \
3843 _(ikev2_profile_set_id_reply)                           \
3844 _(ikev2_profile_set_ts_reply)                           \
3845 _(ikev2_set_local_key_reply)                            \
3846 _(delete_loopback_reply)                                \
3847 _(bd_ip_mac_add_del_reply)                              \
3848 _(map_del_domain_reply)                                 \
3849 _(map_add_del_rule_reply)                               \
3850 _(want_interface_events_reply)                          \
3851 _(want_stats_reply)                                     \
3852 _(cop_interface_enable_disable_reply)                   \
3853 _(cop_whitelist_enable_disable_reply)                   \
3854 _(sw_interface_clear_stats_reply)                       \
3855 _(ioam_enable_reply)                              \
3856 _(ioam_disable_reply)                              \
3857 _(lisp_add_del_locator_reply)                           \
3858 _(lisp_add_del_local_eid_reply)                         \
3859 _(lisp_add_del_remote_mapping_reply)                    \
3860 _(lisp_add_del_adjacency_reply)                         \
3861 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3862 _(lisp_add_del_map_resolver_reply)                      \
3863 _(lisp_add_del_map_server_reply)                        \
3864 _(lisp_gpe_enable_disable_reply)                        \
3865 _(lisp_gpe_add_del_iface_reply)                         \
3866 _(lisp_enable_disable_reply)                            \
3867 _(lisp_rloc_probe_enable_disable_reply)                 \
3868 _(lisp_map_register_enable_disable_reply)               \
3869 _(lisp_pitr_set_locator_set_reply)                      \
3870 _(lisp_map_request_mode_reply)                          \
3871 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3872 _(lisp_eid_table_add_del_map_reply)                     \
3873 _(vxlan_gpe_add_del_tunnel_reply)                       \
3874 _(af_packet_delete_reply)                               \
3875 _(policer_classify_set_interface_reply)                 \
3876 _(netmap_create_reply)                                  \
3877 _(netmap_delete_reply)                                  \
3878 _(set_ipfix_exporter_reply)                             \
3879 _(set_ipfix_classify_stream_reply)                      \
3880 _(ipfix_classify_table_add_del_reply)                   \
3881 _(flow_classify_set_interface_reply)                    \
3882 _(sw_interface_span_enable_disable_reply)               \
3883 _(pg_capture_reply)                                     \
3884 _(pg_enable_disable_reply)                              \
3885 _(ip_source_and_port_range_check_add_del_reply)         \
3886 _(ip_source_and_port_range_check_interface_add_del_reply)\
3887 _(delete_subif_reply)                                   \
3888 _(l2_interface_pbb_tag_rewrite_reply)                   \
3889 _(punt_reply)                                           \
3890 _(feature_enable_disable_reply)                         \
3891 _(sw_interface_tag_add_del_reply)                       \
3892 _(sw_interface_set_mtu_reply)
3893
3894 #if DPDK > 0
3895 #define foreach_standard_dpdk_reply_retval_handler      \
3896 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3897 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3898 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3899 #endif
3900
3901 #define _(n)                                    \
3902     static void vl_api_##n##_t_handler          \
3903     (vl_api_##n##_t * mp)                       \
3904     {                                           \
3905         vat_main_t * vam = &vat_main;           \
3906         i32 retval = ntohl(mp->retval);         \
3907         if (vam->async_mode) {                  \
3908             vam->async_errors += (retval < 0);  \
3909         } else {                                \
3910             vam->retval = retval;               \
3911             vam->result_ready = 1;              \
3912         }                                       \
3913     }
3914 foreach_standard_reply_retval_handler;
3915 #undef _
3916
3917 #define _(n)                                    \
3918     static void vl_api_##n##_t_handler_json     \
3919     (vl_api_##n##_t * mp)                       \
3920     {                                           \
3921         vat_main_t * vam = &vat_main;           \
3922         vat_json_node_t node;                   \
3923         vat_json_init_object(&node);            \
3924         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3925         vat_json_print(vam->ofp, &node);        \
3926         vam->retval = ntohl(mp->retval);        \
3927         vam->result_ready = 1;                  \
3928     }
3929 foreach_standard_reply_retval_handler;
3930 #undef _
3931
3932 #if DPDK > 0
3933 #define _(n)                                    \
3934     static void vl_api_##n##_t_handler          \
3935     (vl_api_##n##_t * mp)                       \
3936     {                                           \
3937         vat_main_t * vam = &vat_main;           \
3938         i32 retval = ntohl(mp->retval);         \
3939         if (vam->async_mode) {                  \
3940             vam->async_errors += (retval < 0);  \
3941         } else {                                \
3942             vam->retval = retval;               \
3943             vam->result_ready = 1;              \
3944         }                                       \
3945     }
3946 foreach_standard_dpdk_reply_retval_handler;
3947 #undef _
3948
3949 #define _(n)                                    \
3950     static void vl_api_##n##_t_handler_json     \
3951     (vl_api_##n##_t * mp)                       \
3952     {                                           \
3953         vat_main_t * vam = &vat_main;           \
3954         vat_json_node_t node;                   \
3955         vat_json_init_object(&node);            \
3956         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3957         vat_json_print(vam->ofp, &node);        \
3958         vam->retval = ntohl(mp->retval);        \
3959         vam->result_ready = 1;                  \
3960     }
3961 foreach_standard_dpdk_reply_retval_handler;
3962 #undef _
3963 #endif
3964
3965 /*
3966  * Table of message reply handlers, must include boilerplate handlers
3967  * we just generated
3968  */
3969
3970 #define foreach_vpe_api_reply_msg                                       \
3971 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3972 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3973 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3974 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3975 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3976 _(CLI_REPLY, cli_reply)                                                 \
3977 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3978 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3979   sw_interface_add_del_address_reply)                                   \
3980 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3981 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3982 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3983 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3984 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3985   sw_interface_set_l2_xconnect_reply)                                   \
3986 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3987   sw_interface_set_l2_bridge_reply)                                     \
3988 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3989 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3990 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3991 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3992 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3993 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3994 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3995 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3996 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3997 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3998 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3999 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4000 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4001 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4002 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4003 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4004   proxy_arp_intfc_enable_disable_reply)                                 \
4005 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4006 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4007   sw_interface_set_unnumbered_reply)                                    \
4008 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4009 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4010 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4011 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4012 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4013 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4014 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4015 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
4016 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4017 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4018 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4019 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4020   sw_interface_ip6_enable_disable_reply)                                \
4021 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4022   sw_interface_ip6_set_link_local_address_reply)                        \
4023 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4024   sw_interface_ip6nd_ra_prefix_reply)                                   \
4025 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4026   sw_interface_ip6nd_ra_config_reply)                                   \
4027 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4028 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4029 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4030 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4031 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4032 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4033 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4034 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4035 classify_set_interface_ip_table_reply)                                  \
4036 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4037   classify_set_interface_l2_tables_reply)                               \
4038 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4039 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4040 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4041 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4042 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4043   l2tpv3_interface_enable_disable_reply)                                \
4044 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4045 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4046 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4047 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4048 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4049 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4050 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4051 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4052 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4053 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4054 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4055 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4056 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4057 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4058 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4059 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4060 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4061 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4062 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4063 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4064 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4065 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4066 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4067 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4068 _(IP_DETAILS, ip_details)                                               \
4069 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4070 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4071 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4072 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4073 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4074 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4075 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4076 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4077 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4078 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4079 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4080 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4081 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4082 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4083 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4084 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4085 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4086 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
4087 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4088 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4089 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4090 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4091 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4092 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4093 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4094 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4095 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4096 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4097 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4098 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4099 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4100 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4101 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
4102 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
4103 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
4104 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
4105 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
4106 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
4107 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
4108 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
4109 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
4110 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
4111 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
4112   lisp_map_register_enable_disable_reply)                               \
4113 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
4114   lisp_rloc_probe_enable_disable_reply)                                 \
4115 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
4116 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
4117 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
4118 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
4119 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
4120 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
4121 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
4122 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
4123 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
4124 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
4125 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
4126 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
4127 _(LISP_GPE_FWD_ENTRIES_GET_REPLY, lisp_gpe_fwd_entries_get_reply)       \
4128 _(LISP_GPE_FWD_ENTRY_PATH_DETAILS,                                      \
4129   lisp_gpe_fwd_entry_path_details)                                      \
4130 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
4131 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
4132   lisp_add_del_map_request_itr_rlocs_reply)                             \
4133 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
4134   lisp_get_map_request_itr_rlocs_reply)                                 \
4135 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
4136 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
4137 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
4138 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
4139   show_lisp_map_register_state_reply)                                   \
4140 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4141 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4142 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4143 _(POLICER_DETAILS, policer_details)                                     \
4144 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4145 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4146 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4147 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4148 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4149 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4150 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4151 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4152 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4153 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4154 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4155 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4156 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4157 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4158 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4159 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4160 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4161 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4162 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4163 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4164 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4165 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4166 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4167 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4168 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4169  ip_source_and_port_range_check_add_del_reply)                          \
4170 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4171  ip_source_and_port_range_check_interface_add_del_reply)                \
4172 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4173 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4174 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4175 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4176 _(PUNT_REPLY, punt_reply)                                               \
4177 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4178 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4179 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4180 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4181 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4182 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4183 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4184 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4185
4186 #if DPDK > 0
4187 #define foreach_vpe_dpdk_api_reply_msg                                  \
4188 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
4189   sw_interface_set_dpdk_hqos_pipe_reply)                                \
4190 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
4191   sw_interface_set_dpdk_hqos_subport_reply)                             \
4192 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
4193   sw_interface_set_dpdk_hqos_tctbl_reply)
4194 #endif
4195
4196 typedef struct
4197 {
4198   u8 *name;
4199   u32 value;
4200 } name_sort_t;
4201
4202
4203 #define STR_VTR_OP_CASE(op)     \
4204     case L2_VTR_ ## op:         \
4205         return "" # op;
4206
4207 static const char *
4208 str_vtr_op (u32 vtr_op)
4209 {
4210   switch (vtr_op)
4211     {
4212       STR_VTR_OP_CASE (DISABLED);
4213       STR_VTR_OP_CASE (PUSH_1);
4214       STR_VTR_OP_CASE (PUSH_2);
4215       STR_VTR_OP_CASE (POP_1);
4216       STR_VTR_OP_CASE (POP_2);
4217       STR_VTR_OP_CASE (TRANSLATE_1_1);
4218       STR_VTR_OP_CASE (TRANSLATE_1_2);
4219       STR_VTR_OP_CASE (TRANSLATE_2_1);
4220       STR_VTR_OP_CASE (TRANSLATE_2_2);
4221     }
4222
4223   return "UNKNOWN";
4224 }
4225
4226 static int
4227 dump_sub_interface_table (vat_main_t * vam)
4228 {
4229   const sw_interface_subif_t *sub = NULL;
4230
4231   if (vam->json_output)
4232     {
4233       clib_warning
4234         ("JSON output supported only for VPE API calls and dump_stats_table");
4235       return -99;
4236     }
4237
4238   print (vam->ofp,
4239          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4240          "Interface", "sw_if_index",
4241          "sub id", "dot1ad", "tags", "outer id",
4242          "inner id", "exact", "default", "outer any", "inner any");
4243
4244   vec_foreach (sub, vam->sw_if_subif_table)
4245   {
4246     print (vam->ofp,
4247            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4248            sub->interface_name,
4249            sub->sw_if_index,
4250            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4251            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4252            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4253            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4254     if (sub->vtr_op != L2_VTR_DISABLED)
4255       {
4256         print (vam->ofp,
4257                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4258                "tag1: %d tag2: %d ]",
4259                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4260                sub->vtr_tag1, sub->vtr_tag2);
4261       }
4262   }
4263
4264   return 0;
4265 }
4266
4267 static int
4268 name_sort_cmp (void *a1, void *a2)
4269 {
4270   name_sort_t *n1 = a1;
4271   name_sort_t *n2 = a2;
4272
4273   return strcmp ((char *) n1->name, (char *) n2->name);
4274 }
4275
4276 static int
4277 dump_interface_table (vat_main_t * vam)
4278 {
4279   hash_pair_t *p;
4280   name_sort_t *nses = 0, *ns;
4281
4282   if (vam->json_output)
4283     {
4284       clib_warning
4285         ("JSON output supported only for VPE API calls and dump_stats_table");
4286       return -99;
4287     }
4288
4289   /* *INDENT-OFF* */
4290   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4291   ({
4292     vec_add2 (nses, ns, 1);
4293     ns->name = (u8 *)(p->key);
4294     ns->value = (u32) p->value[0];
4295   }));
4296   /* *INDENT-ON* */
4297
4298   vec_sort_with_function (nses, name_sort_cmp);
4299
4300   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4301   vec_foreach (ns, nses)
4302   {
4303     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4304   }
4305   vec_free (nses);
4306   return 0;
4307 }
4308
4309 static int
4310 dump_ip_table (vat_main_t * vam, int is_ipv6)
4311 {
4312   const ip_details_t *det = NULL;
4313   const ip_address_details_t *address = NULL;
4314   u32 i = ~0;
4315
4316   print (vam->ofp, "%-12s", "sw_if_index");
4317
4318   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4319   {
4320     i++;
4321     if (!det->present)
4322       {
4323         continue;
4324       }
4325     print (vam->ofp, "%-12d", i);
4326     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4327     if (!det->addr)
4328       {
4329         continue;
4330       }
4331     vec_foreach (address, det->addr)
4332     {
4333       print (vam->ofp,
4334              "            %-30U%-13d",
4335              is_ipv6 ? format_ip6_address : format_ip4_address,
4336              address->ip, address->prefix_length);
4337     }
4338   }
4339
4340   return 0;
4341 }
4342
4343 static int
4344 dump_ipv4_table (vat_main_t * vam)
4345 {
4346   if (vam->json_output)
4347     {
4348       clib_warning
4349         ("JSON output supported only for VPE API calls and dump_stats_table");
4350       return -99;
4351     }
4352
4353   return dump_ip_table (vam, 0);
4354 }
4355
4356 static int
4357 dump_ipv6_table (vat_main_t * vam)
4358 {
4359   if (vam->json_output)
4360     {
4361       clib_warning
4362         ("JSON output supported only for VPE API calls and dump_stats_table");
4363       return -99;
4364     }
4365
4366   return dump_ip_table (vam, 1);
4367 }
4368
4369 static char *
4370 counter_type_to_str (u8 counter_type, u8 is_combined)
4371 {
4372   if (!is_combined)
4373     {
4374       switch (counter_type)
4375         {
4376         case VNET_INTERFACE_COUNTER_DROP:
4377           return "drop";
4378         case VNET_INTERFACE_COUNTER_PUNT:
4379           return "punt";
4380         case VNET_INTERFACE_COUNTER_IP4:
4381           return "ip4";
4382         case VNET_INTERFACE_COUNTER_IP6:
4383           return "ip6";
4384         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4385           return "rx-no-buf";
4386         case VNET_INTERFACE_COUNTER_RX_MISS:
4387           return "rx-miss";
4388         case VNET_INTERFACE_COUNTER_RX_ERROR:
4389           return "rx-error";
4390         case VNET_INTERFACE_COUNTER_TX_ERROR:
4391           return "tx-error";
4392         default:
4393           return "INVALID-COUNTER-TYPE";
4394         }
4395     }
4396   else
4397     {
4398       switch (counter_type)
4399         {
4400         case VNET_INTERFACE_COUNTER_RX:
4401           return "rx";
4402         case VNET_INTERFACE_COUNTER_TX:
4403           return "tx";
4404         default:
4405           return "INVALID-COUNTER-TYPE";
4406         }
4407     }
4408 }
4409
4410 static int
4411 dump_stats_table (vat_main_t * vam)
4412 {
4413   vat_json_node_t node;
4414   vat_json_node_t *msg_array;
4415   vat_json_node_t *msg;
4416   vat_json_node_t *counter_array;
4417   vat_json_node_t *counter;
4418   interface_counter_t c;
4419   u64 packets;
4420   ip4_fib_counter_t *c4;
4421   ip6_fib_counter_t *c6;
4422   ip4_nbr_counter_t *n4;
4423   ip6_nbr_counter_t *n6;
4424   int i, j;
4425
4426   if (!vam->json_output)
4427     {
4428       clib_warning ("dump_stats_table supported only in JSON format");
4429       return -99;
4430     }
4431
4432   vat_json_init_object (&node);
4433
4434   /* interface counters */
4435   msg_array = vat_json_object_add (&node, "interface_counters");
4436   vat_json_init_array (msg_array);
4437   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4438     {
4439       msg = vat_json_array_add (msg_array);
4440       vat_json_init_object (msg);
4441       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4442                                        (u8 *) counter_type_to_str (i, 0));
4443       vat_json_object_add_int (msg, "is_combined", 0);
4444       counter_array = vat_json_object_add (msg, "data");
4445       vat_json_init_array (counter_array);
4446       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4447         {
4448           packets = vam->simple_interface_counters[i][j];
4449           vat_json_array_add_uint (counter_array, packets);
4450         }
4451     }
4452   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4453     {
4454       msg = vat_json_array_add (msg_array);
4455       vat_json_init_object (msg);
4456       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4457                                        (u8 *) counter_type_to_str (i, 1));
4458       vat_json_object_add_int (msg, "is_combined", 1);
4459       counter_array = vat_json_object_add (msg, "data");
4460       vat_json_init_array (counter_array);
4461       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4462         {
4463           c = vam->combined_interface_counters[i][j];
4464           counter = vat_json_array_add (counter_array);
4465           vat_json_init_object (counter);
4466           vat_json_object_add_uint (counter, "packets", c.packets);
4467           vat_json_object_add_uint (counter, "bytes", c.bytes);
4468         }
4469     }
4470
4471   /* ip4 fib counters */
4472   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4473   vat_json_init_array (msg_array);
4474   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4475     {
4476       msg = vat_json_array_add (msg_array);
4477       vat_json_init_object (msg);
4478       vat_json_object_add_uint (msg, "vrf_id",
4479                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4480       counter_array = vat_json_object_add (msg, "c");
4481       vat_json_init_array (counter_array);
4482       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4483         {
4484           counter = vat_json_array_add (counter_array);
4485           vat_json_init_object (counter);
4486           c4 = &vam->ip4_fib_counters[i][j];
4487           vat_json_object_add_ip4 (counter, "address", c4->address);
4488           vat_json_object_add_uint (counter, "address_length",
4489                                     c4->address_length);
4490           vat_json_object_add_uint (counter, "packets", c4->packets);
4491           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4492         }
4493     }
4494
4495   /* ip6 fib counters */
4496   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4497   vat_json_init_array (msg_array);
4498   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4499     {
4500       msg = vat_json_array_add (msg_array);
4501       vat_json_init_object (msg);
4502       vat_json_object_add_uint (msg, "vrf_id",
4503                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4504       counter_array = vat_json_object_add (msg, "c");
4505       vat_json_init_array (counter_array);
4506       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4507         {
4508           counter = vat_json_array_add (counter_array);
4509           vat_json_init_object (counter);
4510           c6 = &vam->ip6_fib_counters[i][j];
4511           vat_json_object_add_ip6 (counter, "address", c6->address);
4512           vat_json_object_add_uint (counter, "address_length",
4513                                     c6->address_length);
4514           vat_json_object_add_uint (counter, "packets", c6->packets);
4515           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4516         }
4517     }
4518
4519   /* ip4 nbr counters */
4520   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4521   vat_json_init_array (msg_array);
4522   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4523     {
4524       msg = vat_json_array_add (msg_array);
4525       vat_json_init_object (msg);
4526       vat_json_object_add_uint (msg, "sw_if_index", i);
4527       counter_array = vat_json_object_add (msg, "c");
4528       vat_json_init_array (counter_array);
4529       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4530         {
4531           counter = vat_json_array_add (counter_array);
4532           vat_json_init_object (counter);
4533           n4 = &vam->ip4_nbr_counters[i][j];
4534           vat_json_object_add_ip4 (counter, "address", n4->address);
4535           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4536           vat_json_object_add_uint (counter, "packets", n4->packets);
4537           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4538         }
4539     }
4540
4541   /* ip6 nbr counters */
4542   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4543   vat_json_init_array (msg_array);
4544   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4545     {
4546       msg = vat_json_array_add (msg_array);
4547       vat_json_init_object (msg);
4548       vat_json_object_add_uint (msg, "sw_if_index", i);
4549       counter_array = vat_json_object_add (msg, "c");
4550       vat_json_init_array (counter_array);
4551       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4552         {
4553           counter = vat_json_array_add (counter_array);
4554           vat_json_init_object (counter);
4555           n6 = &vam->ip6_nbr_counters[i][j];
4556           vat_json_object_add_ip6 (counter, "address", n6->address);
4557           vat_json_object_add_uint (counter, "packets", n6->packets);
4558           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4559         }
4560     }
4561
4562   vat_json_print (vam->ofp, &node);
4563   vat_json_free (&node);
4564
4565   return 0;
4566 }
4567
4568 int
4569 exec (vat_main_t * vam)
4570 {
4571   api_main_t *am = &api_main;
4572   vl_api_cli_request_t *mp;
4573   f64 timeout;
4574   void *oldheap;
4575   u8 *cmd = 0;
4576   unformat_input_t *i = vam->input;
4577
4578   if (vec_len (i->buffer) == 0)
4579     return -1;
4580
4581   if (vam->exec_mode == 0 && unformat (i, "mode"))
4582     {
4583       vam->exec_mode = 1;
4584       return 0;
4585     }
4586   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4587     {
4588       vam->exec_mode = 0;
4589       return 0;
4590     }
4591
4592
4593   M (CLI_REQUEST, cli_request);
4594
4595   /*
4596    * Copy cmd into shared memory.
4597    * In order for the CLI command to work, it
4598    * must be a vector ending in \n, not a C-string ending
4599    * in \n\0.
4600    */
4601   pthread_mutex_lock (&am->vlib_rp->mutex);
4602   oldheap = svm_push_data_heap (am->vlib_rp);
4603
4604   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4605   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4606
4607   svm_pop_heap (oldheap);
4608   pthread_mutex_unlock (&am->vlib_rp->mutex);
4609
4610   mp->cmd_in_shmem = (u64) cmd;
4611   S;
4612   timeout = vat_time_now (vam) + 10.0;
4613
4614   while (vat_time_now (vam) < timeout)
4615     {
4616       if (vam->result_ready == 1)
4617         {
4618           u8 *free_me;
4619           if (vam->shmem_result != NULL)
4620             print (vam->ofp, "%s", vam->shmem_result);
4621           pthread_mutex_lock (&am->vlib_rp->mutex);
4622           oldheap = svm_push_data_heap (am->vlib_rp);
4623
4624           free_me = (u8 *) vam->shmem_result;
4625           vec_free (free_me);
4626
4627           svm_pop_heap (oldheap);
4628           pthread_mutex_unlock (&am->vlib_rp->mutex);
4629           return 0;
4630         }
4631     }
4632   return -99;
4633 }
4634
4635 /*
4636  * Future replacement of exec() that passes CLI buffers directly in
4637  * the API messages instead of an additional shared memory area.
4638  */
4639 static int
4640 exec_inband (vat_main_t * vam)
4641 {
4642   vl_api_cli_inband_t *mp;
4643   f64 timeout;
4644   unformat_input_t *i = vam->input;
4645
4646   if (vec_len (i->buffer) == 0)
4647     return -1;
4648
4649   if (vam->exec_mode == 0 && unformat (i, "mode"))
4650     {
4651       vam->exec_mode = 1;
4652       return 0;
4653     }
4654   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4655     {
4656       vam->exec_mode = 0;
4657       return 0;
4658     }
4659
4660   /*
4661    * In order for the CLI command to work, it
4662    * must be a vector ending in \n, not a C-string ending
4663    * in \n\0.
4664    */
4665   u32 len = vec_len (vam->input->buffer);
4666   M2 (CLI_INBAND, cli_inband, len);
4667   clib_memcpy (mp->cmd, vam->input->buffer, len);
4668   mp->length = htonl (len);
4669
4670   S;
4671   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4672 }
4673
4674 static int
4675 api_create_loopback (vat_main_t * vam)
4676 {
4677   unformat_input_t *i = vam->input;
4678   vl_api_create_loopback_t *mp;
4679   f64 timeout;
4680   u8 mac_address[6];
4681   u8 mac_set = 0;
4682
4683   memset (mac_address, 0, sizeof (mac_address));
4684
4685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4686     {
4687       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4688         mac_set = 1;
4689       else
4690         break;
4691     }
4692
4693   /* Construct the API message */
4694   M (CREATE_LOOPBACK, create_loopback);
4695   if (mac_set)
4696     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4697
4698   S;
4699   W;
4700 }
4701
4702 static int
4703 api_delete_loopback (vat_main_t * vam)
4704 {
4705   unformat_input_t *i = vam->input;
4706   vl_api_delete_loopback_t *mp;
4707   f64 timeout;
4708   u32 sw_if_index = ~0;
4709
4710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4711     {
4712       if (unformat (i, "sw_if_index %d", &sw_if_index))
4713         ;
4714       else
4715         break;
4716     }
4717
4718   if (sw_if_index == ~0)
4719     {
4720       errmsg ("missing sw_if_index");
4721       return -99;
4722     }
4723
4724   /* Construct the API message */
4725   M (DELETE_LOOPBACK, delete_loopback);
4726   mp->sw_if_index = ntohl (sw_if_index);
4727
4728   S;
4729   W;
4730 }
4731
4732 static int
4733 api_want_stats (vat_main_t * vam)
4734 {
4735   unformat_input_t *i = vam->input;
4736   vl_api_want_stats_t *mp;
4737   f64 timeout;
4738   int enable = -1;
4739
4740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4741     {
4742       if (unformat (i, "enable"))
4743         enable = 1;
4744       else if (unformat (i, "disable"))
4745         enable = 0;
4746       else
4747         break;
4748     }
4749
4750   if (enable == -1)
4751     {
4752       errmsg ("missing enable|disable");
4753       return -99;
4754     }
4755
4756   M (WANT_STATS, want_stats);
4757   mp->enable_disable = enable;
4758
4759   S;
4760   W;
4761 }
4762
4763 static int
4764 api_want_interface_events (vat_main_t * vam)
4765 {
4766   unformat_input_t *i = vam->input;
4767   vl_api_want_interface_events_t *mp;
4768   f64 timeout;
4769   int enable = -1;
4770
4771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4772     {
4773       if (unformat (i, "enable"))
4774         enable = 1;
4775       else if (unformat (i, "disable"))
4776         enable = 0;
4777       else
4778         break;
4779     }
4780
4781   if (enable == -1)
4782     {
4783       errmsg ("missing enable|disable");
4784       return -99;
4785     }
4786
4787   M (WANT_INTERFACE_EVENTS, want_interface_events);
4788   mp->enable_disable = enable;
4789
4790   vam->interface_event_display = enable;
4791
4792   S;
4793   W;
4794 }
4795
4796
4797 /* Note: non-static, called once to set up the initial intfc table */
4798 int
4799 api_sw_interface_dump (vat_main_t * vam)
4800 {
4801   vl_api_sw_interface_dump_t *mp;
4802   f64 timeout;
4803   hash_pair_t *p;
4804   name_sort_t *nses = 0, *ns;
4805   sw_interface_subif_t *sub = NULL;
4806
4807   /* Toss the old name table */
4808   /* *INDENT-OFF* */
4809   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4810   ({
4811     vec_add2 (nses, ns, 1);
4812     ns->name = (u8 *)(p->key);
4813     ns->value = (u32) p->value[0];
4814   }));
4815   /* *INDENT-ON* */
4816
4817   hash_free (vam->sw_if_index_by_interface_name);
4818
4819   vec_foreach (ns, nses) vec_free (ns->name);
4820
4821   vec_free (nses);
4822
4823   vec_foreach (sub, vam->sw_if_subif_table)
4824   {
4825     vec_free (sub->interface_name);
4826   }
4827   vec_free (vam->sw_if_subif_table);
4828
4829   /* recreate the interface name hash table */
4830   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4831
4832   /* Get list of ethernets */
4833   M (SW_INTERFACE_DUMP, sw_interface_dump);
4834   mp->name_filter_valid = 1;
4835   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4836   S;
4837
4838   /* and local / loopback interfaces */
4839   M (SW_INTERFACE_DUMP, sw_interface_dump);
4840   mp->name_filter_valid = 1;
4841   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4842   S;
4843
4844   /* and packet-generator interfaces */
4845   M (SW_INTERFACE_DUMP, sw_interface_dump);
4846   mp->name_filter_valid = 1;
4847   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4848   S;
4849
4850   /* and vxlan-gpe tunnel interfaces */
4851   M (SW_INTERFACE_DUMP, sw_interface_dump);
4852   mp->name_filter_valid = 1;
4853   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4854            sizeof (mp->name_filter) - 1);
4855   S;
4856
4857   /* and vxlan tunnel interfaces */
4858   M (SW_INTERFACE_DUMP, sw_interface_dump);
4859   mp->name_filter_valid = 1;
4860   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4861   S;
4862
4863   /* and host (af_packet) interfaces */
4864   M (SW_INTERFACE_DUMP, sw_interface_dump);
4865   mp->name_filter_valid = 1;
4866   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4867   S;
4868
4869   /* and l2tpv3 tunnel interfaces */
4870   M (SW_INTERFACE_DUMP, sw_interface_dump);
4871   mp->name_filter_valid = 1;
4872   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4873            sizeof (mp->name_filter) - 1);
4874   S;
4875
4876   /* and GRE tunnel interfaces */
4877   M (SW_INTERFACE_DUMP, sw_interface_dump);
4878   mp->name_filter_valid = 1;
4879   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4880   S;
4881
4882   /* and LISP-GPE interfaces */
4883   M (SW_INTERFACE_DUMP, sw_interface_dump);
4884   mp->name_filter_valid = 1;
4885   strncpy ((char *) mp->name_filter, "lisp_gpe",
4886            sizeof (mp->name_filter) - 1);
4887   S;
4888
4889   /* and IPSEC tunnel interfaces */
4890   M (SW_INTERFACE_DUMP, sw_interface_dump);
4891   mp->name_filter_valid = 1;
4892   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4893   S;
4894
4895   /* Use a control ping for synchronization */
4896   {
4897     vl_api_control_ping_t *mp;
4898     M (CONTROL_PING, control_ping);
4899     S;
4900   }
4901   W;
4902 }
4903
4904 static int
4905 api_sw_interface_set_flags (vat_main_t * vam)
4906 {
4907   unformat_input_t *i = vam->input;
4908   vl_api_sw_interface_set_flags_t *mp;
4909   f64 timeout;
4910   u32 sw_if_index;
4911   u8 sw_if_index_set = 0;
4912   u8 admin_up = 0, link_up = 0;
4913
4914   /* Parse args required to build the message */
4915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4916     {
4917       if (unformat (i, "admin-up"))
4918         admin_up = 1;
4919       else if (unformat (i, "admin-down"))
4920         admin_up = 0;
4921       else if (unformat (i, "link-up"))
4922         link_up = 1;
4923       else if (unformat (i, "link-down"))
4924         link_up = 0;
4925       else
4926         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4927         sw_if_index_set = 1;
4928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4929         sw_if_index_set = 1;
4930       else
4931         break;
4932     }
4933
4934   if (sw_if_index_set == 0)
4935     {
4936       errmsg ("missing interface name or sw_if_index");
4937       return -99;
4938     }
4939
4940   /* Construct the API message */
4941   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4942   mp->sw_if_index = ntohl (sw_if_index);
4943   mp->admin_up_down = admin_up;
4944   mp->link_up_down = link_up;
4945
4946   /* send it... */
4947   S;
4948
4949   /* Wait for a reply, return the good/bad news... */
4950   W;
4951 }
4952
4953 static int
4954 api_sw_interface_clear_stats (vat_main_t * vam)
4955 {
4956   unformat_input_t *i = vam->input;
4957   vl_api_sw_interface_clear_stats_t *mp;
4958   f64 timeout;
4959   u32 sw_if_index;
4960   u8 sw_if_index_set = 0;
4961
4962   /* Parse args required to build the message */
4963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4964     {
4965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4966         sw_if_index_set = 1;
4967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4968         sw_if_index_set = 1;
4969       else
4970         break;
4971     }
4972
4973   /* Construct the API message */
4974   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4975
4976   if (sw_if_index_set == 1)
4977     mp->sw_if_index = ntohl (sw_if_index);
4978   else
4979     mp->sw_if_index = ~0;
4980
4981   /* send it... */
4982   S;
4983
4984   /* Wait for a reply, return the good/bad news... */
4985   W;
4986 }
4987
4988 #if DPDK >0
4989 static int
4990 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4991 {
4992   unformat_input_t *i = vam->input;
4993   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4994   f64 timeout;
4995   u32 sw_if_index;
4996   u8 sw_if_index_set = 0;
4997   u32 subport;
4998   u8 subport_set = 0;
4999   u32 pipe;
5000   u8 pipe_set = 0;
5001   u32 profile;
5002   u8 profile_set = 0;
5003
5004   /* Parse args required to build the message */
5005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5006     {
5007       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5008         sw_if_index_set = 1;
5009       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5010         sw_if_index_set = 1;
5011       else if (unformat (i, "subport %u", &subport))
5012         subport_set = 1;
5013       else
5014         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5015         sw_if_index_set = 1;
5016       else if (unformat (i, "pipe %u", &pipe))
5017         pipe_set = 1;
5018       else if (unformat (i, "profile %u", &profile))
5019         profile_set = 1;
5020       else
5021         break;
5022     }
5023
5024   if (sw_if_index_set == 0)
5025     {
5026       errmsg ("missing interface name or sw_if_index");
5027       return -99;
5028     }
5029
5030   if (subport_set == 0)
5031     {
5032       errmsg ("missing subport ");
5033       return -99;
5034     }
5035
5036   if (pipe_set == 0)
5037     {
5038       errmsg ("missing pipe");
5039       return -99;
5040     }
5041
5042   if (profile_set == 0)
5043     {
5044       errmsg ("missing profile");
5045       return -99;
5046     }
5047
5048   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
5049
5050   mp->sw_if_index = ntohl (sw_if_index);
5051   mp->subport = ntohl (subport);
5052   mp->pipe = ntohl (pipe);
5053   mp->profile = ntohl (profile);
5054
5055
5056   S;
5057   W;
5058   /* NOTREACHED */
5059   return 0;
5060 }
5061
5062 static int
5063 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
5064 {
5065   unformat_input_t *i = vam->input;
5066   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
5067   f64 timeout;
5068   u32 sw_if_index;
5069   u8 sw_if_index_set = 0;
5070   u32 subport;
5071   u8 subport_set = 0;
5072   u32 tb_rate = 1250000000;     /* 10GbE */
5073   u32 tb_size = 1000000;
5074   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
5075   u32 tc_period = 10;
5076
5077   /* Parse args required to build the message */
5078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5079     {
5080       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5081         sw_if_index_set = 1;
5082       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5083         sw_if_index_set = 1;
5084       else if (unformat (i, "subport %u", &subport))
5085         subport_set = 1;
5086       else
5087         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5088         sw_if_index_set = 1;
5089       else if (unformat (i, "rate %u", &tb_rate))
5090         {
5091           u32 tc_id;
5092
5093           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
5094                tc_id++)
5095             tc_rate[tc_id] = tb_rate;
5096         }
5097       else if (unformat (i, "bktsize %u", &tb_size))
5098         ;
5099       else if (unformat (i, "tc0 %u", &tc_rate[0]))
5100         ;
5101       else if (unformat (i, "tc1 %u", &tc_rate[1]))
5102         ;
5103       else if (unformat (i, "tc2 %u", &tc_rate[2]))
5104         ;
5105       else if (unformat (i, "tc3 %u", &tc_rate[3]))
5106         ;
5107       else if (unformat (i, "period %u", &tc_period))
5108         ;
5109       else
5110         break;
5111     }
5112
5113   if (sw_if_index_set == 0)
5114     {
5115       errmsg ("missing interface name or sw_if_index");
5116       return -99;
5117     }
5118
5119   if (subport_set == 0)
5120     {
5121       errmsg ("missing subport ");
5122       return -99;
5123     }
5124
5125   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
5126
5127   mp->sw_if_index = ntohl (sw_if_index);
5128   mp->subport = ntohl (subport);
5129   mp->tb_rate = ntohl (tb_rate);
5130   mp->tb_size = ntohl (tb_size);
5131   mp->tc_rate[0] = ntohl (tc_rate[0]);
5132   mp->tc_rate[1] = ntohl (tc_rate[1]);
5133   mp->tc_rate[2] = ntohl (tc_rate[2]);
5134   mp->tc_rate[3] = ntohl (tc_rate[3]);
5135   mp->tc_period = ntohl (tc_period);
5136
5137   S;
5138   W;
5139   /* NOTREACHED */
5140   return 0;
5141 }
5142
5143 static int
5144 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
5145 {
5146   unformat_input_t *i = vam->input;
5147   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
5148   f64 timeout;
5149   u32 sw_if_index;
5150   u8 sw_if_index_set = 0;
5151   u8 entry_set = 0;
5152   u8 tc_set = 0;
5153   u8 queue_set = 0;
5154   u32 entry, tc, queue;
5155
5156   /* Parse args required to build the message */
5157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5158     {
5159       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5160         sw_if_index_set = 1;
5161       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5162         sw_if_index_set = 1;
5163       else if (unformat (i, "entry %d", &entry))
5164         entry_set = 1;
5165       else if (unformat (i, "tc %d", &tc))
5166         tc_set = 1;
5167       else if (unformat (i, "queue %d", &queue))
5168         queue_set = 1;
5169       else
5170         break;
5171     }
5172
5173   if (sw_if_index_set == 0)
5174     {
5175       errmsg ("missing interface name or sw_if_index");
5176       return -99;
5177     }
5178
5179   if (entry_set == 0)
5180     {
5181       errmsg ("missing entry ");
5182       return -99;
5183     }
5184
5185   if (tc_set == 0)
5186     {
5187       errmsg ("missing traffic class ");
5188       return -99;
5189     }
5190
5191   if (queue_set == 0)
5192     {
5193       errmsg ("missing queue ");
5194       return -99;
5195     }
5196
5197   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
5198
5199   mp->sw_if_index = ntohl (sw_if_index);
5200   mp->entry = ntohl (entry);
5201   mp->tc = ntohl (tc);
5202   mp->queue = ntohl (queue);
5203
5204   S;
5205   W;
5206   /* NOTREACHED */
5207   return 0;
5208 }
5209 #endif
5210
5211 static int
5212 api_sw_interface_add_del_address (vat_main_t * vam)
5213 {
5214   unformat_input_t *i = vam->input;
5215   vl_api_sw_interface_add_del_address_t *mp;
5216   f64 timeout;
5217   u32 sw_if_index;
5218   u8 sw_if_index_set = 0;
5219   u8 is_add = 1, del_all = 0;
5220   u32 address_length = 0;
5221   u8 v4_address_set = 0;
5222   u8 v6_address_set = 0;
5223   ip4_address_t v4address;
5224   ip6_address_t v6address;
5225
5226   /* Parse args required to build the message */
5227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5228     {
5229       if (unformat (i, "del-all"))
5230         del_all = 1;
5231       else if (unformat (i, "del"))
5232         is_add = 0;
5233       else
5234         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5235         sw_if_index_set = 1;
5236       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5237         sw_if_index_set = 1;
5238       else if (unformat (i, "%U/%d",
5239                          unformat_ip4_address, &v4address, &address_length))
5240         v4_address_set = 1;
5241       else if (unformat (i, "%U/%d",
5242                          unformat_ip6_address, &v6address, &address_length))
5243         v6_address_set = 1;
5244       else
5245         break;
5246     }
5247
5248   if (sw_if_index_set == 0)
5249     {
5250       errmsg ("missing interface name or sw_if_index");
5251       return -99;
5252     }
5253   if (v4_address_set && v6_address_set)
5254     {
5255       errmsg ("both v4 and v6 addresses set");
5256       return -99;
5257     }
5258   if (!v4_address_set && !v6_address_set && !del_all)
5259     {
5260       errmsg ("no addresses set");
5261       return -99;
5262     }
5263
5264   /* Construct the API message */
5265   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
5266
5267   mp->sw_if_index = ntohl (sw_if_index);
5268   mp->is_add = is_add;
5269   mp->del_all = del_all;
5270   if (v6_address_set)
5271     {
5272       mp->is_ipv6 = 1;
5273       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5274     }
5275   else
5276     {
5277       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5278     }
5279   mp->address_length = address_length;
5280
5281   /* send it... */
5282   S;
5283
5284   /* Wait for a reply, return good/bad news  */
5285   W;
5286 }
5287
5288 static int
5289 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5290 {
5291   unformat_input_t *i = vam->input;
5292   vl_api_sw_interface_set_mpls_enable_t *mp;
5293   f64 timeout;
5294   u32 sw_if_index;
5295   u8 sw_if_index_set = 0;
5296   u8 enable = 1;
5297
5298   /* Parse args required to build the message */
5299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5300     {
5301       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5302         sw_if_index_set = 1;
5303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5304         sw_if_index_set = 1;
5305       else if (unformat (i, "disable"))
5306         enable = 0;
5307       else if (unformat (i, "dis"))
5308         enable = 0;
5309       else
5310         break;
5311     }
5312
5313   if (sw_if_index_set == 0)
5314     {
5315       errmsg ("missing interface name or sw_if_index");
5316       return -99;
5317     }
5318
5319   /* Construct the API message */
5320   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5321
5322   mp->sw_if_index = ntohl (sw_if_index);
5323   mp->enable = enable;
5324
5325   /* send it... */
5326   S;
5327
5328   /* Wait for a reply... */
5329   W;
5330 }
5331
5332 static int
5333 api_sw_interface_set_table (vat_main_t * vam)
5334 {
5335   unformat_input_t *i = vam->input;
5336   vl_api_sw_interface_set_table_t *mp;
5337   f64 timeout;
5338   u32 sw_if_index, vrf_id = 0;
5339   u8 sw_if_index_set = 0;
5340   u8 is_ipv6 = 0;
5341
5342   /* Parse args required to build the message */
5343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5344     {
5345       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5346         sw_if_index_set = 1;
5347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5348         sw_if_index_set = 1;
5349       else if (unformat (i, "vrf %d", &vrf_id))
5350         ;
5351       else if (unformat (i, "ipv6"))
5352         is_ipv6 = 1;
5353       else
5354         break;
5355     }
5356
5357   if (sw_if_index_set == 0)
5358     {
5359       errmsg ("missing interface name or sw_if_index");
5360       return -99;
5361     }
5362
5363   /* Construct the API message */
5364   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5365
5366   mp->sw_if_index = ntohl (sw_if_index);
5367   mp->is_ipv6 = is_ipv6;
5368   mp->vrf_id = ntohl (vrf_id);
5369
5370   /* send it... */
5371   S;
5372
5373   /* Wait for a reply... */
5374   W;
5375 }
5376
5377 static void vl_api_sw_interface_get_table_reply_t_handler
5378   (vl_api_sw_interface_get_table_reply_t * mp)
5379 {
5380   vat_main_t *vam = &vat_main;
5381
5382   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5383
5384   vam->retval = ntohl (mp->retval);
5385   vam->result_ready = 1;
5386
5387 }
5388
5389 static void vl_api_sw_interface_get_table_reply_t_handler_json
5390   (vl_api_sw_interface_get_table_reply_t * mp)
5391 {
5392   vat_main_t *vam = &vat_main;
5393   vat_json_node_t node;
5394
5395   vat_json_init_object (&node);
5396   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5397   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5398
5399   vat_json_print (vam->ofp, &node);
5400   vat_json_free (&node);
5401
5402   vam->retval = ntohl (mp->retval);
5403   vam->result_ready = 1;
5404 }
5405
5406 static int
5407 api_sw_interface_get_table (vat_main_t * vam)
5408 {
5409   unformat_input_t *i = vam->input;
5410   vl_api_sw_interface_get_table_t *mp;
5411   u32 sw_if_index;
5412   u8 sw_if_index_set = 0;
5413   u8 is_ipv6 = 0;
5414   f64 timeout;
5415
5416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5417     {
5418       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5419         sw_if_index_set = 1;
5420       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5421         sw_if_index_set = 1;
5422       else if (unformat (i, "ipv6"))
5423         is_ipv6 = 1;
5424       else
5425         break;
5426     }
5427
5428   if (sw_if_index_set == 0)
5429     {
5430       errmsg ("missing interface name or sw_if_index");
5431       return -99;
5432     }
5433
5434   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5435   mp->sw_if_index = htonl (sw_if_index);
5436   mp->is_ipv6 = is_ipv6;
5437
5438   S;
5439   W;
5440 }
5441
5442 static int
5443 api_sw_interface_set_vpath (vat_main_t * vam)
5444 {
5445   unformat_input_t *i = vam->input;
5446   vl_api_sw_interface_set_vpath_t *mp;
5447   f64 timeout;
5448   u32 sw_if_index = 0;
5449   u8 sw_if_index_set = 0;
5450   u8 is_enable = 0;
5451
5452   /* Parse args required to build the message */
5453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5454     {
5455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5456         sw_if_index_set = 1;
5457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5458         sw_if_index_set = 1;
5459       else if (unformat (i, "enable"))
5460         is_enable = 1;
5461       else if (unformat (i, "disable"))
5462         is_enable = 0;
5463       else
5464         break;
5465     }
5466
5467   if (sw_if_index_set == 0)
5468     {
5469       errmsg ("missing interface name or sw_if_index");
5470       return -99;
5471     }
5472
5473   /* Construct the API message */
5474   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5475
5476   mp->sw_if_index = ntohl (sw_if_index);
5477   mp->enable = is_enable;
5478
5479   /* send it... */
5480   S;
5481
5482   /* Wait for a reply... */
5483   W;
5484 }
5485
5486 static int
5487 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5488 {
5489   unformat_input_t *i = vam->input;
5490   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5491   f64 timeout;
5492   u32 sw_if_index = 0;
5493   u8 sw_if_index_set = 0;
5494   u8 is_enable = 0;
5495   u8 is_ipv6 = 0;
5496
5497   /* Parse args required to build the message */
5498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5499     {
5500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5501         sw_if_index_set = 1;
5502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5503         sw_if_index_set = 1;
5504       else if (unformat (i, "enable"))
5505         is_enable = 1;
5506       else if (unformat (i, "disable"))
5507         is_enable = 0;
5508       else if (unformat (i, "ip4"))
5509         is_ipv6 = 0;
5510       else if (unformat (i, "ip6"))
5511         is_ipv6 = 1;
5512       else
5513         break;
5514     }
5515
5516   if (sw_if_index_set == 0)
5517     {
5518       errmsg ("missing interface name or sw_if_index");
5519       return -99;
5520     }
5521
5522   /* Construct the API message */
5523   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5524
5525   mp->sw_if_index = ntohl (sw_if_index);
5526   mp->enable = is_enable;
5527   mp->is_ipv6 = is_ipv6;
5528
5529   /* send it... */
5530   S;
5531
5532   /* Wait for a reply... */
5533   W;
5534 }
5535
5536 static int
5537 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5538 {
5539   unformat_input_t *i = vam->input;
5540   vl_api_sw_interface_set_l2_xconnect_t *mp;
5541   f64 timeout;
5542   u32 rx_sw_if_index;
5543   u8 rx_sw_if_index_set = 0;
5544   u32 tx_sw_if_index;
5545   u8 tx_sw_if_index_set = 0;
5546   u8 enable = 1;
5547
5548   /* Parse args required to build the message */
5549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5550     {
5551       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5552         rx_sw_if_index_set = 1;
5553       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5554         tx_sw_if_index_set = 1;
5555       else if (unformat (i, "rx"))
5556         {
5557           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5558             {
5559               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5560                             &rx_sw_if_index))
5561                 rx_sw_if_index_set = 1;
5562             }
5563           else
5564             break;
5565         }
5566       else if (unformat (i, "tx"))
5567         {
5568           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5569             {
5570               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5571                             &tx_sw_if_index))
5572                 tx_sw_if_index_set = 1;
5573             }
5574           else
5575             break;
5576         }
5577       else if (unformat (i, "enable"))
5578         enable = 1;
5579       else if (unformat (i, "disable"))
5580         enable = 0;
5581       else
5582         break;
5583     }
5584
5585   if (rx_sw_if_index_set == 0)
5586     {
5587       errmsg ("missing rx interface name or rx_sw_if_index");
5588       return -99;
5589     }
5590
5591   if (enable && (tx_sw_if_index_set == 0))
5592     {
5593       errmsg ("missing tx interface name or tx_sw_if_index");
5594       return -99;
5595     }
5596
5597   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5598
5599   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5600   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5601   mp->enable = enable;
5602
5603   S;
5604   W;
5605   /* NOTREACHED */
5606   return 0;
5607 }
5608
5609 static int
5610 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5611 {
5612   unformat_input_t *i = vam->input;
5613   vl_api_sw_interface_set_l2_bridge_t *mp;
5614   f64 timeout;
5615   u32 rx_sw_if_index;
5616   u8 rx_sw_if_index_set = 0;
5617   u32 bd_id;
5618   u8 bd_id_set = 0;
5619   u8 bvi = 0;
5620   u32 shg = 0;
5621   u8 enable = 1;
5622
5623   /* Parse args required to build the message */
5624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5625     {
5626       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5627         rx_sw_if_index_set = 1;
5628       else if (unformat (i, "bd_id %d", &bd_id))
5629         bd_id_set = 1;
5630       else
5631         if (unformat
5632             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5633         rx_sw_if_index_set = 1;
5634       else if (unformat (i, "shg %d", &shg))
5635         ;
5636       else if (unformat (i, "bvi"))
5637         bvi = 1;
5638       else if (unformat (i, "enable"))
5639         enable = 1;
5640       else if (unformat (i, "disable"))
5641         enable = 0;
5642       else
5643         break;
5644     }
5645
5646   if (rx_sw_if_index_set == 0)
5647     {
5648       errmsg ("missing rx interface name or sw_if_index");
5649       return -99;
5650     }
5651
5652   if (enable && (bd_id_set == 0))
5653     {
5654       errmsg ("missing bridge domain");
5655       return -99;
5656     }
5657
5658   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5659
5660   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5661   mp->bd_id = ntohl (bd_id);
5662   mp->shg = (u8) shg;
5663   mp->bvi = bvi;
5664   mp->enable = enable;
5665
5666   S;
5667   W;
5668   /* NOTREACHED */
5669   return 0;
5670 }
5671
5672 static int
5673 api_bridge_domain_dump (vat_main_t * vam)
5674 {
5675   unformat_input_t *i = vam->input;
5676   vl_api_bridge_domain_dump_t *mp;
5677   f64 timeout;
5678   u32 bd_id = ~0;
5679
5680   /* Parse args required to build the message */
5681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5682     {
5683       if (unformat (i, "bd_id %d", &bd_id))
5684         ;
5685       else
5686         break;
5687     }
5688
5689   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5690   mp->bd_id = ntohl (bd_id);
5691   S;
5692
5693   /* Use a control ping for synchronization */
5694   {
5695     vl_api_control_ping_t *mp;
5696     M (CONTROL_PING, control_ping);
5697     S;
5698   }
5699
5700   W;
5701   /* NOTREACHED */
5702   return 0;
5703 }
5704
5705 static int
5706 api_bridge_domain_add_del (vat_main_t * vam)
5707 {
5708   unformat_input_t *i = vam->input;
5709   vl_api_bridge_domain_add_del_t *mp;
5710   f64 timeout;
5711   u32 bd_id = ~0;
5712   u8 is_add = 1;
5713   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5714   u32 mac_age = 0;
5715
5716   /* Parse args required to build the message */
5717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5718     {
5719       if (unformat (i, "bd_id %d", &bd_id))
5720         ;
5721       else if (unformat (i, "flood %d", &flood))
5722         ;
5723       else if (unformat (i, "uu-flood %d", &uu_flood))
5724         ;
5725       else if (unformat (i, "forward %d", &forward))
5726         ;
5727       else if (unformat (i, "learn %d", &learn))
5728         ;
5729       else if (unformat (i, "arp-term %d", &arp_term))
5730         ;
5731       else if (unformat (i, "mac-age %d", &mac_age))
5732         ;
5733       else if (unformat (i, "del"))
5734         {
5735           is_add = 0;
5736           flood = uu_flood = forward = learn = 0;
5737         }
5738       else
5739         break;
5740     }
5741
5742   if (bd_id == ~0)
5743     {
5744       errmsg ("missing bridge domain");
5745       return -99;
5746     }
5747
5748   if (mac_age > 255)
5749     {
5750       errmsg ("mac age must be less than 256 ");
5751       return -99;
5752     }
5753
5754   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5755
5756   mp->bd_id = ntohl (bd_id);
5757   mp->flood = flood;
5758   mp->uu_flood = uu_flood;
5759   mp->forward = forward;
5760   mp->learn = learn;
5761   mp->arp_term = arp_term;
5762   mp->is_add = is_add;
5763   mp->mac_age = (u8) mac_age;
5764
5765   S;
5766   W;
5767   /* NOTREACHED */
5768   return 0;
5769 }
5770
5771 static int
5772 api_l2fib_add_del (vat_main_t * vam)
5773 {
5774   unformat_input_t *i = vam->input;
5775   vl_api_l2fib_add_del_t *mp;
5776   f64 timeout;
5777   u64 mac = 0;
5778   u8 mac_set = 0;
5779   u32 bd_id;
5780   u8 bd_id_set = 0;
5781   u32 sw_if_index = ~0;
5782   u8 sw_if_index_set = 0;
5783   u8 is_add = 1;
5784   u8 static_mac = 0;
5785   u8 filter_mac = 0;
5786   u8 bvi_mac = 0;
5787   int count = 1;
5788   f64 before = 0;
5789   int j;
5790
5791   /* Parse args required to build the message */
5792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5793     {
5794       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5795         mac_set = 1;
5796       else if (unformat (i, "bd_id %d", &bd_id))
5797         bd_id_set = 1;
5798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5799         sw_if_index_set = 1;
5800       else if (unformat (i, "sw_if"))
5801         {
5802           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5803             {
5804               if (unformat
5805                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5806                 sw_if_index_set = 1;
5807             }
5808           else
5809             break;
5810         }
5811       else if (unformat (i, "static"))
5812         static_mac = 1;
5813       else if (unformat (i, "filter"))
5814         {
5815           filter_mac = 1;
5816           static_mac = 1;
5817         }
5818       else if (unformat (i, "bvi"))
5819         {
5820           bvi_mac = 1;
5821           static_mac = 1;
5822         }
5823       else if (unformat (i, "del"))
5824         is_add = 0;
5825       else if (unformat (i, "count %d", &count))
5826         ;
5827       else
5828         break;
5829     }
5830
5831   if (mac_set == 0)
5832     {
5833       errmsg ("missing mac address");
5834       return -99;
5835     }
5836
5837   if (bd_id_set == 0)
5838     {
5839       errmsg ("missing bridge domain");
5840       return -99;
5841     }
5842
5843   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5844     {
5845       errmsg ("missing interface name or sw_if_index");
5846       return -99;
5847     }
5848
5849   if (count > 1)
5850     {
5851       /* Turn on async mode */
5852       vam->async_mode = 1;
5853       vam->async_errors = 0;
5854       before = vat_time_now (vam);
5855     }
5856
5857   for (j = 0; j < count; j++)
5858     {
5859       M (L2FIB_ADD_DEL, l2fib_add_del);
5860
5861       mp->mac = mac;
5862       mp->bd_id = ntohl (bd_id);
5863       mp->is_add = is_add;
5864
5865       if (is_add)
5866         {
5867           mp->sw_if_index = ntohl (sw_if_index);
5868           mp->static_mac = static_mac;
5869           mp->filter_mac = filter_mac;
5870           mp->bvi_mac = bvi_mac;
5871         }
5872       increment_mac_address (&mac);
5873       /* send it... */
5874       S;
5875     }
5876
5877   if (count > 1)
5878     {
5879       vl_api_control_ping_t *mp;
5880       f64 after;
5881
5882       /* Shut off async mode */
5883       vam->async_mode = 0;
5884
5885       M (CONTROL_PING, control_ping);
5886       S;
5887
5888       timeout = vat_time_now (vam) + 1.0;
5889       while (vat_time_now (vam) < timeout)
5890         if (vam->result_ready == 1)
5891           goto out;
5892       vam->retval = -99;
5893
5894     out:
5895       if (vam->retval == -99)
5896         errmsg ("timeout");
5897
5898       if (vam->async_errors > 0)
5899         {
5900           errmsg ("%d asynchronous errors", vam->async_errors);
5901           vam->retval = -98;
5902         }
5903       vam->async_errors = 0;
5904       after = vat_time_now (vam);
5905
5906       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5907              count, after - before, count / (after - before));
5908     }
5909   else
5910     {
5911       /* Wait for a reply... */
5912       W;
5913     }
5914   /* Return the good/bad news */
5915   return (vam->retval);
5916 }
5917
5918 static int
5919 api_l2_flags (vat_main_t * vam)
5920 {
5921   unformat_input_t *i = vam->input;
5922   vl_api_l2_flags_t *mp;
5923   f64 timeout;
5924   u32 sw_if_index;
5925   u32 feature_bitmap = 0;
5926   u8 sw_if_index_set = 0;
5927
5928   /* Parse args required to build the message */
5929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5930     {
5931       if (unformat (i, "sw_if_index %d", &sw_if_index))
5932         sw_if_index_set = 1;
5933       else if (unformat (i, "sw_if"))
5934         {
5935           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5936             {
5937               if (unformat
5938                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5939                 sw_if_index_set = 1;
5940             }
5941           else
5942             break;
5943         }
5944       else if (unformat (i, "learn"))
5945         feature_bitmap |= L2INPUT_FEAT_LEARN;
5946       else if (unformat (i, "forward"))
5947         feature_bitmap |= L2INPUT_FEAT_FWD;
5948       else if (unformat (i, "flood"))
5949         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5950       else if (unformat (i, "uu-flood"))
5951         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5952       else
5953         break;
5954     }
5955
5956   if (sw_if_index_set == 0)
5957     {
5958       errmsg ("missing interface name or sw_if_index");
5959       return -99;
5960     }
5961
5962   M (L2_FLAGS, l2_flags);
5963
5964   mp->sw_if_index = ntohl (sw_if_index);
5965   mp->feature_bitmap = ntohl (feature_bitmap);
5966
5967   S;
5968   W;
5969   /* NOTREACHED */
5970   return 0;
5971 }
5972
5973 static int
5974 api_bridge_flags (vat_main_t * vam)
5975 {
5976   unformat_input_t *i = vam->input;
5977   vl_api_bridge_flags_t *mp;
5978   f64 timeout;
5979   u32 bd_id;
5980   u8 bd_id_set = 0;
5981   u8 is_set = 1;
5982   u32 flags = 0;
5983
5984   /* Parse args required to build the message */
5985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5986     {
5987       if (unformat (i, "bd_id %d", &bd_id))
5988         bd_id_set = 1;
5989       else if (unformat (i, "learn"))
5990         flags |= L2_LEARN;
5991       else if (unformat (i, "forward"))
5992         flags |= L2_FWD;
5993       else if (unformat (i, "flood"))
5994         flags |= L2_FLOOD;
5995       else if (unformat (i, "uu-flood"))
5996         flags |= L2_UU_FLOOD;
5997       else if (unformat (i, "arp-term"))
5998         flags |= L2_ARP_TERM;
5999       else if (unformat (i, "off"))
6000         is_set = 0;
6001       else if (unformat (i, "disable"))
6002         is_set = 0;
6003       else
6004         break;
6005     }
6006
6007   if (bd_id_set == 0)
6008     {
6009       errmsg ("missing bridge domain");
6010       return -99;
6011     }
6012
6013   M (BRIDGE_FLAGS, bridge_flags);
6014
6015   mp->bd_id = ntohl (bd_id);
6016   mp->feature_bitmap = ntohl (flags);
6017   mp->is_set = is_set;
6018
6019   S;
6020   W;
6021   /* NOTREACHED */
6022   return 0;
6023 }
6024
6025 static int
6026 api_bd_ip_mac_add_del (vat_main_t * vam)
6027 {
6028   unformat_input_t *i = vam->input;
6029   vl_api_bd_ip_mac_add_del_t *mp;
6030   f64 timeout;
6031   u32 bd_id;
6032   u8 is_ipv6 = 0;
6033   u8 is_add = 1;
6034   u8 bd_id_set = 0;
6035   u8 ip_set = 0;
6036   u8 mac_set = 0;
6037   ip4_address_t v4addr;
6038   ip6_address_t v6addr;
6039   u8 macaddr[6];
6040
6041
6042   /* Parse args required to build the message */
6043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6044     {
6045       if (unformat (i, "bd_id %d", &bd_id))
6046         {
6047           bd_id_set++;
6048         }
6049       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6050         {
6051           ip_set++;
6052         }
6053       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6054         {
6055           ip_set++;
6056           is_ipv6++;
6057         }
6058       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6059         {
6060           mac_set++;
6061         }
6062       else if (unformat (i, "del"))
6063         is_add = 0;
6064       else
6065         break;
6066     }
6067
6068   if (bd_id_set == 0)
6069     {
6070       errmsg ("missing bridge domain");
6071       return -99;
6072     }
6073   else if (ip_set == 0)
6074     {
6075       errmsg ("missing IP address");
6076       return -99;
6077     }
6078   else if (mac_set == 0)
6079     {
6080       errmsg ("missing MAC address");
6081       return -99;
6082     }
6083
6084   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
6085
6086   mp->bd_id = ntohl (bd_id);
6087   mp->is_ipv6 = is_ipv6;
6088   mp->is_add = is_add;
6089   if (is_ipv6)
6090     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6091   else
6092     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6093   clib_memcpy (mp->mac_address, macaddr, 6);
6094   S;
6095   W;
6096   /* NOTREACHED */
6097   return 0;
6098 }
6099
6100 static int
6101 api_tap_connect (vat_main_t * vam)
6102 {
6103   unformat_input_t *i = vam->input;
6104   vl_api_tap_connect_t *mp;
6105   f64 timeout;
6106   u8 mac_address[6];
6107   u8 random_mac = 1;
6108   u8 name_set = 0;
6109   u8 *tap_name;
6110   u8 *tag = 0;
6111   ip4_address_t ip4_address;
6112   u32 ip4_mask_width;
6113   int ip4_address_set = 0;
6114   ip6_address_t ip6_address;
6115   u32 ip6_mask_width;
6116   int ip6_address_set = 0;
6117
6118   memset (mac_address, 0, sizeof (mac_address));
6119
6120   /* Parse args required to build the message */
6121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6122     {
6123       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6124         {
6125           random_mac = 0;
6126         }
6127       else if (unformat (i, "random-mac"))
6128         random_mac = 1;
6129       else if (unformat (i, "tapname %s", &tap_name))
6130         name_set = 1;
6131       else if (unformat (i, "tag %s", &tag))
6132         ;
6133       else if (unformat (i, "address %U/%d",
6134                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6135         ip4_address_set = 1;
6136       else if (unformat (i, "address %U/%d",
6137                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6138         ip6_address_set = 1;
6139       else
6140         break;
6141     }
6142
6143   if (name_set == 0)
6144     {
6145       errmsg ("missing tap name");
6146       return -99;
6147     }
6148   if (vec_len (tap_name) > 63)
6149     {
6150       errmsg ("tap name too long");
6151       return -99;
6152     }
6153   vec_add1 (tap_name, 0);
6154
6155   if (vec_len (tag) > 63)
6156     {
6157       errmsg ("tag too long");
6158       return -99;
6159     }
6160
6161   /* Construct the API message */
6162   M (TAP_CONNECT, tap_connect);
6163
6164   mp->use_random_mac = random_mac;
6165   clib_memcpy (mp->mac_address, mac_address, 6);
6166   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6167   if (tag)
6168     clib_memcpy (mp->tag, tag, vec_len (tag));
6169
6170   if (ip4_address_set)
6171     {
6172       mp->ip4_address_set = 1;
6173       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6174       mp->ip4_mask_width = ip4_mask_width;
6175     }
6176   if (ip6_address_set)
6177     {
6178       mp->ip6_address_set = 1;
6179       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6180       mp->ip6_mask_width = ip6_mask_width;
6181     }
6182
6183   vec_free (tap_name);
6184   vec_free (tag);
6185
6186   /* send it... */
6187   S;
6188
6189   /* Wait for a reply... */
6190   W;
6191 }
6192
6193 static int
6194 api_tap_modify (vat_main_t * vam)
6195 {
6196   unformat_input_t *i = vam->input;
6197   vl_api_tap_modify_t *mp;
6198   f64 timeout;
6199   u8 mac_address[6];
6200   u8 random_mac = 1;
6201   u8 name_set = 0;
6202   u8 *tap_name;
6203   u32 sw_if_index = ~0;
6204   u8 sw_if_index_set = 0;
6205
6206   memset (mac_address, 0, sizeof (mac_address));
6207
6208   /* Parse args required to build the message */
6209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6210     {
6211       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6212         sw_if_index_set = 1;
6213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6214         sw_if_index_set = 1;
6215       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6216         {
6217           random_mac = 0;
6218         }
6219       else if (unformat (i, "random-mac"))
6220         random_mac = 1;
6221       else if (unformat (i, "tapname %s", &tap_name))
6222         name_set = 1;
6223       else
6224         break;
6225     }
6226
6227   if (sw_if_index_set == 0)
6228     {
6229       errmsg ("missing vpp interface name");
6230       return -99;
6231     }
6232   if (name_set == 0)
6233     {
6234       errmsg ("missing tap name");
6235       return -99;
6236     }
6237   if (vec_len (tap_name) > 63)
6238     {
6239       errmsg ("tap name too long");
6240     }
6241   vec_add1 (tap_name, 0);
6242
6243   /* Construct the API message */
6244   M (TAP_MODIFY, tap_modify);
6245
6246   mp->use_random_mac = random_mac;
6247   mp->sw_if_index = ntohl (sw_if_index);
6248   clib_memcpy (mp->mac_address, mac_address, 6);
6249   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6250   vec_free (tap_name);
6251
6252   /* send it... */
6253   S;
6254
6255   /* Wait for a reply... */
6256   W;
6257 }
6258
6259 static int
6260 api_tap_delete (vat_main_t * vam)
6261 {
6262   unformat_input_t *i = vam->input;
6263   vl_api_tap_delete_t *mp;
6264   f64 timeout;
6265   u32 sw_if_index = ~0;
6266   u8 sw_if_index_set = 0;
6267
6268   /* Parse args required to build the message */
6269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6270     {
6271       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6272         sw_if_index_set = 1;
6273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6274         sw_if_index_set = 1;
6275       else
6276         break;
6277     }
6278
6279   if (sw_if_index_set == 0)
6280     {
6281       errmsg ("missing vpp interface name");
6282       return -99;
6283     }
6284
6285   /* Construct the API message */
6286   M (TAP_DELETE, tap_delete);
6287
6288   mp->sw_if_index = ntohl (sw_if_index);
6289
6290   /* send it... */
6291   S;
6292
6293   /* Wait for a reply... */
6294   W;
6295 }
6296
6297 static int
6298 api_ip_add_del_route (vat_main_t * vam)
6299 {
6300   unformat_input_t *i = vam->input;
6301   vl_api_ip_add_del_route_t *mp;
6302   f64 timeout;
6303   u32 sw_if_index = ~0, vrf_id = 0;
6304   u8 is_ipv6 = 0;
6305   u8 is_local = 0, is_drop = 0;
6306   u8 is_unreach = 0, is_prohibit = 0;
6307   u8 create_vrf_if_needed = 0;
6308   u8 is_add = 1;
6309   u32 next_hop_weight = 1;
6310   u8 not_last = 0;
6311   u8 is_multipath = 0;
6312   u8 address_set = 0;
6313   u8 address_length_set = 0;
6314   u32 next_hop_table_id = 0;
6315   u32 resolve_attempts = 0;
6316   u32 dst_address_length = 0;
6317   u8 next_hop_set = 0;
6318   ip4_address_t v4_dst_address, v4_next_hop_address;
6319   ip6_address_t v6_dst_address, v6_next_hop_address;
6320   int count = 1;
6321   int j;
6322   f64 before = 0;
6323   u32 random_add_del = 0;
6324   u32 *random_vector = 0;
6325   uword *random_hash;
6326   u32 random_seed = 0xdeaddabe;
6327   u32 classify_table_index = ~0;
6328   u8 is_classify = 0;
6329   u8 resolve_host = 0, resolve_attached = 0;
6330   mpls_label_t *next_hop_out_label_stack = NULL;
6331   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6332   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6333
6334   /* Parse args required to build the message */
6335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6336     {
6337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6338         ;
6339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6340         ;
6341       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6342         {
6343           address_set = 1;
6344           is_ipv6 = 0;
6345         }
6346       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6347         {
6348           address_set = 1;
6349           is_ipv6 = 1;
6350         }
6351       else if (unformat (i, "/%d", &dst_address_length))
6352         {
6353           address_length_set = 1;
6354         }
6355
6356       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6357                                          &v4_next_hop_address))
6358         {
6359           next_hop_set = 1;
6360         }
6361       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6362                                          &v6_next_hop_address))
6363         {
6364           next_hop_set = 1;
6365         }
6366       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6367         ;
6368       else if (unformat (i, "weight %d", &next_hop_weight))
6369         ;
6370       else if (unformat (i, "drop"))
6371         {
6372           is_drop = 1;
6373         }
6374       else if (unformat (i, "null-send-unreach"))
6375         {
6376           is_unreach = 1;
6377         }
6378       else if (unformat (i, "null-send-prohibit"))
6379         {
6380           is_prohibit = 1;
6381         }
6382       else if (unformat (i, "local"))
6383         {
6384           is_local = 1;
6385         }
6386       else if (unformat (i, "classify %d", &classify_table_index))
6387         {
6388           is_classify = 1;
6389         }
6390       else if (unformat (i, "del"))
6391         is_add = 0;
6392       else if (unformat (i, "add"))
6393         is_add = 1;
6394       else if (unformat (i, "not-last"))
6395         not_last = 1;
6396       else if (unformat (i, "resolve-via-host"))
6397         resolve_host = 1;
6398       else if (unformat (i, "resolve-via-attached"))
6399         resolve_attached = 1;
6400       else if (unformat (i, "multipath"))
6401         is_multipath = 1;
6402       else if (unformat (i, "vrf %d", &vrf_id))
6403         ;
6404       else if (unformat (i, "create-vrf"))
6405         create_vrf_if_needed = 1;
6406       else if (unformat (i, "count %d", &count))
6407         ;
6408       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6409         ;
6410       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6411         ;
6412       else if (unformat (i, "out-label %d", &next_hop_out_label))
6413         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6414       else if (unformat (i, "via-label %d", &next_hop_via_label))
6415         ;
6416       else if (unformat (i, "random"))
6417         random_add_del = 1;
6418       else if (unformat (i, "seed %d", &random_seed))
6419         ;
6420       else
6421         {
6422           clib_warning ("parse error '%U'", format_unformat_error, i);
6423           return -99;
6424         }
6425     }
6426
6427   if (!next_hop_set && !is_drop && !is_local &&
6428       !is_classify && !is_unreach && !is_prohibit &&
6429       MPLS_LABEL_INVALID == next_hop_via_label)
6430     {
6431       errmsg
6432         ("next hop / local / drop / unreach / prohibit / classify not set");
6433       return -99;
6434     }
6435
6436   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6437     {
6438       errmsg ("next hop and next-hop via label set");
6439       return -99;
6440     }
6441   if (address_set == 0)
6442     {
6443       errmsg ("missing addresses");
6444       return -99;
6445     }
6446
6447   if (address_length_set == 0)
6448     {
6449       errmsg ("missing address length");
6450       return -99;
6451     }
6452
6453   /* Generate a pile of unique, random routes */
6454   if (random_add_del)
6455     {
6456       u32 this_random_address;
6457       random_hash = hash_create (count, sizeof (uword));
6458
6459       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6460       for (j = 0; j <= count; j++)
6461         {
6462           do
6463             {
6464               this_random_address = random_u32 (&random_seed);
6465               this_random_address =
6466                 clib_host_to_net_u32 (this_random_address);
6467             }
6468           while (hash_get (random_hash, this_random_address));
6469           vec_add1 (random_vector, this_random_address);
6470           hash_set (random_hash, this_random_address, 1);
6471         }
6472       hash_free (random_hash);
6473       v4_dst_address.as_u32 = random_vector[0];
6474     }
6475
6476   if (count > 1)
6477     {
6478       /* Turn on async mode */
6479       vam->async_mode = 1;
6480       vam->async_errors = 0;
6481       before = vat_time_now (vam);
6482     }
6483
6484   for (j = 0; j < count; j++)
6485     {
6486       /* Construct the API message */
6487       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6488           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6489
6490       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6491       mp->table_id = ntohl (vrf_id);
6492       mp->create_vrf_if_needed = create_vrf_if_needed;
6493
6494       mp->is_add = is_add;
6495       mp->is_drop = is_drop;
6496       mp->is_unreach = is_unreach;
6497       mp->is_prohibit = is_prohibit;
6498       mp->is_ipv6 = is_ipv6;
6499       mp->is_local = is_local;
6500       mp->is_classify = is_classify;
6501       mp->is_multipath = is_multipath;
6502       mp->is_resolve_host = resolve_host;
6503       mp->is_resolve_attached = resolve_attached;
6504       mp->not_last = not_last;
6505       mp->next_hop_weight = next_hop_weight;
6506       mp->dst_address_length = dst_address_length;
6507       mp->next_hop_table_id = ntohl (next_hop_table_id);
6508       mp->classify_table_index = ntohl (classify_table_index);
6509       mp->next_hop_via_label = ntohl (next_hop_via_label);
6510       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6511       if (0 != mp->next_hop_n_out_labels)
6512         {
6513           memcpy (mp->next_hop_out_label_stack,
6514                   next_hop_out_label_stack,
6515                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6516           vec_free (next_hop_out_label_stack);
6517         }
6518
6519       if (is_ipv6)
6520         {
6521           clib_memcpy (mp->dst_address, &v6_dst_address,
6522                        sizeof (v6_dst_address));
6523           if (next_hop_set)
6524             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6525                          sizeof (v6_next_hop_address));
6526           increment_v6_address (&v6_dst_address);
6527         }
6528       else
6529         {
6530           clib_memcpy (mp->dst_address, &v4_dst_address,
6531                        sizeof (v4_dst_address));
6532           if (next_hop_set)
6533             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6534                          sizeof (v4_next_hop_address));
6535           if (random_add_del)
6536             v4_dst_address.as_u32 = random_vector[j + 1];
6537           else
6538             increment_v4_address (&v4_dst_address);
6539         }
6540       /* send it... */
6541       S;
6542       /* If we receive SIGTERM, stop now... */
6543       if (vam->do_exit)
6544         break;
6545     }
6546
6547   /* When testing multiple add/del ops, use a control-ping to sync */
6548   if (count > 1)
6549     {
6550       vl_api_control_ping_t *mp;
6551       f64 after;
6552
6553       /* Shut off async mode */
6554       vam->async_mode = 0;
6555
6556       M (CONTROL_PING, control_ping);
6557       S;
6558
6559       timeout = vat_time_now (vam) + 1.0;
6560       while (vat_time_now (vam) < timeout)
6561         if (vam->result_ready == 1)
6562           goto out;
6563       vam->retval = -99;
6564
6565     out:
6566       if (vam->retval == -99)
6567         errmsg ("timeout");
6568
6569       if (vam->async_errors > 0)
6570         {
6571           errmsg ("%d asynchronous errors", vam->async_errors);
6572           vam->retval = -98;
6573         }
6574       vam->async_errors = 0;
6575       after = vat_time_now (vam);
6576
6577       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6578       if (j > 0)
6579         count = j;
6580
6581       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6582              count, after - before, count / (after - before));
6583     }
6584   else
6585     {
6586       /* Wait for a reply... */
6587       W;
6588     }
6589
6590   /* Return the good/bad news */
6591   return (vam->retval);
6592 }
6593
6594 static int
6595 api_ip_mroute_add_del (vat_main_t * vam)
6596 {
6597   unformat_input_t *i = vam->input;
6598   vl_api_ip_mroute_add_del_t *mp;
6599   f64 timeout;
6600   u32 sw_if_index = ~0, vrf_id = 0;
6601   u8 is_ipv6 = 0;
6602   u8 is_local = 0;
6603   u8 create_vrf_if_needed = 0;
6604   u8 is_add = 1;
6605   u8 address_set = 0;
6606   u32 grp_address_length = 0;
6607   ip4_address_t v4_grp_address, v4_src_address;
6608   ip6_address_t v6_grp_address, v6_src_address;
6609   mfib_itf_flags_t iflags = 0;
6610   mfib_entry_flags_t eflags = 0;
6611
6612   /* Parse args required to build the message */
6613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6614     {
6615       if (unformat (i, "sw_if_index %d", &sw_if_index))
6616         ;
6617       else if (unformat (i, "%U %U",
6618                          unformat_ip4_address, &v4_src_address,
6619                          unformat_ip4_address, &v4_grp_address))
6620         {
6621           grp_address_length = 64;
6622           address_set = 1;
6623           is_ipv6 = 0;
6624         }
6625       else if (unformat (i, "%U %U",
6626                          unformat_ip6_address, &v6_src_address,
6627                          unformat_ip6_address, &v6_grp_address))
6628         {
6629           grp_address_length = 256;
6630           address_set = 1;
6631           is_ipv6 = 1;
6632         }
6633       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6634         {
6635           memset (&v4_src_address, 0, sizeof (v4_src_address));
6636           grp_address_length = 32;
6637           address_set = 1;
6638           is_ipv6 = 0;
6639         }
6640       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6641         {
6642           memset (&v6_src_address, 0, sizeof (v6_src_address));
6643           grp_address_length = 128;
6644           address_set = 1;
6645           is_ipv6 = 1;
6646         }
6647       else if (unformat (i, "/%d", &grp_address_length))
6648         ;
6649       else if (unformat (i, "local"))
6650         {
6651           is_local = 1;
6652         }
6653       else if (unformat (i, "del"))
6654         is_add = 0;
6655       else if (unformat (i, "add"))
6656         is_add = 1;
6657       else if (unformat (i, "vrf %d", &vrf_id))
6658         ;
6659       else if (unformat (i, "create-vrf"))
6660         create_vrf_if_needed = 1;
6661       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6662         ;
6663       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6664         ;
6665       else
6666         {
6667           clib_warning ("parse error '%U'", format_unformat_error, i);
6668           return -99;
6669         }
6670     }
6671
6672   if (address_set == 0)
6673     {
6674       errmsg ("missing addresses\n");
6675       return -99;
6676     }
6677
6678   /* Construct the API message */
6679   M (IP_MROUTE_ADD_DEL, ip_mroute_add_del);
6680
6681   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6682   mp->table_id = ntohl (vrf_id);
6683   mp->create_vrf_if_needed = create_vrf_if_needed;
6684
6685   mp->is_add = is_add;
6686   mp->is_ipv6 = is_ipv6;
6687   mp->is_local = is_local;
6688   mp->itf_flags = ntohl (iflags);
6689   mp->entry_flags = ntohl (eflags);
6690   mp->grp_address_length = grp_address_length;
6691   mp->grp_address_length = ntohs (mp->grp_address_length);
6692
6693   if (is_ipv6)
6694     {
6695       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6696       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6697     }
6698   else
6699     {
6700       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6701       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6702
6703     }
6704
6705   /* send it... */
6706   S;
6707   /* Wait for a reply... */
6708   W;
6709
6710   /* Return the good/bad news */
6711   return (vam->retval);
6712 }
6713
6714 static int
6715 api_mpls_route_add_del (vat_main_t * vam)
6716 {
6717   unformat_input_t *i = vam->input;
6718   vl_api_mpls_route_add_del_t *mp;
6719   f64 timeout;
6720   u32 sw_if_index = ~0, table_id = 0;
6721   u8 create_table_if_needed = 0;
6722   u8 is_add = 1;
6723   u32 next_hop_weight = 1;
6724   u8 is_multipath = 0;
6725   u32 next_hop_table_id = 0;
6726   u8 next_hop_set = 0;
6727   ip4_address_t v4_next_hop_address = {
6728     .as_u32 = 0,
6729   };
6730   ip6_address_t v6_next_hop_address = { {0} };
6731   int count = 1;
6732   int j;
6733   f64 before = 0;
6734   u32 classify_table_index = ~0;
6735   u8 is_classify = 0;
6736   u8 resolve_host = 0, resolve_attached = 0;
6737   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6738   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6739   mpls_label_t *next_hop_out_label_stack = NULL;
6740   mpls_label_t local_label = MPLS_LABEL_INVALID;
6741   u8 is_eos = 0;
6742   u8 next_hop_proto_is_ip4 = 1;
6743
6744   /* Parse args required to build the message */
6745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6746     {
6747       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6748         ;
6749       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6750         ;
6751       else if (unformat (i, "%d", &local_label))
6752         ;
6753       else if (unformat (i, "eos"))
6754         is_eos = 1;
6755       else if (unformat (i, "non-eos"))
6756         is_eos = 0;
6757       else if (unformat (i, "via %U", unformat_ip4_address,
6758                          &v4_next_hop_address))
6759         {
6760           next_hop_set = 1;
6761           next_hop_proto_is_ip4 = 1;
6762         }
6763       else if (unformat (i, "via %U", unformat_ip6_address,
6764                          &v6_next_hop_address))
6765         {
6766           next_hop_set = 1;
6767           next_hop_proto_is_ip4 = 0;
6768         }
6769       else if (unformat (i, "weight %d", &next_hop_weight))
6770         ;
6771       else if (unformat (i, "create-table"))
6772         create_table_if_needed = 1;
6773       else if (unformat (i, "classify %d", &classify_table_index))
6774         {
6775           is_classify = 1;
6776         }
6777       else if (unformat (i, "del"))
6778         is_add = 0;
6779       else if (unformat (i, "add"))
6780         is_add = 1;
6781       else if (unformat (i, "resolve-via-host"))
6782         resolve_host = 1;
6783       else if (unformat (i, "resolve-via-attached"))
6784         resolve_attached = 1;
6785       else if (unformat (i, "multipath"))
6786         is_multipath = 1;
6787       else if (unformat (i, "count %d", &count))
6788         ;
6789       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6790         {
6791           next_hop_set = 1;
6792           next_hop_proto_is_ip4 = 1;
6793         }
6794       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6795         {
6796           next_hop_set = 1;
6797           next_hop_proto_is_ip4 = 0;
6798         }
6799       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6800         ;
6801       else if (unformat (i, "via-label %d", &next_hop_via_label))
6802         ;
6803       else if (unformat (i, "out-label %d", &next_hop_out_label))
6804         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6805       else
6806         {
6807           clib_warning ("parse error '%U'", format_unformat_error, i);
6808           return -99;
6809         }
6810     }
6811
6812   if (!next_hop_set && !is_classify)
6813     {
6814       errmsg ("next hop / classify not set");
6815       return -99;
6816     }
6817
6818   if (MPLS_LABEL_INVALID == local_label)
6819     {
6820       errmsg ("missing label");
6821       return -99;
6822     }
6823
6824   if (count > 1)
6825     {
6826       /* Turn on async mode */
6827       vam->async_mode = 1;
6828       vam->async_errors = 0;
6829       before = vat_time_now (vam);
6830     }
6831
6832   for (j = 0; j < count; j++)
6833     {
6834       /* Construct the API message */
6835       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6836           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6837
6838       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6839       mp->mr_table_id = ntohl (table_id);
6840       mp->mr_create_table_if_needed = create_table_if_needed;
6841
6842       mp->mr_is_add = is_add;
6843       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6844       mp->mr_is_classify = is_classify;
6845       mp->mr_is_multipath = is_multipath;
6846       mp->mr_is_resolve_host = resolve_host;
6847       mp->mr_is_resolve_attached = resolve_attached;
6848       mp->mr_next_hop_weight = next_hop_weight;
6849       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6850       mp->mr_classify_table_index = ntohl (classify_table_index);
6851       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6852       mp->mr_label = ntohl (local_label);
6853       mp->mr_eos = is_eos;
6854
6855       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6856       if (0 != mp->mr_next_hop_n_out_labels)
6857         {
6858           memcpy (mp->mr_next_hop_out_label_stack,
6859                   next_hop_out_label_stack,
6860                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6861           vec_free (next_hop_out_label_stack);
6862         }
6863
6864       if (next_hop_set)
6865         {
6866           if (next_hop_proto_is_ip4)
6867             {
6868               clib_memcpy (mp->mr_next_hop,
6869                            &v4_next_hop_address,
6870                            sizeof (v4_next_hop_address));
6871             }
6872           else
6873             {
6874               clib_memcpy (mp->mr_next_hop,
6875                            &v6_next_hop_address,
6876                            sizeof (v6_next_hop_address));
6877             }
6878         }
6879       local_label++;
6880
6881       /* send it... */
6882       S;
6883       /* If we receive SIGTERM, stop now... */
6884       if (vam->do_exit)
6885         break;
6886     }
6887
6888   /* When testing multiple add/del ops, use a control-ping to sync */
6889   if (count > 1)
6890     {
6891       vl_api_control_ping_t *mp;
6892       f64 after;
6893
6894       /* Shut off async mode */
6895       vam->async_mode = 0;
6896
6897       M (CONTROL_PING, control_ping);
6898       S;
6899
6900       timeout = vat_time_now (vam) + 1.0;
6901       while (vat_time_now (vam) < timeout)
6902         if (vam->result_ready == 1)
6903           goto out;
6904       vam->retval = -99;
6905
6906     out:
6907       if (vam->retval == -99)
6908         errmsg ("timeout");
6909
6910       if (vam->async_errors > 0)
6911         {
6912           errmsg ("%d asynchronous errors", vam->async_errors);
6913           vam->retval = -98;
6914         }
6915       vam->async_errors = 0;
6916       after = vat_time_now (vam);
6917
6918       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6919       if (j > 0)
6920         count = j;
6921
6922       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6923              count, after - before, count / (after - before));
6924     }
6925   else
6926     {
6927       /* Wait for a reply... */
6928       W;
6929     }
6930
6931   /* Return the good/bad news */
6932   return (vam->retval);
6933 }
6934
6935 static int
6936 api_mpls_ip_bind_unbind (vat_main_t * vam)
6937 {
6938   unformat_input_t *i = vam->input;
6939   vl_api_mpls_ip_bind_unbind_t *mp;
6940   f64 timeout;
6941   u32 ip_table_id = 0;
6942   u8 create_table_if_needed = 0;
6943   u8 is_bind = 1;
6944   u8 is_ip4 = 1;
6945   ip4_address_t v4_address;
6946   ip6_address_t v6_address;
6947   u32 address_length;
6948   u8 address_set = 0;
6949   mpls_label_t local_label = MPLS_LABEL_INVALID;
6950
6951   /* Parse args required to build the message */
6952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6953     {
6954       if (unformat (i, "%U/%d", unformat_ip4_address,
6955                     &v4_address, &address_length))
6956         {
6957           is_ip4 = 1;
6958           address_set = 1;
6959         }
6960       else if (unformat (i, "%U/%d", unformat_ip6_address,
6961                          &v6_address, &address_length))
6962         {
6963           is_ip4 = 0;
6964           address_set = 1;
6965         }
6966       else if (unformat (i, "%d", &local_label))
6967         ;
6968       else if (unformat (i, "create-table"))
6969         create_table_if_needed = 1;
6970       else if (unformat (i, "table-id %d", &ip_table_id))
6971         ;
6972       else if (unformat (i, "unbind"))
6973         is_bind = 0;
6974       else if (unformat (i, "bind"))
6975         is_bind = 1;
6976       else
6977         {
6978           clib_warning ("parse error '%U'", format_unformat_error, i);
6979           return -99;
6980         }
6981     }
6982
6983   if (!address_set)
6984     {
6985       errmsg ("IP addres not set");
6986       return -99;
6987     }
6988
6989   if (MPLS_LABEL_INVALID == local_label)
6990     {
6991       errmsg ("missing label");
6992       return -99;
6993     }
6994
6995   /* Construct the API message */
6996   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6997
6998   mp->mb_create_table_if_needed = create_table_if_needed;
6999   mp->mb_is_bind = is_bind;
7000   mp->mb_is_ip4 = is_ip4;
7001   mp->mb_ip_table_id = ntohl (ip_table_id);
7002   mp->mb_mpls_table_id = 0;
7003   mp->mb_label = ntohl (local_label);
7004   mp->mb_address_length = address_length;
7005
7006   if (is_ip4)
7007     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7008   else
7009     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7010
7011   /* send it... */
7012   S;
7013
7014   /* Wait for a reply... */
7015   W;
7016 }
7017
7018 static int
7019 api_proxy_arp_add_del (vat_main_t * vam)
7020 {
7021   unformat_input_t *i = vam->input;
7022   vl_api_proxy_arp_add_del_t *mp;
7023   f64 timeout;
7024   u32 vrf_id = 0;
7025   u8 is_add = 1;
7026   ip4_address_t lo, hi;
7027   u8 range_set = 0;
7028
7029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7030     {
7031       if (unformat (i, "vrf %d", &vrf_id))
7032         ;
7033       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7034                          unformat_ip4_address, &hi))
7035         range_set = 1;
7036       else if (unformat (i, "del"))
7037         is_add = 0;
7038       else
7039         {
7040           clib_warning ("parse error '%U'", format_unformat_error, i);
7041           return -99;
7042         }
7043     }
7044
7045   if (range_set == 0)
7046     {
7047       errmsg ("address range not set");
7048       return -99;
7049     }
7050
7051   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
7052
7053   mp->vrf_id = ntohl (vrf_id);
7054   mp->is_add = is_add;
7055   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7056   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7057
7058   S;
7059   W;
7060   /* NOTREACHED */
7061   return 0;
7062 }
7063
7064 static int
7065 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7066 {
7067   unformat_input_t *i = vam->input;
7068   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7069   f64 timeout;
7070   u32 sw_if_index;
7071   u8 enable = 1;
7072   u8 sw_if_index_set = 0;
7073
7074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7075     {
7076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7077         sw_if_index_set = 1;
7078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7079         sw_if_index_set = 1;
7080       else if (unformat (i, "enable"))
7081         enable = 1;
7082       else if (unformat (i, "disable"))
7083         enable = 0;
7084       else
7085         {
7086           clib_warning ("parse error '%U'", format_unformat_error, i);
7087           return -99;
7088         }
7089     }
7090
7091   if (sw_if_index_set == 0)
7092     {
7093       errmsg ("missing interface name or sw_if_index");
7094       return -99;
7095     }
7096
7097   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
7098
7099   mp->sw_if_index = ntohl (sw_if_index);
7100   mp->enable_disable = enable;
7101
7102   S;
7103   W;
7104   /* NOTREACHED */
7105   return 0;
7106 }
7107
7108 static int
7109 api_mpls_tunnel_add_del (vat_main_t * vam)
7110 {
7111   unformat_input_t *i = vam->input;
7112   vl_api_mpls_tunnel_add_del_t *mp;
7113   f64 timeout;
7114
7115   u8 is_add = 1;
7116   u8 l2_only = 0;
7117   u32 sw_if_index = ~0;
7118   u32 next_hop_sw_if_index = ~0;
7119   u32 next_hop_proto_is_ip4 = 1;
7120
7121   u32 next_hop_table_id = 0;
7122   ip4_address_t v4_next_hop_address = {
7123     .as_u32 = 0,
7124   };
7125   ip6_address_t v6_next_hop_address = { {0} };
7126   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7127
7128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7129     {
7130       if (unformat (i, "add"))
7131         is_add = 1;
7132       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7133         is_add = 0;
7134       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7135         ;
7136       else if (unformat (i, "via %U",
7137                          unformat_ip4_address, &v4_next_hop_address))
7138         {
7139           next_hop_proto_is_ip4 = 1;
7140         }
7141       else if (unformat (i, "via %U",
7142                          unformat_ip6_address, &v6_next_hop_address))
7143         {
7144           next_hop_proto_is_ip4 = 0;
7145         }
7146       else if (unformat (i, "l2-only"))
7147         l2_only = 1;
7148       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7149         ;
7150       else if (unformat (i, "out-label %d", &next_hop_out_label))
7151         vec_add1 (labels, ntohl (next_hop_out_label));
7152       else
7153         {
7154           clib_warning ("parse error '%U'", format_unformat_error, i);
7155           return -99;
7156         }
7157     }
7158
7159   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
7160       sizeof (mpls_label_t) * vec_len (labels));
7161
7162   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7163   mp->mt_sw_if_index = ntohl (sw_if_index);
7164   mp->mt_is_add = is_add;
7165   mp->mt_l2_only = l2_only;
7166   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7167   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7168
7169   mp->mt_next_hop_n_out_labels = vec_len (labels);
7170
7171   if (0 != mp->mt_next_hop_n_out_labels)
7172     {
7173       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7174                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7175       vec_free (labels);
7176     }
7177
7178   if (next_hop_proto_is_ip4)
7179     {
7180       clib_memcpy (mp->mt_next_hop,
7181                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7182     }
7183   else
7184     {
7185       clib_memcpy (mp->mt_next_hop,
7186                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7187     }
7188
7189   S;
7190   W;
7191   /* NOTREACHED */
7192   return 0;
7193 }
7194
7195 static int
7196 api_sw_interface_set_unnumbered (vat_main_t * vam)
7197 {
7198   unformat_input_t *i = vam->input;
7199   vl_api_sw_interface_set_unnumbered_t *mp;
7200   f64 timeout;
7201   u32 sw_if_index;
7202   u32 unnum_sw_index = ~0;
7203   u8 is_add = 1;
7204   u8 sw_if_index_set = 0;
7205
7206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7207     {
7208       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7209         sw_if_index_set = 1;
7210       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7211         sw_if_index_set = 1;
7212       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7213         ;
7214       else if (unformat (i, "del"))
7215         is_add = 0;
7216       else
7217         {
7218           clib_warning ("parse error '%U'", format_unformat_error, i);
7219           return -99;
7220         }
7221     }
7222
7223   if (sw_if_index_set == 0)
7224     {
7225       errmsg ("missing interface name or sw_if_index");
7226       return -99;
7227     }
7228
7229   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
7230
7231   mp->sw_if_index = ntohl (sw_if_index);
7232   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7233   mp->is_add = is_add;
7234
7235   S;
7236   W;
7237   /* NOTREACHED */
7238   return 0;
7239 }
7240
7241 static int
7242 api_ip_neighbor_add_del (vat_main_t * vam)
7243 {
7244   unformat_input_t *i = vam->input;
7245   vl_api_ip_neighbor_add_del_t *mp;
7246   f64 timeout;
7247   u32 sw_if_index;
7248   u8 sw_if_index_set = 0;
7249   u32 vrf_id = 0;
7250   u8 is_add = 1;
7251   u8 is_static = 0;
7252   u8 mac_address[6];
7253   u8 mac_set = 0;
7254   u8 v4_address_set = 0;
7255   u8 v6_address_set = 0;
7256   ip4_address_t v4address;
7257   ip6_address_t v6address;
7258
7259   memset (mac_address, 0, sizeof (mac_address));
7260
7261   /* Parse args required to build the message */
7262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7263     {
7264       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7265         {
7266           mac_set = 1;
7267         }
7268       else if (unformat (i, "del"))
7269         is_add = 0;
7270       else
7271         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7272         sw_if_index_set = 1;
7273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7274         sw_if_index_set = 1;
7275       else if (unformat (i, "is_static"))
7276         is_static = 1;
7277       else if (unformat (i, "vrf %d", &vrf_id))
7278         ;
7279       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7280         v4_address_set = 1;
7281       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7282         v6_address_set = 1;
7283       else
7284         {
7285           clib_warning ("parse error '%U'", format_unformat_error, i);
7286           return -99;
7287         }
7288     }
7289
7290   if (sw_if_index_set == 0)
7291     {
7292       errmsg ("missing interface name or sw_if_index");
7293       return -99;
7294     }
7295   if (v4_address_set && v6_address_set)
7296     {
7297       errmsg ("both v4 and v6 addresses set");
7298       return -99;
7299     }
7300   if (!v4_address_set && !v6_address_set)
7301     {
7302       errmsg ("no address set");
7303       return -99;
7304     }
7305
7306   /* Construct the API message */
7307   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
7308
7309   mp->sw_if_index = ntohl (sw_if_index);
7310   mp->is_add = is_add;
7311   mp->vrf_id = ntohl (vrf_id);
7312   mp->is_static = is_static;
7313   if (mac_set)
7314     clib_memcpy (mp->mac_address, mac_address, 6);
7315   if (v6_address_set)
7316     {
7317       mp->is_ipv6 = 1;
7318       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7319     }
7320   else
7321     {
7322       /* mp->is_ipv6 = 0; via memset in M macro above */
7323       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7324     }
7325
7326   /* send it... */
7327   S;
7328
7329   /* Wait for a reply, return good/bad news  */
7330   W;
7331
7332   /* NOTREACHED */
7333   return 0;
7334 }
7335
7336 static int
7337 api_reset_vrf (vat_main_t * vam)
7338 {
7339   unformat_input_t *i = vam->input;
7340   vl_api_reset_vrf_t *mp;
7341   f64 timeout;
7342   u32 vrf_id = 0;
7343   u8 is_ipv6 = 0;
7344   u8 vrf_id_set = 0;
7345
7346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7347     {
7348       if (unformat (i, "vrf %d", &vrf_id))
7349         vrf_id_set = 1;
7350       else if (unformat (i, "ipv6"))
7351         is_ipv6 = 1;
7352       else
7353         {
7354           clib_warning ("parse error '%U'", format_unformat_error, i);
7355           return -99;
7356         }
7357     }
7358
7359   if (vrf_id_set == 0)
7360     {
7361       errmsg ("missing vrf id");
7362       return -99;
7363     }
7364
7365   M (RESET_VRF, reset_vrf);
7366
7367   mp->vrf_id = ntohl (vrf_id);
7368   mp->is_ipv6 = is_ipv6;
7369
7370   S;
7371   W;
7372   /* NOTREACHED */
7373   return 0;
7374 }
7375
7376 static int
7377 api_create_vlan_subif (vat_main_t * vam)
7378 {
7379   unformat_input_t *i = vam->input;
7380   vl_api_create_vlan_subif_t *mp;
7381   f64 timeout;
7382   u32 sw_if_index;
7383   u8 sw_if_index_set = 0;
7384   u32 vlan_id;
7385   u8 vlan_id_set = 0;
7386
7387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7388     {
7389       if (unformat (i, "sw_if_index %d", &sw_if_index))
7390         sw_if_index_set = 1;
7391       else
7392         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7393         sw_if_index_set = 1;
7394       else if (unformat (i, "vlan %d", &vlan_id))
7395         vlan_id_set = 1;
7396       else
7397         {
7398           clib_warning ("parse error '%U'", format_unformat_error, i);
7399           return -99;
7400         }
7401     }
7402
7403   if (sw_if_index_set == 0)
7404     {
7405       errmsg ("missing interface name or sw_if_index");
7406       return -99;
7407     }
7408
7409   if (vlan_id_set == 0)
7410     {
7411       errmsg ("missing vlan_id");
7412       return -99;
7413     }
7414   M (CREATE_VLAN_SUBIF, create_vlan_subif);
7415
7416   mp->sw_if_index = ntohl (sw_if_index);
7417   mp->vlan_id = ntohl (vlan_id);
7418
7419   S;
7420   W;
7421   /* NOTREACHED */
7422   return 0;
7423 }
7424
7425 #define foreach_create_subif_bit                \
7426 _(no_tags)                                      \
7427 _(one_tag)                                      \
7428 _(two_tags)                                     \
7429 _(dot1ad)                                       \
7430 _(exact_match)                                  \
7431 _(default_sub)                                  \
7432 _(outer_vlan_id_any)                            \
7433 _(inner_vlan_id_any)
7434
7435 static int
7436 api_create_subif (vat_main_t * vam)
7437 {
7438   unformat_input_t *i = vam->input;
7439   vl_api_create_subif_t *mp;
7440   f64 timeout;
7441   u32 sw_if_index;
7442   u8 sw_if_index_set = 0;
7443   u32 sub_id;
7444   u8 sub_id_set = 0;
7445   u32 no_tags = 0;
7446   u32 one_tag = 0;
7447   u32 two_tags = 0;
7448   u32 dot1ad = 0;
7449   u32 exact_match = 0;
7450   u32 default_sub = 0;
7451   u32 outer_vlan_id_any = 0;
7452   u32 inner_vlan_id_any = 0;
7453   u32 tmp;
7454   u16 outer_vlan_id = 0;
7455   u16 inner_vlan_id = 0;
7456
7457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7458     {
7459       if (unformat (i, "sw_if_index %d", &sw_if_index))
7460         sw_if_index_set = 1;
7461       else
7462         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7463         sw_if_index_set = 1;
7464       else if (unformat (i, "sub_id %d", &sub_id))
7465         sub_id_set = 1;
7466       else if (unformat (i, "outer_vlan_id %d", &tmp))
7467         outer_vlan_id = tmp;
7468       else if (unformat (i, "inner_vlan_id %d", &tmp))
7469         inner_vlan_id = tmp;
7470
7471 #define _(a) else if (unformat (i, #a)) a = 1 ;
7472       foreach_create_subif_bit
7473 #undef _
7474         else
7475         {
7476           clib_warning ("parse error '%U'", format_unformat_error, i);
7477           return -99;
7478         }
7479     }
7480
7481   if (sw_if_index_set == 0)
7482     {
7483       errmsg ("missing interface name or sw_if_index");
7484       return -99;
7485     }
7486
7487   if (sub_id_set == 0)
7488     {
7489       errmsg ("missing sub_id");
7490       return -99;
7491     }
7492   M (CREATE_SUBIF, create_subif);
7493
7494   mp->sw_if_index = ntohl (sw_if_index);
7495   mp->sub_id = ntohl (sub_id);
7496
7497 #define _(a) mp->a = a;
7498   foreach_create_subif_bit;
7499 #undef _
7500
7501   mp->outer_vlan_id = ntohs (outer_vlan_id);
7502   mp->inner_vlan_id = ntohs (inner_vlan_id);
7503
7504   S;
7505   W;
7506   /* NOTREACHED */
7507   return 0;
7508 }
7509
7510 static int
7511 api_oam_add_del (vat_main_t * vam)
7512 {
7513   unformat_input_t *i = vam->input;
7514   vl_api_oam_add_del_t *mp;
7515   f64 timeout;
7516   u32 vrf_id = 0;
7517   u8 is_add = 1;
7518   ip4_address_t src, dst;
7519   u8 src_set = 0;
7520   u8 dst_set = 0;
7521
7522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7523     {
7524       if (unformat (i, "vrf %d", &vrf_id))
7525         ;
7526       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7527         src_set = 1;
7528       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7529         dst_set = 1;
7530       else if (unformat (i, "del"))
7531         is_add = 0;
7532       else
7533         {
7534           clib_warning ("parse error '%U'", format_unformat_error, i);
7535           return -99;
7536         }
7537     }
7538
7539   if (src_set == 0)
7540     {
7541       errmsg ("missing src addr");
7542       return -99;
7543     }
7544
7545   if (dst_set == 0)
7546     {
7547       errmsg ("missing dst addr");
7548       return -99;
7549     }
7550
7551   M (OAM_ADD_DEL, oam_add_del);
7552
7553   mp->vrf_id = ntohl (vrf_id);
7554   mp->is_add = is_add;
7555   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7556   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7557
7558   S;
7559   W;
7560   /* NOTREACHED */
7561   return 0;
7562 }
7563
7564 static int
7565 api_reset_fib (vat_main_t * vam)
7566 {
7567   unformat_input_t *i = vam->input;
7568   vl_api_reset_fib_t *mp;
7569   f64 timeout;
7570   u32 vrf_id = 0;
7571   u8 is_ipv6 = 0;
7572   u8 vrf_id_set = 0;
7573
7574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7575     {
7576       if (unformat (i, "vrf %d", &vrf_id))
7577         vrf_id_set = 1;
7578       else if (unformat (i, "ipv6"))
7579         is_ipv6 = 1;
7580       else
7581         {
7582           clib_warning ("parse error '%U'", format_unformat_error, i);
7583           return -99;
7584         }
7585     }
7586
7587   if (vrf_id_set == 0)
7588     {
7589       errmsg ("missing vrf id");
7590       return -99;
7591     }
7592
7593   M (RESET_FIB, reset_fib);
7594
7595   mp->vrf_id = ntohl (vrf_id);
7596   mp->is_ipv6 = is_ipv6;
7597
7598   S;
7599   W;
7600   /* NOTREACHED */
7601   return 0;
7602 }
7603
7604 static int
7605 api_dhcp_proxy_config (vat_main_t * vam)
7606 {
7607   unformat_input_t *i = vam->input;
7608   vl_api_dhcp_proxy_config_t *mp;
7609   f64 timeout;
7610   u32 vrf_id = 0;
7611   u8 is_add = 1;
7612   u8 insert_cid = 1;
7613   u8 v4_address_set = 0;
7614   u8 v6_address_set = 0;
7615   ip4_address_t v4address;
7616   ip6_address_t v6address;
7617   u8 v4_src_address_set = 0;
7618   u8 v6_src_address_set = 0;
7619   ip4_address_t v4srcaddress;
7620   ip6_address_t v6srcaddress;
7621
7622   /* Parse args required to build the message */
7623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7624     {
7625       if (unformat (i, "del"))
7626         is_add = 0;
7627       else if (unformat (i, "vrf %d", &vrf_id))
7628         ;
7629       else if (unformat (i, "insert-cid %d", &insert_cid))
7630         ;
7631       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7632         v4_address_set = 1;
7633       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7634         v6_address_set = 1;
7635       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7636         v4_src_address_set = 1;
7637       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7638         v6_src_address_set = 1;
7639       else
7640         break;
7641     }
7642
7643   if (v4_address_set && v6_address_set)
7644     {
7645       errmsg ("both v4 and v6 server addresses set");
7646       return -99;
7647     }
7648   if (!v4_address_set && !v6_address_set)
7649     {
7650       errmsg ("no server addresses set");
7651       return -99;
7652     }
7653
7654   if (v4_src_address_set && v6_src_address_set)
7655     {
7656       errmsg ("both v4 and v6  src addresses set");
7657       return -99;
7658     }
7659   if (!v4_src_address_set && !v6_src_address_set)
7660     {
7661       errmsg ("no src addresses set");
7662       return -99;
7663     }
7664
7665   if (!(v4_src_address_set && v4_address_set) &&
7666       !(v6_src_address_set && v6_address_set))
7667     {
7668       errmsg ("no matching server and src addresses set");
7669       return -99;
7670     }
7671
7672   /* Construct the API message */
7673   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7674
7675   mp->insert_circuit_id = insert_cid;
7676   mp->is_add = is_add;
7677   mp->vrf_id = ntohl (vrf_id);
7678   if (v6_address_set)
7679     {
7680       mp->is_ipv6 = 1;
7681       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7682       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7683     }
7684   else
7685     {
7686       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7687       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7688     }
7689
7690   /* send it... */
7691   S;
7692
7693   /* Wait for a reply, return good/bad news  */
7694   W;
7695   /* NOTREACHED */
7696   return 0;
7697 }
7698
7699 static int
7700 api_dhcp_proxy_config_2 (vat_main_t * vam)
7701 {
7702   unformat_input_t *i = vam->input;
7703   vl_api_dhcp_proxy_config_2_t *mp;
7704   f64 timeout;
7705   u32 rx_vrf_id = 0;
7706   u32 server_vrf_id = 0;
7707   u8 is_add = 1;
7708   u8 insert_cid = 1;
7709   u8 v4_address_set = 0;
7710   u8 v6_address_set = 0;
7711   ip4_address_t v4address;
7712   ip6_address_t v6address;
7713   u8 v4_src_address_set = 0;
7714   u8 v6_src_address_set = 0;
7715   ip4_address_t v4srcaddress;
7716   ip6_address_t v6srcaddress;
7717
7718   /* Parse args required to build the message */
7719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7720     {
7721       if (unformat (i, "del"))
7722         is_add = 0;
7723       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7724         ;
7725       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7726         ;
7727       else if (unformat (i, "insert-cid %d", &insert_cid))
7728         ;
7729       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7730         v4_address_set = 1;
7731       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7732         v6_address_set = 1;
7733       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7734         v4_src_address_set = 1;
7735       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7736         v6_src_address_set = 1;
7737       else
7738         break;
7739     }
7740
7741   if (v4_address_set && v6_address_set)
7742     {
7743       errmsg ("both v4 and v6 server addresses set");
7744       return -99;
7745     }
7746   if (!v4_address_set && !v6_address_set)
7747     {
7748       errmsg ("no server addresses set");
7749       return -99;
7750     }
7751
7752   if (v4_src_address_set && v6_src_address_set)
7753     {
7754       errmsg ("both v4 and v6  src addresses set");
7755       return -99;
7756     }
7757   if (!v4_src_address_set && !v6_src_address_set)
7758     {
7759       errmsg ("no src addresses set");
7760       return -99;
7761     }
7762
7763   if (!(v4_src_address_set && v4_address_set) &&
7764       !(v6_src_address_set && v6_address_set))
7765     {
7766       errmsg ("no matching server and src addresses set");
7767       return -99;
7768     }
7769
7770   /* Construct the API message */
7771   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7772
7773   mp->insert_circuit_id = insert_cid;
7774   mp->is_add = is_add;
7775   mp->rx_vrf_id = ntohl (rx_vrf_id);
7776   mp->server_vrf_id = ntohl (server_vrf_id);
7777   if (v6_address_set)
7778     {
7779       mp->is_ipv6 = 1;
7780       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7781       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7782     }
7783   else
7784     {
7785       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7786       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7787     }
7788
7789   /* send it... */
7790   S;
7791
7792   /* Wait for a reply, return good/bad news  */
7793   W;
7794   /* NOTREACHED */
7795   return 0;
7796 }
7797
7798 static int
7799 api_dhcp_proxy_set_vss (vat_main_t * vam)
7800 {
7801   unformat_input_t *i = vam->input;
7802   vl_api_dhcp_proxy_set_vss_t *mp;
7803   f64 timeout;
7804   u8 is_ipv6 = 0;
7805   u8 is_add = 1;
7806   u32 tbl_id;
7807   u8 tbl_id_set = 0;
7808   u32 oui;
7809   u8 oui_set = 0;
7810   u32 fib_id;
7811   u8 fib_id_set = 0;
7812
7813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7814     {
7815       if (unformat (i, "tbl_id %d", &tbl_id))
7816         tbl_id_set = 1;
7817       if (unformat (i, "fib_id %d", &fib_id))
7818         fib_id_set = 1;
7819       if (unformat (i, "oui %d", &oui))
7820         oui_set = 1;
7821       else if (unformat (i, "ipv6"))
7822         is_ipv6 = 1;
7823       else if (unformat (i, "del"))
7824         is_add = 0;
7825       else
7826         {
7827           clib_warning ("parse error '%U'", format_unformat_error, i);
7828           return -99;
7829         }
7830     }
7831
7832   if (tbl_id_set == 0)
7833     {
7834       errmsg ("missing tbl id");
7835       return -99;
7836     }
7837
7838   if (fib_id_set == 0)
7839     {
7840       errmsg ("missing fib id");
7841       return -99;
7842     }
7843   if (oui_set == 0)
7844     {
7845       errmsg ("missing oui");
7846       return -99;
7847     }
7848
7849   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7850   mp->tbl_id = ntohl (tbl_id);
7851   mp->fib_id = ntohl (fib_id);
7852   mp->oui = ntohl (oui);
7853   mp->is_ipv6 = is_ipv6;
7854   mp->is_add = is_add;
7855
7856   S;
7857   W;
7858   /* NOTREACHED */
7859   return 0;
7860 }
7861
7862 static int
7863 api_dhcp_client_config (vat_main_t * vam)
7864 {
7865   unformat_input_t *i = vam->input;
7866   vl_api_dhcp_client_config_t *mp;
7867   f64 timeout;
7868   u32 sw_if_index;
7869   u8 sw_if_index_set = 0;
7870   u8 is_add = 1;
7871   u8 *hostname = 0;
7872   u8 disable_event = 0;
7873
7874   /* Parse args required to build the message */
7875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7876     {
7877       if (unformat (i, "del"))
7878         is_add = 0;
7879       else
7880         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7881         sw_if_index_set = 1;
7882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7883         sw_if_index_set = 1;
7884       else if (unformat (i, "hostname %s", &hostname))
7885         ;
7886       else if (unformat (i, "disable_event"))
7887         disable_event = 1;
7888       else
7889         break;
7890     }
7891
7892   if (sw_if_index_set == 0)
7893     {
7894       errmsg ("missing interface name or sw_if_index");
7895       return -99;
7896     }
7897
7898   if (vec_len (hostname) > 63)
7899     {
7900       errmsg ("hostname too long");
7901     }
7902   vec_add1 (hostname, 0);
7903
7904   /* Construct the API message */
7905   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7906
7907   mp->sw_if_index = ntohl (sw_if_index);
7908   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7909   vec_free (hostname);
7910   mp->is_add = is_add;
7911   mp->want_dhcp_event = disable_event ? 0 : 1;
7912   mp->pid = getpid ();
7913
7914   /* send it... */
7915   S;
7916
7917   /* Wait for a reply, return good/bad news  */
7918   W;
7919   /* NOTREACHED */
7920   return 0;
7921 }
7922
7923 static int
7924 api_set_ip_flow_hash (vat_main_t * vam)
7925 {
7926   unformat_input_t *i = vam->input;
7927   vl_api_set_ip_flow_hash_t *mp;
7928   f64 timeout;
7929   u32 vrf_id = 0;
7930   u8 is_ipv6 = 0;
7931   u8 vrf_id_set = 0;
7932   u8 src = 0;
7933   u8 dst = 0;
7934   u8 sport = 0;
7935   u8 dport = 0;
7936   u8 proto = 0;
7937   u8 reverse = 0;
7938
7939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7940     {
7941       if (unformat (i, "vrf %d", &vrf_id))
7942         vrf_id_set = 1;
7943       else if (unformat (i, "ipv6"))
7944         is_ipv6 = 1;
7945       else if (unformat (i, "src"))
7946         src = 1;
7947       else if (unformat (i, "dst"))
7948         dst = 1;
7949       else if (unformat (i, "sport"))
7950         sport = 1;
7951       else if (unformat (i, "dport"))
7952         dport = 1;
7953       else if (unformat (i, "proto"))
7954         proto = 1;
7955       else if (unformat (i, "reverse"))
7956         reverse = 1;
7957
7958       else
7959         {
7960           clib_warning ("parse error '%U'", format_unformat_error, i);
7961           return -99;
7962         }
7963     }
7964
7965   if (vrf_id_set == 0)
7966     {
7967       errmsg ("missing vrf id");
7968       return -99;
7969     }
7970
7971   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7972   mp->src = src;
7973   mp->dst = dst;
7974   mp->sport = sport;
7975   mp->dport = dport;
7976   mp->proto = proto;
7977   mp->reverse = reverse;
7978   mp->vrf_id = ntohl (vrf_id);
7979   mp->is_ipv6 = is_ipv6;
7980
7981   S;
7982   W;
7983   /* NOTREACHED */
7984   return 0;
7985 }
7986
7987 static int
7988 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7989 {
7990   unformat_input_t *i = vam->input;
7991   vl_api_sw_interface_ip6_enable_disable_t *mp;
7992   f64 timeout;
7993   u32 sw_if_index;
7994   u8 sw_if_index_set = 0;
7995   u8 enable = 0;
7996
7997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7998     {
7999       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8000         sw_if_index_set = 1;
8001       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8002         sw_if_index_set = 1;
8003       else if (unformat (i, "enable"))
8004         enable = 1;
8005       else if (unformat (i, "disable"))
8006         enable = 0;
8007       else
8008         {
8009           clib_warning ("parse error '%U'", format_unformat_error, i);
8010           return -99;
8011         }
8012     }
8013
8014   if (sw_if_index_set == 0)
8015     {
8016       errmsg ("missing interface name or sw_if_index");
8017       return -99;
8018     }
8019
8020   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
8021
8022   mp->sw_if_index = ntohl (sw_if_index);
8023   mp->enable = enable;
8024
8025   S;
8026   W;
8027   /* NOTREACHED */
8028   return 0;
8029 }
8030
8031 static int
8032 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8033 {
8034   unformat_input_t *i = vam->input;
8035   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8036   f64 timeout;
8037   u32 sw_if_index;
8038   u8 sw_if_index_set = 0;
8039   u8 v6_address_set = 0;
8040   ip6_address_t v6address;
8041
8042   /* Parse args required to build the message */
8043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8044     {
8045       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8046         sw_if_index_set = 1;
8047       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8048         sw_if_index_set = 1;
8049       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8050         v6_address_set = 1;
8051       else
8052         break;
8053     }
8054
8055   if (sw_if_index_set == 0)
8056     {
8057       errmsg ("missing interface name or sw_if_index");
8058       return -99;
8059     }
8060   if (!v6_address_set)
8061     {
8062       errmsg ("no address set");
8063       return -99;
8064     }
8065
8066   /* Construct the API message */
8067   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
8068      sw_interface_ip6_set_link_local_address);
8069
8070   mp->sw_if_index = ntohl (sw_if_index);
8071   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8072
8073   /* send it... */
8074   S;
8075
8076   /* Wait for a reply, return good/bad news  */
8077   W;
8078
8079   /* NOTREACHED */
8080   return 0;
8081 }
8082
8083
8084 static int
8085 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8086 {
8087   unformat_input_t *i = vam->input;
8088   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8089   f64 timeout;
8090   u32 sw_if_index;
8091   u8 sw_if_index_set = 0;
8092   u32 address_length = 0;
8093   u8 v6_address_set = 0;
8094   ip6_address_t v6address;
8095   u8 use_default = 0;
8096   u8 no_advertise = 0;
8097   u8 off_link = 0;
8098   u8 no_autoconfig = 0;
8099   u8 no_onlink = 0;
8100   u8 is_no = 0;
8101   u32 val_lifetime = 0;
8102   u32 pref_lifetime = 0;
8103
8104   /* Parse args required to build the message */
8105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8106     {
8107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8108         sw_if_index_set = 1;
8109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8110         sw_if_index_set = 1;
8111       else if (unformat (i, "%U/%d",
8112                          unformat_ip6_address, &v6address, &address_length))
8113         v6_address_set = 1;
8114       else if (unformat (i, "val_life %d", &val_lifetime))
8115         ;
8116       else if (unformat (i, "pref_life %d", &pref_lifetime))
8117         ;
8118       else if (unformat (i, "def"))
8119         use_default = 1;
8120       else if (unformat (i, "noadv"))
8121         no_advertise = 1;
8122       else if (unformat (i, "offl"))
8123         off_link = 1;
8124       else if (unformat (i, "noauto"))
8125         no_autoconfig = 1;
8126       else if (unformat (i, "nolink"))
8127         no_onlink = 1;
8128       else if (unformat (i, "isno"))
8129         is_no = 1;
8130       else
8131         {
8132           clib_warning ("parse error '%U'", format_unformat_error, i);
8133           return -99;
8134         }
8135     }
8136
8137   if (sw_if_index_set == 0)
8138     {
8139       errmsg ("missing interface name or sw_if_index");
8140       return -99;
8141     }
8142   if (!v6_address_set)
8143     {
8144       errmsg ("no address set");
8145       return -99;
8146     }
8147
8148   /* Construct the API message */
8149   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
8150
8151   mp->sw_if_index = ntohl (sw_if_index);
8152   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8153   mp->address_length = address_length;
8154   mp->use_default = use_default;
8155   mp->no_advertise = no_advertise;
8156   mp->off_link = off_link;
8157   mp->no_autoconfig = no_autoconfig;
8158   mp->no_onlink = no_onlink;
8159   mp->is_no = is_no;
8160   mp->val_lifetime = ntohl (val_lifetime);
8161   mp->pref_lifetime = ntohl (pref_lifetime);
8162
8163   /* send it... */
8164   S;
8165
8166   /* Wait for a reply, return good/bad news  */
8167   W;
8168
8169   /* NOTREACHED */
8170   return 0;
8171 }
8172
8173 static int
8174 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8175 {
8176   unformat_input_t *i = vam->input;
8177   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8178   f64 timeout;
8179   u32 sw_if_index;
8180   u8 sw_if_index_set = 0;
8181   u8 suppress = 0;
8182   u8 managed = 0;
8183   u8 other = 0;
8184   u8 ll_option = 0;
8185   u8 send_unicast = 0;
8186   u8 cease = 0;
8187   u8 is_no = 0;
8188   u8 default_router = 0;
8189   u32 max_interval = 0;
8190   u32 min_interval = 0;
8191   u32 lifetime = 0;
8192   u32 initial_count = 0;
8193   u32 initial_interval = 0;
8194
8195
8196   /* Parse args required to build the message */
8197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8198     {
8199       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8200         sw_if_index_set = 1;
8201       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8202         sw_if_index_set = 1;
8203       else if (unformat (i, "maxint %d", &max_interval))
8204         ;
8205       else if (unformat (i, "minint %d", &min_interval))
8206         ;
8207       else if (unformat (i, "life %d", &lifetime))
8208         ;
8209       else if (unformat (i, "count %d", &initial_count))
8210         ;
8211       else if (unformat (i, "interval %d", &initial_interval))
8212         ;
8213       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8214         suppress = 1;
8215       else if (unformat (i, "managed"))
8216         managed = 1;
8217       else if (unformat (i, "other"))
8218         other = 1;
8219       else if (unformat (i, "ll"))
8220         ll_option = 1;
8221       else if (unformat (i, "send"))
8222         send_unicast = 1;
8223       else if (unformat (i, "cease"))
8224         cease = 1;
8225       else if (unformat (i, "isno"))
8226         is_no = 1;
8227       else if (unformat (i, "def"))
8228         default_router = 1;
8229       else
8230         {
8231           clib_warning ("parse error '%U'", format_unformat_error, i);
8232           return -99;
8233         }
8234     }
8235
8236   if (sw_if_index_set == 0)
8237     {
8238       errmsg ("missing interface name or sw_if_index");
8239       return -99;
8240     }
8241
8242   /* Construct the API message */
8243   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
8244
8245   mp->sw_if_index = ntohl (sw_if_index);
8246   mp->max_interval = ntohl (max_interval);
8247   mp->min_interval = ntohl (min_interval);
8248   mp->lifetime = ntohl (lifetime);
8249   mp->initial_count = ntohl (initial_count);
8250   mp->initial_interval = ntohl (initial_interval);
8251   mp->suppress = suppress;
8252   mp->managed = managed;
8253   mp->other = other;
8254   mp->ll_option = ll_option;
8255   mp->send_unicast = send_unicast;
8256   mp->cease = cease;
8257   mp->is_no = is_no;
8258   mp->default_router = default_router;
8259
8260   /* send it... */
8261   S;
8262
8263   /* Wait for a reply, return good/bad news  */
8264   W;
8265
8266   /* NOTREACHED */
8267   return 0;
8268 }
8269
8270 static int
8271 api_set_arp_neighbor_limit (vat_main_t * vam)
8272 {
8273   unformat_input_t *i = vam->input;
8274   vl_api_set_arp_neighbor_limit_t *mp;
8275   f64 timeout;
8276   u32 arp_nbr_limit;
8277   u8 limit_set = 0;
8278   u8 is_ipv6 = 0;
8279
8280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8281     {
8282       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8283         limit_set = 1;
8284       else if (unformat (i, "ipv6"))
8285         is_ipv6 = 1;
8286       else
8287         {
8288           clib_warning ("parse error '%U'", format_unformat_error, i);
8289           return -99;
8290         }
8291     }
8292
8293   if (limit_set == 0)
8294     {
8295       errmsg ("missing limit value");
8296       return -99;
8297     }
8298
8299   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
8300
8301   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8302   mp->is_ipv6 = is_ipv6;
8303
8304   S;
8305   W;
8306   /* NOTREACHED */
8307   return 0;
8308 }
8309
8310 static int
8311 api_l2_patch_add_del (vat_main_t * vam)
8312 {
8313   unformat_input_t *i = vam->input;
8314   vl_api_l2_patch_add_del_t *mp;
8315   f64 timeout;
8316   u32 rx_sw_if_index;
8317   u8 rx_sw_if_index_set = 0;
8318   u32 tx_sw_if_index;
8319   u8 tx_sw_if_index_set = 0;
8320   u8 is_add = 1;
8321
8322   /* Parse args required to build the message */
8323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8324     {
8325       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8326         rx_sw_if_index_set = 1;
8327       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8328         tx_sw_if_index_set = 1;
8329       else if (unformat (i, "rx"))
8330         {
8331           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8332             {
8333               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8334                             &rx_sw_if_index))
8335                 rx_sw_if_index_set = 1;
8336             }
8337           else
8338             break;
8339         }
8340       else if (unformat (i, "tx"))
8341         {
8342           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8343             {
8344               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8345                             &tx_sw_if_index))
8346                 tx_sw_if_index_set = 1;
8347             }
8348           else
8349             break;
8350         }
8351       else if (unformat (i, "del"))
8352         is_add = 0;
8353       else
8354         break;
8355     }
8356
8357   if (rx_sw_if_index_set == 0)
8358     {
8359       errmsg ("missing rx interface name or rx_sw_if_index");
8360       return -99;
8361     }
8362
8363   if (tx_sw_if_index_set == 0)
8364     {
8365       errmsg ("missing tx interface name or tx_sw_if_index");
8366       return -99;
8367     }
8368
8369   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
8370
8371   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8372   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8373   mp->is_add = is_add;
8374
8375   S;
8376   W;
8377   /* NOTREACHED */
8378   return 0;
8379 }
8380
8381 static int
8382 api_ioam_enable (vat_main_t * vam)
8383 {
8384   unformat_input_t *input = vam->input;
8385   vl_api_ioam_enable_t *mp;
8386   f64 timeout;
8387   u32 id = 0;
8388   int has_trace_option = 0;
8389   int has_pot_option = 0;
8390   int has_seqno_option = 0;
8391   int has_analyse_option = 0;
8392
8393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8394     {
8395       if (unformat (input, "trace"))
8396         has_trace_option = 1;
8397       else if (unformat (input, "pot"))
8398         has_pot_option = 1;
8399       else if (unformat (input, "seqno"))
8400         has_seqno_option = 1;
8401       else if (unformat (input, "analyse"))
8402         has_analyse_option = 1;
8403       else
8404         break;
8405     }
8406   M (IOAM_ENABLE, ioam_enable);
8407   mp->id = htons (id);
8408   mp->seqno = has_seqno_option;
8409   mp->analyse = has_analyse_option;
8410   mp->pot_enable = has_pot_option;
8411   mp->trace_enable = has_trace_option;
8412
8413   S;
8414   W;
8415
8416   return (0);
8417
8418 }
8419
8420
8421 static int
8422 api_ioam_disable (vat_main_t * vam)
8423 {
8424   vl_api_ioam_disable_t *mp;
8425   f64 timeout;
8426
8427   M (IOAM_DISABLE, ioam_disable);
8428   S;
8429   W;
8430   return 0;
8431 }
8432
8433 static int
8434 api_sr_tunnel_add_del (vat_main_t * vam)
8435 {
8436   unformat_input_t *i = vam->input;
8437   vl_api_sr_tunnel_add_del_t *mp;
8438   f64 timeout;
8439   int is_del = 0;
8440   int pl_index;
8441   ip6_address_t src_address;
8442   int src_address_set = 0;
8443   ip6_address_t dst_address;
8444   u32 dst_mask_width;
8445   int dst_address_set = 0;
8446   u16 flags = 0;
8447   u32 rx_table_id = 0;
8448   u32 tx_table_id = 0;
8449   ip6_address_t *segments = 0;
8450   ip6_address_t *this_seg;
8451   ip6_address_t *tags = 0;
8452   ip6_address_t *this_tag;
8453   ip6_address_t next_address, tag;
8454   u8 *name = 0;
8455   u8 *policy_name = 0;
8456
8457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8458     {
8459       if (unformat (i, "del"))
8460         is_del = 1;
8461       else if (unformat (i, "name %s", &name))
8462         ;
8463       else if (unformat (i, "policy %s", &policy_name))
8464         ;
8465       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8466         ;
8467       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8468         ;
8469       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8470         src_address_set = 1;
8471       else if (unformat (i, "dst %U/%d",
8472                          unformat_ip6_address, &dst_address, &dst_mask_width))
8473         dst_address_set = 1;
8474       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8475         {
8476           vec_add2 (segments, this_seg, 1);
8477           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8478                        sizeof (*this_seg));
8479         }
8480       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8481         {
8482           vec_add2 (tags, this_tag, 1);
8483           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8484         }
8485       else if (unformat (i, "clean"))
8486         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8487       else if (unformat (i, "protected"))
8488         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8489       else if (unformat (i, "InPE %d", &pl_index))
8490         {
8491           if (pl_index <= 0 || pl_index > 4)
8492             {
8493             pl_index_range_error:
8494               errmsg ("pl index %d out of range", pl_index);
8495               return -99;
8496             }
8497           flags |=
8498             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8499         }
8500       else if (unformat (i, "EgPE %d", &pl_index))
8501         {
8502           if (pl_index <= 0 || pl_index > 4)
8503             goto pl_index_range_error;
8504           flags |=
8505             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8506         }
8507       else if (unformat (i, "OrgSrc %d", &pl_index))
8508         {
8509           if (pl_index <= 0 || pl_index > 4)
8510             goto pl_index_range_error;
8511           flags |=
8512             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8513         }
8514       else
8515         break;
8516     }
8517
8518   if (!src_address_set)
8519     {
8520       errmsg ("src address required");
8521       return -99;
8522     }
8523
8524   if (!dst_address_set)
8525     {
8526       errmsg ("dst address required");
8527       return -99;
8528     }
8529
8530   if (!segments)
8531     {
8532       errmsg ("at least one sr segment required");
8533       return -99;
8534     }
8535
8536   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8537       vec_len (segments) * sizeof (ip6_address_t)
8538       + vec_len (tags) * sizeof (ip6_address_t));
8539
8540   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8541   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8542   mp->dst_mask_width = dst_mask_width;
8543   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8544   mp->n_segments = vec_len (segments);
8545   mp->n_tags = vec_len (tags);
8546   mp->is_add = is_del == 0;
8547   clib_memcpy (mp->segs_and_tags, segments,
8548                vec_len (segments) * sizeof (ip6_address_t));
8549   clib_memcpy (mp->segs_and_tags +
8550                vec_len (segments) * sizeof (ip6_address_t), tags,
8551                vec_len (tags) * sizeof (ip6_address_t));
8552
8553   mp->outer_vrf_id = ntohl (rx_table_id);
8554   mp->inner_vrf_id = ntohl (tx_table_id);
8555   memcpy (mp->name, name, vec_len (name));
8556   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8557
8558   vec_free (segments);
8559   vec_free (tags);
8560
8561   S;
8562   W;
8563   /* NOTREACHED */
8564 }
8565
8566 static int
8567 api_sr_policy_add_del (vat_main_t * vam)
8568 {
8569   unformat_input_t *input = vam->input;
8570   vl_api_sr_policy_add_del_t *mp;
8571   f64 timeout;
8572   int is_del = 0;
8573   u8 *name = 0;
8574   u8 *tunnel_name = 0;
8575   u8 **tunnel_names = 0;
8576
8577   int name_set = 0;
8578   int tunnel_set = 0;
8579   int j = 0;
8580   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8581   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8582
8583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8584     {
8585       if (unformat (input, "del"))
8586         is_del = 1;
8587       else if (unformat (input, "name %s", &name))
8588         name_set = 1;
8589       else if (unformat (input, "tunnel %s", &tunnel_name))
8590         {
8591           if (tunnel_name)
8592             {
8593               vec_add1 (tunnel_names, tunnel_name);
8594               /* For serializer:
8595                  - length = #bytes to store in serial vector
8596                  - +1 = byte to store that length
8597                */
8598               tunnel_names_length += (vec_len (tunnel_name) + 1);
8599               tunnel_set = 1;
8600               tunnel_name = 0;
8601             }
8602         }
8603       else
8604         break;
8605     }
8606
8607   if (!name_set)
8608     {
8609       errmsg ("policy name required");
8610       return -99;
8611     }
8612
8613   if ((!tunnel_set) && (!is_del))
8614     {
8615       errmsg ("tunnel name required");
8616       return -99;
8617     }
8618
8619   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8620
8621
8622
8623   mp->is_add = !is_del;
8624
8625   memcpy (mp->name, name, vec_len (name));
8626   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8627   u8 *serial_orig = 0;
8628   vec_validate (serial_orig, tunnel_names_length);
8629   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8630   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8631
8632   for (j = 0; j < vec_len (tunnel_names); j++)
8633     {
8634       tun_name_len = vec_len (tunnel_names[j]);
8635       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8636       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8637       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8638       serial_orig += tun_name_len;      // Advance past the copy
8639     }
8640   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8641
8642   vec_free (tunnel_names);
8643   vec_free (tunnel_name);
8644
8645   S;
8646   W;
8647   /* NOTREACHED */
8648 }
8649
8650 static int
8651 api_sr_multicast_map_add_del (vat_main_t * vam)
8652 {
8653   unformat_input_t *input = vam->input;
8654   vl_api_sr_multicast_map_add_del_t *mp;
8655   f64 timeout;
8656   int is_del = 0;
8657   ip6_address_t multicast_address;
8658   u8 *policy_name = 0;
8659   int multicast_address_set = 0;
8660
8661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8662     {
8663       if (unformat (input, "del"))
8664         is_del = 1;
8665       else
8666         if (unformat
8667             (input, "address %U", unformat_ip6_address, &multicast_address))
8668         multicast_address_set = 1;
8669       else if (unformat (input, "sr-policy %s", &policy_name))
8670         ;
8671       else
8672         break;
8673     }
8674
8675   if (!is_del && !policy_name)
8676     {
8677       errmsg ("sr-policy name required");
8678       return -99;
8679     }
8680
8681
8682   if (!multicast_address_set)
8683     {
8684       errmsg ("address required");
8685       return -99;
8686     }
8687
8688   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8689
8690   mp->is_add = !is_del;
8691   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8692   clib_memcpy (mp->multicast_address, &multicast_address,
8693                sizeof (mp->multicast_address));
8694
8695
8696   vec_free (policy_name);
8697
8698   S;
8699   W;
8700   /* NOTREACHED */
8701 }
8702
8703
8704 #define foreach_tcp_proto_field                 \
8705 _(src_port)                                     \
8706 _(dst_port)
8707
8708 #define foreach_udp_proto_field                 \
8709 _(src_port)                                     \
8710 _(dst_port)
8711
8712 #define foreach_ip4_proto_field                 \
8713 _(src_address)                                  \
8714 _(dst_address)                                  \
8715 _(tos)                                          \
8716 _(length)                                       \
8717 _(fragment_id)                                  \
8718 _(ttl)                                          \
8719 _(protocol)                                     \
8720 _(checksum)
8721
8722 uword
8723 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8724 {
8725   u8 **maskp = va_arg (*args, u8 **);
8726   u8 *mask = 0;
8727   u8 found_something = 0;
8728   tcp_header_t *tcp;
8729
8730 #define _(a) u8 a=0;
8731   foreach_tcp_proto_field;
8732 #undef _
8733
8734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8735     {
8736       if (0);
8737 #define _(a) else if (unformat (input, #a)) a=1;
8738       foreach_tcp_proto_field
8739 #undef _
8740         else
8741         break;
8742     }
8743
8744 #define _(a) found_something += a;
8745   foreach_tcp_proto_field;
8746 #undef _
8747
8748   if (found_something == 0)
8749     return 0;
8750
8751   vec_validate (mask, sizeof (*tcp) - 1);
8752
8753   tcp = (tcp_header_t *) mask;
8754
8755 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8756   foreach_tcp_proto_field;
8757 #undef _
8758
8759   *maskp = mask;
8760   return 1;
8761 }
8762
8763 uword
8764 unformat_udp_mask (unformat_input_t * input, va_list * args)
8765 {
8766   u8 **maskp = va_arg (*args, u8 **);
8767   u8 *mask = 0;
8768   u8 found_something = 0;
8769   udp_header_t *udp;
8770
8771 #define _(a) u8 a=0;
8772   foreach_udp_proto_field;
8773 #undef _
8774
8775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8776     {
8777       if (0);
8778 #define _(a) else if (unformat (input, #a)) a=1;
8779       foreach_udp_proto_field
8780 #undef _
8781         else
8782         break;
8783     }
8784
8785 #define _(a) found_something += a;
8786   foreach_udp_proto_field;
8787 #undef _
8788
8789   if (found_something == 0)
8790     return 0;
8791
8792   vec_validate (mask, sizeof (*udp) - 1);
8793
8794   udp = (udp_header_t *) mask;
8795
8796 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8797   foreach_udp_proto_field;
8798 #undef _
8799
8800   *maskp = mask;
8801   return 1;
8802 }
8803
8804 typedef struct
8805 {
8806   u16 src_port, dst_port;
8807 } tcpudp_header_t;
8808
8809 uword
8810 unformat_l4_mask (unformat_input_t * input, va_list * args)
8811 {
8812   u8 **maskp = va_arg (*args, u8 **);
8813   u16 src_port = 0, dst_port = 0;
8814   tcpudp_header_t *tcpudp;
8815
8816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8817     {
8818       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8819         return 1;
8820       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8821         return 1;
8822       else if (unformat (input, "src_port"))
8823         src_port = 0xFFFF;
8824       else if (unformat (input, "dst_port"))
8825         dst_port = 0xFFFF;
8826       else
8827         return 0;
8828     }
8829
8830   if (!src_port && !dst_port)
8831     return 0;
8832
8833   u8 *mask = 0;
8834   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8835
8836   tcpudp = (tcpudp_header_t *) mask;
8837   tcpudp->src_port = src_port;
8838   tcpudp->dst_port = dst_port;
8839
8840   *maskp = mask;
8841
8842   return 1;
8843 }
8844
8845 uword
8846 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8847 {
8848   u8 **maskp = va_arg (*args, u8 **);
8849   u8 *mask = 0;
8850   u8 found_something = 0;
8851   ip4_header_t *ip;
8852
8853 #define _(a) u8 a=0;
8854   foreach_ip4_proto_field;
8855 #undef _
8856   u8 version = 0;
8857   u8 hdr_length = 0;
8858
8859
8860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8861     {
8862       if (unformat (input, "version"))
8863         version = 1;
8864       else if (unformat (input, "hdr_length"))
8865         hdr_length = 1;
8866       else if (unformat (input, "src"))
8867         src_address = 1;
8868       else if (unformat (input, "dst"))
8869         dst_address = 1;
8870       else if (unformat (input, "proto"))
8871         protocol = 1;
8872
8873 #define _(a) else if (unformat (input, #a)) a=1;
8874       foreach_ip4_proto_field
8875 #undef _
8876         else
8877         break;
8878     }
8879
8880 #define _(a) found_something += a;
8881   foreach_ip4_proto_field;
8882 #undef _
8883
8884   if (found_something == 0)
8885     return 0;
8886
8887   vec_validate (mask, sizeof (*ip) - 1);
8888
8889   ip = (ip4_header_t *) mask;
8890
8891 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8892   foreach_ip4_proto_field;
8893 #undef _
8894
8895   ip->ip_version_and_header_length = 0;
8896
8897   if (version)
8898     ip->ip_version_and_header_length |= 0xF0;
8899
8900   if (hdr_length)
8901     ip->ip_version_and_header_length |= 0x0F;
8902
8903   *maskp = mask;
8904   return 1;
8905 }
8906
8907 #define foreach_ip6_proto_field                 \
8908 _(src_address)                                  \
8909 _(dst_address)                                  \
8910 _(payload_length)                               \
8911 _(hop_limit)                                    \
8912 _(protocol)
8913
8914 uword
8915 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8916 {
8917   u8 **maskp = va_arg (*args, u8 **);
8918   u8 *mask = 0;
8919   u8 found_something = 0;
8920   ip6_header_t *ip;
8921   u32 ip_version_traffic_class_and_flow_label;
8922
8923 #define _(a) u8 a=0;
8924   foreach_ip6_proto_field;
8925 #undef _
8926   u8 version = 0;
8927   u8 traffic_class = 0;
8928   u8 flow_label = 0;
8929
8930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8931     {
8932       if (unformat (input, "version"))
8933         version = 1;
8934       else if (unformat (input, "traffic-class"))
8935         traffic_class = 1;
8936       else if (unformat (input, "flow-label"))
8937         flow_label = 1;
8938       else if (unformat (input, "src"))
8939         src_address = 1;
8940       else if (unformat (input, "dst"))
8941         dst_address = 1;
8942       else if (unformat (input, "proto"))
8943         protocol = 1;
8944
8945 #define _(a) else if (unformat (input, #a)) a=1;
8946       foreach_ip6_proto_field
8947 #undef _
8948         else
8949         break;
8950     }
8951
8952 #define _(a) found_something += a;
8953   foreach_ip6_proto_field;
8954 #undef _
8955
8956   if (found_something == 0)
8957     return 0;
8958
8959   vec_validate (mask, sizeof (*ip) - 1);
8960
8961   ip = (ip6_header_t *) mask;
8962
8963 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8964   foreach_ip6_proto_field;
8965 #undef _
8966
8967   ip_version_traffic_class_and_flow_label = 0;
8968
8969   if (version)
8970     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8971
8972   if (traffic_class)
8973     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8974
8975   if (flow_label)
8976     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8977
8978   ip->ip_version_traffic_class_and_flow_label =
8979     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8980
8981   *maskp = mask;
8982   return 1;
8983 }
8984
8985 uword
8986 unformat_l3_mask (unformat_input_t * input, va_list * args)
8987 {
8988   u8 **maskp = va_arg (*args, u8 **);
8989
8990   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8991     {
8992       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8993         return 1;
8994       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8995         return 1;
8996       else
8997         break;
8998     }
8999   return 0;
9000 }
9001
9002 uword
9003 unformat_l2_mask (unformat_input_t * input, va_list * args)
9004 {
9005   u8 **maskp = va_arg (*args, u8 **);
9006   u8 *mask = 0;
9007   u8 src = 0;
9008   u8 dst = 0;
9009   u8 proto = 0;
9010   u8 tag1 = 0;
9011   u8 tag2 = 0;
9012   u8 ignore_tag1 = 0;
9013   u8 ignore_tag2 = 0;
9014   u8 cos1 = 0;
9015   u8 cos2 = 0;
9016   u8 dot1q = 0;
9017   u8 dot1ad = 0;
9018   int len = 14;
9019
9020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9021     {
9022       if (unformat (input, "src"))
9023         src = 1;
9024       else if (unformat (input, "dst"))
9025         dst = 1;
9026       else if (unformat (input, "proto"))
9027         proto = 1;
9028       else if (unformat (input, "tag1"))
9029         tag1 = 1;
9030       else if (unformat (input, "tag2"))
9031         tag2 = 1;
9032       else if (unformat (input, "ignore-tag1"))
9033         ignore_tag1 = 1;
9034       else if (unformat (input, "ignore-tag2"))
9035         ignore_tag2 = 1;
9036       else if (unformat (input, "cos1"))
9037         cos1 = 1;
9038       else if (unformat (input, "cos2"))
9039         cos2 = 1;
9040       else if (unformat (input, "dot1q"))
9041         dot1q = 1;
9042       else if (unformat (input, "dot1ad"))
9043         dot1ad = 1;
9044       else
9045         break;
9046     }
9047   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9048        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9049     return 0;
9050
9051   if (tag1 || ignore_tag1 || cos1 || dot1q)
9052     len = 18;
9053   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9054     len = 22;
9055
9056   vec_validate (mask, len - 1);
9057
9058   if (dst)
9059     memset (mask, 0xff, 6);
9060
9061   if (src)
9062     memset (mask + 6, 0xff, 6);
9063
9064   if (tag2 || dot1ad)
9065     {
9066       /* inner vlan tag */
9067       if (tag2)
9068         {
9069           mask[19] = 0xff;
9070           mask[18] = 0x0f;
9071         }
9072       if (cos2)
9073         mask[18] |= 0xe0;
9074       if (proto)
9075         mask[21] = mask[20] = 0xff;
9076       if (tag1)
9077         {
9078           mask[15] = 0xff;
9079           mask[14] = 0x0f;
9080         }
9081       if (cos1)
9082         mask[14] |= 0xe0;
9083       *maskp = mask;
9084       return 1;
9085     }
9086   if (tag1 | dot1q)
9087     {
9088       if (tag1)
9089         {
9090           mask[15] = 0xff;
9091           mask[14] = 0x0f;
9092         }
9093       if (cos1)
9094         mask[14] |= 0xe0;
9095       if (proto)
9096         mask[16] = mask[17] = 0xff;
9097
9098       *maskp = mask;
9099       return 1;
9100     }
9101   if (cos2)
9102     mask[18] |= 0xe0;
9103   if (cos1)
9104     mask[14] |= 0xe0;
9105   if (proto)
9106     mask[12] = mask[13] = 0xff;
9107
9108   *maskp = mask;
9109   return 1;
9110 }
9111
9112 uword
9113 unformat_classify_mask (unformat_input_t * input, va_list * args)
9114 {
9115   u8 **maskp = va_arg (*args, u8 **);
9116   u32 *skipp = va_arg (*args, u32 *);
9117   u32 *matchp = va_arg (*args, u32 *);
9118   u32 match;
9119   u8 *mask = 0;
9120   u8 *l2 = 0;
9121   u8 *l3 = 0;
9122   u8 *l4 = 0;
9123   int i;
9124
9125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9126     {
9127       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9128         ;
9129       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9130         ;
9131       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9132         ;
9133       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9134         ;
9135       else
9136         break;
9137     }
9138
9139   if (l4 && !l3)
9140     {
9141       vec_free (mask);
9142       vec_free (l2);
9143       vec_free (l4);
9144       return 0;
9145     }
9146
9147   if (mask || l2 || l3 || l4)
9148     {
9149       if (l2 || l3 || l4)
9150         {
9151           /* "With a free Ethernet header in every package" */
9152           if (l2 == 0)
9153             vec_validate (l2, 13);
9154           mask = l2;
9155           if (vec_len (l3))
9156             {
9157               vec_append (mask, l3);
9158               vec_free (l3);
9159             }
9160           if (vec_len (l4))
9161             {
9162               vec_append (mask, l4);
9163               vec_free (l4);
9164             }
9165         }
9166
9167       /* Scan forward looking for the first significant mask octet */
9168       for (i = 0; i < vec_len (mask); i++)
9169         if (mask[i])
9170           break;
9171
9172       /* compute (skip, match) params */
9173       *skipp = i / sizeof (u32x4);
9174       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9175
9176       /* Pad mask to an even multiple of the vector size */
9177       while (vec_len (mask) % sizeof (u32x4))
9178         vec_add1 (mask, 0);
9179
9180       match = vec_len (mask) / sizeof (u32x4);
9181
9182       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9183         {
9184           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9185           if (*tmp || *(tmp + 1))
9186             break;
9187           match--;
9188         }
9189       if (match == 0)
9190         clib_warning ("BUG: match 0");
9191
9192       _vec_len (mask) = match * sizeof (u32x4);
9193
9194       *matchp = match;
9195       *maskp = mask;
9196
9197       return 1;
9198     }
9199
9200   return 0;
9201 }
9202
9203 #define foreach_l2_next                         \
9204 _(drop, DROP)                                   \
9205 _(ethernet, ETHERNET_INPUT)                     \
9206 _(ip4, IP4_INPUT)                               \
9207 _(ip6, IP6_INPUT)
9208
9209 uword
9210 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9211 {
9212   u32 *miss_next_indexp = va_arg (*args, u32 *);
9213   u32 next_index = 0;
9214   u32 tmp;
9215
9216 #define _(n,N) \
9217   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9218   foreach_l2_next;
9219 #undef _
9220
9221   if (unformat (input, "%d", &tmp))
9222     {
9223       next_index = tmp;
9224       goto out;
9225     }
9226
9227   return 0;
9228
9229 out:
9230   *miss_next_indexp = next_index;
9231   return 1;
9232 }
9233
9234 #define foreach_ip_next                         \
9235 _(drop, DROP)                                   \
9236 _(local, LOCAL)                                 \
9237 _(rewrite, REWRITE)
9238
9239 uword
9240 unformat_ip_next_index (unformat_input_t * input, va_list * args)
9241 {
9242   u32 *miss_next_indexp = va_arg (*args, u32 *);
9243   u32 next_index = 0;
9244   u32 tmp;
9245
9246 #define _(n,N) \
9247   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9248   foreach_ip_next;
9249 #undef _
9250
9251   if (unformat (input, "%d", &tmp))
9252     {
9253       next_index = tmp;
9254       goto out;
9255     }
9256
9257   return 0;
9258
9259 out:
9260   *miss_next_indexp = next_index;
9261   return 1;
9262 }
9263
9264 #define foreach_acl_next                        \
9265 _(deny, DENY)
9266
9267 uword
9268 unformat_acl_next_index (unformat_input_t * input, va_list * args)
9269 {
9270   u32 *miss_next_indexp = va_arg (*args, u32 *);
9271   u32 next_index = 0;
9272   u32 tmp;
9273
9274 #define _(n,N) \
9275   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9276   foreach_acl_next;
9277 #undef _
9278
9279   if (unformat (input, "permit"))
9280     {
9281       next_index = ~0;
9282       goto out;
9283     }
9284   else if (unformat (input, "%d", &tmp))
9285     {
9286       next_index = tmp;
9287       goto out;
9288     }
9289
9290   return 0;
9291
9292 out:
9293   *miss_next_indexp = next_index;
9294   return 1;
9295 }
9296
9297 uword
9298 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9299 {
9300   u32 *r = va_arg (*args, u32 *);
9301
9302   if (unformat (input, "conform-color"))
9303     *r = POLICE_CONFORM;
9304   else if (unformat (input, "exceed-color"))
9305     *r = POLICE_EXCEED;
9306   else
9307     return 0;
9308
9309   return 1;
9310 }
9311
9312 static int
9313 api_classify_add_del_table (vat_main_t * vam)
9314 {
9315   unformat_input_t *i = vam->input;
9316   vl_api_classify_add_del_table_t *mp;
9317
9318   u32 nbuckets = 2;
9319   u32 skip = ~0;
9320   u32 match = ~0;
9321   int is_add = 1;
9322   int del_chain = 0;
9323   u32 table_index = ~0;
9324   u32 next_table_index = ~0;
9325   u32 miss_next_index = ~0;
9326   u32 memory_size = 32 << 20;
9327   u8 *mask = 0;
9328   f64 timeout;
9329   u32 current_data_flag = 0;
9330   int current_data_offset = 0;
9331
9332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9333     {
9334       if (unformat (i, "del"))
9335         is_add = 0;
9336       else if (unformat (i, "del-chain"))
9337         {
9338           is_add = 0;
9339           del_chain = 1;
9340         }
9341       else if (unformat (i, "buckets %d", &nbuckets))
9342         ;
9343       else if (unformat (i, "memory_size %d", &memory_size))
9344         ;
9345       else if (unformat (i, "skip %d", &skip))
9346         ;
9347       else if (unformat (i, "match %d", &match))
9348         ;
9349       else if (unformat (i, "table %d", &table_index))
9350         ;
9351       else if (unformat (i, "mask %U", unformat_classify_mask,
9352                          &mask, &skip, &match))
9353         ;
9354       else if (unformat (i, "next-table %d", &next_table_index))
9355         ;
9356       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
9357                          &miss_next_index))
9358         ;
9359       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9360                          &miss_next_index))
9361         ;
9362       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9363                          &miss_next_index))
9364         ;
9365       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9366         ;
9367       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9368         ;
9369       else
9370         break;
9371     }
9372
9373   if (is_add && mask == 0)
9374     {
9375       errmsg ("Mask required");
9376       return -99;
9377     }
9378
9379   if (is_add && skip == ~0)
9380     {
9381       errmsg ("skip count required");
9382       return -99;
9383     }
9384
9385   if (is_add && match == ~0)
9386     {
9387       errmsg ("match count required");
9388       return -99;
9389     }
9390
9391   if (!is_add && table_index == ~0)
9392     {
9393       errmsg ("table index required for delete");
9394       return -99;
9395     }
9396
9397   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
9398
9399   mp->is_add = is_add;
9400   mp->del_chain = del_chain;
9401   mp->table_index = ntohl (table_index);
9402   mp->nbuckets = ntohl (nbuckets);
9403   mp->memory_size = ntohl (memory_size);
9404   mp->skip_n_vectors = ntohl (skip);
9405   mp->match_n_vectors = ntohl (match);
9406   mp->next_table_index = ntohl (next_table_index);
9407   mp->miss_next_index = ntohl (miss_next_index);
9408   mp->current_data_flag = ntohl (current_data_flag);
9409   mp->current_data_offset = ntohl (current_data_offset);
9410   clib_memcpy (mp->mask, mask, vec_len (mask));
9411
9412   vec_free (mask);
9413
9414   S;
9415   W;
9416   /* NOTREACHED */
9417 }
9418
9419 uword
9420 unformat_l4_match (unformat_input_t * input, va_list * args)
9421 {
9422   u8 **matchp = va_arg (*args, u8 **);
9423
9424   u8 *proto_header = 0;
9425   int src_port = 0;
9426   int dst_port = 0;
9427
9428   tcpudp_header_t h;
9429
9430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9431     {
9432       if (unformat (input, "src_port %d", &src_port))
9433         ;
9434       else if (unformat (input, "dst_port %d", &dst_port))
9435         ;
9436       else
9437         return 0;
9438     }
9439
9440   h.src_port = clib_host_to_net_u16 (src_port);
9441   h.dst_port = clib_host_to_net_u16 (dst_port);
9442   vec_validate (proto_header, sizeof (h) - 1);
9443   memcpy (proto_header, &h, sizeof (h));
9444
9445   *matchp = proto_header;
9446
9447   return 1;
9448 }
9449
9450 uword
9451 unformat_ip4_match (unformat_input_t * input, va_list * args)
9452 {
9453   u8 **matchp = va_arg (*args, u8 **);
9454   u8 *match = 0;
9455   ip4_header_t *ip;
9456   int version = 0;
9457   u32 version_val;
9458   int hdr_length = 0;
9459   u32 hdr_length_val;
9460   int src = 0, dst = 0;
9461   ip4_address_t src_val, dst_val;
9462   int proto = 0;
9463   u32 proto_val;
9464   int tos = 0;
9465   u32 tos_val;
9466   int length = 0;
9467   u32 length_val;
9468   int fragment_id = 0;
9469   u32 fragment_id_val;
9470   int ttl = 0;
9471   int ttl_val;
9472   int checksum = 0;
9473   u32 checksum_val;
9474
9475   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9476     {
9477       if (unformat (input, "version %d", &version_val))
9478         version = 1;
9479       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9480         hdr_length = 1;
9481       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9482         src = 1;
9483       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9484         dst = 1;
9485       else if (unformat (input, "proto %d", &proto_val))
9486         proto = 1;
9487       else if (unformat (input, "tos %d", &tos_val))
9488         tos = 1;
9489       else if (unformat (input, "length %d", &length_val))
9490         length = 1;
9491       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9492         fragment_id = 1;
9493       else if (unformat (input, "ttl %d", &ttl_val))
9494         ttl = 1;
9495       else if (unformat (input, "checksum %d", &checksum_val))
9496         checksum = 1;
9497       else
9498         break;
9499     }
9500
9501   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9502       + ttl + checksum == 0)
9503     return 0;
9504
9505   /*
9506    * Aligned because we use the real comparison functions
9507    */
9508   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9509
9510   ip = (ip4_header_t *) match;
9511
9512   /* These are realistically matched in practice */
9513   if (src)
9514     ip->src_address.as_u32 = src_val.as_u32;
9515
9516   if (dst)
9517     ip->dst_address.as_u32 = dst_val.as_u32;
9518
9519   if (proto)
9520     ip->protocol = proto_val;
9521
9522
9523   /* These are not, but they're included for completeness */
9524   if (version)
9525     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9526
9527   if (hdr_length)
9528     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9529
9530   if (tos)
9531     ip->tos = tos_val;
9532
9533   if (length)
9534     ip->length = clib_host_to_net_u16 (length_val);
9535
9536   if (ttl)
9537     ip->ttl = ttl_val;
9538
9539   if (checksum)
9540     ip->checksum = clib_host_to_net_u16 (checksum_val);
9541
9542   *matchp = match;
9543   return 1;
9544 }
9545
9546 uword
9547 unformat_ip6_match (unformat_input_t * input, va_list * args)
9548 {
9549   u8 **matchp = va_arg (*args, u8 **);
9550   u8 *match = 0;
9551   ip6_header_t *ip;
9552   int version = 0;
9553   u32 version_val;
9554   u8 traffic_class = 0;
9555   u32 traffic_class_val = 0;
9556   u8 flow_label = 0;
9557   u8 flow_label_val;
9558   int src = 0, dst = 0;
9559   ip6_address_t src_val, dst_val;
9560   int proto = 0;
9561   u32 proto_val;
9562   int payload_length = 0;
9563   u32 payload_length_val;
9564   int hop_limit = 0;
9565   int hop_limit_val;
9566   u32 ip_version_traffic_class_and_flow_label;
9567
9568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9569     {
9570       if (unformat (input, "version %d", &version_val))
9571         version = 1;
9572       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9573         traffic_class = 1;
9574       else if (unformat (input, "flow_label %d", &flow_label_val))
9575         flow_label = 1;
9576       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9577         src = 1;
9578       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9579         dst = 1;
9580       else if (unformat (input, "proto %d", &proto_val))
9581         proto = 1;
9582       else if (unformat (input, "payload_length %d", &payload_length_val))
9583         payload_length = 1;
9584       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9585         hop_limit = 1;
9586       else
9587         break;
9588     }
9589
9590   if (version + traffic_class + flow_label + src + dst + proto +
9591       payload_length + hop_limit == 0)
9592     return 0;
9593
9594   /*
9595    * Aligned because we use the real comparison functions
9596    */
9597   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9598
9599   ip = (ip6_header_t *) match;
9600
9601   if (src)
9602     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9603
9604   if (dst)
9605     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9606
9607   if (proto)
9608     ip->protocol = proto_val;
9609
9610   ip_version_traffic_class_and_flow_label = 0;
9611
9612   if (version)
9613     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9614
9615   if (traffic_class)
9616     ip_version_traffic_class_and_flow_label |=
9617       (traffic_class_val & 0xFF) << 20;
9618
9619   if (flow_label)
9620     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9621
9622   ip->ip_version_traffic_class_and_flow_label =
9623     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9624
9625   if (payload_length)
9626     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9627
9628   if (hop_limit)
9629     ip->hop_limit = hop_limit_val;
9630
9631   *matchp = match;
9632   return 1;
9633 }
9634
9635 uword
9636 unformat_l3_match (unformat_input_t * input, va_list * args)
9637 {
9638   u8 **matchp = va_arg (*args, u8 **);
9639
9640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9641     {
9642       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9643         return 1;
9644       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9645         return 1;
9646       else
9647         break;
9648     }
9649   return 0;
9650 }
9651
9652 uword
9653 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9654 {
9655   u8 *tagp = va_arg (*args, u8 *);
9656   u32 tag;
9657
9658   if (unformat (input, "%d", &tag))
9659     {
9660       tagp[0] = (tag >> 8) & 0x0F;
9661       tagp[1] = tag & 0xFF;
9662       return 1;
9663     }
9664
9665   return 0;
9666 }
9667
9668 uword
9669 unformat_l2_match (unformat_input_t * input, va_list * args)
9670 {
9671   u8 **matchp = va_arg (*args, u8 **);
9672   u8 *match = 0;
9673   u8 src = 0;
9674   u8 src_val[6];
9675   u8 dst = 0;
9676   u8 dst_val[6];
9677   u8 proto = 0;
9678   u16 proto_val;
9679   u8 tag1 = 0;
9680   u8 tag1_val[2];
9681   u8 tag2 = 0;
9682   u8 tag2_val[2];
9683   int len = 14;
9684   u8 ignore_tag1 = 0;
9685   u8 ignore_tag2 = 0;
9686   u8 cos1 = 0;
9687   u8 cos2 = 0;
9688   u32 cos1_val = 0;
9689   u32 cos2_val = 0;
9690
9691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9692     {
9693       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9694         src = 1;
9695       else
9696         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9697         dst = 1;
9698       else if (unformat (input, "proto %U",
9699                          unformat_ethernet_type_host_byte_order, &proto_val))
9700         proto = 1;
9701       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9702         tag1 = 1;
9703       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9704         tag2 = 1;
9705       else if (unformat (input, "ignore-tag1"))
9706         ignore_tag1 = 1;
9707       else if (unformat (input, "ignore-tag2"))
9708         ignore_tag2 = 1;
9709       else if (unformat (input, "cos1 %d", &cos1_val))
9710         cos1 = 1;
9711       else if (unformat (input, "cos2 %d", &cos2_val))
9712         cos2 = 1;
9713       else
9714         break;
9715     }
9716   if ((src + dst + proto + tag1 + tag2 +
9717        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9718     return 0;
9719
9720   if (tag1 || ignore_tag1 || cos1)
9721     len = 18;
9722   if (tag2 || ignore_tag2 || cos2)
9723     len = 22;
9724
9725   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9726
9727   if (dst)
9728     clib_memcpy (match, dst_val, 6);
9729
9730   if (src)
9731     clib_memcpy (match + 6, src_val, 6);
9732
9733   if (tag2)
9734     {
9735       /* inner vlan tag */
9736       match[19] = tag2_val[1];
9737       match[18] = tag2_val[0];
9738       if (cos2)
9739         match[18] |= (cos2_val & 0x7) << 5;
9740       if (proto)
9741         {
9742           match[21] = proto_val & 0xff;
9743           match[20] = proto_val >> 8;
9744         }
9745       if (tag1)
9746         {
9747           match[15] = tag1_val[1];
9748           match[14] = tag1_val[0];
9749         }
9750       if (cos1)
9751         match[14] |= (cos1_val & 0x7) << 5;
9752       *matchp = match;
9753       return 1;
9754     }
9755   if (tag1)
9756     {
9757       match[15] = tag1_val[1];
9758       match[14] = tag1_val[0];
9759       if (proto)
9760         {
9761           match[17] = proto_val & 0xff;
9762           match[16] = proto_val >> 8;
9763         }
9764       if (cos1)
9765         match[14] |= (cos1_val & 0x7) << 5;
9766
9767       *matchp = match;
9768       return 1;
9769     }
9770   if (cos2)
9771     match[18] |= (cos2_val & 0x7) << 5;
9772   if (cos1)
9773     match[14] |= (cos1_val & 0x7) << 5;
9774   if (proto)
9775     {
9776       match[13] = proto_val & 0xff;
9777       match[12] = proto_val >> 8;
9778     }
9779
9780   *matchp = match;
9781   return 1;
9782 }
9783
9784
9785 uword
9786 unformat_classify_match (unformat_input_t * input, va_list * args)
9787 {
9788   u8 **matchp = va_arg (*args, u8 **);
9789   u32 skip_n_vectors = va_arg (*args, u32);
9790   u32 match_n_vectors = va_arg (*args, u32);
9791
9792   u8 *match = 0;
9793   u8 *l2 = 0;
9794   u8 *l3 = 0;
9795   u8 *l4 = 0;
9796
9797   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9798     {
9799       if (unformat (input, "hex %U", unformat_hex_string, &match))
9800         ;
9801       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9802         ;
9803       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9804         ;
9805       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9806         ;
9807       else
9808         break;
9809     }
9810
9811   if (l4 && !l3)
9812     {
9813       vec_free (match);
9814       vec_free (l2);
9815       vec_free (l4);
9816       return 0;
9817     }
9818
9819   if (match || l2 || l3 || l4)
9820     {
9821       if (l2 || l3 || l4)
9822         {
9823           /* "Win a free Ethernet header in every packet" */
9824           if (l2 == 0)
9825             vec_validate_aligned (l2, 13, sizeof (u32x4));
9826           match = l2;
9827           if (vec_len (l3))
9828             {
9829               vec_append_aligned (match, l3, sizeof (u32x4));
9830               vec_free (l3);
9831             }
9832           if (vec_len (l4))
9833             {
9834               vec_append_aligned (match, l4, sizeof (u32x4));
9835               vec_free (l4);
9836             }
9837         }
9838
9839       /* Make sure the vector is big enough even if key is all 0's */
9840       vec_validate_aligned
9841         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9842          sizeof (u32x4));
9843
9844       /* Set size, include skipped vectors */
9845       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9846
9847       *matchp = match;
9848
9849       return 1;
9850     }
9851
9852   return 0;
9853 }
9854
9855 static int
9856 api_classify_add_del_session (vat_main_t * vam)
9857 {
9858   unformat_input_t *i = vam->input;
9859   vl_api_classify_add_del_session_t *mp;
9860   int is_add = 1;
9861   u32 table_index = ~0;
9862   u32 hit_next_index = ~0;
9863   u32 opaque_index = ~0;
9864   u8 *match = 0;
9865   i32 advance = 0;
9866   f64 timeout;
9867   u32 skip_n_vectors = 0;
9868   u32 match_n_vectors = 0;
9869   u32 action = 0;
9870   u32 metadata = 0;
9871
9872   /*
9873    * Warning: you have to supply skip_n and match_n
9874    * because the API client cant simply look at the classify
9875    * table object.
9876    */
9877
9878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9879     {
9880       if (unformat (i, "del"))
9881         is_add = 0;
9882       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9883                          &hit_next_index))
9884         ;
9885       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9886                          &hit_next_index))
9887         ;
9888       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9889                          &hit_next_index))
9890         ;
9891       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9892         ;
9893       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9894         ;
9895       else if (unformat (i, "opaque-index %d", &opaque_index))
9896         ;
9897       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9898         ;
9899       else if (unformat (i, "match_n %d", &match_n_vectors))
9900         ;
9901       else if (unformat (i, "match %U", unformat_classify_match,
9902                          &match, skip_n_vectors, match_n_vectors))
9903         ;
9904       else if (unformat (i, "advance %d", &advance))
9905         ;
9906       else if (unformat (i, "table-index %d", &table_index))
9907         ;
9908       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9909         action = 1;
9910       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9911         action = 2;
9912       else if (unformat (i, "action %d", &action))
9913         ;
9914       else if (unformat (i, "metadata %d", &metadata))
9915         ;
9916       else
9917         break;
9918     }
9919
9920   if (table_index == ~0)
9921     {
9922       errmsg ("Table index required");
9923       return -99;
9924     }
9925
9926   if (is_add && match == 0)
9927     {
9928       errmsg ("Match value required");
9929       return -99;
9930     }
9931
9932   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9933
9934   mp->is_add = is_add;
9935   mp->table_index = ntohl (table_index);
9936   mp->hit_next_index = ntohl (hit_next_index);
9937   mp->opaque_index = ntohl (opaque_index);
9938   mp->advance = ntohl (advance);
9939   mp->action = action;
9940   mp->metadata = ntohl (metadata);
9941   clib_memcpy (mp->match, match, vec_len (match));
9942   vec_free (match);
9943
9944   S;
9945   W;
9946   /* NOTREACHED */
9947 }
9948
9949 static int
9950 api_classify_set_interface_ip_table (vat_main_t * vam)
9951 {
9952   unformat_input_t *i = vam->input;
9953   vl_api_classify_set_interface_ip_table_t *mp;
9954   f64 timeout;
9955   u32 sw_if_index;
9956   int sw_if_index_set;
9957   u32 table_index = ~0;
9958   u8 is_ipv6 = 0;
9959
9960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9961     {
9962       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9963         sw_if_index_set = 1;
9964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9965         sw_if_index_set = 1;
9966       else if (unformat (i, "table %d", &table_index))
9967         ;
9968       else
9969         {
9970           clib_warning ("parse error '%U'", format_unformat_error, i);
9971           return -99;
9972         }
9973     }
9974
9975   if (sw_if_index_set == 0)
9976     {
9977       errmsg ("missing interface name or sw_if_index");
9978       return -99;
9979     }
9980
9981
9982   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9983
9984   mp->sw_if_index = ntohl (sw_if_index);
9985   mp->table_index = ntohl (table_index);
9986   mp->is_ipv6 = is_ipv6;
9987
9988   S;
9989   W;
9990   /* NOTREACHED */
9991   return 0;
9992 }
9993
9994 static int
9995 api_classify_set_interface_l2_tables (vat_main_t * vam)
9996 {
9997   unformat_input_t *i = vam->input;
9998   vl_api_classify_set_interface_l2_tables_t *mp;
9999   f64 timeout;
10000   u32 sw_if_index;
10001   int sw_if_index_set;
10002   u32 ip4_table_index = ~0;
10003   u32 ip6_table_index = ~0;
10004   u32 other_table_index = ~0;
10005   u32 is_input = 1;
10006
10007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10008     {
10009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10010         sw_if_index_set = 1;
10011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10012         sw_if_index_set = 1;
10013       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10014         ;
10015       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10016         ;
10017       else if (unformat (i, "other-table %d", &other_table_index))
10018         ;
10019       else if (unformat (i, "is-input %d", &is_input))
10020         ;
10021       else
10022         {
10023           clib_warning ("parse error '%U'", format_unformat_error, i);
10024           return -99;
10025         }
10026     }
10027
10028   if (sw_if_index_set == 0)
10029     {
10030       errmsg ("missing interface name or sw_if_index");
10031       return -99;
10032     }
10033
10034
10035   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
10036
10037   mp->sw_if_index = ntohl (sw_if_index);
10038   mp->ip4_table_index = ntohl (ip4_table_index);
10039   mp->ip6_table_index = ntohl (ip6_table_index);
10040   mp->other_table_index = ntohl (other_table_index);
10041   mp->is_input = (u8) is_input;
10042
10043   S;
10044   W;
10045   /* NOTREACHED */
10046   return 0;
10047 }
10048
10049 static int
10050 api_set_ipfix_exporter (vat_main_t * vam)
10051 {
10052   unformat_input_t *i = vam->input;
10053   vl_api_set_ipfix_exporter_t *mp;
10054   ip4_address_t collector_address;
10055   u8 collector_address_set = 0;
10056   u32 collector_port = ~0;
10057   ip4_address_t src_address;
10058   u8 src_address_set = 0;
10059   u32 vrf_id = ~0;
10060   u32 path_mtu = ~0;
10061   u32 template_interval = ~0;
10062   u8 udp_checksum = 0;
10063   f64 timeout;
10064
10065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10066     {
10067       if (unformat (i, "collector_address %U", unformat_ip4_address,
10068                     &collector_address))
10069         collector_address_set = 1;
10070       else if (unformat (i, "collector_port %d", &collector_port))
10071         ;
10072       else if (unformat (i, "src_address %U", unformat_ip4_address,
10073                          &src_address))
10074         src_address_set = 1;
10075       else if (unformat (i, "vrf_id %d", &vrf_id))
10076         ;
10077       else if (unformat (i, "path_mtu %d", &path_mtu))
10078         ;
10079       else if (unformat (i, "template_interval %d", &template_interval))
10080         ;
10081       else if (unformat (i, "udp_checksum"))
10082         udp_checksum = 1;
10083       else
10084         break;
10085     }
10086
10087   if (collector_address_set == 0)
10088     {
10089       errmsg ("collector_address required");
10090       return -99;
10091     }
10092
10093   if (src_address_set == 0)
10094     {
10095       errmsg ("src_address required");
10096       return -99;
10097     }
10098
10099   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
10100
10101   memcpy (mp->collector_address, collector_address.data,
10102           sizeof (collector_address.data));
10103   mp->collector_port = htons ((u16) collector_port);
10104   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10105   mp->vrf_id = htonl (vrf_id);
10106   mp->path_mtu = htonl (path_mtu);
10107   mp->template_interval = htonl (template_interval);
10108   mp->udp_checksum = udp_checksum;
10109
10110   S;
10111   W;
10112   /* NOTREACHED */
10113 }
10114
10115 static int
10116 api_set_ipfix_classify_stream (vat_main_t * vam)
10117 {
10118   unformat_input_t *i = vam->input;
10119   vl_api_set_ipfix_classify_stream_t *mp;
10120   u32 domain_id = 0;
10121   u32 src_port = UDP_DST_PORT_ipfix;
10122   f64 timeout;
10123
10124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10125     {
10126       if (unformat (i, "domain %d", &domain_id))
10127         ;
10128       else if (unformat (i, "src_port %d", &src_port))
10129         ;
10130       else
10131         {
10132           errmsg ("unknown input `%U'", format_unformat_error, i);
10133           return -99;
10134         }
10135     }
10136
10137   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
10138
10139   mp->domain_id = htonl (domain_id);
10140   mp->src_port = htons ((u16) src_port);
10141
10142   S;
10143   W;
10144   /* NOTREACHED */
10145 }
10146
10147 static int
10148 api_ipfix_classify_table_add_del (vat_main_t * vam)
10149 {
10150   unformat_input_t *i = vam->input;
10151   vl_api_ipfix_classify_table_add_del_t *mp;
10152   int is_add = -1;
10153   u32 classify_table_index = ~0;
10154   u8 ip_version = 0;
10155   u8 transport_protocol = 255;
10156   f64 timeout;
10157
10158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10159     {
10160       if (unformat (i, "add"))
10161         is_add = 1;
10162       else if (unformat (i, "del"))
10163         is_add = 0;
10164       else if (unformat (i, "table %d", &classify_table_index))
10165         ;
10166       else if (unformat (i, "ip4"))
10167         ip_version = 4;
10168       else if (unformat (i, "ip6"))
10169         ip_version = 6;
10170       else if (unformat (i, "tcp"))
10171         transport_protocol = 6;
10172       else if (unformat (i, "udp"))
10173         transport_protocol = 17;
10174       else
10175         {
10176           errmsg ("unknown input `%U'", format_unformat_error, i);
10177           return -99;
10178         }
10179     }
10180
10181   if (is_add == -1)
10182     {
10183       errmsg ("expecting: add|del");
10184       return -99;
10185     }
10186   if (classify_table_index == ~0)
10187     {
10188       errmsg ("classifier table not specified");
10189       return -99;
10190     }
10191   if (ip_version == 0)
10192     {
10193       errmsg ("IP version not specified");
10194       return -99;
10195     }
10196
10197   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
10198
10199   mp->is_add = is_add;
10200   mp->table_id = htonl (classify_table_index);
10201   mp->ip_version = ip_version;
10202   mp->transport_protocol = transport_protocol;
10203
10204   S;
10205   W;
10206   /* NOTREACHED */
10207 }
10208
10209 static int
10210 api_get_node_index (vat_main_t * vam)
10211 {
10212   unformat_input_t *i = vam->input;
10213   vl_api_get_node_index_t *mp;
10214   f64 timeout;
10215   u8 *name = 0;
10216
10217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10218     {
10219       if (unformat (i, "node %s", &name))
10220         ;
10221       else
10222         break;
10223     }
10224   if (name == 0)
10225     {
10226       errmsg ("node name required");
10227       return -99;
10228     }
10229   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10230     {
10231       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10232       return -99;
10233     }
10234
10235   M (GET_NODE_INDEX, get_node_index);
10236   clib_memcpy (mp->node_name, name, vec_len (name));
10237   vec_free (name);
10238
10239   S;
10240   W;
10241   /* NOTREACHED */
10242   return 0;
10243 }
10244
10245 static int
10246 api_get_next_index (vat_main_t * vam)
10247 {
10248   unformat_input_t *i = vam->input;
10249   vl_api_get_next_index_t *mp;
10250   f64 timeout;
10251   u8 *node_name = 0, *next_node_name = 0;
10252
10253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10254     {
10255       if (unformat (i, "node-name %s", &node_name))
10256         ;
10257       else if (unformat (i, "next-node-name %s", &next_node_name))
10258         break;
10259     }
10260
10261   if (node_name == 0)
10262     {
10263       errmsg ("node name required");
10264       return -99;
10265     }
10266   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10267     {
10268       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10269       return -99;
10270     }
10271
10272   if (next_node_name == 0)
10273     {
10274       errmsg ("next node name required");
10275       return -99;
10276     }
10277   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10278     {
10279       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10280       return -99;
10281     }
10282
10283   M (GET_NEXT_INDEX, get_next_index);
10284   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10285   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10286   vec_free (node_name);
10287   vec_free (next_node_name);
10288
10289   S;
10290   W;
10291   /* NOTREACHED */
10292   return 0;
10293 }
10294
10295 static int
10296 api_add_node_next (vat_main_t * vam)
10297 {
10298   unformat_input_t *i = vam->input;
10299   vl_api_add_node_next_t *mp;
10300   f64 timeout;
10301   u8 *name = 0;
10302   u8 *next = 0;
10303
10304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10305     {
10306       if (unformat (i, "node %s", &name))
10307         ;
10308       else if (unformat (i, "next %s", &next))
10309         ;
10310       else
10311         break;
10312     }
10313   if (name == 0)
10314     {
10315       errmsg ("node name required");
10316       return -99;
10317     }
10318   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10319     {
10320       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10321       return -99;
10322     }
10323   if (next == 0)
10324     {
10325       errmsg ("next node required");
10326       return -99;
10327     }
10328   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10329     {
10330       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10331       return -99;
10332     }
10333
10334   M (ADD_NODE_NEXT, add_node_next);
10335   clib_memcpy (mp->node_name, name, vec_len (name));
10336   clib_memcpy (mp->next_name, next, vec_len (next));
10337   vec_free (name);
10338   vec_free (next);
10339
10340   S;
10341   W;
10342   /* NOTREACHED */
10343   return 0;
10344 }
10345
10346 static int
10347 api_l2tpv3_create_tunnel (vat_main_t * vam)
10348 {
10349   unformat_input_t *i = vam->input;
10350   ip6_address_t client_address, our_address;
10351   int client_address_set = 0;
10352   int our_address_set = 0;
10353   u32 local_session_id = 0;
10354   u32 remote_session_id = 0;
10355   u64 local_cookie = 0;
10356   u64 remote_cookie = 0;
10357   u8 l2_sublayer_present = 0;
10358   vl_api_l2tpv3_create_tunnel_t *mp;
10359   f64 timeout;
10360
10361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10362     {
10363       if (unformat (i, "client_address %U", unformat_ip6_address,
10364                     &client_address))
10365         client_address_set = 1;
10366       else if (unformat (i, "our_address %U", unformat_ip6_address,
10367                          &our_address))
10368         our_address_set = 1;
10369       else if (unformat (i, "local_session_id %d", &local_session_id))
10370         ;
10371       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10372         ;
10373       else if (unformat (i, "local_cookie %lld", &local_cookie))
10374         ;
10375       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10376         ;
10377       else if (unformat (i, "l2-sublayer-present"))
10378         l2_sublayer_present = 1;
10379       else
10380         break;
10381     }
10382
10383   if (client_address_set == 0)
10384     {
10385       errmsg ("client_address required");
10386       return -99;
10387     }
10388
10389   if (our_address_set == 0)
10390     {
10391       errmsg ("our_address required");
10392       return -99;
10393     }
10394
10395   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
10396
10397   clib_memcpy (mp->client_address, client_address.as_u8,
10398                sizeof (mp->client_address));
10399
10400   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10401
10402   mp->local_session_id = ntohl (local_session_id);
10403   mp->remote_session_id = ntohl (remote_session_id);
10404   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10405   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10406   mp->l2_sublayer_present = l2_sublayer_present;
10407   mp->is_ipv6 = 1;
10408
10409   S;
10410   W;
10411   /* NOTREACHED */
10412   return 0;
10413 }
10414
10415 static int
10416 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10417 {
10418   unformat_input_t *i = vam->input;
10419   u32 sw_if_index;
10420   u8 sw_if_index_set = 0;
10421   u64 new_local_cookie = 0;
10422   u64 new_remote_cookie = 0;
10423   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10424   f64 timeout;
10425
10426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10427     {
10428       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10429         sw_if_index_set = 1;
10430       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10431         sw_if_index_set = 1;
10432       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10433         ;
10434       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10435         ;
10436       else
10437         break;
10438     }
10439
10440   if (sw_if_index_set == 0)
10441     {
10442       errmsg ("missing interface name or sw_if_index");
10443       return -99;
10444     }
10445
10446   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10447
10448   mp->sw_if_index = ntohl (sw_if_index);
10449   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10450   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10451
10452   S;
10453   W;
10454   /* NOTREACHED */
10455   return 0;
10456 }
10457
10458 static int
10459 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10460 {
10461   unformat_input_t *i = vam->input;
10462   vl_api_l2tpv3_interface_enable_disable_t *mp;
10463   f64 timeout;
10464   u32 sw_if_index;
10465   u8 sw_if_index_set = 0;
10466   u8 enable_disable = 1;
10467
10468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10469     {
10470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10471         sw_if_index_set = 1;
10472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10473         sw_if_index_set = 1;
10474       else if (unformat (i, "enable"))
10475         enable_disable = 1;
10476       else if (unformat (i, "disable"))
10477         enable_disable = 0;
10478       else
10479         break;
10480     }
10481
10482   if (sw_if_index_set == 0)
10483     {
10484       errmsg ("missing interface name or sw_if_index");
10485       return -99;
10486     }
10487
10488   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10489
10490   mp->sw_if_index = ntohl (sw_if_index);
10491   mp->enable_disable = enable_disable;
10492
10493   S;
10494   W;
10495   /* NOTREACHED */
10496   return 0;
10497 }
10498
10499 static int
10500 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10501 {
10502   unformat_input_t *i = vam->input;
10503   vl_api_l2tpv3_set_lookup_key_t *mp;
10504   f64 timeout;
10505   u8 key = ~0;
10506
10507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10508     {
10509       if (unformat (i, "lookup_v6_src"))
10510         key = L2T_LOOKUP_SRC_ADDRESS;
10511       else if (unformat (i, "lookup_v6_dst"))
10512         key = L2T_LOOKUP_DST_ADDRESS;
10513       else if (unformat (i, "lookup_session_id"))
10514         key = L2T_LOOKUP_SESSION_ID;
10515       else
10516         break;
10517     }
10518
10519   if (key == (u8) ~ 0)
10520     {
10521       errmsg ("l2tp session lookup key unset");
10522       return -99;
10523     }
10524
10525   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10526
10527   mp->key = key;
10528
10529   S;
10530   W;
10531   /* NOTREACHED */
10532   return 0;
10533 }
10534
10535 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10536   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10537 {
10538   vat_main_t *vam = &vat_main;
10539
10540   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10541          format_ip6_address, mp->our_address,
10542          format_ip6_address, mp->client_address,
10543          clib_net_to_host_u32 (mp->sw_if_index));
10544
10545   print (vam->ofp,
10546          "   local cookies %016llx %016llx remote cookie %016llx",
10547          clib_net_to_host_u64 (mp->local_cookie[0]),
10548          clib_net_to_host_u64 (mp->local_cookie[1]),
10549          clib_net_to_host_u64 (mp->remote_cookie));
10550
10551   print (vam->ofp, "   local session-id %d remote session-id %d",
10552          clib_net_to_host_u32 (mp->local_session_id),
10553          clib_net_to_host_u32 (mp->remote_session_id));
10554
10555   print (vam->ofp, "   l2 specific sublayer %s\n",
10556          mp->l2_sublayer_present ? "preset" : "absent");
10557
10558 }
10559
10560 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10561   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10562 {
10563   vat_main_t *vam = &vat_main;
10564   vat_json_node_t *node = NULL;
10565   struct in6_addr addr;
10566
10567   if (VAT_JSON_ARRAY != vam->json_tree.type)
10568     {
10569       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10570       vat_json_init_array (&vam->json_tree);
10571     }
10572   node = vat_json_array_add (&vam->json_tree);
10573
10574   vat_json_init_object (node);
10575
10576   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10577   vat_json_object_add_ip6 (node, "our_address", addr);
10578   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10579   vat_json_object_add_ip6 (node, "client_address", addr);
10580
10581   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10582   vat_json_init_array (lc);
10583   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10584   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10585   vat_json_object_add_uint (node, "remote_cookie",
10586                             clib_net_to_host_u64 (mp->remote_cookie));
10587
10588   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10589   vat_json_object_add_uint (node, "local_session_id",
10590                             clib_net_to_host_u32 (mp->local_session_id));
10591   vat_json_object_add_uint (node, "remote_session_id",
10592                             clib_net_to_host_u32 (mp->remote_session_id));
10593   vat_json_object_add_string_copy (node, "l2_sublayer",
10594                                    mp->l2_sublayer_present ? (u8 *) "present"
10595                                    : (u8 *) "absent");
10596 }
10597
10598 static int
10599 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10600 {
10601   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10602   f64 timeout;
10603
10604   /* Get list of l2tpv3-tunnel interfaces */
10605   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10606   S;
10607
10608   /* Use a control ping for synchronization */
10609   {
10610     vl_api_control_ping_t *mp;
10611     M (CONTROL_PING, control_ping);
10612     S;
10613   }
10614   W;
10615 }
10616
10617
10618 static void vl_api_sw_interface_tap_details_t_handler
10619   (vl_api_sw_interface_tap_details_t * mp)
10620 {
10621   vat_main_t *vam = &vat_main;
10622
10623   print (vam->ofp, "%-16s %d",
10624          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10625 }
10626
10627 static void vl_api_sw_interface_tap_details_t_handler_json
10628   (vl_api_sw_interface_tap_details_t * mp)
10629 {
10630   vat_main_t *vam = &vat_main;
10631   vat_json_node_t *node = NULL;
10632
10633   if (VAT_JSON_ARRAY != vam->json_tree.type)
10634     {
10635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10636       vat_json_init_array (&vam->json_tree);
10637     }
10638   node = vat_json_array_add (&vam->json_tree);
10639
10640   vat_json_init_object (node);
10641   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10642   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10643 }
10644
10645 static int
10646 api_sw_interface_tap_dump (vat_main_t * vam)
10647 {
10648   vl_api_sw_interface_tap_dump_t *mp;
10649   f64 timeout;
10650
10651   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10652   /* Get list of tap interfaces */
10653   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10654   S;
10655
10656   /* Use a control ping for synchronization */
10657   {
10658     vl_api_control_ping_t *mp;
10659     M (CONTROL_PING, control_ping);
10660     S;
10661   }
10662   W;
10663 }
10664
10665 static uword unformat_vxlan_decap_next
10666   (unformat_input_t * input, va_list * args)
10667 {
10668   u32 *result = va_arg (*args, u32 *);
10669   u32 tmp;
10670
10671   if (unformat (input, "l2"))
10672     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10673   else if (unformat (input, "%d", &tmp))
10674     *result = tmp;
10675   else
10676     return 0;
10677   return 1;
10678 }
10679
10680 static int
10681 api_vxlan_add_del_tunnel (vat_main_t * vam)
10682 {
10683   unformat_input_t *line_input = vam->input;
10684   vl_api_vxlan_add_del_tunnel_t *mp;
10685   f64 timeout;
10686   ip46_address_t src, dst;
10687   u8 is_add = 1;
10688   u8 ipv4_set = 0, ipv6_set = 0;
10689   u8 src_set = 0;
10690   u8 dst_set = 0;
10691   u8 grp_set = 0;
10692   u32 mcast_sw_if_index = ~0;
10693   u32 encap_vrf_id = 0;
10694   u32 decap_next_index = ~0;
10695   u32 vni = 0;
10696
10697   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10698   memset (&src, 0, sizeof src);
10699   memset (&dst, 0, sizeof dst);
10700
10701   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10702     {
10703       if (unformat (line_input, "del"))
10704         is_add = 0;
10705       else
10706         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10707         {
10708           ipv4_set = 1;
10709           src_set = 1;
10710         }
10711       else
10712         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10713         {
10714           ipv4_set = 1;
10715           dst_set = 1;
10716         }
10717       else
10718         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10719         {
10720           ipv6_set = 1;
10721           src_set = 1;
10722         }
10723       else
10724         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10725         {
10726           ipv6_set = 1;
10727           dst_set = 1;
10728         }
10729       else if (unformat (line_input, "group %U %U",
10730                          unformat_ip4_address, &dst.ip4,
10731                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10732         {
10733           grp_set = dst_set = 1;
10734           ipv4_set = 1;
10735         }
10736       else if (unformat (line_input, "group %U",
10737                          unformat_ip4_address, &dst.ip4))
10738         {
10739           grp_set = dst_set = 1;
10740           ipv4_set = 1;
10741         }
10742       else if (unformat (line_input, "group %U %U",
10743                          unformat_ip6_address, &dst.ip6,
10744                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10745         {
10746           grp_set = dst_set = 1;
10747           ipv6_set = 1;
10748         }
10749       else if (unformat (line_input, "group %U",
10750                          unformat_ip6_address, &dst.ip6))
10751         {
10752           grp_set = dst_set = 1;
10753           ipv6_set = 1;
10754         }
10755       else
10756         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10757         ;
10758       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10759         ;
10760       else if (unformat (line_input, "decap-next %U",
10761                          unformat_vxlan_decap_next, &decap_next_index))
10762         ;
10763       else if (unformat (line_input, "vni %d", &vni))
10764         ;
10765       else
10766         {
10767           errmsg ("parse error '%U'", format_unformat_error, line_input);
10768           return -99;
10769         }
10770     }
10771
10772   if (src_set == 0)
10773     {
10774       errmsg ("tunnel src address not specified");
10775       return -99;
10776     }
10777   if (dst_set == 0)
10778     {
10779       errmsg ("tunnel dst address not specified");
10780       return -99;
10781     }
10782
10783   if (grp_set && !ip46_address_is_multicast (&dst))
10784     {
10785       errmsg ("tunnel group address not multicast");
10786       return -99;
10787     }
10788   if (grp_set && mcast_sw_if_index == ~0)
10789     {
10790       errmsg ("tunnel nonexistent multicast device");
10791       return -99;
10792     }
10793   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10794     {
10795       errmsg ("tunnel dst address must be unicast");
10796       return -99;
10797     }
10798
10799
10800   if (ipv4_set && ipv6_set)
10801     {
10802       errmsg ("both IPv4 and IPv6 addresses specified");
10803       return -99;
10804     }
10805
10806   if ((vni == 0) || (vni >> 24))
10807     {
10808       errmsg ("vni not specified or out of range");
10809       return -99;
10810     }
10811
10812   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10813
10814   if (ipv6_set)
10815     {
10816       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10817       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10818     }
10819   else
10820     {
10821       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10822       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10823     }
10824   mp->encap_vrf_id = ntohl (encap_vrf_id);
10825   mp->decap_next_index = ntohl (decap_next_index);
10826   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10827   mp->vni = ntohl (vni);
10828   mp->is_add = is_add;
10829   mp->is_ipv6 = ipv6_set;
10830
10831   S;
10832   W;
10833   /* NOTREACHED */
10834   return 0;
10835 }
10836
10837 static void vl_api_vxlan_tunnel_details_t_handler
10838   (vl_api_vxlan_tunnel_details_t * mp)
10839 {
10840   vat_main_t *vam = &vat_main;
10841   ip46_address_t src, dst;
10842
10843   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10844   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10845
10846   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10847          ntohl (mp->sw_if_index),
10848          format_ip46_address, &src, IP46_TYPE_ANY,
10849          format_ip46_address, &dst, IP46_TYPE_ANY,
10850          ntohl (mp->encap_vrf_id),
10851          ntohl (mp->decap_next_index), ntohl (mp->vni),
10852          ntohl (mp->mcast_sw_if_index));
10853 }
10854
10855 static void vl_api_vxlan_tunnel_details_t_handler_json
10856   (vl_api_vxlan_tunnel_details_t * mp)
10857 {
10858   vat_main_t *vam = &vat_main;
10859   vat_json_node_t *node = NULL;
10860
10861   if (VAT_JSON_ARRAY != vam->json_tree.type)
10862     {
10863       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10864       vat_json_init_array (&vam->json_tree);
10865     }
10866   node = vat_json_array_add (&vam->json_tree);
10867
10868   vat_json_init_object (node);
10869   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10870   if (mp->is_ipv6)
10871     {
10872       struct in6_addr ip6;
10873
10874       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10875       vat_json_object_add_ip6 (node, "src_address", ip6);
10876       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10877       vat_json_object_add_ip6 (node, "dst_address", ip6);
10878     }
10879   else
10880     {
10881       struct in_addr ip4;
10882
10883       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10884       vat_json_object_add_ip4 (node, "src_address", ip4);
10885       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10886       vat_json_object_add_ip4 (node, "dst_address", ip4);
10887     }
10888   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10889   vat_json_object_add_uint (node, "decap_next_index",
10890                             ntohl (mp->decap_next_index));
10891   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10892   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10893   vat_json_object_add_uint (node, "mcast_sw_if_index",
10894                             ntohl (mp->mcast_sw_if_index));
10895 }
10896
10897 static int
10898 api_vxlan_tunnel_dump (vat_main_t * vam)
10899 {
10900   unformat_input_t *i = vam->input;
10901   vl_api_vxlan_tunnel_dump_t *mp;
10902   f64 timeout;
10903   u32 sw_if_index;
10904   u8 sw_if_index_set = 0;
10905
10906   /* Parse args required to build the message */
10907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10908     {
10909       if (unformat (i, "sw_if_index %d", &sw_if_index))
10910         sw_if_index_set = 1;
10911       else
10912         break;
10913     }
10914
10915   if (sw_if_index_set == 0)
10916     {
10917       sw_if_index = ~0;
10918     }
10919
10920   if (!vam->json_output)
10921     {
10922       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10923              "sw_if_index", "src_address", "dst_address",
10924              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10925     }
10926
10927   /* Get list of vxlan-tunnel interfaces */
10928   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10929
10930   mp->sw_if_index = htonl (sw_if_index);
10931
10932   S;
10933
10934   /* Use a control ping for synchronization */
10935   {
10936     vl_api_control_ping_t *mp;
10937     M (CONTROL_PING, control_ping);
10938     S;
10939   }
10940   W;
10941 }
10942
10943 static int
10944 api_gre_add_del_tunnel (vat_main_t * vam)
10945 {
10946   unformat_input_t *line_input = vam->input;
10947   vl_api_gre_add_del_tunnel_t *mp;
10948   f64 timeout;
10949   ip4_address_t src4, dst4;
10950   u8 is_add = 1;
10951   u8 teb = 0;
10952   u8 src_set = 0;
10953   u8 dst_set = 0;
10954   u32 outer_fib_id = 0;
10955
10956   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10957     {
10958       if (unformat (line_input, "del"))
10959         is_add = 0;
10960       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10961         src_set = 1;
10962       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10963         dst_set = 1;
10964       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10965         ;
10966       else if (unformat (line_input, "teb"))
10967         teb = 1;
10968       else
10969         {
10970           errmsg ("parse error '%U'", format_unformat_error, line_input);
10971           return -99;
10972         }
10973     }
10974
10975   if (src_set == 0)
10976     {
10977       errmsg ("tunnel src address not specified");
10978       return -99;
10979     }
10980   if (dst_set == 0)
10981     {
10982       errmsg ("tunnel dst address not specified");
10983       return -99;
10984     }
10985
10986
10987   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10988
10989   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10990   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10991   mp->outer_fib_id = ntohl (outer_fib_id);
10992   mp->is_add = is_add;
10993   mp->teb = teb;
10994
10995   S;
10996   W;
10997   /* NOTREACHED */
10998   return 0;
10999 }
11000
11001 static void vl_api_gre_tunnel_details_t_handler
11002   (vl_api_gre_tunnel_details_t * mp)
11003 {
11004   vat_main_t *vam = &vat_main;
11005
11006   print (vam->ofp, "%11d%15U%15U%6d%14d",
11007          ntohl (mp->sw_if_index),
11008          format_ip4_address, &mp->src_address,
11009          format_ip4_address, &mp->dst_address,
11010          mp->teb, ntohl (mp->outer_fib_id));
11011 }
11012
11013 static void vl_api_gre_tunnel_details_t_handler_json
11014   (vl_api_gre_tunnel_details_t * mp)
11015 {
11016   vat_main_t *vam = &vat_main;
11017   vat_json_node_t *node = NULL;
11018   struct in_addr ip4;
11019
11020   if (VAT_JSON_ARRAY != vam->json_tree.type)
11021     {
11022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11023       vat_json_init_array (&vam->json_tree);
11024     }
11025   node = vat_json_array_add (&vam->json_tree);
11026
11027   vat_json_init_object (node);
11028   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11029   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11030   vat_json_object_add_ip4 (node, "src_address", ip4);
11031   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11032   vat_json_object_add_ip4 (node, "dst_address", ip4);
11033   vat_json_object_add_uint (node, "teb", mp->teb);
11034   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11035 }
11036
11037 static int
11038 api_gre_tunnel_dump (vat_main_t * vam)
11039 {
11040   unformat_input_t *i = vam->input;
11041   vl_api_gre_tunnel_dump_t *mp;
11042   f64 timeout;
11043   u32 sw_if_index;
11044   u8 sw_if_index_set = 0;
11045
11046   /* Parse args required to build the message */
11047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11048     {
11049       if (unformat (i, "sw_if_index %d", &sw_if_index))
11050         sw_if_index_set = 1;
11051       else
11052         break;
11053     }
11054
11055   if (sw_if_index_set == 0)
11056     {
11057       sw_if_index = ~0;
11058     }
11059
11060   if (!vam->json_output)
11061     {
11062       print (vam->ofp, "%11s%15s%15s%6s%14s",
11063              "sw_if_index", "src_address", "dst_address", "teb",
11064              "outer_fib_id");
11065     }
11066
11067   /* Get list of gre-tunnel interfaces */
11068   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
11069
11070   mp->sw_if_index = htonl (sw_if_index);
11071
11072   S;
11073
11074   /* Use a control ping for synchronization */
11075   {
11076     vl_api_control_ping_t *mp;
11077     M (CONTROL_PING, control_ping);
11078     S;
11079   }
11080   W;
11081 }
11082
11083 static int
11084 api_l2_fib_clear_table (vat_main_t * vam)
11085 {
11086 //  unformat_input_t * i = vam->input;
11087   vl_api_l2_fib_clear_table_t *mp;
11088   f64 timeout;
11089
11090   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
11091
11092   S;
11093   W;
11094   /* NOTREACHED */
11095   return 0;
11096 }
11097
11098 static int
11099 api_l2_interface_efp_filter (vat_main_t * vam)
11100 {
11101   unformat_input_t *i = vam->input;
11102   vl_api_l2_interface_efp_filter_t *mp;
11103   f64 timeout;
11104   u32 sw_if_index;
11105   u8 enable = 1;
11106   u8 sw_if_index_set = 0;
11107
11108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11109     {
11110       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11111         sw_if_index_set = 1;
11112       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11113         sw_if_index_set = 1;
11114       else if (unformat (i, "enable"))
11115         enable = 1;
11116       else if (unformat (i, "disable"))
11117         enable = 0;
11118       else
11119         {
11120           clib_warning ("parse error '%U'", format_unformat_error, i);
11121           return -99;
11122         }
11123     }
11124
11125   if (sw_if_index_set == 0)
11126     {
11127       errmsg ("missing sw_if_index");
11128       return -99;
11129     }
11130
11131   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
11132
11133   mp->sw_if_index = ntohl (sw_if_index);
11134   mp->enable_disable = enable;
11135
11136   S;
11137   W;
11138   /* NOTREACHED */
11139   return 0;
11140 }
11141
11142 #define foreach_vtr_op                          \
11143 _("disable",  L2_VTR_DISABLED)                  \
11144 _("push-1",  L2_VTR_PUSH_1)                     \
11145 _("push-2",  L2_VTR_PUSH_2)                     \
11146 _("pop-1",  L2_VTR_POP_1)                       \
11147 _("pop-2",  L2_VTR_POP_2)                       \
11148 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11149 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11150 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11151 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11152
11153 static int
11154 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11155 {
11156   unformat_input_t *i = vam->input;
11157   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11158   f64 timeout;
11159   u32 sw_if_index;
11160   u8 sw_if_index_set = 0;
11161   u8 vtr_op_set = 0;
11162   u32 vtr_op = 0;
11163   u32 push_dot1q = 1;
11164   u32 tag1 = ~0;
11165   u32 tag2 = ~0;
11166
11167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11168     {
11169       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11170         sw_if_index_set = 1;
11171       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11172         sw_if_index_set = 1;
11173       else if (unformat (i, "vtr_op %d", &vtr_op))
11174         vtr_op_set = 1;
11175 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11176       foreach_vtr_op
11177 #undef _
11178         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11179         ;
11180       else if (unformat (i, "tag1 %d", &tag1))
11181         ;
11182       else if (unformat (i, "tag2 %d", &tag2))
11183         ;
11184       else
11185         {
11186           clib_warning ("parse error '%U'", format_unformat_error, i);
11187           return -99;
11188         }
11189     }
11190
11191   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11192     {
11193       errmsg ("missing vtr operation or sw_if_index");
11194       return -99;
11195     }
11196
11197   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
11198     mp->sw_if_index = ntohl (sw_if_index);
11199   mp->vtr_op = ntohl (vtr_op);
11200   mp->push_dot1q = ntohl (push_dot1q);
11201   mp->tag1 = ntohl (tag1);
11202   mp->tag2 = ntohl (tag2);
11203
11204   S;
11205   W;
11206   /* NOTREACHED */
11207   return 0;
11208 }
11209
11210 static int
11211 api_create_vhost_user_if (vat_main_t * vam)
11212 {
11213   unformat_input_t *i = vam->input;
11214   vl_api_create_vhost_user_if_t *mp;
11215   f64 timeout;
11216   u8 *file_name;
11217   u8 is_server = 0;
11218   u8 file_name_set = 0;
11219   u32 custom_dev_instance = ~0;
11220   u8 hwaddr[6];
11221   u8 use_custom_mac = 0;
11222   u8 *tag = 0;
11223
11224   /* Shut up coverity */
11225   memset (hwaddr, 0, sizeof (hwaddr));
11226
11227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11228     {
11229       if (unformat (i, "socket %s", &file_name))
11230         {
11231           file_name_set = 1;
11232         }
11233       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11234         ;
11235       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11236         use_custom_mac = 1;
11237       else if (unformat (i, "server"))
11238         is_server = 1;
11239       else if (unformat (i, "tag %s", &tag))
11240         ;
11241       else
11242         break;
11243     }
11244
11245   if (file_name_set == 0)
11246     {
11247       errmsg ("missing socket file name");
11248       return -99;
11249     }
11250
11251   if (vec_len (file_name) > 255)
11252     {
11253       errmsg ("socket file name too long");
11254       return -99;
11255     }
11256   vec_add1 (file_name, 0);
11257
11258   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
11259
11260   mp->is_server = is_server;
11261   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11262   vec_free (file_name);
11263   if (custom_dev_instance != ~0)
11264     {
11265       mp->renumber = 1;
11266       mp->custom_dev_instance = ntohl (custom_dev_instance);
11267     }
11268   mp->use_custom_mac = use_custom_mac;
11269   clib_memcpy (mp->mac_address, hwaddr, 6);
11270   if (tag)
11271     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11272   vec_free (tag);
11273
11274   S;
11275   W;
11276   /* NOTREACHED */
11277   return 0;
11278 }
11279
11280 static int
11281 api_modify_vhost_user_if (vat_main_t * vam)
11282 {
11283   unformat_input_t *i = vam->input;
11284   vl_api_modify_vhost_user_if_t *mp;
11285   f64 timeout;
11286   u8 *file_name;
11287   u8 is_server = 0;
11288   u8 file_name_set = 0;
11289   u32 custom_dev_instance = ~0;
11290   u8 sw_if_index_set = 0;
11291   u32 sw_if_index = (u32) ~ 0;
11292
11293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11294     {
11295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11296         sw_if_index_set = 1;
11297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11298         sw_if_index_set = 1;
11299       else if (unformat (i, "socket %s", &file_name))
11300         {
11301           file_name_set = 1;
11302         }
11303       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11304         ;
11305       else if (unformat (i, "server"))
11306         is_server = 1;
11307       else
11308         break;
11309     }
11310
11311   if (sw_if_index_set == 0)
11312     {
11313       errmsg ("missing sw_if_index or interface name");
11314       return -99;
11315     }
11316
11317   if (file_name_set == 0)
11318     {
11319       errmsg ("missing socket file name");
11320       return -99;
11321     }
11322
11323   if (vec_len (file_name) > 255)
11324     {
11325       errmsg ("socket file name too long");
11326       return -99;
11327     }
11328   vec_add1 (file_name, 0);
11329
11330   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
11331
11332   mp->sw_if_index = ntohl (sw_if_index);
11333   mp->is_server = is_server;
11334   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11335   vec_free (file_name);
11336   if (custom_dev_instance != ~0)
11337     {
11338       mp->renumber = 1;
11339       mp->custom_dev_instance = ntohl (custom_dev_instance);
11340     }
11341
11342   S;
11343   W;
11344   /* NOTREACHED */
11345   return 0;
11346 }
11347
11348 static int
11349 api_delete_vhost_user_if (vat_main_t * vam)
11350 {
11351   unformat_input_t *i = vam->input;
11352   vl_api_delete_vhost_user_if_t *mp;
11353   f64 timeout;
11354   u32 sw_if_index = ~0;
11355   u8 sw_if_index_set = 0;
11356
11357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11358     {
11359       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11360         sw_if_index_set = 1;
11361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11362         sw_if_index_set = 1;
11363       else
11364         break;
11365     }
11366
11367   if (sw_if_index_set == 0)
11368     {
11369       errmsg ("missing sw_if_index or interface name");
11370       return -99;
11371     }
11372
11373
11374   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
11375
11376   mp->sw_if_index = ntohl (sw_if_index);
11377
11378   S;
11379   W;
11380   /* NOTREACHED */
11381   return 0;
11382 }
11383
11384 static void vl_api_sw_interface_vhost_user_details_t_handler
11385   (vl_api_sw_interface_vhost_user_details_t * mp)
11386 {
11387   vat_main_t *vam = &vat_main;
11388
11389   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11390          (char *) mp->interface_name,
11391          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11392          clib_net_to_host_u64 (mp->features), mp->is_server,
11393          ntohl (mp->num_regions), (char *) mp->sock_filename);
11394   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11395 }
11396
11397 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11398   (vl_api_sw_interface_vhost_user_details_t * mp)
11399 {
11400   vat_main_t *vam = &vat_main;
11401   vat_json_node_t *node = NULL;
11402
11403   if (VAT_JSON_ARRAY != vam->json_tree.type)
11404     {
11405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11406       vat_json_init_array (&vam->json_tree);
11407     }
11408   node = vat_json_array_add (&vam->json_tree);
11409
11410   vat_json_init_object (node);
11411   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11412   vat_json_object_add_string_copy (node, "interface_name",
11413                                    mp->interface_name);
11414   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11415                             ntohl (mp->virtio_net_hdr_sz));
11416   vat_json_object_add_uint (node, "features",
11417                             clib_net_to_host_u64 (mp->features));
11418   vat_json_object_add_uint (node, "is_server", mp->is_server);
11419   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11420   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11421   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11422 }
11423
11424 static int
11425 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11426 {
11427   vl_api_sw_interface_vhost_user_dump_t *mp;
11428   f64 timeout;
11429   print (vam->ofp,
11430          "Interface name           idx hdr_sz features server regions filename");
11431
11432   /* Get list of vhost-user interfaces */
11433   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11434   S;
11435
11436   /* Use a control ping for synchronization */
11437   {
11438     vl_api_control_ping_t *mp;
11439     M (CONTROL_PING, control_ping);
11440     S;
11441   }
11442   W;
11443 }
11444
11445 static int
11446 api_show_version (vat_main_t * vam)
11447 {
11448   vl_api_show_version_t *mp;
11449   f64 timeout;
11450
11451   M (SHOW_VERSION, show_version);
11452
11453   S;
11454   W;
11455   /* NOTREACHED */
11456   return 0;
11457 }
11458
11459
11460 static int
11461 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11462 {
11463   unformat_input_t *line_input = vam->input;
11464   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11465   f64 timeout;
11466   ip4_address_t local4, remote4;
11467   ip6_address_t local6, remote6;
11468   u8 is_add = 1;
11469   u8 ipv4_set = 0, ipv6_set = 0;
11470   u8 local_set = 0;
11471   u8 remote_set = 0;
11472   u32 encap_vrf_id = 0;
11473   u32 decap_vrf_id = 0;
11474   u8 protocol = ~0;
11475   u32 vni;
11476   u8 vni_set = 0;
11477
11478   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11479     {
11480       if (unformat (line_input, "del"))
11481         is_add = 0;
11482       else if (unformat (line_input, "local %U",
11483                          unformat_ip4_address, &local4))
11484         {
11485           local_set = 1;
11486           ipv4_set = 1;
11487         }
11488       else if (unformat (line_input, "remote %U",
11489                          unformat_ip4_address, &remote4))
11490         {
11491           remote_set = 1;
11492           ipv4_set = 1;
11493         }
11494       else if (unformat (line_input, "local %U",
11495                          unformat_ip6_address, &local6))
11496         {
11497           local_set = 1;
11498           ipv6_set = 1;
11499         }
11500       else if (unformat (line_input, "remote %U",
11501                          unformat_ip6_address, &remote6))
11502         {
11503           remote_set = 1;
11504           ipv6_set = 1;
11505         }
11506       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11507         ;
11508       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11509         ;
11510       else if (unformat (line_input, "vni %d", &vni))
11511         vni_set = 1;
11512       else if (unformat (line_input, "next-ip4"))
11513         protocol = 1;
11514       else if (unformat (line_input, "next-ip6"))
11515         protocol = 2;
11516       else if (unformat (line_input, "next-ethernet"))
11517         protocol = 3;
11518       else if (unformat (line_input, "next-nsh"))
11519         protocol = 4;
11520       else
11521         {
11522           errmsg ("parse error '%U'", format_unformat_error, line_input);
11523           return -99;
11524         }
11525     }
11526
11527   if (local_set == 0)
11528     {
11529       errmsg ("tunnel local address not specified");
11530       return -99;
11531     }
11532   if (remote_set == 0)
11533     {
11534       errmsg ("tunnel remote address not specified");
11535       return -99;
11536     }
11537   if (ipv4_set && ipv6_set)
11538     {
11539       errmsg ("both IPv4 and IPv6 addresses specified");
11540       return -99;
11541     }
11542
11543   if (vni_set == 0)
11544     {
11545       errmsg ("vni not specified");
11546       return -99;
11547     }
11548
11549   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11550
11551
11552   if (ipv6_set)
11553     {
11554       clib_memcpy (&mp->local, &local6, sizeof (local6));
11555       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11556     }
11557   else
11558     {
11559       clib_memcpy (&mp->local, &local4, sizeof (local4));
11560       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11561     }
11562
11563   mp->encap_vrf_id = ntohl (encap_vrf_id);
11564   mp->decap_vrf_id = ntohl (decap_vrf_id);
11565   mp->protocol = protocol;
11566   mp->vni = ntohl (vni);
11567   mp->is_add = is_add;
11568   mp->is_ipv6 = ipv6_set;
11569
11570   S;
11571   W;
11572   /* NOTREACHED */
11573   return 0;
11574 }
11575
11576 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11577   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11578 {
11579   vat_main_t *vam = &vat_main;
11580
11581   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11582          ntohl (mp->sw_if_index),
11583          format_ip46_address, &(mp->local[0]),
11584          format_ip46_address, &(mp->remote[0]),
11585          ntohl (mp->vni),
11586          ntohl (mp->protocol),
11587          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11588 }
11589
11590 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11591   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11592 {
11593   vat_main_t *vam = &vat_main;
11594   vat_json_node_t *node = NULL;
11595   struct in_addr ip4;
11596   struct in6_addr ip6;
11597
11598   if (VAT_JSON_ARRAY != vam->json_tree.type)
11599     {
11600       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11601       vat_json_init_array (&vam->json_tree);
11602     }
11603   node = vat_json_array_add (&vam->json_tree);
11604
11605   vat_json_init_object (node);
11606   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11607   if (mp->is_ipv6)
11608     {
11609       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11610       vat_json_object_add_ip6 (node, "local", ip6);
11611       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11612       vat_json_object_add_ip6 (node, "remote", ip6);
11613     }
11614   else
11615     {
11616       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11617       vat_json_object_add_ip4 (node, "local", ip4);
11618       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11619       vat_json_object_add_ip4 (node, "remote", ip4);
11620     }
11621   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11622   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11623   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11624   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11625   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11626 }
11627
11628 static int
11629 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11630 {
11631   unformat_input_t *i = vam->input;
11632   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11633   f64 timeout;
11634   u32 sw_if_index;
11635   u8 sw_if_index_set = 0;
11636
11637   /* Parse args required to build the message */
11638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11639     {
11640       if (unformat (i, "sw_if_index %d", &sw_if_index))
11641         sw_if_index_set = 1;
11642       else
11643         break;
11644     }
11645
11646   if (sw_if_index_set == 0)
11647     {
11648       sw_if_index = ~0;
11649     }
11650
11651   if (!vam->json_output)
11652     {
11653       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11654              "sw_if_index", "local", "remote", "vni",
11655              "protocol", "encap_vrf_id", "decap_vrf_id");
11656     }
11657
11658   /* Get list of vxlan-tunnel interfaces */
11659   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11660
11661   mp->sw_if_index = htonl (sw_if_index);
11662
11663   S;
11664
11665   /* Use a control ping for synchronization */
11666   {
11667     vl_api_control_ping_t *mp;
11668     M (CONTROL_PING, control_ping);
11669     S;
11670   }
11671   W;
11672 }
11673
11674 u8 *
11675 format_l2_fib_mac_address (u8 * s, va_list * args)
11676 {
11677   u8 *a = va_arg (*args, u8 *);
11678
11679   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11680                  a[2], a[3], a[4], a[5], a[6], a[7]);
11681 }
11682
11683 static void vl_api_l2_fib_table_entry_t_handler
11684   (vl_api_l2_fib_table_entry_t * mp)
11685 {
11686   vat_main_t *vam = &vat_main;
11687
11688   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11689          "       %d       %d     %d",
11690          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11691          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11692          mp->bvi_mac);
11693 }
11694
11695 static void vl_api_l2_fib_table_entry_t_handler_json
11696   (vl_api_l2_fib_table_entry_t * mp)
11697 {
11698   vat_main_t *vam = &vat_main;
11699   vat_json_node_t *node = NULL;
11700
11701   if (VAT_JSON_ARRAY != vam->json_tree.type)
11702     {
11703       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11704       vat_json_init_array (&vam->json_tree);
11705     }
11706   node = vat_json_array_add (&vam->json_tree);
11707
11708   vat_json_init_object (node);
11709   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11710   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11711   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11712   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11713   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11714   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11715 }
11716
11717 static int
11718 api_l2_fib_table_dump (vat_main_t * vam)
11719 {
11720   unformat_input_t *i = vam->input;
11721   vl_api_l2_fib_table_dump_t *mp;
11722   f64 timeout;
11723   u32 bd_id;
11724   u8 bd_id_set = 0;
11725
11726   /* Parse args required to build the message */
11727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11728     {
11729       if (unformat (i, "bd_id %d", &bd_id))
11730         bd_id_set = 1;
11731       else
11732         break;
11733     }
11734
11735   if (bd_id_set == 0)
11736     {
11737       errmsg ("missing bridge domain");
11738       return -99;
11739     }
11740
11741   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11742
11743   /* Get list of l2 fib entries */
11744   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11745
11746   mp->bd_id = ntohl (bd_id);
11747   S;
11748
11749   /* Use a control ping for synchronization */
11750   {
11751     vl_api_control_ping_t *mp;
11752     M (CONTROL_PING, control_ping);
11753     S;
11754   }
11755   W;
11756 }
11757
11758
11759 static int
11760 api_interface_name_renumber (vat_main_t * vam)
11761 {
11762   unformat_input_t *line_input = vam->input;
11763   vl_api_interface_name_renumber_t *mp;
11764   u32 sw_if_index = ~0;
11765   f64 timeout;
11766   u32 new_show_dev_instance = ~0;
11767
11768   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11769     {
11770       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11771                     &sw_if_index))
11772         ;
11773       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11774         ;
11775       else if (unformat (line_input, "new_show_dev_instance %d",
11776                          &new_show_dev_instance))
11777         ;
11778       else
11779         break;
11780     }
11781
11782   if (sw_if_index == ~0)
11783     {
11784       errmsg ("missing interface name or sw_if_index");
11785       return -99;
11786     }
11787
11788   if (new_show_dev_instance == ~0)
11789     {
11790       errmsg ("missing new_show_dev_instance");
11791       return -99;
11792     }
11793
11794   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11795
11796   mp->sw_if_index = ntohl (sw_if_index);
11797   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11798
11799   S;
11800   W;
11801 }
11802
11803 static int
11804 api_want_ip4_arp_events (vat_main_t * vam)
11805 {
11806   unformat_input_t *line_input = vam->input;
11807   vl_api_want_ip4_arp_events_t *mp;
11808   f64 timeout;
11809   ip4_address_t address;
11810   int address_set = 0;
11811   u32 enable_disable = 1;
11812
11813   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11814     {
11815       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11816         address_set = 1;
11817       else if (unformat (line_input, "del"))
11818         enable_disable = 0;
11819       else
11820         break;
11821     }
11822
11823   if (address_set == 0)
11824     {
11825       errmsg ("missing addresses");
11826       return -99;
11827     }
11828
11829   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11830   mp->enable_disable = enable_disable;
11831   mp->pid = getpid ();
11832   mp->address = address.as_u32;
11833
11834   S;
11835   W;
11836 }
11837
11838 static int
11839 api_want_ip6_nd_events (vat_main_t * vam)
11840 {
11841   unformat_input_t *line_input = vam->input;
11842   vl_api_want_ip6_nd_events_t *mp;
11843   f64 timeout;
11844   ip6_address_t address;
11845   int address_set = 0;
11846   u32 enable_disable = 1;
11847
11848   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11849     {
11850       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11851         address_set = 1;
11852       else if (unformat (line_input, "del"))
11853         enable_disable = 0;
11854       else
11855         break;
11856     }
11857
11858   if (address_set == 0)
11859     {
11860       errmsg ("missing addresses");
11861       return -99;
11862     }
11863
11864   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11865   mp->enable_disable = enable_disable;
11866   mp->pid = getpid ();
11867   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11868
11869   S;
11870   W;
11871 }
11872
11873 static int
11874 api_input_acl_set_interface (vat_main_t * vam)
11875 {
11876   unformat_input_t *i = vam->input;
11877   vl_api_input_acl_set_interface_t *mp;
11878   f64 timeout;
11879   u32 sw_if_index;
11880   int sw_if_index_set;
11881   u32 ip4_table_index = ~0;
11882   u32 ip6_table_index = ~0;
11883   u32 l2_table_index = ~0;
11884   u8 is_add = 1;
11885
11886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11887     {
11888       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11889         sw_if_index_set = 1;
11890       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11891         sw_if_index_set = 1;
11892       else if (unformat (i, "del"))
11893         is_add = 0;
11894       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11895         ;
11896       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11897         ;
11898       else if (unformat (i, "l2-table %d", &l2_table_index))
11899         ;
11900       else
11901         {
11902           clib_warning ("parse error '%U'", format_unformat_error, i);
11903           return -99;
11904         }
11905     }
11906
11907   if (sw_if_index_set == 0)
11908     {
11909       errmsg ("missing interface name or sw_if_index");
11910       return -99;
11911     }
11912
11913   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11914
11915   mp->sw_if_index = ntohl (sw_if_index);
11916   mp->ip4_table_index = ntohl (ip4_table_index);
11917   mp->ip6_table_index = ntohl (ip6_table_index);
11918   mp->l2_table_index = ntohl (l2_table_index);
11919   mp->is_add = is_add;
11920
11921   S;
11922   W;
11923   /* NOTREACHED */
11924   return 0;
11925 }
11926
11927 static int
11928 api_ip_address_dump (vat_main_t * vam)
11929 {
11930   unformat_input_t *i = vam->input;
11931   vl_api_ip_address_dump_t *mp;
11932   u32 sw_if_index = ~0;
11933   u8 sw_if_index_set = 0;
11934   u8 ipv4_set = 0;
11935   u8 ipv6_set = 0;
11936   f64 timeout;
11937
11938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11939     {
11940       if (unformat (i, "sw_if_index %d", &sw_if_index))
11941         sw_if_index_set = 1;
11942       else
11943         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11944         sw_if_index_set = 1;
11945       else if (unformat (i, "ipv4"))
11946         ipv4_set = 1;
11947       else if (unformat (i, "ipv6"))
11948         ipv6_set = 1;
11949       else
11950         break;
11951     }
11952
11953   if (ipv4_set && ipv6_set)
11954     {
11955       errmsg ("ipv4 and ipv6 flags cannot be both set");
11956       return -99;
11957     }
11958
11959   if ((!ipv4_set) && (!ipv6_set))
11960     {
11961       errmsg ("no ipv4 nor ipv6 flag set");
11962       return -99;
11963     }
11964
11965   if (sw_if_index_set == 0)
11966     {
11967       errmsg ("missing interface name or sw_if_index");
11968       return -99;
11969     }
11970
11971   vam->current_sw_if_index = sw_if_index;
11972   vam->is_ipv6 = ipv6_set;
11973
11974   M (IP_ADDRESS_DUMP, ip_address_dump);
11975   mp->sw_if_index = ntohl (sw_if_index);
11976   mp->is_ipv6 = ipv6_set;
11977   S;
11978
11979   /* Use a control ping for synchronization */
11980   {
11981     vl_api_control_ping_t *mp;
11982     M (CONTROL_PING, control_ping);
11983     S;
11984   }
11985   W;
11986 }
11987
11988 static int
11989 api_ip_dump (vat_main_t * vam)
11990 {
11991   vl_api_ip_dump_t *mp;
11992   unformat_input_t *in = vam->input;
11993   int ipv4_set = 0;
11994   int ipv6_set = 0;
11995   int is_ipv6;
11996   f64 timeout;
11997   int i;
11998
11999   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12000     {
12001       if (unformat (in, "ipv4"))
12002         ipv4_set = 1;
12003       else if (unformat (in, "ipv6"))
12004         ipv6_set = 1;
12005       else
12006         break;
12007     }
12008
12009   if (ipv4_set && ipv6_set)
12010     {
12011       errmsg ("ipv4 and ipv6 flags cannot be both set");
12012       return -99;
12013     }
12014
12015   if ((!ipv4_set) && (!ipv6_set))
12016     {
12017       errmsg ("no ipv4 nor ipv6 flag set");
12018       return -99;
12019     }
12020
12021   is_ipv6 = ipv6_set;
12022   vam->is_ipv6 = is_ipv6;
12023
12024   /* free old data */
12025   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12026     {
12027       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12028     }
12029   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12030
12031   M (IP_DUMP, ip_dump);
12032   mp->is_ipv6 = ipv6_set;
12033   S;
12034
12035   /* Use a control ping for synchronization */
12036   {
12037     vl_api_control_ping_t *mp;
12038     M (CONTROL_PING, control_ping);
12039     S;
12040   }
12041   W;
12042 }
12043
12044 static int
12045 api_ipsec_spd_add_del (vat_main_t * vam)
12046 {
12047   unformat_input_t *i = vam->input;
12048   vl_api_ipsec_spd_add_del_t *mp;
12049   f64 timeout;
12050   u32 spd_id = ~0;
12051   u8 is_add = 1;
12052
12053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12054     {
12055       if (unformat (i, "spd_id %d", &spd_id))
12056         ;
12057       else if (unformat (i, "del"))
12058         is_add = 0;
12059       else
12060         {
12061           clib_warning ("parse error '%U'", format_unformat_error, i);
12062           return -99;
12063         }
12064     }
12065   if (spd_id == ~0)
12066     {
12067       errmsg ("spd_id must be set");
12068       return -99;
12069     }
12070
12071   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
12072
12073   mp->spd_id = ntohl (spd_id);
12074   mp->is_add = is_add;
12075
12076   S;
12077   W;
12078   /* NOTREACHED */
12079   return 0;
12080 }
12081
12082 static int
12083 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12084 {
12085   unformat_input_t *i = vam->input;
12086   vl_api_ipsec_interface_add_del_spd_t *mp;
12087   f64 timeout;
12088   u32 sw_if_index;
12089   u8 sw_if_index_set = 0;
12090   u32 spd_id = (u32) ~ 0;
12091   u8 is_add = 1;
12092
12093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12094     {
12095       if (unformat (i, "del"))
12096         is_add = 0;
12097       else if (unformat (i, "spd_id %d", &spd_id))
12098         ;
12099       else
12100         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12101         sw_if_index_set = 1;
12102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12103         sw_if_index_set = 1;
12104       else
12105         {
12106           clib_warning ("parse error '%U'", format_unformat_error, i);
12107           return -99;
12108         }
12109
12110     }
12111
12112   if (spd_id == (u32) ~ 0)
12113     {
12114       errmsg ("spd_id must be set");
12115       return -99;
12116     }
12117
12118   if (sw_if_index_set == 0)
12119     {
12120       errmsg ("missing interface name or sw_if_index");
12121       return -99;
12122     }
12123
12124   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
12125
12126   mp->spd_id = ntohl (spd_id);
12127   mp->sw_if_index = ntohl (sw_if_index);
12128   mp->is_add = is_add;
12129
12130   S;
12131   W;
12132   /* NOTREACHED */
12133   return 0;
12134 }
12135
12136 static int
12137 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12138 {
12139   unformat_input_t *i = vam->input;
12140   vl_api_ipsec_spd_add_del_entry_t *mp;
12141   f64 timeout;
12142   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12143   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12144   i32 priority = 0;
12145   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12146   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12147   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12148   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12149
12150   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12151   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12152   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12153   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12154   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12155   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12156
12157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12158     {
12159       if (unformat (i, "del"))
12160         is_add = 0;
12161       if (unformat (i, "outbound"))
12162         is_outbound = 1;
12163       if (unformat (i, "inbound"))
12164         is_outbound = 0;
12165       else if (unformat (i, "spd_id %d", &spd_id))
12166         ;
12167       else if (unformat (i, "sa_id %d", &sa_id))
12168         ;
12169       else if (unformat (i, "priority %d", &priority))
12170         ;
12171       else if (unformat (i, "protocol %d", &protocol))
12172         ;
12173       else if (unformat (i, "lport_start %d", &lport_start))
12174         ;
12175       else if (unformat (i, "lport_stop %d", &lport_stop))
12176         ;
12177       else if (unformat (i, "rport_start %d", &rport_start))
12178         ;
12179       else if (unformat (i, "rport_stop %d", &rport_stop))
12180         ;
12181       else
12182         if (unformat
12183             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12184         {
12185           is_ipv6 = 0;
12186           is_ip_any = 0;
12187         }
12188       else
12189         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12190         {
12191           is_ipv6 = 0;
12192           is_ip_any = 0;
12193         }
12194       else
12195         if (unformat
12196             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12197         {
12198           is_ipv6 = 0;
12199           is_ip_any = 0;
12200         }
12201       else
12202         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12203         {
12204           is_ipv6 = 0;
12205           is_ip_any = 0;
12206         }
12207       else
12208         if (unformat
12209             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12210         {
12211           is_ipv6 = 1;
12212           is_ip_any = 0;
12213         }
12214       else
12215         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12216         {
12217           is_ipv6 = 1;
12218           is_ip_any = 0;
12219         }
12220       else
12221         if (unformat
12222             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12223         {
12224           is_ipv6 = 1;
12225           is_ip_any = 0;
12226         }
12227       else
12228         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12229         {
12230           is_ipv6 = 1;
12231           is_ip_any = 0;
12232         }
12233       else
12234         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12235         {
12236           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12237             {
12238               clib_warning ("unsupported action: 'resolve'");
12239               return -99;
12240             }
12241         }
12242       else
12243         {
12244           clib_warning ("parse error '%U'", format_unformat_error, i);
12245           return -99;
12246         }
12247
12248     }
12249
12250   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
12251
12252   mp->spd_id = ntohl (spd_id);
12253   mp->priority = ntohl (priority);
12254   mp->is_outbound = is_outbound;
12255
12256   mp->is_ipv6 = is_ipv6;
12257   if (is_ipv6 || is_ip_any)
12258     {
12259       clib_memcpy (mp->remote_address_start, &raddr6_start,
12260                    sizeof (ip6_address_t));
12261       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12262                    sizeof (ip6_address_t));
12263       clib_memcpy (mp->local_address_start, &laddr6_start,
12264                    sizeof (ip6_address_t));
12265       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12266                    sizeof (ip6_address_t));
12267     }
12268   else
12269     {
12270       clib_memcpy (mp->remote_address_start, &raddr4_start,
12271                    sizeof (ip4_address_t));
12272       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12273                    sizeof (ip4_address_t));
12274       clib_memcpy (mp->local_address_start, &laddr4_start,
12275                    sizeof (ip4_address_t));
12276       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12277                    sizeof (ip4_address_t));
12278     }
12279   mp->protocol = (u8) protocol;
12280   mp->local_port_start = ntohs ((u16) lport_start);
12281   mp->local_port_stop = ntohs ((u16) lport_stop);
12282   mp->remote_port_start = ntohs ((u16) rport_start);
12283   mp->remote_port_stop = ntohs ((u16) rport_stop);
12284   mp->policy = (u8) policy;
12285   mp->sa_id = ntohl (sa_id);
12286   mp->is_add = is_add;
12287   mp->is_ip_any = is_ip_any;
12288   S;
12289   W;
12290   /* NOTREACHED */
12291   return 0;
12292 }
12293
12294 static int
12295 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12296 {
12297   unformat_input_t *i = vam->input;
12298   vl_api_ipsec_sad_add_del_entry_t *mp;
12299   f64 timeout;
12300   u32 sad_id = 0, spi = 0;
12301   u8 *ck = 0, *ik = 0;
12302   u8 is_add = 1;
12303
12304   u8 protocol = IPSEC_PROTOCOL_AH;
12305   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12306   u32 crypto_alg = 0, integ_alg = 0;
12307   ip4_address_t tun_src4;
12308   ip4_address_t tun_dst4;
12309   ip6_address_t tun_src6;
12310   ip6_address_t tun_dst6;
12311
12312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12313     {
12314       if (unformat (i, "del"))
12315         is_add = 0;
12316       else if (unformat (i, "sad_id %d", &sad_id))
12317         ;
12318       else if (unformat (i, "spi %d", &spi))
12319         ;
12320       else if (unformat (i, "esp"))
12321         protocol = IPSEC_PROTOCOL_ESP;
12322       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12323         {
12324           is_tunnel = 1;
12325           is_tunnel_ipv6 = 0;
12326         }
12327       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12328         {
12329           is_tunnel = 1;
12330           is_tunnel_ipv6 = 0;
12331         }
12332       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12333         {
12334           is_tunnel = 1;
12335           is_tunnel_ipv6 = 1;
12336         }
12337       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12338         {
12339           is_tunnel = 1;
12340           is_tunnel_ipv6 = 1;
12341         }
12342       else
12343         if (unformat
12344             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12345         {
12346           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12347               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12348             {
12349               clib_warning ("unsupported crypto-alg: '%U'",
12350                             format_ipsec_crypto_alg, crypto_alg);
12351               return -99;
12352             }
12353         }
12354       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12355         ;
12356       else
12357         if (unformat
12358             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12359         {
12360           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12361               integ_alg >= IPSEC_INTEG_N_ALG)
12362             {
12363               clib_warning ("unsupported integ-alg: '%U'",
12364                             format_ipsec_integ_alg, integ_alg);
12365               return -99;
12366             }
12367         }
12368       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12369         ;
12370       else
12371         {
12372           clib_warning ("parse error '%U'", format_unformat_error, i);
12373           return -99;
12374         }
12375
12376     }
12377
12378   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12379
12380   mp->sad_id = ntohl (sad_id);
12381   mp->is_add = is_add;
12382   mp->protocol = protocol;
12383   mp->spi = ntohl (spi);
12384   mp->is_tunnel = is_tunnel;
12385   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12386   mp->crypto_algorithm = crypto_alg;
12387   mp->integrity_algorithm = integ_alg;
12388   mp->crypto_key_length = vec_len (ck);
12389   mp->integrity_key_length = vec_len (ik);
12390
12391   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12392     mp->crypto_key_length = sizeof (mp->crypto_key);
12393
12394   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12395     mp->integrity_key_length = sizeof (mp->integrity_key);
12396
12397   if (ck)
12398     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12399   if (ik)
12400     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12401
12402   if (is_tunnel)
12403     {
12404       if (is_tunnel_ipv6)
12405         {
12406           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12407                        sizeof (ip6_address_t));
12408           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12409                        sizeof (ip6_address_t));
12410         }
12411       else
12412         {
12413           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12414                        sizeof (ip4_address_t));
12415           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12416                        sizeof (ip4_address_t));
12417         }
12418     }
12419
12420   S;
12421   W;
12422   /* NOTREACHED */
12423   return 0;
12424 }
12425
12426 static int
12427 api_ipsec_sa_set_key (vat_main_t * vam)
12428 {
12429   unformat_input_t *i = vam->input;
12430   vl_api_ipsec_sa_set_key_t *mp;
12431   f64 timeout;
12432   u32 sa_id;
12433   u8 *ck = 0, *ik = 0;
12434
12435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12436     {
12437       if (unformat (i, "sa_id %d", &sa_id))
12438         ;
12439       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12440         ;
12441       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12442         ;
12443       else
12444         {
12445           clib_warning ("parse error '%U'", format_unformat_error, i);
12446           return -99;
12447         }
12448     }
12449
12450   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12451
12452   mp->sa_id = ntohl (sa_id);
12453   mp->crypto_key_length = vec_len (ck);
12454   mp->integrity_key_length = vec_len (ik);
12455
12456   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12457     mp->crypto_key_length = sizeof (mp->crypto_key);
12458
12459   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12460     mp->integrity_key_length = sizeof (mp->integrity_key);
12461
12462   if (ck)
12463     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12464   if (ik)
12465     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12466
12467   S;
12468   W;
12469   /* NOTREACHED */
12470   return 0;
12471 }
12472
12473 static int
12474 api_ikev2_profile_add_del (vat_main_t * vam)
12475 {
12476   unformat_input_t *i = vam->input;
12477   vl_api_ikev2_profile_add_del_t *mp;
12478   f64 timeout;
12479   u8 is_add = 1;
12480   u8 *name = 0;
12481
12482   const char *valid_chars = "a-zA-Z0-9_";
12483
12484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12485     {
12486       if (unformat (i, "del"))
12487         is_add = 0;
12488       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12489         vec_add1 (name, 0);
12490       else
12491         {
12492           errmsg ("parse error '%U'", format_unformat_error, i);
12493           return -99;
12494         }
12495     }
12496
12497   if (!vec_len (name))
12498     {
12499       errmsg ("profile name must be specified");
12500       return -99;
12501     }
12502
12503   if (vec_len (name) > 64)
12504     {
12505       errmsg ("profile name too long");
12506       return -99;
12507     }
12508
12509   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12510
12511   clib_memcpy (mp->name, name, vec_len (name));
12512   mp->is_add = is_add;
12513   vec_free (name);
12514
12515   S;
12516   W;
12517   /* NOTREACHED */
12518   return 0;
12519 }
12520
12521 static int
12522 api_ikev2_profile_set_auth (vat_main_t * vam)
12523 {
12524   unformat_input_t *i = vam->input;
12525   vl_api_ikev2_profile_set_auth_t *mp;
12526   f64 timeout;
12527   u8 *name = 0;
12528   u8 *data = 0;
12529   u32 auth_method = 0;
12530   u8 is_hex = 0;
12531
12532   const char *valid_chars = "a-zA-Z0-9_";
12533
12534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12535     {
12536       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12537         vec_add1 (name, 0);
12538       else if (unformat (i, "auth_method %U",
12539                          unformat_ikev2_auth_method, &auth_method))
12540         ;
12541       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12542         is_hex = 1;
12543       else if (unformat (i, "auth_data %v", &data))
12544         ;
12545       else
12546         {
12547           errmsg ("parse error '%U'", format_unformat_error, i);
12548           return -99;
12549         }
12550     }
12551
12552   if (!vec_len (name))
12553     {
12554       errmsg ("profile name must be specified");
12555       return -99;
12556     }
12557
12558   if (vec_len (name) > 64)
12559     {
12560       errmsg ("profile name too long");
12561       return -99;
12562     }
12563
12564   if (!vec_len (data))
12565     {
12566       errmsg ("auth_data must be specified");
12567       return -99;
12568     }
12569
12570   if (!auth_method)
12571     {
12572       errmsg ("auth_method must be specified");
12573       return -99;
12574     }
12575
12576   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12577
12578   mp->is_hex = is_hex;
12579   mp->auth_method = (u8) auth_method;
12580   mp->data_len = vec_len (data);
12581   clib_memcpy (mp->name, name, vec_len (name));
12582   clib_memcpy (mp->data, data, vec_len (data));
12583   vec_free (name);
12584   vec_free (data);
12585
12586   S;
12587   W;
12588   /* NOTREACHED */
12589   return 0;
12590 }
12591
12592 static int
12593 api_ikev2_profile_set_id (vat_main_t * vam)
12594 {
12595   unformat_input_t *i = vam->input;
12596   vl_api_ikev2_profile_set_id_t *mp;
12597   f64 timeout;
12598   u8 *name = 0;
12599   u8 *data = 0;
12600   u8 is_local = 0;
12601   u32 id_type = 0;
12602   ip4_address_t ip4;
12603
12604   const char *valid_chars = "a-zA-Z0-9_";
12605
12606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12607     {
12608       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12609         vec_add1 (name, 0);
12610       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12611         ;
12612       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12613         {
12614           data = vec_new (u8, 4);
12615           clib_memcpy (data, ip4.as_u8, 4);
12616         }
12617       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12618         ;
12619       else if (unformat (i, "id_data %v", &data))
12620         ;
12621       else if (unformat (i, "local"))
12622         is_local = 1;
12623       else if (unformat (i, "remote"))
12624         is_local = 0;
12625       else
12626         {
12627           errmsg ("parse error '%U'", format_unformat_error, i);
12628           return -99;
12629         }
12630     }
12631
12632   if (!vec_len (name))
12633     {
12634       errmsg ("profile name must be specified");
12635       return -99;
12636     }
12637
12638   if (vec_len (name) > 64)
12639     {
12640       errmsg ("profile name too long");
12641       return -99;
12642     }
12643
12644   if (!vec_len (data))
12645     {
12646       errmsg ("id_data must be specified");
12647       return -99;
12648     }
12649
12650   if (!id_type)
12651     {
12652       errmsg ("id_type must be specified");
12653       return -99;
12654     }
12655
12656   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12657
12658   mp->is_local = is_local;
12659   mp->id_type = (u8) id_type;
12660   mp->data_len = vec_len (data);
12661   clib_memcpy (mp->name, name, vec_len (name));
12662   clib_memcpy (mp->data, data, vec_len (data));
12663   vec_free (name);
12664   vec_free (data);
12665
12666   S;
12667   W;
12668   /* NOTREACHED */
12669   return 0;
12670 }
12671
12672 static int
12673 api_ikev2_profile_set_ts (vat_main_t * vam)
12674 {
12675   unformat_input_t *i = vam->input;
12676   vl_api_ikev2_profile_set_ts_t *mp;
12677   f64 timeout;
12678   u8 *name = 0;
12679   u8 is_local = 0;
12680   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12681   ip4_address_t start_addr, end_addr;
12682
12683   const char *valid_chars = "a-zA-Z0-9_";
12684
12685   start_addr.as_u32 = 0;
12686   end_addr.as_u32 = (u32) ~ 0;
12687
12688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12689     {
12690       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12691         vec_add1 (name, 0);
12692       else if (unformat (i, "protocol %d", &proto))
12693         ;
12694       else if (unformat (i, "start_port %d", &start_port))
12695         ;
12696       else if (unformat (i, "end_port %d", &end_port))
12697         ;
12698       else
12699         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12700         ;
12701       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12702         ;
12703       else if (unformat (i, "local"))
12704         is_local = 1;
12705       else if (unformat (i, "remote"))
12706         is_local = 0;
12707       else
12708         {
12709           errmsg ("parse error '%U'", format_unformat_error, i);
12710           return -99;
12711         }
12712     }
12713
12714   if (!vec_len (name))
12715     {
12716       errmsg ("profile name must be specified");
12717       return -99;
12718     }
12719
12720   if (vec_len (name) > 64)
12721     {
12722       errmsg ("profile name too long");
12723       return -99;
12724     }
12725
12726   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12727
12728   mp->is_local = is_local;
12729   mp->proto = (u8) proto;
12730   mp->start_port = (u16) start_port;
12731   mp->end_port = (u16) end_port;
12732   mp->start_addr = start_addr.as_u32;
12733   mp->end_addr = end_addr.as_u32;
12734   clib_memcpy (mp->name, name, vec_len (name));
12735   vec_free (name);
12736
12737   S;
12738   W;
12739   /* NOTREACHED */
12740   return 0;
12741 }
12742
12743 static int
12744 api_ikev2_set_local_key (vat_main_t * vam)
12745 {
12746   unformat_input_t *i = vam->input;
12747   vl_api_ikev2_set_local_key_t *mp;
12748   f64 timeout;
12749   u8 *file = 0;
12750
12751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12752     {
12753       if (unformat (i, "file %v", &file))
12754         vec_add1 (file, 0);
12755       else
12756         {
12757           errmsg ("parse error '%U'", format_unformat_error, i);
12758           return -99;
12759         }
12760     }
12761
12762   if (!vec_len (file))
12763     {
12764       errmsg ("RSA key file must be specified");
12765       return -99;
12766     }
12767
12768   if (vec_len (file) > 256)
12769     {
12770       errmsg ("file name too long");
12771       return -99;
12772     }
12773
12774   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12775
12776   clib_memcpy (mp->key_file, file, vec_len (file));
12777   vec_free (file);
12778
12779   S;
12780   W;
12781   /* NOTREACHED */
12782   return 0;
12783 }
12784
12785 /*
12786  * MAP
12787  */
12788 static int
12789 api_map_add_domain (vat_main_t * vam)
12790 {
12791   unformat_input_t *i = vam->input;
12792   vl_api_map_add_domain_t *mp;
12793   f64 timeout;
12794
12795   ip4_address_t ip4_prefix;
12796   ip6_address_t ip6_prefix;
12797   ip6_address_t ip6_src;
12798   u32 num_m_args = 0;
12799   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12800     0, psid_length = 0;
12801   u8 is_translation = 0;
12802   u32 mtu = 0;
12803   u32 ip6_src_len = 128;
12804
12805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12806     {
12807       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12808                     &ip4_prefix, &ip4_prefix_len))
12809         num_m_args++;
12810       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12811                          &ip6_prefix, &ip6_prefix_len))
12812         num_m_args++;
12813       else
12814         if (unformat
12815             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12816              &ip6_src_len))
12817         num_m_args++;
12818       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12819         num_m_args++;
12820       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12821         num_m_args++;
12822       else if (unformat (i, "psid-offset %d", &psid_offset))
12823         num_m_args++;
12824       else if (unformat (i, "psid-len %d", &psid_length))
12825         num_m_args++;
12826       else if (unformat (i, "mtu %d", &mtu))
12827         num_m_args++;
12828       else if (unformat (i, "map-t"))
12829         is_translation = 1;
12830       else
12831         {
12832           clib_warning ("parse error '%U'", format_unformat_error, i);
12833           return -99;
12834         }
12835     }
12836
12837   if (num_m_args < 3)
12838     {
12839       errmsg ("mandatory argument(s) missing");
12840       return -99;
12841     }
12842
12843   /* Construct the API message */
12844   M (MAP_ADD_DOMAIN, map_add_domain);
12845
12846   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12847   mp->ip4_prefix_len = ip4_prefix_len;
12848
12849   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12850   mp->ip6_prefix_len = ip6_prefix_len;
12851
12852   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12853   mp->ip6_src_prefix_len = ip6_src_len;
12854
12855   mp->ea_bits_len = ea_bits_len;
12856   mp->psid_offset = psid_offset;
12857   mp->psid_length = psid_length;
12858   mp->is_translation = is_translation;
12859   mp->mtu = htons (mtu);
12860
12861   /* send it... */
12862   S;
12863
12864   /* Wait for a reply, return good/bad news  */
12865   W;
12866 }
12867
12868 static int
12869 api_map_del_domain (vat_main_t * vam)
12870 {
12871   unformat_input_t *i = vam->input;
12872   vl_api_map_del_domain_t *mp;
12873   f64 timeout;
12874
12875   u32 num_m_args = 0;
12876   u32 index;
12877
12878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12879     {
12880       if (unformat (i, "index %d", &index))
12881         num_m_args++;
12882       else
12883         {
12884           clib_warning ("parse error '%U'", format_unformat_error, i);
12885           return -99;
12886         }
12887     }
12888
12889   if (num_m_args != 1)
12890     {
12891       errmsg ("mandatory argument(s) missing");
12892       return -99;
12893     }
12894
12895   /* Construct the API message */
12896   M (MAP_DEL_DOMAIN, map_del_domain);
12897
12898   mp->index = ntohl (index);
12899
12900   /* send it... */
12901   S;
12902
12903   /* Wait for a reply, return good/bad news  */
12904   W;
12905 }
12906
12907 static int
12908 api_map_add_del_rule (vat_main_t * vam)
12909 {
12910   unformat_input_t *i = vam->input;
12911   vl_api_map_add_del_rule_t *mp;
12912   f64 timeout;
12913   u8 is_add = 1;
12914   ip6_address_t ip6_dst;
12915   u32 num_m_args = 0, index, psid = 0;
12916
12917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12918     {
12919       if (unformat (i, "index %d", &index))
12920         num_m_args++;
12921       else if (unformat (i, "psid %d", &psid))
12922         num_m_args++;
12923       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12924         num_m_args++;
12925       else if (unformat (i, "del"))
12926         {
12927           is_add = 0;
12928         }
12929       else
12930         {
12931           clib_warning ("parse error '%U'", format_unformat_error, i);
12932           return -99;
12933         }
12934     }
12935
12936   /* Construct the API message */
12937   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12938
12939   mp->index = ntohl (index);
12940   mp->is_add = is_add;
12941   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12942   mp->psid = ntohs (psid);
12943
12944   /* send it... */
12945   S;
12946
12947   /* Wait for a reply, return good/bad news  */
12948   W;
12949 }
12950
12951 static int
12952 api_map_domain_dump (vat_main_t * vam)
12953 {
12954   vl_api_map_domain_dump_t *mp;
12955   f64 timeout;
12956
12957   /* Construct the API message */
12958   M (MAP_DOMAIN_DUMP, map_domain_dump);
12959
12960   /* send it... */
12961   S;
12962
12963   /* Use a control ping for synchronization */
12964   {
12965     vl_api_control_ping_t *mp;
12966     M (CONTROL_PING, control_ping);
12967     S;
12968   }
12969   W;
12970 }
12971
12972 static int
12973 api_map_rule_dump (vat_main_t * vam)
12974 {
12975   unformat_input_t *i = vam->input;
12976   vl_api_map_rule_dump_t *mp;
12977   f64 timeout;
12978   u32 domain_index = ~0;
12979
12980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12981     {
12982       if (unformat (i, "index %u", &domain_index))
12983         ;
12984       else
12985         break;
12986     }
12987
12988   if (domain_index == ~0)
12989     {
12990       clib_warning ("parse error: domain index expected");
12991       return -99;
12992     }
12993
12994   /* Construct the API message */
12995   M (MAP_RULE_DUMP, map_rule_dump);
12996
12997   mp->domain_index = htonl (domain_index);
12998
12999   /* send it... */
13000   S;
13001
13002   /* Use a control ping for synchronization */
13003   {
13004     vl_api_control_ping_t *mp;
13005     M (CONTROL_PING, control_ping);
13006     S;
13007   }
13008   W;
13009 }
13010
13011 static void vl_api_map_add_domain_reply_t_handler
13012   (vl_api_map_add_domain_reply_t * mp)
13013 {
13014   vat_main_t *vam = &vat_main;
13015   i32 retval = ntohl (mp->retval);
13016
13017   if (vam->async_mode)
13018     {
13019       vam->async_errors += (retval < 0);
13020     }
13021   else
13022     {
13023       vam->retval = retval;
13024       vam->result_ready = 1;
13025     }
13026 }
13027
13028 static void vl_api_map_add_domain_reply_t_handler_json
13029   (vl_api_map_add_domain_reply_t * mp)
13030 {
13031   vat_main_t *vam = &vat_main;
13032   vat_json_node_t node;
13033
13034   vat_json_init_object (&node);
13035   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13036   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13037
13038   vat_json_print (vam->ofp, &node);
13039   vat_json_free (&node);
13040
13041   vam->retval = ntohl (mp->retval);
13042   vam->result_ready = 1;
13043 }
13044
13045 static int
13046 api_get_first_msg_id (vat_main_t * vam)
13047 {
13048   vl_api_get_first_msg_id_t *mp;
13049   f64 timeout;
13050   unformat_input_t *i = vam->input;
13051   u8 *name;
13052   u8 name_set = 0;
13053
13054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13055     {
13056       if (unformat (i, "client %s", &name))
13057         name_set = 1;
13058       else
13059         break;
13060     }
13061
13062   if (name_set == 0)
13063     {
13064       errmsg ("missing client name");
13065       return -99;
13066     }
13067   vec_add1 (name, 0);
13068
13069   if (vec_len (name) > 63)
13070     {
13071       errmsg ("client name too long");
13072       return -99;
13073     }
13074
13075   M (GET_FIRST_MSG_ID, get_first_msg_id);
13076   clib_memcpy (mp->name, name, vec_len (name));
13077   S;
13078   W;
13079   /* NOTREACHED */
13080   return 0;
13081 }
13082
13083 static int
13084 api_cop_interface_enable_disable (vat_main_t * vam)
13085 {
13086   unformat_input_t *line_input = vam->input;
13087   vl_api_cop_interface_enable_disable_t *mp;
13088   f64 timeout;
13089   u32 sw_if_index = ~0;
13090   u8 enable_disable = 1;
13091
13092   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13093     {
13094       if (unformat (line_input, "disable"))
13095         enable_disable = 0;
13096       if (unformat (line_input, "enable"))
13097         enable_disable = 1;
13098       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13099                          vam, &sw_if_index))
13100         ;
13101       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13102         ;
13103       else
13104         break;
13105     }
13106
13107   if (sw_if_index == ~0)
13108     {
13109       errmsg ("missing interface name or sw_if_index");
13110       return -99;
13111     }
13112
13113   /* Construct the API message */
13114   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
13115   mp->sw_if_index = ntohl (sw_if_index);
13116   mp->enable_disable = enable_disable;
13117
13118   /* send it... */
13119   S;
13120   /* Wait for the reply */
13121   W;
13122 }
13123
13124 static int
13125 api_cop_whitelist_enable_disable (vat_main_t * vam)
13126 {
13127   unformat_input_t *line_input = vam->input;
13128   vl_api_cop_whitelist_enable_disable_t *mp;
13129   f64 timeout;
13130   u32 sw_if_index = ~0;
13131   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13132   u32 fib_id = 0;
13133
13134   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13135     {
13136       if (unformat (line_input, "ip4"))
13137         ip4 = 1;
13138       else if (unformat (line_input, "ip6"))
13139         ip6 = 1;
13140       else if (unformat (line_input, "default"))
13141         default_cop = 1;
13142       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13143                          vam, &sw_if_index))
13144         ;
13145       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13146         ;
13147       else if (unformat (line_input, "fib-id %d", &fib_id))
13148         ;
13149       else
13150         break;
13151     }
13152
13153   if (sw_if_index == ~0)
13154     {
13155       errmsg ("missing interface name or sw_if_index");
13156       return -99;
13157     }
13158
13159   /* Construct the API message */
13160   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
13161   mp->sw_if_index = ntohl (sw_if_index);
13162   mp->fib_id = ntohl (fib_id);
13163   mp->ip4 = ip4;
13164   mp->ip6 = ip6;
13165   mp->default_cop = default_cop;
13166
13167   /* send it... */
13168   S;
13169   /* Wait for the reply */
13170   W;
13171 }
13172
13173 static int
13174 api_get_node_graph (vat_main_t * vam)
13175 {
13176   vl_api_get_node_graph_t *mp;
13177   f64 timeout;
13178
13179   M (GET_NODE_GRAPH, get_node_graph);
13180
13181   /* send it... */
13182   S;
13183   /* Wait for the reply */
13184   W;
13185 }
13186
13187 /* *INDENT-OFF* */
13188 /** Used for parsing LISP eids */
13189 typedef CLIB_PACKED(struct{
13190   u8 addr[16];   /**< eid address */
13191   u32 len;       /**< prefix length if IP */
13192   u8 type;      /**< type of eid */
13193 }) lisp_eid_vat_t;
13194 /* *INDENT-ON* */
13195
13196 static uword
13197 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13198 {
13199   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13200
13201   memset (a, 0, sizeof (a[0]));
13202
13203   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13204     {
13205       a->type = 0;              /* ipv4 type */
13206     }
13207   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13208     {
13209       a->type = 1;              /* ipv6 type */
13210     }
13211   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13212     {
13213       a->type = 2;              /* mac type */
13214     }
13215   else
13216     {
13217       return 0;
13218     }
13219
13220   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13221     {
13222       return 0;
13223     }
13224
13225   return 1;
13226 }
13227
13228 static int
13229 lisp_eid_size_vat (u8 type)
13230 {
13231   switch (type)
13232     {
13233     case 0:
13234       return 4;
13235     case 1:
13236       return 16;
13237     case 2:
13238       return 6;
13239     }
13240   return 0;
13241 }
13242
13243 static void
13244 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13245 {
13246   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13247 }
13248
13249 /* *INDENT-OFF* */
13250 /** Used for transferring locators via VPP API */
13251 typedef CLIB_PACKED(struct
13252 {
13253   u32 sw_if_index; /**< locator sw_if_index */
13254   u8 priority; /**< locator priority */
13255   u8 weight;   /**< locator weight */
13256 }) ls_locator_t;
13257 /* *INDENT-ON* */
13258
13259 static int
13260 api_lisp_add_del_locator_set (vat_main_t * vam)
13261 {
13262   unformat_input_t *input = vam->input;
13263   vl_api_lisp_add_del_locator_set_t *mp;
13264   f64 timeout = ~0;
13265   u8 is_add = 1;
13266   u8 *locator_set_name = NULL;
13267   u8 locator_set_name_set = 0;
13268   ls_locator_t locator, *locators = 0;
13269   u32 sw_if_index, priority, weight;
13270   u32 data_len = 0;
13271
13272   /* Parse args required to build the message */
13273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13274     {
13275       if (unformat (input, "del"))
13276         {
13277           is_add = 0;
13278         }
13279       else if (unformat (input, "locator-set %s", &locator_set_name))
13280         {
13281           locator_set_name_set = 1;
13282         }
13283       else if (unformat (input, "sw_if_index %u p %u w %u",
13284                          &sw_if_index, &priority, &weight))
13285         {
13286           locator.sw_if_index = htonl (sw_if_index);
13287           locator.priority = priority;
13288           locator.weight = weight;
13289           vec_add1 (locators, locator);
13290         }
13291       else
13292         if (unformat
13293             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13294              &sw_if_index, &priority, &weight))
13295         {
13296           locator.sw_if_index = htonl (sw_if_index);
13297           locator.priority = priority;
13298           locator.weight = weight;
13299           vec_add1 (locators, locator);
13300         }
13301       else
13302         break;
13303     }
13304
13305   if (locator_set_name_set == 0)
13306     {
13307       errmsg ("missing locator-set name");
13308       vec_free (locators);
13309       return -99;
13310     }
13311
13312   if (vec_len (locator_set_name) > 64)
13313     {
13314       errmsg ("locator-set name too long");
13315       vec_free (locator_set_name);
13316       vec_free (locators);
13317       return -99;
13318     }
13319   vec_add1 (locator_set_name, 0);
13320
13321   data_len = sizeof (ls_locator_t) * vec_len (locators);
13322
13323   /* Construct the API message */
13324   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
13325
13326   mp->is_add = is_add;
13327   clib_memcpy (mp->locator_set_name, locator_set_name,
13328                vec_len (locator_set_name));
13329   vec_free (locator_set_name);
13330
13331   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13332   if (locators)
13333     clib_memcpy (mp->locators, locators, data_len);
13334   vec_free (locators);
13335
13336   /* send it... */
13337   S;
13338
13339   /* Wait for a reply... */
13340   W;
13341
13342   /* NOTREACHED */
13343   return 0;
13344 }
13345
13346 static int
13347 api_lisp_add_del_locator (vat_main_t * vam)
13348 {
13349   unformat_input_t *input = vam->input;
13350   vl_api_lisp_add_del_locator_t *mp;
13351   f64 timeout = ~0;
13352   u32 tmp_if_index = ~0;
13353   u32 sw_if_index = ~0;
13354   u8 sw_if_index_set = 0;
13355   u8 sw_if_index_if_name_set = 0;
13356   u32 priority = ~0;
13357   u8 priority_set = 0;
13358   u32 weight = ~0;
13359   u8 weight_set = 0;
13360   u8 is_add = 1;
13361   u8 *locator_set_name = NULL;
13362   u8 locator_set_name_set = 0;
13363
13364   /* Parse args required to build the message */
13365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13366     {
13367       if (unformat (input, "del"))
13368         {
13369           is_add = 0;
13370         }
13371       else if (unformat (input, "locator-set %s", &locator_set_name))
13372         {
13373           locator_set_name_set = 1;
13374         }
13375       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13376                          &tmp_if_index))
13377         {
13378           sw_if_index_if_name_set = 1;
13379           sw_if_index = tmp_if_index;
13380         }
13381       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13382         {
13383           sw_if_index_set = 1;
13384           sw_if_index = tmp_if_index;
13385         }
13386       else if (unformat (input, "p %d", &priority))
13387         {
13388           priority_set = 1;
13389         }
13390       else if (unformat (input, "w %d", &weight))
13391         {
13392           weight_set = 1;
13393         }
13394       else
13395         break;
13396     }
13397
13398   if (locator_set_name_set == 0)
13399     {
13400       errmsg ("missing locator-set name");
13401       return -99;
13402     }
13403
13404   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13405     {
13406       errmsg ("missing sw_if_index");
13407       vec_free (locator_set_name);
13408       return -99;
13409     }
13410
13411   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13412     {
13413       errmsg ("cannot use both params interface name and sw_if_index");
13414       vec_free (locator_set_name);
13415       return -99;
13416     }
13417
13418   if (priority_set == 0)
13419     {
13420       errmsg ("missing locator-set priority");
13421       vec_free (locator_set_name);
13422       return -99;
13423     }
13424
13425   if (weight_set == 0)
13426     {
13427       errmsg ("missing locator-set weight");
13428       vec_free (locator_set_name);
13429       return -99;
13430     }
13431
13432   if (vec_len (locator_set_name) > 64)
13433     {
13434       errmsg ("locator-set name too long");
13435       vec_free (locator_set_name);
13436       return -99;
13437     }
13438   vec_add1 (locator_set_name, 0);
13439
13440   /* Construct the API message */
13441   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13442
13443   mp->is_add = is_add;
13444   mp->sw_if_index = ntohl (sw_if_index);
13445   mp->priority = priority;
13446   mp->weight = weight;
13447   clib_memcpy (mp->locator_set_name, locator_set_name,
13448                vec_len (locator_set_name));
13449   vec_free (locator_set_name);
13450
13451   /* send it... */
13452   S;
13453
13454   /* Wait for a reply... */
13455   W;
13456
13457   /* NOTREACHED */
13458   return 0;
13459 }
13460
13461 uword
13462 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13463 {
13464   u32 *key_id = va_arg (*args, u32 *);
13465   u8 *s = 0;
13466
13467   if (unformat (input, "%s", &s))
13468     {
13469       if (!strcmp ((char *) s, "sha1"))
13470         key_id[0] = HMAC_SHA_1_96;
13471       else if (!strcmp ((char *) s, "sha256"))
13472         key_id[0] = HMAC_SHA_256_128;
13473       else
13474         {
13475           clib_warning ("invalid key_id: '%s'", s);
13476           key_id[0] = HMAC_NO_KEY;
13477         }
13478     }
13479   else
13480     return 0;
13481
13482   vec_free (s);
13483   return 1;
13484 }
13485
13486 static int
13487 api_lisp_add_del_local_eid (vat_main_t * vam)
13488 {
13489   unformat_input_t *input = vam->input;
13490   vl_api_lisp_add_del_local_eid_t *mp;
13491   f64 timeout = ~0;
13492   u8 is_add = 1;
13493   u8 eid_set = 0;
13494   lisp_eid_vat_t _eid, *eid = &_eid;
13495   u8 *locator_set_name = 0;
13496   u8 locator_set_name_set = 0;
13497   u32 vni = 0;
13498   u16 key_id = 0;
13499   u8 *key = 0;
13500
13501   /* Parse args required to build the message */
13502   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13503     {
13504       if (unformat (input, "del"))
13505         {
13506           is_add = 0;
13507         }
13508       else if (unformat (input, "vni %d", &vni))
13509         {
13510           ;
13511         }
13512       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13513         {
13514           eid_set = 1;
13515         }
13516       else if (unformat (input, "locator-set %s", &locator_set_name))
13517         {
13518           locator_set_name_set = 1;
13519         }
13520       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13521         ;
13522       else if (unformat (input, "secret-key %_%v%_", &key))
13523         ;
13524       else
13525         break;
13526     }
13527
13528   if (locator_set_name_set == 0)
13529     {
13530       errmsg ("missing locator-set name");
13531       return -99;
13532     }
13533
13534   if (0 == eid_set)
13535     {
13536       errmsg ("EID address not set!");
13537       vec_free (locator_set_name);
13538       return -99;
13539     }
13540
13541   if (key && (0 == key_id))
13542     {
13543       errmsg ("invalid key_id!");
13544       return -99;
13545     }
13546
13547   if (vec_len (key) > 64)
13548     {
13549       errmsg ("key too long");
13550       vec_free (key);
13551       return -99;
13552     }
13553
13554   if (vec_len (locator_set_name) > 64)
13555     {
13556       errmsg ("locator-set name too long");
13557       vec_free (locator_set_name);
13558       return -99;
13559     }
13560   vec_add1 (locator_set_name, 0);
13561
13562   /* Construct the API message */
13563   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13564
13565   mp->is_add = is_add;
13566   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13567   mp->eid_type = eid->type;
13568   mp->prefix_len = eid->len;
13569   mp->vni = clib_host_to_net_u32 (vni);
13570   mp->key_id = clib_host_to_net_u16 (key_id);
13571   clib_memcpy (mp->locator_set_name, locator_set_name,
13572                vec_len (locator_set_name));
13573   clib_memcpy (mp->key, key, vec_len (key));
13574
13575   vec_free (locator_set_name);
13576   vec_free (key);
13577
13578   /* send it... */
13579   S;
13580
13581   /* Wait for a reply... */
13582   W;
13583
13584   /* NOTREACHED */
13585   return 0;
13586 }
13587
13588 /* *INDENT-OFF* */
13589 /** Used for transferring locators via VPP API */
13590 typedef CLIB_PACKED(struct
13591 {
13592   u8 is_ip4; /**< is locator an IPv4 address? */
13593   u8 priority; /**< locator priority */
13594   u8 weight;   /**< locator weight */
13595   u8 addr[16]; /**< IPv4/IPv6 address */
13596 }) rloc_t;
13597 /* *INDENT-ON* */
13598
13599 static int
13600 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13601 {
13602   u32 dp_table = 0, vni = 0;;
13603   unformat_input_t *input = vam->input;
13604   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13605   f64 timeout = ~0;
13606   u8 is_add = 1;
13607   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13608   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13609   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13610   u32 action = ~0, w;
13611   ip4_address_t rmt_rloc4, lcl_rloc4;
13612   ip6_address_t rmt_rloc6, lcl_rloc6;
13613   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13614     0;
13615
13616   memset (&rloc, 0, sizeof (rloc));
13617
13618   /* Parse args required to build the message */
13619   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13620     {
13621       if (unformat (input, "del"))
13622         is_add = 0;
13623       else if (unformat (input, "add"))
13624         is_add = 1;
13625       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13626         {
13627           rmt_eid_set = 1;
13628         }
13629       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13630         {
13631           lcl_eid_set = 1;
13632         }
13633       else if (unformat (input, "vrf %d", &dp_table))
13634         ;
13635       else if (unformat (input, "bd %d", &dp_table))
13636         ;
13637       else if (unformat (input, "vni %d", &vni))
13638         ;
13639       else if (unformat (input, "w %d", &w))
13640         {
13641           if (!curr_rloc)
13642             {
13643               errmsg ("No RLOC configured for setting priority/weight!");
13644               return -99;
13645             }
13646           curr_rloc->weight = w;
13647         }
13648       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13649                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13650         {
13651           rloc.is_ip4 = 1;
13652
13653           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13654           rloc.weight = 0;
13655           vec_add1 (lcl_locs, rloc);
13656
13657           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13658           vec_add1 (rmt_locs, rloc);
13659           /* weight saved in rmt loc */
13660           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13661         }
13662       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13663                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13664         {
13665           rloc.is_ip4 = 0;
13666           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13667           rloc.weight = 0;
13668           vec_add1 (lcl_locs, rloc);
13669
13670           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13671           vec_add1 (rmt_locs, rloc);
13672           /* weight saved in rmt loc */
13673           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13674         }
13675       else if (unformat (input, "action %d", &action))
13676         {
13677           ;
13678         }
13679       else
13680         {
13681           clib_warning ("parse error '%U'", format_unformat_error, input);
13682           return -99;
13683         }
13684     }
13685
13686   if (!rmt_eid_set)
13687     {
13688       errmsg ("remote eid addresses not set");
13689       return -99;
13690     }
13691
13692   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13693     {
13694       errmsg ("eid types don't match");
13695       return -99;
13696     }
13697
13698   if (0 == rmt_locs && (u32) ~ 0 == action)
13699     {
13700       errmsg ("action not set for negative mapping");
13701       return -99;
13702     }
13703
13704   /* Construct the API message */
13705   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry,
13706       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13707
13708   mp->is_add = is_add;
13709   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13710   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13711   mp->eid_type = rmt_eid->type;
13712   mp->dp_table = clib_host_to_net_u32 (dp_table);
13713   mp->vni = clib_host_to_net_u32 (vni);
13714   mp->rmt_len = rmt_eid->len;
13715   mp->lcl_len = lcl_eid->len;
13716   mp->action = action;
13717
13718   if (0 != rmt_locs && 0 != lcl_locs)
13719     {
13720       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13721       clib_memcpy (mp->locs, lcl_locs,
13722                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13723
13724       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13725       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13726                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13727     }
13728   vec_free (lcl_locs);
13729   vec_free (rmt_locs);
13730
13731   /* send it... */
13732   S;
13733
13734   /* Wait for a reply... */
13735   W;
13736
13737   /* NOTREACHED */
13738   return 0;
13739 }
13740
13741 static int
13742 api_lisp_add_del_map_server (vat_main_t * vam)
13743 {
13744   unformat_input_t *input = vam->input;
13745   vl_api_lisp_add_del_map_server_t *mp;
13746   f64 timeout = ~0;
13747   u8 is_add = 1;
13748   u8 ipv4_set = 0;
13749   u8 ipv6_set = 0;
13750   ip4_address_t ipv4;
13751   ip6_address_t ipv6;
13752
13753   /* Parse args required to build the message */
13754   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13755     {
13756       if (unformat (input, "del"))
13757         {
13758           is_add = 0;
13759         }
13760       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13761         {
13762           ipv4_set = 1;
13763         }
13764       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13765         {
13766           ipv6_set = 1;
13767         }
13768       else
13769         break;
13770     }
13771
13772   if (ipv4_set && ipv6_set)
13773     {
13774       errmsg ("both eid v4 and v6 addresses set");
13775       return -99;
13776     }
13777
13778   if (!ipv4_set && !ipv6_set)
13779     {
13780       errmsg ("eid addresses not set");
13781       return -99;
13782     }
13783
13784   /* Construct the API message */
13785   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13786
13787   mp->is_add = is_add;
13788   if (ipv6_set)
13789     {
13790       mp->is_ipv6 = 1;
13791       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13792     }
13793   else
13794     {
13795       mp->is_ipv6 = 0;
13796       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13797     }
13798
13799   /* send it... */
13800   S;
13801
13802   /* Wait for a reply... */
13803   W;
13804
13805   /* NOTREACHED */
13806   return 0;
13807 }
13808
13809 static int
13810 api_lisp_add_del_map_resolver (vat_main_t * vam)
13811 {
13812   unformat_input_t *input = vam->input;
13813   vl_api_lisp_add_del_map_resolver_t *mp;
13814   f64 timeout = ~0;
13815   u8 is_add = 1;
13816   u8 ipv4_set = 0;
13817   u8 ipv6_set = 0;
13818   ip4_address_t ipv4;
13819   ip6_address_t ipv6;
13820
13821   /* Parse args required to build the message */
13822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13823     {
13824       if (unformat (input, "del"))
13825         {
13826           is_add = 0;
13827         }
13828       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13829         {
13830           ipv4_set = 1;
13831         }
13832       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13833         {
13834           ipv6_set = 1;
13835         }
13836       else
13837         break;
13838     }
13839
13840   if (ipv4_set && ipv6_set)
13841     {
13842       errmsg ("both eid v4 and v6 addresses set");
13843       return -99;
13844     }
13845
13846   if (!ipv4_set && !ipv6_set)
13847     {
13848       errmsg ("eid addresses not set");
13849       return -99;
13850     }
13851
13852   /* Construct the API message */
13853   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13854
13855   mp->is_add = is_add;
13856   if (ipv6_set)
13857     {
13858       mp->is_ipv6 = 1;
13859       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13860     }
13861   else
13862     {
13863       mp->is_ipv6 = 0;
13864       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13865     }
13866
13867   /* send it... */
13868   S;
13869
13870   /* Wait for a reply... */
13871   W;
13872
13873   /* NOTREACHED */
13874   return 0;
13875 }
13876
13877 static int
13878 api_lisp_gpe_enable_disable (vat_main_t * vam)
13879 {
13880   unformat_input_t *input = vam->input;
13881   vl_api_lisp_gpe_enable_disable_t *mp;
13882   f64 timeout = ~0;
13883   u8 is_set = 0;
13884   u8 is_en = 1;
13885
13886   /* Parse args required to build the message */
13887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13888     {
13889       if (unformat (input, "enable"))
13890         {
13891           is_set = 1;
13892           is_en = 1;
13893         }
13894       else if (unformat (input, "disable"))
13895         {
13896           is_set = 1;
13897           is_en = 0;
13898         }
13899       else
13900         break;
13901     }
13902
13903   if (is_set == 0)
13904     {
13905       errmsg ("Value not set");
13906       return -99;
13907     }
13908
13909   /* Construct the API message */
13910   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13911
13912   mp->is_en = is_en;
13913
13914   /* send it... */
13915   S;
13916
13917   /* Wait for a reply... */
13918   W;
13919
13920   /* NOTREACHED */
13921   return 0;
13922 }
13923
13924 static int
13925 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13926 {
13927   unformat_input_t *input = vam->input;
13928   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13929   f64 timeout = ~0;
13930   u8 is_set = 0;
13931   u8 is_en = 0;
13932
13933   /* Parse args required to build the message */
13934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13935     {
13936       if (unformat (input, "enable"))
13937         {
13938           is_set = 1;
13939           is_en = 1;
13940         }
13941       else if (unformat (input, "disable"))
13942         is_set = 1;
13943       else
13944         break;
13945     }
13946
13947   if (!is_set)
13948     {
13949       errmsg ("Value not set");
13950       return -99;
13951     }
13952
13953   /* Construct the API message */
13954   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13955
13956   mp->is_enabled = is_en;
13957
13958   /* send it... */
13959   S;
13960
13961   /* Wait for a reply... */
13962   W;
13963
13964   /* NOTREACHED */
13965   return 0;
13966 }
13967
13968 static int
13969 api_lisp_map_register_enable_disable (vat_main_t * vam)
13970 {
13971   unformat_input_t *input = vam->input;
13972   vl_api_lisp_map_register_enable_disable_t *mp;
13973   f64 timeout = ~0;
13974   u8 is_set = 0;
13975   u8 is_en = 0;
13976
13977   /* Parse args required to build the message */
13978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13979     {
13980       if (unformat (input, "enable"))
13981         {
13982           is_set = 1;
13983           is_en = 1;
13984         }
13985       else if (unformat (input, "disable"))
13986         is_set = 1;
13987       else
13988         break;
13989     }
13990
13991   if (!is_set)
13992     {
13993       errmsg ("Value not set");
13994       return -99;
13995     }
13996
13997   /* Construct the API message */
13998   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13999
14000   mp->is_enabled = is_en;
14001
14002   /* send it... */
14003   S;
14004
14005   /* Wait for a reply... */
14006   W;
14007
14008   /* NOTREACHED */
14009   return 0;
14010 }
14011
14012 static int
14013 api_lisp_enable_disable (vat_main_t * vam)
14014 {
14015   unformat_input_t *input = vam->input;
14016   vl_api_lisp_enable_disable_t *mp;
14017   f64 timeout = ~0;
14018   u8 is_set = 0;
14019   u8 is_en = 0;
14020
14021   /* Parse args required to build the message */
14022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14023     {
14024       if (unformat (input, "enable"))
14025         {
14026           is_set = 1;
14027           is_en = 1;
14028         }
14029       else if (unformat (input, "disable"))
14030         {
14031           is_set = 1;
14032         }
14033       else
14034         break;
14035     }
14036
14037   if (!is_set)
14038     {
14039       errmsg ("Value not set");
14040       return -99;
14041     }
14042
14043   /* Construct the API message */
14044   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
14045
14046   mp->is_en = is_en;
14047
14048   /* send it... */
14049   S;
14050
14051   /* Wait for a reply... */
14052   W;
14053
14054   /* NOTREACHED */
14055   return 0;
14056 }
14057
14058 static int
14059 api_show_lisp_map_register_state (vat_main_t * vam)
14060 {
14061   f64 timeout = ~0;
14062   vl_api_show_lisp_map_register_state_t *mp;
14063
14064   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
14065
14066   /* send */
14067   S;
14068
14069   /* wait for reply */
14070   W;
14071
14072   return 0;
14073 }
14074
14075 static int
14076 api_show_lisp_rloc_probe_state (vat_main_t * vam)
14077 {
14078   f64 timeout = ~0;
14079   vl_api_show_lisp_rloc_probe_state_t *mp;
14080
14081   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
14082
14083   /* send */
14084   S;
14085
14086   /* wait for reply */
14087   W;
14088
14089   return 0;
14090 }
14091
14092 static int
14093 api_show_lisp_map_request_mode (vat_main_t * vam)
14094 {
14095   f64 timeout = ~0;
14096   vl_api_show_lisp_map_request_mode_t *mp;
14097
14098   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
14099
14100   /* send */
14101   S;
14102
14103   /* wait for reply */
14104   W;
14105
14106   return 0;
14107 }
14108
14109 static int
14110 api_lisp_map_request_mode (vat_main_t * vam)
14111 {
14112   f64 timeout = ~0;
14113   unformat_input_t *input = vam->input;
14114   vl_api_lisp_map_request_mode_t *mp;
14115   u8 mode = 0;
14116
14117   /* Parse args required to build the message */
14118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14119     {
14120       if (unformat (input, "dst-only"))
14121         mode = 0;
14122       else if (unformat (input, "src-dst"))
14123         mode = 1;
14124       else
14125         {
14126           errmsg ("parse error '%U'", format_unformat_error, input);
14127           return -99;
14128         }
14129     }
14130
14131   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
14132
14133   mp->mode = mode;
14134
14135   /* send */
14136   S;
14137
14138   /* wait for reply */
14139   W;
14140
14141   /* notreached */
14142   return 0;
14143 }
14144
14145 /**
14146  * Enable/disable LISP proxy ITR.
14147  *
14148  * @param vam vpp API test context
14149  * @return return code
14150  */
14151 static int
14152 api_lisp_pitr_set_locator_set (vat_main_t * vam)
14153 {
14154   f64 timeout = ~0;
14155   u8 ls_name_set = 0;
14156   unformat_input_t *input = vam->input;
14157   vl_api_lisp_pitr_set_locator_set_t *mp;
14158   u8 is_add = 1;
14159   u8 *ls_name = 0;
14160
14161   /* Parse args required to build the message */
14162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14163     {
14164       if (unformat (input, "del"))
14165         is_add = 0;
14166       else if (unformat (input, "locator-set %s", &ls_name))
14167         ls_name_set = 1;
14168       else
14169         {
14170           errmsg ("parse error '%U'", format_unformat_error, input);
14171           return -99;
14172         }
14173     }
14174
14175   if (!ls_name_set)
14176     {
14177       errmsg ("locator-set name not set!");
14178       return -99;
14179     }
14180
14181   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
14182
14183   mp->is_add = is_add;
14184   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14185   vec_free (ls_name);
14186
14187   /* send */
14188   S;
14189
14190   /* wait for reply */
14191   W;
14192
14193   /* notreached */
14194   return 0;
14195 }
14196
14197 static int
14198 api_show_lisp_pitr (vat_main_t * vam)
14199 {
14200   vl_api_show_lisp_pitr_t *mp;
14201   f64 timeout = ~0;
14202
14203   if (!vam->json_output)
14204     {
14205       print (vam->ofp, "%=20s", "lisp status:");
14206     }
14207
14208   M (SHOW_LISP_PITR, show_lisp_pitr);
14209   /* send it... */
14210   S;
14211
14212   /* Wait for a reply... */
14213   W;
14214
14215   /* NOTREACHED */
14216   return 0;
14217 }
14218
14219 /**
14220  * Add/delete mapping between vni and vrf
14221  */
14222 static int
14223 api_lisp_eid_table_add_del_map (vat_main_t * vam)
14224 {
14225   f64 timeout = ~0;
14226   unformat_input_t *input = vam->input;
14227   vl_api_lisp_eid_table_add_del_map_t *mp;
14228   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14229   u32 vni, vrf, bd_index;
14230
14231   /* Parse args required to build the message */
14232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14233     {
14234       if (unformat (input, "del"))
14235         is_add = 0;
14236       else if (unformat (input, "vrf %d", &vrf))
14237         vrf_set = 1;
14238       else if (unformat (input, "bd_index %d", &bd_index))
14239         bd_index_set = 1;
14240       else if (unformat (input, "vni %d", &vni))
14241         vni_set = 1;
14242       else
14243         break;
14244     }
14245
14246   if (!vni_set || (!vrf_set && !bd_index_set))
14247     {
14248       errmsg ("missing arguments!");
14249       return -99;
14250     }
14251
14252   if (vrf_set && bd_index_set)
14253     {
14254       errmsg ("error: both vrf and bd entered!");
14255       return -99;
14256     }
14257
14258   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
14259
14260   mp->is_add = is_add;
14261   mp->vni = htonl (vni);
14262   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14263   mp->is_l2 = bd_index_set;
14264
14265   /* send */
14266   S;
14267
14268   /* wait for reply */
14269   W;
14270
14271   /* notreached */
14272   return 0;
14273 }
14274
14275 uword
14276 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14277 {
14278   u32 *action = va_arg (*args, u32 *);
14279   u8 *s = 0;
14280
14281   if (unformat (input, "%s", &s))
14282     {
14283       if (!strcmp ((char *) s, "no-action"))
14284         action[0] = 0;
14285       else if (!strcmp ((char *) s, "natively-forward"))
14286         action[0] = 1;
14287       else if (!strcmp ((char *) s, "send-map-request"))
14288         action[0] = 2;
14289       else if (!strcmp ((char *) s, "drop"))
14290         action[0] = 3;
14291       else
14292         {
14293           clib_warning ("invalid action: '%s'", s);
14294           action[0] = 3;
14295         }
14296     }
14297   else
14298     return 0;
14299
14300   vec_free (s);
14301   return 1;
14302 }
14303
14304 /**
14305  * Add/del remote mapping to/from LISP control plane
14306  *
14307  * @param vam vpp API test context
14308  * @return return code
14309  */
14310 static int
14311 api_lisp_add_del_remote_mapping (vat_main_t * vam)
14312 {
14313   unformat_input_t *input = vam->input;
14314   vl_api_lisp_add_del_remote_mapping_t *mp;
14315   f64 timeout = ~0;
14316   u32 vni = 0;
14317   lisp_eid_vat_t _eid, *eid = &_eid;
14318   lisp_eid_vat_t _seid, *seid = &_seid;
14319   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14320   u32 action = ~0, p, w, data_len;
14321   ip4_address_t rloc4;
14322   ip6_address_t rloc6;
14323   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
14324
14325   memset (&rloc, 0, sizeof (rloc));
14326
14327   /* Parse args required to build the message */
14328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14329     {
14330       if (unformat (input, "del-all"))
14331         {
14332           del_all = 1;
14333         }
14334       else if (unformat (input, "del"))
14335         {
14336           is_add = 0;
14337         }
14338       else if (unformat (input, "add"))
14339         {
14340           is_add = 1;
14341         }
14342       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14343         {
14344           eid_set = 1;
14345         }
14346       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14347         {
14348           seid_set = 1;
14349         }
14350       else if (unformat (input, "vni %d", &vni))
14351         {
14352           ;
14353         }
14354       else if (unformat (input, "p %d w %d", &p, &w))
14355         {
14356           if (!curr_rloc)
14357             {
14358               errmsg ("No RLOC configured for setting priority/weight!");
14359               return -99;
14360             }
14361           curr_rloc->priority = p;
14362           curr_rloc->weight = w;
14363         }
14364       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14365         {
14366           rloc.is_ip4 = 1;
14367           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14368           vec_add1 (rlocs, rloc);
14369           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14370         }
14371       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14372         {
14373           rloc.is_ip4 = 0;
14374           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14375           vec_add1 (rlocs, rloc);
14376           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14377         }
14378       else if (unformat (input, "action %U",
14379                          unformat_negative_mapping_action, &action))
14380         {
14381           ;
14382         }
14383       else
14384         {
14385           clib_warning ("parse error '%U'", format_unformat_error, input);
14386           return -99;
14387         }
14388     }
14389
14390   if (0 == eid_set)
14391     {
14392       errmsg ("missing params!");
14393       return -99;
14394     }
14395
14396   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14397     {
14398       errmsg ("no action set for negative map-reply!");
14399       return -99;
14400     }
14401
14402   data_len = vec_len (rlocs) * sizeof (rloc_t);
14403
14404   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14405   mp->is_add = is_add;
14406   mp->vni = htonl (vni);
14407   mp->action = (u8) action;
14408   mp->is_src_dst = seid_set;
14409   mp->eid_len = eid->len;
14410   mp->seid_len = seid->len;
14411   mp->del_all = del_all;
14412   mp->eid_type = eid->type;
14413   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14414   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14415
14416   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14417   clib_memcpy (mp->rlocs, rlocs, data_len);
14418   vec_free (rlocs);
14419
14420   /* send it... */
14421   S;
14422
14423   /* Wait for a reply... */
14424   W;
14425
14426   /* NOTREACHED */
14427   return 0;
14428 }
14429
14430 /**
14431  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14432  * forwarding entries in data-plane accordingly.
14433  *
14434  * @param vam vpp API test context
14435  * @return return code
14436  */
14437 static int
14438 api_lisp_add_del_adjacency (vat_main_t * vam)
14439 {
14440   unformat_input_t *input = vam->input;
14441   vl_api_lisp_add_del_adjacency_t *mp;
14442   f64 timeout = ~0;
14443   u32 vni = 0;
14444   ip4_address_t leid4, reid4;
14445   ip6_address_t leid6, reid6;
14446   u8 reid_mac[6] = { 0 };
14447   u8 leid_mac[6] = { 0 };
14448   u8 reid_type, leid_type;
14449   u32 leid_len = 0, reid_len = 0, len;
14450   u8 is_add = 1;
14451
14452   leid_type = reid_type = (u8) ~ 0;
14453
14454   /* Parse args required to build the message */
14455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14456     {
14457       if (unformat (input, "del"))
14458         {
14459           is_add = 0;
14460         }
14461       else if (unformat (input, "add"))
14462         {
14463           is_add = 1;
14464         }
14465       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14466                          &reid4, &len))
14467         {
14468           reid_type = 0;        /* ipv4 */
14469           reid_len = len;
14470         }
14471       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14472                          &reid6, &len))
14473         {
14474           reid_type = 1;        /* ipv6 */
14475           reid_len = len;
14476         }
14477       else if (unformat (input, "reid %U", unformat_ethernet_address,
14478                          reid_mac))
14479         {
14480           reid_type = 2;        /* mac */
14481         }
14482       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14483                          &leid4, &len))
14484         {
14485           leid_type = 0;        /* ipv4 */
14486           leid_len = len;
14487         }
14488       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14489                          &leid6, &len))
14490         {
14491           leid_type = 1;        /* ipv6 */
14492           leid_len = len;
14493         }
14494       else if (unformat (input, "leid %U", unformat_ethernet_address,
14495                          leid_mac))
14496         {
14497           leid_type = 2;        /* mac */
14498         }
14499       else if (unformat (input, "vni %d", &vni))
14500         {
14501           ;
14502         }
14503       else
14504         {
14505           errmsg ("parse error '%U'", format_unformat_error, input);
14506           return -99;
14507         }
14508     }
14509
14510   if ((u8) ~ 0 == reid_type)
14511     {
14512       errmsg ("missing params!");
14513       return -99;
14514     }
14515
14516   if (leid_type != reid_type)
14517     {
14518       errmsg ("remote and local EIDs are of different types!");
14519       return -99;
14520     }
14521
14522   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14523   mp->is_add = is_add;
14524   mp->vni = htonl (vni);
14525   mp->leid_len = leid_len;
14526   mp->reid_len = reid_len;
14527   mp->eid_type = reid_type;
14528
14529   switch (mp->eid_type)
14530     {
14531     case 0:
14532       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14533       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14534       break;
14535     case 1:
14536       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14537       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14538       break;
14539     case 2:
14540       clib_memcpy (mp->leid, leid_mac, 6);
14541       clib_memcpy (mp->reid, reid_mac, 6);
14542       break;
14543     default:
14544       errmsg ("unknown EID type %d!", mp->eid_type);
14545       return 0;
14546     }
14547
14548   /* send it... */
14549   S;
14550
14551   /* Wait for a reply... */
14552   W;
14553
14554   /* NOTREACHED */
14555   return 0;
14556 }
14557
14558 static int
14559 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14560 {
14561   unformat_input_t *input = vam->input;
14562   vl_api_lisp_gpe_add_del_iface_t *mp;
14563   f64 timeout = ~0;
14564   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14565   u32 dp_table = 0, vni = 0;
14566
14567   /* Parse args required to build the message */
14568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14569     {
14570       if (unformat (input, "up"))
14571         {
14572           action_set = 1;
14573           is_add = 1;
14574         }
14575       else if (unformat (input, "down"))
14576         {
14577           action_set = 1;
14578           is_add = 0;
14579         }
14580       else if (unformat (input, "table_id %d", &dp_table))
14581         {
14582           dp_table_set = 1;
14583         }
14584       else if (unformat (input, "bd_id %d", &dp_table))
14585         {
14586           dp_table_set = 1;
14587           is_l2 = 1;
14588         }
14589       else if (unformat (input, "vni %d", &vni))
14590         {
14591           vni_set = 1;
14592         }
14593       else
14594         break;
14595     }
14596
14597   if (action_set == 0)
14598     {
14599       errmsg ("Action not set");
14600       return -99;
14601     }
14602   if (dp_table_set == 0 || vni_set == 0)
14603     {
14604       errmsg ("vni and dp_table must be set");
14605       return -99;
14606     }
14607
14608   /* Construct the API message */
14609   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14610
14611   mp->is_add = is_add;
14612   mp->dp_table = dp_table;
14613   mp->is_l2 = is_l2;
14614   mp->vni = vni;
14615
14616   /* send it... */
14617   S;
14618
14619   /* Wait for a reply... */
14620   W;
14621
14622   /* NOTREACHED */
14623   return 0;
14624 }
14625
14626 /**
14627  * Add/del map request itr rlocs from LISP control plane and updates
14628  *
14629  * @param vam vpp API test context
14630  * @return return code
14631  */
14632 static int
14633 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14634 {
14635   unformat_input_t *input = vam->input;
14636   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14637   f64 timeout = ~0;
14638   u8 *locator_set_name = 0;
14639   u8 locator_set_name_set = 0;
14640   u8 is_add = 1;
14641
14642   /* Parse args required to build the message */
14643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14644     {
14645       if (unformat (input, "del"))
14646         {
14647           is_add = 0;
14648         }
14649       else if (unformat (input, "%_%v%_", &locator_set_name))
14650         {
14651           locator_set_name_set = 1;
14652         }
14653       else
14654         {
14655           clib_warning ("parse error '%U'", format_unformat_error, input);
14656           return -99;
14657         }
14658     }
14659
14660   if (is_add && !locator_set_name_set)
14661     {
14662       errmsg ("itr-rloc is not set!");
14663       return -99;
14664     }
14665
14666   if (is_add && vec_len (locator_set_name) > 64)
14667     {
14668       errmsg ("itr-rloc locator-set name too long");
14669       vec_free (locator_set_name);
14670       return -99;
14671     }
14672
14673   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14674   mp->is_add = is_add;
14675   if (is_add)
14676     {
14677       clib_memcpy (mp->locator_set_name, locator_set_name,
14678                    vec_len (locator_set_name));
14679     }
14680   else
14681     {
14682       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14683     }
14684   vec_free (locator_set_name);
14685
14686   /* send it... */
14687   S;
14688
14689   /* Wait for a reply... */
14690   W;
14691
14692   /* NOTREACHED */
14693   return 0;
14694 }
14695
14696 static int
14697 api_lisp_locator_dump (vat_main_t * vam)
14698 {
14699   unformat_input_t *input = vam->input;
14700   vl_api_lisp_locator_dump_t *mp;
14701   f64 timeout = ~0;
14702   u8 is_index_set = 0, is_name_set = 0;
14703   u8 *ls_name = 0;
14704   u32 ls_index = ~0;
14705
14706   /* Parse args required to build the message */
14707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14708     {
14709       if (unformat (input, "ls_name %_%v%_", &ls_name))
14710         {
14711           is_name_set = 1;
14712         }
14713       else if (unformat (input, "ls_index %d", &ls_index))
14714         {
14715           is_index_set = 1;
14716         }
14717       else
14718         {
14719           errmsg ("parse error '%U'", format_unformat_error, input);
14720           return -99;
14721         }
14722     }
14723
14724   if (!is_index_set && !is_name_set)
14725     {
14726       errmsg ("error: expected one of index or name!");
14727       return -99;
14728     }
14729
14730   if (is_index_set && is_name_set)
14731     {
14732       errmsg ("error: only one param expected!");
14733       return -99;
14734     }
14735
14736   if (vec_len (ls_name) > 62)
14737     {
14738       errmsg ("error: locator set name too long!");
14739       return -99;
14740     }
14741
14742   if (!vam->json_output)
14743     {
14744       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14745     }
14746
14747   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14748   mp->is_index_set = is_index_set;
14749
14750   if (is_index_set)
14751     mp->ls_index = clib_host_to_net_u32 (ls_index);
14752   else
14753     {
14754       vec_add1 (ls_name, 0);
14755       strncpy ((char *) mp->ls_name, (char *) ls_name,
14756                sizeof (mp->ls_name) - 1);
14757     }
14758
14759   /* send it... */
14760   S;
14761
14762   /* Use a control ping for synchronization */
14763   {
14764     vl_api_control_ping_t *mp;
14765     M (CONTROL_PING, control_ping);
14766     S;
14767   }
14768   /* Wait for a reply... */
14769   W;
14770
14771   /* NOTREACHED */
14772   return 0;
14773 }
14774
14775 static int
14776 api_lisp_locator_set_dump (vat_main_t * vam)
14777 {
14778   vl_api_lisp_locator_set_dump_t *mp;
14779   unformat_input_t *input = vam->input;
14780   f64 timeout = ~0;
14781   u8 filter = 0;
14782
14783   /* Parse args required to build the message */
14784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14785     {
14786       if (unformat (input, "local"))
14787         {
14788           filter = 1;
14789         }
14790       else if (unformat (input, "remote"))
14791         {
14792           filter = 2;
14793         }
14794       else
14795         {
14796           errmsg ("parse error '%U'", format_unformat_error, input);
14797           return -99;
14798         }
14799     }
14800
14801   if (!vam->json_output)
14802     {
14803       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14804     }
14805
14806   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14807
14808   mp->filter = filter;
14809
14810   /* send it... */
14811   S;
14812
14813   /* Use a control ping for synchronization */
14814   {
14815     vl_api_control_ping_t *mp;
14816     M (CONTROL_PING, control_ping);
14817     S;
14818   }
14819   /* Wait for a reply... */
14820   W;
14821
14822   /* NOTREACHED */
14823   return 0;
14824 }
14825
14826 static int
14827 api_lisp_eid_table_map_dump (vat_main_t * vam)
14828 {
14829   u8 is_l2 = 0;
14830   u8 mode_set = 0;
14831   unformat_input_t *input = vam->input;
14832   vl_api_lisp_eid_table_map_dump_t *mp;
14833   f64 timeout = ~0;
14834
14835   /* Parse args required to build the message */
14836   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14837     {
14838       if (unformat (input, "l2"))
14839         {
14840           is_l2 = 1;
14841           mode_set = 1;
14842         }
14843       else if (unformat (input, "l3"))
14844         {
14845           is_l2 = 0;
14846           mode_set = 1;
14847         }
14848       else
14849         {
14850           errmsg ("parse error '%U'", format_unformat_error, input);
14851           return -99;
14852         }
14853     }
14854
14855   if (!mode_set)
14856     {
14857       errmsg ("expected one of 'l2' or 'l3' parameter!");
14858       return -99;
14859     }
14860
14861   if (!vam->json_output)
14862     {
14863       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14864     }
14865
14866   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14867   mp->is_l2 = is_l2;
14868
14869   /* send it... */
14870   S;
14871
14872   /* Use a control ping for synchronization */
14873   {
14874     vl_api_control_ping_t *mp;
14875     M (CONTROL_PING, control_ping);
14876     S;
14877   }
14878   /* Wait for a reply... */
14879   W;
14880
14881   /* NOTREACHED */
14882   return 0;
14883 }
14884
14885 static int
14886 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14887 {
14888   vl_api_lisp_eid_table_vni_dump_t *mp;
14889   f64 timeout = ~0;
14890
14891   if (!vam->json_output)
14892     {
14893       print (vam->ofp, "VNI");
14894     }
14895
14896   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14897
14898   /* send it... */
14899   S;
14900
14901   /* Use a control ping for synchronization */
14902   {
14903     vl_api_control_ping_t *mp;
14904     M (CONTROL_PING, control_ping);
14905     S;
14906   }
14907   /* Wait for a reply... */
14908   W;
14909
14910   /* NOTREACHED */
14911   return 0;
14912 }
14913
14914 static int
14915 api_lisp_eid_table_dump (vat_main_t * vam)
14916 {
14917   unformat_input_t *i = vam->input;
14918   vl_api_lisp_eid_table_dump_t *mp;
14919   f64 timeout = ~0;
14920   struct in_addr ip4;
14921   struct in6_addr ip6;
14922   u8 mac[6];
14923   u8 eid_type = ~0, eid_set = 0;
14924   u32 prefix_length = ~0, t, vni = 0;
14925   u8 filter = 0;
14926
14927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14928     {
14929       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14930         {
14931           eid_set = 1;
14932           eid_type = 0;
14933           prefix_length = t;
14934         }
14935       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14936         {
14937           eid_set = 1;
14938           eid_type = 1;
14939           prefix_length = t;
14940         }
14941       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14942         {
14943           eid_set = 1;
14944           eid_type = 2;
14945         }
14946       else if (unformat (i, "vni %d", &t))
14947         {
14948           vni = t;
14949         }
14950       else if (unformat (i, "local"))
14951         {
14952           filter = 1;
14953         }
14954       else if (unformat (i, "remote"))
14955         {
14956           filter = 2;
14957         }
14958       else
14959         {
14960           errmsg ("parse error '%U'", format_unformat_error, i);
14961           return -99;
14962         }
14963     }
14964
14965   if (!vam->json_output)
14966     {
14967       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14968              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14969     }
14970
14971   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14972
14973   mp->filter = filter;
14974   if (eid_set)
14975     {
14976       mp->eid_set = 1;
14977       mp->vni = htonl (vni);
14978       mp->eid_type = eid_type;
14979       switch (eid_type)
14980         {
14981         case 0:
14982           mp->prefix_length = prefix_length;
14983           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14984           break;
14985         case 1:
14986           mp->prefix_length = prefix_length;
14987           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14988           break;
14989         case 2:
14990           clib_memcpy (mp->eid, mac, sizeof (mac));
14991           break;
14992         default:
14993           errmsg ("unknown EID type %d!", eid_type);
14994           return -99;
14995         }
14996     }
14997
14998   /* send it... */
14999   S;
15000
15001   /* Use a control ping for synchronization */
15002   {
15003     vl_api_control_ping_t *mp;
15004     M (CONTROL_PING, control_ping);
15005     S;
15006   }
15007
15008   /* Wait for a reply... */
15009   W;
15010
15011   /* NOTREACHED */
15012   return 0;
15013 }
15014
15015 static int
15016 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15017 {
15018   unformat_input_t *i = vam->input;
15019   vl_api_lisp_gpe_fwd_entries_get_t *mp;
15020   f64 timeout = ~0;
15021   u8 vni_set = 0;
15022   u32 vni = ~0;
15023
15024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15025     {
15026       if (unformat (i, "vni %d", &vni))
15027         {
15028           vni_set = 1;
15029         }
15030       else
15031         {
15032           errmsg ("parse error '%U'", format_unformat_error, i);
15033           return -99;
15034         }
15035     }
15036
15037   if (!vni_set)
15038     {
15039       errmsg ("vni not set!");
15040       return -99;
15041     }
15042
15043   if (!vam->json_output)
15044     {
15045       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15046              "leid", "reid");
15047     }
15048
15049   M (LISP_GPE_FWD_ENTRIES_GET, lisp_gpe_fwd_entries_get);
15050   mp->vni = clib_host_to_net_u32 (vni);
15051
15052   /* send it... */
15053   S;
15054
15055   /* Wait for a reply... */
15056   W;
15057
15058   /* NOTREACHED */
15059   return 0;
15060 }
15061
15062 #define vl_api_lisp_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15063 #define vl_api_lisp_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15064 #define vl_api_lisp_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15065 #define vl_api_lisp_gpe_fwd_entry_path_details_t_print vl_noop_handler
15066
15067 static int
15068 api_lisp_adjacencies_get (vat_main_t * vam)
15069 {
15070   unformat_input_t *i = vam->input;
15071   vl_api_lisp_adjacencies_get_t *mp;
15072   f64 timeout = ~0;
15073   u8 vni_set = 0;
15074   u32 vni = ~0;
15075
15076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15077     {
15078       if (unformat (i, "vni %d", &vni))
15079         {
15080           vni_set = 1;
15081         }
15082       else
15083         {
15084           errmsg ("parse error '%U'", format_unformat_error, i);
15085           return -99;
15086         }
15087     }
15088
15089   if (!vni_set)
15090     {
15091       errmsg ("vni not set!");
15092       return -99;
15093     }
15094
15095   if (!vam->json_output)
15096     {
15097       print (vam->ofp, "%s %40s", "leid", "reid");
15098     }
15099
15100   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
15101   mp->vni = clib_host_to_net_u32 (vni);
15102
15103   /* send it... */
15104   S;
15105
15106   /* Wait for a reply... */
15107   W;
15108
15109   /* NOTREACHED */
15110   return 0;
15111 }
15112
15113 static int
15114 api_lisp_map_server_dump (vat_main_t * vam)
15115 {
15116   vl_api_lisp_map_server_dump_t *mp;
15117   f64 timeout = ~0;
15118
15119   if (!vam->json_output)
15120     {
15121       print (vam->ofp, "%=20s", "Map server");
15122     }
15123
15124   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
15125   /* send it... */
15126   S;
15127
15128   /* Use a control ping for synchronization */
15129   {
15130     vl_api_control_ping_t *mp;
15131     M (CONTROL_PING, control_ping);
15132     S;
15133   }
15134   /* Wait for a reply... */
15135   W;
15136
15137   /* NOTREACHED */
15138   return 0;
15139 }
15140
15141 static int
15142 api_lisp_map_resolver_dump (vat_main_t * vam)
15143 {
15144   vl_api_lisp_map_resolver_dump_t *mp;
15145   f64 timeout = ~0;
15146
15147   if (!vam->json_output)
15148     {
15149       print (vam->ofp, "%=20s", "Map resolver");
15150     }
15151
15152   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
15153   /* send it... */
15154   S;
15155
15156   /* Use a control ping for synchronization */
15157   {
15158     vl_api_control_ping_t *mp;
15159     M (CONTROL_PING, control_ping);
15160     S;
15161   }
15162   /* Wait for a reply... */
15163   W;
15164
15165   /* NOTREACHED */
15166   return 0;
15167 }
15168
15169 static int
15170 api_show_lisp_status (vat_main_t * vam)
15171 {
15172   vl_api_show_lisp_status_t *mp;
15173   f64 timeout = ~0;
15174
15175   if (!vam->json_output)
15176     {
15177       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
15178     }
15179
15180   M (SHOW_LISP_STATUS, show_lisp_status);
15181   /* send it... */
15182   S;
15183   /* Wait for a reply... */
15184   W;
15185
15186   /* NOTREACHED */
15187   return 0;
15188 }
15189
15190 static int
15191 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15192 {
15193   vl_api_lisp_gpe_fwd_entry_path_dump_t *mp;
15194   f64 timeout = ~0;
15195   unformat_input_t *i = vam->input;
15196   u32 fwd_entry_index = ~0;
15197
15198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15199     {
15200       if (unformat (i, "index %d", &fwd_entry_index))
15201         ;
15202       else
15203         break;
15204     }
15205
15206   if (~0 == fwd_entry_index)
15207     {
15208       errmsg ("no index specified!");
15209       return -99;
15210     }
15211
15212   if (!vam->json_output)
15213     {
15214       print (vam->ofp, "first line");
15215     }
15216
15217   M (LISP_GPE_FWD_ENTRY_PATH_DUMP, lisp_gpe_fwd_entry_path_dump);
15218
15219   /* send it... */
15220   S;
15221   /* Use a control ping for synchronization */
15222   {
15223     vl_api_control_ping_t *mp;
15224     M (CONTROL_PING, control_ping);
15225     S;
15226   }
15227   /* Wait for a reply... */
15228   W;
15229
15230   /* NOTREACHED */
15231   return 0;
15232 }
15233
15234 static int
15235 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
15236 {
15237   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
15238   f64 timeout = ~0;
15239
15240   if (!vam->json_output)
15241     {
15242       print (vam->ofp, "%=20s", "itr-rlocs:");
15243     }
15244
15245   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
15246   /* send it... */
15247   S;
15248   /* Wait for a reply... */
15249   W;
15250
15251   /* NOTREACHED */
15252   return 0;
15253 }
15254
15255 static int
15256 api_af_packet_create (vat_main_t * vam)
15257 {
15258   unformat_input_t *i = vam->input;
15259   vl_api_af_packet_create_t *mp;
15260   f64 timeout;
15261   u8 *host_if_name = 0;
15262   u8 hw_addr[6];
15263   u8 random_hw_addr = 1;
15264
15265   memset (hw_addr, 0, sizeof (hw_addr));
15266
15267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15268     {
15269       if (unformat (i, "name %s", &host_if_name))
15270         vec_add1 (host_if_name, 0);
15271       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15272         random_hw_addr = 0;
15273       else
15274         break;
15275     }
15276
15277   if (!vec_len (host_if_name))
15278     {
15279       errmsg ("host-interface name must be specified");
15280       return -99;
15281     }
15282
15283   if (vec_len (host_if_name) > 64)
15284     {
15285       errmsg ("host-interface name too long");
15286       return -99;
15287     }
15288
15289   M (AF_PACKET_CREATE, af_packet_create);
15290
15291   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15292   clib_memcpy (mp->hw_addr, hw_addr, 6);
15293   mp->use_random_hw_addr = random_hw_addr;
15294   vec_free (host_if_name);
15295
15296   S;
15297   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15298   /* NOTREACHED */
15299   return 0;
15300 }
15301
15302 static int
15303 api_af_packet_delete (vat_main_t * vam)
15304 {
15305   unformat_input_t *i = vam->input;
15306   vl_api_af_packet_delete_t *mp;
15307   f64 timeout;
15308   u8 *host_if_name = 0;
15309
15310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15311     {
15312       if (unformat (i, "name %s", &host_if_name))
15313         vec_add1 (host_if_name, 0);
15314       else
15315         break;
15316     }
15317
15318   if (!vec_len (host_if_name))
15319     {
15320       errmsg ("host-interface name must be specified");
15321       return -99;
15322     }
15323
15324   if (vec_len (host_if_name) > 64)
15325     {
15326       errmsg ("host-interface name too long");
15327       return -99;
15328     }
15329
15330   M (AF_PACKET_DELETE, af_packet_delete);
15331
15332   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15333   vec_free (host_if_name);
15334
15335   S;
15336   W;
15337   /* NOTREACHED */
15338   return 0;
15339 }
15340
15341 static int
15342 api_policer_add_del (vat_main_t * vam)
15343 {
15344   unformat_input_t *i = vam->input;
15345   vl_api_policer_add_del_t *mp;
15346   f64 timeout;
15347   u8 is_add = 1;
15348   u8 *name = 0;
15349   u32 cir = 0;
15350   u32 eir = 0;
15351   u64 cb = 0;
15352   u64 eb = 0;
15353   u8 rate_type = 0;
15354   u8 round_type = 0;
15355   u8 type = 0;
15356   u8 color_aware = 0;
15357   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15358
15359   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15360   conform_action.dscp = 0;
15361   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15362   exceed_action.dscp = 0;
15363   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15364   violate_action.dscp = 0;
15365
15366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15367     {
15368       if (unformat (i, "del"))
15369         is_add = 0;
15370       else if (unformat (i, "name %s", &name))
15371         vec_add1 (name, 0);
15372       else if (unformat (i, "cir %u", &cir))
15373         ;
15374       else if (unformat (i, "eir %u", &eir))
15375         ;
15376       else if (unformat (i, "cb %u", &cb))
15377         ;
15378       else if (unformat (i, "eb %u", &eb))
15379         ;
15380       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15381                          &rate_type))
15382         ;
15383       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15384                          &round_type))
15385         ;
15386       else if (unformat (i, "type %U", unformat_policer_type, &type))
15387         ;
15388       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15389                          &conform_action))
15390         ;
15391       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15392                          &exceed_action))
15393         ;
15394       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15395                          &violate_action))
15396         ;
15397       else if (unformat (i, "color-aware"))
15398         color_aware = 1;
15399       else
15400         break;
15401     }
15402
15403   if (!vec_len (name))
15404     {
15405       errmsg ("policer name must be specified");
15406       return -99;
15407     }
15408
15409   if (vec_len (name) > 64)
15410     {
15411       errmsg ("policer name too long");
15412       return -99;
15413     }
15414
15415   M (POLICER_ADD_DEL, policer_add_del);
15416
15417   clib_memcpy (mp->name, name, vec_len (name));
15418   vec_free (name);
15419   mp->is_add = is_add;
15420   mp->cir = cir;
15421   mp->eir = eir;
15422   mp->cb = cb;
15423   mp->eb = eb;
15424   mp->rate_type = rate_type;
15425   mp->round_type = round_type;
15426   mp->type = type;
15427   mp->conform_action_type = conform_action.action_type;
15428   mp->conform_dscp = conform_action.dscp;
15429   mp->exceed_action_type = exceed_action.action_type;
15430   mp->exceed_dscp = exceed_action.dscp;
15431   mp->violate_action_type = violate_action.action_type;
15432   mp->violate_dscp = violate_action.dscp;
15433   mp->color_aware = color_aware;
15434
15435   S;
15436   W;
15437   /* NOTREACHED */
15438   return 0;
15439 }
15440
15441 static int
15442 api_policer_dump (vat_main_t * vam)
15443 {
15444   unformat_input_t *i = vam->input;
15445   vl_api_policer_dump_t *mp;
15446   f64 timeout = ~0;
15447   u8 *match_name = 0;
15448   u8 match_name_valid = 0;
15449
15450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15451     {
15452       if (unformat (i, "name %s", &match_name))
15453         {
15454           vec_add1 (match_name, 0);
15455           match_name_valid = 1;
15456         }
15457       else
15458         break;
15459     }
15460
15461   M (POLICER_DUMP, policer_dump);
15462   mp->match_name_valid = match_name_valid;
15463   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15464   vec_free (match_name);
15465   /* send it... */
15466   S;
15467
15468   /* Use a control ping for synchronization */
15469   {
15470     vl_api_control_ping_t *mp;
15471     M (CONTROL_PING, control_ping);
15472     S;
15473   }
15474   /* Wait for a reply... */
15475   W;
15476
15477   /* NOTREACHED */
15478   return 0;
15479 }
15480
15481 static int
15482 api_policer_classify_set_interface (vat_main_t * vam)
15483 {
15484   unformat_input_t *i = vam->input;
15485   vl_api_policer_classify_set_interface_t *mp;
15486   f64 timeout;
15487   u32 sw_if_index;
15488   int sw_if_index_set;
15489   u32 ip4_table_index = ~0;
15490   u32 ip6_table_index = ~0;
15491   u32 l2_table_index = ~0;
15492   u8 is_add = 1;
15493
15494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15495     {
15496       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15497         sw_if_index_set = 1;
15498       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15499         sw_if_index_set = 1;
15500       else if (unformat (i, "del"))
15501         is_add = 0;
15502       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15503         ;
15504       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15505         ;
15506       else if (unformat (i, "l2-table %d", &l2_table_index))
15507         ;
15508       else
15509         {
15510           clib_warning ("parse error '%U'", format_unformat_error, i);
15511           return -99;
15512         }
15513     }
15514
15515   if (sw_if_index_set == 0)
15516     {
15517       errmsg ("missing interface name or sw_if_index");
15518       return -99;
15519     }
15520
15521   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15522
15523   mp->sw_if_index = ntohl (sw_if_index);
15524   mp->ip4_table_index = ntohl (ip4_table_index);
15525   mp->ip6_table_index = ntohl (ip6_table_index);
15526   mp->l2_table_index = ntohl (l2_table_index);
15527   mp->is_add = is_add;
15528
15529   S;
15530   W;
15531   /* NOTREACHED */
15532   return 0;
15533 }
15534
15535 static int
15536 api_policer_classify_dump (vat_main_t * vam)
15537 {
15538   unformat_input_t *i = vam->input;
15539   vl_api_policer_classify_dump_t *mp;
15540   f64 timeout = ~0;
15541   u8 type = POLICER_CLASSIFY_N_TABLES;
15542
15543   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15544     ;
15545   else
15546     {
15547       errmsg ("classify table type must be specified");
15548       return -99;
15549     }
15550
15551   if (!vam->json_output)
15552     {
15553       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15554     }
15555
15556   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15557   mp->type = type;
15558   /* send it... */
15559   S;
15560
15561   /* Use a control ping for synchronization */
15562   {
15563     vl_api_control_ping_t *mp;
15564     M (CONTROL_PING, control_ping);
15565     S;
15566   }
15567   /* Wait for a reply... */
15568   W;
15569
15570   /* NOTREACHED */
15571   return 0;
15572 }
15573
15574 static int
15575 api_netmap_create (vat_main_t * vam)
15576 {
15577   unformat_input_t *i = vam->input;
15578   vl_api_netmap_create_t *mp;
15579   f64 timeout;
15580   u8 *if_name = 0;
15581   u8 hw_addr[6];
15582   u8 random_hw_addr = 1;
15583   u8 is_pipe = 0;
15584   u8 is_master = 0;
15585
15586   memset (hw_addr, 0, sizeof (hw_addr));
15587
15588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15589     {
15590       if (unformat (i, "name %s", &if_name))
15591         vec_add1 (if_name, 0);
15592       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15593         random_hw_addr = 0;
15594       else if (unformat (i, "pipe"))
15595         is_pipe = 1;
15596       else if (unformat (i, "master"))
15597         is_master = 1;
15598       else if (unformat (i, "slave"))
15599         is_master = 0;
15600       else
15601         break;
15602     }
15603
15604   if (!vec_len (if_name))
15605     {
15606       errmsg ("interface name must be specified");
15607       return -99;
15608     }
15609
15610   if (vec_len (if_name) > 64)
15611     {
15612       errmsg ("interface name too long");
15613       return -99;
15614     }
15615
15616   M (NETMAP_CREATE, netmap_create);
15617
15618   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15619   clib_memcpy (mp->hw_addr, hw_addr, 6);
15620   mp->use_random_hw_addr = random_hw_addr;
15621   mp->is_pipe = is_pipe;
15622   mp->is_master = is_master;
15623   vec_free (if_name);
15624
15625   S;
15626   W;
15627   /* NOTREACHED */
15628   return 0;
15629 }
15630
15631 static int
15632 api_netmap_delete (vat_main_t * vam)
15633 {
15634   unformat_input_t *i = vam->input;
15635   vl_api_netmap_delete_t *mp;
15636   f64 timeout;
15637   u8 *if_name = 0;
15638
15639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15640     {
15641       if (unformat (i, "name %s", &if_name))
15642         vec_add1 (if_name, 0);
15643       else
15644         break;
15645     }
15646
15647   if (!vec_len (if_name))
15648     {
15649       errmsg ("interface name must be specified");
15650       return -99;
15651     }
15652
15653   if (vec_len (if_name) > 64)
15654     {
15655       errmsg ("interface name too long");
15656       return -99;
15657     }
15658
15659   M (NETMAP_DELETE, netmap_delete);
15660
15661   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15662   vec_free (if_name);
15663
15664   S;
15665   W;
15666   /* NOTREACHED */
15667   return 0;
15668 }
15669
15670 static void vl_api_mpls_tunnel_details_t_handler
15671   (vl_api_mpls_tunnel_details_t * mp)
15672 {
15673   vat_main_t *vam = &vat_main;
15674   i32 len = mp->mt_next_hop_n_labels;
15675   i32 i;
15676
15677   print (vam->ofp, "[%d]: via %U %d labels ",
15678          mp->tunnel_index,
15679          format_ip4_address, mp->mt_next_hop,
15680          ntohl (mp->mt_next_hop_sw_if_index));
15681   for (i = 0; i < len; i++)
15682     {
15683       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15684     }
15685   print (vam->ofp, "");
15686 }
15687
15688 static void vl_api_mpls_tunnel_details_t_handler_json
15689   (vl_api_mpls_tunnel_details_t * mp)
15690 {
15691   vat_main_t *vam = &vat_main;
15692   vat_json_node_t *node = NULL;
15693   struct in_addr ip4;
15694   i32 i;
15695   i32 len = mp->mt_next_hop_n_labels;
15696
15697   if (VAT_JSON_ARRAY != vam->json_tree.type)
15698     {
15699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15700       vat_json_init_array (&vam->json_tree);
15701     }
15702   node = vat_json_array_add (&vam->json_tree);
15703
15704   vat_json_init_object (node);
15705   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15706   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15707   vat_json_object_add_ip4 (node, "next_hop", ip4);
15708   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15709                             ntohl (mp->mt_next_hop_sw_if_index));
15710   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15711   vat_json_object_add_uint (node, "label_count", len);
15712   for (i = 0; i < len; i++)
15713     {
15714       vat_json_object_add_uint (node, "label",
15715                                 ntohl (mp->mt_next_hop_out_labels[i]));
15716     }
15717 }
15718
15719 static int
15720 api_mpls_tunnel_dump (vat_main_t * vam)
15721 {
15722   vl_api_mpls_tunnel_dump_t *mp;
15723   f64 timeout;
15724   i32 index = -1;
15725
15726   /* Parse args required to build the message */
15727   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15728     {
15729       if (!unformat (vam->input, "tunnel_index %d", &index))
15730         {
15731           index = -1;
15732           break;
15733         }
15734     }
15735
15736   print (vam->ofp, "  tunnel_index %d", index);
15737
15738   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15739   mp->tunnel_index = htonl (index);
15740   S;
15741
15742   /* Use a control ping for synchronization */
15743   {
15744     vl_api_control_ping_t *mp;
15745     M (CONTROL_PING, control_ping);
15746     S;
15747   }
15748   W;
15749 }
15750
15751 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15752 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15753
15754 static void
15755 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15756 {
15757   vat_main_t *vam = &vat_main;
15758   int count = ntohl (mp->count);
15759   vl_api_fib_path2_t *fp;
15760   int i;
15761
15762   print (vam->ofp,
15763          "table-id %d, label %u, ess_bit %u",
15764          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15765   fp = mp->path;
15766   for (i = 0; i < count; i++)
15767     {
15768       if (fp->afi == IP46_TYPE_IP6)
15769         print (vam->ofp,
15770                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15771                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15772                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15773                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15774                format_ip6_address, fp->next_hop);
15775       else if (fp->afi == IP46_TYPE_IP4)
15776         print (vam->ofp,
15777                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15778                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15779                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15780                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15781                format_ip4_address, fp->next_hop);
15782       fp++;
15783     }
15784 }
15785
15786 static void vl_api_mpls_fib_details_t_handler_json
15787   (vl_api_mpls_fib_details_t * mp)
15788 {
15789   vat_main_t *vam = &vat_main;
15790   int count = ntohl (mp->count);
15791   vat_json_node_t *node = NULL;
15792   struct in_addr ip4;
15793   struct in6_addr ip6;
15794   vl_api_fib_path2_t *fp;
15795   int i;
15796
15797   if (VAT_JSON_ARRAY != vam->json_tree.type)
15798     {
15799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15800       vat_json_init_array (&vam->json_tree);
15801     }
15802   node = vat_json_array_add (&vam->json_tree);
15803
15804   vat_json_init_object (node);
15805   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15806   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15807   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15808   vat_json_object_add_uint (node, "path_count", count);
15809   fp = mp->path;
15810   for (i = 0; i < count; i++)
15811     {
15812       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15813       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15814       vat_json_object_add_uint (node, "is_local", fp->is_local);
15815       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15816       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15817       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15818       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15819       if (fp->afi == IP46_TYPE_IP4)
15820         {
15821           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15822           vat_json_object_add_ip4 (node, "next_hop", ip4);
15823         }
15824       else if (fp->afi == IP46_TYPE_IP6)
15825         {
15826           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15827           vat_json_object_add_ip6 (node, "next_hop", ip6);
15828         }
15829     }
15830 }
15831
15832 static int
15833 api_mpls_fib_dump (vat_main_t * vam)
15834 {
15835   vl_api_mpls_fib_dump_t *mp;
15836   f64 timeout;
15837
15838   M (MPLS_FIB_DUMP, mpls_fib_dump);
15839   S;
15840
15841   /* Use a control ping for synchronization */
15842   {
15843     vl_api_control_ping_t *mp;
15844     M (CONTROL_PING, control_ping);
15845     S;
15846   }
15847   W;
15848 }
15849
15850 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15851 #define vl_api_ip_fib_details_t_print vl_noop_handler
15852
15853 static void
15854 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15855 {
15856   vat_main_t *vam = &vat_main;
15857   int count = ntohl (mp->count);
15858   vl_api_fib_path_t *fp;
15859   int i;
15860
15861   print (vam->ofp,
15862          "table-id %d, prefix %U/%d",
15863          ntohl (mp->table_id), format_ip4_address, mp->address,
15864          mp->address_length);
15865   fp = mp->path;
15866   for (i = 0; i < count; i++)
15867     {
15868       if (fp->afi == IP46_TYPE_IP6)
15869         print (vam->ofp,
15870                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15871                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15872                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15873                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15874                format_ip6_address, fp->next_hop);
15875       else if (fp->afi == IP46_TYPE_IP4)
15876         print (vam->ofp,
15877                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15878                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15879                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15880                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15881                format_ip4_address, fp->next_hop);
15882       fp++;
15883     }
15884 }
15885
15886 static void vl_api_ip_fib_details_t_handler_json
15887   (vl_api_ip_fib_details_t * mp)
15888 {
15889   vat_main_t *vam = &vat_main;
15890   int count = ntohl (mp->count);
15891   vat_json_node_t *node = NULL;
15892   struct in_addr ip4;
15893   struct in6_addr ip6;
15894   vl_api_fib_path_t *fp;
15895   int i;
15896
15897   if (VAT_JSON_ARRAY != vam->json_tree.type)
15898     {
15899       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15900       vat_json_init_array (&vam->json_tree);
15901     }
15902   node = vat_json_array_add (&vam->json_tree);
15903
15904   vat_json_init_object (node);
15905   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15906   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15907   vat_json_object_add_ip4 (node, "prefix", ip4);
15908   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15909   vat_json_object_add_uint (node, "path_count", count);
15910   fp = mp->path;
15911   for (i = 0; i < count; i++)
15912     {
15913       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15914       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15915       vat_json_object_add_uint (node, "is_local", fp->is_local);
15916       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15917       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15918       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15919       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15920       if (fp->afi == IP46_TYPE_IP4)
15921         {
15922           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15923           vat_json_object_add_ip4 (node, "next_hop", ip4);
15924         }
15925       else if (fp->afi == IP46_TYPE_IP6)
15926         {
15927           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15928           vat_json_object_add_ip6 (node, "next_hop", ip6);
15929         }
15930     }
15931 }
15932
15933 static int
15934 api_ip_fib_dump (vat_main_t * vam)
15935 {
15936   vl_api_ip_fib_dump_t *mp;
15937   f64 timeout;
15938
15939   M (IP_FIB_DUMP, ip_fib_dump);
15940   S;
15941
15942   /* Use a control ping for synchronization */
15943   {
15944     vl_api_control_ping_t *mp;
15945     M (CONTROL_PING, control_ping);
15946     S;
15947   }
15948   W;
15949 }
15950
15951 static void vl_api_ip_neighbor_details_t_handler
15952   (vl_api_ip_neighbor_details_t * mp)
15953 {
15954   vat_main_t *vam = &vat_main;
15955
15956   print (vam->ofp, "%c %U %U",
15957          (mp->is_static) ? 'S' : 'D',
15958          format_ethernet_address, &mp->mac_address,
15959          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15960          &mp->ip_address);
15961 }
15962
15963 static void vl_api_ip_neighbor_details_t_handler_json
15964   (vl_api_ip_neighbor_details_t * mp)
15965 {
15966
15967   vat_main_t *vam = &vat_main;
15968   vat_json_node_t *node;
15969   struct in_addr ip4;
15970   struct in6_addr ip6;
15971
15972   if (VAT_JSON_ARRAY != vam->json_tree.type)
15973     {
15974       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15975       vat_json_init_array (&vam->json_tree);
15976     }
15977   node = vat_json_array_add (&vam->json_tree);
15978
15979   vat_json_init_object (node);
15980   vat_json_object_add_string_copy (node, "flag",
15981                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15982                                    "dynamic");
15983
15984   vat_json_object_add_string_copy (node, "link_layer",
15985                                    format (0, "%U", format_ethernet_address,
15986                                            &mp->mac_address));
15987
15988   if (mp->is_ipv6)
15989     {
15990       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15991       vat_json_object_add_ip6 (node, "ip_address", ip6);
15992     }
15993   else
15994     {
15995       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15996       vat_json_object_add_ip4 (node, "ip_address", ip4);
15997     }
15998 }
15999
16000 static int
16001 api_ip_neighbor_dump (vat_main_t * vam)
16002 {
16003   unformat_input_t *i = vam->input;
16004   vl_api_ip_neighbor_dump_t *mp;
16005   f64 timeout;
16006   u8 is_ipv6 = 0;
16007   u32 sw_if_index = ~0;
16008
16009   /* Parse args required to build the message */
16010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16011     {
16012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16013         ;
16014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16015         ;
16016       else if (unformat (i, "ip6"))
16017         is_ipv6 = 1;
16018       else
16019         break;
16020     }
16021
16022   if (sw_if_index == ~0)
16023     {
16024       errmsg ("missing interface name or sw_if_index");
16025       return -99;
16026     }
16027
16028   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
16029   mp->is_ipv6 = (u8) is_ipv6;
16030   mp->sw_if_index = ntohl (sw_if_index);
16031   S;
16032
16033   /* Use a control ping for synchronization */
16034   {
16035     vl_api_control_ping_t *mp;
16036     M (CONTROL_PING, control_ping);
16037     S;
16038   }
16039   W;
16040 }
16041
16042 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16043 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16044
16045 static void
16046 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16047 {
16048   vat_main_t *vam = &vat_main;
16049   int count = ntohl (mp->count);
16050   vl_api_fib_path_t *fp;
16051   int i;
16052
16053   print (vam->ofp,
16054          "table-id %d, prefix %U/%d",
16055          ntohl (mp->table_id), format_ip6_address, mp->address,
16056          mp->address_length);
16057   fp = mp->path;
16058   for (i = 0; i < count; i++)
16059     {
16060       if (fp->afi == IP46_TYPE_IP6)
16061         print (vam->ofp,
16062                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16063                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16064                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16065                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16066                format_ip6_address, fp->next_hop);
16067       else if (fp->afi == IP46_TYPE_IP4)
16068         print (vam->ofp,
16069                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16070                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16071                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16072                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16073                format_ip4_address, fp->next_hop);
16074       fp++;
16075     }
16076 }
16077
16078 static void vl_api_ip6_fib_details_t_handler_json
16079   (vl_api_ip6_fib_details_t * mp)
16080 {
16081   vat_main_t *vam = &vat_main;
16082   int count = ntohl (mp->count);
16083   vat_json_node_t *node = NULL;
16084   struct in_addr ip4;
16085   struct in6_addr ip6;
16086   vl_api_fib_path_t *fp;
16087   int i;
16088
16089   if (VAT_JSON_ARRAY != vam->json_tree.type)
16090     {
16091       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16092       vat_json_init_array (&vam->json_tree);
16093     }
16094   node = vat_json_array_add (&vam->json_tree);
16095
16096   vat_json_init_object (node);
16097   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16098   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16099   vat_json_object_add_ip6 (node, "prefix", ip6);
16100   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16101   vat_json_object_add_uint (node, "path_count", count);
16102   fp = mp->path;
16103   for (i = 0; i < count; i++)
16104     {
16105       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16106       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16107       vat_json_object_add_uint (node, "is_local", fp->is_local);
16108       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16109       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16110       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16111       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16112       if (fp->afi == IP46_TYPE_IP4)
16113         {
16114           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16115           vat_json_object_add_ip4 (node, "next_hop", ip4);
16116         }
16117       else if (fp->afi == IP46_TYPE_IP6)
16118         {
16119           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16120           vat_json_object_add_ip6 (node, "next_hop", ip6);
16121         }
16122     }
16123 }
16124
16125 static int
16126 api_ip6_fib_dump (vat_main_t * vam)
16127 {
16128   vl_api_ip6_fib_dump_t *mp;
16129   f64 timeout;
16130
16131   M (IP6_FIB_DUMP, ip6_fib_dump);
16132   S;
16133
16134   /* Use a control ping for synchronization */
16135   {
16136     vl_api_control_ping_t *mp;
16137     M (CONTROL_PING, control_ping);
16138     S;
16139   }
16140   W;
16141 }
16142
16143 int
16144 api_classify_table_ids (vat_main_t * vam)
16145 {
16146   vl_api_classify_table_ids_t *mp;
16147   f64 timeout;
16148
16149   /* Construct the API message */
16150   M (CLASSIFY_TABLE_IDS, classify_table_ids);
16151   mp->context = 0;
16152
16153   S;
16154   W;
16155   /* NOTREACHED */
16156   return 0;
16157 }
16158
16159 int
16160 api_classify_table_by_interface (vat_main_t * vam)
16161 {
16162   unformat_input_t *input = vam->input;
16163   vl_api_classify_table_by_interface_t *mp;
16164   f64 timeout;
16165
16166   u32 sw_if_index = ~0;
16167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16168     {
16169       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16170         ;
16171       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16172         ;
16173       else
16174         break;
16175     }
16176   if (sw_if_index == ~0)
16177     {
16178       errmsg ("missing interface name or sw_if_index");
16179       return -99;
16180     }
16181
16182   /* Construct the API message */
16183   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
16184   mp->context = 0;
16185   mp->sw_if_index = ntohl (sw_if_index);
16186
16187   S;
16188   W;
16189   /* NOTREACHED */
16190   return 0;
16191 }
16192
16193 int
16194 api_classify_table_info (vat_main_t * vam)
16195 {
16196   unformat_input_t *input = vam->input;
16197   vl_api_classify_table_info_t *mp;
16198   f64 timeout;
16199
16200   u32 table_id = ~0;
16201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16202     {
16203       if (unformat (input, "table_id %d", &table_id))
16204         ;
16205       else
16206         break;
16207     }
16208   if (table_id == ~0)
16209     {
16210       errmsg ("missing table id");
16211       return -99;
16212     }
16213
16214   /* Construct the API message */
16215   M (CLASSIFY_TABLE_INFO, classify_table_info);
16216   mp->context = 0;
16217   mp->table_id = ntohl (table_id);
16218
16219   S;
16220   W;
16221   /* NOTREACHED */
16222   return 0;
16223 }
16224
16225 int
16226 api_classify_session_dump (vat_main_t * vam)
16227 {
16228   unformat_input_t *input = vam->input;
16229   vl_api_classify_session_dump_t *mp;
16230   f64 timeout;
16231
16232   u32 table_id = ~0;
16233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16234     {
16235       if (unformat (input, "table_id %d", &table_id))
16236         ;
16237       else
16238         break;
16239     }
16240   if (table_id == ~0)
16241     {
16242       errmsg ("missing table id");
16243       return -99;
16244     }
16245
16246   /* Construct the API message */
16247   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
16248   mp->context = 0;
16249   mp->table_id = ntohl (table_id);
16250   S;
16251
16252   /* Use a control ping for synchronization */
16253   {
16254     vl_api_control_ping_t *mp;
16255     M (CONTROL_PING, control_ping);
16256     S;
16257   }
16258   W;
16259   /* NOTREACHED */
16260   return 0;
16261 }
16262
16263 static void
16264 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16265 {
16266   vat_main_t *vam = &vat_main;
16267
16268   print (vam->ofp, "collector_address %U, collector_port %d, "
16269          "src_address %U, vrf_id %d, path_mtu %u, "
16270          "template_interval %u, udp_checksum %d",
16271          format_ip4_address, mp->collector_address,
16272          ntohs (mp->collector_port),
16273          format_ip4_address, mp->src_address,
16274          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16275          ntohl (mp->template_interval), mp->udp_checksum);
16276
16277   vam->retval = 0;
16278   vam->result_ready = 1;
16279 }
16280
16281 static void
16282   vl_api_ipfix_exporter_details_t_handler_json
16283   (vl_api_ipfix_exporter_details_t * mp)
16284 {
16285   vat_main_t *vam = &vat_main;
16286   vat_json_node_t node;
16287   struct in_addr collector_address;
16288   struct in_addr src_address;
16289
16290   vat_json_init_object (&node);
16291   clib_memcpy (&collector_address, &mp->collector_address,
16292                sizeof (collector_address));
16293   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16294   vat_json_object_add_uint (&node, "collector_port",
16295                             ntohs (mp->collector_port));
16296   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16297   vat_json_object_add_ip4 (&node, "src_address", src_address);
16298   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16299   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16300   vat_json_object_add_uint (&node, "template_interval",
16301                             ntohl (mp->template_interval));
16302   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16303
16304   vat_json_print (vam->ofp, &node);
16305   vat_json_free (&node);
16306   vam->retval = 0;
16307   vam->result_ready = 1;
16308 }
16309
16310 int
16311 api_ipfix_exporter_dump (vat_main_t * vam)
16312 {
16313   vl_api_ipfix_exporter_dump_t *mp;
16314   f64 timeout;
16315
16316   /* Construct the API message */
16317   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
16318   mp->context = 0;
16319
16320   S;
16321   W;
16322   /* NOTREACHED */
16323   return 0;
16324 }
16325
16326 static int
16327 api_ipfix_classify_stream_dump (vat_main_t * vam)
16328 {
16329   vl_api_ipfix_classify_stream_dump_t *mp;
16330   f64 timeout;
16331
16332   /* Construct the API message */
16333   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
16334   mp->context = 0;
16335
16336   S;
16337   W;
16338   /* NOTREACHED */
16339   return 0;
16340 }
16341
16342 static void
16343   vl_api_ipfix_classify_stream_details_t_handler
16344   (vl_api_ipfix_classify_stream_details_t * mp)
16345 {
16346   vat_main_t *vam = &vat_main;
16347   print (vam->ofp, "domain_id %d, src_port %d",
16348          ntohl (mp->domain_id), ntohs (mp->src_port));
16349   vam->retval = 0;
16350   vam->result_ready = 1;
16351 }
16352
16353 static void
16354   vl_api_ipfix_classify_stream_details_t_handler_json
16355   (vl_api_ipfix_classify_stream_details_t * mp)
16356 {
16357   vat_main_t *vam = &vat_main;
16358   vat_json_node_t node;
16359
16360   vat_json_init_object (&node);
16361   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16362   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16363
16364   vat_json_print (vam->ofp, &node);
16365   vat_json_free (&node);
16366   vam->retval = 0;
16367   vam->result_ready = 1;
16368 }
16369
16370 static int
16371 api_ipfix_classify_table_dump (vat_main_t * vam)
16372 {
16373   vl_api_ipfix_classify_table_dump_t *mp;
16374   f64 timeout;
16375
16376   if (!vam->json_output)
16377     {
16378       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16379              "transport_protocol");
16380     }
16381
16382   /* Construct the API message */
16383   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
16384
16385   /* send it... */
16386   S;
16387
16388   /* Use a control ping for synchronization */
16389   {
16390     vl_api_control_ping_t *mp;
16391     M (CONTROL_PING, control_ping);
16392     S;
16393   }
16394   W;
16395 }
16396
16397 static void
16398   vl_api_ipfix_classify_table_details_t_handler
16399   (vl_api_ipfix_classify_table_details_t * mp)
16400 {
16401   vat_main_t *vam = &vat_main;
16402   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16403          mp->transport_protocol);
16404 }
16405
16406 static void
16407   vl_api_ipfix_classify_table_details_t_handler_json
16408   (vl_api_ipfix_classify_table_details_t * mp)
16409 {
16410   vat_json_node_t *node = NULL;
16411   vat_main_t *vam = &vat_main;
16412
16413   if (VAT_JSON_ARRAY != vam->json_tree.type)
16414     {
16415       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16416       vat_json_init_array (&vam->json_tree);
16417     }
16418
16419   node = vat_json_array_add (&vam->json_tree);
16420   vat_json_init_object (node);
16421
16422   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16423   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16424   vat_json_object_add_uint (node, "transport_protocol",
16425                             mp->transport_protocol);
16426 }
16427
16428 static int
16429 api_sw_interface_span_enable_disable (vat_main_t * vam)
16430 {
16431   unformat_input_t *i = vam->input;
16432   vl_api_sw_interface_span_enable_disable_t *mp;
16433   f64 timeout;
16434   u32 src_sw_if_index = ~0;
16435   u32 dst_sw_if_index = ~0;
16436   u8 state = 3;
16437
16438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16439     {
16440       if (unformat
16441           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16442         ;
16443       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16444         ;
16445       else
16446         if (unformat
16447             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16448         ;
16449       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16450         ;
16451       else if (unformat (i, "disable"))
16452         state = 0;
16453       else if (unformat (i, "rx"))
16454         state = 1;
16455       else if (unformat (i, "tx"))
16456         state = 2;
16457       else if (unformat (i, "both"))
16458         state = 3;
16459       else
16460         break;
16461     }
16462
16463   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16464
16465   mp->sw_if_index_from = htonl (src_sw_if_index);
16466   mp->sw_if_index_to = htonl (dst_sw_if_index);
16467   mp->state = state;
16468
16469   S;
16470   W;
16471   /* NOTREACHED */
16472   return 0;
16473 }
16474
16475 static void
16476 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16477                                             * mp)
16478 {
16479   vat_main_t *vam = &vat_main;
16480   u8 *sw_if_from_name = 0;
16481   u8 *sw_if_to_name = 0;
16482   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16483   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16484   char *states[] = { "none", "rx", "tx", "both" };
16485   hash_pair_t *p;
16486
16487   /* *INDENT-OFF* */
16488   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16489   ({
16490     if ((u32) p->value[0] == sw_if_index_from)
16491       {
16492         sw_if_from_name = (u8 *)(p->key);
16493         if (sw_if_to_name)
16494           break;
16495       }
16496     if ((u32) p->value[0] == sw_if_index_to)
16497       {
16498         sw_if_to_name = (u8 *)(p->key);
16499         if (sw_if_from_name)
16500           break;
16501       }
16502   }));
16503   /* *INDENT-ON* */
16504   print (vam->ofp, "%20s => %20s (%s)",
16505          sw_if_from_name, sw_if_to_name, states[mp->state]);
16506 }
16507
16508 static void
16509   vl_api_sw_interface_span_details_t_handler_json
16510   (vl_api_sw_interface_span_details_t * mp)
16511 {
16512   vat_main_t *vam = &vat_main;
16513   vat_json_node_t *node = NULL;
16514   u8 *sw_if_from_name = 0;
16515   u8 *sw_if_to_name = 0;
16516   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16517   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16518   hash_pair_t *p;
16519
16520   /* *INDENT-OFF* */
16521   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16522   ({
16523     if ((u32) p->value[0] == sw_if_index_from)
16524       {
16525         sw_if_from_name = (u8 *)(p->key);
16526         if (sw_if_to_name)
16527           break;
16528       }
16529     if ((u32) p->value[0] == sw_if_index_to)
16530       {
16531         sw_if_to_name = (u8 *)(p->key);
16532         if (sw_if_from_name)
16533           break;
16534       }
16535   }));
16536   /* *INDENT-ON* */
16537
16538   if (VAT_JSON_ARRAY != vam->json_tree.type)
16539     {
16540       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16541       vat_json_init_array (&vam->json_tree);
16542     }
16543   node = vat_json_array_add (&vam->json_tree);
16544
16545   vat_json_init_object (node);
16546   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16547   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16548   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16549   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16550   vat_json_object_add_uint (node, "state", mp->state);
16551 }
16552
16553 static int
16554 api_sw_interface_span_dump (vat_main_t * vam)
16555 {
16556   vl_api_sw_interface_span_dump_t *mp;
16557   f64 timeout;
16558
16559   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16560   S;
16561
16562   /* Use a control ping for synchronization */
16563   {
16564     vl_api_control_ping_t *mp;
16565     M (CONTROL_PING, control_ping);
16566     S;
16567   }
16568   W;
16569 }
16570
16571 int
16572 api_pg_create_interface (vat_main_t * vam)
16573 {
16574   unformat_input_t *input = vam->input;
16575   vl_api_pg_create_interface_t *mp;
16576   f64 timeout;
16577
16578   u32 if_id = ~0;
16579   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16580     {
16581       if (unformat (input, "if_id %d", &if_id))
16582         ;
16583       else
16584         break;
16585     }
16586   if (if_id == ~0)
16587     {
16588       errmsg ("missing pg interface index");
16589       return -99;
16590     }
16591
16592   /* Construct the API message */
16593   M (PG_CREATE_INTERFACE, pg_create_interface);
16594   mp->context = 0;
16595   mp->interface_id = ntohl (if_id);
16596
16597   S;
16598   W;
16599   /* NOTREACHED */
16600   return 0;
16601 }
16602
16603 int
16604 api_pg_capture (vat_main_t * vam)
16605 {
16606   unformat_input_t *input = vam->input;
16607   vl_api_pg_capture_t *mp;
16608   f64 timeout;
16609
16610   u32 if_id = ~0;
16611   u8 enable = 1;
16612   u32 count = 1;
16613   u8 pcap_file_set = 0;
16614   u8 *pcap_file = 0;
16615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16616     {
16617       if (unformat (input, "if_id %d", &if_id))
16618         ;
16619       else if (unformat (input, "pcap %s", &pcap_file))
16620         pcap_file_set = 1;
16621       else if (unformat (input, "count %d", &count))
16622         ;
16623       else if (unformat (input, "disable"))
16624         enable = 0;
16625       else
16626         break;
16627     }
16628   if (if_id == ~0)
16629     {
16630       errmsg ("missing pg interface index");
16631       return -99;
16632     }
16633   if (pcap_file_set > 0)
16634     {
16635       if (vec_len (pcap_file) > 255)
16636         {
16637           errmsg ("pcap file name is too long");
16638           return -99;
16639         }
16640     }
16641
16642   u32 name_len = vec_len (pcap_file);
16643   /* Construct the API message */
16644   M (PG_CAPTURE, pg_capture);
16645   mp->context = 0;
16646   mp->interface_id = ntohl (if_id);
16647   mp->is_enabled = enable;
16648   mp->count = ntohl (count);
16649   mp->pcap_name_length = ntohl (name_len);
16650   if (pcap_file_set != 0)
16651     {
16652       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16653     }
16654   vec_free (pcap_file);
16655
16656   S;
16657   W;
16658   /* NOTREACHED */
16659   return 0;
16660 }
16661
16662 int
16663 api_pg_enable_disable (vat_main_t * vam)
16664 {
16665   unformat_input_t *input = vam->input;
16666   vl_api_pg_enable_disable_t *mp;
16667   f64 timeout;
16668
16669   u8 enable = 1;
16670   u8 stream_name_set = 0;
16671   u8 *stream_name = 0;
16672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16673     {
16674       if (unformat (input, "stream %s", &stream_name))
16675         stream_name_set = 1;
16676       else if (unformat (input, "disable"))
16677         enable = 0;
16678       else
16679         break;
16680     }
16681
16682   if (stream_name_set > 0)
16683     {
16684       if (vec_len (stream_name) > 255)
16685         {
16686           errmsg ("stream name too long");
16687           return -99;
16688         }
16689     }
16690
16691   u32 name_len = vec_len (stream_name);
16692   /* Construct the API message */
16693   M (PG_ENABLE_DISABLE, pg_enable_disable);
16694   mp->context = 0;
16695   mp->is_enabled = enable;
16696   if (stream_name_set != 0)
16697     {
16698       mp->stream_name_length = ntohl (name_len);
16699       clib_memcpy (mp->stream_name, stream_name, name_len);
16700     }
16701   vec_free (stream_name);
16702
16703   S;
16704   W;
16705   /* NOTREACHED */
16706   return 0;
16707 }
16708
16709 int
16710 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16711 {
16712   unformat_input_t *input = vam->input;
16713   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16714   f64 timeout;
16715
16716   u16 *low_ports = 0;
16717   u16 *high_ports = 0;
16718   u16 this_low;
16719   u16 this_hi;
16720   ip4_address_t ip4_addr;
16721   ip6_address_t ip6_addr;
16722   u32 length;
16723   u32 tmp, tmp2;
16724   u8 prefix_set = 0;
16725   u32 vrf_id = ~0;
16726   u8 is_add = 1;
16727   u8 is_ipv6 = 0;
16728
16729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16730     {
16731       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16732         {
16733           prefix_set = 1;
16734         }
16735       else
16736         if (unformat
16737             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16738         {
16739           prefix_set = 1;
16740           is_ipv6 = 1;
16741         }
16742       else if (unformat (input, "vrf %d", &vrf_id))
16743         ;
16744       else if (unformat (input, "del"))
16745         is_add = 0;
16746       else if (unformat (input, "port %d", &tmp))
16747         {
16748           if (tmp == 0 || tmp > 65535)
16749             {
16750               errmsg ("port %d out of range", tmp);
16751               return -99;
16752             }
16753           this_low = tmp;
16754           this_hi = this_low + 1;
16755           vec_add1 (low_ports, this_low);
16756           vec_add1 (high_ports, this_hi);
16757         }
16758       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16759         {
16760           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16761             {
16762               errmsg ("incorrect range parameters");
16763               return -99;
16764             }
16765           this_low = tmp;
16766           /* Note: in debug CLI +1 is added to high before
16767              passing to real fn that does "the work"
16768              (ip_source_and_port_range_check_add_del).
16769              This fn is a wrapper around the binary API fn a
16770              control plane will call, which expects this increment
16771              to have occurred. Hence letting the binary API control
16772              plane fn do the increment for consistency between VAT
16773              and other control planes.
16774            */
16775           this_hi = tmp2;
16776           vec_add1 (low_ports, this_low);
16777           vec_add1 (high_ports, this_hi);
16778         }
16779       else
16780         break;
16781     }
16782
16783   if (prefix_set == 0)
16784     {
16785       errmsg ("<address>/<mask> not specified");
16786       return -99;
16787     }
16788
16789   if (vrf_id == ~0)
16790     {
16791       errmsg ("VRF ID required, not specified");
16792       return -99;
16793     }
16794
16795   if (vrf_id == 0)
16796     {
16797       errmsg
16798         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16799       return -99;
16800     }
16801
16802   if (vec_len (low_ports) == 0)
16803     {
16804       errmsg ("At least one port or port range required");
16805       return -99;
16806     }
16807
16808   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16809      ip_source_and_port_range_check_add_del);
16810
16811   mp->is_add = is_add;
16812
16813   if (is_ipv6)
16814     {
16815       mp->is_ipv6 = 1;
16816       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16817     }
16818   else
16819     {
16820       mp->is_ipv6 = 0;
16821       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16822     }
16823
16824   mp->mask_length = length;
16825   mp->number_of_ranges = vec_len (low_ports);
16826
16827   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16828   vec_free (low_ports);
16829
16830   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16831   vec_free (high_ports);
16832
16833   mp->vrf_id = ntohl (vrf_id);
16834
16835   S;
16836   W;
16837   /* NOTREACHED */
16838   return 0;
16839 }
16840
16841 int
16842 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16843 {
16844   unformat_input_t *input = vam->input;
16845   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16846   f64 timeout;
16847   u32 sw_if_index = ~0;
16848   int vrf_set = 0;
16849   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16850   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16851   u8 is_add = 1;
16852
16853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16854     {
16855       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16856         ;
16857       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16858         ;
16859       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16860         vrf_set = 1;
16861       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16862         vrf_set = 1;
16863       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16864         vrf_set = 1;
16865       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16866         vrf_set = 1;
16867       else if (unformat (input, "del"))
16868         is_add = 0;
16869       else
16870         break;
16871     }
16872
16873   if (sw_if_index == ~0)
16874     {
16875       errmsg ("Interface required but not specified");
16876       return -99;
16877     }
16878
16879   if (vrf_set == 0)
16880     {
16881       errmsg ("VRF ID required but not specified");
16882       return -99;
16883     }
16884
16885   if (tcp_out_vrf_id == 0
16886       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16887     {
16888       errmsg
16889         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16890       return -99;
16891     }
16892
16893   /* Construct the API message */
16894   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16895      ip_source_and_port_range_check_interface_add_del);
16896
16897   mp->sw_if_index = ntohl (sw_if_index);
16898   mp->is_add = is_add;
16899   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16900   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16901   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16902   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16903
16904   /* send it... */
16905   S;
16906
16907   /* Wait for a reply... */
16908   W;
16909 }
16910
16911 static int
16912 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16913 {
16914   unformat_input_t *i = vam->input;
16915   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16916   f64 timeout;
16917   u32 local_sa_id = 0;
16918   u32 remote_sa_id = 0;
16919   ip4_address_t src_address;
16920   ip4_address_t dst_address;
16921   u8 is_add = 1;
16922
16923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16924     {
16925       if (unformat (i, "local_sa %d", &local_sa_id))
16926         ;
16927       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16928         ;
16929       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16930         ;
16931       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16932         ;
16933       else if (unformat (i, "del"))
16934         is_add = 0;
16935       else
16936         {
16937           clib_warning ("parse error '%U'", format_unformat_error, i);
16938           return -99;
16939         }
16940     }
16941
16942   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16943
16944   mp->local_sa_id = ntohl (local_sa_id);
16945   mp->remote_sa_id = ntohl (remote_sa_id);
16946   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16947   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16948   mp->is_add = is_add;
16949
16950   S;
16951   W;
16952   /* NOTREACHED */
16953   return 0;
16954 }
16955
16956 static int
16957 api_punt (vat_main_t * vam)
16958 {
16959   unformat_input_t *i = vam->input;
16960   vl_api_punt_t *mp;
16961   f64 timeout;
16962   u32 ipv = ~0;
16963   u32 protocol = ~0;
16964   u32 port = ~0;
16965   int is_add = 1;
16966
16967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16968     {
16969       if (unformat (i, "ip %d", &ipv))
16970         ;
16971       else if (unformat (i, "protocol %d", &protocol))
16972         ;
16973       else if (unformat (i, "port %d", &port))
16974         ;
16975       else if (unformat (i, "del"))
16976         is_add = 0;
16977       else
16978         {
16979           clib_warning ("parse error '%U'", format_unformat_error, i);
16980           return -99;
16981         }
16982     }
16983
16984   M (PUNT, punt);
16985
16986   mp->is_add = (u8) is_add;
16987   mp->ipv = (u8) ipv;
16988   mp->l4_protocol = (u8) protocol;
16989   mp->l4_port = htons ((u16) port);
16990
16991   S;
16992   W;
16993   /* NOTREACHED */
16994   return 0;
16995 }
16996
16997 static void vl_api_ipsec_gre_tunnel_details_t_handler
16998   (vl_api_ipsec_gre_tunnel_details_t * mp)
16999 {
17000   vat_main_t *vam = &vat_main;
17001
17002   print (vam->ofp, "%11d%15U%15U%14d%14d",
17003          ntohl (mp->sw_if_index),
17004          format_ip4_address, &mp->src_address,
17005          format_ip4_address, &mp->dst_address,
17006          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17007 }
17008
17009 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17010   (vl_api_ipsec_gre_tunnel_details_t * mp)
17011 {
17012   vat_main_t *vam = &vat_main;
17013   vat_json_node_t *node = NULL;
17014   struct in_addr ip4;
17015
17016   if (VAT_JSON_ARRAY != vam->json_tree.type)
17017     {
17018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17019       vat_json_init_array (&vam->json_tree);
17020     }
17021   node = vat_json_array_add (&vam->json_tree);
17022
17023   vat_json_init_object (node);
17024   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17025   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17026   vat_json_object_add_ip4 (node, "src_address", ip4);
17027   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17028   vat_json_object_add_ip4 (node, "dst_address", ip4);
17029   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17030   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17031 }
17032
17033 static int
17034 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17035 {
17036   unformat_input_t *i = vam->input;
17037   vl_api_ipsec_gre_tunnel_dump_t *mp;
17038   f64 timeout;
17039   u32 sw_if_index;
17040   u8 sw_if_index_set = 0;
17041
17042   /* Parse args required to build the message */
17043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17044     {
17045       if (unformat (i, "sw_if_index %d", &sw_if_index))
17046         sw_if_index_set = 1;
17047       else
17048         break;
17049     }
17050
17051   if (sw_if_index_set == 0)
17052     {
17053       sw_if_index = ~0;
17054     }
17055
17056   if (!vam->json_output)
17057     {
17058       print (vam->ofp, "%11s%15s%15s%14s%14s",
17059              "sw_if_index", "src_address", "dst_address",
17060              "local_sa_id", "remote_sa_id");
17061     }
17062
17063   /* Get list of gre-tunnel interfaces */
17064   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
17065
17066   mp->sw_if_index = htonl (sw_if_index);
17067
17068   S;
17069
17070   /* Use a control ping for synchronization */
17071   {
17072     vl_api_control_ping_t *mp;
17073     M (CONTROL_PING, control_ping);
17074     S;
17075   }
17076   W;
17077 }
17078
17079 static int
17080 api_delete_subif (vat_main_t * vam)
17081 {
17082   unformat_input_t *i = vam->input;
17083   vl_api_delete_subif_t *mp;
17084   f64 timeout;
17085   u32 sw_if_index = ~0;
17086
17087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17088     {
17089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17090         ;
17091       if (unformat (i, "sw_if_index %d", &sw_if_index))
17092         ;
17093       else
17094         break;
17095     }
17096
17097   if (sw_if_index == ~0)
17098     {
17099       errmsg ("missing sw_if_index");
17100       return -99;
17101     }
17102
17103   /* Construct the API message */
17104   M (DELETE_SUBIF, delete_subif);
17105   mp->sw_if_index = ntohl (sw_if_index);
17106
17107   S;
17108   W;
17109 }
17110
17111 #define foreach_pbb_vtr_op      \
17112 _("disable",  L2_VTR_DISABLED)  \
17113 _("pop",  L2_VTR_POP_2)         \
17114 _("push",  L2_VTR_PUSH_2)
17115
17116 static int
17117 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17118 {
17119   unformat_input_t *i = vam->input;
17120   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17121   f64 timeout;
17122   u32 sw_if_index = ~0, vtr_op = ~0;
17123   u16 outer_tag = ~0;
17124   u8 dmac[6], smac[6];
17125   u8 dmac_set = 0, smac_set = 0;
17126   u16 vlanid = 0;
17127   u32 sid = ~0;
17128   u32 tmp;
17129
17130   /* Shut up coverity */
17131   memset (dmac, 0, sizeof (dmac));
17132   memset (smac, 0, sizeof (smac));
17133
17134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17135     {
17136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17137         ;
17138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17139         ;
17140       else if (unformat (i, "vtr_op %d", &vtr_op))
17141         ;
17142 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17143       foreach_pbb_vtr_op
17144 #undef _
17145         else if (unformat (i, "translate_pbb_stag"))
17146         {
17147           if (unformat (i, "%d", &tmp))
17148             {
17149               vtr_op = L2_VTR_TRANSLATE_2_1;
17150               outer_tag = tmp;
17151             }
17152           else
17153             {
17154               errmsg
17155                 ("translate_pbb_stag operation requires outer tag definition");
17156               return -99;
17157             }
17158         }
17159       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17160         dmac_set++;
17161       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17162         smac_set++;
17163       else if (unformat (i, "sid %d", &sid))
17164         ;
17165       else if (unformat (i, "vlanid %d", &tmp))
17166         vlanid = tmp;
17167       else
17168         {
17169           clib_warning ("parse error '%U'", format_unformat_error, i);
17170           return -99;
17171         }
17172     }
17173
17174   if ((sw_if_index == ~0) || (vtr_op == ~0))
17175     {
17176       errmsg ("missing sw_if_index or vtr operation");
17177       return -99;
17178     }
17179   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17180       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17181     {
17182       errmsg
17183         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17184       return -99;
17185     }
17186
17187   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
17188   mp->sw_if_index = ntohl (sw_if_index);
17189   mp->vtr_op = ntohl (vtr_op);
17190   mp->outer_tag = ntohs (outer_tag);
17191   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17192   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17193   mp->b_vlanid = ntohs (vlanid);
17194   mp->i_sid = ntohl (sid);
17195
17196   S;
17197   W;
17198   /* NOTREACHED */
17199   return 0;
17200 }
17201
17202 static int
17203 api_flow_classify_set_interface (vat_main_t * vam)
17204 {
17205   unformat_input_t *i = vam->input;
17206   vl_api_flow_classify_set_interface_t *mp;
17207   f64 timeout;
17208   u32 sw_if_index;
17209   int sw_if_index_set;
17210   u32 ip4_table_index = ~0;
17211   u32 ip6_table_index = ~0;
17212   u8 is_add = 1;
17213
17214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17215     {
17216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17217         sw_if_index_set = 1;
17218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17219         sw_if_index_set = 1;
17220       else if (unformat (i, "del"))
17221         is_add = 0;
17222       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17223         ;
17224       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17225         ;
17226       else
17227         {
17228           clib_warning ("parse error '%U'", format_unformat_error, i);
17229           return -99;
17230         }
17231     }
17232
17233   if (sw_if_index_set == 0)
17234     {
17235       errmsg ("missing interface name or sw_if_index");
17236       return -99;
17237     }
17238
17239   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
17240
17241   mp->sw_if_index = ntohl (sw_if_index);
17242   mp->ip4_table_index = ntohl (ip4_table_index);
17243   mp->ip6_table_index = ntohl (ip6_table_index);
17244   mp->is_add = is_add;
17245
17246   S;
17247   W;
17248   /* NOTREACHED */
17249   return 0;
17250 }
17251
17252 static int
17253 api_flow_classify_dump (vat_main_t * vam)
17254 {
17255   unformat_input_t *i = vam->input;
17256   vl_api_flow_classify_dump_t *mp;
17257   f64 timeout = ~0;
17258   u8 type = FLOW_CLASSIFY_N_TABLES;
17259
17260   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17261     ;
17262   else
17263     {
17264       errmsg ("classify table type must be specified");
17265       return -99;
17266     }
17267
17268   if (!vam->json_output)
17269     {
17270       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17271     }
17272
17273   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
17274   mp->type = type;
17275   /* send it... */
17276   S;
17277
17278   /* Use a control ping for synchronization */
17279   {
17280     vl_api_control_ping_t *mp;
17281     M (CONTROL_PING, control_ping);
17282     S;
17283   }
17284   /* Wait for a reply... */
17285   W;
17286
17287   /* NOTREACHED */
17288   return 0;
17289 }
17290
17291 static int
17292 api_feature_enable_disable (vat_main_t * vam)
17293 {
17294   unformat_input_t *i = vam->input;
17295   vl_api_feature_enable_disable_t *mp;
17296   f64 timeout;
17297   u8 *arc_name = 0;
17298   u8 *feature_name = 0;
17299   u32 sw_if_index = ~0;
17300   u8 enable = 1;
17301
17302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17303     {
17304       if (unformat (i, "arc_name %s", &arc_name))
17305         ;
17306       else if (unformat (i, "feature_name %s", &feature_name))
17307         ;
17308       else
17309         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17310         ;
17311       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17312         ;
17313       else if (unformat (i, "disable"))
17314         enable = 0;
17315       else
17316         break;
17317     }
17318
17319   if (arc_name == 0)
17320     {
17321       errmsg ("missing arc name");
17322       return -99;
17323     }
17324   if (vec_len (arc_name) > 63)
17325     {
17326       errmsg ("arc name too long");
17327     }
17328
17329   if (feature_name == 0)
17330     {
17331       errmsg ("missing feature name");
17332       return -99;
17333     }
17334   if (vec_len (feature_name) > 63)
17335     {
17336       errmsg ("feature name too long");
17337     }
17338
17339   if (sw_if_index == ~0)
17340     {
17341       errmsg ("missing interface name or sw_if_index");
17342       return -99;
17343     }
17344
17345   /* Construct the API message */
17346   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
17347   mp->sw_if_index = ntohl (sw_if_index);
17348   mp->enable = enable;
17349   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17350   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17351   vec_free (arc_name);
17352   vec_free (feature_name);
17353
17354   S;
17355   W;
17356 }
17357
17358 static int
17359 api_sw_interface_tag_add_del (vat_main_t * vam)
17360 {
17361   unformat_input_t *i = vam->input;
17362   vl_api_sw_interface_tag_add_del_t *mp;
17363   f64 timeout;
17364   u32 sw_if_index = ~0;
17365   u8 *tag = 0;
17366   u8 enable = 1;
17367
17368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17369     {
17370       if (unformat (i, "tag %s", &tag))
17371         ;
17372       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17373         ;
17374       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17375         ;
17376       else if (unformat (i, "del"))
17377         enable = 0;
17378       else
17379         break;
17380     }
17381
17382   if (sw_if_index == ~0)
17383     {
17384       errmsg ("missing interface name or sw_if_index");
17385       return -99;
17386     }
17387
17388   if (enable && (tag == 0))
17389     {
17390       errmsg ("no tag specified");
17391       return -99;
17392     }
17393
17394   /* Construct the API message */
17395   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
17396   mp->sw_if_index = ntohl (sw_if_index);
17397   mp->is_add = enable;
17398   if (enable)
17399     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17400   vec_free (tag);
17401
17402   S;
17403   W;
17404 }
17405
17406 static void vl_api_l2_xconnect_details_t_handler
17407   (vl_api_l2_xconnect_details_t * mp)
17408 {
17409   vat_main_t *vam = &vat_main;
17410
17411   print (vam->ofp, "%15d%15d",
17412          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17413 }
17414
17415 static void vl_api_l2_xconnect_details_t_handler_json
17416   (vl_api_l2_xconnect_details_t * mp)
17417 {
17418   vat_main_t *vam = &vat_main;
17419   vat_json_node_t *node = NULL;
17420
17421   if (VAT_JSON_ARRAY != vam->json_tree.type)
17422     {
17423       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17424       vat_json_init_array (&vam->json_tree);
17425     }
17426   node = vat_json_array_add (&vam->json_tree);
17427
17428   vat_json_init_object (node);
17429   vat_json_object_add_uint (node, "rx_sw_if_index",
17430                             ntohl (mp->rx_sw_if_index));
17431   vat_json_object_add_uint (node, "tx_sw_if_index",
17432                             ntohl (mp->tx_sw_if_index));
17433 }
17434
17435 static int
17436 api_l2_xconnect_dump (vat_main_t * vam)
17437 {
17438   vl_api_l2_xconnect_dump_t *mp;
17439   f64 timeout;
17440
17441   if (!vam->json_output)
17442     {
17443       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17444     }
17445
17446   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
17447
17448   S;
17449
17450   /* Use a control ping for synchronization */
17451   {
17452     vl_api_control_ping_t *mp;
17453     M (CONTROL_PING, control_ping);
17454     S;
17455   }
17456   W;
17457 }
17458
17459 static int
17460 api_sw_interface_set_mtu (vat_main_t * vam)
17461 {
17462   unformat_input_t *i = vam->input;
17463   vl_api_sw_interface_set_mtu_t *mp;
17464   f64 timeout;
17465   u32 sw_if_index = ~0;
17466   u32 mtu = 0;
17467
17468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17469     {
17470       if (unformat (i, "mtu %d", &mtu))
17471         ;
17472       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17473         ;
17474       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17475         ;
17476       else
17477         break;
17478     }
17479
17480   if (sw_if_index == ~0)
17481     {
17482       errmsg ("missing interface name or sw_if_index");
17483       return -99;
17484     }
17485
17486   if (mtu == 0)
17487     {
17488       errmsg ("no mtu specified");
17489       return -99;
17490     }
17491
17492   /* Construct the API message */
17493   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17494   mp->sw_if_index = ntohl (sw_if_index);
17495   mp->mtu = ntohs ((u16) mtu);
17496
17497   S;
17498   W;
17499 }
17500
17501
17502 static int
17503 q_or_quit (vat_main_t * vam)
17504 {
17505   longjmp (vam->jump_buf, 1);
17506   return 0;                     /* not so much */
17507 }
17508
17509 static int
17510 q (vat_main_t * vam)
17511 {
17512   return q_or_quit (vam);
17513 }
17514
17515 static int
17516 quit (vat_main_t * vam)
17517 {
17518   return q_or_quit (vam);
17519 }
17520
17521 static int
17522 comment (vat_main_t * vam)
17523 {
17524   return 0;
17525 }
17526
17527 static int
17528 cmd_cmp (void *a1, void *a2)
17529 {
17530   u8 **c1 = a1;
17531   u8 **c2 = a2;
17532
17533   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17534 }
17535
17536 static int
17537 help (vat_main_t * vam)
17538 {
17539   u8 **cmds = 0;
17540   u8 *name = 0;
17541   hash_pair_t *p;
17542   unformat_input_t *i = vam->input;
17543   int j;
17544
17545   if (unformat (i, "%s", &name))
17546     {
17547       uword *hs;
17548
17549       vec_add1 (name, 0);
17550
17551       hs = hash_get_mem (vam->help_by_name, name);
17552       if (hs)
17553         print (vam->ofp, "usage: %s %s", name, hs[0]);
17554       else
17555         print (vam->ofp, "No such msg / command '%s'", name);
17556       vec_free (name);
17557       return 0;
17558     }
17559
17560   print (vam->ofp, "Help is available for the following:");
17561
17562     /* *INDENT-OFF* */
17563     hash_foreach_pair (p, vam->function_by_name,
17564     ({
17565       vec_add1 (cmds, (u8 *)(p->key));
17566     }));
17567     /* *INDENT-ON* */
17568
17569   vec_sort_with_function (cmds, cmd_cmp);
17570
17571   for (j = 0; j < vec_len (cmds); j++)
17572     print (vam->ofp, "%s", cmds[j]);
17573
17574   vec_free (cmds);
17575   return 0;
17576 }
17577
17578 static int
17579 set (vat_main_t * vam)
17580 {
17581   u8 *name = 0, *value = 0;
17582   unformat_input_t *i = vam->input;
17583
17584   if (unformat (i, "%s", &name))
17585     {
17586       /* The input buffer is a vector, not a string. */
17587       value = vec_dup (i->buffer);
17588       vec_delete (value, i->index, 0);
17589       /* Almost certainly has a trailing newline */
17590       if (value[vec_len (value) - 1] == '\n')
17591         value[vec_len (value) - 1] = 0;
17592       /* Make sure it's a proper string, one way or the other */
17593       vec_add1 (value, 0);
17594       (void) clib_macro_set_value (&vam->macro_main,
17595                                    (char *) name, (char *) value);
17596     }
17597   else
17598     errmsg ("usage: set <name> <value>");
17599
17600   vec_free (name);
17601   vec_free (value);
17602   return 0;
17603 }
17604
17605 static int
17606 unset (vat_main_t * vam)
17607 {
17608   u8 *name = 0;
17609
17610   if (unformat (vam->input, "%s", &name))
17611     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17612       errmsg ("unset: %s wasn't set", name);
17613   vec_free (name);
17614   return 0;
17615 }
17616
17617 typedef struct
17618 {
17619   u8 *name;
17620   u8 *value;
17621 } macro_sort_t;
17622
17623
17624 static int
17625 macro_sort_cmp (void *a1, void *a2)
17626 {
17627   macro_sort_t *s1 = a1;
17628   macro_sort_t *s2 = a2;
17629
17630   return strcmp ((char *) (s1->name), (char *) (s2->name));
17631 }
17632
17633 static int
17634 dump_macro_table (vat_main_t * vam)
17635 {
17636   macro_sort_t *sort_me = 0, *sm;
17637   int i;
17638   hash_pair_t *p;
17639
17640     /* *INDENT-OFF* */
17641     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17642     ({
17643       vec_add2 (sort_me, sm, 1);
17644       sm->name = (u8 *)(p->key);
17645       sm->value = (u8 *) (p->value[0]);
17646     }));
17647     /* *INDENT-ON* */
17648
17649   vec_sort_with_function (sort_me, macro_sort_cmp);
17650
17651   if (vec_len (sort_me))
17652     print (vam->ofp, "%-15s%s", "Name", "Value");
17653   else
17654     print (vam->ofp, "The macro table is empty...");
17655
17656   for (i = 0; i < vec_len (sort_me); i++)
17657     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17658   return 0;
17659 }
17660
17661 static int
17662 dump_node_table (vat_main_t * vam)
17663 {
17664   int i, j;
17665   vlib_node_t *node, *next_node;
17666
17667   if (vec_len (vam->graph_nodes) == 0)
17668     {
17669       print (vam->ofp, "Node table empty, issue get_node_graph...");
17670       return 0;
17671     }
17672
17673   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17674     {
17675       node = vam->graph_nodes[i];
17676       print (vam->ofp, "[%d] %s", i, node->name);
17677       for (j = 0; j < vec_len (node->next_nodes); j++)
17678         {
17679           if (node->next_nodes[j] != ~0)
17680             {
17681               next_node = vam->graph_nodes[node->next_nodes[j]];
17682               print (vam->ofp, "  [%d] %s", j, next_node->name);
17683             }
17684         }
17685     }
17686   return 0;
17687 }
17688
17689 static int
17690 value_sort_cmp (void *a1, void *a2)
17691 {
17692   name_sort_t *n1 = a1;
17693   name_sort_t *n2 = a2;
17694
17695   if (n1->value < n2->value)
17696     return -1;
17697   if (n1->value > n2->value)
17698     return 1;
17699   return 0;
17700 }
17701
17702
17703 static int
17704 dump_msg_api_table (vat_main_t * vam)
17705 {
17706   api_main_t *am = &api_main;
17707   name_sort_t *nses = 0, *ns;
17708   hash_pair_t *hp;
17709   int i;
17710
17711   /* *INDENT-OFF* */
17712   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17713   ({
17714     vec_add2 (nses, ns, 1);
17715     ns->name = (u8 *)(hp->key);
17716     ns->value = (u32) hp->value[0];
17717   }));
17718   /* *INDENT-ON* */
17719
17720   vec_sort_with_function (nses, value_sort_cmp);
17721
17722   for (i = 0; i < vec_len (nses); i++)
17723     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17724   vec_free (nses);
17725   return 0;
17726 }
17727
17728 static int
17729 get_msg_id (vat_main_t * vam)
17730 {
17731   u8 *name_and_crc;
17732   u32 message_index;
17733
17734   if (unformat (vam->input, "%s", &name_and_crc))
17735     {
17736       message_index = vl_api_get_msg_index (name_and_crc);
17737       if (message_index == ~0)
17738         {
17739           print (vam->ofp, " '%s' not found", name_and_crc);
17740           return 0;
17741         }
17742       print (vam->ofp, " '%s' has message index %d",
17743              name_and_crc, message_index);
17744       return 0;
17745     }
17746   errmsg ("name_and_crc required...");
17747   return 0;
17748 }
17749
17750 static int
17751 search_node_table (vat_main_t * vam)
17752 {
17753   unformat_input_t *line_input = vam->input;
17754   u8 *node_to_find;
17755   int j;
17756   vlib_node_t *node, *next_node;
17757   uword *p;
17758
17759   if (vam->graph_node_index_by_name == 0)
17760     {
17761       print (vam->ofp, "Node table empty, issue get_node_graph...");
17762       return 0;
17763     }
17764
17765   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17766     {
17767       if (unformat (line_input, "%s", &node_to_find))
17768         {
17769           vec_add1 (node_to_find, 0);
17770           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17771           if (p == 0)
17772             {
17773               print (vam->ofp, "%s not found...", node_to_find);
17774               goto out;
17775             }
17776           node = vam->graph_nodes[p[0]];
17777           print (vam->ofp, "[%d] %s", p[0], node->name);
17778           for (j = 0; j < vec_len (node->next_nodes); j++)
17779             {
17780               if (node->next_nodes[j] != ~0)
17781                 {
17782                   next_node = vam->graph_nodes[node->next_nodes[j]];
17783                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17784                 }
17785             }
17786         }
17787
17788       else
17789         {
17790           clib_warning ("parse error '%U'", format_unformat_error,
17791                         line_input);
17792           return -99;
17793         }
17794
17795     out:
17796       vec_free (node_to_find);
17797
17798     }
17799
17800   return 0;
17801 }
17802
17803
17804 static int
17805 script (vat_main_t * vam)
17806 {
17807 #if (VPP_API_TEST_BUILTIN==0)
17808   u8 *s = 0;
17809   char *save_current_file;
17810   unformat_input_t save_input;
17811   jmp_buf save_jump_buf;
17812   u32 save_line_number;
17813
17814   FILE *new_fp, *save_ifp;
17815
17816   if (unformat (vam->input, "%s", &s))
17817     {
17818       new_fp = fopen ((char *) s, "r");
17819       if (new_fp == 0)
17820         {
17821           errmsg ("Couldn't open script file %s", s);
17822           vec_free (s);
17823           return -99;
17824         }
17825     }
17826   else
17827     {
17828       errmsg ("Missing script name");
17829       return -99;
17830     }
17831
17832   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17833   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17834   save_ifp = vam->ifp;
17835   save_line_number = vam->input_line_number;
17836   save_current_file = (char *) vam->current_file;
17837
17838   vam->input_line_number = 0;
17839   vam->ifp = new_fp;
17840   vam->current_file = s;
17841   do_one_file (vam);
17842
17843   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17844   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17845   vam->ifp = save_ifp;
17846   vam->input_line_number = save_line_number;
17847   vam->current_file = (u8 *) save_current_file;
17848   vec_free (s);
17849
17850   return 0;
17851 #else
17852   clib_warning ("use the exec command...");
17853   return -99;
17854 #endif
17855 }
17856
17857 static int
17858 echo (vat_main_t * vam)
17859 {
17860   print (vam->ofp, "%v", vam->input->buffer);
17861   return 0;
17862 }
17863
17864 /* List of API message constructors, CLI names map to api_xxx */
17865 #define foreach_vpe_api_msg                                             \
17866 _(create_loopback,"[mac <mac-addr>]")                                   \
17867 _(sw_interface_dump,"")                                                 \
17868 _(sw_interface_set_flags,                                               \
17869   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17870 _(sw_interface_add_del_address,                                         \
17871   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17872 _(sw_interface_set_table,                                               \
17873   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17874 _(sw_interface_set_mpls_enable,                                         \
17875   "<intfc> | sw_if_index [disable | dis]")                              \
17876 _(sw_interface_set_vpath,                                               \
17877   "<intfc> | sw_if_index <id> enable | disable")                        \
17878 _(sw_interface_set_vxlan_bypass,                                        \
17879   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17880 _(sw_interface_set_l2_xconnect,                                         \
17881   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17882   "enable | disable")                                                   \
17883 _(sw_interface_set_l2_bridge,                                           \
17884   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17885   "[shg <split-horizon-group>] [bvi]\n"                                 \
17886   "enable | disable")                                                   \
17887 _(bridge_domain_add_del,                                                \
17888   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17889 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17890 _(l2fib_add_del,                                                        \
17891   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17892 _(l2_flags,                                                             \
17893   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17894 _(bridge_flags,                                                         \
17895   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17896 _(tap_connect,                                                          \
17897   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17898 _(tap_modify,                                                           \
17899   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17900 _(tap_delete,                                                           \
17901   "<vpp-if-name> | sw_if_index <id>")                                   \
17902 _(sw_interface_tap_dump, "")                                            \
17903 _(ip_add_del_route,                                                     \
17904   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17905   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17906   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17907   "[multipath] [count <n>]")                                            \
17908 _(ip_mroute_add_del,                                                    \
17909   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
17910   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
17911 _(mpls_route_add_del,                                                   \
17912   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17913   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17914   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17915   "[multipath] [count <n>]")                                            \
17916 _(mpls_ip_bind_unbind,                                                  \
17917   "<label> <addr/len>")                                                 \
17918 _(mpls_tunnel_add_del,                                                  \
17919   " via <addr> [table-id <n>]\n"                                        \
17920   "sw_if_index <id>] [l2]  [del]")                                      \
17921 _(proxy_arp_add_del,                                                    \
17922   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17923 _(proxy_arp_intfc_enable_disable,                                       \
17924   "<intfc> | sw_if_index <id> enable | disable")                        \
17925 _(sw_interface_set_unnumbered,                                          \
17926   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17927 _(ip_neighbor_add_del,                                                  \
17928   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17929   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17930 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17931 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17932 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17933   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17934   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17935   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17936 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17937 _(reset_fib, "vrf <n> [ipv6]")                                          \
17938 _(dhcp_proxy_config,                                                    \
17939   "svr <v46-address> src <v46-address>\n"                               \
17940    "insert-cid <n> [del]")                                              \
17941 _(dhcp_proxy_config_2,                                                  \
17942   "svr <v46-address> src <v46-address>\n"                               \
17943    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17944 _(dhcp_proxy_set_vss,                                                   \
17945   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17946 _(dhcp_client_config,                                                   \
17947   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17948 _(set_ip_flow_hash,                                                     \
17949   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17950 _(sw_interface_ip6_enable_disable,                                      \
17951   "<intfc> | sw_if_index <id> enable | disable")                        \
17952 _(sw_interface_ip6_set_link_local_address,                              \
17953   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17954 _(sw_interface_ip6nd_ra_prefix,                                         \
17955   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17956   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17957   "[nolink] [isno]")                                                    \
17958 _(sw_interface_ip6nd_ra_config,                                         \
17959   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17960   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17961   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17962 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17963 _(l2_patch_add_del,                                                     \
17964   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17965   "enable | disable")                                                   \
17966 _(sr_tunnel_add_del,                                                    \
17967   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17968   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17969   "[policy <policy_name>]")                                             \
17970 _(sr_policy_add_del,                                                    \
17971   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17972 _(sr_multicast_map_add_del,                                             \
17973   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17974 _(classify_add_del_table,                                               \
17975   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17976   " [del] [del-chain] mask <mask-value>\n"                              \
17977   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17978   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17979 _(classify_add_del_session,                                             \
17980   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17981   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17982   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17983   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17984 _(classify_set_interface_ip_table,                                      \
17985   "<intfc> | sw_if_index <nn> table <nn>")                              \
17986 _(classify_set_interface_l2_tables,                                     \
17987   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17988   "  [other-table <nn>]")                                               \
17989 _(get_node_index, "node <node-name")                                    \
17990 _(add_node_next, "node <node-name> next <next-node-name>")              \
17991 _(l2tpv3_create_tunnel,                                                 \
17992   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17993   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17994   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17995 _(l2tpv3_set_tunnel_cookies,                                            \
17996   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17997   "[new_remote_cookie <nn>]\n")                                         \
17998 _(l2tpv3_interface_enable_disable,                                      \
17999   "<intfc> | sw_if_index <nn> enable | disable")                        \
18000 _(l2tpv3_set_lookup_key,                                                \
18001   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18002 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18003 _(vxlan_add_del_tunnel,                                                 \
18004   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18005   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18006   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18007 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18008 _(gre_add_del_tunnel,                                                   \
18009   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18010 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18011 _(l2_fib_clear_table, "")                                               \
18012 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18013 _(l2_interface_vlan_tag_rewrite,                                        \
18014   "<intfc> | sw_if_index <nn> \n"                                       \
18015   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18016   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18017 _(create_vhost_user_if,                                                 \
18018         "socket <filename> [server] [renumber <dev_instance>] "         \
18019         "[mac <mac_address>]")                                          \
18020 _(modify_vhost_user_if,                                                 \
18021         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18022         "[server] [renumber <dev_instance>]")                           \
18023 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18024 _(sw_interface_vhost_user_dump, "")                                     \
18025 _(show_version, "")                                                     \
18026 _(vxlan_gpe_add_del_tunnel,                                             \
18027   "local <addr> remote <addr> vni <nn>\n"                               \
18028     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18029   "[next-ethernet] [next-nsh]\n")                                       \
18030 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18031 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18032 _(interface_name_renumber,                                              \
18033   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18034 _(input_acl_set_interface,                                              \
18035   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18036   "  [l2-table <nn>] [del]")                                            \
18037 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18038 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18039 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18040 _(ip_dump, "ipv4 | ipv6")                                               \
18041 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18042 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18043   "  spid_id <n> ")                                                     \
18044 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18045   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18046   "  integ_alg <alg> integ_key <hex>")                                  \
18047 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18048   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18049   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18050   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18051 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18052 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18053 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18054   "(auth_data 0x<data> | auth_data <data>)")                            \
18055 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18056   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18057 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18058   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18059   "(local|remote)")                                                     \
18060 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18061 _(delete_loopback,"sw_if_index <nn>")                                   \
18062 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18063 _(map_add_domain,                                                       \
18064   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18065   "ip6-src <ip6addr> "                                                  \
18066   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18067 _(map_del_domain, "index <n>")                                          \
18068 _(map_add_del_rule,                                                     \
18069   "index <n> psid <n> dst <ip6addr> [del]")                             \
18070 _(map_domain_dump, "")                                                  \
18071 _(map_rule_dump, "index <map-domain>")                                  \
18072 _(want_interface_events,  "enable|disable")                             \
18073 _(want_stats,"enable|disable")                                          \
18074 _(get_first_msg_id, "client <name>")                                    \
18075 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18076 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18077   "fib-id <nn> [ip4][ip6][default]")                                    \
18078 _(get_node_graph, " ")                                                  \
18079 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18080 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18081 _(ioam_disable, "")                                                     \
18082 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18083                             " sw_if_index <sw_if_index> p <priority> "  \
18084                             "w <weight>] [del]")                        \
18085 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18086                         "iface <intf> | sw_if_index <sw_if_index> "     \
18087                         "p <priority> w <weight> [del]")                \
18088 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18089                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18090                          "locator-set <locator_name> [del]"             \
18091                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18092 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18093   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18094 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18095 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18096 _(lisp_gpe_enable_disable, "enable|disable")                            \
18097 _(lisp_enable_disable, "enable|disable")                                \
18098 _(lisp_map_register_enable_disable, "enable|disable")                   \
18099 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18100 _(lisp_gpe_add_del_iface, "up|down")                                    \
18101 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18102                                "[seid <seid>] "                         \
18103                                "rloc <locator> p <prio> "               \
18104                                "w <weight> [rloc <loc> ... ] "          \
18105                                "action <action> [del-all]")             \
18106 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18107                           "<local-eid>")                                \
18108 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18109 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18110 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18111 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18112 _(lisp_locator_set_dump, "[local | remote]")                            \
18113 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18114 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18115                        "[local] | [remote]")                            \
18116 _(lisp_eid_table_vni_dump, "")                                          \
18117 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18118 _(lisp_map_resolver_dump, "")                                           \
18119 _(lisp_map_server_dump, "")                                             \
18120 _(lisp_adjacencies_get, "vni <vni>")                                    \
18121 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18122 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18123 _(show_lisp_rloc_probe_state, "")                                       \
18124 _(show_lisp_map_register_state, "")                                     \
18125 _(show_lisp_status, "")                                                 \
18126 _(lisp_get_map_request_itr_rlocs, "")                                   \
18127 _(show_lisp_pitr, "")                                                   \
18128 _(show_lisp_map_request_mode, "")                                       \
18129 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18130 _(af_packet_delete, "name <host interface name>")                       \
18131 _(policer_add_del, "name <policer name> <params> [del]")                \
18132 _(policer_dump, "[name <policer name>]")                                \
18133 _(policer_classify_set_interface,                                       \
18134   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18135   "  [l2-table <nn>] [del]")                                            \
18136 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18137 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18138     "[master|slave]")                                                   \
18139 _(netmap_delete, "name <interface name>")                               \
18140 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18141 _(mpls_fib_dump, "")                                                    \
18142 _(classify_table_ids, "")                                               \
18143 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18144 _(classify_table_info, "table_id <nn>")                                 \
18145 _(classify_session_dump, "table_id <nn>")                               \
18146 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18147     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18148     "[template_interval <nn>] [udp_checksum]")                          \
18149 _(ipfix_exporter_dump, "")                                              \
18150 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18151 _(ipfix_classify_stream_dump, "")                                       \
18152 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18153 _(ipfix_classify_table_dump, "")                                        \
18154 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18155 _(sw_interface_span_dump, "")                                           \
18156 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18157 _(pg_create_interface, "if_id <nn>")                                    \
18158 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18159 _(pg_enable_disable, "[stream <id>] disable")                           \
18160 _(ip_source_and_port_range_check_add_del,                               \
18161   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18162 _(ip_source_and_port_range_check_interface_add_del,                     \
18163   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18164   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18165 _(ipsec_gre_add_del_tunnel,                                             \
18166   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18167 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18168 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18169 _(l2_interface_pbb_tag_rewrite,                                         \
18170   "<intfc> | sw_if_index <nn> \n"                                       \
18171   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18172   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18173 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18174 _(flow_classify_set_interface,                                          \
18175   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18176 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18177 _(ip_fib_dump, "")                                                      \
18178 _(ip6_fib_dump, "")                                                     \
18179 _(feature_enable_disable, "arc_name <arc_name> "                        \
18180   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18181 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18182 "[disable]")                                                            \
18183 _(l2_xconnect_dump, "")                                                 \
18184 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18185 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18186 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18187
18188 #if DPDK > 0
18189 #define foreach_vpe_dpdk_api_msg                                        \
18190 _(sw_interface_set_dpdk_hqos_pipe,                                      \
18191   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
18192   "profile <profile-id>\n")                                             \
18193 _(sw_interface_set_dpdk_hqos_subport,                                   \
18194   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
18195   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
18196 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
18197   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
18198 #endif
18199
18200 /* List of command functions, CLI names map directly to functions */
18201 #define foreach_cli_function                                    \
18202 _(comment, "usage: comment <ignore-rest-of-line>")              \
18203 _(dump_interface_table, "usage: dump_interface_table")          \
18204 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18205 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18206 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18207 _(dump_stats_table, "usage: dump_stats_table")                  \
18208 _(dump_macro_table, "usage: dump_macro_table ")                 \
18209 _(dump_node_table, "usage: dump_node_table")                    \
18210 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18211 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18212 _(echo, "usage: echo <message>")                                \
18213 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18214 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18215 _(help, "usage: help")                                          \
18216 _(q, "usage: quit")                                             \
18217 _(quit, "usage: quit")                                          \
18218 _(search_node_table, "usage: search_node_table <name>...")      \
18219 _(set, "usage: set <variable-name> <value>")                    \
18220 _(script, "usage: script <file-name>")                          \
18221 _(unset, "usage: unset <variable-name>")
18222
18223 #define _(N,n)                                  \
18224     static void vl_api_##n##_t_handler_uni      \
18225     (vl_api_##n##_t * mp)                       \
18226     {                                           \
18227         vat_main_t * vam = &vat_main;           \
18228         if (vam->json_output) {                 \
18229             vl_api_##n##_t_handler_json(mp);    \
18230         } else {                                \
18231             vl_api_##n##_t_handler(mp);         \
18232         }                                       \
18233     }
18234 foreach_vpe_api_reply_msg;
18235 #undef _
18236
18237 #if DPDK > 0
18238 #define _(N,n)                                  \
18239     static void vl_api_##n##_t_handler_uni      \
18240     (vl_api_##n##_t * mp)                       \
18241     {                                           \
18242         vat_main_t * vam = &vat_main;           \
18243         if (vam->json_output) {                 \
18244             vl_api_##n##_t_handler_json(mp);    \
18245         } else {                                \
18246             vl_api_##n##_t_handler(mp);         \
18247         }                                       \
18248     }
18249 foreach_vpe_dpdk_api_reply_msg;
18250 #undef _
18251 #endif
18252
18253 void
18254 vat_api_hookup (vat_main_t * vam)
18255 {
18256 #define _(N,n)                                                  \
18257     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18258                            vl_api_##n##_t_handler_uni,          \
18259                            vl_noop_handler,                     \
18260                            vl_api_##n##_t_endian,               \
18261                            vl_api_##n##_t_print,                \
18262                            sizeof(vl_api_##n##_t), 1);
18263   foreach_vpe_api_reply_msg;
18264 #undef _
18265
18266 #if DPDK > 0
18267 #define _(N,n)                                                  \
18268     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18269                            vl_api_##n##_t_handler_uni,          \
18270                            vl_noop_handler,                     \
18271                            vl_api_##n##_t_endian,               \
18272                            vl_api_##n##_t_print,                \
18273                            sizeof(vl_api_##n##_t), 1);
18274   foreach_vpe_dpdk_api_reply_msg;
18275 #undef _
18276 #endif
18277
18278 #if (VPP_API_TEST_BUILTIN==0)
18279   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18280 #endif
18281
18282   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18283
18284   vam->function_by_name = hash_create_string (0, sizeof (uword));
18285
18286   vam->help_by_name = hash_create_string (0, sizeof (uword));
18287
18288   /* API messages we can send */
18289 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18290   foreach_vpe_api_msg;
18291 #undef _
18292 #if DPDK >0
18293 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18294   foreach_vpe_dpdk_api_msg;
18295 #undef _
18296 #endif
18297
18298   /* Help strings */
18299 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18300   foreach_vpe_api_msg;
18301 #undef _
18302 #if DPDK >0
18303 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18304   foreach_vpe_dpdk_api_msg;
18305 #undef _
18306 #endif
18307
18308   /* CLI functions */
18309 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18310   foreach_cli_function;
18311 #undef _
18312
18313   /* Help strings */
18314 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18315   foreach_cli_function;
18316 #undef _
18317 }
18318
18319 /*
18320  * fd.io coding-style-patch-verification: ON
18321  *
18322  * Local Variables:
18323  * eval: (c-set-style "gnu")
18324  * End:
18325  */