IP Multicast FIB (mfib)
[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   vl_api_lisp_adjacencies_get_reply_t_handler
2687   (vl_api_lisp_adjacencies_get_reply_t * mp)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   u32 i, n;
2691   int retval = clib_net_to_host_u32 (mp->retval);
2692   vl_api_lisp_adjacency_t *a;
2693
2694   if (retval)
2695     goto end;
2696
2697   n = clib_net_to_host_u32 (mp->count);
2698
2699   for (i = 0; i < n; i++)
2700     {
2701       a = &mp->adjacencies[i];
2702       print (vam->ofp, "%U %40U",
2703              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2704              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2705     }
2706
2707 end:
2708   vam->retval = retval;
2709   vam->result_ready = 1;
2710 }
2711
2712 static void
2713   vl_api_lisp_adjacencies_get_reply_t_handler_json
2714   (vl_api_lisp_adjacencies_get_reply_t * mp)
2715 {
2716   u8 *s = 0;
2717   vat_main_t *vam = &vat_main;
2718   vat_json_node_t *e = 0, root;
2719   u32 i, n;
2720   int retval = clib_net_to_host_u32 (mp->retval);
2721   vl_api_lisp_adjacency_t *a;
2722
2723   if (retval)
2724     goto end;
2725
2726   n = clib_net_to_host_u32 (mp->count);
2727   vat_json_init_array (&root);
2728
2729   for (i = 0; i < n; i++)
2730     {
2731       e = vat_json_array_add (&root);
2732       a = &mp->adjacencies[i];
2733
2734       vat_json_init_object (e);
2735       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2736                   a->leid_prefix_len);
2737       vec_add1 (s, 0);
2738       vat_json_object_add_string_copy (e, "leid", s);
2739       vec_free (s);
2740
2741       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2742                   a->reid_prefix_len);
2743       vec_add1 (s, 0);
2744       vat_json_object_add_string_copy (e, "reid", s);
2745       vec_free (s);
2746     }
2747
2748   vat_json_print (vam->ofp, &root);
2749   vat_json_free (&root);
2750
2751 end:
2752   vam->retval = retval;
2753   vam->result_ready = 1;
2754 }
2755
2756 static void
2757 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2758                                           * mp)
2759 {
2760   vat_main_t *vam = &vat_main;
2761
2762   print (vam->ofp, "%=20U",
2763          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2764          mp->ip_address);
2765 }
2766
2767 static void
2768   vl_api_lisp_map_server_details_t_handler_json
2769   (vl_api_lisp_map_server_details_t * mp)
2770 {
2771   vat_main_t *vam = &vat_main;
2772   vat_json_node_t *node = NULL;
2773   struct in6_addr ip6;
2774   struct in_addr ip4;
2775
2776   if (VAT_JSON_ARRAY != vam->json_tree.type)
2777     {
2778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2779       vat_json_init_array (&vam->json_tree);
2780     }
2781   node = vat_json_array_add (&vam->json_tree);
2782
2783   vat_json_init_object (node);
2784   if (mp->is_ipv6)
2785     {
2786       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2787       vat_json_object_add_ip6 (node, "map-server", ip6);
2788     }
2789   else
2790     {
2791       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2792       vat_json_object_add_ip4 (node, "map-server", ip4);
2793     }
2794 }
2795
2796 static void
2797 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2798                                             * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801
2802   print (vam->ofp, "%=20U",
2803          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2804          mp->ip_address);
2805 }
2806
2807 static void
2808   vl_api_lisp_map_resolver_details_t_handler_json
2809   (vl_api_lisp_map_resolver_details_t * mp)
2810 {
2811   vat_main_t *vam = &vat_main;
2812   vat_json_node_t *node = NULL;
2813   struct in6_addr ip6;
2814   struct in_addr ip4;
2815
2816   if (VAT_JSON_ARRAY != vam->json_tree.type)
2817     {
2818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2819       vat_json_init_array (&vam->json_tree);
2820     }
2821   node = vat_json_array_add (&vam->json_tree);
2822
2823   vat_json_init_object (node);
2824   if (mp->is_ipv6)
2825     {
2826       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2827       vat_json_object_add_ip6 (node, "map resolver", ip6);
2828     }
2829   else
2830     {
2831       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2832       vat_json_object_add_ip4 (node, "map resolver", ip4);
2833     }
2834 }
2835
2836 static void
2837   vl_api_show_lisp_status_reply_t_handler
2838   (vl_api_show_lisp_status_reply_t * mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   i32 retval = ntohl (mp->retval);
2842
2843   if (0 <= retval)
2844     {
2845       print (vam->ofp, "feature: %s\ngpe: %s",
2846              mp->feature_status ? "enabled" : "disabled",
2847              mp->gpe_status ? "enabled" : "disabled");
2848     }
2849
2850   vam->retval = retval;
2851   vam->result_ready = 1;
2852 }
2853
2854 static void
2855   vl_api_show_lisp_status_reply_t_handler_json
2856   (vl_api_show_lisp_status_reply_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   vat_json_node_t node;
2860   u8 *gpe_status = NULL;
2861   u8 *feature_status = NULL;
2862
2863   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2864   feature_status = format (0, "%s",
2865                            mp->feature_status ? "enabled" : "disabled");
2866   vec_add1 (gpe_status, 0);
2867   vec_add1 (feature_status, 0);
2868
2869   vat_json_init_object (&node);
2870   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2871   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2872
2873   vec_free (gpe_status);
2874   vec_free (feature_status);
2875
2876   vat_json_print (vam->ofp, &node);
2877   vat_json_free (&node);
2878
2879   vam->retval = ntohl (mp->retval);
2880   vam->result_ready = 1;
2881 }
2882
2883 static void
2884   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2885   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2886 {
2887   vat_main_t *vam = &vat_main;
2888   i32 retval = ntohl (mp->retval);
2889
2890   if (retval >= 0)
2891     {
2892       print (vam->ofp, "%=20s", mp->locator_set_name);
2893     }
2894
2895   vam->retval = retval;
2896   vam->result_ready = 1;
2897 }
2898
2899 static void
2900   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2901   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2902 {
2903   vat_main_t *vam = &vat_main;
2904   vat_json_node_t *node = NULL;
2905
2906   if (VAT_JSON_ARRAY != vam->json_tree.type)
2907     {
2908       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2909       vat_json_init_array (&vam->json_tree);
2910     }
2911   node = vat_json_array_add (&vam->json_tree);
2912
2913   vat_json_init_object (node);
2914   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2915
2916   vat_json_print (vam->ofp, node);
2917   vat_json_free (node);
2918
2919   vam->retval = ntohl (mp->retval);
2920   vam->result_ready = 1;
2921 }
2922
2923 static u8 *
2924 format_lisp_map_request_mode (u8 * s, va_list * args)
2925 {
2926   u32 mode = va_arg (*args, u32);
2927
2928   switch (mode)
2929     {
2930     case 0:
2931       return format (0, "dst-only");
2932     case 1:
2933       return format (0, "src-dst");
2934     }
2935   return 0;
2936 }
2937
2938 static void
2939   vl_api_show_lisp_map_request_mode_reply_t_handler
2940   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2941 {
2942   vat_main_t *vam = &vat_main;
2943   i32 retval = ntohl (mp->retval);
2944
2945   if (0 <= retval)
2946     {
2947       u32 mode = mp->mode;
2948       print (vam->ofp, "map_request_mode: %U",
2949              format_lisp_map_request_mode, mode);
2950     }
2951
2952   vam->retval = retval;
2953   vam->result_ready = 1;
2954 }
2955
2956 static void
2957   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2958   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   vat_json_node_t node;
2962   u8 *s = 0;
2963   u32 mode;
2964
2965   mode = mp->mode;
2966   s = format (0, "%U", format_lisp_map_request_mode, mode);
2967   vec_add1 (s, 0);
2968
2969   vat_json_init_object (&node);
2970   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2971   vat_json_print (vam->ofp, &node);
2972   vat_json_free (&node);
2973
2974   vec_free (s);
2975   vam->retval = ntohl (mp->retval);
2976   vam->result_ready = 1;
2977 }
2978
2979 static void
2980 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2981 {
2982   vat_main_t *vam = &vat_main;
2983   i32 retval = ntohl (mp->retval);
2984
2985   if (0 <= retval)
2986     {
2987       print (vam->ofp, "%-20s%-16s",
2988              mp->status ? "enabled" : "disabled",
2989              mp->status ? (char *) mp->locator_set_name : "");
2990     }
2991
2992   vam->retval = retval;
2993   vam->result_ready = 1;
2994 }
2995
2996 static void
2997 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2998                                             mp)
2999 {
3000   vat_main_t *vam = &vat_main;
3001   vat_json_node_t node;
3002   u8 *status = 0;
3003
3004   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3005   vec_add1 (status, 0);
3006
3007   vat_json_init_object (&node);
3008   vat_json_object_add_string_copy (&node, "status", status);
3009   if (mp->status)
3010     {
3011       vat_json_object_add_string_copy (&node, "locator_set",
3012                                        mp->locator_set_name);
3013     }
3014
3015   vec_free (status);
3016
3017   vat_json_print (vam->ofp, &node);
3018   vat_json_free (&node);
3019
3020   vam->retval = ntohl (mp->retval);
3021   vam->result_ready = 1;
3022 }
3023
3024 static u8 *
3025 format_policer_type (u8 * s, va_list * va)
3026 {
3027   u32 i = va_arg (*va, u32);
3028
3029   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3030     s = format (s, "1r2c");
3031   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3032     s = format (s, "1r3c");
3033   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3034     s = format (s, "2r3c-2698");
3035   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3036     s = format (s, "2r3c-4115");
3037   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3038     s = format (s, "2r3c-mef5cf1");
3039   else
3040     s = format (s, "ILLEGAL");
3041   return s;
3042 }
3043
3044 static u8 *
3045 format_policer_rate_type (u8 * s, va_list * va)
3046 {
3047   u32 i = va_arg (*va, u32);
3048
3049   if (i == SSE2_QOS_RATE_KBPS)
3050     s = format (s, "kbps");
3051   else if (i == SSE2_QOS_RATE_PPS)
3052     s = format (s, "pps");
3053   else
3054     s = format (s, "ILLEGAL");
3055   return s;
3056 }
3057
3058 static u8 *
3059 format_policer_round_type (u8 * s, va_list * va)
3060 {
3061   u32 i = va_arg (*va, u32);
3062
3063   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3064     s = format (s, "closest");
3065   else if (i == SSE2_QOS_ROUND_TO_UP)
3066     s = format (s, "up");
3067   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3068     s = format (s, "down");
3069   else
3070     s = format (s, "ILLEGAL");
3071   return s;
3072 }
3073
3074 static u8 *
3075 format_policer_action_type (u8 * s, va_list * va)
3076 {
3077   u32 i = va_arg (*va, u32);
3078
3079   if (i == SSE2_QOS_ACTION_DROP)
3080     s = format (s, "drop");
3081   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3082     s = format (s, "transmit");
3083   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3084     s = format (s, "mark-and-transmit");
3085   else
3086     s = format (s, "ILLEGAL");
3087   return s;
3088 }
3089
3090 static u8 *
3091 format_dscp (u8 * s, va_list * va)
3092 {
3093   u32 i = va_arg (*va, u32);
3094   char *t = 0;
3095
3096   switch (i)
3097     {
3098 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3099       foreach_vnet_dscp
3100 #undef _
3101     default:
3102       return format (s, "ILLEGAL");
3103     }
3104   s = format (s, "%s", t);
3105   return s;
3106 }
3107
3108 static void
3109 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3110 {
3111   vat_main_t *vam = &vat_main;
3112   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3113
3114   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3115     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3116   else
3117     conform_dscp_str = format (0, "");
3118
3119   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3120     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3121   else
3122     exceed_dscp_str = format (0, "");
3123
3124   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3125     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3126   else
3127     violate_dscp_str = format (0, "");
3128
3129   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3130          "rate type %U, round type %U, %s rate, %s color-aware, "
3131          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3132          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3133          "conform action %U%s, exceed action %U%s, violate action %U%s",
3134          mp->name,
3135          format_policer_type, mp->type,
3136          ntohl (mp->cir),
3137          ntohl (mp->eir),
3138          clib_net_to_host_u64 (mp->cb),
3139          clib_net_to_host_u64 (mp->eb),
3140          format_policer_rate_type, mp->rate_type,
3141          format_policer_round_type, mp->round_type,
3142          mp->single_rate ? "single" : "dual",
3143          mp->color_aware ? "is" : "not",
3144          ntohl (mp->cir_tokens_per_period),
3145          ntohl (mp->pir_tokens_per_period),
3146          ntohl (mp->scale),
3147          ntohl (mp->current_limit),
3148          ntohl (mp->current_bucket),
3149          ntohl (mp->extended_limit),
3150          ntohl (mp->extended_bucket),
3151          clib_net_to_host_u64 (mp->last_update_time),
3152          format_policer_action_type, mp->conform_action_type,
3153          conform_dscp_str,
3154          format_policer_action_type, mp->exceed_action_type,
3155          exceed_dscp_str,
3156          format_policer_action_type, mp->violate_action_type,
3157          violate_dscp_str);
3158
3159   vec_free (conform_dscp_str);
3160   vec_free (exceed_dscp_str);
3161   vec_free (violate_dscp_str);
3162 }
3163
3164 static void vl_api_policer_details_t_handler_json
3165   (vl_api_policer_details_t * mp)
3166 {
3167   vat_main_t *vam = &vat_main;
3168   vat_json_node_t *node;
3169   u8 *rate_type_str, *round_type_str, *type_str;
3170   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3171
3172   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3173   round_type_str =
3174     format (0, "%U", format_policer_round_type, mp->round_type);
3175   type_str = format (0, "%U", format_policer_type, mp->type);
3176   conform_action_str = format (0, "%U", format_policer_action_type,
3177                                mp->conform_action_type);
3178   exceed_action_str = format (0, "%U", format_policer_action_type,
3179                               mp->exceed_action_type);
3180   violate_action_str = format (0, "%U", format_policer_action_type,
3181                                mp->violate_action_type);
3182
3183   if (VAT_JSON_ARRAY != vam->json_tree.type)
3184     {
3185       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3186       vat_json_init_array (&vam->json_tree);
3187     }
3188   node = vat_json_array_add (&vam->json_tree);
3189
3190   vat_json_init_object (node);
3191   vat_json_object_add_string_copy (node, "name", mp->name);
3192   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3193   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3194   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3195   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3196   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3197   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3198   vat_json_object_add_string_copy (node, "type", type_str);
3199   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3200   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3201   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3202   vat_json_object_add_uint (node, "cir_tokens_per_period",
3203                             ntohl (mp->cir_tokens_per_period));
3204   vat_json_object_add_uint (node, "eir_tokens_per_period",
3205                             ntohl (mp->pir_tokens_per_period));
3206   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3207   vat_json_object_add_uint (node, "current_bucket",
3208                             ntohl (mp->current_bucket));
3209   vat_json_object_add_uint (node, "extended_limit",
3210                             ntohl (mp->extended_limit));
3211   vat_json_object_add_uint (node, "extended_bucket",
3212                             ntohl (mp->extended_bucket));
3213   vat_json_object_add_uint (node, "last_update_time",
3214                             ntohl (mp->last_update_time));
3215   vat_json_object_add_string_copy (node, "conform_action",
3216                                    conform_action_str);
3217   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3218     {
3219       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3220       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3221       vec_free (dscp_str);
3222     }
3223   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3224   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3225     {
3226       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3227       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3228       vec_free (dscp_str);
3229     }
3230   vat_json_object_add_string_copy (node, "violate_action",
3231                                    violate_action_str);
3232   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3233     {
3234       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3235       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3236       vec_free (dscp_str);
3237     }
3238
3239   vec_free (rate_type_str);
3240   vec_free (round_type_str);
3241   vec_free (type_str);
3242   vec_free (conform_action_str);
3243   vec_free (exceed_action_str);
3244   vec_free (violate_action_str);
3245 }
3246
3247 static void
3248 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3249                                            mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252   int i, count = ntohl (mp->count);
3253
3254   if (count > 0)
3255     print (vam->ofp, "classify table ids (%d) : ", count);
3256   for (i = 0; i < count; i++)
3257     {
3258       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3259       print (vam->ofp, (i < count - 1) ? "," : "");
3260     }
3261   vam->retval = ntohl (mp->retval);
3262   vam->result_ready = 1;
3263 }
3264
3265 static void
3266   vl_api_classify_table_ids_reply_t_handler_json
3267   (vl_api_classify_table_ids_reply_t * mp)
3268 {
3269   vat_main_t *vam = &vat_main;
3270   int i, count = ntohl (mp->count);
3271
3272   if (count > 0)
3273     {
3274       vat_json_node_t node;
3275
3276       vat_json_init_object (&node);
3277       for (i = 0; i < count; i++)
3278         {
3279           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3280         }
3281       vat_json_print (vam->ofp, &node);
3282       vat_json_free (&node);
3283     }
3284   vam->retval = ntohl (mp->retval);
3285   vam->result_ready = 1;
3286 }
3287
3288 static void
3289   vl_api_classify_table_by_interface_reply_t_handler
3290   (vl_api_classify_table_by_interface_reply_t * mp)
3291 {
3292   vat_main_t *vam = &vat_main;
3293   u32 table_id;
3294
3295   table_id = ntohl (mp->l2_table_id);
3296   if (table_id != ~0)
3297     print (vam->ofp, "l2 table id : %d", table_id);
3298   else
3299     print (vam->ofp, "l2 table id : No input ACL tables configured");
3300   table_id = ntohl (mp->ip4_table_id);
3301   if (table_id != ~0)
3302     print (vam->ofp, "ip4 table id : %d", table_id);
3303   else
3304     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3305   table_id = ntohl (mp->ip6_table_id);
3306   if (table_id != ~0)
3307     print (vam->ofp, "ip6 table id : %d", table_id);
3308   else
3309     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3310   vam->retval = ntohl (mp->retval);
3311   vam->result_ready = 1;
3312 }
3313
3314 static void
3315   vl_api_classify_table_by_interface_reply_t_handler_json
3316   (vl_api_classify_table_by_interface_reply_t * mp)
3317 {
3318   vat_main_t *vam = &vat_main;
3319   vat_json_node_t node;
3320
3321   vat_json_init_object (&node);
3322
3323   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3324   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3325   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3326
3327   vat_json_print (vam->ofp, &node);
3328   vat_json_free (&node);
3329
3330   vam->retval = ntohl (mp->retval);
3331   vam->result_ready = 1;
3332 }
3333
3334 static void vl_api_policer_add_del_reply_t_handler
3335   (vl_api_policer_add_del_reply_t * mp)
3336 {
3337   vat_main_t *vam = &vat_main;
3338   i32 retval = ntohl (mp->retval);
3339   if (vam->async_mode)
3340     {
3341       vam->async_errors += (retval < 0);
3342     }
3343   else
3344     {
3345       vam->retval = retval;
3346       vam->result_ready = 1;
3347       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3348         /*
3349          * Note: this is just barely thread-safe, depends on
3350          * the main thread spinning waiting for an answer...
3351          */
3352         errmsg ("policer index %d", ntohl (mp->policer_index));
3353     }
3354 }
3355
3356 static void vl_api_policer_add_del_reply_t_handler_json
3357   (vl_api_policer_add_del_reply_t * mp)
3358 {
3359   vat_main_t *vam = &vat_main;
3360   vat_json_node_t node;
3361
3362   vat_json_init_object (&node);
3363   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3364   vat_json_object_add_uint (&node, "policer_index",
3365                             ntohl (mp->policer_index));
3366
3367   vat_json_print (vam->ofp, &node);
3368   vat_json_free (&node);
3369
3370   vam->retval = ntohl (mp->retval);
3371   vam->result_ready = 1;
3372 }
3373
3374 /* Format hex dump. */
3375 u8 *
3376 format_hex_bytes (u8 * s, va_list * va)
3377 {
3378   u8 *bytes = va_arg (*va, u8 *);
3379   int n_bytes = va_arg (*va, int);
3380   uword i;
3381
3382   /* Print short or long form depending on byte count. */
3383   uword short_form = n_bytes <= 32;
3384   uword indent = format_get_indent (s);
3385
3386   if (n_bytes == 0)
3387     return s;
3388
3389   for (i = 0; i < n_bytes; i++)
3390     {
3391       if (!short_form && (i % 32) == 0)
3392         s = format (s, "%08x: ", i);
3393       s = format (s, "%02x", bytes[i]);
3394       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3395         s = format (s, "\n%U", format_white_space, indent);
3396     }
3397
3398   return s;
3399 }
3400
3401 static void
3402 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3403                                             * mp)
3404 {
3405   vat_main_t *vam = &vat_main;
3406   i32 retval = ntohl (mp->retval);
3407   if (retval == 0)
3408     {
3409       print (vam->ofp, "classify table info :");
3410       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3411              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3412              ntohl (mp->miss_next_index));
3413       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3414              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3415              ntohl (mp->match_n_vectors));
3416       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3417              ntohl (mp->mask_length));
3418     }
3419   vam->retval = retval;
3420   vam->result_ready = 1;
3421 }
3422
3423 static void
3424   vl_api_classify_table_info_reply_t_handler_json
3425   (vl_api_classify_table_info_reply_t * mp)
3426 {
3427   vat_main_t *vam = &vat_main;
3428   vat_json_node_t node;
3429
3430   i32 retval = ntohl (mp->retval);
3431   if (retval == 0)
3432     {
3433       vat_json_init_object (&node);
3434
3435       vat_json_object_add_int (&node, "sessions",
3436                                ntohl (mp->active_sessions));
3437       vat_json_object_add_int (&node, "nexttbl",
3438                                ntohl (mp->next_table_index));
3439       vat_json_object_add_int (&node, "nextnode",
3440                                ntohl (mp->miss_next_index));
3441       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3442       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3443       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3444       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3445                       ntohl (mp->mask_length), 0);
3446       vat_json_object_add_string_copy (&node, "mask", s);
3447
3448       vat_json_print (vam->ofp, &node);
3449       vat_json_free (&node);
3450     }
3451   vam->retval = ntohl (mp->retval);
3452   vam->result_ready = 1;
3453 }
3454
3455 static void
3456 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3457                                            mp)
3458 {
3459   vat_main_t *vam = &vat_main;
3460
3461   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3462          ntohl (mp->hit_next_index), ntohl (mp->advance),
3463          ntohl (mp->opaque_index));
3464   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3465          ntohl (mp->match_length));
3466 }
3467
3468 static void
3469   vl_api_classify_session_details_t_handler_json
3470   (vl_api_classify_session_details_t * mp)
3471 {
3472   vat_main_t *vam = &vat_main;
3473   vat_json_node_t *node = NULL;
3474
3475   if (VAT_JSON_ARRAY != vam->json_tree.type)
3476     {
3477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3478       vat_json_init_array (&vam->json_tree);
3479     }
3480   node = vat_json_array_add (&vam->json_tree);
3481
3482   vat_json_init_object (node);
3483   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3484   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3485   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3486   u8 *s =
3487     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3488             0);
3489   vat_json_object_add_string_copy (node, "match", s);
3490 }
3491
3492 static void vl_api_pg_create_interface_reply_t_handler
3493   (vl_api_pg_create_interface_reply_t * mp)
3494 {
3495   vat_main_t *vam = &vat_main;
3496
3497   vam->retval = ntohl (mp->retval);
3498   vam->result_ready = 1;
3499 }
3500
3501 static void vl_api_pg_create_interface_reply_t_handler_json
3502   (vl_api_pg_create_interface_reply_t * mp)
3503 {
3504   vat_main_t *vam = &vat_main;
3505   vat_json_node_t node;
3506
3507   i32 retval = ntohl (mp->retval);
3508   if (retval == 0)
3509     {
3510       vat_json_init_object (&node);
3511
3512       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3513
3514       vat_json_print (vam->ofp, &node);
3515       vat_json_free (&node);
3516     }
3517   vam->retval = ntohl (mp->retval);
3518   vam->result_ready = 1;
3519 }
3520
3521 static void vl_api_policer_classify_details_t_handler
3522   (vl_api_policer_classify_details_t * mp)
3523 {
3524   vat_main_t *vam = &vat_main;
3525
3526   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3527          ntohl (mp->table_index));
3528 }
3529
3530 static void vl_api_policer_classify_details_t_handler_json
3531   (vl_api_policer_classify_details_t * mp)
3532 {
3533   vat_main_t *vam = &vat_main;
3534   vat_json_node_t *node;
3535
3536   if (VAT_JSON_ARRAY != vam->json_tree.type)
3537     {
3538       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3539       vat_json_init_array (&vam->json_tree);
3540     }
3541   node = vat_json_array_add (&vam->json_tree);
3542
3543   vat_json_init_object (node);
3544   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3545   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3546 }
3547
3548 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3549   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3550 {
3551   vat_main_t *vam = &vat_main;
3552   i32 retval = ntohl (mp->retval);
3553   if (vam->async_mode)
3554     {
3555       vam->async_errors += (retval < 0);
3556     }
3557   else
3558     {
3559       vam->retval = retval;
3560       vam->sw_if_index = ntohl (mp->sw_if_index);
3561       vam->result_ready = 1;
3562     }
3563 }
3564
3565 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3566   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3567 {
3568   vat_main_t *vam = &vat_main;
3569   vat_json_node_t node;
3570
3571   vat_json_init_object (&node);
3572   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3573   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3574
3575   vat_json_print (vam->ofp, &node);
3576   vat_json_free (&node);
3577
3578   vam->retval = ntohl (mp->retval);
3579   vam->result_ready = 1;
3580 }
3581
3582 static void vl_api_flow_classify_details_t_handler
3583   (vl_api_flow_classify_details_t * mp)
3584 {
3585   vat_main_t *vam = &vat_main;
3586
3587   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3588          ntohl (mp->table_index));
3589 }
3590
3591 static void vl_api_flow_classify_details_t_handler_json
3592   (vl_api_flow_classify_details_t * mp)
3593 {
3594   vat_main_t *vam = &vat_main;
3595   vat_json_node_t *node;
3596
3597   if (VAT_JSON_ARRAY != vam->json_tree.type)
3598     {
3599       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3600       vat_json_init_array (&vam->json_tree);
3601     }
3602   node = vat_json_array_add (&vam->json_tree);
3603
3604   vat_json_init_object (node);
3605   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3606   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3607 }
3608
3609
3610
3611 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3612 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3613 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3614 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3615 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3616 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3617 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3618 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3619 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3620 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3621
3622 /*
3623  * Generate boilerplate reply handlers, which
3624  * dig the return value out of the xxx_reply_t API message,
3625  * stick it into vam->retval, and set vam->result_ready
3626  *
3627  * Could also do this by pointing N message decode slots at
3628  * a single function, but that could break in subtle ways.
3629  */
3630
3631 #define foreach_standard_reply_retval_handler           \
3632 _(sw_interface_set_flags_reply)                         \
3633 _(sw_interface_add_del_address_reply)                   \
3634 _(sw_interface_set_table_reply)                         \
3635 _(sw_interface_set_mpls_enable_reply)                   \
3636 _(sw_interface_set_vpath_reply)                         \
3637 _(sw_interface_set_vxlan_bypass_reply)                  \
3638 _(sw_interface_set_l2_bridge_reply)                     \
3639 _(bridge_domain_add_del_reply)                          \
3640 _(sw_interface_set_l2_xconnect_reply)                   \
3641 _(l2fib_add_del_reply)                                  \
3642 _(ip_add_del_route_reply)                               \
3643 _(ip_mroute_add_del_reply)                              \
3644 _(mpls_route_add_del_reply)                             \
3645 _(mpls_ip_bind_unbind_reply)                            \
3646 _(proxy_arp_add_del_reply)                              \
3647 _(proxy_arp_intfc_enable_disable_reply)                 \
3648 _(sw_interface_set_unnumbered_reply)                    \
3649 _(ip_neighbor_add_del_reply)                            \
3650 _(reset_vrf_reply)                                      \
3651 _(oam_add_del_reply)                                    \
3652 _(reset_fib_reply)                                      \
3653 _(dhcp_proxy_config_reply)                              \
3654 _(dhcp_proxy_config_2_reply)                            \
3655 _(dhcp_proxy_set_vss_reply)                             \
3656 _(dhcp_client_config_reply)                             \
3657 _(set_ip_flow_hash_reply)                               \
3658 _(sw_interface_ip6_enable_disable_reply)                \
3659 _(sw_interface_ip6_set_link_local_address_reply)        \
3660 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3661 _(sw_interface_ip6nd_ra_config_reply)                   \
3662 _(set_arp_neighbor_limit_reply)                         \
3663 _(l2_patch_add_del_reply)                               \
3664 _(sr_tunnel_add_del_reply)                              \
3665 _(sr_policy_add_del_reply)                              \
3666 _(sr_multicast_map_add_del_reply)                       \
3667 _(classify_add_del_session_reply)                       \
3668 _(classify_set_interface_ip_table_reply)                \
3669 _(classify_set_interface_l2_tables_reply)               \
3670 _(l2tpv3_set_tunnel_cookies_reply)                      \
3671 _(l2tpv3_interface_enable_disable_reply)                \
3672 _(l2tpv3_set_lookup_key_reply)                          \
3673 _(l2_fib_clear_table_reply)                             \
3674 _(l2_interface_efp_filter_reply)                        \
3675 _(l2_interface_vlan_tag_rewrite_reply)                  \
3676 _(modify_vhost_user_if_reply)                           \
3677 _(delete_vhost_user_if_reply)                           \
3678 _(want_ip4_arp_events_reply)                            \
3679 _(want_ip6_nd_events_reply)                             \
3680 _(input_acl_set_interface_reply)                        \
3681 _(ipsec_spd_add_del_reply)                              \
3682 _(ipsec_interface_add_del_spd_reply)                    \
3683 _(ipsec_spd_add_del_entry_reply)                        \
3684 _(ipsec_sad_add_del_entry_reply)                        \
3685 _(ipsec_sa_set_key_reply)                               \
3686 _(ikev2_profile_add_del_reply)                          \
3687 _(ikev2_profile_set_auth_reply)                         \
3688 _(ikev2_profile_set_id_reply)                           \
3689 _(ikev2_profile_set_ts_reply)                           \
3690 _(ikev2_set_local_key_reply)                            \
3691 _(delete_loopback_reply)                                \
3692 _(bd_ip_mac_add_del_reply)                              \
3693 _(map_del_domain_reply)                                 \
3694 _(map_add_del_rule_reply)                               \
3695 _(want_interface_events_reply)                          \
3696 _(want_stats_reply)                                     \
3697 _(cop_interface_enable_disable_reply)                   \
3698 _(cop_whitelist_enable_disable_reply)                   \
3699 _(sw_interface_clear_stats_reply)                       \
3700 _(ioam_enable_reply)                              \
3701 _(ioam_disable_reply)                              \
3702 _(lisp_add_del_locator_reply)                           \
3703 _(lisp_add_del_local_eid_reply)                         \
3704 _(lisp_add_del_remote_mapping_reply)                    \
3705 _(lisp_add_del_adjacency_reply)                         \
3706 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3707 _(lisp_add_del_map_resolver_reply)                      \
3708 _(lisp_add_del_map_server_reply)                        \
3709 _(lisp_gpe_enable_disable_reply)                        \
3710 _(lisp_gpe_add_del_iface_reply)                         \
3711 _(lisp_enable_disable_reply)                            \
3712 _(lisp_rloc_probe_enable_disable_reply)                 \
3713 _(lisp_map_register_enable_disable_reply)               \
3714 _(lisp_pitr_set_locator_set_reply)                      \
3715 _(lisp_map_request_mode_reply)                          \
3716 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3717 _(lisp_eid_table_add_del_map_reply)                     \
3718 _(vxlan_gpe_add_del_tunnel_reply)                       \
3719 _(af_packet_delete_reply)                               \
3720 _(policer_classify_set_interface_reply)                 \
3721 _(netmap_create_reply)                                  \
3722 _(netmap_delete_reply)                                  \
3723 _(set_ipfix_exporter_reply)                             \
3724 _(set_ipfix_classify_stream_reply)                      \
3725 _(ipfix_classify_table_add_del_reply)                   \
3726 _(flow_classify_set_interface_reply)                    \
3727 _(sw_interface_span_enable_disable_reply)               \
3728 _(pg_capture_reply)                                     \
3729 _(pg_enable_disable_reply)                              \
3730 _(ip_source_and_port_range_check_add_del_reply)         \
3731 _(ip_source_and_port_range_check_interface_add_del_reply)\
3732 _(delete_subif_reply)                                   \
3733 _(l2_interface_pbb_tag_rewrite_reply)                   \
3734 _(punt_reply)                                           \
3735 _(feature_enable_disable_reply)                         \
3736 _(sw_interface_tag_add_del_reply)                       \
3737 _(sw_interface_set_mtu_reply)
3738
3739 #if DPDK > 0
3740 #define foreach_standard_dpdk_reply_retval_handler      \
3741 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3742 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3743 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3744 #endif
3745
3746 #define _(n)                                    \
3747     static void vl_api_##n##_t_handler          \
3748     (vl_api_##n##_t * mp)                       \
3749     {                                           \
3750         vat_main_t * vam = &vat_main;           \
3751         i32 retval = ntohl(mp->retval);         \
3752         if (vam->async_mode) {                  \
3753             vam->async_errors += (retval < 0);  \
3754         } else {                                \
3755             vam->retval = retval;               \
3756             vam->result_ready = 1;              \
3757         }                                       \
3758     }
3759 foreach_standard_reply_retval_handler;
3760 #undef _
3761
3762 #define _(n)                                    \
3763     static void vl_api_##n##_t_handler_json     \
3764     (vl_api_##n##_t * mp)                       \
3765     {                                           \
3766         vat_main_t * vam = &vat_main;           \
3767         vat_json_node_t node;                   \
3768         vat_json_init_object(&node);            \
3769         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3770         vat_json_print(vam->ofp, &node);        \
3771         vam->retval = ntohl(mp->retval);        \
3772         vam->result_ready = 1;                  \
3773     }
3774 foreach_standard_reply_retval_handler;
3775 #undef _
3776
3777 #if DPDK > 0
3778 #define _(n)                                    \
3779     static void vl_api_##n##_t_handler          \
3780     (vl_api_##n##_t * mp)                       \
3781     {                                           \
3782         vat_main_t * vam = &vat_main;           \
3783         i32 retval = ntohl(mp->retval);         \
3784         if (vam->async_mode) {                  \
3785             vam->async_errors += (retval < 0);  \
3786         } else {                                \
3787             vam->retval = retval;               \
3788             vam->result_ready = 1;              \
3789         }                                       \
3790     }
3791 foreach_standard_dpdk_reply_retval_handler;
3792 #undef _
3793
3794 #define _(n)                                    \
3795     static void vl_api_##n##_t_handler_json     \
3796     (vl_api_##n##_t * mp)                       \
3797     {                                           \
3798         vat_main_t * vam = &vat_main;           \
3799         vat_json_node_t node;                   \
3800         vat_json_init_object(&node);            \
3801         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3802         vat_json_print(vam->ofp, &node);        \
3803         vam->retval = ntohl(mp->retval);        \
3804         vam->result_ready = 1;                  \
3805     }
3806 foreach_standard_dpdk_reply_retval_handler;
3807 #undef _
3808 #endif
3809
3810 /*
3811  * Table of message reply handlers, must include boilerplate handlers
3812  * we just generated
3813  */
3814
3815 #define foreach_vpe_api_reply_msg                                       \
3816 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3817 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3818 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3819 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3820 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3821 _(CLI_REPLY, cli_reply)                                                 \
3822 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3823 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3824   sw_interface_add_del_address_reply)                                   \
3825 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3826 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3827 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3828 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3829 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3830   sw_interface_set_l2_xconnect_reply)                                   \
3831 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3832   sw_interface_set_l2_bridge_reply)                                     \
3833 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3834 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3835 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3836 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3837 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3838 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3839 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3840 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3841 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3842 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3843 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3844 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
3845 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3846 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3847 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3848 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3849   proxy_arp_intfc_enable_disable_reply)                                 \
3850 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3851 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3852   sw_interface_set_unnumbered_reply)                                    \
3853 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3854 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3855 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3856 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3857 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3858 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3859 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3860 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3861 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3862 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3863 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3864 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3865   sw_interface_ip6_enable_disable_reply)                                \
3866 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3867   sw_interface_ip6_set_link_local_address_reply)                        \
3868 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3869   sw_interface_ip6nd_ra_prefix_reply)                                   \
3870 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3871   sw_interface_ip6nd_ra_config_reply)                                   \
3872 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3873 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3874 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3875 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3876 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3877 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3878 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3879 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3880 classify_set_interface_ip_table_reply)                                  \
3881 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3882   classify_set_interface_l2_tables_reply)                               \
3883 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3884 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3885 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3886 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3887 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3888   l2tpv3_interface_enable_disable_reply)                                \
3889 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3890 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3891 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3892 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3893 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3894 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3895 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3896 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3897 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3898 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3899 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3900 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3901 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3902 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3903 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3904 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3905 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3906 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3907 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3908 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3909 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3910 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3911 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3912 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3913 _(IP_DETAILS, ip_details)                                               \
3914 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3915 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3916 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3917 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3918 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3919 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3920 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3921 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3922 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3923 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3924 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3925 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3926 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3927 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3928 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3929 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3930 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
3931 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
3932 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3933 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3934 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3935 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3936 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3937 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3938 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3939 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3940 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3941 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3942 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3943 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3944 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3945 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3946 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3947 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3948 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3949 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3950 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3951 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3952 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3953 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3954 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3955 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3956 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3957   lisp_map_register_enable_disable_reply)                               \
3958 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3959   lisp_rloc_probe_enable_disable_reply)                                 \
3960 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3961 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3962 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3963 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3964 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3965 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3966 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3967 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3968 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3969 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3970 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3971 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3972 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3973 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3974   lisp_add_del_map_request_itr_rlocs_reply)                             \
3975 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3976   lisp_get_map_request_itr_rlocs_reply)                                 \
3977 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3978 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3979 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3980 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3981   show_lisp_map_register_state_reply)                                   \
3982 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3983 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3984 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3985 _(POLICER_DETAILS, policer_details)                                     \
3986 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3987 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3988 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3989 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3990 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3991 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3992 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3993 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3994 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3995 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3996 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3997 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3998 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3999 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4000 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4001 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4002 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4003 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4004 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4005 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4006 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4007 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4008 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4009 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4010 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4011  ip_source_and_port_range_check_add_del_reply)                          \
4012 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4013  ip_source_and_port_range_check_interface_add_del_reply)                \
4014 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4015 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4016 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4017 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4018 _(PUNT_REPLY, punt_reply)                                               \
4019 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4020 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4021 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4022 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4023 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4024 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4025 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4026 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4027
4028 #if DPDK > 0
4029 #define foreach_vpe_dpdk_api_reply_msg                                  \
4030 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
4031   sw_interface_set_dpdk_hqos_pipe_reply)                                \
4032 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
4033   sw_interface_set_dpdk_hqos_subport_reply)                             \
4034 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
4035   sw_interface_set_dpdk_hqos_tctbl_reply)
4036 #endif
4037
4038 typedef struct
4039 {
4040   u8 *name;
4041   u32 value;
4042 } name_sort_t;
4043
4044
4045 #define STR_VTR_OP_CASE(op)     \
4046     case L2_VTR_ ## op:         \
4047         return "" # op;
4048
4049 static const char *
4050 str_vtr_op (u32 vtr_op)
4051 {
4052   switch (vtr_op)
4053     {
4054       STR_VTR_OP_CASE (DISABLED);
4055       STR_VTR_OP_CASE (PUSH_1);
4056       STR_VTR_OP_CASE (PUSH_2);
4057       STR_VTR_OP_CASE (POP_1);
4058       STR_VTR_OP_CASE (POP_2);
4059       STR_VTR_OP_CASE (TRANSLATE_1_1);
4060       STR_VTR_OP_CASE (TRANSLATE_1_2);
4061       STR_VTR_OP_CASE (TRANSLATE_2_1);
4062       STR_VTR_OP_CASE (TRANSLATE_2_2);
4063     }
4064
4065   return "UNKNOWN";
4066 }
4067
4068 static int
4069 dump_sub_interface_table (vat_main_t * vam)
4070 {
4071   const sw_interface_subif_t *sub = NULL;
4072
4073   if (vam->json_output)
4074     {
4075       clib_warning
4076         ("JSON output supported only for VPE API calls and dump_stats_table");
4077       return -99;
4078     }
4079
4080   print (vam->ofp,
4081          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4082          "Interface", "sw_if_index",
4083          "sub id", "dot1ad", "tags", "outer id",
4084          "inner id", "exact", "default", "outer any", "inner any");
4085
4086   vec_foreach (sub, vam->sw_if_subif_table)
4087   {
4088     print (vam->ofp,
4089            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4090            sub->interface_name,
4091            sub->sw_if_index,
4092            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4093            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4094            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4095            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4096     if (sub->vtr_op != L2_VTR_DISABLED)
4097       {
4098         print (vam->ofp,
4099                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4100                "tag1: %d tag2: %d ]",
4101                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4102                sub->vtr_tag1, sub->vtr_tag2);
4103       }
4104   }
4105
4106   return 0;
4107 }
4108
4109 static int
4110 name_sort_cmp (void *a1, void *a2)
4111 {
4112   name_sort_t *n1 = a1;
4113   name_sort_t *n2 = a2;
4114
4115   return strcmp ((char *) n1->name, (char *) n2->name);
4116 }
4117
4118 static int
4119 dump_interface_table (vat_main_t * vam)
4120 {
4121   hash_pair_t *p;
4122   name_sort_t *nses = 0, *ns;
4123
4124   if (vam->json_output)
4125     {
4126       clib_warning
4127         ("JSON output supported only for VPE API calls and dump_stats_table");
4128       return -99;
4129     }
4130
4131   /* *INDENT-OFF* */
4132   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4133   ({
4134     vec_add2 (nses, ns, 1);
4135     ns->name = (u8 *)(p->key);
4136     ns->value = (u32) p->value[0];
4137   }));
4138   /* *INDENT-ON* */
4139
4140   vec_sort_with_function (nses, name_sort_cmp);
4141
4142   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4143   vec_foreach (ns, nses)
4144   {
4145     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4146   }
4147   vec_free (nses);
4148   return 0;
4149 }
4150
4151 static int
4152 dump_ip_table (vat_main_t * vam, int is_ipv6)
4153 {
4154   const ip_details_t *det = NULL;
4155   const ip_address_details_t *address = NULL;
4156   u32 i = ~0;
4157
4158   print (vam->ofp, "%-12s", "sw_if_index");
4159
4160   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4161   {
4162     i++;
4163     if (!det->present)
4164       {
4165         continue;
4166       }
4167     print (vam->ofp, "%-12d", i);
4168     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4169     if (!det->addr)
4170       {
4171         continue;
4172       }
4173     vec_foreach (address, det->addr)
4174     {
4175       print (vam->ofp,
4176              "            %-30U%-13d",
4177              is_ipv6 ? format_ip6_address : format_ip4_address,
4178              address->ip, address->prefix_length);
4179     }
4180   }
4181
4182   return 0;
4183 }
4184
4185 static int
4186 dump_ipv4_table (vat_main_t * vam)
4187 {
4188   if (vam->json_output)
4189     {
4190       clib_warning
4191         ("JSON output supported only for VPE API calls and dump_stats_table");
4192       return -99;
4193     }
4194
4195   return dump_ip_table (vam, 0);
4196 }
4197
4198 static int
4199 dump_ipv6_table (vat_main_t * vam)
4200 {
4201   if (vam->json_output)
4202     {
4203       clib_warning
4204         ("JSON output supported only for VPE API calls and dump_stats_table");
4205       return -99;
4206     }
4207
4208   return dump_ip_table (vam, 1);
4209 }
4210
4211 static char *
4212 counter_type_to_str (u8 counter_type, u8 is_combined)
4213 {
4214   if (!is_combined)
4215     {
4216       switch (counter_type)
4217         {
4218         case VNET_INTERFACE_COUNTER_DROP:
4219           return "drop";
4220         case VNET_INTERFACE_COUNTER_PUNT:
4221           return "punt";
4222         case VNET_INTERFACE_COUNTER_IP4:
4223           return "ip4";
4224         case VNET_INTERFACE_COUNTER_IP6:
4225           return "ip6";
4226         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4227           return "rx-no-buf";
4228         case VNET_INTERFACE_COUNTER_RX_MISS:
4229           return "rx-miss";
4230         case VNET_INTERFACE_COUNTER_RX_ERROR:
4231           return "rx-error";
4232         case VNET_INTERFACE_COUNTER_TX_ERROR:
4233           return "tx-error";
4234         default:
4235           return "INVALID-COUNTER-TYPE";
4236         }
4237     }
4238   else
4239     {
4240       switch (counter_type)
4241         {
4242         case VNET_INTERFACE_COUNTER_RX:
4243           return "rx";
4244         case VNET_INTERFACE_COUNTER_TX:
4245           return "tx";
4246         default:
4247           return "INVALID-COUNTER-TYPE";
4248         }
4249     }
4250 }
4251
4252 static int
4253 dump_stats_table (vat_main_t * vam)
4254 {
4255   vat_json_node_t node;
4256   vat_json_node_t *msg_array;
4257   vat_json_node_t *msg;
4258   vat_json_node_t *counter_array;
4259   vat_json_node_t *counter;
4260   interface_counter_t c;
4261   u64 packets;
4262   ip4_fib_counter_t *c4;
4263   ip6_fib_counter_t *c6;
4264   ip4_nbr_counter_t *n4;
4265   ip6_nbr_counter_t *n6;
4266   int i, j;
4267
4268   if (!vam->json_output)
4269     {
4270       clib_warning ("dump_stats_table supported only in JSON format");
4271       return -99;
4272     }
4273
4274   vat_json_init_object (&node);
4275
4276   /* interface counters */
4277   msg_array = vat_json_object_add (&node, "interface_counters");
4278   vat_json_init_array (msg_array);
4279   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4280     {
4281       msg = vat_json_array_add (msg_array);
4282       vat_json_init_object (msg);
4283       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4284                                        (u8 *) counter_type_to_str (i, 0));
4285       vat_json_object_add_int (msg, "is_combined", 0);
4286       counter_array = vat_json_object_add (msg, "data");
4287       vat_json_init_array (counter_array);
4288       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4289         {
4290           packets = vam->simple_interface_counters[i][j];
4291           vat_json_array_add_uint (counter_array, packets);
4292         }
4293     }
4294   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4295     {
4296       msg = vat_json_array_add (msg_array);
4297       vat_json_init_object (msg);
4298       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4299                                        (u8 *) counter_type_to_str (i, 1));
4300       vat_json_object_add_int (msg, "is_combined", 1);
4301       counter_array = vat_json_object_add (msg, "data");
4302       vat_json_init_array (counter_array);
4303       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4304         {
4305           c = vam->combined_interface_counters[i][j];
4306           counter = vat_json_array_add (counter_array);
4307           vat_json_init_object (counter);
4308           vat_json_object_add_uint (counter, "packets", c.packets);
4309           vat_json_object_add_uint (counter, "bytes", c.bytes);
4310         }
4311     }
4312
4313   /* ip4 fib counters */
4314   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4315   vat_json_init_array (msg_array);
4316   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4317     {
4318       msg = vat_json_array_add (msg_array);
4319       vat_json_init_object (msg);
4320       vat_json_object_add_uint (msg, "vrf_id",
4321                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4322       counter_array = vat_json_object_add (msg, "c");
4323       vat_json_init_array (counter_array);
4324       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4325         {
4326           counter = vat_json_array_add (counter_array);
4327           vat_json_init_object (counter);
4328           c4 = &vam->ip4_fib_counters[i][j];
4329           vat_json_object_add_ip4 (counter, "address", c4->address);
4330           vat_json_object_add_uint (counter, "address_length",
4331                                     c4->address_length);
4332           vat_json_object_add_uint (counter, "packets", c4->packets);
4333           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4334         }
4335     }
4336
4337   /* ip6 fib counters */
4338   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4339   vat_json_init_array (msg_array);
4340   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4341     {
4342       msg = vat_json_array_add (msg_array);
4343       vat_json_init_object (msg);
4344       vat_json_object_add_uint (msg, "vrf_id",
4345                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4346       counter_array = vat_json_object_add (msg, "c");
4347       vat_json_init_array (counter_array);
4348       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4349         {
4350           counter = vat_json_array_add (counter_array);
4351           vat_json_init_object (counter);
4352           c6 = &vam->ip6_fib_counters[i][j];
4353           vat_json_object_add_ip6 (counter, "address", c6->address);
4354           vat_json_object_add_uint (counter, "address_length",
4355                                     c6->address_length);
4356           vat_json_object_add_uint (counter, "packets", c6->packets);
4357           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4358         }
4359     }
4360
4361   /* ip4 nbr counters */
4362   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4363   vat_json_init_array (msg_array);
4364   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4365     {
4366       msg = vat_json_array_add (msg_array);
4367       vat_json_init_object (msg);
4368       vat_json_object_add_uint (msg, "sw_if_index", i);
4369       counter_array = vat_json_object_add (msg, "c");
4370       vat_json_init_array (counter_array);
4371       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4372         {
4373           counter = vat_json_array_add (counter_array);
4374           vat_json_init_object (counter);
4375           n4 = &vam->ip4_nbr_counters[i][j];
4376           vat_json_object_add_ip4 (counter, "address", n4->address);
4377           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4378           vat_json_object_add_uint (counter, "packets", n4->packets);
4379           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4380         }
4381     }
4382
4383   /* ip6 nbr counters */
4384   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4385   vat_json_init_array (msg_array);
4386   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4387     {
4388       msg = vat_json_array_add (msg_array);
4389       vat_json_init_object (msg);
4390       vat_json_object_add_uint (msg, "sw_if_index", i);
4391       counter_array = vat_json_object_add (msg, "c");
4392       vat_json_init_array (counter_array);
4393       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4394         {
4395           counter = vat_json_array_add (counter_array);
4396           vat_json_init_object (counter);
4397           n6 = &vam->ip6_nbr_counters[i][j];
4398           vat_json_object_add_ip6 (counter, "address", n6->address);
4399           vat_json_object_add_uint (counter, "packets", n6->packets);
4400           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4401         }
4402     }
4403
4404   vat_json_print (vam->ofp, &node);
4405   vat_json_free (&node);
4406
4407   return 0;
4408 }
4409
4410 int
4411 exec (vat_main_t * vam)
4412 {
4413   api_main_t *am = &api_main;
4414   vl_api_cli_request_t *mp;
4415   f64 timeout;
4416   void *oldheap;
4417   u8 *cmd = 0;
4418   unformat_input_t *i = vam->input;
4419
4420   if (vec_len (i->buffer) == 0)
4421     return -1;
4422
4423   if (vam->exec_mode == 0 && unformat (i, "mode"))
4424     {
4425       vam->exec_mode = 1;
4426       return 0;
4427     }
4428   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4429     {
4430       vam->exec_mode = 0;
4431       return 0;
4432     }
4433
4434
4435   M (CLI_REQUEST, cli_request);
4436
4437   /*
4438    * Copy cmd into shared memory.
4439    * In order for the CLI command to work, it
4440    * must be a vector ending in \n, not a C-string ending
4441    * in \n\0.
4442    */
4443   pthread_mutex_lock (&am->vlib_rp->mutex);
4444   oldheap = svm_push_data_heap (am->vlib_rp);
4445
4446   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4447   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4448
4449   svm_pop_heap (oldheap);
4450   pthread_mutex_unlock (&am->vlib_rp->mutex);
4451
4452   mp->cmd_in_shmem = (u64) cmd;
4453   S;
4454   timeout = vat_time_now (vam) + 10.0;
4455
4456   while (vat_time_now (vam) < timeout)
4457     {
4458       if (vam->result_ready == 1)
4459         {
4460           u8 *free_me;
4461           if (vam->shmem_result != NULL)
4462             print (vam->ofp, "%s", vam->shmem_result);
4463           pthread_mutex_lock (&am->vlib_rp->mutex);
4464           oldheap = svm_push_data_heap (am->vlib_rp);
4465
4466           free_me = (u8 *) vam->shmem_result;
4467           vec_free (free_me);
4468
4469           svm_pop_heap (oldheap);
4470           pthread_mutex_unlock (&am->vlib_rp->mutex);
4471           return 0;
4472         }
4473     }
4474   return -99;
4475 }
4476
4477 /*
4478  * Future replacement of exec() that passes CLI buffers directly in
4479  * the API messages instead of an additional shared memory area.
4480  */
4481 static int
4482 exec_inband (vat_main_t * vam)
4483 {
4484   vl_api_cli_inband_t *mp;
4485   f64 timeout;
4486   unformat_input_t *i = vam->input;
4487
4488   if (vec_len (i->buffer) == 0)
4489     return -1;
4490
4491   if (vam->exec_mode == 0 && unformat (i, "mode"))
4492     {
4493       vam->exec_mode = 1;
4494       return 0;
4495     }
4496   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4497     {
4498       vam->exec_mode = 0;
4499       return 0;
4500     }
4501
4502   /*
4503    * In order for the CLI command to work, it
4504    * must be a vector ending in \n, not a C-string ending
4505    * in \n\0.
4506    */
4507   u32 len = vec_len (vam->input->buffer);
4508   M2 (CLI_INBAND, cli_inband, len);
4509   clib_memcpy (mp->cmd, vam->input->buffer, len);
4510   mp->length = htonl (len);
4511
4512   S;
4513   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4514 }
4515
4516 static int
4517 api_create_loopback (vat_main_t * vam)
4518 {
4519   unformat_input_t *i = vam->input;
4520   vl_api_create_loopback_t *mp;
4521   f64 timeout;
4522   u8 mac_address[6];
4523   u8 mac_set = 0;
4524
4525   memset (mac_address, 0, sizeof (mac_address));
4526
4527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4528     {
4529       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4530         mac_set = 1;
4531       else
4532         break;
4533     }
4534
4535   /* Construct the API message */
4536   M (CREATE_LOOPBACK, create_loopback);
4537   if (mac_set)
4538     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4539
4540   S;
4541   W;
4542 }
4543
4544 static int
4545 api_delete_loopback (vat_main_t * vam)
4546 {
4547   unformat_input_t *i = vam->input;
4548   vl_api_delete_loopback_t *mp;
4549   f64 timeout;
4550   u32 sw_if_index = ~0;
4551
4552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4553     {
4554       if (unformat (i, "sw_if_index %d", &sw_if_index))
4555         ;
4556       else
4557         break;
4558     }
4559
4560   if (sw_if_index == ~0)
4561     {
4562       errmsg ("missing sw_if_index");
4563       return -99;
4564     }
4565
4566   /* Construct the API message */
4567   M (DELETE_LOOPBACK, delete_loopback);
4568   mp->sw_if_index = ntohl (sw_if_index);
4569
4570   S;
4571   W;
4572 }
4573
4574 static int
4575 api_want_stats (vat_main_t * vam)
4576 {
4577   unformat_input_t *i = vam->input;
4578   vl_api_want_stats_t *mp;
4579   f64 timeout;
4580   int enable = -1;
4581
4582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4583     {
4584       if (unformat (i, "enable"))
4585         enable = 1;
4586       else if (unformat (i, "disable"))
4587         enable = 0;
4588       else
4589         break;
4590     }
4591
4592   if (enable == -1)
4593     {
4594       errmsg ("missing enable|disable");
4595       return -99;
4596     }
4597
4598   M (WANT_STATS, want_stats);
4599   mp->enable_disable = enable;
4600
4601   S;
4602   W;
4603 }
4604
4605 static int
4606 api_want_interface_events (vat_main_t * vam)
4607 {
4608   unformat_input_t *i = vam->input;
4609   vl_api_want_interface_events_t *mp;
4610   f64 timeout;
4611   int enable = -1;
4612
4613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4614     {
4615       if (unformat (i, "enable"))
4616         enable = 1;
4617       else if (unformat (i, "disable"))
4618         enable = 0;
4619       else
4620         break;
4621     }
4622
4623   if (enable == -1)
4624     {
4625       errmsg ("missing enable|disable");
4626       return -99;
4627     }
4628
4629   M (WANT_INTERFACE_EVENTS, want_interface_events);
4630   mp->enable_disable = enable;
4631
4632   vam->interface_event_display = enable;
4633
4634   S;
4635   W;
4636 }
4637
4638
4639 /* Note: non-static, called once to set up the initial intfc table */
4640 int
4641 api_sw_interface_dump (vat_main_t * vam)
4642 {
4643   vl_api_sw_interface_dump_t *mp;
4644   f64 timeout;
4645   hash_pair_t *p;
4646   name_sort_t *nses = 0, *ns;
4647   sw_interface_subif_t *sub = NULL;
4648
4649   /* Toss the old name table */
4650   /* *INDENT-OFF* */
4651   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4652   ({
4653     vec_add2 (nses, ns, 1);
4654     ns->name = (u8 *)(p->key);
4655     ns->value = (u32) p->value[0];
4656   }));
4657   /* *INDENT-ON* */
4658
4659   hash_free (vam->sw_if_index_by_interface_name);
4660
4661   vec_foreach (ns, nses) vec_free (ns->name);
4662
4663   vec_free (nses);
4664
4665   vec_foreach (sub, vam->sw_if_subif_table)
4666   {
4667     vec_free (sub->interface_name);
4668   }
4669   vec_free (vam->sw_if_subif_table);
4670
4671   /* recreate the interface name hash table */
4672   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4673
4674   /* Get list of ethernets */
4675   M (SW_INTERFACE_DUMP, sw_interface_dump);
4676   mp->name_filter_valid = 1;
4677   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4678   S;
4679
4680   /* and local / loopback interfaces */
4681   M (SW_INTERFACE_DUMP, sw_interface_dump);
4682   mp->name_filter_valid = 1;
4683   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4684   S;
4685
4686   /* and packet-generator interfaces */
4687   M (SW_INTERFACE_DUMP, sw_interface_dump);
4688   mp->name_filter_valid = 1;
4689   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4690   S;
4691
4692   /* and vxlan-gpe tunnel interfaces */
4693   M (SW_INTERFACE_DUMP, sw_interface_dump);
4694   mp->name_filter_valid = 1;
4695   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4696            sizeof (mp->name_filter) - 1);
4697   S;
4698
4699   /* and vxlan tunnel interfaces */
4700   M (SW_INTERFACE_DUMP, sw_interface_dump);
4701   mp->name_filter_valid = 1;
4702   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4703   S;
4704
4705   /* and host (af_packet) interfaces */
4706   M (SW_INTERFACE_DUMP, sw_interface_dump);
4707   mp->name_filter_valid = 1;
4708   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4709   S;
4710
4711   /* and l2tpv3 tunnel interfaces */
4712   M (SW_INTERFACE_DUMP, sw_interface_dump);
4713   mp->name_filter_valid = 1;
4714   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4715            sizeof (mp->name_filter) - 1);
4716   S;
4717
4718   /* and GRE tunnel interfaces */
4719   M (SW_INTERFACE_DUMP, sw_interface_dump);
4720   mp->name_filter_valid = 1;
4721   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4722   S;
4723
4724   /* and LISP-GPE interfaces */
4725   M (SW_INTERFACE_DUMP, sw_interface_dump);
4726   mp->name_filter_valid = 1;
4727   strncpy ((char *) mp->name_filter, "lisp_gpe",
4728            sizeof (mp->name_filter) - 1);
4729   S;
4730
4731   /* and IPSEC tunnel interfaces */
4732   M (SW_INTERFACE_DUMP, sw_interface_dump);
4733   mp->name_filter_valid = 1;
4734   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4735   S;
4736
4737   /* Use a control ping for synchronization */
4738   {
4739     vl_api_control_ping_t *mp;
4740     M (CONTROL_PING, control_ping);
4741     S;
4742   }
4743   W;
4744 }
4745
4746 static int
4747 api_sw_interface_set_flags (vat_main_t * vam)
4748 {
4749   unformat_input_t *i = vam->input;
4750   vl_api_sw_interface_set_flags_t *mp;
4751   f64 timeout;
4752   u32 sw_if_index;
4753   u8 sw_if_index_set = 0;
4754   u8 admin_up = 0, link_up = 0;
4755
4756   /* Parse args required to build the message */
4757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4758     {
4759       if (unformat (i, "admin-up"))
4760         admin_up = 1;
4761       else if (unformat (i, "admin-down"))
4762         admin_up = 0;
4763       else if (unformat (i, "link-up"))
4764         link_up = 1;
4765       else if (unformat (i, "link-down"))
4766         link_up = 0;
4767       else
4768         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4769         sw_if_index_set = 1;
4770       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4771         sw_if_index_set = 1;
4772       else
4773         break;
4774     }
4775
4776   if (sw_if_index_set == 0)
4777     {
4778       errmsg ("missing interface name or sw_if_index");
4779       return -99;
4780     }
4781
4782   /* Construct the API message */
4783   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4784   mp->sw_if_index = ntohl (sw_if_index);
4785   mp->admin_up_down = admin_up;
4786   mp->link_up_down = link_up;
4787
4788   /* send it... */
4789   S;
4790
4791   /* Wait for a reply, return the good/bad news... */
4792   W;
4793 }
4794
4795 static int
4796 api_sw_interface_clear_stats (vat_main_t * vam)
4797 {
4798   unformat_input_t *i = vam->input;
4799   vl_api_sw_interface_clear_stats_t *mp;
4800   f64 timeout;
4801   u32 sw_if_index;
4802   u8 sw_if_index_set = 0;
4803
4804   /* Parse args required to build the message */
4805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4806     {
4807       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4808         sw_if_index_set = 1;
4809       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4810         sw_if_index_set = 1;
4811       else
4812         break;
4813     }
4814
4815   /* Construct the API message */
4816   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4817
4818   if (sw_if_index_set == 1)
4819     mp->sw_if_index = ntohl (sw_if_index);
4820   else
4821     mp->sw_if_index = ~0;
4822
4823   /* send it... */
4824   S;
4825
4826   /* Wait for a reply, return the good/bad news... */
4827   W;
4828 }
4829
4830 #if DPDK >0
4831 static int
4832 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4833 {
4834   unformat_input_t *i = vam->input;
4835   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4836   f64 timeout;
4837   u32 sw_if_index;
4838   u8 sw_if_index_set = 0;
4839   u32 subport;
4840   u8 subport_set = 0;
4841   u32 pipe;
4842   u8 pipe_set = 0;
4843   u32 profile;
4844   u8 profile_set = 0;
4845
4846   /* Parse args required to build the message */
4847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4848     {
4849       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4850         sw_if_index_set = 1;
4851       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4852         sw_if_index_set = 1;
4853       else if (unformat (i, "subport %u", &subport))
4854         subport_set = 1;
4855       else
4856         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4857         sw_if_index_set = 1;
4858       else if (unformat (i, "pipe %u", &pipe))
4859         pipe_set = 1;
4860       else if (unformat (i, "profile %u", &profile))
4861         profile_set = 1;
4862       else
4863         break;
4864     }
4865
4866   if (sw_if_index_set == 0)
4867     {
4868       errmsg ("missing interface name or sw_if_index");
4869       return -99;
4870     }
4871
4872   if (subport_set == 0)
4873     {
4874       errmsg ("missing subport ");
4875       return -99;
4876     }
4877
4878   if (pipe_set == 0)
4879     {
4880       errmsg ("missing pipe");
4881       return -99;
4882     }
4883
4884   if (profile_set == 0)
4885     {
4886       errmsg ("missing profile");
4887       return -99;
4888     }
4889
4890   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4891
4892   mp->sw_if_index = ntohl (sw_if_index);
4893   mp->subport = ntohl (subport);
4894   mp->pipe = ntohl (pipe);
4895   mp->profile = ntohl (profile);
4896
4897
4898   S;
4899   W;
4900   /* NOTREACHED */
4901   return 0;
4902 }
4903
4904 static int
4905 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4906 {
4907   unformat_input_t *i = vam->input;
4908   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4909   f64 timeout;
4910   u32 sw_if_index;
4911   u8 sw_if_index_set = 0;
4912   u32 subport;
4913   u8 subport_set = 0;
4914   u32 tb_rate = 1250000000;     /* 10GbE */
4915   u32 tb_size = 1000000;
4916   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4917   u32 tc_period = 10;
4918
4919   /* Parse args required to build the message */
4920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4921     {
4922       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4923         sw_if_index_set = 1;
4924       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4925         sw_if_index_set = 1;
4926       else if (unformat (i, "subport %u", &subport))
4927         subport_set = 1;
4928       else
4929         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4930         sw_if_index_set = 1;
4931       else if (unformat (i, "rate %u", &tb_rate))
4932         {
4933           u32 tc_id;
4934
4935           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4936                tc_id++)
4937             tc_rate[tc_id] = tb_rate;
4938         }
4939       else if (unformat (i, "bktsize %u", &tb_size))
4940         ;
4941       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4942         ;
4943       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4944         ;
4945       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4946         ;
4947       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4948         ;
4949       else if (unformat (i, "period %u", &tc_period))
4950         ;
4951       else
4952         break;
4953     }
4954
4955   if (sw_if_index_set == 0)
4956     {
4957       errmsg ("missing interface name or sw_if_index");
4958       return -99;
4959     }
4960
4961   if (subport_set == 0)
4962     {
4963       errmsg ("missing subport ");
4964       return -99;
4965     }
4966
4967   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4968
4969   mp->sw_if_index = ntohl (sw_if_index);
4970   mp->subport = ntohl (subport);
4971   mp->tb_rate = ntohl (tb_rate);
4972   mp->tb_size = ntohl (tb_size);
4973   mp->tc_rate[0] = ntohl (tc_rate[0]);
4974   mp->tc_rate[1] = ntohl (tc_rate[1]);
4975   mp->tc_rate[2] = ntohl (tc_rate[2]);
4976   mp->tc_rate[3] = ntohl (tc_rate[3]);
4977   mp->tc_period = ntohl (tc_period);
4978
4979   S;
4980   W;
4981   /* NOTREACHED */
4982   return 0;
4983 }
4984
4985 static int
4986 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4987 {
4988   unformat_input_t *i = vam->input;
4989   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4990   f64 timeout;
4991   u32 sw_if_index;
4992   u8 sw_if_index_set = 0;
4993   u8 entry_set = 0;
4994   u8 tc_set = 0;
4995   u8 queue_set = 0;
4996   u32 entry, tc, queue;
4997
4998   /* Parse args required to build the message */
4999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5000     {
5001       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5002         sw_if_index_set = 1;
5003       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5004         sw_if_index_set = 1;
5005       else if (unformat (i, "entry %d", &entry))
5006         entry_set = 1;
5007       else if (unformat (i, "tc %d", &tc))
5008         tc_set = 1;
5009       else if (unformat (i, "queue %d", &queue))
5010         queue_set = 1;
5011       else
5012         break;
5013     }
5014
5015   if (sw_if_index_set == 0)
5016     {
5017       errmsg ("missing interface name or sw_if_index");
5018       return -99;
5019     }
5020
5021   if (entry_set == 0)
5022     {
5023       errmsg ("missing entry ");
5024       return -99;
5025     }
5026
5027   if (tc_set == 0)
5028     {
5029       errmsg ("missing traffic class ");
5030       return -99;
5031     }
5032
5033   if (queue_set == 0)
5034     {
5035       errmsg ("missing queue ");
5036       return -99;
5037     }
5038
5039   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
5040
5041   mp->sw_if_index = ntohl (sw_if_index);
5042   mp->entry = ntohl (entry);
5043   mp->tc = ntohl (tc);
5044   mp->queue = ntohl (queue);
5045
5046   S;
5047   W;
5048   /* NOTREACHED */
5049   return 0;
5050 }
5051 #endif
5052
5053 static int
5054 api_sw_interface_add_del_address (vat_main_t * vam)
5055 {
5056   unformat_input_t *i = vam->input;
5057   vl_api_sw_interface_add_del_address_t *mp;
5058   f64 timeout;
5059   u32 sw_if_index;
5060   u8 sw_if_index_set = 0;
5061   u8 is_add = 1, del_all = 0;
5062   u32 address_length = 0;
5063   u8 v4_address_set = 0;
5064   u8 v6_address_set = 0;
5065   ip4_address_t v4address;
5066   ip6_address_t v6address;
5067
5068   /* Parse args required to build the message */
5069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5070     {
5071       if (unformat (i, "del-all"))
5072         del_all = 1;
5073       else if (unformat (i, "del"))
5074         is_add = 0;
5075       else
5076         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5077         sw_if_index_set = 1;
5078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5079         sw_if_index_set = 1;
5080       else if (unformat (i, "%U/%d",
5081                          unformat_ip4_address, &v4address, &address_length))
5082         v4_address_set = 1;
5083       else if (unformat (i, "%U/%d",
5084                          unformat_ip6_address, &v6address, &address_length))
5085         v6_address_set = 1;
5086       else
5087         break;
5088     }
5089
5090   if (sw_if_index_set == 0)
5091     {
5092       errmsg ("missing interface name or sw_if_index");
5093       return -99;
5094     }
5095   if (v4_address_set && v6_address_set)
5096     {
5097       errmsg ("both v4 and v6 addresses set");
5098       return -99;
5099     }
5100   if (!v4_address_set && !v6_address_set && !del_all)
5101     {
5102       errmsg ("no addresses set");
5103       return -99;
5104     }
5105
5106   /* Construct the API message */
5107   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
5108
5109   mp->sw_if_index = ntohl (sw_if_index);
5110   mp->is_add = is_add;
5111   mp->del_all = del_all;
5112   if (v6_address_set)
5113     {
5114       mp->is_ipv6 = 1;
5115       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5116     }
5117   else
5118     {
5119       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5120     }
5121   mp->address_length = address_length;
5122
5123   /* send it... */
5124   S;
5125
5126   /* Wait for a reply, return good/bad news  */
5127   W;
5128 }
5129
5130 static int
5131 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5132 {
5133   unformat_input_t *i = vam->input;
5134   vl_api_sw_interface_set_mpls_enable_t *mp;
5135   f64 timeout;
5136   u32 sw_if_index;
5137   u8 sw_if_index_set = 0;
5138   u8 enable = 1;
5139
5140   /* Parse args required to build the message */
5141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5142     {
5143       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5144         sw_if_index_set = 1;
5145       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5146         sw_if_index_set = 1;
5147       else if (unformat (i, "disable"))
5148         enable = 0;
5149       else if (unformat (i, "dis"))
5150         enable = 0;
5151       else
5152         break;
5153     }
5154
5155   if (sw_if_index_set == 0)
5156     {
5157       errmsg ("missing interface name or sw_if_index");
5158       return -99;
5159     }
5160
5161   /* Construct the API message */
5162   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5163
5164   mp->sw_if_index = ntohl (sw_if_index);
5165   mp->enable = enable;
5166
5167   /* send it... */
5168   S;
5169
5170   /* Wait for a reply... */
5171   W;
5172 }
5173
5174 static int
5175 api_sw_interface_set_table (vat_main_t * vam)
5176 {
5177   unformat_input_t *i = vam->input;
5178   vl_api_sw_interface_set_table_t *mp;
5179   f64 timeout;
5180   u32 sw_if_index, vrf_id = 0;
5181   u8 sw_if_index_set = 0;
5182   u8 is_ipv6 = 0;
5183
5184   /* Parse args required to build the message */
5185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5186     {
5187       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5188         sw_if_index_set = 1;
5189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5190         sw_if_index_set = 1;
5191       else if (unformat (i, "vrf %d", &vrf_id))
5192         ;
5193       else if (unformat (i, "ipv6"))
5194         is_ipv6 = 1;
5195       else
5196         break;
5197     }
5198
5199   if (sw_if_index_set == 0)
5200     {
5201       errmsg ("missing interface name or sw_if_index");
5202       return -99;
5203     }
5204
5205   /* Construct the API message */
5206   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5207
5208   mp->sw_if_index = ntohl (sw_if_index);
5209   mp->is_ipv6 = is_ipv6;
5210   mp->vrf_id = ntohl (vrf_id);
5211
5212   /* send it... */
5213   S;
5214
5215   /* Wait for a reply... */
5216   W;
5217 }
5218
5219 static void vl_api_sw_interface_get_table_reply_t_handler
5220   (vl_api_sw_interface_get_table_reply_t * mp)
5221 {
5222   vat_main_t *vam = &vat_main;
5223
5224   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5225
5226   vam->retval = ntohl (mp->retval);
5227   vam->result_ready = 1;
5228
5229 }
5230
5231 static void vl_api_sw_interface_get_table_reply_t_handler_json
5232   (vl_api_sw_interface_get_table_reply_t * mp)
5233 {
5234   vat_main_t *vam = &vat_main;
5235   vat_json_node_t node;
5236
5237   vat_json_init_object (&node);
5238   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5239   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5240
5241   vat_json_print (vam->ofp, &node);
5242   vat_json_free (&node);
5243
5244   vam->retval = ntohl (mp->retval);
5245   vam->result_ready = 1;
5246 }
5247
5248 static int
5249 api_sw_interface_get_table (vat_main_t * vam)
5250 {
5251   unformat_input_t *i = vam->input;
5252   vl_api_sw_interface_get_table_t *mp;
5253   u32 sw_if_index;
5254   u8 sw_if_index_set = 0;
5255   u8 is_ipv6 = 0;
5256   f64 timeout;
5257
5258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5259     {
5260       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5261         sw_if_index_set = 1;
5262       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5263         sw_if_index_set = 1;
5264       else if (unformat (i, "ipv6"))
5265         is_ipv6 = 1;
5266       else
5267         break;
5268     }
5269
5270   if (sw_if_index_set == 0)
5271     {
5272       errmsg ("missing interface name or sw_if_index");
5273       return -99;
5274     }
5275
5276   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5277   mp->sw_if_index = htonl (sw_if_index);
5278   mp->is_ipv6 = is_ipv6;
5279
5280   S;
5281   W;
5282 }
5283
5284 static int
5285 api_sw_interface_set_vpath (vat_main_t * vam)
5286 {
5287   unformat_input_t *i = vam->input;
5288   vl_api_sw_interface_set_vpath_t *mp;
5289   f64 timeout;
5290   u32 sw_if_index = 0;
5291   u8 sw_if_index_set = 0;
5292   u8 is_enable = 0;
5293
5294   /* Parse args required to build the message */
5295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5296     {
5297       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5298         sw_if_index_set = 1;
5299       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5300         sw_if_index_set = 1;
5301       else if (unformat (i, "enable"))
5302         is_enable = 1;
5303       else if (unformat (i, "disable"))
5304         is_enable = 0;
5305       else
5306         break;
5307     }
5308
5309   if (sw_if_index_set == 0)
5310     {
5311       errmsg ("missing interface name or sw_if_index");
5312       return -99;
5313     }
5314
5315   /* Construct the API message */
5316   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5317
5318   mp->sw_if_index = ntohl (sw_if_index);
5319   mp->enable = is_enable;
5320
5321   /* send it... */
5322   S;
5323
5324   /* Wait for a reply... */
5325   W;
5326 }
5327
5328 static int
5329 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5330 {
5331   unformat_input_t *i = vam->input;
5332   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5333   f64 timeout;
5334   u32 sw_if_index = 0;
5335   u8 sw_if_index_set = 0;
5336   u8 is_enable = 0;
5337   u8 is_ipv6 = 0;
5338
5339   /* Parse args required to build the message */
5340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5341     {
5342       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5343         sw_if_index_set = 1;
5344       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5345         sw_if_index_set = 1;
5346       else if (unformat (i, "enable"))
5347         is_enable = 1;
5348       else if (unformat (i, "disable"))
5349         is_enable = 0;
5350       else if (unformat (i, "ip4"))
5351         is_ipv6 = 0;
5352       else if (unformat (i, "ip6"))
5353         is_ipv6 = 1;
5354       else
5355         break;
5356     }
5357
5358   if (sw_if_index_set == 0)
5359     {
5360       errmsg ("missing interface name or sw_if_index");
5361       return -99;
5362     }
5363
5364   /* Construct the API message */
5365   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5366
5367   mp->sw_if_index = ntohl (sw_if_index);
5368   mp->enable = is_enable;
5369   mp->is_ipv6 = is_ipv6;
5370
5371   /* send it... */
5372   S;
5373
5374   /* Wait for a reply... */
5375   W;
5376 }
5377
5378 static int
5379 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5380 {
5381   unformat_input_t *i = vam->input;
5382   vl_api_sw_interface_set_l2_xconnect_t *mp;
5383   f64 timeout;
5384   u32 rx_sw_if_index;
5385   u8 rx_sw_if_index_set = 0;
5386   u32 tx_sw_if_index;
5387   u8 tx_sw_if_index_set = 0;
5388   u8 enable = 1;
5389
5390   /* Parse args required to build the message */
5391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5392     {
5393       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5394         rx_sw_if_index_set = 1;
5395       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5396         tx_sw_if_index_set = 1;
5397       else if (unformat (i, "rx"))
5398         {
5399           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5400             {
5401               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5402                             &rx_sw_if_index))
5403                 rx_sw_if_index_set = 1;
5404             }
5405           else
5406             break;
5407         }
5408       else if (unformat (i, "tx"))
5409         {
5410           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5411             {
5412               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5413                             &tx_sw_if_index))
5414                 tx_sw_if_index_set = 1;
5415             }
5416           else
5417             break;
5418         }
5419       else if (unformat (i, "enable"))
5420         enable = 1;
5421       else if (unformat (i, "disable"))
5422         enable = 0;
5423       else
5424         break;
5425     }
5426
5427   if (rx_sw_if_index_set == 0)
5428     {
5429       errmsg ("missing rx interface name or rx_sw_if_index");
5430       return -99;
5431     }
5432
5433   if (enable && (tx_sw_if_index_set == 0))
5434     {
5435       errmsg ("missing tx interface name or tx_sw_if_index");
5436       return -99;
5437     }
5438
5439   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5440
5441   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5442   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5443   mp->enable = enable;
5444
5445   S;
5446   W;
5447   /* NOTREACHED */
5448   return 0;
5449 }
5450
5451 static int
5452 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5453 {
5454   unformat_input_t *i = vam->input;
5455   vl_api_sw_interface_set_l2_bridge_t *mp;
5456   f64 timeout;
5457   u32 rx_sw_if_index;
5458   u8 rx_sw_if_index_set = 0;
5459   u32 bd_id;
5460   u8 bd_id_set = 0;
5461   u8 bvi = 0;
5462   u32 shg = 0;
5463   u8 enable = 1;
5464
5465   /* Parse args required to build the message */
5466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5467     {
5468       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5469         rx_sw_if_index_set = 1;
5470       else if (unformat (i, "bd_id %d", &bd_id))
5471         bd_id_set = 1;
5472       else
5473         if (unformat
5474             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5475         rx_sw_if_index_set = 1;
5476       else if (unformat (i, "shg %d", &shg))
5477         ;
5478       else if (unformat (i, "bvi"))
5479         bvi = 1;
5480       else if (unformat (i, "enable"))
5481         enable = 1;
5482       else if (unformat (i, "disable"))
5483         enable = 0;
5484       else
5485         break;
5486     }
5487
5488   if (rx_sw_if_index_set == 0)
5489     {
5490       errmsg ("missing rx interface name or sw_if_index");
5491       return -99;
5492     }
5493
5494   if (enable && (bd_id_set == 0))
5495     {
5496       errmsg ("missing bridge domain");
5497       return -99;
5498     }
5499
5500   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5501
5502   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5503   mp->bd_id = ntohl (bd_id);
5504   mp->shg = (u8) shg;
5505   mp->bvi = bvi;
5506   mp->enable = enable;
5507
5508   S;
5509   W;
5510   /* NOTREACHED */
5511   return 0;
5512 }
5513
5514 static int
5515 api_bridge_domain_dump (vat_main_t * vam)
5516 {
5517   unformat_input_t *i = vam->input;
5518   vl_api_bridge_domain_dump_t *mp;
5519   f64 timeout;
5520   u32 bd_id = ~0;
5521
5522   /* Parse args required to build the message */
5523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5524     {
5525       if (unformat (i, "bd_id %d", &bd_id))
5526         ;
5527       else
5528         break;
5529     }
5530
5531   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5532   mp->bd_id = ntohl (bd_id);
5533   S;
5534
5535   /* Use a control ping for synchronization */
5536   {
5537     vl_api_control_ping_t *mp;
5538     M (CONTROL_PING, control_ping);
5539     S;
5540   }
5541
5542   W;
5543   /* NOTREACHED */
5544   return 0;
5545 }
5546
5547 static int
5548 api_bridge_domain_add_del (vat_main_t * vam)
5549 {
5550   unformat_input_t *i = vam->input;
5551   vl_api_bridge_domain_add_del_t *mp;
5552   f64 timeout;
5553   u32 bd_id = ~0;
5554   u8 is_add = 1;
5555   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5556   u32 mac_age = 0;
5557
5558   /* Parse args required to build the message */
5559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5560     {
5561       if (unformat (i, "bd_id %d", &bd_id))
5562         ;
5563       else if (unformat (i, "flood %d", &flood))
5564         ;
5565       else if (unformat (i, "uu-flood %d", &uu_flood))
5566         ;
5567       else if (unformat (i, "forward %d", &forward))
5568         ;
5569       else if (unformat (i, "learn %d", &learn))
5570         ;
5571       else if (unformat (i, "arp-term %d", &arp_term))
5572         ;
5573       else if (unformat (i, "mac-age %d", &mac_age))
5574         ;
5575       else if (unformat (i, "del"))
5576         {
5577           is_add = 0;
5578           flood = uu_flood = forward = learn = 0;
5579         }
5580       else
5581         break;
5582     }
5583
5584   if (bd_id == ~0)
5585     {
5586       errmsg ("missing bridge domain");
5587       return -99;
5588     }
5589
5590   if (mac_age > 255)
5591     {
5592       errmsg ("mac age must be less than 256 ");
5593       return -99;
5594     }
5595
5596   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5597
5598   mp->bd_id = ntohl (bd_id);
5599   mp->flood = flood;
5600   mp->uu_flood = uu_flood;
5601   mp->forward = forward;
5602   mp->learn = learn;
5603   mp->arp_term = arp_term;
5604   mp->is_add = is_add;
5605   mp->mac_age = (u8) mac_age;
5606
5607   S;
5608   W;
5609   /* NOTREACHED */
5610   return 0;
5611 }
5612
5613 static int
5614 api_l2fib_add_del (vat_main_t * vam)
5615 {
5616   unformat_input_t *i = vam->input;
5617   vl_api_l2fib_add_del_t *mp;
5618   f64 timeout;
5619   u64 mac = 0;
5620   u8 mac_set = 0;
5621   u32 bd_id;
5622   u8 bd_id_set = 0;
5623   u32 sw_if_index = ~0;
5624   u8 sw_if_index_set = 0;
5625   u8 is_add = 1;
5626   u8 static_mac = 0;
5627   u8 filter_mac = 0;
5628   u8 bvi_mac = 0;
5629   int count = 1;
5630   f64 before = 0;
5631   int j;
5632
5633   /* Parse args required to build the message */
5634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5635     {
5636       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5637         mac_set = 1;
5638       else if (unformat (i, "bd_id %d", &bd_id))
5639         bd_id_set = 1;
5640       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5641         sw_if_index_set = 1;
5642       else if (unformat (i, "sw_if"))
5643         {
5644           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5645             {
5646               if (unformat
5647                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5648                 sw_if_index_set = 1;
5649             }
5650           else
5651             break;
5652         }
5653       else if (unformat (i, "static"))
5654         static_mac = 1;
5655       else if (unformat (i, "filter"))
5656         {
5657           filter_mac = 1;
5658           static_mac = 1;
5659         }
5660       else if (unformat (i, "bvi"))
5661         {
5662           bvi_mac = 1;
5663           static_mac = 1;
5664         }
5665       else if (unformat (i, "del"))
5666         is_add = 0;
5667       else if (unformat (i, "count %d", &count))
5668         ;
5669       else
5670         break;
5671     }
5672
5673   if (mac_set == 0)
5674     {
5675       errmsg ("missing mac address");
5676       return -99;
5677     }
5678
5679   if (bd_id_set == 0)
5680     {
5681       errmsg ("missing bridge domain");
5682       return -99;
5683     }
5684
5685   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5686     {
5687       errmsg ("missing interface name or sw_if_index");
5688       return -99;
5689     }
5690
5691   if (count > 1)
5692     {
5693       /* Turn on async mode */
5694       vam->async_mode = 1;
5695       vam->async_errors = 0;
5696       before = vat_time_now (vam);
5697     }
5698
5699   for (j = 0; j < count; j++)
5700     {
5701       M (L2FIB_ADD_DEL, l2fib_add_del);
5702
5703       mp->mac = mac;
5704       mp->bd_id = ntohl (bd_id);
5705       mp->is_add = is_add;
5706
5707       if (is_add)
5708         {
5709           mp->sw_if_index = ntohl (sw_if_index);
5710           mp->static_mac = static_mac;
5711           mp->filter_mac = filter_mac;
5712           mp->bvi_mac = bvi_mac;
5713         }
5714       increment_mac_address (&mac);
5715       /* send it... */
5716       S;
5717     }
5718
5719   if (count > 1)
5720     {
5721       vl_api_control_ping_t *mp;
5722       f64 after;
5723
5724       /* Shut off async mode */
5725       vam->async_mode = 0;
5726
5727       M (CONTROL_PING, control_ping);
5728       S;
5729
5730       timeout = vat_time_now (vam) + 1.0;
5731       while (vat_time_now (vam) < timeout)
5732         if (vam->result_ready == 1)
5733           goto out;
5734       vam->retval = -99;
5735
5736     out:
5737       if (vam->retval == -99)
5738         errmsg ("timeout");
5739
5740       if (vam->async_errors > 0)
5741         {
5742           errmsg ("%d asynchronous errors", vam->async_errors);
5743           vam->retval = -98;
5744         }
5745       vam->async_errors = 0;
5746       after = vat_time_now (vam);
5747
5748       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5749              count, after - before, count / (after - before));
5750     }
5751   else
5752     {
5753       /* Wait for a reply... */
5754       W;
5755     }
5756   /* Return the good/bad news */
5757   return (vam->retval);
5758 }
5759
5760 static int
5761 api_l2_flags (vat_main_t * vam)
5762 {
5763   unformat_input_t *i = vam->input;
5764   vl_api_l2_flags_t *mp;
5765   f64 timeout;
5766   u32 sw_if_index;
5767   u32 feature_bitmap = 0;
5768   u8 sw_if_index_set = 0;
5769
5770   /* Parse args required to build the message */
5771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5772     {
5773       if (unformat (i, "sw_if_index %d", &sw_if_index))
5774         sw_if_index_set = 1;
5775       else if (unformat (i, "sw_if"))
5776         {
5777           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5778             {
5779               if (unformat
5780                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5781                 sw_if_index_set = 1;
5782             }
5783           else
5784             break;
5785         }
5786       else if (unformat (i, "learn"))
5787         feature_bitmap |= L2INPUT_FEAT_LEARN;
5788       else if (unformat (i, "forward"))
5789         feature_bitmap |= L2INPUT_FEAT_FWD;
5790       else if (unformat (i, "flood"))
5791         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5792       else if (unformat (i, "uu-flood"))
5793         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5794       else
5795         break;
5796     }
5797
5798   if (sw_if_index_set == 0)
5799     {
5800       errmsg ("missing interface name or sw_if_index");
5801       return -99;
5802     }
5803
5804   M (L2_FLAGS, l2_flags);
5805
5806   mp->sw_if_index = ntohl (sw_if_index);
5807   mp->feature_bitmap = ntohl (feature_bitmap);
5808
5809   S;
5810   W;
5811   /* NOTREACHED */
5812   return 0;
5813 }
5814
5815 static int
5816 api_bridge_flags (vat_main_t * vam)
5817 {
5818   unformat_input_t *i = vam->input;
5819   vl_api_bridge_flags_t *mp;
5820   f64 timeout;
5821   u32 bd_id;
5822   u8 bd_id_set = 0;
5823   u8 is_set = 1;
5824   u32 flags = 0;
5825
5826   /* Parse args required to build the message */
5827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5828     {
5829       if (unformat (i, "bd_id %d", &bd_id))
5830         bd_id_set = 1;
5831       else if (unformat (i, "learn"))
5832         flags |= L2_LEARN;
5833       else if (unformat (i, "forward"))
5834         flags |= L2_FWD;
5835       else if (unformat (i, "flood"))
5836         flags |= L2_FLOOD;
5837       else if (unformat (i, "uu-flood"))
5838         flags |= L2_UU_FLOOD;
5839       else if (unformat (i, "arp-term"))
5840         flags |= L2_ARP_TERM;
5841       else if (unformat (i, "off"))
5842         is_set = 0;
5843       else if (unformat (i, "disable"))
5844         is_set = 0;
5845       else
5846         break;
5847     }
5848
5849   if (bd_id_set == 0)
5850     {
5851       errmsg ("missing bridge domain");
5852       return -99;
5853     }
5854
5855   M (BRIDGE_FLAGS, bridge_flags);
5856
5857   mp->bd_id = ntohl (bd_id);
5858   mp->feature_bitmap = ntohl (flags);
5859   mp->is_set = is_set;
5860
5861   S;
5862   W;
5863   /* NOTREACHED */
5864   return 0;
5865 }
5866
5867 static int
5868 api_bd_ip_mac_add_del (vat_main_t * vam)
5869 {
5870   unformat_input_t *i = vam->input;
5871   vl_api_bd_ip_mac_add_del_t *mp;
5872   f64 timeout;
5873   u32 bd_id;
5874   u8 is_ipv6 = 0;
5875   u8 is_add = 1;
5876   u8 bd_id_set = 0;
5877   u8 ip_set = 0;
5878   u8 mac_set = 0;
5879   ip4_address_t v4addr;
5880   ip6_address_t v6addr;
5881   u8 macaddr[6];
5882
5883
5884   /* Parse args required to build the message */
5885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5886     {
5887       if (unformat (i, "bd_id %d", &bd_id))
5888         {
5889           bd_id_set++;
5890         }
5891       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5892         {
5893           ip_set++;
5894         }
5895       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5896         {
5897           ip_set++;
5898           is_ipv6++;
5899         }
5900       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5901         {
5902           mac_set++;
5903         }
5904       else if (unformat (i, "del"))
5905         is_add = 0;
5906       else
5907         break;
5908     }
5909
5910   if (bd_id_set == 0)
5911     {
5912       errmsg ("missing bridge domain");
5913       return -99;
5914     }
5915   else if (ip_set == 0)
5916     {
5917       errmsg ("missing IP address");
5918       return -99;
5919     }
5920   else if (mac_set == 0)
5921     {
5922       errmsg ("missing MAC address");
5923       return -99;
5924     }
5925
5926   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5927
5928   mp->bd_id = ntohl (bd_id);
5929   mp->is_ipv6 = is_ipv6;
5930   mp->is_add = is_add;
5931   if (is_ipv6)
5932     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5933   else
5934     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5935   clib_memcpy (mp->mac_address, macaddr, 6);
5936   S;
5937   W;
5938   /* NOTREACHED */
5939   return 0;
5940 }
5941
5942 static int
5943 api_tap_connect (vat_main_t * vam)
5944 {
5945   unformat_input_t *i = vam->input;
5946   vl_api_tap_connect_t *mp;
5947   f64 timeout;
5948   u8 mac_address[6];
5949   u8 random_mac = 1;
5950   u8 name_set = 0;
5951   u8 *tap_name;
5952   u8 *tag = 0;
5953   ip4_address_t ip4_address;
5954   u32 ip4_mask_width;
5955   int ip4_address_set = 0;
5956   ip6_address_t ip6_address;
5957   u32 ip6_mask_width;
5958   int ip6_address_set = 0;
5959
5960   memset (mac_address, 0, sizeof (mac_address));
5961
5962   /* Parse args required to build the message */
5963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5964     {
5965       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5966         {
5967           random_mac = 0;
5968         }
5969       else if (unformat (i, "random-mac"))
5970         random_mac = 1;
5971       else if (unformat (i, "tapname %s", &tap_name))
5972         name_set = 1;
5973       else if (unformat (i, "tag %s", &tag))
5974         ;
5975       else if (unformat (i, "address %U/%d",
5976                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
5977         ip4_address_set = 1;
5978       else if (unformat (i, "address %U/%d",
5979                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
5980         ip6_address_set = 1;
5981       else
5982         break;
5983     }
5984
5985   if (name_set == 0)
5986     {
5987       errmsg ("missing tap name");
5988       return -99;
5989     }
5990   if (vec_len (tap_name) > 63)
5991     {
5992       errmsg ("tap name too long");
5993       return -99;
5994     }
5995   vec_add1 (tap_name, 0);
5996
5997   if (vec_len (tag) > 63)
5998     {
5999       errmsg ("tag too long");
6000       return -99;
6001     }
6002
6003   /* Construct the API message */
6004   M (TAP_CONNECT, tap_connect);
6005
6006   mp->use_random_mac = random_mac;
6007   clib_memcpy (mp->mac_address, mac_address, 6);
6008   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6009   if (tag)
6010     clib_memcpy (mp->tag, tag, vec_len (tag));
6011
6012   if (ip4_address_set)
6013     {
6014       mp->ip4_address_set = 1;
6015       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6016       mp->ip4_mask_width = ip4_mask_width;
6017     }
6018   if (ip6_address_set)
6019     {
6020       mp->ip6_address_set = 1;
6021       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6022       mp->ip6_mask_width = ip6_mask_width;
6023     }
6024
6025   vec_free (tap_name);
6026   vec_free (tag);
6027
6028   /* send it... */
6029   S;
6030
6031   /* Wait for a reply... */
6032   W;
6033 }
6034
6035 static int
6036 api_tap_modify (vat_main_t * vam)
6037 {
6038   unformat_input_t *i = vam->input;
6039   vl_api_tap_modify_t *mp;
6040   f64 timeout;
6041   u8 mac_address[6];
6042   u8 random_mac = 1;
6043   u8 name_set = 0;
6044   u8 *tap_name;
6045   u32 sw_if_index = ~0;
6046   u8 sw_if_index_set = 0;
6047
6048   memset (mac_address, 0, sizeof (mac_address));
6049
6050   /* Parse args required to build the message */
6051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6052     {
6053       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6054         sw_if_index_set = 1;
6055       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6056         sw_if_index_set = 1;
6057       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6058         {
6059           random_mac = 0;
6060         }
6061       else if (unformat (i, "random-mac"))
6062         random_mac = 1;
6063       else if (unformat (i, "tapname %s", &tap_name))
6064         name_set = 1;
6065       else
6066         break;
6067     }
6068
6069   if (sw_if_index_set == 0)
6070     {
6071       errmsg ("missing vpp interface name");
6072       return -99;
6073     }
6074   if (name_set == 0)
6075     {
6076       errmsg ("missing tap name");
6077       return -99;
6078     }
6079   if (vec_len (tap_name) > 63)
6080     {
6081       errmsg ("tap name too long");
6082     }
6083   vec_add1 (tap_name, 0);
6084
6085   /* Construct the API message */
6086   M (TAP_MODIFY, tap_modify);
6087
6088   mp->use_random_mac = random_mac;
6089   mp->sw_if_index = ntohl (sw_if_index);
6090   clib_memcpy (mp->mac_address, mac_address, 6);
6091   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6092   vec_free (tap_name);
6093
6094   /* send it... */
6095   S;
6096
6097   /* Wait for a reply... */
6098   W;
6099 }
6100
6101 static int
6102 api_tap_delete (vat_main_t * vam)
6103 {
6104   unformat_input_t *i = vam->input;
6105   vl_api_tap_delete_t *mp;
6106   f64 timeout;
6107   u32 sw_if_index = ~0;
6108   u8 sw_if_index_set = 0;
6109
6110   /* Parse args required to build the message */
6111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6112     {
6113       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6114         sw_if_index_set = 1;
6115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6116         sw_if_index_set = 1;
6117       else
6118         break;
6119     }
6120
6121   if (sw_if_index_set == 0)
6122     {
6123       errmsg ("missing vpp interface name");
6124       return -99;
6125     }
6126
6127   /* Construct the API message */
6128   M (TAP_DELETE, tap_delete);
6129
6130   mp->sw_if_index = ntohl (sw_if_index);
6131
6132   /* send it... */
6133   S;
6134
6135   /* Wait for a reply... */
6136   W;
6137 }
6138
6139 static int
6140 api_ip_add_del_route (vat_main_t * vam)
6141 {
6142   unformat_input_t *i = vam->input;
6143   vl_api_ip_add_del_route_t *mp;
6144   f64 timeout;
6145   u32 sw_if_index = ~0, vrf_id = 0;
6146   u8 is_ipv6 = 0;
6147   u8 is_local = 0, is_drop = 0;
6148   u8 is_unreach = 0, is_prohibit = 0;
6149   u8 create_vrf_if_needed = 0;
6150   u8 is_add = 1;
6151   u32 next_hop_weight = 1;
6152   u8 not_last = 0;
6153   u8 is_multipath = 0;
6154   u8 address_set = 0;
6155   u8 address_length_set = 0;
6156   u32 next_hop_table_id = 0;
6157   u32 resolve_attempts = 0;
6158   u32 dst_address_length = 0;
6159   u8 next_hop_set = 0;
6160   ip4_address_t v4_dst_address, v4_next_hop_address;
6161   ip6_address_t v6_dst_address, v6_next_hop_address;
6162   int count = 1;
6163   int j;
6164   f64 before = 0;
6165   u32 random_add_del = 0;
6166   u32 *random_vector = 0;
6167   uword *random_hash;
6168   u32 random_seed = 0xdeaddabe;
6169   u32 classify_table_index = ~0;
6170   u8 is_classify = 0;
6171   u8 resolve_host = 0, resolve_attached = 0;
6172   mpls_label_t *next_hop_out_label_stack = NULL;
6173   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6174   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6175
6176   /* Parse args required to build the message */
6177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6178     {
6179       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6180         ;
6181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6182         ;
6183       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6184         {
6185           address_set = 1;
6186           is_ipv6 = 0;
6187         }
6188       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6189         {
6190           address_set = 1;
6191           is_ipv6 = 1;
6192         }
6193       else if (unformat (i, "/%d", &dst_address_length))
6194         {
6195           address_length_set = 1;
6196         }
6197
6198       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6199                                          &v4_next_hop_address))
6200         {
6201           next_hop_set = 1;
6202         }
6203       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6204                                          &v6_next_hop_address))
6205         {
6206           next_hop_set = 1;
6207         }
6208       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6209         ;
6210       else if (unformat (i, "weight %d", &next_hop_weight))
6211         ;
6212       else if (unformat (i, "drop"))
6213         {
6214           is_drop = 1;
6215         }
6216       else if (unformat (i, "null-send-unreach"))
6217         {
6218           is_unreach = 1;
6219         }
6220       else if (unformat (i, "null-send-prohibit"))
6221         {
6222           is_prohibit = 1;
6223         }
6224       else if (unformat (i, "local"))
6225         {
6226           is_local = 1;
6227         }
6228       else if (unformat (i, "classify %d", &classify_table_index))
6229         {
6230           is_classify = 1;
6231         }
6232       else if (unformat (i, "del"))
6233         is_add = 0;
6234       else if (unformat (i, "add"))
6235         is_add = 1;
6236       else if (unformat (i, "not-last"))
6237         not_last = 1;
6238       else if (unformat (i, "resolve-via-host"))
6239         resolve_host = 1;
6240       else if (unformat (i, "resolve-via-attached"))
6241         resolve_attached = 1;
6242       else if (unformat (i, "multipath"))
6243         is_multipath = 1;
6244       else if (unformat (i, "vrf %d", &vrf_id))
6245         ;
6246       else if (unformat (i, "create-vrf"))
6247         create_vrf_if_needed = 1;
6248       else if (unformat (i, "count %d", &count))
6249         ;
6250       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6251         ;
6252       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6253         ;
6254       else if (unformat (i, "out-label %d", &next_hop_out_label))
6255         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6256       else if (unformat (i, "via-label %d", &next_hop_via_label))
6257         ;
6258       else if (unformat (i, "random"))
6259         random_add_del = 1;
6260       else if (unformat (i, "seed %d", &random_seed))
6261         ;
6262       else
6263         {
6264           clib_warning ("parse error '%U'", format_unformat_error, i);
6265           return -99;
6266         }
6267     }
6268
6269   if (!next_hop_set && !is_drop && !is_local &&
6270       !is_classify && !is_unreach && !is_prohibit &&
6271       MPLS_LABEL_INVALID == next_hop_via_label)
6272     {
6273       errmsg
6274         ("next hop / local / drop / unreach / prohibit / classify not set");
6275       return -99;
6276     }
6277
6278   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6279     {
6280       errmsg ("next hop and next-hop via label set");
6281       return -99;
6282     }
6283   if (address_set == 0)
6284     {
6285       errmsg ("missing addresses");
6286       return -99;
6287     }
6288
6289   if (address_length_set == 0)
6290     {
6291       errmsg ("missing address length");
6292       return -99;
6293     }
6294
6295   /* Generate a pile of unique, random routes */
6296   if (random_add_del)
6297     {
6298       u32 this_random_address;
6299       random_hash = hash_create (count, sizeof (uword));
6300
6301       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6302       for (j = 0; j <= count; j++)
6303         {
6304           do
6305             {
6306               this_random_address = random_u32 (&random_seed);
6307               this_random_address =
6308                 clib_host_to_net_u32 (this_random_address);
6309             }
6310           while (hash_get (random_hash, this_random_address));
6311           vec_add1 (random_vector, this_random_address);
6312           hash_set (random_hash, this_random_address, 1);
6313         }
6314       hash_free (random_hash);
6315       v4_dst_address.as_u32 = random_vector[0];
6316     }
6317
6318   if (count > 1)
6319     {
6320       /* Turn on async mode */
6321       vam->async_mode = 1;
6322       vam->async_errors = 0;
6323       before = vat_time_now (vam);
6324     }
6325
6326   for (j = 0; j < count; j++)
6327     {
6328       /* Construct the API message */
6329       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6330           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6331
6332       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6333       mp->table_id = ntohl (vrf_id);
6334       mp->create_vrf_if_needed = create_vrf_if_needed;
6335
6336       mp->is_add = is_add;
6337       mp->is_drop = is_drop;
6338       mp->is_unreach = is_unreach;
6339       mp->is_prohibit = is_prohibit;
6340       mp->is_ipv6 = is_ipv6;
6341       mp->is_local = is_local;
6342       mp->is_classify = is_classify;
6343       mp->is_multipath = is_multipath;
6344       mp->is_resolve_host = resolve_host;
6345       mp->is_resolve_attached = resolve_attached;
6346       mp->not_last = not_last;
6347       mp->next_hop_weight = next_hop_weight;
6348       mp->dst_address_length = dst_address_length;
6349       mp->next_hop_table_id = ntohl (next_hop_table_id);
6350       mp->classify_table_index = ntohl (classify_table_index);
6351       mp->next_hop_via_label = ntohl (next_hop_via_label);
6352       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6353       if (0 != mp->next_hop_n_out_labels)
6354         {
6355           memcpy (mp->next_hop_out_label_stack,
6356                   next_hop_out_label_stack,
6357                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6358           vec_free (next_hop_out_label_stack);
6359         }
6360
6361       if (is_ipv6)
6362         {
6363           clib_memcpy (mp->dst_address, &v6_dst_address,
6364                        sizeof (v6_dst_address));
6365           if (next_hop_set)
6366             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6367                          sizeof (v6_next_hop_address));
6368           increment_v6_address (&v6_dst_address);
6369         }
6370       else
6371         {
6372           clib_memcpy (mp->dst_address, &v4_dst_address,
6373                        sizeof (v4_dst_address));
6374           if (next_hop_set)
6375             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6376                          sizeof (v4_next_hop_address));
6377           if (random_add_del)
6378             v4_dst_address.as_u32 = random_vector[j + 1];
6379           else
6380             increment_v4_address (&v4_dst_address);
6381         }
6382       /* send it... */
6383       S;
6384       /* If we receive SIGTERM, stop now... */
6385       if (vam->do_exit)
6386         break;
6387     }
6388
6389   /* When testing multiple add/del ops, use a control-ping to sync */
6390   if (count > 1)
6391     {
6392       vl_api_control_ping_t *mp;
6393       f64 after;
6394
6395       /* Shut off async mode */
6396       vam->async_mode = 0;
6397
6398       M (CONTROL_PING, control_ping);
6399       S;
6400
6401       timeout = vat_time_now (vam) + 1.0;
6402       while (vat_time_now (vam) < timeout)
6403         if (vam->result_ready == 1)
6404           goto out;
6405       vam->retval = -99;
6406
6407     out:
6408       if (vam->retval == -99)
6409         errmsg ("timeout");
6410
6411       if (vam->async_errors > 0)
6412         {
6413           errmsg ("%d asynchronous errors", vam->async_errors);
6414           vam->retval = -98;
6415         }
6416       vam->async_errors = 0;
6417       after = vat_time_now (vam);
6418
6419       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6420       if (j > 0)
6421         count = j;
6422
6423       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6424              count, after - before, count / (after - before));
6425     }
6426   else
6427     {
6428       /* Wait for a reply... */
6429       W;
6430     }
6431
6432   /* Return the good/bad news */
6433   return (vam->retval);
6434 }
6435
6436 static int
6437 api_ip_mroute_add_del (vat_main_t * vam)
6438 {
6439   unformat_input_t *i = vam->input;
6440   vl_api_ip_mroute_add_del_t *mp;
6441   f64 timeout;
6442   u32 sw_if_index = ~0, vrf_id = 0;
6443   u8 is_ipv6 = 0;
6444   u8 is_local = 0;
6445   u8 create_vrf_if_needed = 0;
6446   u8 is_add = 1;
6447   u8 address_set = 0;
6448   u32 grp_address_length = 0;
6449   ip4_address_t v4_grp_address, v4_src_address;
6450   ip6_address_t v6_grp_address, v6_src_address;
6451   mfib_itf_flags_t iflags = 0;
6452   mfib_entry_flags_t eflags = 0;
6453
6454   /* Parse args required to build the message */
6455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6456     {
6457       if (unformat (i, "sw_if_index %d", &sw_if_index))
6458         ;
6459       else if (unformat (i, "%U %U",
6460                          unformat_ip4_address, &v4_src_address,
6461                          unformat_ip4_address, &v4_grp_address))
6462         {
6463           grp_address_length = 64;
6464           address_set = 1;
6465           is_ipv6 = 0;
6466         }
6467       else if (unformat (i, "%U %U",
6468                          unformat_ip6_address, &v6_src_address,
6469                          unformat_ip6_address, &v6_grp_address))
6470         {
6471           grp_address_length = 256;
6472           address_set = 1;
6473           is_ipv6 = 1;
6474         }
6475       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6476         {
6477           memset (&v4_src_address, 0, sizeof (v4_src_address));
6478           grp_address_length = 32;
6479           address_set = 1;
6480           is_ipv6 = 0;
6481         }
6482       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6483         {
6484           memset (&v6_src_address, 0, sizeof (v6_src_address));
6485           grp_address_length = 128;
6486           address_set = 1;
6487           is_ipv6 = 1;
6488         }
6489       else if (unformat (i, "/%d", &grp_address_length))
6490         ;
6491       else if (unformat (i, "local"))
6492         {
6493           is_local = 1;
6494         }
6495       else if (unformat (i, "del"))
6496         is_add = 0;
6497       else if (unformat (i, "add"))
6498         is_add = 1;
6499       else if (unformat (i, "vrf %d", &vrf_id))
6500         ;
6501       else if (unformat (i, "create-vrf"))
6502         create_vrf_if_needed = 1;
6503       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6504         ;
6505       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6506         ;
6507       else
6508         {
6509           clib_warning ("parse error '%U'", format_unformat_error, i);
6510           return -99;
6511         }
6512     }
6513
6514   if (address_set == 0)
6515     {
6516       errmsg ("missing addresses\n");
6517       return -99;
6518     }
6519
6520   /* Construct the API message */
6521   M (IP_MROUTE_ADD_DEL, ip_mroute_add_del);
6522
6523   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6524   mp->table_id = ntohl (vrf_id);
6525   mp->create_vrf_if_needed = create_vrf_if_needed;
6526
6527   mp->is_add = is_add;
6528   mp->is_ipv6 = is_ipv6;
6529   mp->is_local = is_local;
6530   mp->itf_flags = ntohl (iflags);
6531   mp->entry_flags = ntohl (eflags);
6532   mp->grp_address_length = grp_address_length;
6533   mp->grp_address_length = ntohs (mp->grp_address_length);
6534
6535   if (is_ipv6)
6536     {
6537       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6538       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6539     }
6540   else
6541     {
6542       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6543       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6544
6545     }
6546
6547   /* send it... */
6548   S;
6549   /* Wait for a reply... */
6550   W;
6551
6552   /* Return the good/bad news */
6553   return (vam->retval);
6554 }
6555
6556 static int
6557 api_mpls_route_add_del (vat_main_t * vam)
6558 {
6559   unformat_input_t *i = vam->input;
6560   vl_api_mpls_route_add_del_t *mp;
6561   f64 timeout;
6562   u32 sw_if_index = ~0, table_id = 0;
6563   u8 create_table_if_needed = 0;
6564   u8 is_add = 1;
6565   u32 next_hop_weight = 1;
6566   u8 is_multipath = 0;
6567   u32 next_hop_table_id = 0;
6568   u8 next_hop_set = 0;
6569   ip4_address_t v4_next_hop_address = {
6570     .as_u32 = 0,
6571   };
6572   ip6_address_t v6_next_hop_address = { {0} };
6573   int count = 1;
6574   int j;
6575   f64 before = 0;
6576   u32 classify_table_index = ~0;
6577   u8 is_classify = 0;
6578   u8 resolve_host = 0, resolve_attached = 0;
6579   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6580   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6581   mpls_label_t *next_hop_out_label_stack = NULL;
6582   mpls_label_t local_label = MPLS_LABEL_INVALID;
6583   u8 is_eos = 0;
6584   u8 next_hop_proto_is_ip4 = 1;
6585
6586   /* Parse args required to build the message */
6587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6588     {
6589       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6590         ;
6591       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6592         ;
6593       else if (unformat (i, "%d", &local_label))
6594         ;
6595       else if (unformat (i, "eos"))
6596         is_eos = 1;
6597       else if (unformat (i, "non-eos"))
6598         is_eos = 0;
6599       else if (unformat (i, "via %U", unformat_ip4_address,
6600                          &v4_next_hop_address))
6601         {
6602           next_hop_set = 1;
6603           next_hop_proto_is_ip4 = 1;
6604         }
6605       else if (unformat (i, "via %U", unformat_ip6_address,
6606                          &v6_next_hop_address))
6607         {
6608           next_hop_set = 1;
6609           next_hop_proto_is_ip4 = 0;
6610         }
6611       else if (unformat (i, "weight %d", &next_hop_weight))
6612         ;
6613       else if (unformat (i, "create-table"))
6614         create_table_if_needed = 1;
6615       else if (unformat (i, "classify %d", &classify_table_index))
6616         {
6617           is_classify = 1;
6618         }
6619       else if (unformat (i, "del"))
6620         is_add = 0;
6621       else if (unformat (i, "add"))
6622         is_add = 1;
6623       else if (unformat (i, "resolve-via-host"))
6624         resolve_host = 1;
6625       else if (unformat (i, "resolve-via-attached"))
6626         resolve_attached = 1;
6627       else if (unformat (i, "multipath"))
6628         is_multipath = 1;
6629       else if (unformat (i, "count %d", &count))
6630         ;
6631       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6632         {
6633           next_hop_set = 1;
6634           next_hop_proto_is_ip4 = 1;
6635         }
6636       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6637         {
6638           next_hop_set = 1;
6639           next_hop_proto_is_ip4 = 0;
6640         }
6641       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6642         ;
6643       else if (unformat (i, "via-label %d", &next_hop_via_label))
6644         ;
6645       else if (unformat (i, "out-label %d", &next_hop_out_label))
6646         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6647       else
6648         {
6649           clib_warning ("parse error '%U'", format_unformat_error, i);
6650           return -99;
6651         }
6652     }
6653
6654   if (!next_hop_set && !is_classify)
6655     {
6656       errmsg ("next hop / classify not set");
6657       return -99;
6658     }
6659
6660   if (MPLS_LABEL_INVALID == local_label)
6661     {
6662       errmsg ("missing label");
6663       return -99;
6664     }
6665
6666   if (count > 1)
6667     {
6668       /* Turn on async mode */
6669       vam->async_mode = 1;
6670       vam->async_errors = 0;
6671       before = vat_time_now (vam);
6672     }
6673
6674   for (j = 0; j < count; j++)
6675     {
6676       /* Construct the API message */
6677       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6678           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6679
6680       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6681       mp->mr_table_id = ntohl (table_id);
6682       mp->mr_create_table_if_needed = create_table_if_needed;
6683
6684       mp->mr_is_add = is_add;
6685       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6686       mp->mr_is_classify = is_classify;
6687       mp->mr_is_multipath = is_multipath;
6688       mp->mr_is_resolve_host = resolve_host;
6689       mp->mr_is_resolve_attached = resolve_attached;
6690       mp->mr_next_hop_weight = next_hop_weight;
6691       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6692       mp->mr_classify_table_index = ntohl (classify_table_index);
6693       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6694       mp->mr_label = ntohl (local_label);
6695       mp->mr_eos = is_eos;
6696
6697       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6698       if (0 != mp->mr_next_hop_n_out_labels)
6699         {
6700           memcpy (mp->mr_next_hop_out_label_stack,
6701                   next_hop_out_label_stack,
6702                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6703           vec_free (next_hop_out_label_stack);
6704         }
6705
6706       if (next_hop_set)
6707         {
6708           if (next_hop_proto_is_ip4)
6709             {
6710               clib_memcpy (mp->mr_next_hop,
6711                            &v4_next_hop_address,
6712                            sizeof (v4_next_hop_address));
6713             }
6714           else
6715             {
6716               clib_memcpy (mp->mr_next_hop,
6717                            &v6_next_hop_address,
6718                            sizeof (v6_next_hop_address));
6719             }
6720         }
6721       local_label++;
6722
6723       /* send it... */
6724       S;
6725       /* If we receive SIGTERM, stop now... */
6726       if (vam->do_exit)
6727         break;
6728     }
6729
6730   /* When testing multiple add/del ops, use a control-ping to sync */
6731   if (count > 1)
6732     {
6733       vl_api_control_ping_t *mp;
6734       f64 after;
6735
6736       /* Shut off async mode */
6737       vam->async_mode = 0;
6738
6739       M (CONTROL_PING, control_ping);
6740       S;
6741
6742       timeout = vat_time_now (vam) + 1.0;
6743       while (vat_time_now (vam) < timeout)
6744         if (vam->result_ready == 1)
6745           goto out;
6746       vam->retval = -99;
6747
6748     out:
6749       if (vam->retval == -99)
6750         errmsg ("timeout");
6751
6752       if (vam->async_errors > 0)
6753         {
6754           errmsg ("%d asynchronous errors", vam->async_errors);
6755           vam->retval = -98;
6756         }
6757       vam->async_errors = 0;
6758       after = vat_time_now (vam);
6759
6760       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6761       if (j > 0)
6762         count = j;
6763
6764       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6765              count, after - before, count / (after - before));
6766     }
6767   else
6768     {
6769       /* Wait for a reply... */
6770       W;
6771     }
6772
6773   /* Return the good/bad news */
6774   return (vam->retval);
6775 }
6776
6777 static int
6778 api_mpls_ip_bind_unbind (vat_main_t * vam)
6779 {
6780   unformat_input_t *i = vam->input;
6781   vl_api_mpls_ip_bind_unbind_t *mp;
6782   f64 timeout;
6783   u32 ip_table_id = 0;
6784   u8 create_table_if_needed = 0;
6785   u8 is_bind = 1;
6786   u8 is_ip4 = 1;
6787   ip4_address_t v4_address;
6788   ip6_address_t v6_address;
6789   u32 address_length;
6790   u8 address_set = 0;
6791   mpls_label_t local_label = MPLS_LABEL_INVALID;
6792
6793   /* Parse args required to build the message */
6794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6795     {
6796       if (unformat (i, "%U/%d", unformat_ip4_address,
6797                     &v4_address, &address_length))
6798         {
6799           is_ip4 = 1;
6800           address_set = 1;
6801         }
6802       else if (unformat (i, "%U/%d", unformat_ip6_address,
6803                          &v6_address, &address_length))
6804         {
6805           is_ip4 = 0;
6806           address_set = 1;
6807         }
6808       else if (unformat (i, "%d", &local_label))
6809         ;
6810       else if (unformat (i, "create-table"))
6811         create_table_if_needed = 1;
6812       else if (unformat (i, "table-id %d", &ip_table_id))
6813         ;
6814       else if (unformat (i, "unbind"))
6815         is_bind = 0;
6816       else if (unformat (i, "bind"))
6817         is_bind = 1;
6818       else
6819         {
6820           clib_warning ("parse error '%U'", format_unformat_error, i);
6821           return -99;
6822         }
6823     }
6824
6825   if (!address_set)
6826     {
6827       errmsg ("IP addres not set");
6828       return -99;
6829     }
6830
6831   if (MPLS_LABEL_INVALID == local_label)
6832     {
6833       errmsg ("missing label");
6834       return -99;
6835     }
6836
6837   /* Construct the API message */
6838   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6839
6840   mp->mb_create_table_if_needed = create_table_if_needed;
6841   mp->mb_is_bind = is_bind;
6842   mp->mb_is_ip4 = is_ip4;
6843   mp->mb_ip_table_id = ntohl (ip_table_id);
6844   mp->mb_mpls_table_id = 0;
6845   mp->mb_label = ntohl (local_label);
6846   mp->mb_address_length = address_length;
6847
6848   if (is_ip4)
6849     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6850   else
6851     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6852
6853   /* send it... */
6854   S;
6855
6856   /* Wait for a reply... */
6857   W;
6858 }
6859
6860 static int
6861 api_proxy_arp_add_del (vat_main_t * vam)
6862 {
6863   unformat_input_t *i = vam->input;
6864   vl_api_proxy_arp_add_del_t *mp;
6865   f64 timeout;
6866   u32 vrf_id = 0;
6867   u8 is_add = 1;
6868   ip4_address_t lo, hi;
6869   u8 range_set = 0;
6870
6871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6872     {
6873       if (unformat (i, "vrf %d", &vrf_id))
6874         ;
6875       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6876                          unformat_ip4_address, &hi))
6877         range_set = 1;
6878       else if (unformat (i, "del"))
6879         is_add = 0;
6880       else
6881         {
6882           clib_warning ("parse error '%U'", format_unformat_error, i);
6883           return -99;
6884         }
6885     }
6886
6887   if (range_set == 0)
6888     {
6889       errmsg ("address range not set");
6890       return -99;
6891     }
6892
6893   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6894
6895   mp->vrf_id = ntohl (vrf_id);
6896   mp->is_add = is_add;
6897   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6898   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6899
6900   S;
6901   W;
6902   /* NOTREACHED */
6903   return 0;
6904 }
6905
6906 static int
6907 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6908 {
6909   unformat_input_t *i = vam->input;
6910   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6911   f64 timeout;
6912   u32 sw_if_index;
6913   u8 enable = 1;
6914   u8 sw_if_index_set = 0;
6915
6916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6917     {
6918       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6919         sw_if_index_set = 1;
6920       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6921         sw_if_index_set = 1;
6922       else if (unformat (i, "enable"))
6923         enable = 1;
6924       else if (unformat (i, "disable"))
6925         enable = 0;
6926       else
6927         {
6928           clib_warning ("parse error '%U'", format_unformat_error, i);
6929           return -99;
6930         }
6931     }
6932
6933   if (sw_if_index_set == 0)
6934     {
6935       errmsg ("missing interface name or sw_if_index");
6936       return -99;
6937     }
6938
6939   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6940
6941   mp->sw_if_index = ntohl (sw_if_index);
6942   mp->enable_disable = enable;
6943
6944   S;
6945   W;
6946   /* NOTREACHED */
6947   return 0;
6948 }
6949
6950 static int
6951 api_mpls_tunnel_add_del (vat_main_t * vam)
6952 {
6953   unformat_input_t *i = vam->input;
6954   vl_api_mpls_tunnel_add_del_t *mp;
6955   f64 timeout;
6956
6957   u8 is_add = 1;
6958   u8 l2_only = 0;
6959   u32 sw_if_index = ~0;
6960   u32 next_hop_sw_if_index = ~0;
6961   u32 next_hop_proto_is_ip4 = 1;
6962
6963   u32 next_hop_table_id = 0;
6964   ip4_address_t v4_next_hop_address = {
6965     .as_u32 = 0,
6966   };
6967   ip6_address_t v6_next_hop_address = { {0} };
6968   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6969
6970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6971     {
6972       if (unformat (i, "add"))
6973         is_add = 1;
6974       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6975         is_add = 0;
6976       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6977         ;
6978       else if (unformat (i, "via %U",
6979                          unformat_ip4_address, &v4_next_hop_address))
6980         {
6981           next_hop_proto_is_ip4 = 1;
6982         }
6983       else if (unformat (i, "via %U",
6984                          unformat_ip6_address, &v6_next_hop_address))
6985         {
6986           next_hop_proto_is_ip4 = 0;
6987         }
6988       else if (unformat (i, "l2-only"))
6989         l2_only = 1;
6990       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6991         ;
6992       else if (unformat (i, "out-label %d", &next_hop_out_label))
6993         vec_add1 (labels, ntohl (next_hop_out_label));
6994       else
6995         {
6996           clib_warning ("parse error '%U'", format_unformat_error, i);
6997           return -99;
6998         }
6999     }
7000
7001   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
7002       sizeof (mpls_label_t) * vec_len (labels));
7003
7004   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7005   mp->mt_sw_if_index = ntohl (sw_if_index);
7006   mp->mt_is_add = is_add;
7007   mp->mt_l2_only = l2_only;
7008   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7009   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7010
7011   mp->mt_next_hop_n_out_labels = vec_len (labels);
7012
7013   if (0 != mp->mt_next_hop_n_out_labels)
7014     {
7015       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7016                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7017       vec_free (labels);
7018     }
7019
7020   if (next_hop_proto_is_ip4)
7021     {
7022       clib_memcpy (mp->mt_next_hop,
7023                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7024     }
7025   else
7026     {
7027       clib_memcpy (mp->mt_next_hop,
7028                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7029     }
7030
7031   S;
7032   W;
7033   /* NOTREACHED */
7034   return 0;
7035 }
7036
7037 static int
7038 api_sw_interface_set_unnumbered (vat_main_t * vam)
7039 {
7040   unformat_input_t *i = vam->input;
7041   vl_api_sw_interface_set_unnumbered_t *mp;
7042   f64 timeout;
7043   u32 sw_if_index;
7044   u32 unnum_sw_index = ~0;
7045   u8 is_add = 1;
7046   u8 sw_if_index_set = 0;
7047
7048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7049     {
7050       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7051         sw_if_index_set = 1;
7052       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7053         sw_if_index_set = 1;
7054       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7055         ;
7056       else if (unformat (i, "del"))
7057         is_add = 0;
7058       else
7059         {
7060           clib_warning ("parse error '%U'", format_unformat_error, i);
7061           return -99;
7062         }
7063     }
7064
7065   if (sw_if_index_set == 0)
7066     {
7067       errmsg ("missing interface name or sw_if_index");
7068       return -99;
7069     }
7070
7071   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
7072
7073   mp->sw_if_index = ntohl (sw_if_index);
7074   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7075   mp->is_add = is_add;
7076
7077   S;
7078   W;
7079   /* NOTREACHED */
7080   return 0;
7081 }
7082
7083 static int
7084 api_ip_neighbor_add_del (vat_main_t * vam)
7085 {
7086   unformat_input_t *i = vam->input;
7087   vl_api_ip_neighbor_add_del_t *mp;
7088   f64 timeout;
7089   u32 sw_if_index;
7090   u8 sw_if_index_set = 0;
7091   u32 vrf_id = 0;
7092   u8 is_add = 1;
7093   u8 is_static = 0;
7094   u8 mac_address[6];
7095   u8 mac_set = 0;
7096   u8 v4_address_set = 0;
7097   u8 v6_address_set = 0;
7098   ip4_address_t v4address;
7099   ip6_address_t v6address;
7100
7101   memset (mac_address, 0, sizeof (mac_address));
7102
7103   /* Parse args required to build the message */
7104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7105     {
7106       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7107         {
7108           mac_set = 1;
7109         }
7110       else if (unformat (i, "del"))
7111         is_add = 0;
7112       else
7113         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7114         sw_if_index_set = 1;
7115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7116         sw_if_index_set = 1;
7117       else if (unformat (i, "is_static"))
7118         is_static = 1;
7119       else if (unformat (i, "vrf %d", &vrf_id))
7120         ;
7121       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7122         v4_address_set = 1;
7123       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7124         v6_address_set = 1;
7125       else
7126         {
7127           clib_warning ("parse error '%U'", format_unformat_error, i);
7128           return -99;
7129         }
7130     }
7131
7132   if (sw_if_index_set == 0)
7133     {
7134       errmsg ("missing interface name or sw_if_index");
7135       return -99;
7136     }
7137   if (v4_address_set && v6_address_set)
7138     {
7139       errmsg ("both v4 and v6 addresses set");
7140       return -99;
7141     }
7142   if (!v4_address_set && !v6_address_set)
7143     {
7144       errmsg ("no address set");
7145       return -99;
7146     }
7147
7148   /* Construct the API message */
7149   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
7150
7151   mp->sw_if_index = ntohl (sw_if_index);
7152   mp->is_add = is_add;
7153   mp->vrf_id = ntohl (vrf_id);
7154   mp->is_static = is_static;
7155   if (mac_set)
7156     clib_memcpy (mp->mac_address, mac_address, 6);
7157   if (v6_address_set)
7158     {
7159       mp->is_ipv6 = 1;
7160       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7161     }
7162   else
7163     {
7164       /* mp->is_ipv6 = 0; via memset in M macro above */
7165       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7166     }
7167
7168   /* send it... */
7169   S;
7170
7171   /* Wait for a reply, return good/bad news  */
7172   W;
7173
7174   /* NOTREACHED */
7175   return 0;
7176 }
7177
7178 static int
7179 api_reset_vrf (vat_main_t * vam)
7180 {
7181   unformat_input_t *i = vam->input;
7182   vl_api_reset_vrf_t *mp;
7183   f64 timeout;
7184   u32 vrf_id = 0;
7185   u8 is_ipv6 = 0;
7186   u8 vrf_id_set = 0;
7187
7188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7189     {
7190       if (unformat (i, "vrf %d", &vrf_id))
7191         vrf_id_set = 1;
7192       else if (unformat (i, "ipv6"))
7193         is_ipv6 = 1;
7194       else
7195         {
7196           clib_warning ("parse error '%U'", format_unformat_error, i);
7197           return -99;
7198         }
7199     }
7200
7201   if (vrf_id_set == 0)
7202     {
7203       errmsg ("missing vrf id");
7204       return -99;
7205     }
7206
7207   M (RESET_VRF, reset_vrf);
7208
7209   mp->vrf_id = ntohl (vrf_id);
7210   mp->is_ipv6 = is_ipv6;
7211
7212   S;
7213   W;
7214   /* NOTREACHED */
7215   return 0;
7216 }
7217
7218 static int
7219 api_create_vlan_subif (vat_main_t * vam)
7220 {
7221   unformat_input_t *i = vam->input;
7222   vl_api_create_vlan_subif_t *mp;
7223   f64 timeout;
7224   u32 sw_if_index;
7225   u8 sw_if_index_set = 0;
7226   u32 vlan_id;
7227   u8 vlan_id_set = 0;
7228
7229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7230     {
7231       if (unformat (i, "sw_if_index %d", &sw_if_index))
7232         sw_if_index_set = 1;
7233       else
7234         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7235         sw_if_index_set = 1;
7236       else if (unformat (i, "vlan %d", &vlan_id))
7237         vlan_id_set = 1;
7238       else
7239         {
7240           clib_warning ("parse error '%U'", format_unformat_error, i);
7241           return -99;
7242         }
7243     }
7244
7245   if (sw_if_index_set == 0)
7246     {
7247       errmsg ("missing interface name or sw_if_index");
7248       return -99;
7249     }
7250
7251   if (vlan_id_set == 0)
7252     {
7253       errmsg ("missing vlan_id");
7254       return -99;
7255     }
7256   M (CREATE_VLAN_SUBIF, create_vlan_subif);
7257
7258   mp->sw_if_index = ntohl (sw_if_index);
7259   mp->vlan_id = ntohl (vlan_id);
7260
7261   S;
7262   W;
7263   /* NOTREACHED */
7264   return 0;
7265 }
7266
7267 #define foreach_create_subif_bit                \
7268 _(no_tags)                                      \
7269 _(one_tag)                                      \
7270 _(two_tags)                                     \
7271 _(dot1ad)                                       \
7272 _(exact_match)                                  \
7273 _(default_sub)                                  \
7274 _(outer_vlan_id_any)                            \
7275 _(inner_vlan_id_any)
7276
7277 static int
7278 api_create_subif (vat_main_t * vam)
7279 {
7280   unformat_input_t *i = vam->input;
7281   vl_api_create_subif_t *mp;
7282   f64 timeout;
7283   u32 sw_if_index;
7284   u8 sw_if_index_set = 0;
7285   u32 sub_id;
7286   u8 sub_id_set = 0;
7287   u32 no_tags = 0;
7288   u32 one_tag = 0;
7289   u32 two_tags = 0;
7290   u32 dot1ad = 0;
7291   u32 exact_match = 0;
7292   u32 default_sub = 0;
7293   u32 outer_vlan_id_any = 0;
7294   u32 inner_vlan_id_any = 0;
7295   u32 tmp;
7296   u16 outer_vlan_id = 0;
7297   u16 inner_vlan_id = 0;
7298
7299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7300     {
7301       if (unformat (i, "sw_if_index %d", &sw_if_index))
7302         sw_if_index_set = 1;
7303       else
7304         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7305         sw_if_index_set = 1;
7306       else if (unformat (i, "sub_id %d", &sub_id))
7307         sub_id_set = 1;
7308       else if (unformat (i, "outer_vlan_id %d", &tmp))
7309         outer_vlan_id = tmp;
7310       else if (unformat (i, "inner_vlan_id %d", &tmp))
7311         inner_vlan_id = tmp;
7312
7313 #define _(a) else if (unformat (i, #a)) a = 1 ;
7314       foreach_create_subif_bit
7315 #undef _
7316         else
7317         {
7318           clib_warning ("parse error '%U'", format_unformat_error, i);
7319           return -99;
7320         }
7321     }
7322
7323   if (sw_if_index_set == 0)
7324     {
7325       errmsg ("missing interface name or sw_if_index");
7326       return -99;
7327     }
7328
7329   if (sub_id_set == 0)
7330     {
7331       errmsg ("missing sub_id");
7332       return -99;
7333     }
7334   M (CREATE_SUBIF, create_subif);
7335
7336   mp->sw_if_index = ntohl (sw_if_index);
7337   mp->sub_id = ntohl (sub_id);
7338
7339 #define _(a) mp->a = a;
7340   foreach_create_subif_bit;
7341 #undef _
7342
7343   mp->outer_vlan_id = ntohs (outer_vlan_id);
7344   mp->inner_vlan_id = ntohs (inner_vlan_id);
7345
7346   S;
7347   W;
7348   /* NOTREACHED */
7349   return 0;
7350 }
7351
7352 static int
7353 api_oam_add_del (vat_main_t * vam)
7354 {
7355   unformat_input_t *i = vam->input;
7356   vl_api_oam_add_del_t *mp;
7357   f64 timeout;
7358   u32 vrf_id = 0;
7359   u8 is_add = 1;
7360   ip4_address_t src, dst;
7361   u8 src_set = 0;
7362   u8 dst_set = 0;
7363
7364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7365     {
7366       if (unformat (i, "vrf %d", &vrf_id))
7367         ;
7368       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7369         src_set = 1;
7370       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7371         dst_set = 1;
7372       else if (unformat (i, "del"))
7373         is_add = 0;
7374       else
7375         {
7376           clib_warning ("parse error '%U'", format_unformat_error, i);
7377           return -99;
7378         }
7379     }
7380
7381   if (src_set == 0)
7382     {
7383       errmsg ("missing src addr");
7384       return -99;
7385     }
7386
7387   if (dst_set == 0)
7388     {
7389       errmsg ("missing dst addr");
7390       return -99;
7391     }
7392
7393   M (OAM_ADD_DEL, oam_add_del);
7394
7395   mp->vrf_id = ntohl (vrf_id);
7396   mp->is_add = is_add;
7397   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7398   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7399
7400   S;
7401   W;
7402   /* NOTREACHED */
7403   return 0;
7404 }
7405
7406 static int
7407 api_reset_fib (vat_main_t * vam)
7408 {
7409   unformat_input_t *i = vam->input;
7410   vl_api_reset_fib_t *mp;
7411   f64 timeout;
7412   u32 vrf_id = 0;
7413   u8 is_ipv6 = 0;
7414   u8 vrf_id_set = 0;
7415
7416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7417     {
7418       if (unformat (i, "vrf %d", &vrf_id))
7419         vrf_id_set = 1;
7420       else if (unformat (i, "ipv6"))
7421         is_ipv6 = 1;
7422       else
7423         {
7424           clib_warning ("parse error '%U'", format_unformat_error, i);
7425           return -99;
7426         }
7427     }
7428
7429   if (vrf_id_set == 0)
7430     {
7431       errmsg ("missing vrf id");
7432       return -99;
7433     }
7434
7435   M (RESET_FIB, reset_fib);
7436
7437   mp->vrf_id = ntohl (vrf_id);
7438   mp->is_ipv6 = is_ipv6;
7439
7440   S;
7441   W;
7442   /* NOTREACHED */
7443   return 0;
7444 }
7445
7446 static int
7447 api_dhcp_proxy_config (vat_main_t * vam)
7448 {
7449   unformat_input_t *i = vam->input;
7450   vl_api_dhcp_proxy_config_t *mp;
7451   f64 timeout;
7452   u32 vrf_id = 0;
7453   u8 is_add = 1;
7454   u8 insert_cid = 1;
7455   u8 v4_address_set = 0;
7456   u8 v6_address_set = 0;
7457   ip4_address_t v4address;
7458   ip6_address_t v6address;
7459   u8 v4_src_address_set = 0;
7460   u8 v6_src_address_set = 0;
7461   ip4_address_t v4srcaddress;
7462   ip6_address_t v6srcaddress;
7463
7464   /* Parse args required to build the message */
7465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7466     {
7467       if (unformat (i, "del"))
7468         is_add = 0;
7469       else if (unformat (i, "vrf %d", &vrf_id))
7470         ;
7471       else if (unformat (i, "insert-cid %d", &insert_cid))
7472         ;
7473       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7474         v4_address_set = 1;
7475       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7476         v6_address_set = 1;
7477       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7478         v4_src_address_set = 1;
7479       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7480         v6_src_address_set = 1;
7481       else
7482         break;
7483     }
7484
7485   if (v4_address_set && v6_address_set)
7486     {
7487       errmsg ("both v4 and v6 server addresses set");
7488       return -99;
7489     }
7490   if (!v4_address_set && !v6_address_set)
7491     {
7492       errmsg ("no server addresses set");
7493       return -99;
7494     }
7495
7496   if (v4_src_address_set && v6_src_address_set)
7497     {
7498       errmsg ("both v4 and v6  src addresses set");
7499       return -99;
7500     }
7501   if (!v4_src_address_set && !v6_src_address_set)
7502     {
7503       errmsg ("no src addresses set");
7504       return -99;
7505     }
7506
7507   if (!(v4_src_address_set && v4_address_set) &&
7508       !(v6_src_address_set && v6_address_set))
7509     {
7510       errmsg ("no matching server and src addresses set");
7511       return -99;
7512     }
7513
7514   /* Construct the API message */
7515   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7516
7517   mp->insert_circuit_id = insert_cid;
7518   mp->is_add = is_add;
7519   mp->vrf_id = ntohl (vrf_id);
7520   if (v6_address_set)
7521     {
7522       mp->is_ipv6 = 1;
7523       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7524       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7525     }
7526   else
7527     {
7528       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7529       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7530     }
7531
7532   /* send it... */
7533   S;
7534
7535   /* Wait for a reply, return good/bad news  */
7536   W;
7537   /* NOTREACHED */
7538   return 0;
7539 }
7540
7541 static int
7542 api_dhcp_proxy_config_2 (vat_main_t * vam)
7543 {
7544   unformat_input_t *i = vam->input;
7545   vl_api_dhcp_proxy_config_2_t *mp;
7546   f64 timeout;
7547   u32 rx_vrf_id = 0;
7548   u32 server_vrf_id = 0;
7549   u8 is_add = 1;
7550   u8 insert_cid = 1;
7551   u8 v4_address_set = 0;
7552   u8 v6_address_set = 0;
7553   ip4_address_t v4address;
7554   ip6_address_t v6address;
7555   u8 v4_src_address_set = 0;
7556   u8 v6_src_address_set = 0;
7557   ip4_address_t v4srcaddress;
7558   ip6_address_t v6srcaddress;
7559
7560   /* Parse args required to build the message */
7561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7562     {
7563       if (unformat (i, "del"))
7564         is_add = 0;
7565       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7566         ;
7567       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7568         ;
7569       else if (unformat (i, "insert-cid %d", &insert_cid))
7570         ;
7571       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7572         v4_address_set = 1;
7573       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7574         v6_address_set = 1;
7575       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7576         v4_src_address_set = 1;
7577       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7578         v6_src_address_set = 1;
7579       else
7580         break;
7581     }
7582
7583   if (v4_address_set && v6_address_set)
7584     {
7585       errmsg ("both v4 and v6 server addresses set");
7586       return -99;
7587     }
7588   if (!v4_address_set && !v6_address_set)
7589     {
7590       errmsg ("no server addresses set");
7591       return -99;
7592     }
7593
7594   if (v4_src_address_set && v6_src_address_set)
7595     {
7596       errmsg ("both v4 and v6  src addresses set");
7597       return -99;
7598     }
7599   if (!v4_src_address_set && !v6_src_address_set)
7600     {
7601       errmsg ("no src addresses set");
7602       return -99;
7603     }
7604
7605   if (!(v4_src_address_set && v4_address_set) &&
7606       !(v6_src_address_set && v6_address_set))
7607     {
7608       errmsg ("no matching server and src addresses set");
7609       return -99;
7610     }
7611
7612   /* Construct the API message */
7613   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7614
7615   mp->insert_circuit_id = insert_cid;
7616   mp->is_add = is_add;
7617   mp->rx_vrf_id = ntohl (rx_vrf_id);
7618   mp->server_vrf_id = ntohl (server_vrf_id);
7619   if (v6_address_set)
7620     {
7621       mp->is_ipv6 = 1;
7622       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7623       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7624     }
7625   else
7626     {
7627       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7628       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7629     }
7630
7631   /* send it... */
7632   S;
7633
7634   /* Wait for a reply, return good/bad news  */
7635   W;
7636   /* NOTREACHED */
7637   return 0;
7638 }
7639
7640 static int
7641 api_dhcp_proxy_set_vss (vat_main_t * vam)
7642 {
7643   unformat_input_t *i = vam->input;
7644   vl_api_dhcp_proxy_set_vss_t *mp;
7645   f64 timeout;
7646   u8 is_ipv6 = 0;
7647   u8 is_add = 1;
7648   u32 tbl_id;
7649   u8 tbl_id_set = 0;
7650   u32 oui;
7651   u8 oui_set = 0;
7652   u32 fib_id;
7653   u8 fib_id_set = 0;
7654
7655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7656     {
7657       if (unformat (i, "tbl_id %d", &tbl_id))
7658         tbl_id_set = 1;
7659       if (unformat (i, "fib_id %d", &fib_id))
7660         fib_id_set = 1;
7661       if (unformat (i, "oui %d", &oui))
7662         oui_set = 1;
7663       else if (unformat (i, "ipv6"))
7664         is_ipv6 = 1;
7665       else if (unformat (i, "del"))
7666         is_add = 0;
7667       else
7668         {
7669           clib_warning ("parse error '%U'", format_unformat_error, i);
7670           return -99;
7671         }
7672     }
7673
7674   if (tbl_id_set == 0)
7675     {
7676       errmsg ("missing tbl id");
7677       return -99;
7678     }
7679
7680   if (fib_id_set == 0)
7681     {
7682       errmsg ("missing fib id");
7683       return -99;
7684     }
7685   if (oui_set == 0)
7686     {
7687       errmsg ("missing oui");
7688       return -99;
7689     }
7690
7691   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7692   mp->tbl_id = ntohl (tbl_id);
7693   mp->fib_id = ntohl (fib_id);
7694   mp->oui = ntohl (oui);
7695   mp->is_ipv6 = is_ipv6;
7696   mp->is_add = is_add;
7697
7698   S;
7699   W;
7700   /* NOTREACHED */
7701   return 0;
7702 }
7703
7704 static int
7705 api_dhcp_client_config (vat_main_t * vam)
7706 {
7707   unformat_input_t *i = vam->input;
7708   vl_api_dhcp_client_config_t *mp;
7709   f64 timeout;
7710   u32 sw_if_index;
7711   u8 sw_if_index_set = 0;
7712   u8 is_add = 1;
7713   u8 *hostname = 0;
7714   u8 disable_event = 0;
7715
7716   /* Parse args required to build the message */
7717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7718     {
7719       if (unformat (i, "del"))
7720         is_add = 0;
7721       else
7722         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7723         sw_if_index_set = 1;
7724       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7725         sw_if_index_set = 1;
7726       else if (unformat (i, "hostname %s", &hostname))
7727         ;
7728       else if (unformat (i, "disable_event"))
7729         disable_event = 1;
7730       else
7731         break;
7732     }
7733
7734   if (sw_if_index_set == 0)
7735     {
7736       errmsg ("missing interface name or sw_if_index");
7737       return -99;
7738     }
7739
7740   if (vec_len (hostname) > 63)
7741     {
7742       errmsg ("hostname too long");
7743     }
7744   vec_add1 (hostname, 0);
7745
7746   /* Construct the API message */
7747   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7748
7749   mp->sw_if_index = ntohl (sw_if_index);
7750   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7751   vec_free (hostname);
7752   mp->is_add = is_add;
7753   mp->want_dhcp_event = disable_event ? 0 : 1;
7754   mp->pid = getpid ();
7755
7756   /* send it... */
7757   S;
7758
7759   /* Wait for a reply, return good/bad news  */
7760   W;
7761   /* NOTREACHED */
7762   return 0;
7763 }
7764
7765 static int
7766 api_set_ip_flow_hash (vat_main_t * vam)
7767 {
7768   unformat_input_t *i = vam->input;
7769   vl_api_set_ip_flow_hash_t *mp;
7770   f64 timeout;
7771   u32 vrf_id = 0;
7772   u8 is_ipv6 = 0;
7773   u8 vrf_id_set = 0;
7774   u8 src = 0;
7775   u8 dst = 0;
7776   u8 sport = 0;
7777   u8 dport = 0;
7778   u8 proto = 0;
7779   u8 reverse = 0;
7780
7781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7782     {
7783       if (unformat (i, "vrf %d", &vrf_id))
7784         vrf_id_set = 1;
7785       else if (unformat (i, "ipv6"))
7786         is_ipv6 = 1;
7787       else if (unformat (i, "src"))
7788         src = 1;
7789       else if (unformat (i, "dst"))
7790         dst = 1;
7791       else if (unformat (i, "sport"))
7792         sport = 1;
7793       else if (unformat (i, "dport"))
7794         dport = 1;
7795       else if (unformat (i, "proto"))
7796         proto = 1;
7797       else if (unformat (i, "reverse"))
7798         reverse = 1;
7799
7800       else
7801         {
7802           clib_warning ("parse error '%U'", format_unformat_error, i);
7803           return -99;
7804         }
7805     }
7806
7807   if (vrf_id_set == 0)
7808     {
7809       errmsg ("missing vrf id");
7810       return -99;
7811     }
7812
7813   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7814   mp->src = src;
7815   mp->dst = dst;
7816   mp->sport = sport;
7817   mp->dport = dport;
7818   mp->proto = proto;
7819   mp->reverse = reverse;
7820   mp->vrf_id = ntohl (vrf_id);
7821   mp->is_ipv6 = is_ipv6;
7822
7823   S;
7824   W;
7825   /* NOTREACHED */
7826   return 0;
7827 }
7828
7829 static int
7830 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7831 {
7832   unformat_input_t *i = vam->input;
7833   vl_api_sw_interface_ip6_enable_disable_t *mp;
7834   f64 timeout;
7835   u32 sw_if_index;
7836   u8 sw_if_index_set = 0;
7837   u8 enable = 0;
7838
7839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7840     {
7841       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7842         sw_if_index_set = 1;
7843       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7844         sw_if_index_set = 1;
7845       else if (unformat (i, "enable"))
7846         enable = 1;
7847       else if (unformat (i, "disable"))
7848         enable = 0;
7849       else
7850         {
7851           clib_warning ("parse error '%U'", format_unformat_error, i);
7852           return -99;
7853         }
7854     }
7855
7856   if (sw_if_index_set == 0)
7857     {
7858       errmsg ("missing interface name or sw_if_index");
7859       return -99;
7860     }
7861
7862   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7863
7864   mp->sw_if_index = ntohl (sw_if_index);
7865   mp->enable = enable;
7866
7867   S;
7868   W;
7869   /* NOTREACHED */
7870   return 0;
7871 }
7872
7873 static int
7874 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7875 {
7876   unformat_input_t *i = vam->input;
7877   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7878   f64 timeout;
7879   u32 sw_if_index;
7880   u8 sw_if_index_set = 0;
7881   u8 v6_address_set = 0;
7882   ip6_address_t v6address;
7883
7884   /* Parse args required to build the message */
7885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7886     {
7887       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7888         sw_if_index_set = 1;
7889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7890         sw_if_index_set = 1;
7891       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7892         v6_address_set = 1;
7893       else
7894         break;
7895     }
7896
7897   if (sw_if_index_set == 0)
7898     {
7899       errmsg ("missing interface name or sw_if_index");
7900       return -99;
7901     }
7902   if (!v6_address_set)
7903     {
7904       errmsg ("no address set");
7905       return -99;
7906     }
7907
7908   /* Construct the API message */
7909   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7910      sw_interface_ip6_set_link_local_address);
7911
7912   mp->sw_if_index = ntohl (sw_if_index);
7913   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7914
7915   /* send it... */
7916   S;
7917
7918   /* Wait for a reply, return good/bad news  */
7919   W;
7920
7921   /* NOTREACHED */
7922   return 0;
7923 }
7924
7925
7926 static int
7927 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7928 {
7929   unformat_input_t *i = vam->input;
7930   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7931   f64 timeout;
7932   u32 sw_if_index;
7933   u8 sw_if_index_set = 0;
7934   u32 address_length = 0;
7935   u8 v6_address_set = 0;
7936   ip6_address_t v6address;
7937   u8 use_default = 0;
7938   u8 no_advertise = 0;
7939   u8 off_link = 0;
7940   u8 no_autoconfig = 0;
7941   u8 no_onlink = 0;
7942   u8 is_no = 0;
7943   u32 val_lifetime = 0;
7944   u32 pref_lifetime = 0;
7945
7946   /* Parse args required to build the message */
7947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7948     {
7949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7950         sw_if_index_set = 1;
7951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7952         sw_if_index_set = 1;
7953       else if (unformat (i, "%U/%d",
7954                          unformat_ip6_address, &v6address, &address_length))
7955         v6_address_set = 1;
7956       else if (unformat (i, "val_life %d", &val_lifetime))
7957         ;
7958       else if (unformat (i, "pref_life %d", &pref_lifetime))
7959         ;
7960       else if (unformat (i, "def"))
7961         use_default = 1;
7962       else if (unformat (i, "noadv"))
7963         no_advertise = 1;
7964       else if (unformat (i, "offl"))
7965         off_link = 1;
7966       else if (unformat (i, "noauto"))
7967         no_autoconfig = 1;
7968       else if (unformat (i, "nolink"))
7969         no_onlink = 1;
7970       else if (unformat (i, "isno"))
7971         is_no = 1;
7972       else
7973         {
7974           clib_warning ("parse error '%U'", format_unformat_error, i);
7975           return -99;
7976         }
7977     }
7978
7979   if (sw_if_index_set == 0)
7980     {
7981       errmsg ("missing interface name or sw_if_index");
7982       return -99;
7983     }
7984   if (!v6_address_set)
7985     {
7986       errmsg ("no address set");
7987       return -99;
7988     }
7989
7990   /* Construct the API message */
7991   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7992
7993   mp->sw_if_index = ntohl (sw_if_index);
7994   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7995   mp->address_length = address_length;
7996   mp->use_default = use_default;
7997   mp->no_advertise = no_advertise;
7998   mp->off_link = off_link;
7999   mp->no_autoconfig = no_autoconfig;
8000   mp->no_onlink = no_onlink;
8001   mp->is_no = is_no;
8002   mp->val_lifetime = ntohl (val_lifetime);
8003   mp->pref_lifetime = ntohl (pref_lifetime);
8004
8005   /* send it... */
8006   S;
8007
8008   /* Wait for a reply, return good/bad news  */
8009   W;
8010
8011   /* NOTREACHED */
8012   return 0;
8013 }
8014
8015 static int
8016 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8017 {
8018   unformat_input_t *i = vam->input;
8019   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8020   f64 timeout;
8021   u32 sw_if_index;
8022   u8 sw_if_index_set = 0;
8023   u8 suppress = 0;
8024   u8 managed = 0;
8025   u8 other = 0;
8026   u8 ll_option = 0;
8027   u8 send_unicast = 0;
8028   u8 cease = 0;
8029   u8 is_no = 0;
8030   u8 default_router = 0;
8031   u32 max_interval = 0;
8032   u32 min_interval = 0;
8033   u32 lifetime = 0;
8034   u32 initial_count = 0;
8035   u32 initial_interval = 0;
8036
8037
8038   /* Parse args required to build the message */
8039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8040     {
8041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8042         sw_if_index_set = 1;
8043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8044         sw_if_index_set = 1;
8045       else if (unformat (i, "maxint %d", &max_interval))
8046         ;
8047       else if (unformat (i, "minint %d", &min_interval))
8048         ;
8049       else if (unformat (i, "life %d", &lifetime))
8050         ;
8051       else if (unformat (i, "count %d", &initial_count))
8052         ;
8053       else if (unformat (i, "interval %d", &initial_interval))
8054         ;
8055       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8056         suppress = 1;
8057       else if (unformat (i, "managed"))
8058         managed = 1;
8059       else if (unformat (i, "other"))
8060         other = 1;
8061       else if (unformat (i, "ll"))
8062         ll_option = 1;
8063       else if (unformat (i, "send"))
8064         send_unicast = 1;
8065       else if (unformat (i, "cease"))
8066         cease = 1;
8067       else if (unformat (i, "isno"))
8068         is_no = 1;
8069       else if (unformat (i, "def"))
8070         default_router = 1;
8071       else
8072         {
8073           clib_warning ("parse error '%U'", format_unformat_error, i);
8074           return -99;
8075         }
8076     }
8077
8078   if (sw_if_index_set == 0)
8079     {
8080       errmsg ("missing interface name or sw_if_index");
8081       return -99;
8082     }
8083
8084   /* Construct the API message */
8085   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
8086
8087   mp->sw_if_index = ntohl (sw_if_index);
8088   mp->max_interval = ntohl (max_interval);
8089   mp->min_interval = ntohl (min_interval);
8090   mp->lifetime = ntohl (lifetime);
8091   mp->initial_count = ntohl (initial_count);
8092   mp->initial_interval = ntohl (initial_interval);
8093   mp->suppress = suppress;
8094   mp->managed = managed;
8095   mp->other = other;
8096   mp->ll_option = ll_option;
8097   mp->send_unicast = send_unicast;
8098   mp->cease = cease;
8099   mp->is_no = is_no;
8100   mp->default_router = default_router;
8101
8102   /* send it... */
8103   S;
8104
8105   /* Wait for a reply, return good/bad news  */
8106   W;
8107
8108   /* NOTREACHED */
8109   return 0;
8110 }
8111
8112 static int
8113 api_set_arp_neighbor_limit (vat_main_t * vam)
8114 {
8115   unformat_input_t *i = vam->input;
8116   vl_api_set_arp_neighbor_limit_t *mp;
8117   f64 timeout;
8118   u32 arp_nbr_limit;
8119   u8 limit_set = 0;
8120   u8 is_ipv6 = 0;
8121
8122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8123     {
8124       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8125         limit_set = 1;
8126       else if (unformat (i, "ipv6"))
8127         is_ipv6 = 1;
8128       else
8129         {
8130           clib_warning ("parse error '%U'", format_unformat_error, i);
8131           return -99;
8132         }
8133     }
8134
8135   if (limit_set == 0)
8136     {
8137       errmsg ("missing limit value");
8138       return -99;
8139     }
8140
8141   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
8142
8143   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8144   mp->is_ipv6 = is_ipv6;
8145
8146   S;
8147   W;
8148   /* NOTREACHED */
8149   return 0;
8150 }
8151
8152 static int
8153 api_l2_patch_add_del (vat_main_t * vam)
8154 {
8155   unformat_input_t *i = vam->input;
8156   vl_api_l2_patch_add_del_t *mp;
8157   f64 timeout;
8158   u32 rx_sw_if_index;
8159   u8 rx_sw_if_index_set = 0;
8160   u32 tx_sw_if_index;
8161   u8 tx_sw_if_index_set = 0;
8162   u8 is_add = 1;
8163
8164   /* Parse args required to build the message */
8165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8166     {
8167       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8168         rx_sw_if_index_set = 1;
8169       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8170         tx_sw_if_index_set = 1;
8171       else if (unformat (i, "rx"))
8172         {
8173           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8174             {
8175               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8176                             &rx_sw_if_index))
8177                 rx_sw_if_index_set = 1;
8178             }
8179           else
8180             break;
8181         }
8182       else if (unformat (i, "tx"))
8183         {
8184           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8185             {
8186               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8187                             &tx_sw_if_index))
8188                 tx_sw_if_index_set = 1;
8189             }
8190           else
8191             break;
8192         }
8193       else if (unformat (i, "del"))
8194         is_add = 0;
8195       else
8196         break;
8197     }
8198
8199   if (rx_sw_if_index_set == 0)
8200     {
8201       errmsg ("missing rx interface name or rx_sw_if_index");
8202       return -99;
8203     }
8204
8205   if (tx_sw_if_index_set == 0)
8206     {
8207       errmsg ("missing tx interface name or tx_sw_if_index");
8208       return -99;
8209     }
8210
8211   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
8212
8213   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8214   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8215   mp->is_add = is_add;
8216
8217   S;
8218   W;
8219   /* NOTREACHED */
8220   return 0;
8221 }
8222
8223 static int
8224 api_ioam_enable (vat_main_t * vam)
8225 {
8226   unformat_input_t *input = vam->input;
8227   vl_api_ioam_enable_t *mp;
8228   f64 timeout;
8229   u32 id = 0;
8230   int has_trace_option = 0;
8231   int has_pot_option = 0;
8232   int has_seqno_option = 0;
8233   int has_analyse_option = 0;
8234
8235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8236     {
8237       if (unformat (input, "trace"))
8238         has_trace_option = 1;
8239       else if (unformat (input, "pot"))
8240         has_pot_option = 1;
8241       else if (unformat (input, "seqno"))
8242         has_seqno_option = 1;
8243       else if (unformat (input, "analyse"))
8244         has_analyse_option = 1;
8245       else
8246         break;
8247     }
8248   M (IOAM_ENABLE, ioam_enable);
8249   mp->id = htons (id);
8250   mp->seqno = has_seqno_option;
8251   mp->analyse = has_analyse_option;
8252   mp->pot_enable = has_pot_option;
8253   mp->trace_enable = has_trace_option;
8254
8255   S;
8256   W;
8257
8258   return (0);
8259
8260 }
8261
8262
8263 static int
8264 api_ioam_disable (vat_main_t * vam)
8265 {
8266   vl_api_ioam_disable_t *mp;
8267   f64 timeout;
8268
8269   M (IOAM_DISABLE, ioam_disable);
8270   S;
8271   W;
8272   return 0;
8273 }
8274
8275 static int
8276 api_sr_tunnel_add_del (vat_main_t * vam)
8277 {
8278   unformat_input_t *i = vam->input;
8279   vl_api_sr_tunnel_add_del_t *mp;
8280   f64 timeout;
8281   int is_del = 0;
8282   int pl_index;
8283   ip6_address_t src_address;
8284   int src_address_set = 0;
8285   ip6_address_t dst_address;
8286   u32 dst_mask_width;
8287   int dst_address_set = 0;
8288   u16 flags = 0;
8289   u32 rx_table_id = 0;
8290   u32 tx_table_id = 0;
8291   ip6_address_t *segments = 0;
8292   ip6_address_t *this_seg;
8293   ip6_address_t *tags = 0;
8294   ip6_address_t *this_tag;
8295   ip6_address_t next_address, tag;
8296   u8 *name = 0;
8297   u8 *policy_name = 0;
8298
8299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8300     {
8301       if (unformat (i, "del"))
8302         is_del = 1;
8303       else if (unformat (i, "name %s", &name))
8304         ;
8305       else if (unformat (i, "policy %s", &policy_name))
8306         ;
8307       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8308         ;
8309       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8310         ;
8311       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8312         src_address_set = 1;
8313       else if (unformat (i, "dst %U/%d",
8314                          unformat_ip6_address, &dst_address, &dst_mask_width))
8315         dst_address_set = 1;
8316       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8317         {
8318           vec_add2 (segments, this_seg, 1);
8319           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8320                        sizeof (*this_seg));
8321         }
8322       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8323         {
8324           vec_add2 (tags, this_tag, 1);
8325           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8326         }
8327       else if (unformat (i, "clean"))
8328         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8329       else if (unformat (i, "protected"))
8330         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8331       else if (unformat (i, "InPE %d", &pl_index))
8332         {
8333           if (pl_index <= 0 || pl_index > 4)
8334             {
8335             pl_index_range_error:
8336               errmsg ("pl index %d out of range", pl_index);
8337               return -99;
8338             }
8339           flags |=
8340             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8341         }
8342       else if (unformat (i, "EgPE %d", &pl_index))
8343         {
8344           if (pl_index <= 0 || pl_index > 4)
8345             goto pl_index_range_error;
8346           flags |=
8347             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8348         }
8349       else if (unformat (i, "OrgSrc %d", &pl_index))
8350         {
8351           if (pl_index <= 0 || pl_index > 4)
8352             goto pl_index_range_error;
8353           flags |=
8354             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8355         }
8356       else
8357         break;
8358     }
8359
8360   if (!src_address_set)
8361     {
8362       errmsg ("src address required");
8363       return -99;
8364     }
8365
8366   if (!dst_address_set)
8367     {
8368       errmsg ("dst address required");
8369       return -99;
8370     }
8371
8372   if (!segments)
8373     {
8374       errmsg ("at least one sr segment required");
8375       return -99;
8376     }
8377
8378   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8379       vec_len (segments) * sizeof (ip6_address_t)
8380       + vec_len (tags) * sizeof (ip6_address_t));
8381
8382   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8383   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8384   mp->dst_mask_width = dst_mask_width;
8385   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8386   mp->n_segments = vec_len (segments);
8387   mp->n_tags = vec_len (tags);
8388   mp->is_add = is_del == 0;
8389   clib_memcpy (mp->segs_and_tags, segments,
8390                vec_len (segments) * sizeof (ip6_address_t));
8391   clib_memcpy (mp->segs_and_tags +
8392                vec_len (segments) * sizeof (ip6_address_t), tags,
8393                vec_len (tags) * sizeof (ip6_address_t));
8394
8395   mp->outer_vrf_id = ntohl (rx_table_id);
8396   mp->inner_vrf_id = ntohl (tx_table_id);
8397   memcpy (mp->name, name, vec_len (name));
8398   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8399
8400   vec_free (segments);
8401   vec_free (tags);
8402
8403   S;
8404   W;
8405   /* NOTREACHED */
8406 }
8407
8408 static int
8409 api_sr_policy_add_del (vat_main_t * vam)
8410 {
8411   unformat_input_t *input = vam->input;
8412   vl_api_sr_policy_add_del_t *mp;
8413   f64 timeout;
8414   int is_del = 0;
8415   u8 *name = 0;
8416   u8 *tunnel_name = 0;
8417   u8 **tunnel_names = 0;
8418
8419   int name_set = 0;
8420   int tunnel_set = 0;
8421   int j = 0;
8422   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8423   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8424
8425   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8426     {
8427       if (unformat (input, "del"))
8428         is_del = 1;
8429       else if (unformat (input, "name %s", &name))
8430         name_set = 1;
8431       else if (unformat (input, "tunnel %s", &tunnel_name))
8432         {
8433           if (tunnel_name)
8434             {
8435               vec_add1 (tunnel_names, tunnel_name);
8436               /* For serializer:
8437                  - length = #bytes to store in serial vector
8438                  - +1 = byte to store that length
8439                */
8440               tunnel_names_length += (vec_len (tunnel_name) + 1);
8441               tunnel_set = 1;
8442               tunnel_name = 0;
8443             }
8444         }
8445       else
8446         break;
8447     }
8448
8449   if (!name_set)
8450     {
8451       errmsg ("policy name required");
8452       return -99;
8453     }
8454
8455   if ((!tunnel_set) && (!is_del))
8456     {
8457       errmsg ("tunnel name required");
8458       return -99;
8459     }
8460
8461   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8462
8463
8464
8465   mp->is_add = !is_del;
8466
8467   memcpy (mp->name, name, vec_len (name));
8468   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8469   u8 *serial_orig = 0;
8470   vec_validate (serial_orig, tunnel_names_length);
8471   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8472   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8473
8474   for (j = 0; j < vec_len (tunnel_names); j++)
8475     {
8476       tun_name_len = vec_len (tunnel_names[j]);
8477       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8478       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8479       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8480       serial_orig += tun_name_len;      // Advance past the copy
8481     }
8482   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8483
8484   vec_free (tunnel_names);
8485   vec_free (tunnel_name);
8486
8487   S;
8488   W;
8489   /* NOTREACHED */
8490 }
8491
8492 static int
8493 api_sr_multicast_map_add_del (vat_main_t * vam)
8494 {
8495   unformat_input_t *input = vam->input;
8496   vl_api_sr_multicast_map_add_del_t *mp;
8497   f64 timeout;
8498   int is_del = 0;
8499   ip6_address_t multicast_address;
8500   u8 *policy_name = 0;
8501   int multicast_address_set = 0;
8502
8503   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8504     {
8505       if (unformat (input, "del"))
8506         is_del = 1;
8507       else
8508         if (unformat
8509             (input, "address %U", unformat_ip6_address, &multicast_address))
8510         multicast_address_set = 1;
8511       else if (unformat (input, "sr-policy %s", &policy_name))
8512         ;
8513       else
8514         break;
8515     }
8516
8517   if (!is_del && !policy_name)
8518     {
8519       errmsg ("sr-policy name required");
8520       return -99;
8521     }
8522
8523
8524   if (!multicast_address_set)
8525     {
8526       errmsg ("address required");
8527       return -99;
8528     }
8529
8530   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8531
8532   mp->is_add = !is_del;
8533   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8534   clib_memcpy (mp->multicast_address, &multicast_address,
8535                sizeof (mp->multicast_address));
8536
8537
8538   vec_free (policy_name);
8539
8540   S;
8541   W;
8542   /* NOTREACHED */
8543 }
8544
8545
8546 #define foreach_tcp_proto_field                 \
8547 _(src_port)                                     \
8548 _(dst_port)
8549
8550 #define foreach_udp_proto_field                 \
8551 _(src_port)                                     \
8552 _(dst_port)
8553
8554 #define foreach_ip4_proto_field                 \
8555 _(src_address)                                  \
8556 _(dst_address)                                  \
8557 _(tos)                                          \
8558 _(length)                                       \
8559 _(fragment_id)                                  \
8560 _(ttl)                                          \
8561 _(protocol)                                     \
8562 _(checksum)
8563
8564 uword
8565 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8566 {
8567   u8 **maskp = va_arg (*args, u8 **);
8568   u8 *mask = 0;
8569   u8 found_something = 0;
8570   tcp_header_t *tcp;
8571
8572 #define _(a) u8 a=0;
8573   foreach_tcp_proto_field;
8574 #undef _
8575
8576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8577     {
8578       if (0);
8579 #define _(a) else if (unformat (input, #a)) a=1;
8580       foreach_tcp_proto_field
8581 #undef _
8582         else
8583         break;
8584     }
8585
8586 #define _(a) found_something += a;
8587   foreach_tcp_proto_field;
8588 #undef _
8589
8590   if (found_something == 0)
8591     return 0;
8592
8593   vec_validate (mask, sizeof (*tcp) - 1);
8594
8595   tcp = (tcp_header_t *) mask;
8596
8597 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8598   foreach_tcp_proto_field;
8599 #undef _
8600
8601   *maskp = mask;
8602   return 1;
8603 }
8604
8605 uword
8606 unformat_udp_mask (unformat_input_t * input, va_list * args)
8607 {
8608   u8 **maskp = va_arg (*args, u8 **);
8609   u8 *mask = 0;
8610   u8 found_something = 0;
8611   udp_header_t *udp;
8612
8613 #define _(a) u8 a=0;
8614   foreach_udp_proto_field;
8615 #undef _
8616
8617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8618     {
8619       if (0);
8620 #define _(a) else if (unformat (input, #a)) a=1;
8621       foreach_udp_proto_field
8622 #undef _
8623         else
8624         break;
8625     }
8626
8627 #define _(a) found_something += a;
8628   foreach_udp_proto_field;
8629 #undef _
8630
8631   if (found_something == 0)
8632     return 0;
8633
8634   vec_validate (mask, sizeof (*udp) - 1);
8635
8636   udp = (udp_header_t *) mask;
8637
8638 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8639   foreach_udp_proto_field;
8640 #undef _
8641
8642   *maskp = mask;
8643   return 1;
8644 }
8645
8646 typedef struct
8647 {
8648   u16 src_port, dst_port;
8649 } tcpudp_header_t;
8650
8651 uword
8652 unformat_l4_mask (unformat_input_t * input, va_list * args)
8653 {
8654   u8 **maskp = va_arg (*args, u8 **);
8655   u16 src_port = 0, dst_port = 0;
8656   tcpudp_header_t *tcpudp;
8657
8658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8661         return 1;
8662       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8663         return 1;
8664       else if (unformat (input, "src_port"))
8665         src_port = 0xFFFF;
8666       else if (unformat (input, "dst_port"))
8667         dst_port = 0xFFFF;
8668       else
8669         return 0;
8670     }
8671
8672   if (!src_port && !dst_port)
8673     return 0;
8674
8675   u8 *mask = 0;
8676   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8677
8678   tcpudp = (tcpudp_header_t *) mask;
8679   tcpudp->src_port = src_port;
8680   tcpudp->dst_port = dst_port;
8681
8682   *maskp = mask;
8683
8684   return 1;
8685 }
8686
8687 uword
8688 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8689 {
8690   u8 **maskp = va_arg (*args, u8 **);
8691   u8 *mask = 0;
8692   u8 found_something = 0;
8693   ip4_header_t *ip;
8694
8695 #define _(a) u8 a=0;
8696   foreach_ip4_proto_field;
8697 #undef _
8698   u8 version = 0;
8699   u8 hdr_length = 0;
8700
8701
8702   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8703     {
8704       if (unformat (input, "version"))
8705         version = 1;
8706       else if (unformat (input, "hdr_length"))
8707         hdr_length = 1;
8708       else if (unformat (input, "src"))
8709         src_address = 1;
8710       else if (unformat (input, "dst"))
8711         dst_address = 1;
8712       else if (unformat (input, "proto"))
8713         protocol = 1;
8714
8715 #define _(a) else if (unformat (input, #a)) a=1;
8716       foreach_ip4_proto_field
8717 #undef _
8718         else
8719         break;
8720     }
8721
8722 #define _(a) found_something += a;
8723   foreach_ip4_proto_field;
8724 #undef _
8725
8726   if (found_something == 0)
8727     return 0;
8728
8729   vec_validate (mask, sizeof (*ip) - 1);
8730
8731   ip = (ip4_header_t *) mask;
8732
8733 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8734   foreach_ip4_proto_field;
8735 #undef _
8736
8737   ip->ip_version_and_header_length = 0;
8738
8739   if (version)
8740     ip->ip_version_and_header_length |= 0xF0;
8741
8742   if (hdr_length)
8743     ip->ip_version_and_header_length |= 0x0F;
8744
8745   *maskp = mask;
8746   return 1;
8747 }
8748
8749 #define foreach_ip6_proto_field                 \
8750 _(src_address)                                  \
8751 _(dst_address)                                  \
8752 _(payload_length)                               \
8753 _(hop_limit)                                    \
8754 _(protocol)
8755
8756 uword
8757 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8758 {
8759   u8 **maskp = va_arg (*args, u8 **);
8760   u8 *mask = 0;
8761   u8 found_something = 0;
8762   ip6_header_t *ip;
8763   u32 ip_version_traffic_class_and_flow_label;
8764
8765 #define _(a) u8 a=0;
8766   foreach_ip6_proto_field;
8767 #undef _
8768   u8 version = 0;
8769   u8 traffic_class = 0;
8770   u8 flow_label = 0;
8771
8772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8773     {
8774       if (unformat (input, "version"))
8775         version = 1;
8776       else if (unformat (input, "traffic-class"))
8777         traffic_class = 1;
8778       else if (unformat (input, "flow-label"))
8779         flow_label = 1;
8780       else if (unformat (input, "src"))
8781         src_address = 1;
8782       else if (unformat (input, "dst"))
8783         dst_address = 1;
8784       else if (unformat (input, "proto"))
8785         protocol = 1;
8786
8787 #define _(a) else if (unformat (input, #a)) a=1;
8788       foreach_ip6_proto_field
8789 #undef _
8790         else
8791         break;
8792     }
8793
8794 #define _(a) found_something += a;
8795   foreach_ip6_proto_field;
8796 #undef _
8797
8798   if (found_something == 0)
8799     return 0;
8800
8801   vec_validate (mask, sizeof (*ip) - 1);
8802
8803   ip = (ip6_header_t *) mask;
8804
8805 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8806   foreach_ip6_proto_field;
8807 #undef _
8808
8809   ip_version_traffic_class_and_flow_label = 0;
8810
8811   if (version)
8812     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8813
8814   if (traffic_class)
8815     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8816
8817   if (flow_label)
8818     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8819
8820   ip->ip_version_traffic_class_and_flow_label =
8821     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8822
8823   *maskp = mask;
8824   return 1;
8825 }
8826
8827 uword
8828 unformat_l3_mask (unformat_input_t * input, va_list * args)
8829 {
8830   u8 **maskp = va_arg (*args, u8 **);
8831
8832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8833     {
8834       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8835         return 1;
8836       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8837         return 1;
8838       else
8839         break;
8840     }
8841   return 0;
8842 }
8843
8844 uword
8845 unformat_l2_mask (unformat_input_t * input, va_list * args)
8846 {
8847   u8 **maskp = va_arg (*args, u8 **);
8848   u8 *mask = 0;
8849   u8 src = 0;
8850   u8 dst = 0;
8851   u8 proto = 0;
8852   u8 tag1 = 0;
8853   u8 tag2 = 0;
8854   u8 ignore_tag1 = 0;
8855   u8 ignore_tag2 = 0;
8856   u8 cos1 = 0;
8857   u8 cos2 = 0;
8858   u8 dot1q = 0;
8859   u8 dot1ad = 0;
8860   int len = 14;
8861
8862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8863     {
8864       if (unformat (input, "src"))
8865         src = 1;
8866       else if (unformat (input, "dst"))
8867         dst = 1;
8868       else if (unformat (input, "proto"))
8869         proto = 1;
8870       else if (unformat (input, "tag1"))
8871         tag1 = 1;
8872       else if (unformat (input, "tag2"))
8873         tag2 = 1;
8874       else if (unformat (input, "ignore-tag1"))
8875         ignore_tag1 = 1;
8876       else if (unformat (input, "ignore-tag2"))
8877         ignore_tag2 = 1;
8878       else if (unformat (input, "cos1"))
8879         cos1 = 1;
8880       else if (unformat (input, "cos2"))
8881         cos2 = 1;
8882       else if (unformat (input, "dot1q"))
8883         dot1q = 1;
8884       else if (unformat (input, "dot1ad"))
8885         dot1ad = 1;
8886       else
8887         break;
8888     }
8889   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8890        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8891     return 0;
8892
8893   if (tag1 || ignore_tag1 || cos1 || dot1q)
8894     len = 18;
8895   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8896     len = 22;
8897
8898   vec_validate (mask, len - 1);
8899
8900   if (dst)
8901     memset (mask, 0xff, 6);
8902
8903   if (src)
8904     memset (mask + 6, 0xff, 6);
8905
8906   if (tag2 || dot1ad)
8907     {
8908       /* inner vlan tag */
8909       if (tag2)
8910         {
8911           mask[19] = 0xff;
8912           mask[18] = 0x0f;
8913         }
8914       if (cos2)
8915         mask[18] |= 0xe0;
8916       if (proto)
8917         mask[21] = mask[20] = 0xff;
8918       if (tag1)
8919         {
8920           mask[15] = 0xff;
8921           mask[14] = 0x0f;
8922         }
8923       if (cos1)
8924         mask[14] |= 0xe0;
8925       *maskp = mask;
8926       return 1;
8927     }
8928   if (tag1 | dot1q)
8929     {
8930       if (tag1)
8931         {
8932           mask[15] = 0xff;
8933           mask[14] = 0x0f;
8934         }
8935       if (cos1)
8936         mask[14] |= 0xe0;
8937       if (proto)
8938         mask[16] = mask[17] = 0xff;
8939
8940       *maskp = mask;
8941       return 1;
8942     }
8943   if (cos2)
8944     mask[18] |= 0xe0;
8945   if (cos1)
8946     mask[14] |= 0xe0;
8947   if (proto)
8948     mask[12] = mask[13] = 0xff;
8949
8950   *maskp = mask;
8951   return 1;
8952 }
8953
8954 uword
8955 unformat_classify_mask (unformat_input_t * input, va_list * args)
8956 {
8957   u8 **maskp = va_arg (*args, u8 **);
8958   u32 *skipp = va_arg (*args, u32 *);
8959   u32 *matchp = va_arg (*args, u32 *);
8960   u32 match;
8961   u8 *mask = 0;
8962   u8 *l2 = 0;
8963   u8 *l3 = 0;
8964   u8 *l4 = 0;
8965   int i;
8966
8967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8968     {
8969       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8970         ;
8971       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8972         ;
8973       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8974         ;
8975       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8976         ;
8977       else
8978         break;
8979     }
8980
8981   if (l4 && !l3)
8982     {
8983       vec_free (mask);
8984       vec_free (l2);
8985       vec_free (l4);
8986       return 0;
8987     }
8988
8989   if (mask || l2 || l3 || l4)
8990     {
8991       if (l2 || l3 || l4)
8992         {
8993           /* "With a free Ethernet header in every package" */
8994           if (l2 == 0)
8995             vec_validate (l2, 13);
8996           mask = l2;
8997           if (vec_len (l3))
8998             {
8999               vec_append (mask, l3);
9000               vec_free (l3);
9001             }
9002           if (vec_len (l4))
9003             {
9004               vec_append (mask, l4);
9005               vec_free (l4);
9006             }
9007         }
9008
9009       /* Scan forward looking for the first significant mask octet */
9010       for (i = 0; i < vec_len (mask); i++)
9011         if (mask[i])
9012           break;
9013
9014       /* compute (skip, match) params */
9015       *skipp = i / sizeof (u32x4);
9016       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9017
9018       /* Pad mask to an even multiple of the vector size */
9019       while (vec_len (mask) % sizeof (u32x4))
9020         vec_add1 (mask, 0);
9021
9022       match = vec_len (mask) / sizeof (u32x4);
9023
9024       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9025         {
9026           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9027           if (*tmp || *(tmp + 1))
9028             break;
9029           match--;
9030         }
9031       if (match == 0)
9032         clib_warning ("BUG: match 0");
9033
9034       _vec_len (mask) = match * sizeof (u32x4);
9035
9036       *matchp = match;
9037       *maskp = mask;
9038
9039       return 1;
9040     }
9041
9042   return 0;
9043 }
9044
9045 #define foreach_l2_next                         \
9046 _(drop, DROP)                                   \
9047 _(ethernet, ETHERNET_INPUT)                     \
9048 _(ip4, IP4_INPUT)                               \
9049 _(ip6, IP6_INPUT)
9050
9051 uword
9052 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9053 {
9054   u32 *miss_next_indexp = va_arg (*args, u32 *);
9055   u32 next_index = 0;
9056   u32 tmp;
9057
9058 #define _(n,N) \
9059   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9060   foreach_l2_next;
9061 #undef _
9062
9063   if (unformat (input, "%d", &tmp))
9064     {
9065       next_index = tmp;
9066       goto out;
9067     }
9068
9069   return 0;
9070
9071 out:
9072   *miss_next_indexp = next_index;
9073   return 1;
9074 }
9075
9076 #define foreach_ip_next                         \
9077 _(drop, DROP)                                   \
9078 _(local, LOCAL)                                 \
9079 _(rewrite, REWRITE)
9080
9081 uword
9082 unformat_ip_next_index (unformat_input_t * input, va_list * args)
9083 {
9084   u32 *miss_next_indexp = va_arg (*args, u32 *);
9085   u32 next_index = 0;
9086   u32 tmp;
9087
9088 #define _(n,N) \
9089   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9090   foreach_ip_next;
9091 #undef _
9092
9093   if (unformat (input, "%d", &tmp))
9094     {
9095       next_index = tmp;
9096       goto out;
9097     }
9098
9099   return 0;
9100
9101 out:
9102   *miss_next_indexp = next_index;
9103   return 1;
9104 }
9105
9106 #define foreach_acl_next                        \
9107 _(deny, DENY)
9108
9109 uword
9110 unformat_acl_next_index (unformat_input_t * input, va_list * args)
9111 {
9112   u32 *miss_next_indexp = va_arg (*args, u32 *);
9113   u32 next_index = 0;
9114   u32 tmp;
9115
9116 #define _(n,N) \
9117   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9118   foreach_acl_next;
9119 #undef _
9120
9121   if (unformat (input, "permit"))
9122     {
9123       next_index = ~0;
9124       goto out;
9125     }
9126   else if (unformat (input, "%d", &tmp))
9127     {
9128       next_index = tmp;
9129       goto out;
9130     }
9131
9132   return 0;
9133
9134 out:
9135   *miss_next_indexp = next_index;
9136   return 1;
9137 }
9138
9139 uword
9140 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9141 {
9142   u32 *r = va_arg (*args, u32 *);
9143
9144   if (unformat (input, "conform-color"))
9145     *r = POLICE_CONFORM;
9146   else if (unformat (input, "exceed-color"))
9147     *r = POLICE_EXCEED;
9148   else
9149     return 0;
9150
9151   return 1;
9152 }
9153
9154 static int
9155 api_classify_add_del_table (vat_main_t * vam)
9156 {
9157   unformat_input_t *i = vam->input;
9158   vl_api_classify_add_del_table_t *mp;
9159
9160   u32 nbuckets = 2;
9161   u32 skip = ~0;
9162   u32 match = ~0;
9163   int is_add = 1;
9164   int del_chain = 0;
9165   u32 table_index = ~0;
9166   u32 next_table_index = ~0;
9167   u32 miss_next_index = ~0;
9168   u32 memory_size = 32 << 20;
9169   u8 *mask = 0;
9170   f64 timeout;
9171   u32 current_data_flag = 0;
9172   int current_data_offset = 0;
9173
9174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9175     {
9176       if (unformat (i, "del"))
9177         is_add = 0;
9178       else if (unformat (i, "del-chain"))
9179         {
9180           is_add = 0;
9181           del_chain = 1;
9182         }
9183       else if (unformat (i, "buckets %d", &nbuckets))
9184         ;
9185       else if (unformat (i, "memory_size %d", &memory_size))
9186         ;
9187       else if (unformat (i, "skip %d", &skip))
9188         ;
9189       else if (unformat (i, "match %d", &match))
9190         ;
9191       else if (unformat (i, "table %d", &table_index))
9192         ;
9193       else if (unformat (i, "mask %U", unformat_classify_mask,
9194                          &mask, &skip, &match))
9195         ;
9196       else if (unformat (i, "next-table %d", &next_table_index))
9197         ;
9198       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
9199                          &miss_next_index))
9200         ;
9201       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9202                          &miss_next_index))
9203         ;
9204       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9205                          &miss_next_index))
9206         ;
9207       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9208         ;
9209       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9210         ;
9211       else
9212         break;
9213     }
9214
9215   if (is_add && mask == 0)
9216     {
9217       errmsg ("Mask required");
9218       return -99;
9219     }
9220
9221   if (is_add && skip == ~0)
9222     {
9223       errmsg ("skip count required");
9224       return -99;
9225     }
9226
9227   if (is_add && match == ~0)
9228     {
9229       errmsg ("match count required");
9230       return -99;
9231     }
9232
9233   if (!is_add && table_index == ~0)
9234     {
9235       errmsg ("table index required for delete");
9236       return -99;
9237     }
9238
9239   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
9240
9241   mp->is_add = is_add;
9242   mp->del_chain = del_chain;
9243   mp->table_index = ntohl (table_index);
9244   mp->nbuckets = ntohl (nbuckets);
9245   mp->memory_size = ntohl (memory_size);
9246   mp->skip_n_vectors = ntohl (skip);
9247   mp->match_n_vectors = ntohl (match);
9248   mp->next_table_index = ntohl (next_table_index);
9249   mp->miss_next_index = ntohl (miss_next_index);
9250   mp->current_data_flag = ntohl (current_data_flag);
9251   mp->current_data_offset = ntohl (current_data_offset);
9252   clib_memcpy (mp->mask, mask, vec_len (mask));
9253
9254   vec_free (mask);
9255
9256   S;
9257   W;
9258   /* NOTREACHED */
9259 }
9260
9261 uword
9262 unformat_l4_match (unformat_input_t * input, va_list * args)
9263 {
9264   u8 **matchp = va_arg (*args, u8 **);
9265
9266   u8 *proto_header = 0;
9267   int src_port = 0;
9268   int dst_port = 0;
9269
9270   tcpudp_header_t h;
9271
9272   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9273     {
9274       if (unformat (input, "src_port %d", &src_port))
9275         ;
9276       else if (unformat (input, "dst_port %d", &dst_port))
9277         ;
9278       else
9279         return 0;
9280     }
9281
9282   h.src_port = clib_host_to_net_u16 (src_port);
9283   h.dst_port = clib_host_to_net_u16 (dst_port);
9284   vec_validate (proto_header, sizeof (h) - 1);
9285   memcpy (proto_header, &h, sizeof (h));
9286
9287   *matchp = proto_header;
9288
9289   return 1;
9290 }
9291
9292 uword
9293 unformat_ip4_match (unformat_input_t * input, va_list * args)
9294 {
9295   u8 **matchp = va_arg (*args, u8 **);
9296   u8 *match = 0;
9297   ip4_header_t *ip;
9298   int version = 0;
9299   u32 version_val;
9300   int hdr_length = 0;
9301   u32 hdr_length_val;
9302   int src = 0, dst = 0;
9303   ip4_address_t src_val, dst_val;
9304   int proto = 0;
9305   u32 proto_val;
9306   int tos = 0;
9307   u32 tos_val;
9308   int length = 0;
9309   u32 length_val;
9310   int fragment_id = 0;
9311   u32 fragment_id_val;
9312   int ttl = 0;
9313   int ttl_val;
9314   int checksum = 0;
9315   u32 checksum_val;
9316
9317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9318     {
9319       if (unformat (input, "version %d", &version_val))
9320         version = 1;
9321       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9322         hdr_length = 1;
9323       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9324         src = 1;
9325       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9326         dst = 1;
9327       else if (unformat (input, "proto %d", &proto_val))
9328         proto = 1;
9329       else if (unformat (input, "tos %d", &tos_val))
9330         tos = 1;
9331       else if (unformat (input, "length %d", &length_val))
9332         length = 1;
9333       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9334         fragment_id = 1;
9335       else if (unformat (input, "ttl %d", &ttl_val))
9336         ttl = 1;
9337       else if (unformat (input, "checksum %d", &checksum_val))
9338         checksum = 1;
9339       else
9340         break;
9341     }
9342
9343   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9344       + ttl + checksum == 0)
9345     return 0;
9346
9347   /*
9348    * Aligned because we use the real comparison functions
9349    */
9350   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9351
9352   ip = (ip4_header_t *) match;
9353
9354   /* These are realistically matched in practice */
9355   if (src)
9356     ip->src_address.as_u32 = src_val.as_u32;
9357
9358   if (dst)
9359     ip->dst_address.as_u32 = dst_val.as_u32;
9360
9361   if (proto)
9362     ip->protocol = proto_val;
9363
9364
9365   /* These are not, but they're included for completeness */
9366   if (version)
9367     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9368
9369   if (hdr_length)
9370     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9371
9372   if (tos)
9373     ip->tos = tos_val;
9374
9375   if (length)
9376     ip->length = clib_host_to_net_u16 (length_val);
9377
9378   if (ttl)
9379     ip->ttl = ttl_val;
9380
9381   if (checksum)
9382     ip->checksum = clib_host_to_net_u16 (checksum_val);
9383
9384   *matchp = match;
9385   return 1;
9386 }
9387
9388 uword
9389 unformat_ip6_match (unformat_input_t * input, va_list * args)
9390 {
9391   u8 **matchp = va_arg (*args, u8 **);
9392   u8 *match = 0;
9393   ip6_header_t *ip;
9394   int version = 0;
9395   u32 version_val;
9396   u8 traffic_class = 0;
9397   u32 traffic_class_val = 0;
9398   u8 flow_label = 0;
9399   u8 flow_label_val;
9400   int src = 0, dst = 0;
9401   ip6_address_t src_val, dst_val;
9402   int proto = 0;
9403   u32 proto_val;
9404   int payload_length = 0;
9405   u32 payload_length_val;
9406   int hop_limit = 0;
9407   int hop_limit_val;
9408   u32 ip_version_traffic_class_and_flow_label;
9409
9410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9411     {
9412       if (unformat (input, "version %d", &version_val))
9413         version = 1;
9414       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9415         traffic_class = 1;
9416       else if (unformat (input, "flow_label %d", &flow_label_val))
9417         flow_label = 1;
9418       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9419         src = 1;
9420       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9421         dst = 1;
9422       else if (unformat (input, "proto %d", &proto_val))
9423         proto = 1;
9424       else if (unformat (input, "payload_length %d", &payload_length_val))
9425         payload_length = 1;
9426       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9427         hop_limit = 1;
9428       else
9429         break;
9430     }
9431
9432   if (version + traffic_class + flow_label + src + dst + proto +
9433       payload_length + hop_limit == 0)
9434     return 0;
9435
9436   /*
9437    * Aligned because we use the real comparison functions
9438    */
9439   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9440
9441   ip = (ip6_header_t *) match;
9442
9443   if (src)
9444     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9445
9446   if (dst)
9447     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9448
9449   if (proto)
9450     ip->protocol = proto_val;
9451
9452   ip_version_traffic_class_and_flow_label = 0;
9453
9454   if (version)
9455     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9456
9457   if (traffic_class)
9458     ip_version_traffic_class_and_flow_label |=
9459       (traffic_class_val & 0xFF) << 20;
9460
9461   if (flow_label)
9462     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9463
9464   ip->ip_version_traffic_class_and_flow_label =
9465     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9466
9467   if (payload_length)
9468     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9469
9470   if (hop_limit)
9471     ip->hop_limit = hop_limit_val;
9472
9473   *matchp = match;
9474   return 1;
9475 }
9476
9477 uword
9478 unformat_l3_match (unformat_input_t * input, va_list * args)
9479 {
9480   u8 **matchp = va_arg (*args, u8 **);
9481
9482   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9483     {
9484       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9485         return 1;
9486       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9487         return 1;
9488       else
9489         break;
9490     }
9491   return 0;
9492 }
9493
9494 uword
9495 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9496 {
9497   u8 *tagp = va_arg (*args, u8 *);
9498   u32 tag;
9499
9500   if (unformat (input, "%d", &tag))
9501     {
9502       tagp[0] = (tag >> 8) & 0x0F;
9503       tagp[1] = tag & 0xFF;
9504       return 1;
9505     }
9506
9507   return 0;
9508 }
9509
9510 uword
9511 unformat_l2_match (unformat_input_t * input, va_list * args)
9512 {
9513   u8 **matchp = va_arg (*args, u8 **);
9514   u8 *match = 0;
9515   u8 src = 0;
9516   u8 src_val[6];
9517   u8 dst = 0;
9518   u8 dst_val[6];
9519   u8 proto = 0;
9520   u16 proto_val;
9521   u8 tag1 = 0;
9522   u8 tag1_val[2];
9523   u8 tag2 = 0;
9524   u8 tag2_val[2];
9525   int len = 14;
9526   u8 ignore_tag1 = 0;
9527   u8 ignore_tag2 = 0;
9528   u8 cos1 = 0;
9529   u8 cos2 = 0;
9530   u32 cos1_val = 0;
9531   u32 cos2_val = 0;
9532
9533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9534     {
9535       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9536         src = 1;
9537       else
9538         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9539         dst = 1;
9540       else if (unformat (input, "proto %U",
9541                          unformat_ethernet_type_host_byte_order, &proto_val))
9542         proto = 1;
9543       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9544         tag1 = 1;
9545       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9546         tag2 = 1;
9547       else if (unformat (input, "ignore-tag1"))
9548         ignore_tag1 = 1;
9549       else if (unformat (input, "ignore-tag2"))
9550         ignore_tag2 = 1;
9551       else if (unformat (input, "cos1 %d", &cos1_val))
9552         cos1 = 1;
9553       else if (unformat (input, "cos2 %d", &cos2_val))
9554         cos2 = 1;
9555       else
9556         break;
9557     }
9558   if ((src + dst + proto + tag1 + tag2 +
9559        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9560     return 0;
9561
9562   if (tag1 || ignore_tag1 || cos1)
9563     len = 18;
9564   if (tag2 || ignore_tag2 || cos2)
9565     len = 22;
9566
9567   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9568
9569   if (dst)
9570     clib_memcpy (match, dst_val, 6);
9571
9572   if (src)
9573     clib_memcpy (match + 6, src_val, 6);
9574
9575   if (tag2)
9576     {
9577       /* inner vlan tag */
9578       match[19] = tag2_val[1];
9579       match[18] = tag2_val[0];
9580       if (cos2)
9581         match[18] |= (cos2_val & 0x7) << 5;
9582       if (proto)
9583         {
9584           match[21] = proto_val & 0xff;
9585           match[20] = proto_val >> 8;
9586         }
9587       if (tag1)
9588         {
9589           match[15] = tag1_val[1];
9590           match[14] = tag1_val[0];
9591         }
9592       if (cos1)
9593         match[14] |= (cos1_val & 0x7) << 5;
9594       *matchp = match;
9595       return 1;
9596     }
9597   if (tag1)
9598     {
9599       match[15] = tag1_val[1];
9600       match[14] = tag1_val[0];
9601       if (proto)
9602         {
9603           match[17] = proto_val & 0xff;
9604           match[16] = proto_val >> 8;
9605         }
9606       if (cos1)
9607         match[14] |= (cos1_val & 0x7) << 5;
9608
9609       *matchp = match;
9610       return 1;
9611     }
9612   if (cos2)
9613     match[18] |= (cos2_val & 0x7) << 5;
9614   if (cos1)
9615     match[14] |= (cos1_val & 0x7) << 5;
9616   if (proto)
9617     {
9618       match[13] = proto_val & 0xff;
9619       match[12] = proto_val >> 8;
9620     }
9621
9622   *matchp = match;
9623   return 1;
9624 }
9625
9626
9627 uword
9628 unformat_classify_match (unformat_input_t * input, va_list * args)
9629 {
9630   u8 **matchp = va_arg (*args, u8 **);
9631   u32 skip_n_vectors = va_arg (*args, u32);
9632   u32 match_n_vectors = va_arg (*args, u32);
9633
9634   u8 *match = 0;
9635   u8 *l2 = 0;
9636   u8 *l3 = 0;
9637   u8 *l4 = 0;
9638
9639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9640     {
9641       if (unformat (input, "hex %U", unformat_hex_string, &match))
9642         ;
9643       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9644         ;
9645       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9646         ;
9647       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9648         ;
9649       else
9650         break;
9651     }
9652
9653   if (l4 && !l3)
9654     {
9655       vec_free (match);
9656       vec_free (l2);
9657       vec_free (l4);
9658       return 0;
9659     }
9660
9661   if (match || l2 || l3 || l4)
9662     {
9663       if (l2 || l3 || l4)
9664         {
9665           /* "Win a free Ethernet header in every packet" */
9666           if (l2 == 0)
9667             vec_validate_aligned (l2, 13, sizeof (u32x4));
9668           match = l2;
9669           if (vec_len (l3))
9670             {
9671               vec_append_aligned (match, l3, sizeof (u32x4));
9672               vec_free (l3);
9673             }
9674           if (vec_len (l4))
9675             {
9676               vec_append_aligned (match, l4, sizeof (u32x4));
9677               vec_free (l4);
9678             }
9679         }
9680
9681       /* Make sure the vector is big enough even if key is all 0's */
9682       vec_validate_aligned
9683         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9684          sizeof (u32x4));
9685
9686       /* Set size, include skipped vectors */
9687       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9688
9689       *matchp = match;
9690
9691       return 1;
9692     }
9693
9694   return 0;
9695 }
9696
9697 static int
9698 api_classify_add_del_session (vat_main_t * vam)
9699 {
9700   unformat_input_t *i = vam->input;
9701   vl_api_classify_add_del_session_t *mp;
9702   int is_add = 1;
9703   u32 table_index = ~0;
9704   u32 hit_next_index = ~0;
9705   u32 opaque_index = ~0;
9706   u8 *match = 0;
9707   i32 advance = 0;
9708   f64 timeout;
9709   u32 skip_n_vectors = 0;
9710   u32 match_n_vectors = 0;
9711   u32 action = 0;
9712   u32 metadata = 0;
9713
9714   /*
9715    * Warning: you have to supply skip_n and match_n
9716    * because the API client cant simply look at the classify
9717    * table object.
9718    */
9719
9720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9721     {
9722       if (unformat (i, "del"))
9723         is_add = 0;
9724       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9725                          &hit_next_index))
9726         ;
9727       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9728                          &hit_next_index))
9729         ;
9730       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9731                          &hit_next_index))
9732         ;
9733       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9734         ;
9735       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9736         ;
9737       else if (unformat (i, "opaque-index %d", &opaque_index))
9738         ;
9739       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9740         ;
9741       else if (unformat (i, "match_n %d", &match_n_vectors))
9742         ;
9743       else if (unformat (i, "match %U", unformat_classify_match,
9744                          &match, skip_n_vectors, match_n_vectors))
9745         ;
9746       else if (unformat (i, "advance %d", &advance))
9747         ;
9748       else if (unformat (i, "table-index %d", &table_index))
9749         ;
9750       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9751         action = 1;
9752       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9753         action = 2;
9754       else if (unformat (i, "action %d", &action))
9755         ;
9756       else if (unformat (i, "metadata %d", &metadata))
9757         ;
9758       else
9759         break;
9760     }
9761
9762   if (table_index == ~0)
9763     {
9764       errmsg ("Table index required");
9765       return -99;
9766     }
9767
9768   if (is_add && match == 0)
9769     {
9770       errmsg ("Match value required");
9771       return -99;
9772     }
9773
9774   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9775
9776   mp->is_add = is_add;
9777   mp->table_index = ntohl (table_index);
9778   mp->hit_next_index = ntohl (hit_next_index);
9779   mp->opaque_index = ntohl (opaque_index);
9780   mp->advance = ntohl (advance);
9781   mp->action = action;
9782   mp->metadata = ntohl (metadata);
9783   clib_memcpy (mp->match, match, vec_len (match));
9784   vec_free (match);
9785
9786   S;
9787   W;
9788   /* NOTREACHED */
9789 }
9790
9791 static int
9792 api_classify_set_interface_ip_table (vat_main_t * vam)
9793 {
9794   unformat_input_t *i = vam->input;
9795   vl_api_classify_set_interface_ip_table_t *mp;
9796   f64 timeout;
9797   u32 sw_if_index;
9798   int sw_if_index_set;
9799   u32 table_index = ~0;
9800   u8 is_ipv6 = 0;
9801
9802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9803     {
9804       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9805         sw_if_index_set = 1;
9806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9807         sw_if_index_set = 1;
9808       else if (unformat (i, "table %d", &table_index))
9809         ;
9810       else
9811         {
9812           clib_warning ("parse error '%U'", format_unformat_error, i);
9813           return -99;
9814         }
9815     }
9816
9817   if (sw_if_index_set == 0)
9818     {
9819       errmsg ("missing interface name or sw_if_index");
9820       return -99;
9821     }
9822
9823
9824   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9825
9826   mp->sw_if_index = ntohl (sw_if_index);
9827   mp->table_index = ntohl (table_index);
9828   mp->is_ipv6 = is_ipv6;
9829
9830   S;
9831   W;
9832   /* NOTREACHED */
9833   return 0;
9834 }
9835
9836 static int
9837 api_classify_set_interface_l2_tables (vat_main_t * vam)
9838 {
9839   unformat_input_t *i = vam->input;
9840   vl_api_classify_set_interface_l2_tables_t *mp;
9841   f64 timeout;
9842   u32 sw_if_index;
9843   int sw_if_index_set;
9844   u32 ip4_table_index = ~0;
9845   u32 ip6_table_index = ~0;
9846   u32 other_table_index = ~0;
9847   u32 is_input = 1;
9848
9849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9850     {
9851       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9852         sw_if_index_set = 1;
9853       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9854         sw_if_index_set = 1;
9855       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9856         ;
9857       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9858         ;
9859       else if (unformat (i, "other-table %d", &other_table_index))
9860         ;
9861       else if (unformat (i, "is-input %d", &is_input))
9862         ;
9863       else
9864         {
9865           clib_warning ("parse error '%U'", format_unformat_error, i);
9866           return -99;
9867         }
9868     }
9869
9870   if (sw_if_index_set == 0)
9871     {
9872       errmsg ("missing interface name or sw_if_index");
9873       return -99;
9874     }
9875
9876
9877   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9878
9879   mp->sw_if_index = ntohl (sw_if_index);
9880   mp->ip4_table_index = ntohl (ip4_table_index);
9881   mp->ip6_table_index = ntohl (ip6_table_index);
9882   mp->other_table_index = ntohl (other_table_index);
9883   mp->is_input = (u8) is_input;
9884
9885   S;
9886   W;
9887   /* NOTREACHED */
9888   return 0;
9889 }
9890
9891 static int
9892 api_set_ipfix_exporter (vat_main_t * vam)
9893 {
9894   unformat_input_t *i = vam->input;
9895   vl_api_set_ipfix_exporter_t *mp;
9896   ip4_address_t collector_address;
9897   u8 collector_address_set = 0;
9898   u32 collector_port = ~0;
9899   ip4_address_t src_address;
9900   u8 src_address_set = 0;
9901   u32 vrf_id = ~0;
9902   u32 path_mtu = ~0;
9903   u32 template_interval = ~0;
9904   u8 udp_checksum = 0;
9905   f64 timeout;
9906
9907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9908     {
9909       if (unformat (i, "collector_address %U", unformat_ip4_address,
9910                     &collector_address))
9911         collector_address_set = 1;
9912       else if (unformat (i, "collector_port %d", &collector_port))
9913         ;
9914       else if (unformat (i, "src_address %U", unformat_ip4_address,
9915                          &src_address))
9916         src_address_set = 1;
9917       else if (unformat (i, "vrf_id %d", &vrf_id))
9918         ;
9919       else if (unformat (i, "path_mtu %d", &path_mtu))
9920         ;
9921       else if (unformat (i, "template_interval %d", &template_interval))
9922         ;
9923       else if (unformat (i, "udp_checksum"))
9924         udp_checksum = 1;
9925       else
9926         break;
9927     }
9928
9929   if (collector_address_set == 0)
9930     {
9931       errmsg ("collector_address required");
9932       return -99;
9933     }
9934
9935   if (src_address_set == 0)
9936     {
9937       errmsg ("src_address required");
9938       return -99;
9939     }
9940
9941   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9942
9943   memcpy (mp->collector_address, collector_address.data,
9944           sizeof (collector_address.data));
9945   mp->collector_port = htons ((u16) collector_port);
9946   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9947   mp->vrf_id = htonl (vrf_id);
9948   mp->path_mtu = htonl (path_mtu);
9949   mp->template_interval = htonl (template_interval);
9950   mp->udp_checksum = udp_checksum;
9951
9952   S;
9953   W;
9954   /* NOTREACHED */
9955 }
9956
9957 static int
9958 api_set_ipfix_classify_stream (vat_main_t * vam)
9959 {
9960   unformat_input_t *i = vam->input;
9961   vl_api_set_ipfix_classify_stream_t *mp;
9962   u32 domain_id = 0;
9963   u32 src_port = UDP_DST_PORT_ipfix;
9964   f64 timeout;
9965
9966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9967     {
9968       if (unformat (i, "domain %d", &domain_id))
9969         ;
9970       else if (unformat (i, "src_port %d", &src_port))
9971         ;
9972       else
9973         {
9974           errmsg ("unknown input `%U'", format_unformat_error, i);
9975           return -99;
9976         }
9977     }
9978
9979   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9980
9981   mp->domain_id = htonl (domain_id);
9982   mp->src_port = htons ((u16) src_port);
9983
9984   S;
9985   W;
9986   /* NOTREACHED */
9987 }
9988
9989 static int
9990 api_ipfix_classify_table_add_del (vat_main_t * vam)
9991 {
9992   unformat_input_t *i = vam->input;
9993   vl_api_ipfix_classify_table_add_del_t *mp;
9994   int is_add = -1;
9995   u32 classify_table_index = ~0;
9996   u8 ip_version = 0;
9997   u8 transport_protocol = 255;
9998   f64 timeout;
9999
10000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10001     {
10002       if (unformat (i, "add"))
10003         is_add = 1;
10004       else if (unformat (i, "del"))
10005         is_add = 0;
10006       else if (unformat (i, "table %d", &classify_table_index))
10007         ;
10008       else if (unformat (i, "ip4"))
10009         ip_version = 4;
10010       else if (unformat (i, "ip6"))
10011         ip_version = 6;
10012       else if (unformat (i, "tcp"))
10013         transport_protocol = 6;
10014       else if (unformat (i, "udp"))
10015         transport_protocol = 17;
10016       else
10017         {
10018           errmsg ("unknown input `%U'", format_unformat_error, i);
10019           return -99;
10020         }
10021     }
10022
10023   if (is_add == -1)
10024     {
10025       errmsg ("expecting: add|del");
10026       return -99;
10027     }
10028   if (classify_table_index == ~0)
10029     {
10030       errmsg ("classifier table not specified");
10031       return -99;
10032     }
10033   if (ip_version == 0)
10034     {
10035       errmsg ("IP version not specified");
10036       return -99;
10037     }
10038
10039   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
10040
10041   mp->is_add = is_add;
10042   mp->table_id = htonl (classify_table_index);
10043   mp->ip_version = ip_version;
10044   mp->transport_protocol = transport_protocol;
10045
10046   S;
10047   W;
10048   /* NOTREACHED */
10049 }
10050
10051 static int
10052 api_get_node_index (vat_main_t * vam)
10053 {
10054   unformat_input_t *i = vam->input;
10055   vl_api_get_node_index_t *mp;
10056   f64 timeout;
10057   u8 *name = 0;
10058
10059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10060     {
10061       if (unformat (i, "node %s", &name))
10062         ;
10063       else
10064         break;
10065     }
10066   if (name == 0)
10067     {
10068       errmsg ("node name required");
10069       return -99;
10070     }
10071   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10072     {
10073       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10074       return -99;
10075     }
10076
10077   M (GET_NODE_INDEX, get_node_index);
10078   clib_memcpy (mp->node_name, name, vec_len (name));
10079   vec_free (name);
10080
10081   S;
10082   W;
10083   /* NOTREACHED */
10084   return 0;
10085 }
10086
10087 static int
10088 api_get_next_index (vat_main_t * vam)
10089 {
10090   unformat_input_t *i = vam->input;
10091   vl_api_get_next_index_t *mp;
10092   f64 timeout;
10093   u8 *node_name = 0, *next_node_name = 0;
10094
10095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10096     {
10097       if (unformat (i, "node-name %s", &node_name))
10098         ;
10099       else if (unformat (i, "next-node-name %s", &next_node_name))
10100         break;
10101     }
10102
10103   if (node_name == 0)
10104     {
10105       errmsg ("node name required");
10106       return -99;
10107     }
10108   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10109     {
10110       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10111       return -99;
10112     }
10113
10114   if (next_node_name == 0)
10115     {
10116       errmsg ("next node name required");
10117       return -99;
10118     }
10119   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10120     {
10121       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10122       return -99;
10123     }
10124
10125   M (GET_NEXT_INDEX, get_next_index);
10126   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10127   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10128   vec_free (node_name);
10129   vec_free (next_node_name);
10130
10131   S;
10132   W;
10133   /* NOTREACHED */
10134   return 0;
10135 }
10136
10137 static int
10138 api_add_node_next (vat_main_t * vam)
10139 {
10140   unformat_input_t *i = vam->input;
10141   vl_api_add_node_next_t *mp;
10142   f64 timeout;
10143   u8 *name = 0;
10144   u8 *next = 0;
10145
10146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10147     {
10148       if (unformat (i, "node %s", &name))
10149         ;
10150       else if (unformat (i, "next %s", &next))
10151         ;
10152       else
10153         break;
10154     }
10155   if (name == 0)
10156     {
10157       errmsg ("node name required");
10158       return -99;
10159     }
10160   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10161     {
10162       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10163       return -99;
10164     }
10165   if (next == 0)
10166     {
10167       errmsg ("next node required");
10168       return -99;
10169     }
10170   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10171     {
10172       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10173       return -99;
10174     }
10175
10176   M (ADD_NODE_NEXT, add_node_next);
10177   clib_memcpy (mp->node_name, name, vec_len (name));
10178   clib_memcpy (mp->next_name, next, vec_len (next));
10179   vec_free (name);
10180   vec_free (next);
10181
10182   S;
10183   W;
10184   /* NOTREACHED */
10185   return 0;
10186 }
10187
10188 static int
10189 api_l2tpv3_create_tunnel (vat_main_t * vam)
10190 {
10191   unformat_input_t *i = vam->input;
10192   ip6_address_t client_address, our_address;
10193   int client_address_set = 0;
10194   int our_address_set = 0;
10195   u32 local_session_id = 0;
10196   u32 remote_session_id = 0;
10197   u64 local_cookie = 0;
10198   u64 remote_cookie = 0;
10199   u8 l2_sublayer_present = 0;
10200   vl_api_l2tpv3_create_tunnel_t *mp;
10201   f64 timeout;
10202
10203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10204     {
10205       if (unformat (i, "client_address %U", unformat_ip6_address,
10206                     &client_address))
10207         client_address_set = 1;
10208       else if (unformat (i, "our_address %U", unformat_ip6_address,
10209                          &our_address))
10210         our_address_set = 1;
10211       else if (unformat (i, "local_session_id %d", &local_session_id))
10212         ;
10213       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10214         ;
10215       else if (unformat (i, "local_cookie %lld", &local_cookie))
10216         ;
10217       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10218         ;
10219       else if (unformat (i, "l2-sublayer-present"))
10220         l2_sublayer_present = 1;
10221       else
10222         break;
10223     }
10224
10225   if (client_address_set == 0)
10226     {
10227       errmsg ("client_address required");
10228       return -99;
10229     }
10230
10231   if (our_address_set == 0)
10232     {
10233       errmsg ("our_address required");
10234       return -99;
10235     }
10236
10237   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
10238
10239   clib_memcpy (mp->client_address, client_address.as_u8,
10240                sizeof (mp->client_address));
10241
10242   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10243
10244   mp->local_session_id = ntohl (local_session_id);
10245   mp->remote_session_id = ntohl (remote_session_id);
10246   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10247   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10248   mp->l2_sublayer_present = l2_sublayer_present;
10249   mp->is_ipv6 = 1;
10250
10251   S;
10252   W;
10253   /* NOTREACHED */
10254   return 0;
10255 }
10256
10257 static int
10258 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10259 {
10260   unformat_input_t *i = vam->input;
10261   u32 sw_if_index;
10262   u8 sw_if_index_set = 0;
10263   u64 new_local_cookie = 0;
10264   u64 new_remote_cookie = 0;
10265   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10266   f64 timeout;
10267
10268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10269     {
10270       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10271         sw_if_index_set = 1;
10272       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10273         sw_if_index_set = 1;
10274       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10275         ;
10276       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10277         ;
10278       else
10279         break;
10280     }
10281
10282   if (sw_if_index_set == 0)
10283     {
10284       errmsg ("missing interface name or sw_if_index");
10285       return -99;
10286     }
10287
10288   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10289
10290   mp->sw_if_index = ntohl (sw_if_index);
10291   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10292   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10293
10294   S;
10295   W;
10296   /* NOTREACHED */
10297   return 0;
10298 }
10299
10300 static int
10301 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10302 {
10303   unformat_input_t *i = vam->input;
10304   vl_api_l2tpv3_interface_enable_disable_t *mp;
10305   f64 timeout;
10306   u32 sw_if_index;
10307   u8 sw_if_index_set = 0;
10308   u8 enable_disable = 1;
10309
10310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10311     {
10312       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10313         sw_if_index_set = 1;
10314       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10315         sw_if_index_set = 1;
10316       else if (unformat (i, "enable"))
10317         enable_disable = 1;
10318       else if (unformat (i, "disable"))
10319         enable_disable = 0;
10320       else
10321         break;
10322     }
10323
10324   if (sw_if_index_set == 0)
10325     {
10326       errmsg ("missing interface name or sw_if_index");
10327       return -99;
10328     }
10329
10330   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10331
10332   mp->sw_if_index = ntohl (sw_if_index);
10333   mp->enable_disable = enable_disable;
10334
10335   S;
10336   W;
10337   /* NOTREACHED */
10338   return 0;
10339 }
10340
10341 static int
10342 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10343 {
10344   unformat_input_t *i = vam->input;
10345   vl_api_l2tpv3_set_lookup_key_t *mp;
10346   f64 timeout;
10347   u8 key = ~0;
10348
10349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10350     {
10351       if (unformat (i, "lookup_v6_src"))
10352         key = L2T_LOOKUP_SRC_ADDRESS;
10353       else if (unformat (i, "lookup_v6_dst"))
10354         key = L2T_LOOKUP_DST_ADDRESS;
10355       else if (unformat (i, "lookup_session_id"))
10356         key = L2T_LOOKUP_SESSION_ID;
10357       else
10358         break;
10359     }
10360
10361   if (key == (u8) ~ 0)
10362     {
10363       errmsg ("l2tp session lookup key unset");
10364       return -99;
10365     }
10366
10367   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10368
10369   mp->key = key;
10370
10371   S;
10372   W;
10373   /* NOTREACHED */
10374   return 0;
10375 }
10376
10377 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10378   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10379 {
10380   vat_main_t *vam = &vat_main;
10381
10382   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10383          format_ip6_address, mp->our_address,
10384          format_ip6_address, mp->client_address,
10385          clib_net_to_host_u32 (mp->sw_if_index));
10386
10387   print (vam->ofp,
10388          "   local cookies %016llx %016llx remote cookie %016llx",
10389          clib_net_to_host_u64 (mp->local_cookie[0]),
10390          clib_net_to_host_u64 (mp->local_cookie[1]),
10391          clib_net_to_host_u64 (mp->remote_cookie));
10392
10393   print (vam->ofp, "   local session-id %d remote session-id %d",
10394          clib_net_to_host_u32 (mp->local_session_id),
10395          clib_net_to_host_u32 (mp->remote_session_id));
10396
10397   print (vam->ofp, "   l2 specific sublayer %s\n",
10398          mp->l2_sublayer_present ? "preset" : "absent");
10399
10400 }
10401
10402 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10403   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10404 {
10405   vat_main_t *vam = &vat_main;
10406   vat_json_node_t *node = NULL;
10407   struct in6_addr addr;
10408
10409   if (VAT_JSON_ARRAY != vam->json_tree.type)
10410     {
10411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10412       vat_json_init_array (&vam->json_tree);
10413     }
10414   node = vat_json_array_add (&vam->json_tree);
10415
10416   vat_json_init_object (node);
10417
10418   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10419   vat_json_object_add_ip6 (node, "our_address", addr);
10420   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10421   vat_json_object_add_ip6 (node, "client_address", addr);
10422
10423   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10424   vat_json_init_array (lc);
10425   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10426   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10427   vat_json_object_add_uint (node, "remote_cookie",
10428                             clib_net_to_host_u64 (mp->remote_cookie));
10429
10430   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10431   vat_json_object_add_uint (node, "local_session_id",
10432                             clib_net_to_host_u32 (mp->local_session_id));
10433   vat_json_object_add_uint (node, "remote_session_id",
10434                             clib_net_to_host_u32 (mp->remote_session_id));
10435   vat_json_object_add_string_copy (node, "l2_sublayer",
10436                                    mp->l2_sublayer_present ? (u8 *) "present"
10437                                    : (u8 *) "absent");
10438 }
10439
10440 static int
10441 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10442 {
10443   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10444   f64 timeout;
10445
10446   /* Get list of l2tpv3-tunnel interfaces */
10447   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10448   S;
10449
10450   /* Use a control ping for synchronization */
10451   {
10452     vl_api_control_ping_t *mp;
10453     M (CONTROL_PING, control_ping);
10454     S;
10455   }
10456   W;
10457 }
10458
10459
10460 static void vl_api_sw_interface_tap_details_t_handler
10461   (vl_api_sw_interface_tap_details_t * mp)
10462 {
10463   vat_main_t *vam = &vat_main;
10464
10465   print (vam->ofp, "%-16s %d",
10466          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10467 }
10468
10469 static void vl_api_sw_interface_tap_details_t_handler_json
10470   (vl_api_sw_interface_tap_details_t * mp)
10471 {
10472   vat_main_t *vam = &vat_main;
10473   vat_json_node_t *node = NULL;
10474
10475   if (VAT_JSON_ARRAY != vam->json_tree.type)
10476     {
10477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10478       vat_json_init_array (&vam->json_tree);
10479     }
10480   node = vat_json_array_add (&vam->json_tree);
10481
10482   vat_json_init_object (node);
10483   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10484   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10485 }
10486
10487 static int
10488 api_sw_interface_tap_dump (vat_main_t * vam)
10489 {
10490   vl_api_sw_interface_tap_dump_t *mp;
10491   f64 timeout;
10492
10493   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10494   /* Get list of tap interfaces */
10495   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10496   S;
10497
10498   /* Use a control ping for synchronization */
10499   {
10500     vl_api_control_ping_t *mp;
10501     M (CONTROL_PING, control_ping);
10502     S;
10503   }
10504   W;
10505 }
10506
10507 static uword unformat_vxlan_decap_next
10508   (unformat_input_t * input, va_list * args)
10509 {
10510   u32 *result = va_arg (*args, u32 *);
10511   u32 tmp;
10512
10513   if (unformat (input, "l2"))
10514     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10515   else if (unformat (input, "%d", &tmp))
10516     *result = tmp;
10517   else
10518     return 0;
10519   return 1;
10520 }
10521
10522 static int
10523 api_vxlan_add_del_tunnel (vat_main_t * vam)
10524 {
10525   unformat_input_t *line_input = vam->input;
10526   vl_api_vxlan_add_del_tunnel_t *mp;
10527   f64 timeout;
10528   ip46_address_t src, dst;
10529   u8 is_add = 1;
10530   u8 ipv4_set = 0, ipv6_set = 0;
10531   u8 src_set = 0;
10532   u8 dst_set = 0;
10533   u8 grp_set = 0;
10534   u32 mcast_sw_if_index = ~0;
10535   u32 encap_vrf_id = 0;
10536   u32 decap_next_index = ~0;
10537   u32 vni = 0;
10538
10539   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10540   memset (&src, 0, sizeof src);
10541   memset (&dst, 0, sizeof dst);
10542
10543   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10544     {
10545       if (unformat (line_input, "del"))
10546         is_add = 0;
10547       else
10548         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10549         {
10550           ipv4_set = 1;
10551           src_set = 1;
10552         }
10553       else
10554         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10555         {
10556           ipv4_set = 1;
10557           dst_set = 1;
10558         }
10559       else
10560         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10561         {
10562           ipv6_set = 1;
10563           src_set = 1;
10564         }
10565       else
10566         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10567         {
10568           ipv6_set = 1;
10569           dst_set = 1;
10570         }
10571       else if (unformat (line_input, "group %U %U",
10572                          unformat_ip4_address, &dst.ip4,
10573                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10574         {
10575           grp_set = dst_set = 1;
10576           ipv4_set = 1;
10577         }
10578       else if (unformat (line_input, "group %U",
10579                          unformat_ip4_address, &dst.ip4))
10580         {
10581           grp_set = dst_set = 1;
10582           ipv4_set = 1;
10583         }
10584       else if (unformat (line_input, "group %U %U",
10585                          unformat_ip6_address, &dst.ip6,
10586                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10587         {
10588           grp_set = dst_set = 1;
10589           ipv6_set = 1;
10590         }
10591       else if (unformat (line_input, "group %U",
10592                          unformat_ip6_address, &dst.ip6))
10593         {
10594           grp_set = dst_set = 1;
10595           ipv6_set = 1;
10596         }
10597       else
10598         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10599         ;
10600       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10601         ;
10602       else if (unformat (line_input, "decap-next %U",
10603                          unformat_vxlan_decap_next, &decap_next_index))
10604         ;
10605       else if (unformat (line_input, "vni %d", &vni))
10606         ;
10607       else
10608         {
10609           errmsg ("parse error '%U'", format_unformat_error, line_input);
10610           return -99;
10611         }
10612     }
10613
10614   if (src_set == 0)
10615     {
10616       errmsg ("tunnel src address not specified");
10617       return -99;
10618     }
10619   if (dst_set == 0)
10620     {
10621       errmsg ("tunnel dst address not specified");
10622       return -99;
10623     }
10624
10625   if (grp_set && !ip46_address_is_multicast (&dst))
10626     {
10627       errmsg ("tunnel group address not multicast");
10628       return -99;
10629     }
10630   if (grp_set && mcast_sw_if_index == ~0)
10631     {
10632       errmsg ("tunnel nonexistent multicast device");
10633       return -99;
10634     }
10635   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10636     {
10637       errmsg ("tunnel dst address must be unicast");
10638       return -99;
10639     }
10640
10641
10642   if (ipv4_set && ipv6_set)
10643     {
10644       errmsg ("both IPv4 and IPv6 addresses specified");
10645       return -99;
10646     }
10647
10648   if ((vni == 0) || (vni >> 24))
10649     {
10650       errmsg ("vni not specified or out of range");
10651       return -99;
10652     }
10653
10654   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10655
10656   if (ipv6_set)
10657     {
10658       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10659       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10660     }
10661   else
10662     {
10663       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10664       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10665     }
10666   mp->encap_vrf_id = ntohl (encap_vrf_id);
10667   mp->decap_next_index = ntohl (decap_next_index);
10668   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10669   mp->vni = ntohl (vni);
10670   mp->is_add = is_add;
10671   mp->is_ipv6 = ipv6_set;
10672
10673   S;
10674   W;
10675   /* NOTREACHED */
10676   return 0;
10677 }
10678
10679 static void vl_api_vxlan_tunnel_details_t_handler
10680   (vl_api_vxlan_tunnel_details_t * mp)
10681 {
10682   vat_main_t *vam = &vat_main;
10683   ip46_address_t src, dst;
10684
10685   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10686   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10687
10688   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10689          ntohl (mp->sw_if_index),
10690          format_ip46_address, &src, IP46_TYPE_ANY,
10691          format_ip46_address, &dst, IP46_TYPE_ANY,
10692          ntohl (mp->encap_vrf_id),
10693          ntohl (mp->decap_next_index), ntohl (mp->vni),
10694          ntohl (mp->mcast_sw_if_index));
10695 }
10696
10697 static void vl_api_vxlan_tunnel_details_t_handler_json
10698   (vl_api_vxlan_tunnel_details_t * mp)
10699 {
10700   vat_main_t *vam = &vat_main;
10701   vat_json_node_t *node = NULL;
10702
10703   if (VAT_JSON_ARRAY != vam->json_tree.type)
10704     {
10705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10706       vat_json_init_array (&vam->json_tree);
10707     }
10708   node = vat_json_array_add (&vam->json_tree);
10709
10710   vat_json_init_object (node);
10711   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10712   if (mp->is_ipv6)
10713     {
10714       struct in6_addr ip6;
10715
10716       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10717       vat_json_object_add_ip6 (node, "src_address", ip6);
10718       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10719       vat_json_object_add_ip6 (node, "dst_address", ip6);
10720     }
10721   else
10722     {
10723       struct in_addr ip4;
10724
10725       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10726       vat_json_object_add_ip4 (node, "src_address", ip4);
10727       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10728       vat_json_object_add_ip4 (node, "dst_address", ip4);
10729     }
10730   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10731   vat_json_object_add_uint (node, "decap_next_index",
10732                             ntohl (mp->decap_next_index));
10733   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10734   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10735   vat_json_object_add_uint (node, "mcast_sw_if_index",
10736                             ntohl (mp->mcast_sw_if_index));
10737 }
10738
10739 static int
10740 api_vxlan_tunnel_dump (vat_main_t * vam)
10741 {
10742   unformat_input_t *i = vam->input;
10743   vl_api_vxlan_tunnel_dump_t *mp;
10744   f64 timeout;
10745   u32 sw_if_index;
10746   u8 sw_if_index_set = 0;
10747
10748   /* Parse args required to build the message */
10749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10750     {
10751       if (unformat (i, "sw_if_index %d", &sw_if_index))
10752         sw_if_index_set = 1;
10753       else
10754         break;
10755     }
10756
10757   if (sw_if_index_set == 0)
10758     {
10759       sw_if_index = ~0;
10760     }
10761
10762   if (!vam->json_output)
10763     {
10764       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10765              "sw_if_index", "src_address", "dst_address",
10766              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10767     }
10768
10769   /* Get list of vxlan-tunnel interfaces */
10770   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10771
10772   mp->sw_if_index = htonl (sw_if_index);
10773
10774   S;
10775
10776   /* Use a control ping for synchronization */
10777   {
10778     vl_api_control_ping_t *mp;
10779     M (CONTROL_PING, control_ping);
10780     S;
10781   }
10782   W;
10783 }
10784
10785 static int
10786 api_gre_add_del_tunnel (vat_main_t * vam)
10787 {
10788   unformat_input_t *line_input = vam->input;
10789   vl_api_gre_add_del_tunnel_t *mp;
10790   f64 timeout;
10791   ip4_address_t src4, dst4;
10792   u8 is_add = 1;
10793   u8 teb = 0;
10794   u8 src_set = 0;
10795   u8 dst_set = 0;
10796   u32 outer_fib_id = 0;
10797
10798   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10799     {
10800       if (unformat (line_input, "del"))
10801         is_add = 0;
10802       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10803         src_set = 1;
10804       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10805         dst_set = 1;
10806       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10807         ;
10808       else if (unformat (line_input, "teb"))
10809         teb = 1;
10810       else
10811         {
10812           errmsg ("parse error '%U'", format_unformat_error, line_input);
10813           return -99;
10814         }
10815     }
10816
10817   if (src_set == 0)
10818     {
10819       errmsg ("tunnel src address not specified");
10820       return -99;
10821     }
10822   if (dst_set == 0)
10823     {
10824       errmsg ("tunnel dst address not specified");
10825       return -99;
10826     }
10827
10828
10829   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10830
10831   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10832   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10833   mp->outer_fib_id = ntohl (outer_fib_id);
10834   mp->is_add = is_add;
10835   mp->teb = teb;
10836
10837   S;
10838   W;
10839   /* NOTREACHED */
10840   return 0;
10841 }
10842
10843 static void vl_api_gre_tunnel_details_t_handler
10844   (vl_api_gre_tunnel_details_t * mp)
10845 {
10846   vat_main_t *vam = &vat_main;
10847
10848   print (vam->ofp, "%11d%15U%15U%6d%14d",
10849          ntohl (mp->sw_if_index),
10850          format_ip4_address, &mp->src_address,
10851          format_ip4_address, &mp->dst_address,
10852          mp->teb, ntohl (mp->outer_fib_id));
10853 }
10854
10855 static void vl_api_gre_tunnel_details_t_handler_json
10856   (vl_api_gre_tunnel_details_t * mp)
10857 {
10858   vat_main_t *vam = &vat_main;
10859   vat_json_node_t *node = NULL;
10860   struct in_addr ip4;
10861
10862   if (VAT_JSON_ARRAY != vam->json_tree.type)
10863     {
10864       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10865       vat_json_init_array (&vam->json_tree);
10866     }
10867   node = vat_json_array_add (&vam->json_tree);
10868
10869   vat_json_init_object (node);
10870   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10871   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10872   vat_json_object_add_ip4 (node, "src_address", ip4);
10873   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10874   vat_json_object_add_ip4 (node, "dst_address", ip4);
10875   vat_json_object_add_uint (node, "teb", mp->teb);
10876   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10877 }
10878
10879 static int
10880 api_gre_tunnel_dump (vat_main_t * vam)
10881 {
10882   unformat_input_t *i = vam->input;
10883   vl_api_gre_tunnel_dump_t *mp;
10884   f64 timeout;
10885   u32 sw_if_index;
10886   u8 sw_if_index_set = 0;
10887
10888   /* Parse args required to build the message */
10889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10890     {
10891       if (unformat (i, "sw_if_index %d", &sw_if_index))
10892         sw_if_index_set = 1;
10893       else
10894         break;
10895     }
10896
10897   if (sw_if_index_set == 0)
10898     {
10899       sw_if_index = ~0;
10900     }
10901
10902   if (!vam->json_output)
10903     {
10904       print (vam->ofp, "%11s%15s%15s%6s%14s",
10905              "sw_if_index", "src_address", "dst_address", "teb",
10906              "outer_fib_id");
10907     }
10908
10909   /* Get list of gre-tunnel interfaces */
10910   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10911
10912   mp->sw_if_index = htonl (sw_if_index);
10913
10914   S;
10915
10916   /* Use a control ping for synchronization */
10917   {
10918     vl_api_control_ping_t *mp;
10919     M (CONTROL_PING, control_ping);
10920     S;
10921   }
10922   W;
10923 }
10924
10925 static int
10926 api_l2_fib_clear_table (vat_main_t * vam)
10927 {
10928 //  unformat_input_t * i = vam->input;
10929   vl_api_l2_fib_clear_table_t *mp;
10930   f64 timeout;
10931
10932   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10933
10934   S;
10935   W;
10936   /* NOTREACHED */
10937   return 0;
10938 }
10939
10940 static int
10941 api_l2_interface_efp_filter (vat_main_t * vam)
10942 {
10943   unformat_input_t *i = vam->input;
10944   vl_api_l2_interface_efp_filter_t *mp;
10945   f64 timeout;
10946   u32 sw_if_index;
10947   u8 enable = 1;
10948   u8 sw_if_index_set = 0;
10949
10950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10951     {
10952       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10953         sw_if_index_set = 1;
10954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10955         sw_if_index_set = 1;
10956       else if (unformat (i, "enable"))
10957         enable = 1;
10958       else if (unformat (i, "disable"))
10959         enable = 0;
10960       else
10961         {
10962           clib_warning ("parse error '%U'", format_unformat_error, i);
10963           return -99;
10964         }
10965     }
10966
10967   if (sw_if_index_set == 0)
10968     {
10969       errmsg ("missing sw_if_index");
10970       return -99;
10971     }
10972
10973   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10974
10975   mp->sw_if_index = ntohl (sw_if_index);
10976   mp->enable_disable = enable;
10977
10978   S;
10979   W;
10980   /* NOTREACHED */
10981   return 0;
10982 }
10983
10984 #define foreach_vtr_op                          \
10985 _("disable",  L2_VTR_DISABLED)                  \
10986 _("push-1",  L2_VTR_PUSH_1)                     \
10987 _("push-2",  L2_VTR_PUSH_2)                     \
10988 _("pop-1",  L2_VTR_POP_1)                       \
10989 _("pop-2",  L2_VTR_POP_2)                       \
10990 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10991 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10992 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10993 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10994
10995 static int
10996 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10997 {
10998   unformat_input_t *i = vam->input;
10999   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11000   f64 timeout;
11001   u32 sw_if_index;
11002   u8 sw_if_index_set = 0;
11003   u8 vtr_op_set = 0;
11004   u32 vtr_op = 0;
11005   u32 push_dot1q = 1;
11006   u32 tag1 = ~0;
11007   u32 tag2 = ~0;
11008
11009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11010     {
11011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11012         sw_if_index_set = 1;
11013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11014         sw_if_index_set = 1;
11015       else if (unformat (i, "vtr_op %d", &vtr_op))
11016         vtr_op_set = 1;
11017 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11018       foreach_vtr_op
11019 #undef _
11020         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11021         ;
11022       else if (unformat (i, "tag1 %d", &tag1))
11023         ;
11024       else if (unformat (i, "tag2 %d", &tag2))
11025         ;
11026       else
11027         {
11028           clib_warning ("parse error '%U'", format_unformat_error, i);
11029           return -99;
11030         }
11031     }
11032
11033   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11034     {
11035       errmsg ("missing vtr operation or sw_if_index");
11036       return -99;
11037     }
11038
11039   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
11040     mp->sw_if_index = ntohl (sw_if_index);
11041   mp->vtr_op = ntohl (vtr_op);
11042   mp->push_dot1q = ntohl (push_dot1q);
11043   mp->tag1 = ntohl (tag1);
11044   mp->tag2 = ntohl (tag2);
11045
11046   S;
11047   W;
11048   /* NOTREACHED */
11049   return 0;
11050 }
11051
11052 static int
11053 api_create_vhost_user_if (vat_main_t * vam)
11054 {
11055   unformat_input_t *i = vam->input;
11056   vl_api_create_vhost_user_if_t *mp;
11057   f64 timeout;
11058   u8 *file_name;
11059   u8 is_server = 0;
11060   u8 file_name_set = 0;
11061   u32 custom_dev_instance = ~0;
11062   u8 hwaddr[6];
11063   u8 use_custom_mac = 0;
11064   u8 *tag = 0;
11065
11066   /* Shut up coverity */
11067   memset (hwaddr, 0, sizeof (hwaddr));
11068
11069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11070     {
11071       if (unformat (i, "socket %s", &file_name))
11072         {
11073           file_name_set = 1;
11074         }
11075       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11076         ;
11077       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11078         use_custom_mac = 1;
11079       else if (unformat (i, "server"))
11080         is_server = 1;
11081       else if (unformat (i, "tag %s", &tag))
11082         ;
11083       else
11084         break;
11085     }
11086
11087   if (file_name_set == 0)
11088     {
11089       errmsg ("missing socket file name");
11090       return -99;
11091     }
11092
11093   if (vec_len (file_name) > 255)
11094     {
11095       errmsg ("socket file name too long");
11096       return -99;
11097     }
11098   vec_add1 (file_name, 0);
11099
11100   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
11101
11102   mp->is_server = is_server;
11103   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11104   vec_free (file_name);
11105   if (custom_dev_instance != ~0)
11106     {
11107       mp->renumber = 1;
11108       mp->custom_dev_instance = ntohl (custom_dev_instance);
11109     }
11110   mp->use_custom_mac = use_custom_mac;
11111   clib_memcpy (mp->mac_address, hwaddr, 6);
11112   if (tag)
11113     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11114   vec_free (tag);
11115
11116   S;
11117   W;
11118   /* NOTREACHED */
11119   return 0;
11120 }
11121
11122 static int
11123 api_modify_vhost_user_if (vat_main_t * vam)
11124 {
11125   unformat_input_t *i = vam->input;
11126   vl_api_modify_vhost_user_if_t *mp;
11127   f64 timeout;
11128   u8 *file_name;
11129   u8 is_server = 0;
11130   u8 file_name_set = 0;
11131   u32 custom_dev_instance = ~0;
11132   u8 sw_if_index_set = 0;
11133   u32 sw_if_index = (u32) ~ 0;
11134
11135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11136     {
11137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11138         sw_if_index_set = 1;
11139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11140         sw_if_index_set = 1;
11141       else if (unformat (i, "socket %s", &file_name))
11142         {
11143           file_name_set = 1;
11144         }
11145       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11146         ;
11147       else if (unformat (i, "server"))
11148         is_server = 1;
11149       else
11150         break;
11151     }
11152
11153   if (sw_if_index_set == 0)
11154     {
11155       errmsg ("missing sw_if_index or interface name");
11156       return -99;
11157     }
11158
11159   if (file_name_set == 0)
11160     {
11161       errmsg ("missing socket file name");
11162       return -99;
11163     }
11164
11165   if (vec_len (file_name) > 255)
11166     {
11167       errmsg ("socket file name too long");
11168       return -99;
11169     }
11170   vec_add1 (file_name, 0);
11171
11172   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
11173
11174   mp->sw_if_index = ntohl (sw_if_index);
11175   mp->is_server = is_server;
11176   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11177   vec_free (file_name);
11178   if (custom_dev_instance != ~0)
11179     {
11180       mp->renumber = 1;
11181       mp->custom_dev_instance = ntohl (custom_dev_instance);
11182     }
11183
11184   S;
11185   W;
11186   /* NOTREACHED */
11187   return 0;
11188 }
11189
11190 static int
11191 api_delete_vhost_user_if (vat_main_t * vam)
11192 {
11193   unformat_input_t *i = vam->input;
11194   vl_api_delete_vhost_user_if_t *mp;
11195   f64 timeout;
11196   u32 sw_if_index = ~0;
11197   u8 sw_if_index_set = 0;
11198
11199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11200     {
11201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11202         sw_if_index_set = 1;
11203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11204         sw_if_index_set = 1;
11205       else
11206         break;
11207     }
11208
11209   if (sw_if_index_set == 0)
11210     {
11211       errmsg ("missing sw_if_index or interface name");
11212       return -99;
11213     }
11214
11215
11216   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
11217
11218   mp->sw_if_index = ntohl (sw_if_index);
11219
11220   S;
11221   W;
11222   /* NOTREACHED */
11223   return 0;
11224 }
11225
11226 static void vl_api_sw_interface_vhost_user_details_t_handler
11227   (vl_api_sw_interface_vhost_user_details_t * mp)
11228 {
11229   vat_main_t *vam = &vat_main;
11230
11231   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11232          (char *) mp->interface_name,
11233          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11234          clib_net_to_host_u64 (mp->features), mp->is_server,
11235          ntohl (mp->num_regions), (char *) mp->sock_filename);
11236   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11237 }
11238
11239 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11240   (vl_api_sw_interface_vhost_user_details_t * mp)
11241 {
11242   vat_main_t *vam = &vat_main;
11243   vat_json_node_t *node = NULL;
11244
11245   if (VAT_JSON_ARRAY != vam->json_tree.type)
11246     {
11247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11248       vat_json_init_array (&vam->json_tree);
11249     }
11250   node = vat_json_array_add (&vam->json_tree);
11251
11252   vat_json_init_object (node);
11253   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11254   vat_json_object_add_string_copy (node, "interface_name",
11255                                    mp->interface_name);
11256   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11257                             ntohl (mp->virtio_net_hdr_sz));
11258   vat_json_object_add_uint (node, "features",
11259                             clib_net_to_host_u64 (mp->features));
11260   vat_json_object_add_uint (node, "is_server", mp->is_server);
11261   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11262   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11263   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11264 }
11265
11266 static int
11267 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11268 {
11269   vl_api_sw_interface_vhost_user_dump_t *mp;
11270   f64 timeout;
11271   print (vam->ofp,
11272          "Interface name           idx hdr_sz features server regions filename");
11273
11274   /* Get list of vhost-user interfaces */
11275   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11276   S;
11277
11278   /* Use a control ping for synchronization */
11279   {
11280     vl_api_control_ping_t *mp;
11281     M (CONTROL_PING, control_ping);
11282     S;
11283   }
11284   W;
11285 }
11286
11287 static int
11288 api_show_version (vat_main_t * vam)
11289 {
11290   vl_api_show_version_t *mp;
11291   f64 timeout;
11292
11293   M (SHOW_VERSION, show_version);
11294
11295   S;
11296   W;
11297   /* NOTREACHED */
11298   return 0;
11299 }
11300
11301
11302 static int
11303 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11304 {
11305   unformat_input_t *line_input = vam->input;
11306   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11307   f64 timeout;
11308   ip4_address_t local4, remote4;
11309   ip6_address_t local6, remote6;
11310   u8 is_add = 1;
11311   u8 ipv4_set = 0, ipv6_set = 0;
11312   u8 local_set = 0;
11313   u8 remote_set = 0;
11314   u32 encap_vrf_id = 0;
11315   u32 decap_vrf_id = 0;
11316   u8 protocol = ~0;
11317   u32 vni;
11318   u8 vni_set = 0;
11319
11320   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11321     {
11322       if (unformat (line_input, "del"))
11323         is_add = 0;
11324       else if (unformat (line_input, "local %U",
11325                          unformat_ip4_address, &local4))
11326         {
11327           local_set = 1;
11328           ipv4_set = 1;
11329         }
11330       else if (unformat (line_input, "remote %U",
11331                          unformat_ip4_address, &remote4))
11332         {
11333           remote_set = 1;
11334           ipv4_set = 1;
11335         }
11336       else if (unformat (line_input, "local %U",
11337                          unformat_ip6_address, &local6))
11338         {
11339           local_set = 1;
11340           ipv6_set = 1;
11341         }
11342       else if (unformat (line_input, "remote %U",
11343                          unformat_ip6_address, &remote6))
11344         {
11345           remote_set = 1;
11346           ipv6_set = 1;
11347         }
11348       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11349         ;
11350       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11351         ;
11352       else if (unformat (line_input, "vni %d", &vni))
11353         vni_set = 1;
11354       else if (unformat (line_input, "next-ip4"))
11355         protocol = 1;
11356       else if (unformat (line_input, "next-ip6"))
11357         protocol = 2;
11358       else if (unformat (line_input, "next-ethernet"))
11359         protocol = 3;
11360       else if (unformat (line_input, "next-nsh"))
11361         protocol = 4;
11362       else
11363         {
11364           errmsg ("parse error '%U'", format_unformat_error, line_input);
11365           return -99;
11366         }
11367     }
11368
11369   if (local_set == 0)
11370     {
11371       errmsg ("tunnel local address not specified");
11372       return -99;
11373     }
11374   if (remote_set == 0)
11375     {
11376       errmsg ("tunnel remote address not specified");
11377       return -99;
11378     }
11379   if (ipv4_set && ipv6_set)
11380     {
11381       errmsg ("both IPv4 and IPv6 addresses specified");
11382       return -99;
11383     }
11384
11385   if (vni_set == 0)
11386     {
11387       errmsg ("vni not specified");
11388       return -99;
11389     }
11390
11391   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11392
11393
11394   if (ipv6_set)
11395     {
11396       clib_memcpy (&mp->local, &local6, sizeof (local6));
11397       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11398     }
11399   else
11400     {
11401       clib_memcpy (&mp->local, &local4, sizeof (local4));
11402       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11403     }
11404
11405   mp->encap_vrf_id = ntohl (encap_vrf_id);
11406   mp->decap_vrf_id = ntohl (decap_vrf_id);
11407   mp->protocol = protocol;
11408   mp->vni = ntohl (vni);
11409   mp->is_add = is_add;
11410   mp->is_ipv6 = ipv6_set;
11411
11412   S;
11413   W;
11414   /* NOTREACHED */
11415   return 0;
11416 }
11417
11418 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11419   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11420 {
11421   vat_main_t *vam = &vat_main;
11422
11423   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11424          ntohl (mp->sw_if_index),
11425          format_ip46_address, &(mp->local[0]),
11426          format_ip46_address, &(mp->remote[0]),
11427          ntohl (mp->vni),
11428          ntohl (mp->protocol),
11429          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11430 }
11431
11432 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11433   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11434 {
11435   vat_main_t *vam = &vat_main;
11436   vat_json_node_t *node = NULL;
11437   struct in_addr ip4;
11438   struct in6_addr ip6;
11439
11440   if (VAT_JSON_ARRAY != vam->json_tree.type)
11441     {
11442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11443       vat_json_init_array (&vam->json_tree);
11444     }
11445   node = vat_json_array_add (&vam->json_tree);
11446
11447   vat_json_init_object (node);
11448   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11449   if (mp->is_ipv6)
11450     {
11451       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11452       vat_json_object_add_ip6 (node, "local", ip6);
11453       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11454       vat_json_object_add_ip6 (node, "remote", ip6);
11455     }
11456   else
11457     {
11458       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11459       vat_json_object_add_ip4 (node, "local", ip4);
11460       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11461       vat_json_object_add_ip4 (node, "remote", ip4);
11462     }
11463   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11464   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11465   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11466   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11467   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11468 }
11469
11470 static int
11471 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11472 {
11473   unformat_input_t *i = vam->input;
11474   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11475   f64 timeout;
11476   u32 sw_if_index;
11477   u8 sw_if_index_set = 0;
11478
11479   /* Parse args required to build the message */
11480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11481     {
11482       if (unformat (i, "sw_if_index %d", &sw_if_index))
11483         sw_if_index_set = 1;
11484       else
11485         break;
11486     }
11487
11488   if (sw_if_index_set == 0)
11489     {
11490       sw_if_index = ~0;
11491     }
11492
11493   if (!vam->json_output)
11494     {
11495       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11496              "sw_if_index", "local", "remote", "vni",
11497              "protocol", "encap_vrf_id", "decap_vrf_id");
11498     }
11499
11500   /* Get list of vxlan-tunnel interfaces */
11501   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11502
11503   mp->sw_if_index = htonl (sw_if_index);
11504
11505   S;
11506
11507   /* Use a control ping for synchronization */
11508   {
11509     vl_api_control_ping_t *mp;
11510     M (CONTROL_PING, control_ping);
11511     S;
11512   }
11513   W;
11514 }
11515
11516 u8 *
11517 format_l2_fib_mac_address (u8 * s, va_list * args)
11518 {
11519   u8 *a = va_arg (*args, u8 *);
11520
11521   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11522                  a[2], a[3], a[4], a[5], a[6], a[7]);
11523 }
11524
11525 static void vl_api_l2_fib_table_entry_t_handler
11526   (vl_api_l2_fib_table_entry_t * mp)
11527 {
11528   vat_main_t *vam = &vat_main;
11529
11530   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11531          "       %d       %d     %d",
11532          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11533          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11534          mp->bvi_mac);
11535 }
11536
11537 static void vl_api_l2_fib_table_entry_t_handler_json
11538   (vl_api_l2_fib_table_entry_t * mp)
11539 {
11540   vat_main_t *vam = &vat_main;
11541   vat_json_node_t *node = NULL;
11542
11543   if (VAT_JSON_ARRAY != vam->json_tree.type)
11544     {
11545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11546       vat_json_init_array (&vam->json_tree);
11547     }
11548   node = vat_json_array_add (&vam->json_tree);
11549
11550   vat_json_init_object (node);
11551   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11552   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11553   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11554   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11555   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11556   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11557 }
11558
11559 static int
11560 api_l2_fib_table_dump (vat_main_t * vam)
11561 {
11562   unformat_input_t *i = vam->input;
11563   vl_api_l2_fib_table_dump_t *mp;
11564   f64 timeout;
11565   u32 bd_id;
11566   u8 bd_id_set = 0;
11567
11568   /* Parse args required to build the message */
11569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11570     {
11571       if (unformat (i, "bd_id %d", &bd_id))
11572         bd_id_set = 1;
11573       else
11574         break;
11575     }
11576
11577   if (bd_id_set == 0)
11578     {
11579       errmsg ("missing bridge domain");
11580       return -99;
11581     }
11582
11583   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11584
11585   /* Get list of l2 fib entries */
11586   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11587
11588   mp->bd_id = ntohl (bd_id);
11589   S;
11590
11591   /* Use a control ping for synchronization */
11592   {
11593     vl_api_control_ping_t *mp;
11594     M (CONTROL_PING, control_ping);
11595     S;
11596   }
11597   W;
11598 }
11599
11600
11601 static int
11602 api_interface_name_renumber (vat_main_t * vam)
11603 {
11604   unformat_input_t *line_input = vam->input;
11605   vl_api_interface_name_renumber_t *mp;
11606   u32 sw_if_index = ~0;
11607   f64 timeout;
11608   u32 new_show_dev_instance = ~0;
11609
11610   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11611     {
11612       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11613                     &sw_if_index))
11614         ;
11615       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11616         ;
11617       else if (unformat (line_input, "new_show_dev_instance %d",
11618                          &new_show_dev_instance))
11619         ;
11620       else
11621         break;
11622     }
11623
11624   if (sw_if_index == ~0)
11625     {
11626       errmsg ("missing interface name or sw_if_index");
11627       return -99;
11628     }
11629
11630   if (new_show_dev_instance == ~0)
11631     {
11632       errmsg ("missing new_show_dev_instance");
11633       return -99;
11634     }
11635
11636   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11637
11638   mp->sw_if_index = ntohl (sw_if_index);
11639   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11640
11641   S;
11642   W;
11643 }
11644
11645 static int
11646 api_want_ip4_arp_events (vat_main_t * vam)
11647 {
11648   unformat_input_t *line_input = vam->input;
11649   vl_api_want_ip4_arp_events_t *mp;
11650   f64 timeout;
11651   ip4_address_t address;
11652   int address_set = 0;
11653   u32 enable_disable = 1;
11654
11655   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11656     {
11657       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11658         address_set = 1;
11659       else if (unformat (line_input, "del"))
11660         enable_disable = 0;
11661       else
11662         break;
11663     }
11664
11665   if (address_set == 0)
11666     {
11667       errmsg ("missing addresses");
11668       return -99;
11669     }
11670
11671   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11672   mp->enable_disable = enable_disable;
11673   mp->pid = getpid ();
11674   mp->address = address.as_u32;
11675
11676   S;
11677   W;
11678 }
11679
11680 static int
11681 api_want_ip6_nd_events (vat_main_t * vam)
11682 {
11683   unformat_input_t *line_input = vam->input;
11684   vl_api_want_ip6_nd_events_t *mp;
11685   f64 timeout;
11686   ip6_address_t address;
11687   int address_set = 0;
11688   u32 enable_disable = 1;
11689
11690   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11691     {
11692       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11693         address_set = 1;
11694       else if (unformat (line_input, "del"))
11695         enable_disable = 0;
11696       else
11697         break;
11698     }
11699
11700   if (address_set == 0)
11701     {
11702       errmsg ("missing addresses");
11703       return -99;
11704     }
11705
11706   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11707   mp->enable_disable = enable_disable;
11708   mp->pid = getpid ();
11709   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11710
11711   S;
11712   W;
11713 }
11714
11715 static int
11716 api_input_acl_set_interface (vat_main_t * vam)
11717 {
11718   unformat_input_t *i = vam->input;
11719   vl_api_input_acl_set_interface_t *mp;
11720   f64 timeout;
11721   u32 sw_if_index;
11722   int sw_if_index_set;
11723   u32 ip4_table_index = ~0;
11724   u32 ip6_table_index = ~0;
11725   u32 l2_table_index = ~0;
11726   u8 is_add = 1;
11727
11728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11729     {
11730       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11731         sw_if_index_set = 1;
11732       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11733         sw_if_index_set = 1;
11734       else if (unformat (i, "del"))
11735         is_add = 0;
11736       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11737         ;
11738       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11739         ;
11740       else if (unformat (i, "l2-table %d", &l2_table_index))
11741         ;
11742       else
11743         {
11744           clib_warning ("parse error '%U'", format_unformat_error, i);
11745           return -99;
11746         }
11747     }
11748
11749   if (sw_if_index_set == 0)
11750     {
11751       errmsg ("missing interface name or sw_if_index");
11752       return -99;
11753     }
11754
11755   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11756
11757   mp->sw_if_index = ntohl (sw_if_index);
11758   mp->ip4_table_index = ntohl (ip4_table_index);
11759   mp->ip6_table_index = ntohl (ip6_table_index);
11760   mp->l2_table_index = ntohl (l2_table_index);
11761   mp->is_add = is_add;
11762
11763   S;
11764   W;
11765   /* NOTREACHED */
11766   return 0;
11767 }
11768
11769 static int
11770 api_ip_address_dump (vat_main_t * vam)
11771 {
11772   unformat_input_t *i = vam->input;
11773   vl_api_ip_address_dump_t *mp;
11774   u32 sw_if_index = ~0;
11775   u8 sw_if_index_set = 0;
11776   u8 ipv4_set = 0;
11777   u8 ipv6_set = 0;
11778   f64 timeout;
11779
11780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11781     {
11782       if (unformat (i, "sw_if_index %d", &sw_if_index))
11783         sw_if_index_set = 1;
11784       else
11785         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11786         sw_if_index_set = 1;
11787       else if (unformat (i, "ipv4"))
11788         ipv4_set = 1;
11789       else if (unformat (i, "ipv6"))
11790         ipv6_set = 1;
11791       else
11792         break;
11793     }
11794
11795   if (ipv4_set && ipv6_set)
11796     {
11797       errmsg ("ipv4 and ipv6 flags cannot be both set");
11798       return -99;
11799     }
11800
11801   if ((!ipv4_set) && (!ipv6_set))
11802     {
11803       errmsg ("no ipv4 nor ipv6 flag set");
11804       return -99;
11805     }
11806
11807   if (sw_if_index_set == 0)
11808     {
11809       errmsg ("missing interface name or sw_if_index");
11810       return -99;
11811     }
11812
11813   vam->current_sw_if_index = sw_if_index;
11814   vam->is_ipv6 = ipv6_set;
11815
11816   M (IP_ADDRESS_DUMP, ip_address_dump);
11817   mp->sw_if_index = ntohl (sw_if_index);
11818   mp->is_ipv6 = ipv6_set;
11819   S;
11820
11821   /* Use a control ping for synchronization */
11822   {
11823     vl_api_control_ping_t *mp;
11824     M (CONTROL_PING, control_ping);
11825     S;
11826   }
11827   W;
11828 }
11829
11830 static int
11831 api_ip_dump (vat_main_t * vam)
11832 {
11833   vl_api_ip_dump_t *mp;
11834   unformat_input_t *in = vam->input;
11835   int ipv4_set = 0;
11836   int ipv6_set = 0;
11837   int is_ipv6;
11838   f64 timeout;
11839   int i;
11840
11841   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11842     {
11843       if (unformat (in, "ipv4"))
11844         ipv4_set = 1;
11845       else if (unformat (in, "ipv6"))
11846         ipv6_set = 1;
11847       else
11848         break;
11849     }
11850
11851   if (ipv4_set && ipv6_set)
11852     {
11853       errmsg ("ipv4 and ipv6 flags cannot be both set");
11854       return -99;
11855     }
11856
11857   if ((!ipv4_set) && (!ipv6_set))
11858     {
11859       errmsg ("no ipv4 nor ipv6 flag set");
11860       return -99;
11861     }
11862
11863   is_ipv6 = ipv6_set;
11864   vam->is_ipv6 = is_ipv6;
11865
11866   /* free old data */
11867   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11868     {
11869       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11870     }
11871   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11872
11873   M (IP_DUMP, ip_dump);
11874   mp->is_ipv6 = ipv6_set;
11875   S;
11876
11877   /* Use a control ping for synchronization */
11878   {
11879     vl_api_control_ping_t *mp;
11880     M (CONTROL_PING, control_ping);
11881     S;
11882   }
11883   W;
11884 }
11885
11886 static int
11887 api_ipsec_spd_add_del (vat_main_t * vam)
11888 {
11889   unformat_input_t *i = vam->input;
11890   vl_api_ipsec_spd_add_del_t *mp;
11891   f64 timeout;
11892   u32 spd_id = ~0;
11893   u8 is_add = 1;
11894
11895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11896     {
11897       if (unformat (i, "spd_id %d", &spd_id))
11898         ;
11899       else if (unformat (i, "del"))
11900         is_add = 0;
11901       else
11902         {
11903           clib_warning ("parse error '%U'", format_unformat_error, i);
11904           return -99;
11905         }
11906     }
11907   if (spd_id == ~0)
11908     {
11909       errmsg ("spd_id must be set");
11910       return -99;
11911     }
11912
11913   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11914
11915   mp->spd_id = ntohl (spd_id);
11916   mp->is_add = is_add;
11917
11918   S;
11919   W;
11920   /* NOTREACHED */
11921   return 0;
11922 }
11923
11924 static int
11925 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11926 {
11927   unformat_input_t *i = vam->input;
11928   vl_api_ipsec_interface_add_del_spd_t *mp;
11929   f64 timeout;
11930   u32 sw_if_index;
11931   u8 sw_if_index_set = 0;
11932   u32 spd_id = (u32) ~ 0;
11933   u8 is_add = 1;
11934
11935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11936     {
11937       if (unformat (i, "del"))
11938         is_add = 0;
11939       else if (unformat (i, "spd_id %d", &spd_id))
11940         ;
11941       else
11942         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11943         sw_if_index_set = 1;
11944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11945         sw_if_index_set = 1;
11946       else
11947         {
11948           clib_warning ("parse error '%U'", format_unformat_error, i);
11949           return -99;
11950         }
11951
11952     }
11953
11954   if (spd_id == (u32) ~ 0)
11955     {
11956       errmsg ("spd_id must be set");
11957       return -99;
11958     }
11959
11960   if (sw_if_index_set == 0)
11961     {
11962       errmsg ("missing interface name or sw_if_index");
11963       return -99;
11964     }
11965
11966   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11967
11968   mp->spd_id = ntohl (spd_id);
11969   mp->sw_if_index = ntohl (sw_if_index);
11970   mp->is_add = is_add;
11971
11972   S;
11973   W;
11974   /* NOTREACHED */
11975   return 0;
11976 }
11977
11978 static int
11979 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11980 {
11981   unformat_input_t *i = vam->input;
11982   vl_api_ipsec_spd_add_del_entry_t *mp;
11983   f64 timeout;
11984   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11985   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11986   i32 priority = 0;
11987   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11988   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11989   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11990   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11991
11992   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11993   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11994   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11995   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11996   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11997   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11998
11999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12000     {
12001       if (unformat (i, "del"))
12002         is_add = 0;
12003       if (unformat (i, "outbound"))
12004         is_outbound = 1;
12005       if (unformat (i, "inbound"))
12006         is_outbound = 0;
12007       else if (unformat (i, "spd_id %d", &spd_id))
12008         ;
12009       else if (unformat (i, "sa_id %d", &sa_id))
12010         ;
12011       else if (unformat (i, "priority %d", &priority))
12012         ;
12013       else if (unformat (i, "protocol %d", &protocol))
12014         ;
12015       else if (unformat (i, "lport_start %d", &lport_start))
12016         ;
12017       else if (unformat (i, "lport_stop %d", &lport_stop))
12018         ;
12019       else if (unformat (i, "rport_start %d", &rport_start))
12020         ;
12021       else if (unformat (i, "rport_stop %d", &rport_stop))
12022         ;
12023       else
12024         if (unformat
12025             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12026         {
12027           is_ipv6 = 0;
12028           is_ip_any = 0;
12029         }
12030       else
12031         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12032         {
12033           is_ipv6 = 0;
12034           is_ip_any = 0;
12035         }
12036       else
12037         if (unformat
12038             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12039         {
12040           is_ipv6 = 0;
12041           is_ip_any = 0;
12042         }
12043       else
12044         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12045         {
12046           is_ipv6 = 0;
12047           is_ip_any = 0;
12048         }
12049       else
12050         if (unformat
12051             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12052         {
12053           is_ipv6 = 1;
12054           is_ip_any = 0;
12055         }
12056       else
12057         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12058         {
12059           is_ipv6 = 1;
12060           is_ip_any = 0;
12061         }
12062       else
12063         if (unformat
12064             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12065         {
12066           is_ipv6 = 1;
12067           is_ip_any = 0;
12068         }
12069       else
12070         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12071         {
12072           is_ipv6 = 1;
12073           is_ip_any = 0;
12074         }
12075       else
12076         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12077         {
12078           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12079             {
12080               clib_warning ("unsupported action: 'resolve'");
12081               return -99;
12082             }
12083         }
12084       else
12085         {
12086           clib_warning ("parse error '%U'", format_unformat_error, i);
12087           return -99;
12088         }
12089
12090     }
12091
12092   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
12093
12094   mp->spd_id = ntohl (spd_id);
12095   mp->priority = ntohl (priority);
12096   mp->is_outbound = is_outbound;
12097
12098   mp->is_ipv6 = is_ipv6;
12099   if (is_ipv6 || is_ip_any)
12100     {
12101       clib_memcpy (mp->remote_address_start, &raddr6_start,
12102                    sizeof (ip6_address_t));
12103       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12104                    sizeof (ip6_address_t));
12105       clib_memcpy (mp->local_address_start, &laddr6_start,
12106                    sizeof (ip6_address_t));
12107       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12108                    sizeof (ip6_address_t));
12109     }
12110   else
12111     {
12112       clib_memcpy (mp->remote_address_start, &raddr4_start,
12113                    sizeof (ip4_address_t));
12114       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12115                    sizeof (ip4_address_t));
12116       clib_memcpy (mp->local_address_start, &laddr4_start,
12117                    sizeof (ip4_address_t));
12118       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12119                    sizeof (ip4_address_t));
12120     }
12121   mp->protocol = (u8) protocol;
12122   mp->local_port_start = ntohs ((u16) lport_start);
12123   mp->local_port_stop = ntohs ((u16) lport_stop);
12124   mp->remote_port_start = ntohs ((u16) rport_start);
12125   mp->remote_port_stop = ntohs ((u16) rport_stop);
12126   mp->policy = (u8) policy;
12127   mp->sa_id = ntohl (sa_id);
12128   mp->is_add = is_add;
12129   mp->is_ip_any = is_ip_any;
12130   S;
12131   W;
12132   /* NOTREACHED */
12133   return 0;
12134 }
12135
12136 static int
12137 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12138 {
12139   unformat_input_t *i = vam->input;
12140   vl_api_ipsec_sad_add_del_entry_t *mp;
12141   f64 timeout;
12142   u32 sad_id = 0, spi = 0;
12143   u8 *ck = 0, *ik = 0;
12144   u8 is_add = 1;
12145
12146   u8 protocol = IPSEC_PROTOCOL_AH;
12147   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12148   u32 crypto_alg = 0, integ_alg = 0;
12149   ip4_address_t tun_src4;
12150   ip4_address_t tun_dst4;
12151   ip6_address_t tun_src6;
12152   ip6_address_t tun_dst6;
12153
12154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12155     {
12156       if (unformat (i, "del"))
12157         is_add = 0;
12158       else if (unformat (i, "sad_id %d", &sad_id))
12159         ;
12160       else if (unformat (i, "spi %d", &spi))
12161         ;
12162       else if (unformat (i, "esp"))
12163         protocol = IPSEC_PROTOCOL_ESP;
12164       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12165         {
12166           is_tunnel = 1;
12167           is_tunnel_ipv6 = 0;
12168         }
12169       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12170         {
12171           is_tunnel = 1;
12172           is_tunnel_ipv6 = 0;
12173         }
12174       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12175         {
12176           is_tunnel = 1;
12177           is_tunnel_ipv6 = 1;
12178         }
12179       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12180         {
12181           is_tunnel = 1;
12182           is_tunnel_ipv6 = 1;
12183         }
12184       else
12185         if (unformat
12186             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12187         {
12188           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12189               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12190             {
12191               clib_warning ("unsupported crypto-alg: '%U'",
12192                             format_ipsec_crypto_alg, crypto_alg);
12193               return -99;
12194             }
12195         }
12196       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12197         ;
12198       else
12199         if (unformat
12200             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12201         {
12202 #if DPDK_CRYPTO==1
12203           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
12204 #else
12205           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12206 #endif
12207               integ_alg >= IPSEC_INTEG_N_ALG)
12208             {
12209               clib_warning ("unsupported integ-alg: '%U'",
12210                             format_ipsec_integ_alg, integ_alg);
12211               return -99;
12212             }
12213         }
12214       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12215         ;
12216       else
12217         {
12218           clib_warning ("parse error '%U'", format_unformat_error, i);
12219           return -99;
12220         }
12221
12222     }
12223
12224 #if DPDK_CRYPTO==1
12225   /*Special cases, aes-gcm-128 encryption */
12226   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
12227     {
12228       if (integ_alg != IPSEC_INTEG_ALG_NONE
12229           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
12230         {
12231           clib_warning
12232             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
12233           return -99;
12234         }
12235       else                      /*set integ-alg internally to aes-gcm-128 */
12236         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
12237     }
12238   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
12239     {
12240       clib_warning ("unsupported integ-alg: aes-gcm-128");
12241       return -99;
12242     }
12243   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
12244     {
12245       clib_warning ("unsupported integ-alg: none");
12246       return -99;
12247     }
12248 #endif
12249
12250
12251   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12252
12253   mp->sad_id = ntohl (sad_id);
12254   mp->is_add = is_add;
12255   mp->protocol = protocol;
12256   mp->spi = ntohl (spi);
12257   mp->is_tunnel = is_tunnel;
12258   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12259   mp->crypto_algorithm = crypto_alg;
12260   mp->integrity_algorithm = integ_alg;
12261   mp->crypto_key_length = vec_len (ck);
12262   mp->integrity_key_length = vec_len (ik);
12263
12264   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12265     mp->crypto_key_length = sizeof (mp->crypto_key);
12266
12267   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12268     mp->integrity_key_length = sizeof (mp->integrity_key);
12269
12270   if (ck)
12271     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12272   if (ik)
12273     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12274
12275   if (is_tunnel)
12276     {
12277       if (is_tunnel_ipv6)
12278         {
12279           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12280                        sizeof (ip6_address_t));
12281           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12282                        sizeof (ip6_address_t));
12283         }
12284       else
12285         {
12286           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12287                        sizeof (ip4_address_t));
12288           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12289                        sizeof (ip4_address_t));
12290         }
12291     }
12292
12293   S;
12294   W;
12295   /* NOTREACHED */
12296   return 0;
12297 }
12298
12299 static int
12300 api_ipsec_sa_set_key (vat_main_t * vam)
12301 {
12302   unformat_input_t *i = vam->input;
12303   vl_api_ipsec_sa_set_key_t *mp;
12304   f64 timeout;
12305   u32 sa_id;
12306   u8 *ck = 0, *ik = 0;
12307
12308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12309     {
12310       if (unformat (i, "sa_id %d", &sa_id))
12311         ;
12312       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12313         ;
12314       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12315         ;
12316       else
12317         {
12318           clib_warning ("parse error '%U'", format_unformat_error, i);
12319           return -99;
12320         }
12321     }
12322
12323   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12324
12325   mp->sa_id = ntohl (sa_id);
12326   mp->crypto_key_length = vec_len (ck);
12327   mp->integrity_key_length = vec_len (ik);
12328
12329   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12330     mp->crypto_key_length = sizeof (mp->crypto_key);
12331
12332   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12333     mp->integrity_key_length = sizeof (mp->integrity_key);
12334
12335   if (ck)
12336     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12337   if (ik)
12338     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12339
12340   S;
12341   W;
12342   /* NOTREACHED */
12343   return 0;
12344 }
12345
12346 static int
12347 api_ikev2_profile_add_del (vat_main_t * vam)
12348 {
12349   unformat_input_t *i = vam->input;
12350   vl_api_ikev2_profile_add_del_t *mp;
12351   f64 timeout;
12352   u8 is_add = 1;
12353   u8 *name = 0;
12354
12355   const char *valid_chars = "a-zA-Z0-9_";
12356
12357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12358     {
12359       if (unformat (i, "del"))
12360         is_add = 0;
12361       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12362         vec_add1 (name, 0);
12363       else
12364         {
12365           errmsg ("parse error '%U'", format_unformat_error, i);
12366           return -99;
12367         }
12368     }
12369
12370   if (!vec_len (name))
12371     {
12372       errmsg ("profile name must be specified");
12373       return -99;
12374     }
12375
12376   if (vec_len (name) > 64)
12377     {
12378       errmsg ("profile name too long");
12379       return -99;
12380     }
12381
12382   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12383
12384   clib_memcpy (mp->name, name, vec_len (name));
12385   mp->is_add = is_add;
12386   vec_free (name);
12387
12388   S;
12389   W;
12390   /* NOTREACHED */
12391   return 0;
12392 }
12393
12394 static int
12395 api_ikev2_profile_set_auth (vat_main_t * vam)
12396 {
12397   unformat_input_t *i = vam->input;
12398   vl_api_ikev2_profile_set_auth_t *mp;
12399   f64 timeout;
12400   u8 *name = 0;
12401   u8 *data = 0;
12402   u32 auth_method = 0;
12403   u8 is_hex = 0;
12404
12405   const char *valid_chars = "a-zA-Z0-9_";
12406
12407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12408     {
12409       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12410         vec_add1 (name, 0);
12411       else if (unformat (i, "auth_method %U",
12412                          unformat_ikev2_auth_method, &auth_method))
12413         ;
12414       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12415         is_hex = 1;
12416       else if (unformat (i, "auth_data %v", &data))
12417         ;
12418       else
12419         {
12420           errmsg ("parse error '%U'", format_unformat_error, i);
12421           return -99;
12422         }
12423     }
12424
12425   if (!vec_len (name))
12426     {
12427       errmsg ("profile name must be specified");
12428       return -99;
12429     }
12430
12431   if (vec_len (name) > 64)
12432     {
12433       errmsg ("profile name too long");
12434       return -99;
12435     }
12436
12437   if (!vec_len (data))
12438     {
12439       errmsg ("auth_data must be specified");
12440       return -99;
12441     }
12442
12443   if (!auth_method)
12444     {
12445       errmsg ("auth_method must be specified");
12446       return -99;
12447     }
12448
12449   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12450
12451   mp->is_hex = is_hex;
12452   mp->auth_method = (u8) auth_method;
12453   mp->data_len = vec_len (data);
12454   clib_memcpy (mp->name, name, vec_len (name));
12455   clib_memcpy (mp->data, data, vec_len (data));
12456   vec_free (name);
12457   vec_free (data);
12458
12459   S;
12460   W;
12461   /* NOTREACHED */
12462   return 0;
12463 }
12464
12465 static int
12466 api_ikev2_profile_set_id (vat_main_t * vam)
12467 {
12468   unformat_input_t *i = vam->input;
12469   vl_api_ikev2_profile_set_id_t *mp;
12470   f64 timeout;
12471   u8 *name = 0;
12472   u8 *data = 0;
12473   u8 is_local = 0;
12474   u32 id_type = 0;
12475   ip4_address_t ip4;
12476
12477   const char *valid_chars = "a-zA-Z0-9_";
12478
12479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12480     {
12481       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12482         vec_add1 (name, 0);
12483       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12484         ;
12485       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12486         {
12487           data = vec_new (u8, 4);
12488           clib_memcpy (data, ip4.as_u8, 4);
12489         }
12490       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12491         ;
12492       else if (unformat (i, "id_data %v", &data))
12493         ;
12494       else if (unformat (i, "local"))
12495         is_local = 1;
12496       else if (unformat (i, "remote"))
12497         is_local = 0;
12498       else
12499         {
12500           errmsg ("parse error '%U'", format_unformat_error, i);
12501           return -99;
12502         }
12503     }
12504
12505   if (!vec_len (name))
12506     {
12507       errmsg ("profile name must be specified");
12508       return -99;
12509     }
12510
12511   if (vec_len (name) > 64)
12512     {
12513       errmsg ("profile name too long");
12514       return -99;
12515     }
12516
12517   if (!vec_len (data))
12518     {
12519       errmsg ("id_data must be specified");
12520       return -99;
12521     }
12522
12523   if (!id_type)
12524     {
12525       errmsg ("id_type must be specified");
12526       return -99;
12527     }
12528
12529   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12530
12531   mp->is_local = is_local;
12532   mp->id_type = (u8) id_type;
12533   mp->data_len = vec_len (data);
12534   clib_memcpy (mp->name, name, vec_len (name));
12535   clib_memcpy (mp->data, data, vec_len (data));
12536   vec_free (name);
12537   vec_free (data);
12538
12539   S;
12540   W;
12541   /* NOTREACHED */
12542   return 0;
12543 }
12544
12545 static int
12546 api_ikev2_profile_set_ts (vat_main_t * vam)
12547 {
12548   unformat_input_t *i = vam->input;
12549   vl_api_ikev2_profile_set_ts_t *mp;
12550   f64 timeout;
12551   u8 *name = 0;
12552   u8 is_local = 0;
12553   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12554   ip4_address_t start_addr, end_addr;
12555
12556   const char *valid_chars = "a-zA-Z0-9_";
12557
12558   start_addr.as_u32 = 0;
12559   end_addr.as_u32 = (u32) ~ 0;
12560
12561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12562     {
12563       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12564         vec_add1 (name, 0);
12565       else if (unformat (i, "protocol %d", &proto))
12566         ;
12567       else if (unformat (i, "start_port %d", &start_port))
12568         ;
12569       else if (unformat (i, "end_port %d", &end_port))
12570         ;
12571       else
12572         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12573         ;
12574       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12575         ;
12576       else if (unformat (i, "local"))
12577         is_local = 1;
12578       else if (unformat (i, "remote"))
12579         is_local = 0;
12580       else
12581         {
12582           errmsg ("parse error '%U'", format_unformat_error, i);
12583           return -99;
12584         }
12585     }
12586
12587   if (!vec_len (name))
12588     {
12589       errmsg ("profile name must be specified");
12590       return -99;
12591     }
12592
12593   if (vec_len (name) > 64)
12594     {
12595       errmsg ("profile name too long");
12596       return -99;
12597     }
12598
12599   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12600
12601   mp->is_local = is_local;
12602   mp->proto = (u8) proto;
12603   mp->start_port = (u16) start_port;
12604   mp->end_port = (u16) end_port;
12605   mp->start_addr = start_addr.as_u32;
12606   mp->end_addr = end_addr.as_u32;
12607   clib_memcpy (mp->name, name, vec_len (name));
12608   vec_free (name);
12609
12610   S;
12611   W;
12612   /* NOTREACHED */
12613   return 0;
12614 }
12615
12616 static int
12617 api_ikev2_set_local_key (vat_main_t * vam)
12618 {
12619   unformat_input_t *i = vam->input;
12620   vl_api_ikev2_set_local_key_t *mp;
12621   f64 timeout;
12622   u8 *file = 0;
12623
12624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12625     {
12626       if (unformat (i, "file %v", &file))
12627         vec_add1 (file, 0);
12628       else
12629         {
12630           errmsg ("parse error '%U'", format_unformat_error, i);
12631           return -99;
12632         }
12633     }
12634
12635   if (!vec_len (file))
12636     {
12637       errmsg ("RSA key file must be specified");
12638       return -99;
12639     }
12640
12641   if (vec_len (file) > 256)
12642     {
12643       errmsg ("file name too long");
12644       return -99;
12645     }
12646
12647   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12648
12649   clib_memcpy (mp->key_file, file, vec_len (file));
12650   vec_free (file);
12651
12652   S;
12653   W;
12654   /* NOTREACHED */
12655   return 0;
12656 }
12657
12658 /*
12659  * MAP
12660  */
12661 static int
12662 api_map_add_domain (vat_main_t * vam)
12663 {
12664   unformat_input_t *i = vam->input;
12665   vl_api_map_add_domain_t *mp;
12666   f64 timeout;
12667
12668   ip4_address_t ip4_prefix;
12669   ip6_address_t ip6_prefix;
12670   ip6_address_t ip6_src;
12671   u32 num_m_args = 0;
12672   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12673     0, psid_length = 0;
12674   u8 is_translation = 0;
12675   u32 mtu = 0;
12676   u32 ip6_src_len = 128;
12677
12678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12679     {
12680       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12681                     &ip4_prefix, &ip4_prefix_len))
12682         num_m_args++;
12683       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12684                          &ip6_prefix, &ip6_prefix_len))
12685         num_m_args++;
12686       else
12687         if (unformat
12688             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12689              &ip6_src_len))
12690         num_m_args++;
12691       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12692         num_m_args++;
12693       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12694         num_m_args++;
12695       else if (unformat (i, "psid-offset %d", &psid_offset))
12696         num_m_args++;
12697       else if (unformat (i, "psid-len %d", &psid_length))
12698         num_m_args++;
12699       else if (unformat (i, "mtu %d", &mtu))
12700         num_m_args++;
12701       else if (unformat (i, "map-t"))
12702         is_translation = 1;
12703       else
12704         {
12705           clib_warning ("parse error '%U'", format_unformat_error, i);
12706           return -99;
12707         }
12708     }
12709
12710   if (num_m_args < 3)
12711     {
12712       errmsg ("mandatory argument(s) missing");
12713       return -99;
12714     }
12715
12716   /* Construct the API message */
12717   M (MAP_ADD_DOMAIN, map_add_domain);
12718
12719   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12720   mp->ip4_prefix_len = ip4_prefix_len;
12721
12722   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12723   mp->ip6_prefix_len = ip6_prefix_len;
12724
12725   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12726   mp->ip6_src_prefix_len = ip6_src_len;
12727
12728   mp->ea_bits_len = ea_bits_len;
12729   mp->psid_offset = psid_offset;
12730   mp->psid_length = psid_length;
12731   mp->is_translation = is_translation;
12732   mp->mtu = htons (mtu);
12733
12734   /* send it... */
12735   S;
12736
12737   /* Wait for a reply, return good/bad news  */
12738   W;
12739 }
12740
12741 static int
12742 api_map_del_domain (vat_main_t * vam)
12743 {
12744   unformat_input_t *i = vam->input;
12745   vl_api_map_del_domain_t *mp;
12746   f64 timeout;
12747
12748   u32 num_m_args = 0;
12749   u32 index;
12750
12751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12752     {
12753       if (unformat (i, "index %d", &index))
12754         num_m_args++;
12755       else
12756         {
12757           clib_warning ("parse error '%U'", format_unformat_error, i);
12758           return -99;
12759         }
12760     }
12761
12762   if (num_m_args != 1)
12763     {
12764       errmsg ("mandatory argument(s) missing");
12765       return -99;
12766     }
12767
12768   /* Construct the API message */
12769   M (MAP_DEL_DOMAIN, map_del_domain);
12770
12771   mp->index = ntohl (index);
12772
12773   /* send it... */
12774   S;
12775
12776   /* Wait for a reply, return good/bad news  */
12777   W;
12778 }
12779
12780 static int
12781 api_map_add_del_rule (vat_main_t * vam)
12782 {
12783   unformat_input_t *i = vam->input;
12784   vl_api_map_add_del_rule_t *mp;
12785   f64 timeout;
12786   u8 is_add = 1;
12787   ip6_address_t ip6_dst;
12788   u32 num_m_args = 0, index, psid = 0;
12789
12790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12791     {
12792       if (unformat (i, "index %d", &index))
12793         num_m_args++;
12794       else if (unformat (i, "psid %d", &psid))
12795         num_m_args++;
12796       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12797         num_m_args++;
12798       else if (unformat (i, "del"))
12799         {
12800           is_add = 0;
12801         }
12802       else
12803         {
12804           clib_warning ("parse error '%U'", format_unformat_error, i);
12805           return -99;
12806         }
12807     }
12808
12809   /* Construct the API message */
12810   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12811
12812   mp->index = ntohl (index);
12813   mp->is_add = is_add;
12814   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12815   mp->psid = ntohs (psid);
12816
12817   /* send it... */
12818   S;
12819
12820   /* Wait for a reply, return good/bad news  */
12821   W;
12822 }
12823
12824 static int
12825 api_map_domain_dump (vat_main_t * vam)
12826 {
12827   vl_api_map_domain_dump_t *mp;
12828   f64 timeout;
12829
12830   /* Construct the API message */
12831   M (MAP_DOMAIN_DUMP, map_domain_dump);
12832
12833   /* send it... */
12834   S;
12835
12836   /* Use a control ping for synchronization */
12837   {
12838     vl_api_control_ping_t *mp;
12839     M (CONTROL_PING, control_ping);
12840     S;
12841   }
12842   W;
12843 }
12844
12845 static int
12846 api_map_rule_dump (vat_main_t * vam)
12847 {
12848   unformat_input_t *i = vam->input;
12849   vl_api_map_rule_dump_t *mp;
12850   f64 timeout;
12851   u32 domain_index = ~0;
12852
12853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12854     {
12855       if (unformat (i, "index %u", &domain_index))
12856         ;
12857       else
12858         break;
12859     }
12860
12861   if (domain_index == ~0)
12862     {
12863       clib_warning ("parse error: domain index expected");
12864       return -99;
12865     }
12866
12867   /* Construct the API message */
12868   M (MAP_RULE_DUMP, map_rule_dump);
12869
12870   mp->domain_index = htonl (domain_index);
12871
12872   /* send it... */
12873   S;
12874
12875   /* Use a control ping for synchronization */
12876   {
12877     vl_api_control_ping_t *mp;
12878     M (CONTROL_PING, control_ping);
12879     S;
12880   }
12881   W;
12882 }
12883
12884 static void vl_api_map_add_domain_reply_t_handler
12885   (vl_api_map_add_domain_reply_t * mp)
12886 {
12887   vat_main_t *vam = &vat_main;
12888   i32 retval = ntohl (mp->retval);
12889
12890   if (vam->async_mode)
12891     {
12892       vam->async_errors += (retval < 0);
12893     }
12894   else
12895     {
12896       vam->retval = retval;
12897       vam->result_ready = 1;
12898     }
12899 }
12900
12901 static void vl_api_map_add_domain_reply_t_handler_json
12902   (vl_api_map_add_domain_reply_t * mp)
12903 {
12904   vat_main_t *vam = &vat_main;
12905   vat_json_node_t node;
12906
12907   vat_json_init_object (&node);
12908   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12909   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12910
12911   vat_json_print (vam->ofp, &node);
12912   vat_json_free (&node);
12913
12914   vam->retval = ntohl (mp->retval);
12915   vam->result_ready = 1;
12916 }
12917
12918 static int
12919 api_get_first_msg_id (vat_main_t * vam)
12920 {
12921   vl_api_get_first_msg_id_t *mp;
12922   f64 timeout;
12923   unformat_input_t *i = vam->input;
12924   u8 *name;
12925   u8 name_set = 0;
12926
12927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12928     {
12929       if (unformat (i, "client %s", &name))
12930         name_set = 1;
12931       else
12932         break;
12933     }
12934
12935   if (name_set == 0)
12936     {
12937       errmsg ("missing client name");
12938       return -99;
12939     }
12940   vec_add1 (name, 0);
12941
12942   if (vec_len (name) > 63)
12943     {
12944       errmsg ("client name too long");
12945       return -99;
12946     }
12947
12948   M (GET_FIRST_MSG_ID, get_first_msg_id);
12949   clib_memcpy (mp->name, name, vec_len (name));
12950   S;
12951   W;
12952   /* NOTREACHED */
12953   return 0;
12954 }
12955
12956 static int
12957 api_cop_interface_enable_disable (vat_main_t * vam)
12958 {
12959   unformat_input_t *line_input = vam->input;
12960   vl_api_cop_interface_enable_disable_t *mp;
12961   f64 timeout;
12962   u32 sw_if_index = ~0;
12963   u8 enable_disable = 1;
12964
12965   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12966     {
12967       if (unformat (line_input, "disable"))
12968         enable_disable = 0;
12969       if (unformat (line_input, "enable"))
12970         enable_disable = 1;
12971       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12972                          vam, &sw_if_index))
12973         ;
12974       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12975         ;
12976       else
12977         break;
12978     }
12979
12980   if (sw_if_index == ~0)
12981     {
12982       errmsg ("missing interface name or sw_if_index");
12983       return -99;
12984     }
12985
12986   /* Construct the API message */
12987   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12988   mp->sw_if_index = ntohl (sw_if_index);
12989   mp->enable_disable = enable_disable;
12990
12991   /* send it... */
12992   S;
12993   /* Wait for the reply */
12994   W;
12995 }
12996
12997 static int
12998 api_cop_whitelist_enable_disable (vat_main_t * vam)
12999 {
13000   unformat_input_t *line_input = vam->input;
13001   vl_api_cop_whitelist_enable_disable_t *mp;
13002   f64 timeout;
13003   u32 sw_if_index = ~0;
13004   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13005   u32 fib_id = 0;
13006
13007   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13008     {
13009       if (unformat (line_input, "ip4"))
13010         ip4 = 1;
13011       else if (unformat (line_input, "ip6"))
13012         ip6 = 1;
13013       else if (unformat (line_input, "default"))
13014         default_cop = 1;
13015       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13016                          vam, &sw_if_index))
13017         ;
13018       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13019         ;
13020       else if (unformat (line_input, "fib-id %d", &fib_id))
13021         ;
13022       else
13023         break;
13024     }
13025
13026   if (sw_if_index == ~0)
13027     {
13028       errmsg ("missing interface name or sw_if_index");
13029       return -99;
13030     }
13031
13032   /* Construct the API message */
13033   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
13034   mp->sw_if_index = ntohl (sw_if_index);
13035   mp->fib_id = ntohl (fib_id);
13036   mp->ip4 = ip4;
13037   mp->ip6 = ip6;
13038   mp->default_cop = default_cop;
13039
13040   /* send it... */
13041   S;
13042   /* Wait for the reply */
13043   W;
13044 }
13045
13046 static int
13047 api_get_node_graph (vat_main_t * vam)
13048 {
13049   vl_api_get_node_graph_t *mp;
13050   f64 timeout;
13051
13052   M (GET_NODE_GRAPH, get_node_graph);
13053
13054   /* send it... */
13055   S;
13056   /* Wait for the reply */
13057   W;
13058 }
13059
13060 /* *INDENT-OFF* */
13061 /** Used for parsing LISP eids */
13062 typedef CLIB_PACKED(struct{
13063   u8 addr[16];   /**< eid address */
13064   u32 len;       /**< prefix length if IP */
13065   u8 type;      /**< type of eid */
13066 }) lisp_eid_vat_t;
13067 /* *INDENT-ON* */
13068
13069 static uword
13070 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13071 {
13072   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13073
13074   memset (a, 0, sizeof (a[0]));
13075
13076   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13077     {
13078       a->type = 0;              /* ipv4 type */
13079     }
13080   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13081     {
13082       a->type = 1;              /* ipv6 type */
13083     }
13084   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13085     {
13086       a->type = 2;              /* mac type */
13087     }
13088   else
13089     {
13090       return 0;
13091     }
13092
13093   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13094     {
13095       return 0;
13096     }
13097
13098   return 1;
13099 }
13100
13101 static int
13102 lisp_eid_size_vat (u8 type)
13103 {
13104   switch (type)
13105     {
13106     case 0:
13107       return 4;
13108     case 1:
13109       return 16;
13110     case 2:
13111       return 6;
13112     }
13113   return 0;
13114 }
13115
13116 static void
13117 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13118 {
13119   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13120 }
13121
13122 /* *INDENT-OFF* */
13123 /** Used for transferring locators via VPP API */
13124 typedef CLIB_PACKED(struct
13125 {
13126   u32 sw_if_index; /**< locator sw_if_index */
13127   u8 priority; /**< locator priority */
13128   u8 weight;   /**< locator weight */
13129 }) ls_locator_t;
13130 /* *INDENT-ON* */
13131
13132 static int
13133 api_lisp_add_del_locator_set (vat_main_t * vam)
13134 {
13135   unformat_input_t *input = vam->input;
13136   vl_api_lisp_add_del_locator_set_t *mp;
13137   f64 timeout = ~0;
13138   u8 is_add = 1;
13139   u8 *locator_set_name = NULL;
13140   u8 locator_set_name_set = 0;
13141   ls_locator_t locator, *locators = 0;
13142   u32 sw_if_index, priority, weight;
13143   u32 data_len = 0;
13144
13145   /* Parse args required to build the message */
13146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13147     {
13148       if (unformat (input, "del"))
13149         {
13150           is_add = 0;
13151         }
13152       else if (unformat (input, "locator-set %s", &locator_set_name))
13153         {
13154           locator_set_name_set = 1;
13155         }
13156       else if (unformat (input, "sw_if_index %u p %u w %u",
13157                          &sw_if_index, &priority, &weight))
13158         {
13159           locator.sw_if_index = htonl (sw_if_index);
13160           locator.priority = priority;
13161           locator.weight = weight;
13162           vec_add1 (locators, locator);
13163         }
13164       else
13165         if (unformat
13166             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13167              &sw_if_index, &priority, &weight))
13168         {
13169           locator.sw_if_index = htonl (sw_if_index);
13170           locator.priority = priority;
13171           locator.weight = weight;
13172           vec_add1 (locators, locator);
13173         }
13174       else
13175         break;
13176     }
13177
13178   if (locator_set_name_set == 0)
13179     {
13180       errmsg ("missing locator-set name");
13181       vec_free (locators);
13182       return -99;
13183     }
13184
13185   if (vec_len (locator_set_name) > 64)
13186     {
13187       errmsg ("locator-set name too long");
13188       vec_free (locator_set_name);
13189       vec_free (locators);
13190       return -99;
13191     }
13192   vec_add1 (locator_set_name, 0);
13193
13194   data_len = sizeof (ls_locator_t) * vec_len (locators);
13195
13196   /* Construct the API message */
13197   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
13198
13199   mp->is_add = is_add;
13200   clib_memcpy (mp->locator_set_name, locator_set_name,
13201                vec_len (locator_set_name));
13202   vec_free (locator_set_name);
13203
13204   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13205   if (locators)
13206     clib_memcpy (mp->locators, locators, data_len);
13207   vec_free (locators);
13208
13209   /* send it... */
13210   S;
13211
13212   /* Wait for a reply... */
13213   W;
13214
13215   /* NOTREACHED */
13216   return 0;
13217 }
13218
13219 static int
13220 api_lisp_add_del_locator (vat_main_t * vam)
13221 {
13222   unformat_input_t *input = vam->input;
13223   vl_api_lisp_add_del_locator_t *mp;
13224   f64 timeout = ~0;
13225   u32 tmp_if_index = ~0;
13226   u32 sw_if_index = ~0;
13227   u8 sw_if_index_set = 0;
13228   u8 sw_if_index_if_name_set = 0;
13229   u32 priority = ~0;
13230   u8 priority_set = 0;
13231   u32 weight = ~0;
13232   u8 weight_set = 0;
13233   u8 is_add = 1;
13234   u8 *locator_set_name = NULL;
13235   u8 locator_set_name_set = 0;
13236
13237   /* Parse args required to build the message */
13238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13239     {
13240       if (unformat (input, "del"))
13241         {
13242           is_add = 0;
13243         }
13244       else if (unformat (input, "locator-set %s", &locator_set_name))
13245         {
13246           locator_set_name_set = 1;
13247         }
13248       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13249                          &tmp_if_index))
13250         {
13251           sw_if_index_if_name_set = 1;
13252           sw_if_index = tmp_if_index;
13253         }
13254       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13255         {
13256           sw_if_index_set = 1;
13257           sw_if_index = tmp_if_index;
13258         }
13259       else if (unformat (input, "p %d", &priority))
13260         {
13261           priority_set = 1;
13262         }
13263       else if (unformat (input, "w %d", &weight))
13264         {
13265           weight_set = 1;
13266         }
13267       else
13268         break;
13269     }
13270
13271   if (locator_set_name_set == 0)
13272     {
13273       errmsg ("missing locator-set name");
13274       return -99;
13275     }
13276
13277   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13278     {
13279       errmsg ("missing sw_if_index");
13280       vec_free (locator_set_name);
13281       return -99;
13282     }
13283
13284   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13285     {
13286       errmsg ("cannot use both params interface name and sw_if_index");
13287       vec_free (locator_set_name);
13288       return -99;
13289     }
13290
13291   if (priority_set == 0)
13292     {
13293       errmsg ("missing locator-set priority");
13294       vec_free (locator_set_name);
13295       return -99;
13296     }
13297
13298   if (weight_set == 0)
13299     {
13300       errmsg ("missing locator-set weight");
13301       vec_free (locator_set_name);
13302       return -99;
13303     }
13304
13305   if (vec_len (locator_set_name) > 64)
13306     {
13307       errmsg ("locator-set name too long");
13308       vec_free (locator_set_name);
13309       return -99;
13310     }
13311   vec_add1 (locator_set_name, 0);
13312
13313   /* Construct the API message */
13314   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13315
13316   mp->is_add = is_add;
13317   mp->sw_if_index = ntohl (sw_if_index);
13318   mp->priority = priority;
13319   mp->weight = weight;
13320   clib_memcpy (mp->locator_set_name, locator_set_name,
13321                vec_len (locator_set_name));
13322   vec_free (locator_set_name);
13323
13324   /* send it... */
13325   S;
13326
13327   /* Wait for a reply... */
13328   W;
13329
13330   /* NOTREACHED */
13331   return 0;
13332 }
13333
13334 uword
13335 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13336 {
13337   u32 *key_id = va_arg (*args, u32 *);
13338   u8 *s = 0;
13339
13340   if (unformat (input, "%s", &s))
13341     {
13342       if (!strcmp ((char *) s, "sha1"))
13343         key_id[0] = HMAC_SHA_1_96;
13344       else if (!strcmp ((char *) s, "sha256"))
13345         key_id[0] = HMAC_SHA_256_128;
13346       else
13347         {
13348           clib_warning ("invalid key_id: '%s'", s);
13349           key_id[0] = HMAC_NO_KEY;
13350         }
13351     }
13352   else
13353     return 0;
13354
13355   vec_free (s);
13356   return 1;
13357 }
13358
13359 static int
13360 api_lisp_add_del_local_eid (vat_main_t * vam)
13361 {
13362   unformat_input_t *input = vam->input;
13363   vl_api_lisp_add_del_local_eid_t *mp;
13364   f64 timeout = ~0;
13365   u8 is_add = 1;
13366   u8 eid_set = 0;
13367   lisp_eid_vat_t _eid, *eid = &_eid;
13368   u8 *locator_set_name = 0;
13369   u8 locator_set_name_set = 0;
13370   u32 vni = 0;
13371   u16 key_id = 0;
13372   u8 *key = 0;
13373
13374   /* Parse args required to build the message */
13375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13376     {
13377       if (unformat (input, "del"))
13378         {
13379           is_add = 0;
13380         }
13381       else if (unformat (input, "vni %d", &vni))
13382         {
13383           ;
13384         }
13385       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13386         {
13387           eid_set = 1;
13388         }
13389       else if (unformat (input, "locator-set %s", &locator_set_name))
13390         {
13391           locator_set_name_set = 1;
13392         }
13393       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13394         ;
13395       else if (unformat (input, "secret-key %_%v%_", &key))
13396         ;
13397       else
13398         break;
13399     }
13400
13401   if (locator_set_name_set == 0)
13402     {
13403       errmsg ("missing locator-set name");
13404       return -99;
13405     }
13406
13407   if (0 == eid_set)
13408     {
13409       errmsg ("EID address not set!");
13410       vec_free (locator_set_name);
13411       return -99;
13412     }
13413
13414   if (key && (0 == key_id))
13415     {
13416       errmsg ("invalid key_id!");
13417       return -99;
13418     }
13419
13420   if (vec_len (key) > 64)
13421     {
13422       errmsg ("key too long");
13423       vec_free (key);
13424       return -99;
13425     }
13426
13427   if (vec_len (locator_set_name) > 64)
13428     {
13429       errmsg ("locator-set name too long");
13430       vec_free (locator_set_name);
13431       return -99;
13432     }
13433   vec_add1 (locator_set_name, 0);
13434
13435   /* Construct the API message */
13436   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13437
13438   mp->is_add = is_add;
13439   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13440   mp->eid_type = eid->type;
13441   mp->prefix_len = eid->len;
13442   mp->vni = clib_host_to_net_u32 (vni);
13443   mp->key_id = clib_host_to_net_u16 (key_id);
13444   clib_memcpy (mp->locator_set_name, locator_set_name,
13445                vec_len (locator_set_name));
13446   clib_memcpy (mp->key, key, vec_len (key));
13447
13448   vec_free (locator_set_name);
13449   vec_free (key);
13450
13451   /* send it... */
13452   S;
13453
13454   /* Wait for a reply... */
13455   W;
13456
13457   /* NOTREACHED */
13458   return 0;
13459 }
13460
13461 /* *INDENT-OFF* */
13462 /** Used for transferring locators via VPP API */
13463 typedef CLIB_PACKED(struct
13464 {
13465   u8 is_ip4; /**< is locator an IPv4 address? */
13466   u8 priority; /**< locator priority */
13467   u8 weight;   /**< locator weight */
13468   u8 addr[16]; /**< IPv4/IPv6 address */
13469 }) rloc_t;
13470 /* *INDENT-ON* */
13471
13472 static int
13473 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13474 {
13475   u32 dp_table = 0, vni = 0;;
13476   unformat_input_t *input = vam->input;
13477   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13478   f64 timeout = ~0;
13479   u8 is_add = 1;
13480   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13481   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13482   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13483   u32 action = ~0, w;
13484   ip4_address_t rmt_rloc4, lcl_rloc4;
13485   ip6_address_t rmt_rloc6, lcl_rloc6;
13486   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13487     0;
13488
13489   memset (&rloc, 0, sizeof (rloc));
13490
13491   /* Parse args required to build the message */
13492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13493     {
13494       if (unformat (input, "del"))
13495         is_add = 0;
13496       else if (unformat (input, "add"))
13497         is_add = 1;
13498       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13499         {
13500           rmt_eid_set = 1;
13501         }
13502       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13503         {
13504           lcl_eid_set = 1;
13505         }
13506       else if (unformat (input, "vrf %d", &dp_table))
13507         ;
13508       else if (unformat (input, "bd %d", &dp_table))
13509         ;
13510       else if (unformat (input, "vni %d", &vni))
13511         ;
13512       else if (unformat (input, "w %d", &w))
13513         {
13514           if (!curr_rloc)
13515             {
13516               errmsg ("No RLOC configured for setting priority/weight!");
13517               return -99;
13518             }
13519           curr_rloc->weight = w;
13520         }
13521       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13522                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13523         {
13524           rloc.is_ip4 = 1;
13525
13526           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13527           rloc.weight = 0;
13528           vec_add1 (lcl_locs, rloc);
13529
13530           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13531           vec_add1 (rmt_locs, rloc);
13532           /* weight saved in rmt loc */
13533           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13534         }
13535       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13536                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13537         {
13538           rloc.is_ip4 = 0;
13539           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13540           rloc.weight = 0;
13541           vec_add1 (lcl_locs, rloc);
13542
13543           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13544           vec_add1 (rmt_locs, rloc);
13545           /* weight saved in rmt loc */
13546           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13547         }
13548       else if (unformat (input, "action %d", &action))
13549         {
13550           ;
13551         }
13552       else
13553         {
13554           clib_warning ("parse error '%U'", format_unformat_error, input);
13555           return -99;
13556         }
13557     }
13558
13559   if (!rmt_eid_set)
13560     {
13561       errmsg ("remote eid addresses not set");
13562       return -99;
13563     }
13564
13565   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13566     {
13567       errmsg ("eid types don't match");
13568       return -99;
13569     }
13570
13571   if (0 == rmt_locs && (u32) ~ 0 == action)
13572     {
13573       errmsg ("action not set for negative mapping");
13574       return -99;
13575     }
13576
13577   /* Construct the API message */
13578   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry,
13579       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13580
13581   mp->is_add = is_add;
13582   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13583   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13584   mp->eid_type = rmt_eid->type;
13585   mp->dp_table = clib_host_to_net_u32 (dp_table);
13586   mp->vni = clib_host_to_net_u32 (vni);
13587   mp->rmt_len = rmt_eid->len;
13588   mp->lcl_len = lcl_eid->len;
13589   mp->action = action;
13590
13591   if (0 != rmt_locs && 0 != lcl_locs)
13592     {
13593       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13594       clib_memcpy (mp->locs, lcl_locs,
13595                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13596
13597       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13598       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13599                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13600     }
13601   vec_free (lcl_locs);
13602   vec_free (rmt_locs);
13603
13604   /* send it... */
13605   S;
13606
13607   /* Wait for a reply... */
13608   W;
13609
13610   /* NOTREACHED */
13611   return 0;
13612 }
13613
13614 static int
13615 api_lisp_add_del_map_server (vat_main_t * vam)
13616 {
13617   unformat_input_t *input = vam->input;
13618   vl_api_lisp_add_del_map_server_t *mp;
13619   f64 timeout = ~0;
13620   u8 is_add = 1;
13621   u8 ipv4_set = 0;
13622   u8 ipv6_set = 0;
13623   ip4_address_t ipv4;
13624   ip6_address_t ipv6;
13625
13626   /* Parse args required to build the message */
13627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13628     {
13629       if (unformat (input, "del"))
13630         {
13631           is_add = 0;
13632         }
13633       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13634         {
13635           ipv4_set = 1;
13636         }
13637       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13638         {
13639           ipv6_set = 1;
13640         }
13641       else
13642         break;
13643     }
13644
13645   if (ipv4_set && ipv6_set)
13646     {
13647       errmsg ("both eid v4 and v6 addresses set");
13648       return -99;
13649     }
13650
13651   if (!ipv4_set && !ipv6_set)
13652     {
13653       errmsg ("eid addresses not set");
13654       return -99;
13655     }
13656
13657   /* Construct the API message */
13658   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13659
13660   mp->is_add = is_add;
13661   if (ipv6_set)
13662     {
13663       mp->is_ipv6 = 1;
13664       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13665     }
13666   else
13667     {
13668       mp->is_ipv6 = 0;
13669       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13670     }
13671
13672   /* send it... */
13673   S;
13674
13675   /* Wait for a reply... */
13676   W;
13677
13678   /* NOTREACHED */
13679   return 0;
13680 }
13681
13682 static int
13683 api_lisp_add_del_map_resolver (vat_main_t * vam)
13684 {
13685   unformat_input_t *input = vam->input;
13686   vl_api_lisp_add_del_map_resolver_t *mp;
13687   f64 timeout = ~0;
13688   u8 is_add = 1;
13689   u8 ipv4_set = 0;
13690   u8 ipv6_set = 0;
13691   ip4_address_t ipv4;
13692   ip6_address_t ipv6;
13693
13694   /* Parse args required to build the message */
13695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13696     {
13697       if (unformat (input, "del"))
13698         {
13699           is_add = 0;
13700         }
13701       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13702         {
13703           ipv4_set = 1;
13704         }
13705       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13706         {
13707           ipv6_set = 1;
13708         }
13709       else
13710         break;
13711     }
13712
13713   if (ipv4_set && ipv6_set)
13714     {
13715       errmsg ("both eid v4 and v6 addresses set");
13716       return -99;
13717     }
13718
13719   if (!ipv4_set && !ipv6_set)
13720     {
13721       errmsg ("eid addresses not set");
13722       return -99;
13723     }
13724
13725   /* Construct the API message */
13726   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13727
13728   mp->is_add = is_add;
13729   if (ipv6_set)
13730     {
13731       mp->is_ipv6 = 1;
13732       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13733     }
13734   else
13735     {
13736       mp->is_ipv6 = 0;
13737       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13738     }
13739
13740   /* send it... */
13741   S;
13742
13743   /* Wait for a reply... */
13744   W;
13745
13746   /* NOTREACHED */
13747   return 0;
13748 }
13749
13750 static int
13751 api_lisp_gpe_enable_disable (vat_main_t * vam)
13752 {
13753   unformat_input_t *input = vam->input;
13754   vl_api_lisp_gpe_enable_disable_t *mp;
13755   f64 timeout = ~0;
13756   u8 is_set = 0;
13757   u8 is_en = 1;
13758
13759   /* Parse args required to build the message */
13760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13761     {
13762       if (unformat (input, "enable"))
13763         {
13764           is_set = 1;
13765           is_en = 1;
13766         }
13767       else if (unformat (input, "disable"))
13768         {
13769           is_set = 1;
13770           is_en = 0;
13771         }
13772       else
13773         break;
13774     }
13775
13776   if (is_set == 0)
13777     {
13778       errmsg ("Value not set");
13779       return -99;
13780     }
13781
13782   /* Construct the API message */
13783   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13784
13785   mp->is_en = is_en;
13786
13787   /* send it... */
13788   S;
13789
13790   /* Wait for a reply... */
13791   W;
13792
13793   /* NOTREACHED */
13794   return 0;
13795 }
13796
13797 static int
13798 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13799 {
13800   unformat_input_t *input = vam->input;
13801   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13802   f64 timeout = ~0;
13803   u8 is_set = 0;
13804   u8 is_en = 0;
13805
13806   /* Parse args required to build the message */
13807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13808     {
13809       if (unformat (input, "enable"))
13810         {
13811           is_set = 1;
13812           is_en = 1;
13813         }
13814       else if (unformat (input, "disable"))
13815         is_set = 1;
13816       else
13817         break;
13818     }
13819
13820   if (!is_set)
13821     {
13822       errmsg ("Value not set");
13823       return -99;
13824     }
13825
13826   /* Construct the API message */
13827   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13828
13829   mp->is_enabled = is_en;
13830
13831   /* send it... */
13832   S;
13833
13834   /* Wait for a reply... */
13835   W;
13836
13837   /* NOTREACHED */
13838   return 0;
13839 }
13840
13841 static int
13842 api_lisp_map_register_enable_disable (vat_main_t * vam)
13843 {
13844   unformat_input_t *input = vam->input;
13845   vl_api_lisp_map_register_enable_disable_t *mp;
13846   f64 timeout = ~0;
13847   u8 is_set = 0;
13848   u8 is_en = 0;
13849
13850   /* Parse args required to build the message */
13851   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13852     {
13853       if (unformat (input, "enable"))
13854         {
13855           is_set = 1;
13856           is_en = 1;
13857         }
13858       else if (unformat (input, "disable"))
13859         is_set = 1;
13860       else
13861         break;
13862     }
13863
13864   if (!is_set)
13865     {
13866       errmsg ("Value not set");
13867       return -99;
13868     }
13869
13870   /* Construct the API message */
13871   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13872
13873   mp->is_enabled = is_en;
13874
13875   /* send it... */
13876   S;
13877
13878   /* Wait for a reply... */
13879   W;
13880
13881   /* NOTREACHED */
13882   return 0;
13883 }
13884
13885 static int
13886 api_lisp_enable_disable (vat_main_t * vam)
13887 {
13888   unformat_input_t *input = vam->input;
13889   vl_api_lisp_enable_disable_t *mp;
13890   f64 timeout = ~0;
13891   u8 is_set = 0;
13892   u8 is_en = 0;
13893
13894   /* Parse args required to build the message */
13895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13896     {
13897       if (unformat (input, "enable"))
13898         {
13899           is_set = 1;
13900           is_en = 1;
13901         }
13902       else if (unformat (input, "disable"))
13903         {
13904           is_set = 1;
13905         }
13906       else
13907         break;
13908     }
13909
13910   if (!is_set)
13911     {
13912       errmsg ("Value not set");
13913       return -99;
13914     }
13915
13916   /* Construct the API message */
13917   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13918
13919   mp->is_en = is_en;
13920
13921   /* send it... */
13922   S;
13923
13924   /* Wait for a reply... */
13925   W;
13926
13927   /* NOTREACHED */
13928   return 0;
13929 }
13930
13931 static int
13932 api_show_lisp_map_register_state (vat_main_t * vam)
13933 {
13934   f64 timeout = ~0;
13935   vl_api_show_lisp_map_register_state_t *mp;
13936
13937   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13938
13939   /* send */
13940   S;
13941
13942   /* wait for reply */
13943   W;
13944
13945   return 0;
13946 }
13947
13948 static int
13949 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13950 {
13951   f64 timeout = ~0;
13952   vl_api_show_lisp_rloc_probe_state_t *mp;
13953
13954   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13955
13956   /* send */
13957   S;
13958
13959   /* wait for reply */
13960   W;
13961
13962   return 0;
13963 }
13964
13965 static int
13966 api_show_lisp_map_request_mode (vat_main_t * vam)
13967 {
13968   f64 timeout = ~0;
13969   vl_api_show_lisp_map_request_mode_t *mp;
13970
13971   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13972
13973   /* send */
13974   S;
13975
13976   /* wait for reply */
13977   W;
13978
13979   return 0;
13980 }
13981
13982 static int
13983 api_lisp_map_request_mode (vat_main_t * vam)
13984 {
13985   f64 timeout = ~0;
13986   unformat_input_t *input = vam->input;
13987   vl_api_lisp_map_request_mode_t *mp;
13988   u8 mode = 0;
13989
13990   /* Parse args required to build the message */
13991   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13992     {
13993       if (unformat (input, "dst-only"))
13994         mode = 0;
13995       else if (unformat (input, "src-dst"))
13996         mode = 1;
13997       else
13998         {
13999           errmsg ("parse error '%U'", format_unformat_error, input);
14000           return -99;
14001         }
14002     }
14003
14004   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
14005
14006   mp->mode = mode;
14007
14008   /* send */
14009   S;
14010
14011   /* wait for reply */
14012   W;
14013
14014   /* notreached */
14015   return 0;
14016 }
14017
14018 /**
14019  * Enable/disable LISP proxy ITR.
14020  *
14021  * @param vam vpp API test context
14022  * @return return code
14023  */
14024 static int
14025 api_lisp_pitr_set_locator_set (vat_main_t * vam)
14026 {
14027   f64 timeout = ~0;
14028   u8 ls_name_set = 0;
14029   unformat_input_t *input = vam->input;
14030   vl_api_lisp_pitr_set_locator_set_t *mp;
14031   u8 is_add = 1;
14032   u8 *ls_name = 0;
14033
14034   /* Parse args required to build the message */
14035   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14036     {
14037       if (unformat (input, "del"))
14038         is_add = 0;
14039       else if (unformat (input, "locator-set %s", &ls_name))
14040         ls_name_set = 1;
14041       else
14042         {
14043           errmsg ("parse error '%U'", format_unformat_error, input);
14044           return -99;
14045         }
14046     }
14047
14048   if (!ls_name_set)
14049     {
14050       errmsg ("locator-set name not set!");
14051       return -99;
14052     }
14053
14054   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
14055
14056   mp->is_add = is_add;
14057   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14058   vec_free (ls_name);
14059
14060   /* send */
14061   S;
14062
14063   /* wait for reply */
14064   W;
14065
14066   /* notreached */
14067   return 0;
14068 }
14069
14070 static int
14071 api_show_lisp_pitr (vat_main_t * vam)
14072 {
14073   vl_api_show_lisp_pitr_t *mp;
14074   f64 timeout = ~0;
14075
14076   if (!vam->json_output)
14077     {
14078       print (vam->ofp, "%=20s", "lisp status:");
14079     }
14080
14081   M (SHOW_LISP_PITR, show_lisp_pitr);
14082   /* send it... */
14083   S;
14084
14085   /* Wait for a reply... */
14086   W;
14087
14088   /* NOTREACHED */
14089   return 0;
14090 }
14091
14092 /**
14093  * Add/delete mapping between vni and vrf
14094  */
14095 static int
14096 api_lisp_eid_table_add_del_map (vat_main_t * vam)
14097 {
14098   f64 timeout = ~0;
14099   unformat_input_t *input = vam->input;
14100   vl_api_lisp_eid_table_add_del_map_t *mp;
14101   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14102   u32 vni, vrf, bd_index;
14103
14104   /* Parse args required to build the message */
14105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14106     {
14107       if (unformat (input, "del"))
14108         is_add = 0;
14109       else if (unformat (input, "vrf %d", &vrf))
14110         vrf_set = 1;
14111       else if (unformat (input, "bd_index %d", &bd_index))
14112         bd_index_set = 1;
14113       else if (unformat (input, "vni %d", &vni))
14114         vni_set = 1;
14115       else
14116         break;
14117     }
14118
14119   if (!vni_set || (!vrf_set && !bd_index_set))
14120     {
14121       errmsg ("missing arguments!");
14122       return -99;
14123     }
14124
14125   if (vrf_set && bd_index_set)
14126     {
14127       errmsg ("error: both vrf and bd entered!");
14128       return -99;
14129     }
14130
14131   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
14132
14133   mp->is_add = is_add;
14134   mp->vni = htonl (vni);
14135   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14136   mp->is_l2 = bd_index_set;
14137
14138   /* send */
14139   S;
14140
14141   /* wait for reply */
14142   W;
14143
14144   /* notreached */
14145   return 0;
14146 }
14147
14148 uword
14149 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14150 {
14151   u32 *action = va_arg (*args, u32 *);
14152   u8 *s = 0;
14153
14154   if (unformat (input, "%s", &s))
14155     {
14156       if (!strcmp ((char *) s, "no-action"))
14157         action[0] = 0;
14158       else if (!strcmp ((char *) s, "natively-forward"))
14159         action[0] = 1;
14160       else if (!strcmp ((char *) s, "send-map-request"))
14161         action[0] = 2;
14162       else if (!strcmp ((char *) s, "drop"))
14163         action[0] = 3;
14164       else
14165         {
14166           clib_warning ("invalid action: '%s'", s);
14167           action[0] = 3;
14168         }
14169     }
14170   else
14171     return 0;
14172
14173   vec_free (s);
14174   return 1;
14175 }
14176
14177 /**
14178  * Add/del remote mapping to/from LISP control plane
14179  *
14180  * @param vam vpp API test context
14181  * @return return code
14182  */
14183 static int
14184 api_lisp_add_del_remote_mapping (vat_main_t * vam)
14185 {
14186   unformat_input_t *input = vam->input;
14187   vl_api_lisp_add_del_remote_mapping_t *mp;
14188   f64 timeout = ~0;
14189   u32 vni = 0;
14190   lisp_eid_vat_t _eid, *eid = &_eid;
14191   lisp_eid_vat_t _seid, *seid = &_seid;
14192   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14193   u32 action = ~0, p, w, data_len;
14194   ip4_address_t rloc4;
14195   ip6_address_t rloc6;
14196   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
14197
14198   memset (&rloc, 0, sizeof (rloc));
14199
14200   /* Parse args required to build the message */
14201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14202     {
14203       if (unformat (input, "del-all"))
14204         {
14205           del_all = 1;
14206         }
14207       else if (unformat (input, "del"))
14208         {
14209           is_add = 0;
14210         }
14211       else if (unformat (input, "add"))
14212         {
14213           is_add = 1;
14214         }
14215       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14216         {
14217           eid_set = 1;
14218         }
14219       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14220         {
14221           seid_set = 1;
14222         }
14223       else if (unformat (input, "vni %d", &vni))
14224         {
14225           ;
14226         }
14227       else if (unformat (input, "p %d w %d", &p, &w))
14228         {
14229           if (!curr_rloc)
14230             {
14231               errmsg ("No RLOC configured for setting priority/weight!");
14232               return -99;
14233             }
14234           curr_rloc->priority = p;
14235           curr_rloc->weight = w;
14236         }
14237       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14238         {
14239           rloc.is_ip4 = 1;
14240           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14241           vec_add1 (rlocs, rloc);
14242           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14243         }
14244       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14245         {
14246           rloc.is_ip4 = 0;
14247           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14248           vec_add1 (rlocs, rloc);
14249           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14250         }
14251       else if (unformat (input, "action %U",
14252                          unformat_negative_mapping_action, &action))
14253         {
14254           ;
14255         }
14256       else
14257         {
14258           clib_warning ("parse error '%U'", format_unformat_error, input);
14259           return -99;
14260         }
14261     }
14262
14263   if (0 == eid_set)
14264     {
14265       errmsg ("missing params!");
14266       return -99;
14267     }
14268
14269   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14270     {
14271       errmsg ("no action set for negative map-reply!");
14272       return -99;
14273     }
14274
14275   data_len = vec_len (rlocs) * sizeof (rloc_t);
14276
14277   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14278   mp->is_add = is_add;
14279   mp->vni = htonl (vni);
14280   mp->action = (u8) action;
14281   mp->is_src_dst = seid_set;
14282   mp->eid_len = eid->len;
14283   mp->seid_len = seid->len;
14284   mp->del_all = del_all;
14285   mp->eid_type = eid->type;
14286   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14287   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14288
14289   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14290   clib_memcpy (mp->rlocs, rlocs, data_len);
14291   vec_free (rlocs);
14292
14293   /* send it... */
14294   S;
14295
14296   /* Wait for a reply... */
14297   W;
14298
14299   /* NOTREACHED */
14300   return 0;
14301 }
14302
14303 /**
14304  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14305  * forwarding entries in data-plane accordingly.
14306  *
14307  * @param vam vpp API test context
14308  * @return return code
14309  */
14310 static int
14311 api_lisp_add_del_adjacency (vat_main_t * vam)
14312 {
14313   unformat_input_t *input = vam->input;
14314   vl_api_lisp_add_del_adjacency_t *mp;
14315   f64 timeout = ~0;
14316   u32 vni = 0;
14317   ip4_address_t leid4, reid4;
14318   ip6_address_t leid6, reid6;
14319   u8 reid_mac[6] = { 0 };
14320   u8 leid_mac[6] = { 0 };
14321   u8 reid_type, leid_type;
14322   u32 leid_len = 0, reid_len = 0, len;
14323   u8 is_add = 1;
14324
14325   leid_type = reid_type = (u8) ~ 0;
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"))
14331         {
14332           is_add = 0;
14333         }
14334       else if (unformat (input, "add"))
14335         {
14336           is_add = 1;
14337         }
14338       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14339                          &reid4, &len))
14340         {
14341           reid_type = 0;        /* ipv4 */
14342           reid_len = len;
14343         }
14344       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14345                          &reid6, &len))
14346         {
14347           reid_type = 1;        /* ipv6 */
14348           reid_len = len;
14349         }
14350       else if (unformat (input, "reid %U", unformat_ethernet_address,
14351                          reid_mac))
14352         {
14353           reid_type = 2;        /* mac */
14354         }
14355       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14356                          &leid4, &len))
14357         {
14358           leid_type = 0;        /* ipv4 */
14359           leid_len = len;
14360         }
14361       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14362                          &leid6, &len))
14363         {
14364           leid_type = 1;        /* ipv6 */
14365           leid_len = len;
14366         }
14367       else if (unformat (input, "leid %U", unformat_ethernet_address,
14368                          leid_mac))
14369         {
14370           leid_type = 2;        /* mac */
14371         }
14372       else if (unformat (input, "vni %d", &vni))
14373         {
14374           ;
14375         }
14376       else
14377         {
14378           errmsg ("parse error '%U'", format_unformat_error, input);
14379           return -99;
14380         }
14381     }
14382
14383   if ((u8) ~ 0 == reid_type)
14384     {
14385       errmsg ("missing params!");
14386       return -99;
14387     }
14388
14389   if (leid_type != reid_type)
14390     {
14391       errmsg ("remote and local EIDs are of different types!");
14392       return -99;
14393     }
14394
14395   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14396   mp->is_add = is_add;
14397   mp->vni = htonl (vni);
14398   mp->leid_len = leid_len;
14399   mp->reid_len = reid_len;
14400   mp->eid_type = reid_type;
14401
14402   switch (mp->eid_type)
14403     {
14404     case 0:
14405       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14406       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14407       break;
14408     case 1:
14409       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14410       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14411       break;
14412     case 2:
14413       clib_memcpy (mp->leid, leid_mac, 6);
14414       clib_memcpy (mp->reid, reid_mac, 6);
14415       break;
14416     default:
14417       errmsg ("unknown EID type %d!", mp->eid_type);
14418       return 0;
14419     }
14420
14421   /* send it... */
14422   S;
14423
14424   /* Wait for a reply... */
14425   W;
14426
14427   /* NOTREACHED */
14428   return 0;
14429 }
14430
14431 static int
14432 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14433 {
14434   unformat_input_t *input = vam->input;
14435   vl_api_lisp_gpe_add_del_iface_t *mp;
14436   f64 timeout = ~0;
14437   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14438   u32 dp_table = 0, vni = 0;
14439
14440   /* Parse args required to build the message */
14441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14442     {
14443       if (unformat (input, "up"))
14444         {
14445           action_set = 1;
14446           is_add = 1;
14447         }
14448       else if (unformat (input, "down"))
14449         {
14450           action_set = 1;
14451           is_add = 0;
14452         }
14453       else if (unformat (input, "table_id %d", &dp_table))
14454         {
14455           dp_table_set = 1;
14456         }
14457       else if (unformat (input, "bd_id %d", &dp_table))
14458         {
14459           dp_table_set = 1;
14460           is_l2 = 1;
14461         }
14462       else if (unformat (input, "vni %d", &vni))
14463         {
14464           vni_set = 1;
14465         }
14466       else
14467         break;
14468     }
14469
14470   if (action_set == 0)
14471     {
14472       errmsg ("Action not set");
14473       return -99;
14474     }
14475   if (dp_table_set == 0 || vni_set == 0)
14476     {
14477       errmsg ("vni and dp_table must be set");
14478       return -99;
14479     }
14480
14481   /* Construct the API message */
14482   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14483
14484   mp->is_add = is_add;
14485   mp->dp_table = dp_table;
14486   mp->is_l2 = is_l2;
14487   mp->vni = vni;
14488
14489   /* send it... */
14490   S;
14491
14492   /* Wait for a reply... */
14493   W;
14494
14495   /* NOTREACHED */
14496   return 0;
14497 }
14498
14499 /**
14500  * Add/del map request itr rlocs from LISP control plane and updates
14501  *
14502  * @param vam vpp API test context
14503  * @return return code
14504  */
14505 static int
14506 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14507 {
14508   unformat_input_t *input = vam->input;
14509   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14510   f64 timeout = ~0;
14511   u8 *locator_set_name = 0;
14512   u8 locator_set_name_set = 0;
14513   u8 is_add = 1;
14514
14515   /* Parse args required to build the message */
14516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14517     {
14518       if (unformat (input, "del"))
14519         {
14520           is_add = 0;
14521         }
14522       else if (unformat (input, "%_%v%_", &locator_set_name))
14523         {
14524           locator_set_name_set = 1;
14525         }
14526       else
14527         {
14528           clib_warning ("parse error '%U'", format_unformat_error, input);
14529           return -99;
14530         }
14531     }
14532
14533   if (is_add && !locator_set_name_set)
14534     {
14535       errmsg ("itr-rloc is not set!");
14536       return -99;
14537     }
14538
14539   if (is_add && vec_len (locator_set_name) > 64)
14540     {
14541       errmsg ("itr-rloc locator-set name too long");
14542       vec_free (locator_set_name);
14543       return -99;
14544     }
14545
14546   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14547   mp->is_add = is_add;
14548   if (is_add)
14549     {
14550       clib_memcpy (mp->locator_set_name, locator_set_name,
14551                    vec_len (locator_set_name));
14552     }
14553   else
14554     {
14555       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14556     }
14557   vec_free (locator_set_name);
14558
14559   /* send it... */
14560   S;
14561
14562   /* Wait for a reply... */
14563   W;
14564
14565   /* NOTREACHED */
14566   return 0;
14567 }
14568
14569 static int
14570 api_lisp_locator_dump (vat_main_t * vam)
14571 {
14572   unformat_input_t *input = vam->input;
14573   vl_api_lisp_locator_dump_t *mp;
14574   f64 timeout = ~0;
14575   u8 is_index_set = 0, is_name_set = 0;
14576   u8 *ls_name = 0;
14577   u32 ls_index = ~0;
14578
14579   /* Parse args required to build the message */
14580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14581     {
14582       if (unformat (input, "ls_name %_%v%_", &ls_name))
14583         {
14584           is_name_set = 1;
14585         }
14586       else if (unformat (input, "ls_index %d", &ls_index))
14587         {
14588           is_index_set = 1;
14589         }
14590       else
14591         {
14592           errmsg ("parse error '%U'", format_unformat_error, input);
14593           return -99;
14594         }
14595     }
14596
14597   if (!is_index_set && !is_name_set)
14598     {
14599       errmsg ("error: expected one of index or name!");
14600       return -99;
14601     }
14602
14603   if (is_index_set && is_name_set)
14604     {
14605       errmsg ("error: only one param expected!");
14606       return -99;
14607     }
14608
14609   if (vec_len (ls_name) > 62)
14610     {
14611       errmsg ("error: locator set name too long!");
14612       return -99;
14613     }
14614
14615   if (!vam->json_output)
14616     {
14617       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14618     }
14619
14620   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14621   mp->is_index_set = is_index_set;
14622
14623   if (is_index_set)
14624     mp->ls_index = clib_host_to_net_u32 (ls_index);
14625   else
14626     {
14627       vec_add1 (ls_name, 0);
14628       strncpy ((char *) mp->ls_name, (char *) ls_name,
14629                sizeof (mp->ls_name) - 1);
14630     }
14631
14632   /* send it... */
14633   S;
14634
14635   /* Use a control ping for synchronization */
14636   {
14637     vl_api_control_ping_t *mp;
14638     M (CONTROL_PING, control_ping);
14639     S;
14640   }
14641   /* Wait for a reply... */
14642   W;
14643
14644   /* NOTREACHED */
14645   return 0;
14646 }
14647
14648 static int
14649 api_lisp_locator_set_dump (vat_main_t * vam)
14650 {
14651   vl_api_lisp_locator_set_dump_t *mp;
14652   unformat_input_t *input = vam->input;
14653   f64 timeout = ~0;
14654   u8 filter = 0;
14655
14656   /* Parse args required to build the message */
14657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14658     {
14659       if (unformat (input, "local"))
14660         {
14661           filter = 1;
14662         }
14663       else if (unformat (input, "remote"))
14664         {
14665           filter = 2;
14666         }
14667       else
14668         {
14669           errmsg ("parse error '%U'", format_unformat_error, input);
14670           return -99;
14671         }
14672     }
14673
14674   if (!vam->json_output)
14675     {
14676       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14677     }
14678
14679   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14680
14681   mp->filter = filter;
14682
14683   /* send it... */
14684   S;
14685
14686   /* Use a control ping for synchronization */
14687   {
14688     vl_api_control_ping_t *mp;
14689     M (CONTROL_PING, control_ping);
14690     S;
14691   }
14692   /* Wait for a reply... */
14693   W;
14694
14695   /* NOTREACHED */
14696   return 0;
14697 }
14698
14699 static int
14700 api_lisp_eid_table_map_dump (vat_main_t * vam)
14701 {
14702   u8 is_l2 = 0;
14703   u8 mode_set = 0;
14704   unformat_input_t *input = vam->input;
14705   vl_api_lisp_eid_table_map_dump_t *mp;
14706   f64 timeout = ~0;
14707
14708   /* Parse args required to build the message */
14709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14710     {
14711       if (unformat (input, "l2"))
14712         {
14713           is_l2 = 1;
14714           mode_set = 1;
14715         }
14716       else if (unformat (input, "l3"))
14717         {
14718           is_l2 = 0;
14719           mode_set = 1;
14720         }
14721       else
14722         {
14723           errmsg ("parse error '%U'", format_unformat_error, input);
14724           return -99;
14725         }
14726     }
14727
14728   if (!mode_set)
14729     {
14730       errmsg ("expected one of 'l2' or 'l3' parameter!");
14731       return -99;
14732     }
14733
14734   if (!vam->json_output)
14735     {
14736       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14737     }
14738
14739   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14740   mp->is_l2 = is_l2;
14741
14742   /* send it... */
14743   S;
14744
14745   /* Use a control ping for synchronization */
14746   {
14747     vl_api_control_ping_t *mp;
14748     M (CONTROL_PING, control_ping);
14749     S;
14750   }
14751   /* Wait for a reply... */
14752   W;
14753
14754   /* NOTREACHED */
14755   return 0;
14756 }
14757
14758 static int
14759 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14760 {
14761   vl_api_lisp_eid_table_vni_dump_t *mp;
14762   f64 timeout = ~0;
14763
14764   if (!vam->json_output)
14765     {
14766       print (vam->ofp, "VNI");
14767     }
14768
14769   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14770
14771   /* send it... */
14772   S;
14773
14774   /* Use a control ping for synchronization */
14775   {
14776     vl_api_control_ping_t *mp;
14777     M (CONTROL_PING, control_ping);
14778     S;
14779   }
14780   /* Wait for a reply... */
14781   W;
14782
14783   /* NOTREACHED */
14784   return 0;
14785 }
14786
14787 static int
14788 api_lisp_eid_table_dump (vat_main_t * vam)
14789 {
14790   unformat_input_t *i = vam->input;
14791   vl_api_lisp_eid_table_dump_t *mp;
14792   f64 timeout = ~0;
14793   struct in_addr ip4;
14794   struct in6_addr ip6;
14795   u8 mac[6];
14796   u8 eid_type = ~0, eid_set = 0;
14797   u32 prefix_length = ~0, t, vni = 0;
14798   u8 filter = 0;
14799
14800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14801     {
14802       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14803         {
14804           eid_set = 1;
14805           eid_type = 0;
14806           prefix_length = t;
14807         }
14808       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14809         {
14810           eid_set = 1;
14811           eid_type = 1;
14812           prefix_length = t;
14813         }
14814       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14815         {
14816           eid_set = 1;
14817           eid_type = 2;
14818         }
14819       else if (unformat (i, "vni %d", &t))
14820         {
14821           vni = t;
14822         }
14823       else if (unformat (i, "local"))
14824         {
14825           filter = 1;
14826         }
14827       else if (unformat (i, "remote"))
14828         {
14829           filter = 2;
14830         }
14831       else
14832         {
14833           errmsg ("parse error '%U'", format_unformat_error, i);
14834           return -99;
14835         }
14836     }
14837
14838   if (!vam->json_output)
14839     {
14840       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14841              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14842     }
14843
14844   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14845
14846   mp->filter = filter;
14847   if (eid_set)
14848     {
14849       mp->eid_set = 1;
14850       mp->vni = htonl (vni);
14851       mp->eid_type = eid_type;
14852       switch (eid_type)
14853         {
14854         case 0:
14855           mp->prefix_length = prefix_length;
14856           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14857           break;
14858         case 1:
14859           mp->prefix_length = prefix_length;
14860           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14861           break;
14862         case 2:
14863           clib_memcpy (mp->eid, mac, sizeof (mac));
14864           break;
14865         default:
14866           errmsg ("unknown EID type %d!", eid_type);
14867           return -99;
14868         }
14869     }
14870
14871   /* send it... */
14872   S;
14873
14874   /* Use a control ping for synchronization */
14875   {
14876     vl_api_control_ping_t *mp;
14877     M (CONTROL_PING, control_ping);
14878     S;
14879   }
14880
14881   /* Wait for a reply... */
14882   W;
14883
14884   /* NOTREACHED */
14885   return 0;
14886 }
14887
14888 static int
14889 api_lisp_adjacencies_get (vat_main_t * vam)
14890 {
14891   unformat_input_t *i = vam->input;
14892   vl_api_lisp_adjacencies_get_t *mp;
14893   f64 timeout = ~0;
14894   u8 vni_set = 0;
14895   u32 vni = ~0;
14896
14897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14898     {
14899       if (unformat (i, "vni %d", &vni))
14900         {
14901           vni_set = 1;
14902         }
14903       else
14904         {
14905           errmsg ("parse error '%U'", format_unformat_error, i);
14906           return -99;
14907         }
14908     }
14909
14910   if (!vni_set)
14911     {
14912       errmsg ("vni not set!");
14913       return -99;
14914     }
14915
14916   if (!vam->json_output)
14917     {
14918       print (vam->ofp, "%s %40s", "leid", "reid");
14919     }
14920
14921   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14922   mp->vni = clib_host_to_net_u32 (vni);
14923
14924   /* send it... */
14925   S;
14926
14927   /* Wait for a reply... */
14928   W;
14929
14930   /* NOTREACHED */
14931   return 0;
14932 }
14933
14934 static int
14935 api_lisp_map_server_dump (vat_main_t * vam)
14936 {
14937   vl_api_lisp_map_server_dump_t *mp;
14938   f64 timeout = ~0;
14939
14940   if (!vam->json_output)
14941     {
14942       print (vam->ofp, "%=20s", "Map server");
14943     }
14944
14945   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14946   /* send it... */
14947   S;
14948
14949   /* Use a control ping for synchronization */
14950   {
14951     vl_api_control_ping_t *mp;
14952     M (CONTROL_PING, control_ping);
14953     S;
14954   }
14955   /* Wait for a reply... */
14956   W;
14957
14958   /* NOTREACHED */
14959   return 0;
14960 }
14961
14962 static int
14963 api_lisp_map_resolver_dump (vat_main_t * vam)
14964 {
14965   vl_api_lisp_map_resolver_dump_t *mp;
14966   f64 timeout = ~0;
14967
14968   if (!vam->json_output)
14969     {
14970       print (vam->ofp, "%=20s", "Map resolver");
14971     }
14972
14973   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14974   /* send it... */
14975   S;
14976
14977   /* Use a control ping for synchronization */
14978   {
14979     vl_api_control_ping_t *mp;
14980     M (CONTROL_PING, control_ping);
14981     S;
14982   }
14983   /* Wait for a reply... */
14984   W;
14985
14986   /* NOTREACHED */
14987   return 0;
14988 }
14989
14990 static int
14991 api_show_lisp_status (vat_main_t * vam)
14992 {
14993   vl_api_show_lisp_status_t *mp;
14994   f64 timeout = ~0;
14995
14996   if (!vam->json_output)
14997     {
14998       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14999     }
15000
15001   M (SHOW_LISP_STATUS, show_lisp_status);
15002   /* send it... */
15003   S;
15004   /* Wait for a reply... */
15005   W;
15006
15007   /* NOTREACHED */
15008   return 0;
15009 }
15010
15011 static int
15012 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
15013 {
15014   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
15015   f64 timeout = ~0;
15016
15017   if (!vam->json_output)
15018     {
15019       print (vam->ofp, "%=20s", "itr-rlocs:");
15020     }
15021
15022   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
15023   /* send it... */
15024   S;
15025   /* Wait for a reply... */
15026   W;
15027
15028   /* NOTREACHED */
15029   return 0;
15030 }
15031
15032 static int
15033 api_af_packet_create (vat_main_t * vam)
15034 {
15035   unformat_input_t *i = vam->input;
15036   vl_api_af_packet_create_t *mp;
15037   f64 timeout;
15038   u8 *host_if_name = 0;
15039   u8 hw_addr[6];
15040   u8 random_hw_addr = 1;
15041
15042   memset (hw_addr, 0, sizeof (hw_addr));
15043
15044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15045     {
15046       if (unformat (i, "name %s", &host_if_name))
15047         vec_add1 (host_if_name, 0);
15048       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15049         random_hw_addr = 0;
15050       else
15051         break;
15052     }
15053
15054   if (!vec_len (host_if_name))
15055     {
15056       errmsg ("host-interface name must be specified");
15057       return -99;
15058     }
15059
15060   if (vec_len (host_if_name) > 64)
15061     {
15062       errmsg ("host-interface name too long");
15063       return -99;
15064     }
15065
15066   M (AF_PACKET_CREATE, af_packet_create);
15067
15068   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15069   clib_memcpy (mp->hw_addr, hw_addr, 6);
15070   mp->use_random_hw_addr = random_hw_addr;
15071   vec_free (host_if_name);
15072
15073   S;
15074   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15075   /* NOTREACHED */
15076   return 0;
15077 }
15078
15079 static int
15080 api_af_packet_delete (vat_main_t * vam)
15081 {
15082   unformat_input_t *i = vam->input;
15083   vl_api_af_packet_delete_t *mp;
15084   f64 timeout;
15085   u8 *host_if_name = 0;
15086
15087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15088     {
15089       if (unformat (i, "name %s", &host_if_name))
15090         vec_add1 (host_if_name, 0);
15091       else
15092         break;
15093     }
15094
15095   if (!vec_len (host_if_name))
15096     {
15097       errmsg ("host-interface name must be specified");
15098       return -99;
15099     }
15100
15101   if (vec_len (host_if_name) > 64)
15102     {
15103       errmsg ("host-interface name too long");
15104       return -99;
15105     }
15106
15107   M (AF_PACKET_DELETE, af_packet_delete);
15108
15109   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15110   vec_free (host_if_name);
15111
15112   S;
15113   W;
15114   /* NOTREACHED */
15115   return 0;
15116 }
15117
15118 static int
15119 api_policer_add_del (vat_main_t * vam)
15120 {
15121   unformat_input_t *i = vam->input;
15122   vl_api_policer_add_del_t *mp;
15123   f64 timeout;
15124   u8 is_add = 1;
15125   u8 *name = 0;
15126   u32 cir = 0;
15127   u32 eir = 0;
15128   u64 cb = 0;
15129   u64 eb = 0;
15130   u8 rate_type = 0;
15131   u8 round_type = 0;
15132   u8 type = 0;
15133   u8 color_aware = 0;
15134   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15135
15136   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15137   conform_action.dscp = 0;
15138   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15139   exceed_action.dscp = 0;
15140   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15141   violate_action.dscp = 0;
15142
15143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15144     {
15145       if (unformat (i, "del"))
15146         is_add = 0;
15147       else if (unformat (i, "name %s", &name))
15148         vec_add1 (name, 0);
15149       else if (unformat (i, "cir %u", &cir))
15150         ;
15151       else if (unformat (i, "eir %u", &eir))
15152         ;
15153       else if (unformat (i, "cb %u", &cb))
15154         ;
15155       else if (unformat (i, "eb %u", &eb))
15156         ;
15157       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15158                          &rate_type))
15159         ;
15160       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15161                          &round_type))
15162         ;
15163       else if (unformat (i, "type %U", unformat_policer_type, &type))
15164         ;
15165       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15166                          &conform_action))
15167         ;
15168       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15169                          &exceed_action))
15170         ;
15171       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15172                          &violate_action))
15173         ;
15174       else if (unformat (i, "color-aware"))
15175         color_aware = 1;
15176       else
15177         break;
15178     }
15179
15180   if (!vec_len (name))
15181     {
15182       errmsg ("policer name must be specified");
15183       return -99;
15184     }
15185
15186   if (vec_len (name) > 64)
15187     {
15188       errmsg ("policer name too long");
15189       return -99;
15190     }
15191
15192   M (POLICER_ADD_DEL, policer_add_del);
15193
15194   clib_memcpy (mp->name, name, vec_len (name));
15195   vec_free (name);
15196   mp->is_add = is_add;
15197   mp->cir = cir;
15198   mp->eir = eir;
15199   mp->cb = cb;
15200   mp->eb = eb;
15201   mp->rate_type = rate_type;
15202   mp->round_type = round_type;
15203   mp->type = type;
15204   mp->conform_action_type = conform_action.action_type;
15205   mp->conform_dscp = conform_action.dscp;
15206   mp->exceed_action_type = exceed_action.action_type;
15207   mp->exceed_dscp = exceed_action.dscp;
15208   mp->violate_action_type = violate_action.action_type;
15209   mp->violate_dscp = violate_action.dscp;
15210   mp->color_aware = color_aware;
15211
15212   S;
15213   W;
15214   /* NOTREACHED */
15215   return 0;
15216 }
15217
15218 static int
15219 api_policer_dump (vat_main_t * vam)
15220 {
15221   unformat_input_t *i = vam->input;
15222   vl_api_policer_dump_t *mp;
15223   f64 timeout = ~0;
15224   u8 *match_name = 0;
15225   u8 match_name_valid = 0;
15226
15227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15228     {
15229       if (unformat (i, "name %s", &match_name))
15230         {
15231           vec_add1 (match_name, 0);
15232           match_name_valid = 1;
15233         }
15234       else
15235         break;
15236     }
15237
15238   M (POLICER_DUMP, policer_dump);
15239   mp->match_name_valid = match_name_valid;
15240   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15241   vec_free (match_name);
15242   /* send it... */
15243   S;
15244
15245   /* Use a control ping for synchronization */
15246   {
15247     vl_api_control_ping_t *mp;
15248     M (CONTROL_PING, control_ping);
15249     S;
15250   }
15251   /* Wait for a reply... */
15252   W;
15253
15254   /* NOTREACHED */
15255   return 0;
15256 }
15257
15258 static int
15259 api_policer_classify_set_interface (vat_main_t * vam)
15260 {
15261   unformat_input_t *i = vam->input;
15262   vl_api_policer_classify_set_interface_t *mp;
15263   f64 timeout;
15264   u32 sw_if_index;
15265   int sw_if_index_set;
15266   u32 ip4_table_index = ~0;
15267   u32 ip6_table_index = ~0;
15268   u32 l2_table_index = ~0;
15269   u8 is_add = 1;
15270
15271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15272     {
15273       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15274         sw_if_index_set = 1;
15275       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15276         sw_if_index_set = 1;
15277       else if (unformat (i, "del"))
15278         is_add = 0;
15279       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15280         ;
15281       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15282         ;
15283       else if (unformat (i, "l2-table %d", &l2_table_index))
15284         ;
15285       else
15286         {
15287           clib_warning ("parse error '%U'", format_unformat_error, i);
15288           return -99;
15289         }
15290     }
15291
15292   if (sw_if_index_set == 0)
15293     {
15294       errmsg ("missing interface name or sw_if_index");
15295       return -99;
15296     }
15297
15298   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15299
15300   mp->sw_if_index = ntohl (sw_if_index);
15301   mp->ip4_table_index = ntohl (ip4_table_index);
15302   mp->ip6_table_index = ntohl (ip6_table_index);
15303   mp->l2_table_index = ntohl (l2_table_index);
15304   mp->is_add = is_add;
15305
15306   S;
15307   W;
15308   /* NOTREACHED */
15309   return 0;
15310 }
15311
15312 static int
15313 api_policer_classify_dump (vat_main_t * vam)
15314 {
15315   unformat_input_t *i = vam->input;
15316   vl_api_policer_classify_dump_t *mp;
15317   f64 timeout = ~0;
15318   u8 type = POLICER_CLASSIFY_N_TABLES;
15319
15320   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15321     ;
15322   else
15323     {
15324       errmsg ("classify table type must be specified");
15325       return -99;
15326     }
15327
15328   if (!vam->json_output)
15329     {
15330       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15331     }
15332
15333   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15334   mp->type = type;
15335   /* send it... */
15336   S;
15337
15338   /* Use a control ping for synchronization */
15339   {
15340     vl_api_control_ping_t *mp;
15341     M (CONTROL_PING, control_ping);
15342     S;
15343   }
15344   /* Wait for a reply... */
15345   W;
15346
15347   /* NOTREACHED */
15348   return 0;
15349 }
15350
15351 static int
15352 api_netmap_create (vat_main_t * vam)
15353 {
15354   unformat_input_t *i = vam->input;
15355   vl_api_netmap_create_t *mp;
15356   f64 timeout;
15357   u8 *if_name = 0;
15358   u8 hw_addr[6];
15359   u8 random_hw_addr = 1;
15360   u8 is_pipe = 0;
15361   u8 is_master = 0;
15362
15363   memset (hw_addr, 0, sizeof (hw_addr));
15364
15365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15366     {
15367       if (unformat (i, "name %s", &if_name))
15368         vec_add1 (if_name, 0);
15369       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15370         random_hw_addr = 0;
15371       else if (unformat (i, "pipe"))
15372         is_pipe = 1;
15373       else if (unformat (i, "master"))
15374         is_master = 1;
15375       else if (unformat (i, "slave"))
15376         is_master = 0;
15377       else
15378         break;
15379     }
15380
15381   if (!vec_len (if_name))
15382     {
15383       errmsg ("interface name must be specified");
15384       return -99;
15385     }
15386
15387   if (vec_len (if_name) > 64)
15388     {
15389       errmsg ("interface name too long");
15390       return -99;
15391     }
15392
15393   M (NETMAP_CREATE, netmap_create);
15394
15395   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15396   clib_memcpy (mp->hw_addr, hw_addr, 6);
15397   mp->use_random_hw_addr = random_hw_addr;
15398   mp->is_pipe = is_pipe;
15399   mp->is_master = is_master;
15400   vec_free (if_name);
15401
15402   S;
15403   W;
15404   /* NOTREACHED */
15405   return 0;
15406 }
15407
15408 static int
15409 api_netmap_delete (vat_main_t * vam)
15410 {
15411   unformat_input_t *i = vam->input;
15412   vl_api_netmap_delete_t *mp;
15413   f64 timeout;
15414   u8 *if_name = 0;
15415
15416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15417     {
15418       if (unformat (i, "name %s", &if_name))
15419         vec_add1 (if_name, 0);
15420       else
15421         break;
15422     }
15423
15424   if (!vec_len (if_name))
15425     {
15426       errmsg ("interface name must be specified");
15427       return -99;
15428     }
15429
15430   if (vec_len (if_name) > 64)
15431     {
15432       errmsg ("interface name too long");
15433       return -99;
15434     }
15435
15436   M (NETMAP_DELETE, netmap_delete);
15437
15438   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15439   vec_free (if_name);
15440
15441   S;
15442   W;
15443   /* NOTREACHED */
15444   return 0;
15445 }
15446
15447 static void vl_api_mpls_tunnel_details_t_handler
15448   (vl_api_mpls_tunnel_details_t * mp)
15449 {
15450   vat_main_t *vam = &vat_main;
15451   i32 len = mp->mt_next_hop_n_labels;
15452   i32 i;
15453
15454   print (vam->ofp, "[%d]: via %U %d labels ",
15455          mp->tunnel_index,
15456          format_ip4_address, mp->mt_next_hop,
15457          ntohl (mp->mt_next_hop_sw_if_index));
15458   for (i = 0; i < len; i++)
15459     {
15460       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15461     }
15462   print (vam->ofp, "");
15463 }
15464
15465 static void vl_api_mpls_tunnel_details_t_handler_json
15466   (vl_api_mpls_tunnel_details_t * mp)
15467 {
15468   vat_main_t *vam = &vat_main;
15469   vat_json_node_t *node = NULL;
15470   struct in_addr ip4;
15471   i32 i;
15472   i32 len = mp->mt_next_hop_n_labels;
15473
15474   if (VAT_JSON_ARRAY != vam->json_tree.type)
15475     {
15476       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15477       vat_json_init_array (&vam->json_tree);
15478     }
15479   node = vat_json_array_add (&vam->json_tree);
15480
15481   vat_json_init_object (node);
15482   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15483   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15484   vat_json_object_add_ip4 (node, "next_hop", ip4);
15485   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15486                             ntohl (mp->mt_next_hop_sw_if_index));
15487   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15488   vat_json_object_add_uint (node, "label_count", len);
15489   for (i = 0; i < len; i++)
15490     {
15491       vat_json_object_add_uint (node, "label",
15492                                 ntohl (mp->mt_next_hop_out_labels[i]));
15493     }
15494 }
15495
15496 static int
15497 api_mpls_tunnel_dump (vat_main_t * vam)
15498 {
15499   vl_api_mpls_tunnel_dump_t *mp;
15500   f64 timeout;
15501   i32 index = -1;
15502
15503   /* Parse args required to build the message */
15504   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15505     {
15506       if (!unformat (vam->input, "tunnel_index %d", &index))
15507         {
15508           index = -1;
15509           break;
15510         }
15511     }
15512
15513   print (vam->ofp, "  tunnel_index %d", index);
15514
15515   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15516   mp->tunnel_index = htonl (index);
15517   S;
15518
15519   /* Use a control ping for synchronization */
15520   {
15521     vl_api_control_ping_t *mp;
15522     M (CONTROL_PING, control_ping);
15523     S;
15524   }
15525   W;
15526 }
15527
15528 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15529 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15530
15531 static void
15532 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15533 {
15534   vat_main_t *vam = &vat_main;
15535   int count = ntohl (mp->count);
15536   vl_api_fib_path2_t *fp;
15537   int i;
15538
15539   print (vam->ofp,
15540          "table-id %d, label %u, ess_bit %u",
15541          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15542   fp = mp->path;
15543   for (i = 0; i < count; i++)
15544     {
15545       if (fp->afi == IP46_TYPE_IP6)
15546         print (vam->ofp,
15547                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15548                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15549                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15550                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15551                format_ip6_address, fp->next_hop);
15552       else if (fp->afi == IP46_TYPE_IP4)
15553         print (vam->ofp,
15554                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15555                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15556                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15557                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15558                format_ip4_address, fp->next_hop);
15559       fp++;
15560     }
15561 }
15562
15563 static void vl_api_mpls_fib_details_t_handler_json
15564   (vl_api_mpls_fib_details_t * mp)
15565 {
15566   vat_main_t *vam = &vat_main;
15567   int count = ntohl (mp->count);
15568   vat_json_node_t *node = NULL;
15569   struct in_addr ip4;
15570   struct in6_addr ip6;
15571   vl_api_fib_path2_t *fp;
15572   int i;
15573
15574   if (VAT_JSON_ARRAY != vam->json_tree.type)
15575     {
15576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15577       vat_json_init_array (&vam->json_tree);
15578     }
15579   node = vat_json_array_add (&vam->json_tree);
15580
15581   vat_json_init_object (node);
15582   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15583   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15584   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15585   vat_json_object_add_uint (node, "path_count", count);
15586   fp = mp->path;
15587   for (i = 0; i < count; i++)
15588     {
15589       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15590       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15591       vat_json_object_add_uint (node, "is_local", fp->is_local);
15592       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15593       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15594       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15595       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15596       if (fp->afi == IP46_TYPE_IP4)
15597         {
15598           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15599           vat_json_object_add_ip4 (node, "next_hop", ip4);
15600         }
15601       else if (fp->afi == IP46_TYPE_IP6)
15602         {
15603           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15604           vat_json_object_add_ip6 (node, "next_hop", ip6);
15605         }
15606     }
15607 }
15608
15609 static int
15610 api_mpls_fib_dump (vat_main_t * vam)
15611 {
15612   vl_api_mpls_fib_dump_t *mp;
15613   f64 timeout;
15614
15615   M (MPLS_FIB_DUMP, mpls_fib_dump);
15616   S;
15617
15618   /* Use a control ping for synchronization */
15619   {
15620     vl_api_control_ping_t *mp;
15621     M (CONTROL_PING, control_ping);
15622     S;
15623   }
15624   W;
15625 }
15626
15627 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15628 #define vl_api_ip_fib_details_t_print vl_noop_handler
15629
15630 static void
15631 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15632 {
15633   vat_main_t *vam = &vat_main;
15634   int count = ntohl (mp->count);
15635   vl_api_fib_path_t *fp;
15636   int i;
15637
15638   print (vam->ofp,
15639          "table-id %d, prefix %U/%d",
15640          ntohl (mp->table_id), format_ip4_address, mp->address,
15641          mp->address_length);
15642   fp = mp->path;
15643   for (i = 0; i < count; i++)
15644     {
15645       if (fp->afi == IP46_TYPE_IP6)
15646         print (vam->ofp,
15647                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15648                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15649                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15650                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15651                format_ip6_address, fp->next_hop);
15652       else if (fp->afi == IP46_TYPE_IP4)
15653         print (vam->ofp,
15654                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15655                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15656                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15657                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15658                format_ip4_address, fp->next_hop);
15659       fp++;
15660     }
15661 }
15662
15663 static void vl_api_ip_fib_details_t_handler_json
15664   (vl_api_ip_fib_details_t * mp)
15665 {
15666   vat_main_t *vam = &vat_main;
15667   int count = ntohl (mp->count);
15668   vat_json_node_t *node = NULL;
15669   struct in_addr ip4;
15670   struct in6_addr ip6;
15671   vl_api_fib_path_t *fp;
15672   int i;
15673
15674   if (VAT_JSON_ARRAY != vam->json_tree.type)
15675     {
15676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15677       vat_json_init_array (&vam->json_tree);
15678     }
15679   node = vat_json_array_add (&vam->json_tree);
15680
15681   vat_json_init_object (node);
15682   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15683   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15684   vat_json_object_add_ip4 (node, "prefix", ip4);
15685   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15686   vat_json_object_add_uint (node, "path_count", count);
15687   fp = mp->path;
15688   for (i = 0; i < count; i++)
15689     {
15690       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15691       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15692       vat_json_object_add_uint (node, "is_local", fp->is_local);
15693       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15694       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15695       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15696       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15697       if (fp->afi == IP46_TYPE_IP4)
15698         {
15699           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15700           vat_json_object_add_ip4 (node, "next_hop", ip4);
15701         }
15702       else if (fp->afi == IP46_TYPE_IP6)
15703         {
15704           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15705           vat_json_object_add_ip6 (node, "next_hop", ip6);
15706         }
15707     }
15708 }
15709
15710 static int
15711 api_ip_fib_dump (vat_main_t * vam)
15712 {
15713   vl_api_ip_fib_dump_t *mp;
15714   f64 timeout;
15715
15716   M (IP_FIB_DUMP, ip_fib_dump);
15717   S;
15718
15719   /* Use a control ping for synchronization */
15720   {
15721     vl_api_control_ping_t *mp;
15722     M (CONTROL_PING, control_ping);
15723     S;
15724   }
15725   W;
15726 }
15727
15728 static void vl_api_ip_neighbor_details_t_handler
15729   (vl_api_ip_neighbor_details_t * mp)
15730 {
15731   vat_main_t *vam = &vat_main;
15732
15733   print (vam->ofp, "%c %U %U",
15734          (mp->is_static) ? 'S' : 'D',
15735          format_ethernet_address, &mp->mac_address,
15736          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15737          &mp->ip_address);
15738 }
15739
15740 static void vl_api_ip_neighbor_details_t_handler_json
15741   (vl_api_ip_neighbor_details_t * mp)
15742 {
15743
15744   vat_main_t *vam = &vat_main;
15745   vat_json_node_t *node;
15746   struct in_addr ip4;
15747   struct in6_addr ip6;
15748
15749   if (VAT_JSON_ARRAY != vam->json_tree.type)
15750     {
15751       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15752       vat_json_init_array (&vam->json_tree);
15753     }
15754   node = vat_json_array_add (&vam->json_tree);
15755
15756   vat_json_init_object (node);
15757   vat_json_object_add_string_copy (node, "flag",
15758                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15759                                    "dynamic");
15760
15761   vat_json_object_add_string_copy (node, "link_layer",
15762                                    format (0, "%U", format_ethernet_address,
15763                                            &mp->mac_address));
15764
15765   if (mp->is_ipv6)
15766     {
15767       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15768       vat_json_object_add_ip6 (node, "ip_address", ip6);
15769     }
15770   else
15771     {
15772       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15773       vat_json_object_add_ip4 (node, "ip_address", ip4);
15774     }
15775 }
15776
15777 static int
15778 api_ip_neighbor_dump (vat_main_t * vam)
15779 {
15780   unformat_input_t *i = vam->input;
15781   vl_api_ip_neighbor_dump_t *mp;
15782   f64 timeout;
15783   u8 is_ipv6 = 0;
15784   u32 sw_if_index = ~0;
15785
15786   /* Parse args required to build the message */
15787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15788     {
15789       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15790         ;
15791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15792         ;
15793       else if (unformat (i, "ip6"))
15794         is_ipv6 = 1;
15795       else
15796         break;
15797     }
15798
15799   if (sw_if_index == ~0)
15800     {
15801       errmsg ("missing interface name or sw_if_index");
15802       return -99;
15803     }
15804
15805   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15806   mp->is_ipv6 = (u8) is_ipv6;
15807   mp->sw_if_index = ntohl (sw_if_index);
15808   S;
15809
15810   /* Use a control ping for synchronization */
15811   {
15812     vl_api_control_ping_t *mp;
15813     M (CONTROL_PING, control_ping);
15814     S;
15815   }
15816   W;
15817 }
15818
15819 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15820 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15821
15822 static void
15823 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15824 {
15825   vat_main_t *vam = &vat_main;
15826   int count = ntohl (mp->count);
15827   vl_api_fib_path_t *fp;
15828   int i;
15829
15830   print (vam->ofp,
15831          "table-id %d, prefix %U/%d",
15832          ntohl (mp->table_id), format_ip6_address, mp->address,
15833          mp->address_length);
15834   fp = mp->path;
15835   for (i = 0; i < count; i++)
15836     {
15837       if (fp->afi == IP46_TYPE_IP6)
15838         print (vam->ofp,
15839                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15840                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15841                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15842                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15843                format_ip6_address, fp->next_hop);
15844       else if (fp->afi == IP46_TYPE_IP4)
15845         print (vam->ofp,
15846                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15847                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15848                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15849                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15850                format_ip4_address, fp->next_hop);
15851       fp++;
15852     }
15853 }
15854
15855 static void vl_api_ip6_fib_details_t_handler_json
15856   (vl_api_ip6_fib_details_t * mp)
15857 {
15858   vat_main_t *vam = &vat_main;
15859   int count = ntohl (mp->count);
15860   vat_json_node_t *node = NULL;
15861   struct in_addr ip4;
15862   struct in6_addr ip6;
15863   vl_api_fib_path_t *fp;
15864   int i;
15865
15866   if (VAT_JSON_ARRAY != vam->json_tree.type)
15867     {
15868       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15869       vat_json_init_array (&vam->json_tree);
15870     }
15871   node = vat_json_array_add (&vam->json_tree);
15872
15873   vat_json_init_object (node);
15874   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15875   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15876   vat_json_object_add_ip6 (node, "prefix", ip6);
15877   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15878   vat_json_object_add_uint (node, "path_count", count);
15879   fp = mp->path;
15880   for (i = 0; i < count; i++)
15881     {
15882       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15883       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15884       vat_json_object_add_uint (node, "is_local", fp->is_local);
15885       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15886       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15887       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15888       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15889       if (fp->afi == IP46_TYPE_IP4)
15890         {
15891           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15892           vat_json_object_add_ip4 (node, "next_hop", ip4);
15893         }
15894       else if (fp->afi == IP46_TYPE_IP6)
15895         {
15896           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15897           vat_json_object_add_ip6 (node, "next_hop", ip6);
15898         }
15899     }
15900 }
15901
15902 static int
15903 api_ip6_fib_dump (vat_main_t * vam)
15904 {
15905   vl_api_ip6_fib_dump_t *mp;
15906   f64 timeout;
15907
15908   M (IP6_FIB_DUMP, ip6_fib_dump);
15909   S;
15910
15911   /* Use a control ping for synchronization */
15912   {
15913     vl_api_control_ping_t *mp;
15914     M (CONTROL_PING, control_ping);
15915     S;
15916   }
15917   W;
15918 }
15919
15920 int
15921 api_classify_table_ids (vat_main_t * vam)
15922 {
15923   vl_api_classify_table_ids_t *mp;
15924   f64 timeout;
15925
15926   /* Construct the API message */
15927   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15928   mp->context = 0;
15929
15930   S;
15931   W;
15932   /* NOTREACHED */
15933   return 0;
15934 }
15935
15936 int
15937 api_classify_table_by_interface (vat_main_t * vam)
15938 {
15939   unformat_input_t *input = vam->input;
15940   vl_api_classify_table_by_interface_t *mp;
15941   f64 timeout;
15942
15943   u32 sw_if_index = ~0;
15944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15945     {
15946       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15947         ;
15948       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15949         ;
15950       else
15951         break;
15952     }
15953   if (sw_if_index == ~0)
15954     {
15955       errmsg ("missing interface name or sw_if_index");
15956       return -99;
15957     }
15958
15959   /* Construct the API message */
15960   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15961   mp->context = 0;
15962   mp->sw_if_index = ntohl (sw_if_index);
15963
15964   S;
15965   W;
15966   /* NOTREACHED */
15967   return 0;
15968 }
15969
15970 int
15971 api_classify_table_info (vat_main_t * vam)
15972 {
15973   unformat_input_t *input = vam->input;
15974   vl_api_classify_table_info_t *mp;
15975   f64 timeout;
15976
15977   u32 table_id = ~0;
15978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15979     {
15980       if (unformat (input, "table_id %d", &table_id))
15981         ;
15982       else
15983         break;
15984     }
15985   if (table_id == ~0)
15986     {
15987       errmsg ("missing table id");
15988       return -99;
15989     }
15990
15991   /* Construct the API message */
15992   M (CLASSIFY_TABLE_INFO, classify_table_info);
15993   mp->context = 0;
15994   mp->table_id = ntohl (table_id);
15995
15996   S;
15997   W;
15998   /* NOTREACHED */
15999   return 0;
16000 }
16001
16002 int
16003 api_classify_session_dump (vat_main_t * vam)
16004 {
16005   unformat_input_t *input = vam->input;
16006   vl_api_classify_session_dump_t *mp;
16007   f64 timeout;
16008
16009   u32 table_id = ~0;
16010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16011     {
16012       if (unformat (input, "table_id %d", &table_id))
16013         ;
16014       else
16015         break;
16016     }
16017   if (table_id == ~0)
16018     {
16019       errmsg ("missing table id");
16020       return -99;
16021     }
16022
16023   /* Construct the API message */
16024   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
16025   mp->context = 0;
16026   mp->table_id = ntohl (table_id);
16027   S;
16028
16029   /* Use a control ping for synchronization */
16030   {
16031     vl_api_control_ping_t *mp;
16032     M (CONTROL_PING, control_ping);
16033     S;
16034   }
16035   W;
16036   /* NOTREACHED */
16037   return 0;
16038 }
16039
16040 static void
16041 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16042 {
16043   vat_main_t *vam = &vat_main;
16044
16045   print (vam->ofp, "collector_address %U, collector_port %d, "
16046          "src_address %U, vrf_id %d, path_mtu %u, "
16047          "template_interval %u, udp_checksum %d",
16048          format_ip4_address, mp->collector_address,
16049          ntohs (mp->collector_port),
16050          format_ip4_address, mp->src_address,
16051          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16052          ntohl (mp->template_interval), mp->udp_checksum);
16053
16054   vam->retval = 0;
16055   vam->result_ready = 1;
16056 }
16057
16058 static void
16059   vl_api_ipfix_exporter_details_t_handler_json
16060   (vl_api_ipfix_exporter_details_t * mp)
16061 {
16062   vat_main_t *vam = &vat_main;
16063   vat_json_node_t node;
16064   struct in_addr collector_address;
16065   struct in_addr src_address;
16066
16067   vat_json_init_object (&node);
16068   clib_memcpy (&collector_address, &mp->collector_address,
16069                sizeof (collector_address));
16070   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16071   vat_json_object_add_uint (&node, "collector_port",
16072                             ntohs (mp->collector_port));
16073   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16074   vat_json_object_add_ip4 (&node, "src_address", src_address);
16075   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16076   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16077   vat_json_object_add_uint (&node, "template_interval",
16078                             ntohl (mp->template_interval));
16079   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16080
16081   vat_json_print (vam->ofp, &node);
16082   vat_json_free (&node);
16083   vam->retval = 0;
16084   vam->result_ready = 1;
16085 }
16086
16087 int
16088 api_ipfix_exporter_dump (vat_main_t * vam)
16089 {
16090   vl_api_ipfix_exporter_dump_t *mp;
16091   f64 timeout;
16092
16093   /* Construct the API message */
16094   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
16095   mp->context = 0;
16096
16097   S;
16098   W;
16099   /* NOTREACHED */
16100   return 0;
16101 }
16102
16103 static int
16104 api_ipfix_classify_stream_dump (vat_main_t * vam)
16105 {
16106   vl_api_ipfix_classify_stream_dump_t *mp;
16107   f64 timeout;
16108
16109   /* Construct the API message */
16110   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
16111   mp->context = 0;
16112
16113   S;
16114   W;
16115   /* NOTREACHED */
16116   return 0;
16117 }
16118
16119 static void
16120   vl_api_ipfix_classify_stream_details_t_handler
16121   (vl_api_ipfix_classify_stream_details_t * mp)
16122 {
16123   vat_main_t *vam = &vat_main;
16124   print (vam->ofp, "domain_id %d, src_port %d",
16125          ntohl (mp->domain_id), ntohs (mp->src_port));
16126   vam->retval = 0;
16127   vam->result_ready = 1;
16128 }
16129
16130 static void
16131   vl_api_ipfix_classify_stream_details_t_handler_json
16132   (vl_api_ipfix_classify_stream_details_t * mp)
16133 {
16134   vat_main_t *vam = &vat_main;
16135   vat_json_node_t node;
16136
16137   vat_json_init_object (&node);
16138   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16139   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16140
16141   vat_json_print (vam->ofp, &node);
16142   vat_json_free (&node);
16143   vam->retval = 0;
16144   vam->result_ready = 1;
16145 }
16146
16147 static int
16148 api_ipfix_classify_table_dump (vat_main_t * vam)
16149 {
16150   vl_api_ipfix_classify_table_dump_t *mp;
16151   f64 timeout;
16152
16153   if (!vam->json_output)
16154     {
16155       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16156              "transport_protocol");
16157     }
16158
16159   /* Construct the API message */
16160   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
16161
16162   /* send it... */
16163   S;
16164
16165   /* Use a control ping for synchronization */
16166   {
16167     vl_api_control_ping_t *mp;
16168     M (CONTROL_PING, control_ping);
16169     S;
16170   }
16171   W;
16172 }
16173
16174 static void
16175   vl_api_ipfix_classify_table_details_t_handler
16176   (vl_api_ipfix_classify_table_details_t * mp)
16177 {
16178   vat_main_t *vam = &vat_main;
16179   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16180          mp->transport_protocol);
16181 }
16182
16183 static void
16184   vl_api_ipfix_classify_table_details_t_handler_json
16185   (vl_api_ipfix_classify_table_details_t * mp)
16186 {
16187   vat_json_node_t *node = NULL;
16188   vat_main_t *vam = &vat_main;
16189
16190   if (VAT_JSON_ARRAY != vam->json_tree.type)
16191     {
16192       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16193       vat_json_init_array (&vam->json_tree);
16194     }
16195
16196   node = vat_json_array_add (&vam->json_tree);
16197   vat_json_init_object (node);
16198
16199   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16200   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16201   vat_json_object_add_uint (node, "transport_protocol",
16202                             mp->transport_protocol);
16203 }
16204
16205 static int
16206 api_sw_interface_span_enable_disable (vat_main_t * vam)
16207 {
16208   unformat_input_t *i = vam->input;
16209   vl_api_sw_interface_span_enable_disable_t *mp;
16210   f64 timeout;
16211   u32 src_sw_if_index = ~0;
16212   u32 dst_sw_if_index = ~0;
16213   u8 state = 3;
16214
16215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16216     {
16217       if (unformat
16218           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16219         ;
16220       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16221         ;
16222       else
16223         if (unformat
16224             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16225         ;
16226       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16227         ;
16228       else if (unformat (i, "disable"))
16229         state = 0;
16230       else if (unformat (i, "rx"))
16231         state = 1;
16232       else if (unformat (i, "tx"))
16233         state = 2;
16234       else if (unformat (i, "both"))
16235         state = 3;
16236       else
16237         break;
16238     }
16239
16240   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16241
16242   mp->sw_if_index_from = htonl (src_sw_if_index);
16243   mp->sw_if_index_to = htonl (dst_sw_if_index);
16244   mp->state = state;
16245
16246   S;
16247   W;
16248   /* NOTREACHED */
16249   return 0;
16250 }
16251
16252 static void
16253 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16254                                             * mp)
16255 {
16256   vat_main_t *vam = &vat_main;
16257   u8 *sw_if_from_name = 0;
16258   u8 *sw_if_to_name = 0;
16259   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16260   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16261   char *states[] = { "none", "rx", "tx", "both" };
16262   hash_pair_t *p;
16263
16264   /* *INDENT-OFF* */
16265   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16266   ({
16267     if ((u32) p->value[0] == sw_if_index_from)
16268       {
16269         sw_if_from_name = (u8 *)(p->key);
16270         if (sw_if_to_name)
16271           break;
16272       }
16273     if ((u32) p->value[0] == sw_if_index_to)
16274       {
16275         sw_if_to_name = (u8 *)(p->key);
16276         if (sw_if_from_name)
16277           break;
16278       }
16279   }));
16280   /* *INDENT-ON* */
16281   print (vam->ofp, "%20s => %20s (%s)",
16282          sw_if_from_name, sw_if_to_name, states[mp->state]);
16283 }
16284
16285 static void
16286   vl_api_sw_interface_span_details_t_handler_json
16287   (vl_api_sw_interface_span_details_t * mp)
16288 {
16289   vat_main_t *vam = &vat_main;
16290   vat_json_node_t *node = NULL;
16291   u8 *sw_if_from_name = 0;
16292   u8 *sw_if_to_name = 0;
16293   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16294   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16295   hash_pair_t *p;
16296
16297   /* *INDENT-OFF* */
16298   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16299   ({
16300     if ((u32) p->value[0] == sw_if_index_from)
16301       {
16302         sw_if_from_name = (u8 *)(p->key);
16303         if (sw_if_to_name)
16304           break;
16305       }
16306     if ((u32) p->value[0] == sw_if_index_to)
16307       {
16308         sw_if_to_name = (u8 *)(p->key);
16309         if (sw_if_from_name)
16310           break;
16311       }
16312   }));
16313   /* *INDENT-ON* */
16314
16315   if (VAT_JSON_ARRAY != vam->json_tree.type)
16316     {
16317       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16318       vat_json_init_array (&vam->json_tree);
16319     }
16320   node = vat_json_array_add (&vam->json_tree);
16321
16322   vat_json_init_object (node);
16323   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16324   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16325   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16326   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16327   vat_json_object_add_uint (node, "state", mp->state);
16328 }
16329
16330 static int
16331 api_sw_interface_span_dump (vat_main_t * vam)
16332 {
16333   vl_api_sw_interface_span_dump_t *mp;
16334   f64 timeout;
16335
16336   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16337   S;
16338
16339   /* Use a control ping for synchronization */
16340   {
16341     vl_api_control_ping_t *mp;
16342     M (CONTROL_PING, control_ping);
16343     S;
16344   }
16345   W;
16346 }
16347
16348 int
16349 api_pg_create_interface (vat_main_t * vam)
16350 {
16351   unformat_input_t *input = vam->input;
16352   vl_api_pg_create_interface_t *mp;
16353   f64 timeout;
16354
16355   u32 if_id = ~0;
16356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16357     {
16358       if (unformat (input, "if_id %d", &if_id))
16359         ;
16360       else
16361         break;
16362     }
16363   if (if_id == ~0)
16364     {
16365       errmsg ("missing pg interface index");
16366       return -99;
16367     }
16368
16369   /* Construct the API message */
16370   M (PG_CREATE_INTERFACE, pg_create_interface);
16371   mp->context = 0;
16372   mp->interface_id = ntohl (if_id);
16373
16374   S;
16375   W;
16376   /* NOTREACHED */
16377   return 0;
16378 }
16379
16380 int
16381 api_pg_capture (vat_main_t * vam)
16382 {
16383   unformat_input_t *input = vam->input;
16384   vl_api_pg_capture_t *mp;
16385   f64 timeout;
16386
16387   u32 if_id = ~0;
16388   u8 enable = 1;
16389   u32 count = 1;
16390   u8 pcap_file_set = 0;
16391   u8 *pcap_file = 0;
16392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16393     {
16394       if (unformat (input, "if_id %d", &if_id))
16395         ;
16396       else if (unformat (input, "pcap %s", &pcap_file))
16397         pcap_file_set = 1;
16398       else if (unformat (input, "count %d", &count))
16399         ;
16400       else if (unformat (input, "disable"))
16401         enable = 0;
16402       else
16403         break;
16404     }
16405   if (if_id == ~0)
16406     {
16407       errmsg ("missing pg interface index");
16408       return -99;
16409     }
16410   if (pcap_file_set > 0)
16411     {
16412       if (vec_len (pcap_file) > 255)
16413         {
16414           errmsg ("pcap file name is too long");
16415           return -99;
16416         }
16417     }
16418
16419   u32 name_len = vec_len (pcap_file);
16420   /* Construct the API message */
16421   M (PG_CAPTURE, pg_capture);
16422   mp->context = 0;
16423   mp->interface_id = ntohl (if_id);
16424   mp->is_enabled = enable;
16425   mp->count = ntohl (count);
16426   mp->pcap_name_length = ntohl (name_len);
16427   if (pcap_file_set != 0)
16428     {
16429       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16430     }
16431   vec_free (pcap_file);
16432
16433   S;
16434   W;
16435   /* NOTREACHED */
16436   return 0;
16437 }
16438
16439 int
16440 api_pg_enable_disable (vat_main_t * vam)
16441 {
16442   unformat_input_t *input = vam->input;
16443   vl_api_pg_enable_disable_t *mp;
16444   f64 timeout;
16445
16446   u8 enable = 1;
16447   u8 stream_name_set = 0;
16448   u8 *stream_name = 0;
16449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16450     {
16451       if (unformat (input, "stream %s", &stream_name))
16452         stream_name_set = 1;
16453       else if (unformat (input, "disable"))
16454         enable = 0;
16455       else
16456         break;
16457     }
16458
16459   if (stream_name_set > 0)
16460     {
16461       if (vec_len (stream_name) > 255)
16462         {
16463           errmsg ("stream name too long");
16464           return -99;
16465         }
16466     }
16467
16468   u32 name_len = vec_len (stream_name);
16469   /* Construct the API message */
16470   M (PG_ENABLE_DISABLE, pg_enable_disable);
16471   mp->context = 0;
16472   mp->is_enabled = enable;
16473   if (stream_name_set != 0)
16474     {
16475       mp->stream_name_length = ntohl (name_len);
16476       clib_memcpy (mp->stream_name, stream_name, name_len);
16477     }
16478   vec_free (stream_name);
16479
16480   S;
16481   W;
16482   /* NOTREACHED */
16483   return 0;
16484 }
16485
16486 int
16487 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16488 {
16489   unformat_input_t *input = vam->input;
16490   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16491   f64 timeout;
16492
16493   u16 *low_ports = 0;
16494   u16 *high_ports = 0;
16495   u16 this_low;
16496   u16 this_hi;
16497   ip4_address_t ip4_addr;
16498   ip6_address_t ip6_addr;
16499   u32 length;
16500   u32 tmp, tmp2;
16501   u8 prefix_set = 0;
16502   u32 vrf_id = ~0;
16503   u8 is_add = 1;
16504   u8 is_ipv6 = 0;
16505
16506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16507     {
16508       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16509         {
16510           prefix_set = 1;
16511         }
16512       else
16513         if (unformat
16514             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16515         {
16516           prefix_set = 1;
16517           is_ipv6 = 1;
16518         }
16519       else if (unformat (input, "vrf %d", &vrf_id))
16520         ;
16521       else if (unformat (input, "del"))
16522         is_add = 0;
16523       else if (unformat (input, "port %d", &tmp))
16524         {
16525           if (tmp == 0 || tmp > 65535)
16526             {
16527               errmsg ("port %d out of range", tmp);
16528               return -99;
16529             }
16530           this_low = tmp;
16531           this_hi = this_low + 1;
16532           vec_add1 (low_ports, this_low);
16533           vec_add1 (high_ports, this_hi);
16534         }
16535       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16536         {
16537           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16538             {
16539               errmsg ("incorrect range parameters");
16540               return -99;
16541             }
16542           this_low = tmp;
16543           /* Note: in debug CLI +1 is added to high before
16544              passing to real fn that does "the work"
16545              (ip_source_and_port_range_check_add_del).
16546              This fn is a wrapper around the binary API fn a
16547              control plane will call, which expects this increment
16548              to have occurred. Hence letting the binary API control
16549              plane fn do the increment for consistency between VAT
16550              and other control planes.
16551            */
16552           this_hi = tmp2;
16553           vec_add1 (low_ports, this_low);
16554           vec_add1 (high_ports, this_hi);
16555         }
16556       else
16557         break;
16558     }
16559
16560   if (prefix_set == 0)
16561     {
16562       errmsg ("<address>/<mask> not specified");
16563       return -99;
16564     }
16565
16566   if (vrf_id == ~0)
16567     {
16568       errmsg ("VRF ID required, not specified");
16569       return -99;
16570     }
16571
16572   if (vrf_id == 0)
16573     {
16574       errmsg
16575         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16576       return -99;
16577     }
16578
16579   if (vec_len (low_ports) == 0)
16580     {
16581       errmsg ("At least one port or port range required");
16582       return -99;
16583     }
16584
16585   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16586      ip_source_and_port_range_check_add_del);
16587
16588   mp->is_add = is_add;
16589
16590   if (is_ipv6)
16591     {
16592       mp->is_ipv6 = 1;
16593       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16594     }
16595   else
16596     {
16597       mp->is_ipv6 = 0;
16598       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16599     }
16600
16601   mp->mask_length = length;
16602   mp->number_of_ranges = vec_len (low_ports);
16603
16604   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16605   vec_free (low_ports);
16606
16607   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16608   vec_free (high_ports);
16609
16610   mp->vrf_id = ntohl (vrf_id);
16611
16612   S;
16613   W;
16614   /* NOTREACHED */
16615   return 0;
16616 }
16617
16618 int
16619 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16620 {
16621   unformat_input_t *input = vam->input;
16622   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16623   f64 timeout;
16624   u32 sw_if_index = ~0;
16625   int vrf_set = 0;
16626   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16627   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16628   u8 is_add = 1;
16629
16630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16631     {
16632       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16633         ;
16634       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16635         ;
16636       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16637         vrf_set = 1;
16638       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16639         vrf_set = 1;
16640       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16641         vrf_set = 1;
16642       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16643         vrf_set = 1;
16644       else if (unformat (input, "del"))
16645         is_add = 0;
16646       else
16647         break;
16648     }
16649
16650   if (sw_if_index == ~0)
16651     {
16652       errmsg ("Interface required but not specified");
16653       return -99;
16654     }
16655
16656   if (vrf_set == 0)
16657     {
16658       errmsg ("VRF ID required but not specified");
16659       return -99;
16660     }
16661
16662   if (tcp_out_vrf_id == 0
16663       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16664     {
16665       errmsg
16666         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16667       return -99;
16668     }
16669
16670   /* Construct the API message */
16671   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16672      ip_source_and_port_range_check_interface_add_del);
16673
16674   mp->sw_if_index = ntohl (sw_if_index);
16675   mp->is_add = is_add;
16676   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16677   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16678   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16679   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16680
16681   /* send it... */
16682   S;
16683
16684   /* Wait for a reply... */
16685   W;
16686 }
16687
16688 static int
16689 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16690 {
16691   unformat_input_t *i = vam->input;
16692   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16693   f64 timeout;
16694   u32 local_sa_id = 0;
16695   u32 remote_sa_id = 0;
16696   ip4_address_t src_address;
16697   ip4_address_t dst_address;
16698   u8 is_add = 1;
16699
16700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16701     {
16702       if (unformat (i, "local_sa %d", &local_sa_id))
16703         ;
16704       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16705         ;
16706       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16707         ;
16708       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16709         ;
16710       else if (unformat (i, "del"))
16711         is_add = 0;
16712       else
16713         {
16714           clib_warning ("parse error '%U'", format_unformat_error, i);
16715           return -99;
16716         }
16717     }
16718
16719   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16720
16721   mp->local_sa_id = ntohl (local_sa_id);
16722   mp->remote_sa_id = ntohl (remote_sa_id);
16723   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16724   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16725   mp->is_add = is_add;
16726
16727   S;
16728   W;
16729   /* NOTREACHED */
16730   return 0;
16731 }
16732
16733 static int
16734 api_punt (vat_main_t * vam)
16735 {
16736   unformat_input_t *i = vam->input;
16737   vl_api_punt_t *mp;
16738   f64 timeout;
16739   u32 ipv = ~0;
16740   u32 protocol = ~0;
16741   u32 port = ~0;
16742   int is_add = 1;
16743
16744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16745     {
16746       if (unformat (i, "ip %d", &ipv))
16747         ;
16748       else if (unformat (i, "protocol %d", &protocol))
16749         ;
16750       else if (unformat (i, "port %d", &port))
16751         ;
16752       else if (unformat (i, "del"))
16753         is_add = 0;
16754       else
16755         {
16756           clib_warning ("parse error '%U'", format_unformat_error, i);
16757           return -99;
16758         }
16759     }
16760
16761   M (PUNT, punt);
16762
16763   mp->is_add = (u8) is_add;
16764   mp->ipv = (u8) ipv;
16765   mp->l4_protocol = (u8) protocol;
16766   mp->l4_port = htons ((u16) port);
16767
16768   S;
16769   W;
16770   /* NOTREACHED */
16771   return 0;
16772 }
16773
16774 static void vl_api_ipsec_gre_tunnel_details_t_handler
16775   (vl_api_ipsec_gre_tunnel_details_t * mp)
16776 {
16777   vat_main_t *vam = &vat_main;
16778
16779   print (vam->ofp, "%11d%15U%15U%14d%14d",
16780          ntohl (mp->sw_if_index),
16781          format_ip4_address, &mp->src_address,
16782          format_ip4_address, &mp->dst_address,
16783          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16784 }
16785
16786 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16787   (vl_api_ipsec_gre_tunnel_details_t * mp)
16788 {
16789   vat_main_t *vam = &vat_main;
16790   vat_json_node_t *node = NULL;
16791   struct in_addr ip4;
16792
16793   if (VAT_JSON_ARRAY != vam->json_tree.type)
16794     {
16795       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16796       vat_json_init_array (&vam->json_tree);
16797     }
16798   node = vat_json_array_add (&vam->json_tree);
16799
16800   vat_json_init_object (node);
16801   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16802   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16803   vat_json_object_add_ip4 (node, "src_address", ip4);
16804   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16805   vat_json_object_add_ip4 (node, "dst_address", ip4);
16806   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16807   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16808 }
16809
16810 static int
16811 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16812 {
16813   unformat_input_t *i = vam->input;
16814   vl_api_ipsec_gre_tunnel_dump_t *mp;
16815   f64 timeout;
16816   u32 sw_if_index;
16817   u8 sw_if_index_set = 0;
16818
16819   /* Parse args required to build the message */
16820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16821     {
16822       if (unformat (i, "sw_if_index %d", &sw_if_index))
16823         sw_if_index_set = 1;
16824       else
16825         break;
16826     }
16827
16828   if (sw_if_index_set == 0)
16829     {
16830       sw_if_index = ~0;
16831     }
16832
16833   if (!vam->json_output)
16834     {
16835       print (vam->ofp, "%11s%15s%15s%14s%14s",
16836              "sw_if_index", "src_address", "dst_address",
16837              "local_sa_id", "remote_sa_id");
16838     }
16839
16840   /* Get list of gre-tunnel interfaces */
16841   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16842
16843   mp->sw_if_index = htonl (sw_if_index);
16844
16845   S;
16846
16847   /* Use a control ping for synchronization */
16848   {
16849     vl_api_control_ping_t *mp;
16850     M (CONTROL_PING, control_ping);
16851     S;
16852   }
16853   W;
16854 }
16855
16856 static int
16857 api_delete_subif (vat_main_t * vam)
16858 {
16859   unformat_input_t *i = vam->input;
16860   vl_api_delete_subif_t *mp;
16861   f64 timeout;
16862   u32 sw_if_index = ~0;
16863
16864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16865     {
16866       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16867         ;
16868       if (unformat (i, "sw_if_index %d", &sw_if_index))
16869         ;
16870       else
16871         break;
16872     }
16873
16874   if (sw_if_index == ~0)
16875     {
16876       errmsg ("missing sw_if_index");
16877       return -99;
16878     }
16879
16880   /* Construct the API message */
16881   M (DELETE_SUBIF, delete_subif);
16882   mp->sw_if_index = ntohl (sw_if_index);
16883
16884   S;
16885   W;
16886 }
16887
16888 #define foreach_pbb_vtr_op      \
16889 _("disable",  L2_VTR_DISABLED)  \
16890 _("pop",  L2_VTR_POP_2)         \
16891 _("push",  L2_VTR_PUSH_2)
16892
16893 static int
16894 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16895 {
16896   unformat_input_t *i = vam->input;
16897   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16898   f64 timeout;
16899   u32 sw_if_index = ~0, vtr_op = ~0;
16900   u16 outer_tag = ~0;
16901   u8 dmac[6], smac[6];
16902   u8 dmac_set = 0, smac_set = 0;
16903   u16 vlanid = 0;
16904   u32 sid = ~0;
16905   u32 tmp;
16906
16907   /* Shut up coverity */
16908   memset (dmac, 0, sizeof (dmac));
16909   memset (smac, 0, sizeof (smac));
16910
16911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16912     {
16913       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16914         ;
16915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16916         ;
16917       else if (unformat (i, "vtr_op %d", &vtr_op))
16918         ;
16919 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16920       foreach_pbb_vtr_op
16921 #undef _
16922         else if (unformat (i, "translate_pbb_stag"))
16923         {
16924           if (unformat (i, "%d", &tmp))
16925             {
16926               vtr_op = L2_VTR_TRANSLATE_2_1;
16927               outer_tag = tmp;
16928             }
16929           else
16930             {
16931               errmsg
16932                 ("translate_pbb_stag operation requires outer tag definition");
16933               return -99;
16934             }
16935         }
16936       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16937         dmac_set++;
16938       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16939         smac_set++;
16940       else if (unformat (i, "sid %d", &sid))
16941         ;
16942       else if (unformat (i, "vlanid %d", &tmp))
16943         vlanid = tmp;
16944       else
16945         {
16946           clib_warning ("parse error '%U'", format_unformat_error, i);
16947           return -99;
16948         }
16949     }
16950
16951   if ((sw_if_index == ~0) || (vtr_op == ~0))
16952     {
16953       errmsg ("missing sw_if_index or vtr operation");
16954       return -99;
16955     }
16956   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16957       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16958     {
16959       errmsg
16960         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16961       return -99;
16962     }
16963
16964   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16965   mp->sw_if_index = ntohl (sw_if_index);
16966   mp->vtr_op = ntohl (vtr_op);
16967   mp->outer_tag = ntohs (outer_tag);
16968   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16969   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16970   mp->b_vlanid = ntohs (vlanid);
16971   mp->i_sid = ntohl (sid);
16972
16973   S;
16974   W;
16975   /* NOTREACHED */
16976   return 0;
16977 }
16978
16979 static int
16980 api_flow_classify_set_interface (vat_main_t * vam)
16981 {
16982   unformat_input_t *i = vam->input;
16983   vl_api_flow_classify_set_interface_t *mp;
16984   f64 timeout;
16985   u32 sw_if_index;
16986   int sw_if_index_set;
16987   u32 ip4_table_index = ~0;
16988   u32 ip6_table_index = ~0;
16989   u8 is_add = 1;
16990
16991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16992     {
16993       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16994         sw_if_index_set = 1;
16995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16996         sw_if_index_set = 1;
16997       else if (unformat (i, "del"))
16998         is_add = 0;
16999       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17000         ;
17001       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17002         ;
17003       else
17004         {
17005           clib_warning ("parse error '%U'", format_unformat_error, i);
17006           return -99;
17007         }
17008     }
17009
17010   if (sw_if_index_set == 0)
17011     {
17012       errmsg ("missing interface name or sw_if_index");
17013       return -99;
17014     }
17015
17016   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
17017
17018   mp->sw_if_index = ntohl (sw_if_index);
17019   mp->ip4_table_index = ntohl (ip4_table_index);
17020   mp->ip6_table_index = ntohl (ip6_table_index);
17021   mp->is_add = is_add;
17022
17023   S;
17024   W;
17025   /* NOTREACHED */
17026   return 0;
17027 }
17028
17029 static int
17030 api_flow_classify_dump (vat_main_t * vam)
17031 {
17032   unformat_input_t *i = vam->input;
17033   vl_api_flow_classify_dump_t *mp;
17034   f64 timeout = ~0;
17035   u8 type = FLOW_CLASSIFY_N_TABLES;
17036
17037   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17038     ;
17039   else
17040     {
17041       errmsg ("classify table type must be specified");
17042       return -99;
17043     }
17044
17045   if (!vam->json_output)
17046     {
17047       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17048     }
17049
17050   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
17051   mp->type = type;
17052   /* send it... */
17053   S;
17054
17055   /* Use a control ping for synchronization */
17056   {
17057     vl_api_control_ping_t *mp;
17058     M (CONTROL_PING, control_ping);
17059     S;
17060   }
17061   /* Wait for a reply... */
17062   W;
17063
17064   /* NOTREACHED */
17065   return 0;
17066 }
17067
17068 static int
17069 api_feature_enable_disable (vat_main_t * vam)
17070 {
17071   unformat_input_t *i = vam->input;
17072   vl_api_feature_enable_disable_t *mp;
17073   f64 timeout;
17074   u8 *arc_name = 0;
17075   u8 *feature_name = 0;
17076   u32 sw_if_index = ~0;
17077   u8 enable = 1;
17078
17079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17080     {
17081       if (unformat (i, "arc_name %s", &arc_name))
17082         ;
17083       else if (unformat (i, "feature_name %s", &feature_name))
17084         ;
17085       else
17086         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17087         ;
17088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17089         ;
17090       else if (unformat (i, "disable"))
17091         enable = 0;
17092       else
17093         break;
17094     }
17095
17096   if (arc_name == 0)
17097     {
17098       errmsg ("missing arc name");
17099       return -99;
17100     }
17101   if (vec_len (arc_name) > 63)
17102     {
17103       errmsg ("arc name too long");
17104     }
17105
17106   if (feature_name == 0)
17107     {
17108       errmsg ("missing feature name");
17109       return -99;
17110     }
17111   if (vec_len (feature_name) > 63)
17112     {
17113       errmsg ("feature name too long");
17114     }
17115
17116   if (sw_if_index == ~0)
17117     {
17118       errmsg ("missing interface name or sw_if_index");
17119       return -99;
17120     }
17121
17122   /* Construct the API message */
17123   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
17124   mp->sw_if_index = ntohl (sw_if_index);
17125   mp->enable = enable;
17126   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17127   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17128   vec_free (arc_name);
17129   vec_free (feature_name);
17130
17131   S;
17132   W;
17133 }
17134
17135 static int
17136 api_sw_interface_tag_add_del (vat_main_t * vam)
17137 {
17138   unformat_input_t *i = vam->input;
17139   vl_api_sw_interface_tag_add_del_t *mp;
17140   f64 timeout;
17141   u32 sw_if_index = ~0;
17142   u8 *tag = 0;
17143   u8 enable = 1;
17144
17145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17146     {
17147       if (unformat (i, "tag %s", &tag))
17148         ;
17149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17150         ;
17151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17152         ;
17153       else if (unformat (i, "del"))
17154         enable = 0;
17155       else
17156         break;
17157     }
17158
17159   if (sw_if_index == ~0)
17160     {
17161       errmsg ("missing interface name or sw_if_index");
17162       return -99;
17163     }
17164
17165   if (enable && (tag == 0))
17166     {
17167       errmsg ("no tag specified");
17168       return -99;
17169     }
17170
17171   /* Construct the API message */
17172   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
17173   mp->sw_if_index = ntohl (sw_if_index);
17174   mp->is_add = enable;
17175   if (enable)
17176     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17177   vec_free (tag);
17178
17179   S;
17180   W;
17181 }
17182
17183 static void vl_api_l2_xconnect_details_t_handler
17184   (vl_api_l2_xconnect_details_t * mp)
17185 {
17186   vat_main_t *vam = &vat_main;
17187
17188   print (vam->ofp, "%15d%15d",
17189          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17190 }
17191
17192 static void vl_api_l2_xconnect_details_t_handler_json
17193   (vl_api_l2_xconnect_details_t * mp)
17194 {
17195   vat_main_t *vam = &vat_main;
17196   vat_json_node_t *node = NULL;
17197
17198   if (VAT_JSON_ARRAY != vam->json_tree.type)
17199     {
17200       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17201       vat_json_init_array (&vam->json_tree);
17202     }
17203   node = vat_json_array_add (&vam->json_tree);
17204
17205   vat_json_init_object (node);
17206   vat_json_object_add_uint (node, "rx_sw_if_index",
17207                             ntohl (mp->rx_sw_if_index));
17208   vat_json_object_add_uint (node, "tx_sw_if_index",
17209                             ntohl (mp->tx_sw_if_index));
17210 }
17211
17212 static int
17213 api_l2_xconnect_dump (vat_main_t * vam)
17214 {
17215   vl_api_l2_xconnect_dump_t *mp;
17216   f64 timeout;
17217
17218   if (!vam->json_output)
17219     {
17220       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17221     }
17222
17223   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
17224
17225   S;
17226
17227   /* Use a control ping for synchronization */
17228   {
17229     vl_api_control_ping_t *mp;
17230     M (CONTROL_PING, control_ping);
17231     S;
17232   }
17233   W;
17234 }
17235
17236 static int
17237 api_sw_interface_set_mtu (vat_main_t * vam)
17238 {
17239   unformat_input_t *i = vam->input;
17240   vl_api_sw_interface_set_mtu_t *mp;
17241   f64 timeout;
17242   u32 sw_if_index = ~0;
17243   u32 mtu = 0;
17244
17245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17246     {
17247       if (unformat (i, "mtu %d", &mtu))
17248         ;
17249       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17250         ;
17251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17252         ;
17253       else
17254         break;
17255     }
17256
17257   if (sw_if_index == ~0)
17258     {
17259       errmsg ("missing interface name or sw_if_index");
17260       return -99;
17261     }
17262
17263   if (mtu == 0)
17264     {
17265       errmsg ("no mtu specified");
17266       return -99;
17267     }
17268
17269   /* Construct the API message */
17270   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17271   mp->sw_if_index = ntohl (sw_if_index);
17272   mp->mtu = ntohs ((u16) mtu);
17273
17274   S;
17275   W;
17276 }
17277
17278
17279 static int
17280 q_or_quit (vat_main_t * vam)
17281 {
17282   longjmp (vam->jump_buf, 1);
17283   return 0;                     /* not so much */
17284 }
17285
17286 static int
17287 q (vat_main_t * vam)
17288 {
17289   return q_or_quit (vam);
17290 }
17291
17292 static int
17293 quit (vat_main_t * vam)
17294 {
17295   return q_or_quit (vam);
17296 }
17297
17298 static int
17299 comment (vat_main_t * vam)
17300 {
17301   return 0;
17302 }
17303
17304 static int
17305 cmd_cmp (void *a1, void *a2)
17306 {
17307   u8 **c1 = a1;
17308   u8 **c2 = a2;
17309
17310   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17311 }
17312
17313 static int
17314 help (vat_main_t * vam)
17315 {
17316   u8 **cmds = 0;
17317   u8 *name = 0;
17318   hash_pair_t *p;
17319   unformat_input_t *i = vam->input;
17320   int j;
17321
17322   if (unformat (i, "%s", &name))
17323     {
17324       uword *hs;
17325
17326       vec_add1 (name, 0);
17327
17328       hs = hash_get_mem (vam->help_by_name, name);
17329       if (hs)
17330         print (vam->ofp, "usage: %s %s", name, hs[0]);
17331       else
17332         print (vam->ofp, "No such msg / command '%s'", name);
17333       vec_free (name);
17334       return 0;
17335     }
17336
17337   print (vam->ofp, "Help is available for the following:");
17338
17339     /* *INDENT-OFF* */
17340     hash_foreach_pair (p, vam->function_by_name,
17341     ({
17342       vec_add1 (cmds, (u8 *)(p->key));
17343     }));
17344     /* *INDENT-ON* */
17345
17346   vec_sort_with_function (cmds, cmd_cmp);
17347
17348   for (j = 0; j < vec_len (cmds); j++)
17349     print (vam->ofp, "%s", cmds[j]);
17350
17351   vec_free (cmds);
17352   return 0;
17353 }
17354
17355 static int
17356 set (vat_main_t * vam)
17357 {
17358   u8 *name = 0, *value = 0;
17359   unformat_input_t *i = vam->input;
17360
17361   if (unformat (i, "%s", &name))
17362     {
17363       /* The input buffer is a vector, not a string. */
17364       value = vec_dup (i->buffer);
17365       vec_delete (value, i->index, 0);
17366       /* Almost certainly has a trailing newline */
17367       if (value[vec_len (value) - 1] == '\n')
17368         value[vec_len (value) - 1] = 0;
17369       /* Make sure it's a proper string, one way or the other */
17370       vec_add1 (value, 0);
17371       (void) clib_macro_set_value (&vam->macro_main,
17372                                    (char *) name, (char *) value);
17373     }
17374   else
17375     errmsg ("usage: set <name> <value>");
17376
17377   vec_free (name);
17378   vec_free (value);
17379   return 0;
17380 }
17381
17382 static int
17383 unset (vat_main_t * vam)
17384 {
17385   u8 *name = 0;
17386
17387   if (unformat (vam->input, "%s", &name))
17388     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17389       errmsg ("unset: %s wasn't set", name);
17390   vec_free (name);
17391   return 0;
17392 }
17393
17394 typedef struct
17395 {
17396   u8 *name;
17397   u8 *value;
17398 } macro_sort_t;
17399
17400
17401 static int
17402 macro_sort_cmp (void *a1, void *a2)
17403 {
17404   macro_sort_t *s1 = a1;
17405   macro_sort_t *s2 = a2;
17406
17407   return strcmp ((char *) (s1->name), (char *) (s2->name));
17408 }
17409
17410 static int
17411 dump_macro_table (vat_main_t * vam)
17412 {
17413   macro_sort_t *sort_me = 0, *sm;
17414   int i;
17415   hash_pair_t *p;
17416
17417     /* *INDENT-OFF* */
17418     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17419     ({
17420       vec_add2 (sort_me, sm, 1);
17421       sm->name = (u8 *)(p->key);
17422       sm->value = (u8 *) (p->value[0]);
17423     }));
17424     /* *INDENT-ON* */
17425
17426   vec_sort_with_function (sort_me, macro_sort_cmp);
17427
17428   if (vec_len (sort_me))
17429     print (vam->ofp, "%-15s%s", "Name", "Value");
17430   else
17431     print (vam->ofp, "The macro table is empty...");
17432
17433   for (i = 0; i < vec_len (sort_me); i++)
17434     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17435   return 0;
17436 }
17437
17438 static int
17439 dump_node_table (vat_main_t * vam)
17440 {
17441   int i, j;
17442   vlib_node_t *node, *next_node;
17443
17444   if (vec_len (vam->graph_nodes) == 0)
17445     {
17446       print (vam->ofp, "Node table empty, issue get_node_graph...");
17447       return 0;
17448     }
17449
17450   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17451     {
17452       node = vam->graph_nodes[i];
17453       print (vam->ofp, "[%d] %s", i, node->name);
17454       for (j = 0; j < vec_len (node->next_nodes); j++)
17455         {
17456           if (node->next_nodes[j] != ~0)
17457             {
17458               next_node = vam->graph_nodes[node->next_nodes[j]];
17459               print (vam->ofp, "  [%d] %s", j, next_node->name);
17460             }
17461         }
17462     }
17463   return 0;
17464 }
17465
17466 static int
17467 value_sort_cmp (void *a1, void *a2)
17468 {
17469   name_sort_t *n1 = a1;
17470   name_sort_t *n2 = a2;
17471
17472   if (n1->value < n2->value)
17473     return -1;
17474   if (n1->value > n2->value)
17475     return 1;
17476   return 0;
17477 }
17478
17479
17480 static int
17481 dump_msg_api_table (vat_main_t * vam)
17482 {
17483   api_main_t *am = &api_main;
17484   name_sort_t *nses = 0, *ns;
17485   hash_pair_t *hp;
17486   int i;
17487
17488   /* *INDENT-OFF* */
17489   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17490   ({
17491     vec_add2 (nses, ns, 1);
17492     ns->name = (u8 *)(hp->key);
17493     ns->value = (u32) hp->value[0];
17494   }));
17495   /* *INDENT-ON* */
17496
17497   vec_sort_with_function (nses, value_sort_cmp);
17498
17499   for (i = 0; i < vec_len (nses); i++)
17500     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17501   vec_free (nses);
17502   return 0;
17503 }
17504
17505 static int
17506 get_msg_id (vat_main_t * vam)
17507 {
17508   u8 *name_and_crc;
17509   u32 message_index;
17510
17511   if (unformat (vam->input, "%s", &name_and_crc))
17512     {
17513       message_index = vl_api_get_msg_index (name_and_crc);
17514       if (message_index == ~0)
17515         {
17516           print (vam->ofp, " '%s' not found", name_and_crc);
17517           return 0;
17518         }
17519       print (vam->ofp, " '%s' has message index %d",
17520              name_and_crc, message_index);
17521       return 0;
17522     }
17523   errmsg ("name_and_crc required...");
17524   return 0;
17525 }
17526
17527 static int
17528 search_node_table (vat_main_t * vam)
17529 {
17530   unformat_input_t *line_input = vam->input;
17531   u8 *node_to_find;
17532   int j;
17533   vlib_node_t *node, *next_node;
17534   uword *p;
17535
17536   if (vam->graph_node_index_by_name == 0)
17537     {
17538       print (vam->ofp, "Node table empty, issue get_node_graph...");
17539       return 0;
17540     }
17541
17542   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17543     {
17544       if (unformat (line_input, "%s", &node_to_find))
17545         {
17546           vec_add1 (node_to_find, 0);
17547           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17548           if (p == 0)
17549             {
17550               print (vam->ofp, "%s not found...", node_to_find);
17551               goto out;
17552             }
17553           node = vam->graph_nodes[p[0]];
17554           print (vam->ofp, "[%d] %s", p[0], node->name);
17555           for (j = 0; j < vec_len (node->next_nodes); j++)
17556             {
17557               if (node->next_nodes[j] != ~0)
17558                 {
17559                   next_node = vam->graph_nodes[node->next_nodes[j]];
17560                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17561                 }
17562             }
17563         }
17564
17565       else
17566         {
17567           clib_warning ("parse error '%U'", format_unformat_error,
17568                         line_input);
17569           return -99;
17570         }
17571
17572     out:
17573       vec_free (node_to_find);
17574
17575     }
17576
17577   return 0;
17578 }
17579
17580
17581 static int
17582 script (vat_main_t * vam)
17583 {
17584 #if (VPP_API_TEST_BUILTIN==0)
17585   u8 *s = 0;
17586   char *save_current_file;
17587   unformat_input_t save_input;
17588   jmp_buf save_jump_buf;
17589   u32 save_line_number;
17590
17591   FILE *new_fp, *save_ifp;
17592
17593   if (unformat (vam->input, "%s", &s))
17594     {
17595       new_fp = fopen ((char *) s, "r");
17596       if (new_fp == 0)
17597         {
17598           errmsg ("Couldn't open script file %s", s);
17599           vec_free (s);
17600           return -99;
17601         }
17602     }
17603   else
17604     {
17605       errmsg ("Missing script name");
17606       return -99;
17607     }
17608
17609   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17610   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17611   save_ifp = vam->ifp;
17612   save_line_number = vam->input_line_number;
17613   save_current_file = (char *) vam->current_file;
17614
17615   vam->input_line_number = 0;
17616   vam->ifp = new_fp;
17617   vam->current_file = s;
17618   do_one_file (vam);
17619
17620   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17621   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17622   vam->ifp = save_ifp;
17623   vam->input_line_number = save_line_number;
17624   vam->current_file = (u8 *) save_current_file;
17625   vec_free (s);
17626
17627   return 0;
17628 #else
17629   clib_warning ("use the exec command...");
17630   return -99;
17631 #endif
17632 }
17633
17634 static int
17635 echo (vat_main_t * vam)
17636 {
17637   print (vam->ofp, "%v", vam->input->buffer);
17638   return 0;
17639 }
17640
17641 /* List of API message constructors, CLI names map to api_xxx */
17642 #define foreach_vpe_api_msg                                             \
17643 _(create_loopback,"[mac <mac-addr>]")                                   \
17644 _(sw_interface_dump,"")                                                 \
17645 _(sw_interface_set_flags,                                               \
17646   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17647 _(sw_interface_add_del_address,                                         \
17648   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17649 _(sw_interface_set_table,                                               \
17650   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17651 _(sw_interface_set_mpls_enable,                                         \
17652   "<intfc> | sw_if_index [disable | dis]")                              \
17653 _(sw_interface_set_vpath,                                               \
17654   "<intfc> | sw_if_index <id> enable | disable")                        \
17655 _(sw_interface_set_vxlan_bypass,                                        \
17656   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17657 _(sw_interface_set_l2_xconnect,                                         \
17658   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17659   "enable | disable")                                                   \
17660 _(sw_interface_set_l2_bridge,                                           \
17661   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17662   "[shg <split-horizon-group>] [bvi]\n"                                 \
17663   "enable | disable")                                                   \
17664 _(bridge_domain_add_del,                                                \
17665   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17666 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17667 _(l2fib_add_del,                                                        \
17668   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17669 _(l2_flags,                                                             \
17670   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17671 _(bridge_flags,                                                         \
17672   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17673 _(tap_connect,                                                          \
17674   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17675 _(tap_modify,                                                           \
17676   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17677 _(tap_delete,                                                           \
17678   "<vpp-if-name> | sw_if_index <id>")                                   \
17679 _(sw_interface_tap_dump, "")                                            \
17680 _(ip_add_del_route,                                                     \
17681   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17682   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17683   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17684   "[multipath] [count <n>]")                                            \
17685 _(ip_mroute_add_del,                                                    \
17686   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
17687   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
17688 _(mpls_route_add_del,                                                   \
17689   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17690   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17691   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17692   "[multipath] [count <n>]")                                            \
17693 _(mpls_ip_bind_unbind,                                                  \
17694   "<label> <addr/len>")                                                 \
17695 _(mpls_tunnel_add_del,                                                  \
17696   " via <addr> [table-id <n>]\n"                                        \
17697   "sw_if_index <id>] [l2]  [del]")                                      \
17698 _(proxy_arp_add_del,                                                    \
17699   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17700 _(proxy_arp_intfc_enable_disable,                                       \
17701   "<intfc> | sw_if_index <id> enable | disable")                        \
17702 _(sw_interface_set_unnumbered,                                          \
17703   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17704 _(ip_neighbor_add_del,                                                  \
17705   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17706   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17707 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17708 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17709 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17710   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17711   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17712   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17713 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17714 _(reset_fib, "vrf <n> [ipv6]")                                          \
17715 _(dhcp_proxy_config,                                                    \
17716   "svr <v46-address> src <v46-address>\n"                               \
17717    "insert-cid <n> [del]")                                              \
17718 _(dhcp_proxy_config_2,                                                  \
17719   "svr <v46-address> src <v46-address>\n"                               \
17720    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17721 _(dhcp_proxy_set_vss,                                                   \
17722   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17723 _(dhcp_client_config,                                                   \
17724   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17725 _(set_ip_flow_hash,                                                     \
17726   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17727 _(sw_interface_ip6_enable_disable,                                      \
17728   "<intfc> | sw_if_index <id> enable | disable")                        \
17729 _(sw_interface_ip6_set_link_local_address,                              \
17730   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17731 _(sw_interface_ip6nd_ra_prefix,                                         \
17732   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17733   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17734   "[nolink] [isno]")                                                    \
17735 _(sw_interface_ip6nd_ra_config,                                         \
17736   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17737   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17738   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17739 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17740 _(l2_patch_add_del,                                                     \
17741   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17742   "enable | disable")                                                   \
17743 _(sr_tunnel_add_del,                                                    \
17744   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17745   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17746   "[policy <policy_name>]")                                             \
17747 _(sr_policy_add_del,                                                    \
17748   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17749 _(sr_multicast_map_add_del,                                             \
17750   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17751 _(classify_add_del_table,                                               \
17752   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17753   " [del] [del-chain] mask <mask-value>\n"                              \
17754   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17755   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17756 _(classify_add_del_session,                                             \
17757   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17758   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17759   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17760   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17761 _(classify_set_interface_ip_table,                                      \
17762   "<intfc> | sw_if_index <nn> table <nn>")                              \
17763 _(classify_set_interface_l2_tables,                                     \
17764   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17765   "  [other-table <nn>]")                                               \
17766 _(get_node_index, "node <node-name")                                    \
17767 _(add_node_next, "node <node-name> next <next-node-name>")              \
17768 _(l2tpv3_create_tunnel,                                                 \
17769   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17770   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17771   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17772 _(l2tpv3_set_tunnel_cookies,                                            \
17773   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17774   "[new_remote_cookie <nn>]\n")                                         \
17775 _(l2tpv3_interface_enable_disable,                                      \
17776   "<intfc> | sw_if_index <nn> enable | disable")                        \
17777 _(l2tpv3_set_lookup_key,                                                \
17778   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17779 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17780 _(vxlan_add_del_tunnel,                                                 \
17781   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17782   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17783   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17784 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17785 _(gre_add_del_tunnel,                                                   \
17786   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17787 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17788 _(l2_fib_clear_table, "")                                               \
17789 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17790 _(l2_interface_vlan_tag_rewrite,                                        \
17791   "<intfc> | sw_if_index <nn> \n"                                       \
17792   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17793   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17794 _(create_vhost_user_if,                                                 \
17795         "socket <filename> [server] [renumber <dev_instance>] "         \
17796         "[mac <mac_address>]")                                          \
17797 _(modify_vhost_user_if,                                                 \
17798         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17799         "[server] [renumber <dev_instance>]")                           \
17800 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17801 _(sw_interface_vhost_user_dump, "")                                     \
17802 _(show_version, "")                                                     \
17803 _(vxlan_gpe_add_del_tunnel,                                             \
17804   "local <addr> remote <addr> vni <nn>\n"                               \
17805     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17806   "[next-ethernet] [next-nsh]\n")                                       \
17807 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17808 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17809 _(interface_name_renumber,                                              \
17810   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17811 _(input_acl_set_interface,                                              \
17812   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17813   "  [l2-table <nn>] [del]")                                            \
17814 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17815 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17816 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17817 _(ip_dump, "ipv4 | ipv6")                                               \
17818 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17819 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17820   "  spid_id <n> ")                                                     \
17821 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17822   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17823   "  integ_alg <alg> integ_key <hex>")                                  \
17824 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17825   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17826   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17827   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17828 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17829 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17830 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17831   "(auth_data 0x<data> | auth_data <data>)")                            \
17832 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17833   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17834 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17835   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17836   "(local|remote)")                                                     \
17837 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17838 _(delete_loopback,"sw_if_index <nn>")                                   \
17839 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17840 _(map_add_domain,                                                       \
17841   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17842   "ip6-src <ip6addr> "                                                  \
17843   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17844 _(map_del_domain, "index <n>")                                          \
17845 _(map_add_del_rule,                                                     \
17846   "index <n> psid <n> dst <ip6addr> [del]")                             \
17847 _(map_domain_dump, "")                                                  \
17848 _(map_rule_dump, "index <map-domain>")                                  \
17849 _(want_interface_events,  "enable|disable")                             \
17850 _(want_stats,"enable|disable")                                          \
17851 _(get_first_msg_id, "client <name>")                                    \
17852 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17853 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17854   "fib-id <nn> [ip4][ip6][default]")                                    \
17855 _(get_node_graph, " ")                                                  \
17856 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17857 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17858 _(ioam_disable, "")                                                     \
17859 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17860                             " sw_if_index <sw_if_index> p <priority> "  \
17861                             "w <weight>] [del]")                        \
17862 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17863                         "iface <intf> | sw_if_index <sw_if_index> "     \
17864                         "p <priority> w <weight> [del]")                \
17865 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17866                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17867                          "locator-set <locator_name> [del]"             \
17868                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17869 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
17870   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
17871 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17872 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17873 _(lisp_gpe_enable_disable, "enable|disable")                            \
17874 _(lisp_enable_disable, "enable|disable")                                \
17875 _(lisp_map_register_enable_disable, "enable|disable")                   \
17876 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17877 _(lisp_gpe_add_del_iface, "up|down")                                    \
17878 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17879                                "[seid <seid>] "                         \
17880                                "rloc <locator> p <prio> "               \
17881                                "w <weight> [rloc <loc> ... ] "          \
17882                                "action <action> [del-all]")             \
17883 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17884                           "<local-eid>")                                \
17885 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17886 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17887 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17888 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17889 _(lisp_locator_set_dump, "[local | remote]")                            \
17890 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17891 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17892                        "[local] | [remote]")                            \
17893 _(lisp_eid_table_vni_dump, "")                                          \
17894 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17895 _(lisp_map_resolver_dump, "")                                           \
17896 _(lisp_map_server_dump, "")                                             \
17897 _(lisp_adjacencies_get, "vni <vni>")                                    \
17898 _(show_lisp_rloc_probe_state, "")                                       \
17899 _(show_lisp_map_register_state, "")                                     \
17900 _(show_lisp_status, "")                                                 \
17901 _(lisp_get_map_request_itr_rlocs, "")                                   \
17902 _(show_lisp_pitr, "")                                                   \
17903 _(show_lisp_map_request_mode, "")                                       \
17904 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17905 _(af_packet_delete, "name <host interface name>")                       \
17906 _(policer_add_del, "name <policer name> <params> [del]")                \
17907 _(policer_dump, "[name <policer name>]")                                \
17908 _(policer_classify_set_interface,                                       \
17909   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17910   "  [l2-table <nn>] [del]")                                            \
17911 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17912 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17913     "[master|slave]")                                                   \
17914 _(netmap_delete, "name <interface name>")                               \
17915 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17916 _(mpls_fib_dump, "")                                                    \
17917 _(classify_table_ids, "")                                               \
17918 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17919 _(classify_table_info, "table_id <nn>")                                 \
17920 _(classify_session_dump, "table_id <nn>")                               \
17921 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17922     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17923     "[template_interval <nn>] [udp_checksum]")                          \
17924 _(ipfix_exporter_dump, "")                                              \
17925 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17926 _(ipfix_classify_stream_dump, "")                                       \
17927 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17928 _(ipfix_classify_table_dump, "")                                        \
17929 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17930 _(sw_interface_span_dump, "")                                           \
17931 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17932 _(pg_create_interface, "if_id <nn>")                                    \
17933 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17934 _(pg_enable_disable, "[stream <id>] disable")                           \
17935 _(ip_source_and_port_range_check_add_del,                               \
17936   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17937 _(ip_source_and_port_range_check_interface_add_del,                     \
17938   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17939   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17940 _(ipsec_gre_add_del_tunnel,                                             \
17941   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17942 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17943 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17944 _(l2_interface_pbb_tag_rewrite,                                         \
17945   "<intfc> | sw_if_index <nn> \n"                                       \
17946   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17947   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17948 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17949 _(flow_classify_set_interface,                                          \
17950   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17951 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17952 _(ip_fib_dump, "")                                                      \
17953 _(ip6_fib_dump, "")                                                     \
17954 _(feature_enable_disable, "arc_name <arc_name> "                        \
17955   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17956 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17957 "[disable]")                                                            \
17958 _(l2_xconnect_dump, "")                                                 \
17959 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17960 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17961 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17962
17963 #if DPDK > 0
17964 #define foreach_vpe_dpdk_api_msg                                        \
17965 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17966   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17967   "profile <profile-id>\n")                                             \
17968 _(sw_interface_set_dpdk_hqos_subport,                                   \
17969   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17970   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17971 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17972   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
17973 #endif
17974
17975 /* List of command functions, CLI names map directly to functions */
17976 #define foreach_cli_function                                    \
17977 _(comment, "usage: comment <ignore-rest-of-line>")              \
17978 _(dump_interface_table, "usage: dump_interface_table")          \
17979 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17980 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17981 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17982 _(dump_stats_table, "usage: dump_stats_table")                  \
17983 _(dump_macro_table, "usage: dump_macro_table ")                 \
17984 _(dump_node_table, "usage: dump_node_table")                    \
17985 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17986 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17987 _(echo, "usage: echo <message>")                                \
17988 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17989 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17990 _(help, "usage: help")                                          \
17991 _(q, "usage: quit")                                             \
17992 _(quit, "usage: quit")                                          \
17993 _(search_node_table, "usage: search_node_table <name>...")      \
17994 _(set, "usage: set <variable-name> <value>")                    \
17995 _(script, "usage: script <file-name>")                          \
17996 _(unset, "usage: unset <variable-name>")
17997
17998 #define _(N,n)                                  \
17999     static void vl_api_##n##_t_handler_uni      \
18000     (vl_api_##n##_t * mp)                       \
18001     {                                           \
18002         vat_main_t * vam = &vat_main;           \
18003         if (vam->json_output) {                 \
18004             vl_api_##n##_t_handler_json(mp);    \
18005         } else {                                \
18006             vl_api_##n##_t_handler(mp);         \
18007         }                                       \
18008     }
18009 foreach_vpe_api_reply_msg;
18010 #undef _
18011
18012 #if DPDK > 0
18013 #define _(N,n)                                  \
18014     static void vl_api_##n##_t_handler_uni      \
18015     (vl_api_##n##_t * mp)                       \
18016     {                                           \
18017         vat_main_t * vam = &vat_main;           \
18018         if (vam->json_output) {                 \
18019             vl_api_##n##_t_handler_json(mp);    \
18020         } else {                                \
18021             vl_api_##n##_t_handler(mp);         \
18022         }                                       \
18023     }
18024 foreach_vpe_dpdk_api_reply_msg;
18025 #undef _
18026 #endif
18027
18028 void
18029 vat_api_hookup (vat_main_t * vam)
18030 {
18031 #define _(N,n)                                                  \
18032     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18033                            vl_api_##n##_t_handler_uni,          \
18034                            vl_noop_handler,                     \
18035                            vl_api_##n##_t_endian,               \
18036                            vl_api_##n##_t_print,                \
18037                            sizeof(vl_api_##n##_t), 1);
18038   foreach_vpe_api_reply_msg;
18039 #undef _
18040
18041 #if DPDK > 0
18042 #define _(N,n)                                                  \
18043     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18044                            vl_api_##n##_t_handler_uni,          \
18045                            vl_noop_handler,                     \
18046                            vl_api_##n##_t_endian,               \
18047                            vl_api_##n##_t_print,                \
18048                            sizeof(vl_api_##n##_t), 1);
18049   foreach_vpe_dpdk_api_reply_msg;
18050 #undef _
18051 #endif
18052
18053 #if (VPP_API_TEST_BUILTIN==0)
18054   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18055 #endif
18056
18057   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18058
18059   vam->function_by_name = hash_create_string (0, sizeof (uword));
18060
18061   vam->help_by_name = hash_create_string (0, sizeof (uword));
18062
18063   /* API messages we can send */
18064 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18065   foreach_vpe_api_msg;
18066 #undef _
18067 #if DPDK >0
18068 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18069   foreach_vpe_dpdk_api_msg;
18070 #undef _
18071 #endif
18072
18073   /* Help strings */
18074 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18075   foreach_vpe_api_msg;
18076 #undef _
18077 #if DPDK >0
18078 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18079   foreach_vpe_dpdk_api_msg;
18080 #undef _
18081 #endif
18082
18083   /* CLI functions */
18084 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18085   foreach_cli_function;
18086 #undef _
18087
18088   /* Help strings */
18089 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18090   foreach_cli_function;
18091 #undef _
18092 }
18093
18094 /*
18095  * fd.io coding-style-patch-verification: ON
18096  *
18097  * Local Variables:
18098  * eval: (c-set-style "gnu")
18099  * End:
18100  */