dpdk: rework cryptodev ipsec build and setup
[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 (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12203               integ_alg >= IPSEC_INTEG_N_ALG)
12204             {
12205               clib_warning ("unsupported integ-alg: '%U'",
12206                             format_ipsec_integ_alg, integ_alg);
12207               return -99;
12208             }
12209         }
12210       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12211         ;
12212       else
12213         {
12214           clib_warning ("parse error '%U'", format_unformat_error, i);
12215           return -99;
12216         }
12217
12218     }
12219
12220   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12221
12222   mp->sad_id = ntohl (sad_id);
12223   mp->is_add = is_add;
12224   mp->protocol = protocol;
12225   mp->spi = ntohl (spi);
12226   mp->is_tunnel = is_tunnel;
12227   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12228   mp->crypto_algorithm = crypto_alg;
12229   mp->integrity_algorithm = integ_alg;
12230   mp->crypto_key_length = vec_len (ck);
12231   mp->integrity_key_length = vec_len (ik);
12232
12233   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12234     mp->crypto_key_length = sizeof (mp->crypto_key);
12235
12236   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12237     mp->integrity_key_length = sizeof (mp->integrity_key);
12238
12239   if (ck)
12240     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12241   if (ik)
12242     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12243
12244   if (is_tunnel)
12245     {
12246       if (is_tunnel_ipv6)
12247         {
12248           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12249                        sizeof (ip6_address_t));
12250           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12251                        sizeof (ip6_address_t));
12252         }
12253       else
12254         {
12255           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12256                        sizeof (ip4_address_t));
12257           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12258                        sizeof (ip4_address_t));
12259         }
12260     }
12261
12262   S;
12263   W;
12264   /* NOTREACHED */
12265   return 0;
12266 }
12267
12268 static int
12269 api_ipsec_sa_set_key (vat_main_t * vam)
12270 {
12271   unformat_input_t *i = vam->input;
12272   vl_api_ipsec_sa_set_key_t *mp;
12273   f64 timeout;
12274   u32 sa_id;
12275   u8 *ck = 0, *ik = 0;
12276
12277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12278     {
12279       if (unformat (i, "sa_id %d", &sa_id))
12280         ;
12281       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12282         ;
12283       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12284         ;
12285       else
12286         {
12287           clib_warning ("parse error '%U'", format_unformat_error, i);
12288           return -99;
12289         }
12290     }
12291
12292   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12293
12294   mp->sa_id = ntohl (sa_id);
12295   mp->crypto_key_length = vec_len (ck);
12296   mp->integrity_key_length = vec_len (ik);
12297
12298   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12299     mp->crypto_key_length = sizeof (mp->crypto_key);
12300
12301   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12302     mp->integrity_key_length = sizeof (mp->integrity_key);
12303
12304   if (ck)
12305     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12306   if (ik)
12307     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12308
12309   S;
12310   W;
12311   /* NOTREACHED */
12312   return 0;
12313 }
12314
12315 static int
12316 api_ikev2_profile_add_del (vat_main_t * vam)
12317 {
12318   unformat_input_t *i = vam->input;
12319   vl_api_ikev2_profile_add_del_t *mp;
12320   f64 timeout;
12321   u8 is_add = 1;
12322   u8 *name = 0;
12323
12324   const char *valid_chars = "a-zA-Z0-9_";
12325
12326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12327     {
12328       if (unformat (i, "del"))
12329         is_add = 0;
12330       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12331         vec_add1 (name, 0);
12332       else
12333         {
12334           errmsg ("parse error '%U'", format_unformat_error, i);
12335           return -99;
12336         }
12337     }
12338
12339   if (!vec_len (name))
12340     {
12341       errmsg ("profile name must be specified");
12342       return -99;
12343     }
12344
12345   if (vec_len (name) > 64)
12346     {
12347       errmsg ("profile name too long");
12348       return -99;
12349     }
12350
12351   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12352
12353   clib_memcpy (mp->name, name, vec_len (name));
12354   mp->is_add = is_add;
12355   vec_free (name);
12356
12357   S;
12358   W;
12359   /* NOTREACHED */
12360   return 0;
12361 }
12362
12363 static int
12364 api_ikev2_profile_set_auth (vat_main_t * vam)
12365 {
12366   unformat_input_t *i = vam->input;
12367   vl_api_ikev2_profile_set_auth_t *mp;
12368   f64 timeout;
12369   u8 *name = 0;
12370   u8 *data = 0;
12371   u32 auth_method = 0;
12372   u8 is_hex = 0;
12373
12374   const char *valid_chars = "a-zA-Z0-9_";
12375
12376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12377     {
12378       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12379         vec_add1 (name, 0);
12380       else if (unformat (i, "auth_method %U",
12381                          unformat_ikev2_auth_method, &auth_method))
12382         ;
12383       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12384         is_hex = 1;
12385       else if (unformat (i, "auth_data %v", &data))
12386         ;
12387       else
12388         {
12389           errmsg ("parse error '%U'", format_unformat_error, i);
12390           return -99;
12391         }
12392     }
12393
12394   if (!vec_len (name))
12395     {
12396       errmsg ("profile name must be specified");
12397       return -99;
12398     }
12399
12400   if (vec_len (name) > 64)
12401     {
12402       errmsg ("profile name too long");
12403       return -99;
12404     }
12405
12406   if (!vec_len (data))
12407     {
12408       errmsg ("auth_data must be specified");
12409       return -99;
12410     }
12411
12412   if (!auth_method)
12413     {
12414       errmsg ("auth_method must be specified");
12415       return -99;
12416     }
12417
12418   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12419
12420   mp->is_hex = is_hex;
12421   mp->auth_method = (u8) auth_method;
12422   mp->data_len = vec_len (data);
12423   clib_memcpy (mp->name, name, vec_len (name));
12424   clib_memcpy (mp->data, data, vec_len (data));
12425   vec_free (name);
12426   vec_free (data);
12427
12428   S;
12429   W;
12430   /* NOTREACHED */
12431   return 0;
12432 }
12433
12434 static int
12435 api_ikev2_profile_set_id (vat_main_t * vam)
12436 {
12437   unformat_input_t *i = vam->input;
12438   vl_api_ikev2_profile_set_id_t *mp;
12439   f64 timeout;
12440   u8 *name = 0;
12441   u8 *data = 0;
12442   u8 is_local = 0;
12443   u32 id_type = 0;
12444   ip4_address_t ip4;
12445
12446   const char *valid_chars = "a-zA-Z0-9_";
12447
12448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12449     {
12450       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12451         vec_add1 (name, 0);
12452       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12453         ;
12454       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12455         {
12456           data = vec_new (u8, 4);
12457           clib_memcpy (data, ip4.as_u8, 4);
12458         }
12459       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12460         ;
12461       else if (unformat (i, "id_data %v", &data))
12462         ;
12463       else if (unformat (i, "local"))
12464         is_local = 1;
12465       else if (unformat (i, "remote"))
12466         is_local = 0;
12467       else
12468         {
12469           errmsg ("parse error '%U'", format_unformat_error, i);
12470           return -99;
12471         }
12472     }
12473
12474   if (!vec_len (name))
12475     {
12476       errmsg ("profile name must be specified");
12477       return -99;
12478     }
12479
12480   if (vec_len (name) > 64)
12481     {
12482       errmsg ("profile name too long");
12483       return -99;
12484     }
12485
12486   if (!vec_len (data))
12487     {
12488       errmsg ("id_data must be specified");
12489       return -99;
12490     }
12491
12492   if (!id_type)
12493     {
12494       errmsg ("id_type must be specified");
12495       return -99;
12496     }
12497
12498   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12499
12500   mp->is_local = is_local;
12501   mp->id_type = (u8) id_type;
12502   mp->data_len = vec_len (data);
12503   clib_memcpy (mp->name, name, vec_len (name));
12504   clib_memcpy (mp->data, data, vec_len (data));
12505   vec_free (name);
12506   vec_free (data);
12507
12508   S;
12509   W;
12510   /* NOTREACHED */
12511   return 0;
12512 }
12513
12514 static int
12515 api_ikev2_profile_set_ts (vat_main_t * vam)
12516 {
12517   unformat_input_t *i = vam->input;
12518   vl_api_ikev2_profile_set_ts_t *mp;
12519   f64 timeout;
12520   u8 *name = 0;
12521   u8 is_local = 0;
12522   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12523   ip4_address_t start_addr, end_addr;
12524
12525   const char *valid_chars = "a-zA-Z0-9_";
12526
12527   start_addr.as_u32 = 0;
12528   end_addr.as_u32 = (u32) ~ 0;
12529
12530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12531     {
12532       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12533         vec_add1 (name, 0);
12534       else if (unformat (i, "protocol %d", &proto))
12535         ;
12536       else if (unformat (i, "start_port %d", &start_port))
12537         ;
12538       else if (unformat (i, "end_port %d", &end_port))
12539         ;
12540       else
12541         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12542         ;
12543       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12544         ;
12545       else if (unformat (i, "local"))
12546         is_local = 1;
12547       else if (unformat (i, "remote"))
12548         is_local = 0;
12549       else
12550         {
12551           errmsg ("parse error '%U'", format_unformat_error, i);
12552           return -99;
12553         }
12554     }
12555
12556   if (!vec_len (name))
12557     {
12558       errmsg ("profile name must be specified");
12559       return -99;
12560     }
12561
12562   if (vec_len (name) > 64)
12563     {
12564       errmsg ("profile name too long");
12565       return -99;
12566     }
12567
12568   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12569
12570   mp->is_local = is_local;
12571   mp->proto = (u8) proto;
12572   mp->start_port = (u16) start_port;
12573   mp->end_port = (u16) end_port;
12574   mp->start_addr = start_addr.as_u32;
12575   mp->end_addr = end_addr.as_u32;
12576   clib_memcpy (mp->name, name, vec_len (name));
12577   vec_free (name);
12578
12579   S;
12580   W;
12581   /* NOTREACHED */
12582   return 0;
12583 }
12584
12585 static int
12586 api_ikev2_set_local_key (vat_main_t * vam)
12587 {
12588   unformat_input_t *i = vam->input;
12589   vl_api_ikev2_set_local_key_t *mp;
12590   f64 timeout;
12591   u8 *file = 0;
12592
12593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12594     {
12595       if (unformat (i, "file %v", &file))
12596         vec_add1 (file, 0);
12597       else
12598         {
12599           errmsg ("parse error '%U'", format_unformat_error, i);
12600           return -99;
12601         }
12602     }
12603
12604   if (!vec_len (file))
12605     {
12606       errmsg ("RSA key file must be specified");
12607       return -99;
12608     }
12609
12610   if (vec_len (file) > 256)
12611     {
12612       errmsg ("file name too long");
12613       return -99;
12614     }
12615
12616   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12617
12618   clib_memcpy (mp->key_file, file, vec_len (file));
12619   vec_free (file);
12620
12621   S;
12622   W;
12623   /* NOTREACHED */
12624   return 0;
12625 }
12626
12627 /*
12628  * MAP
12629  */
12630 static int
12631 api_map_add_domain (vat_main_t * vam)
12632 {
12633   unformat_input_t *i = vam->input;
12634   vl_api_map_add_domain_t *mp;
12635   f64 timeout;
12636
12637   ip4_address_t ip4_prefix;
12638   ip6_address_t ip6_prefix;
12639   ip6_address_t ip6_src;
12640   u32 num_m_args = 0;
12641   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12642     0, psid_length = 0;
12643   u8 is_translation = 0;
12644   u32 mtu = 0;
12645   u32 ip6_src_len = 128;
12646
12647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12648     {
12649       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12650                     &ip4_prefix, &ip4_prefix_len))
12651         num_m_args++;
12652       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12653                          &ip6_prefix, &ip6_prefix_len))
12654         num_m_args++;
12655       else
12656         if (unformat
12657             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12658              &ip6_src_len))
12659         num_m_args++;
12660       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12661         num_m_args++;
12662       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12663         num_m_args++;
12664       else if (unformat (i, "psid-offset %d", &psid_offset))
12665         num_m_args++;
12666       else if (unformat (i, "psid-len %d", &psid_length))
12667         num_m_args++;
12668       else if (unformat (i, "mtu %d", &mtu))
12669         num_m_args++;
12670       else if (unformat (i, "map-t"))
12671         is_translation = 1;
12672       else
12673         {
12674           clib_warning ("parse error '%U'", format_unformat_error, i);
12675           return -99;
12676         }
12677     }
12678
12679   if (num_m_args < 3)
12680     {
12681       errmsg ("mandatory argument(s) missing");
12682       return -99;
12683     }
12684
12685   /* Construct the API message */
12686   M (MAP_ADD_DOMAIN, map_add_domain);
12687
12688   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12689   mp->ip4_prefix_len = ip4_prefix_len;
12690
12691   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12692   mp->ip6_prefix_len = ip6_prefix_len;
12693
12694   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12695   mp->ip6_src_prefix_len = ip6_src_len;
12696
12697   mp->ea_bits_len = ea_bits_len;
12698   mp->psid_offset = psid_offset;
12699   mp->psid_length = psid_length;
12700   mp->is_translation = is_translation;
12701   mp->mtu = htons (mtu);
12702
12703   /* send it... */
12704   S;
12705
12706   /* Wait for a reply, return good/bad news  */
12707   W;
12708 }
12709
12710 static int
12711 api_map_del_domain (vat_main_t * vam)
12712 {
12713   unformat_input_t *i = vam->input;
12714   vl_api_map_del_domain_t *mp;
12715   f64 timeout;
12716
12717   u32 num_m_args = 0;
12718   u32 index;
12719
12720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12721     {
12722       if (unformat (i, "index %d", &index))
12723         num_m_args++;
12724       else
12725         {
12726           clib_warning ("parse error '%U'", format_unformat_error, i);
12727           return -99;
12728         }
12729     }
12730
12731   if (num_m_args != 1)
12732     {
12733       errmsg ("mandatory argument(s) missing");
12734       return -99;
12735     }
12736
12737   /* Construct the API message */
12738   M (MAP_DEL_DOMAIN, map_del_domain);
12739
12740   mp->index = ntohl (index);
12741
12742   /* send it... */
12743   S;
12744
12745   /* Wait for a reply, return good/bad news  */
12746   W;
12747 }
12748
12749 static int
12750 api_map_add_del_rule (vat_main_t * vam)
12751 {
12752   unformat_input_t *i = vam->input;
12753   vl_api_map_add_del_rule_t *mp;
12754   f64 timeout;
12755   u8 is_add = 1;
12756   ip6_address_t ip6_dst;
12757   u32 num_m_args = 0, index, psid = 0;
12758
12759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12760     {
12761       if (unformat (i, "index %d", &index))
12762         num_m_args++;
12763       else if (unformat (i, "psid %d", &psid))
12764         num_m_args++;
12765       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12766         num_m_args++;
12767       else if (unformat (i, "del"))
12768         {
12769           is_add = 0;
12770         }
12771       else
12772         {
12773           clib_warning ("parse error '%U'", format_unformat_error, i);
12774           return -99;
12775         }
12776     }
12777
12778   /* Construct the API message */
12779   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12780
12781   mp->index = ntohl (index);
12782   mp->is_add = is_add;
12783   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12784   mp->psid = ntohs (psid);
12785
12786   /* send it... */
12787   S;
12788
12789   /* Wait for a reply, return good/bad news  */
12790   W;
12791 }
12792
12793 static int
12794 api_map_domain_dump (vat_main_t * vam)
12795 {
12796   vl_api_map_domain_dump_t *mp;
12797   f64 timeout;
12798
12799   /* Construct the API message */
12800   M (MAP_DOMAIN_DUMP, map_domain_dump);
12801
12802   /* send it... */
12803   S;
12804
12805   /* Use a control ping for synchronization */
12806   {
12807     vl_api_control_ping_t *mp;
12808     M (CONTROL_PING, control_ping);
12809     S;
12810   }
12811   W;
12812 }
12813
12814 static int
12815 api_map_rule_dump (vat_main_t * vam)
12816 {
12817   unformat_input_t *i = vam->input;
12818   vl_api_map_rule_dump_t *mp;
12819   f64 timeout;
12820   u32 domain_index = ~0;
12821
12822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12823     {
12824       if (unformat (i, "index %u", &domain_index))
12825         ;
12826       else
12827         break;
12828     }
12829
12830   if (domain_index == ~0)
12831     {
12832       clib_warning ("parse error: domain index expected");
12833       return -99;
12834     }
12835
12836   /* Construct the API message */
12837   M (MAP_RULE_DUMP, map_rule_dump);
12838
12839   mp->domain_index = htonl (domain_index);
12840
12841   /* send it... */
12842   S;
12843
12844   /* Use a control ping for synchronization */
12845   {
12846     vl_api_control_ping_t *mp;
12847     M (CONTROL_PING, control_ping);
12848     S;
12849   }
12850   W;
12851 }
12852
12853 static void vl_api_map_add_domain_reply_t_handler
12854   (vl_api_map_add_domain_reply_t * mp)
12855 {
12856   vat_main_t *vam = &vat_main;
12857   i32 retval = ntohl (mp->retval);
12858
12859   if (vam->async_mode)
12860     {
12861       vam->async_errors += (retval < 0);
12862     }
12863   else
12864     {
12865       vam->retval = retval;
12866       vam->result_ready = 1;
12867     }
12868 }
12869
12870 static void vl_api_map_add_domain_reply_t_handler_json
12871   (vl_api_map_add_domain_reply_t * mp)
12872 {
12873   vat_main_t *vam = &vat_main;
12874   vat_json_node_t node;
12875
12876   vat_json_init_object (&node);
12877   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12878   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12879
12880   vat_json_print (vam->ofp, &node);
12881   vat_json_free (&node);
12882
12883   vam->retval = ntohl (mp->retval);
12884   vam->result_ready = 1;
12885 }
12886
12887 static int
12888 api_get_first_msg_id (vat_main_t * vam)
12889 {
12890   vl_api_get_first_msg_id_t *mp;
12891   f64 timeout;
12892   unformat_input_t *i = vam->input;
12893   u8 *name;
12894   u8 name_set = 0;
12895
12896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12897     {
12898       if (unformat (i, "client %s", &name))
12899         name_set = 1;
12900       else
12901         break;
12902     }
12903
12904   if (name_set == 0)
12905     {
12906       errmsg ("missing client name");
12907       return -99;
12908     }
12909   vec_add1 (name, 0);
12910
12911   if (vec_len (name) > 63)
12912     {
12913       errmsg ("client name too long");
12914       return -99;
12915     }
12916
12917   M (GET_FIRST_MSG_ID, get_first_msg_id);
12918   clib_memcpy (mp->name, name, vec_len (name));
12919   S;
12920   W;
12921   /* NOTREACHED */
12922   return 0;
12923 }
12924
12925 static int
12926 api_cop_interface_enable_disable (vat_main_t * vam)
12927 {
12928   unformat_input_t *line_input = vam->input;
12929   vl_api_cop_interface_enable_disable_t *mp;
12930   f64 timeout;
12931   u32 sw_if_index = ~0;
12932   u8 enable_disable = 1;
12933
12934   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12935     {
12936       if (unformat (line_input, "disable"))
12937         enable_disable = 0;
12938       if (unformat (line_input, "enable"))
12939         enable_disable = 1;
12940       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12941                          vam, &sw_if_index))
12942         ;
12943       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12944         ;
12945       else
12946         break;
12947     }
12948
12949   if (sw_if_index == ~0)
12950     {
12951       errmsg ("missing interface name or sw_if_index");
12952       return -99;
12953     }
12954
12955   /* Construct the API message */
12956   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12957   mp->sw_if_index = ntohl (sw_if_index);
12958   mp->enable_disable = enable_disable;
12959
12960   /* send it... */
12961   S;
12962   /* Wait for the reply */
12963   W;
12964 }
12965
12966 static int
12967 api_cop_whitelist_enable_disable (vat_main_t * vam)
12968 {
12969   unformat_input_t *line_input = vam->input;
12970   vl_api_cop_whitelist_enable_disable_t *mp;
12971   f64 timeout;
12972   u32 sw_if_index = ~0;
12973   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12974   u32 fib_id = 0;
12975
12976   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12977     {
12978       if (unformat (line_input, "ip4"))
12979         ip4 = 1;
12980       else if (unformat (line_input, "ip6"))
12981         ip6 = 1;
12982       else if (unformat (line_input, "default"))
12983         default_cop = 1;
12984       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12985                          vam, &sw_if_index))
12986         ;
12987       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12988         ;
12989       else if (unformat (line_input, "fib-id %d", &fib_id))
12990         ;
12991       else
12992         break;
12993     }
12994
12995   if (sw_if_index == ~0)
12996     {
12997       errmsg ("missing interface name or sw_if_index");
12998       return -99;
12999     }
13000
13001   /* Construct the API message */
13002   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
13003   mp->sw_if_index = ntohl (sw_if_index);
13004   mp->fib_id = ntohl (fib_id);
13005   mp->ip4 = ip4;
13006   mp->ip6 = ip6;
13007   mp->default_cop = default_cop;
13008
13009   /* send it... */
13010   S;
13011   /* Wait for the reply */
13012   W;
13013 }
13014
13015 static int
13016 api_get_node_graph (vat_main_t * vam)
13017 {
13018   vl_api_get_node_graph_t *mp;
13019   f64 timeout;
13020
13021   M (GET_NODE_GRAPH, get_node_graph);
13022
13023   /* send it... */
13024   S;
13025   /* Wait for the reply */
13026   W;
13027 }
13028
13029 /* *INDENT-OFF* */
13030 /** Used for parsing LISP eids */
13031 typedef CLIB_PACKED(struct{
13032   u8 addr[16];   /**< eid address */
13033   u32 len;       /**< prefix length if IP */
13034   u8 type;      /**< type of eid */
13035 }) lisp_eid_vat_t;
13036 /* *INDENT-ON* */
13037
13038 static uword
13039 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13040 {
13041   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13042
13043   memset (a, 0, sizeof (a[0]));
13044
13045   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13046     {
13047       a->type = 0;              /* ipv4 type */
13048     }
13049   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13050     {
13051       a->type = 1;              /* ipv6 type */
13052     }
13053   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13054     {
13055       a->type = 2;              /* mac type */
13056     }
13057   else
13058     {
13059       return 0;
13060     }
13061
13062   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13063     {
13064       return 0;
13065     }
13066
13067   return 1;
13068 }
13069
13070 static int
13071 lisp_eid_size_vat (u8 type)
13072 {
13073   switch (type)
13074     {
13075     case 0:
13076       return 4;
13077     case 1:
13078       return 16;
13079     case 2:
13080       return 6;
13081     }
13082   return 0;
13083 }
13084
13085 static void
13086 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13087 {
13088   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13089 }
13090
13091 /* *INDENT-OFF* */
13092 /** Used for transferring locators via VPP API */
13093 typedef CLIB_PACKED(struct
13094 {
13095   u32 sw_if_index; /**< locator sw_if_index */
13096   u8 priority; /**< locator priority */
13097   u8 weight;   /**< locator weight */
13098 }) ls_locator_t;
13099 /* *INDENT-ON* */
13100
13101 static int
13102 api_lisp_add_del_locator_set (vat_main_t * vam)
13103 {
13104   unformat_input_t *input = vam->input;
13105   vl_api_lisp_add_del_locator_set_t *mp;
13106   f64 timeout = ~0;
13107   u8 is_add = 1;
13108   u8 *locator_set_name = NULL;
13109   u8 locator_set_name_set = 0;
13110   ls_locator_t locator, *locators = 0;
13111   u32 sw_if_index, priority, weight;
13112   u32 data_len = 0;
13113
13114   /* Parse args required to build the message */
13115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13116     {
13117       if (unformat (input, "del"))
13118         {
13119           is_add = 0;
13120         }
13121       else if (unformat (input, "locator-set %s", &locator_set_name))
13122         {
13123           locator_set_name_set = 1;
13124         }
13125       else if (unformat (input, "sw_if_index %u p %u w %u",
13126                          &sw_if_index, &priority, &weight))
13127         {
13128           locator.sw_if_index = htonl (sw_if_index);
13129           locator.priority = priority;
13130           locator.weight = weight;
13131           vec_add1 (locators, locator);
13132         }
13133       else
13134         if (unformat
13135             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13136              &sw_if_index, &priority, &weight))
13137         {
13138           locator.sw_if_index = htonl (sw_if_index);
13139           locator.priority = priority;
13140           locator.weight = weight;
13141           vec_add1 (locators, locator);
13142         }
13143       else
13144         break;
13145     }
13146
13147   if (locator_set_name_set == 0)
13148     {
13149       errmsg ("missing locator-set name");
13150       vec_free (locators);
13151       return -99;
13152     }
13153
13154   if (vec_len (locator_set_name) > 64)
13155     {
13156       errmsg ("locator-set name too long");
13157       vec_free (locator_set_name);
13158       vec_free (locators);
13159       return -99;
13160     }
13161   vec_add1 (locator_set_name, 0);
13162
13163   data_len = sizeof (ls_locator_t) * vec_len (locators);
13164
13165   /* Construct the API message */
13166   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
13167
13168   mp->is_add = is_add;
13169   clib_memcpy (mp->locator_set_name, locator_set_name,
13170                vec_len (locator_set_name));
13171   vec_free (locator_set_name);
13172
13173   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13174   if (locators)
13175     clib_memcpy (mp->locators, locators, data_len);
13176   vec_free (locators);
13177
13178   /* send it... */
13179   S;
13180
13181   /* Wait for a reply... */
13182   W;
13183
13184   /* NOTREACHED */
13185   return 0;
13186 }
13187
13188 static int
13189 api_lisp_add_del_locator (vat_main_t * vam)
13190 {
13191   unformat_input_t *input = vam->input;
13192   vl_api_lisp_add_del_locator_t *mp;
13193   f64 timeout = ~0;
13194   u32 tmp_if_index = ~0;
13195   u32 sw_if_index = ~0;
13196   u8 sw_if_index_set = 0;
13197   u8 sw_if_index_if_name_set = 0;
13198   u32 priority = ~0;
13199   u8 priority_set = 0;
13200   u32 weight = ~0;
13201   u8 weight_set = 0;
13202   u8 is_add = 1;
13203   u8 *locator_set_name = NULL;
13204   u8 locator_set_name_set = 0;
13205
13206   /* Parse args required to build the message */
13207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13208     {
13209       if (unformat (input, "del"))
13210         {
13211           is_add = 0;
13212         }
13213       else if (unformat (input, "locator-set %s", &locator_set_name))
13214         {
13215           locator_set_name_set = 1;
13216         }
13217       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13218                          &tmp_if_index))
13219         {
13220           sw_if_index_if_name_set = 1;
13221           sw_if_index = tmp_if_index;
13222         }
13223       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13224         {
13225           sw_if_index_set = 1;
13226           sw_if_index = tmp_if_index;
13227         }
13228       else if (unformat (input, "p %d", &priority))
13229         {
13230           priority_set = 1;
13231         }
13232       else if (unformat (input, "w %d", &weight))
13233         {
13234           weight_set = 1;
13235         }
13236       else
13237         break;
13238     }
13239
13240   if (locator_set_name_set == 0)
13241     {
13242       errmsg ("missing locator-set name");
13243       return -99;
13244     }
13245
13246   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13247     {
13248       errmsg ("missing sw_if_index");
13249       vec_free (locator_set_name);
13250       return -99;
13251     }
13252
13253   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13254     {
13255       errmsg ("cannot use both params interface name and sw_if_index");
13256       vec_free (locator_set_name);
13257       return -99;
13258     }
13259
13260   if (priority_set == 0)
13261     {
13262       errmsg ("missing locator-set priority");
13263       vec_free (locator_set_name);
13264       return -99;
13265     }
13266
13267   if (weight_set == 0)
13268     {
13269       errmsg ("missing locator-set weight");
13270       vec_free (locator_set_name);
13271       return -99;
13272     }
13273
13274   if (vec_len (locator_set_name) > 64)
13275     {
13276       errmsg ("locator-set name too long");
13277       vec_free (locator_set_name);
13278       return -99;
13279     }
13280   vec_add1 (locator_set_name, 0);
13281
13282   /* Construct the API message */
13283   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13284
13285   mp->is_add = is_add;
13286   mp->sw_if_index = ntohl (sw_if_index);
13287   mp->priority = priority;
13288   mp->weight = weight;
13289   clib_memcpy (mp->locator_set_name, locator_set_name,
13290                vec_len (locator_set_name));
13291   vec_free (locator_set_name);
13292
13293   /* send it... */
13294   S;
13295
13296   /* Wait for a reply... */
13297   W;
13298
13299   /* NOTREACHED */
13300   return 0;
13301 }
13302
13303 uword
13304 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13305 {
13306   u32 *key_id = va_arg (*args, u32 *);
13307   u8 *s = 0;
13308
13309   if (unformat (input, "%s", &s))
13310     {
13311       if (!strcmp ((char *) s, "sha1"))
13312         key_id[0] = HMAC_SHA_1_96;
13313       else if (!strcmp ((char *) s, "sha256"))
13314         key_id[0] = HMAC_SHA_256_128;
13315       else
13316         {
13317           clib_warning ("invalid key_id: '%s'", s);
13318           key_id[0] = HMAC_NO_KEY;
13319         }
13320     }
13321   else
13322     return 0;
13323
13324   vec_free (s);
13325   return 1;
13326 }
13327
13328 static int
13329 api_lisp_add_del_local_eid (vat_main_t * vam)
13330 {
13331   unformat_input_t *input = vam->input;
13332   vl_api_lisp_add_del_local_eid_t *mp;
13333   f64 timeout = ~0;
13334   u8 is_add = 1;
13335   u8 eid_set = 0;
13336   lisp_eid_vat_t _eid, *eid = &_eid;
13337   u8 *locator_set_name = 0;
13338   u8 locator_set_name_set = 0;
13339   u32 vni = 0;
13340   u16 key_id = 0;
13341   u8 *key = 0;
13342
13343   /* Parse args required to build the message */
13344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13345     {
13346       if (unformat (input, "del"))
13347         {
13348           is_add = 0;
13349         }
13350       else if (unformat (input, "vni %d", &vni))
13351         {
13352           ;
13353         }
13354       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13355         {
13356           eid_set = 1;
13357         }
13358       else if (unformat (input, "locator-set %s", &locator_set_name))
13359         {
13360           locator_set_name_set = 1;
13361         }
13362       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13363         ;
13364       else if (unformat (input, "secret-key %_%v%_", &key))
13365         ;
13366       else
13367         break;
13368     }
13369
13370   if (locator_set_name_set == 0)
13371     {
13372       errmsg ("missing locator-set name");
13373       return -99;
13374     }
13375
13376   if (0 == eid_set)
13377     {
13378       errmsg ("EID address not set!");
13379       vec_free (locator_set_name);
13380       return -99;
13381     }
13382
13383   if (key && (0 == key_id))
13384     {
13385       errmsg ("invalid key_id!");
13386       return -99;
13387     }
13388
13389   if (vec_len (key) > 64)
13390     {
13391       errmsg ("key too long");
13392       vec_free (key);
13393       return -99;
13394     }
13395
13396   if (vec_len (locator_set_name) > 64)
13397     {
13398       errmsg ("locator-set name too long");
13399       vec_free (locator_set_name);
13400       return -99;
13401     }
13402   vec_add1 (locator_set_name, 0);
13403
13404   /* Construct the API message */
13405   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13406
13407   mp->is_add = is_add;
13408   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13409   mp->eid_type = eid->type;
13410   mp->prefix_len = eid->len;
13411   mp->vni = clib_host_to_net_u32 (vni);
13412   mp->key_id = clib_host_to_net_u16 (key_id);
13413   clib_memcpy (mp->locator_set_name, locator_set_name,
13414                vec_len (locator_set_name));
13415   clib_memcpy (mp->key, key, vec_len (key));
13416
13417   vec_free (locator_set_name);
13418   vec_free (key);
13419
13420   /* send it... */
13421   S;
13422
13423   /* Wait for a reply... */
13424   W;
13425
13426   /* NOTREACHED */
13427   return 0;
13428 }
13429
13430 /* *INDENT-OFF* */
13431 /** Used for transferring locators via VPP API */
13432 typedef CLIB_PACKED(struct
13433 {
13434   u8 is_ip4; /**< is locator an IPv4 address? */
13435   u8 priority; /**< locator priority */
13436   u8 weight;   /**< locator weight */
13437   u8 addr[16]; /**< IPv4/IPv6 address */
13438 }) rloc_t;
13439 /* *INDENT-ON* */
13440
13441 static int
13442 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13443 {
13444   u32 dp_table = 0, vni = 0;;
13445   unformat_input_t *input = vam->input;
13446   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13447   f64 timeout = ~0;
13448   u8 is_add = 1;
13449   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13450   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13451   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13452   u32 action = ~0, w;
13453   ip4_address_t rmt_rloc4, lcl_rloc4;
13454   ip6_address_t rmt_rloc6, lcl_rloc6;
13455   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13456     0;
13457
13458   memset (&rloc, 0, sizeof (rloc));
13459
13460   /* Parse args required to build the message */
13461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13462     {
13463       if (unformat (input, "del"))
13464         is_add = 0;
13465       else if (unformat (input, "add"))
13466         is_add = 1;
13467       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13468         {
13469           rmt_eid_set = 1;
13470         }
13471       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13472         {
13473           lcl_eid_set = 1;
13474         }
13475       else if (unformat (input, "vrf %d", &dp_table))
13476         ;
13477       else if (unformat (input, "bd %d", &dp_table))
13478         ;
13479       else if (unformat (input, "vni %d", &vni))
13480         ;
13481       else if (unformat (input, "w %d", &w))
13482         {
13483           if (!curr_rloc)
13484             {
13485               errmsg ("No RLOC configured for setting priority/weight!");
13486               return -99;
13487             }
13488           curr_rloc->weight = w;
13489         }
13490       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13491                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13492         {
13493           rloc.is_ip4 = 1;
13494
13495           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13496           rloc.weight = 0;
13497           vec_add1 (lcl_locs, rloc);
13498
13499           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13500           vec_add1 (rmt_locs, rloc);
13501           /* weight saved in rmt loc */
13502           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13503         }
13504       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13505                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13506         {
13507           rloc.is_ip4 = 0;
13508           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13509           rloc.weight = 0;
13510           vec_add1 (lcl_locs, rloc);
13511
13512           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13513           vec_add1 (rmt_locs, rloc);
13514           /* weight saved in rmt loc */
13515           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13516         }
13517       else if (unformat (input, "action %d", &action))
13518         {
13519           ;
13520         }
13521       else
13522         {
13523           clib_warning ("parse error '%U'", format_unformat_error, input);
13524           return -99;
13525         }
13526     }
13527
13528   if (!rmt_eid_set)
13529     {
13530       errmsg ("remote eid addresses not set");
13531       return -99;
13532     }
13533
13534   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13535     {
13536       errmsg ("eid types don't match");
13537       return -99;
13538     }
13539
13540   if (0 == rmt_locs && (u32) ~ 0 == action)
13541     {
13542       errmsg ("action not set for negative mapping");
13543       return -99;
13544     }
13545
13546   /* Construct the API message */
13547   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry,
13548       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13549
13550   mp->is_add = is_add;
13551   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13552   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13553   mp->eid_type = rmt_eid->type;
13554   mp->dp_table = clib_host_to_net_u32 (dp_table);
13555   mp->vni = clib_host_to_net_u32 (vni);
13556   mp->rmt_len = rmt_eid->len;
13557   mp->lcl_len = lcl_eid->len;
13558   mp->action = action;
13559
13560   if (0 != rmt_locs && 0 != lcl_locs)
13561     {
13562       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13563       clib_memcpy (mp->locs, lcl_locs,
13564                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13565
13566       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13567       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13568                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13569     }
13570   vec_free (lcl_locs);
13571   vec_free (rmt_locs);
13572
13573   /* send it... */
13574   S;
13575
13576   /* Wait for a reply... */
13577   W;
13578
13579   /* NOTREACHED */
13580   return 0;
13581 }
13582
13583 static int
13584 api_lisp_add_del_map_server (vat_main_t * vam)
13585 {
13586   unformat_input_t *input = vam->input;
13587   vl_api_lisp_add_del_map_server_t *mp;
13588   f64 timeout = ~0;
13589   u8 is_add = 1;
13590   u8 ipv4_set = 0;
13591   u8 ipv6_set = 0;
13592   ip4_address_t ipv4;
13593   ip6_address_t ipv6;
13594
13595   /* Parse args required to build the message */
13596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13597     {
13598       if (unformat (input, "del"))
13599         {
13600           is_add = 0;
13601         }
13602       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13603         {
13604           ipv4_set = 1;
13605         }
13606       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13607         {
13608           ipv6_set = 1;
13609         }
13610       else
13611         break;
13612     }
13613
13614   if (ipv4_set && ipv6_set)
13615     {
13616       errmsg ("both eid v4 and v6 addresses set");
13617       return -99;
13618     }
13619
13620   if (!ipv4_set && !ipv6_set)
13621     {
13622       errmsg ("eid addresses not set");
13623       return -99;
13624     }
13625
13626   /* Construct the API message */
13627   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13628
13629   mp->is_add = is_add;
13630   if (ipv6_set)
13631     {
13632       mp->is_ipv6 = 1;
13633       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13634     }
13635   else
13636     {
13637       mp->is_ipv6 = 0;
13638       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13639     }
13640
13641   /* send it... */
13642   S;
13643
13644   /* Wait for a reply... */
13645   W;
13646
13647   /* NOTREACHED */
13648   return 0;
13649 }
13650
13651 static int
13652 api_lisp_add_del_map_resolver (vat_main_t * vam)
13653 {
13654   unformat_input_t *input = vam->input;
13655   vl_api_lisp_add_del_map_resolver_t *mp;
13656   f64 timeout = ~0;
13657   u8 is_add = 1;
13658   u8 ipv4_set = 0;
13659   u8 ipv6_set = 0;
13660   ip4_address_t ipv4;
13661   ip6_address_t ipv6;
13662
13663   /* Parse args required to build the message */
13664   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13665     {
13666       if (unformat (input, "del"))
13667         {
13668           is_add = 0;
13669         }
13670       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13671         {
13672           ipv4_set = 1;
13673         }
13674       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13675         {
13676           ipv6_set = 1;
13677         }
13678       else
13679         break;
13680     }
13681
13682   if (ipv4_set && ipv6_set)
13683     {
13684       errmsg ("both eid v4 and v6 addresses set");
13685       return -99;
13686     }
13687
13688   if (!ipv4_set && !ipv6_set)
13689     {
13690       errmsg ("eid addresses not set");
13691       return -99;
13692     }
13693
13694   /* Construct the API message */
13695   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13696
13697   mp->is_add = is_add;
13698   if (ipv6_set)
13699     {
13700       mp->is_ipv6 = 1;
13701       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13702     }
13703   else
13704     {
13705       mp->is_ipv6 = 0;
13706       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13707     }
13708
13709   /* send it... */
13710   S;
13711
13712   /* Wait for a reply... */
13713   W;
13714
13715   /* NOTREACHED */
13716   return 0;
13717 }
13718
13719 static int
13720 api_lisp_gpe_enable_disable (vat_main_t * vam)
13721 {
13722   unformat_input_t *input = vam->input;
13723   vl_api_lisp_gpe_enable_disable_t *mp;
13724   f64 timeout = ~0;
13725   u8 is_set = 0;
13726   u8 is_en = 1;
13727
13728   /* Parse args required to build the message */
13729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13730     {
13731       if (unformat (input, "enable"))
13732         {
13733           is_set = 1;
13734           is_en = 1;
13735         }
13736       else if (unformat (input, "disable"))
13737         {
13738           is_set = 1;
13739           is_en = 0;
13740         }
13741       else
13742         break;
13743     }
13744
13745   if (is_set == 0)
13746     {
13747       errmsg ("Value not set");
13748       return -99;
13749     }
13750
13751   /* Construct the API message */
13752   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13753
13754   mp->is_en = is_en;
13755
13756   /* send it... */
13757   S;
13758
13759   /* Wait for a reply... */
13760   W;
13761
13762   /* NOTREACHED */
13763   return 0;
13764 }
13765
13766 static int
13767 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13768 {
13769   unformat_input_t *input = vam->input;
13770   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13771   f64 timeout = ~0;
13772   u8 is_set = 0;
13773   u8 is_en = 0;
13774
13775   /* Parse args required to build the message */
13776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13777     {
13778       if (unformat (input, "enable"))
13779         {
13780           is_set = 1;
13781           is_en = 1;
13782         }
13783       else if (unformat (input, "disable"))
13784         is_set = 1;
13785       else
13786         break;
13787     }
13788
13789   if (!is_set)
13790     {
13791       errmsg ("Value not set");
13792       return -99;
13793     }
13794
13795   /* Construct the API message */
13796   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13797
13798   mp->is_enabled = is_en;
13799
13800   /* send it... */
13801   S;
13802
13803   /* Wait for a reply... */
13804   W;
13805
13806   /* NOTREACHED */
13807   return 0;
13808 }
13809
13810 static int
13811 api_lisp_map_register_enable_disable (vat_main_t * vam)
13812 {
13813   unformat_input_t *input = vam->input;
13814   vl_api_lisp_map_register_enable_disable_t *mp;
13815   f64 timeout = ~0;
13816   u8 is_set = 0;
13817   u8 is_en = 0;
13818
13819   /* Parse args required to build the message */
13820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13821     {
13822       if (unformat (input, "enable"))
13823         {
13824           is_set = 1;
13825           is_en = 1;
13826         }
13827       else if (unformat (input, "disable"))
13828         is_set = 1;
13829       else
13830         break;
13831     }
13832
13833   if (!is_set)
13834     {
13835       errmsg ("Value not set");
13836       return -99;
13837     }
13838
13839   /* Construct the API message */
13840   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13841
13842   mp->is_enabled = is_en;
13843
13844   /* send it... */
13845   S;
13846
13847   /* Wait for a reply... */
13848   W;
13849
13850   /* NOTREACHED */
13851   return 0;
13852 }
13853
13854 static int
13855 api_lisp_enable_disable (vat_main_t * vam)
13856 {
13857   unformat_input_t *input = vam->input;
13858   vl_api_lisp_enable_disable_t *mp;
13859   f64 timeout = ~0;
13860   u8 is_set = 0;
13861   u8 is_en = 0;
13862
13863   /* Parse args required to build the message */
13864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13865     {
13866       if (unformat (input, "enable"))
13867         {
13868           is_set = 1;
13869           is_en = 1;
13870         }
13871       else if (unformat (input, "disable"))
13872         {
13873           is_set = 1;
13874         }
13875       else
13876         break;
13877     }
13878
13879   if (!is_set)
13880     {
13881       errmsg ("Value not set");
13882       return -99;
13883     }
13884
13885   /* Construct the API message */
13886   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13887
13888   mp->is_en = is_en;
13889
13890   /* send it... */
13891   S;
13892
13893   /* Wait for a reply... */
13894   W;
13895
13896   /* NOTREACHED */
13897   return 0;
13898 }
13899
13900 static int
13901 api_show_lisp_map_register_state (vat_main_t * vam)
13902 {
13903   f64 timeout = ~0;
13904   vl_api_show_lisp_map_register_state_t *mp;
13905
13906   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13907
13908   /* send */
13909   S;
13910
13911   /* wait for reply */
13912   W;
13913
13914   return 0;
13915 }
13916
13917 static int
13918 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13919 {
13920   f64 timeout = ~0;
13921   vl_api_show_lisp_rloc_probe_state_t *mp;
13922
13923   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13924
13925   /* send */
13926   S;
13927
13928   /* wait for reply */
13929   W;
13930
13931   return 0;
13932 }
13933
13934 static int
13935 api_show_lisp_map_request_mode (vat_main_t * vam)
13936 {
13937   f64 timeout = ~0;
13938   vl_api_show_lisp_map_request_mode_t *mp;
13939
13940   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13941
13942   /* send */
13943   S;
13944
13945   /* wait for reply */
13946   W;
13947
13948   return 0;
13949 }
13950
13951 static int
13952 api_lisp_map_request_mode (vat_main_t * vam)
13953 {
13954   f64 timeout = ~0;
13955   unformat_input_t *input = vam->input;
13956   vl_api_lisp_map_request_mode_t *mp;
13957   u8 mode = 0;
13958
13959   /* Parse args required to build the message */
13960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13961     {
13962       if (unformat (input, "dst-only"))
13963         mode = 0;
13964       else if (unformat (input, "src-dst"))
13965         mode = 1;
13966       else
13967         {
13968           errmsg ("parse error '%U'", format_unformat_error, input);
13969           return -99;
13970         }
13971     }
13972
13973   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13974
13975   mp->mode = mode;
13976
13977   /* send */
13978   S;
13979
13980   /* wait for reply */
13981   W;
13982
13983   /* notreached */
13984   return 0;
13985 }
13986
13987 /**
13988  * Enable/disable LISP proxy ITR.
13989  *
13990  * @param vam vpp API test context
13991  * @return return code
13992  */
13993 static int
13994 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13995 {
13996   f64 timeout = ~0;
13997   u8 ls_name_set = 0;
13998   unformat_input_t *input = vam->input;
13999   vl_api_lisp_pitr_set_locator_set_t *mp;
14000   u8 is_add = 1;
14001   u8 *ls_name = 0;
14002
14003   /* Parse args required to build the message */
14004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14005     {
14006       if (unformat (input, "del"))
14007         is_add = 0;
14008       else if (unformat (input, "locator-set %s", &ls_name))
14009         ls_name_set = 1;
14010       else
14011         {
14012           errmsg ("parse error '%U'", format_unformat_error, input);
14013           return -99;
14014         }
14015     }
14016
14017   if (!ls_name_set)
14018     {
14019       errmsg ("locator-set name not set!");
14020       return -99;
14021     }
14022
14023   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
14024
14025   mp->is_add = is_add;
14026   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14027   vec_free (ls_name);
14028
14029   /* send */
14030   S;
14031
14032   /* wait for reply */
14033   W;
14034
14035   /* notreached */
14036   return 0;
14037 }
14038
14039 static int
14040 api_show_lisp_pitr (vat_main_t * vam)
14041 {
14042   vl_api_show_lisp_pitr_t *mp;
14043   f64 timeout = ~0;
14044
14045   if (!vam->json_output)
14046     {
14047       print (vam->ofp, "%=20s", "lisp status:");
14048     }
14049
14050   M (SHOW_LISP_PITR, show_lisp_pitr);
14051   /* send it... */
14052   S;
14053
14054   /* Wait for a reply... */
14055   W;
14056
14057   /* NOTREACHED */
14058   return 0;
14059 }
14060
14061 /**
14062  * Add/delete mapping between vni and vrf
14063  */
14064 static int
14065 api_lisp_eid_table_add_del_map (vat_main_t * vam)
14066 {
14067   f64 timeout = ~0;
14068   unformat_input_t *input = vam->input;
14069   vl_api_lisp_eid_table_add_del_map_t *mp;
14070   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14071   u32 vni, vrf, bd_index;
14072
14073   /* Parse args required to build the message */
14074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14075     {
14076       if (unformat (input, "del"))
14077         is_add = 0;
14078       else if (unformat (input, "vrf %d", &vrf))
14079         vrf_set = 1;
14080       else if (unformat (input, "bd_index %d", &bd_index))
14081         bd_index_set = 1;
14082       else if (unformat (input, "vni %d", &vni))
14083         vni_set = 1;
14084       else
14085         break;
14086     }
14087
14088   if (!vni_set || (!vrf_set && !bd_index_set))
14089     {
14090       errmsg ("missing arguments!");
14091       return -99;
14092     }
14093
14094   if (vrf_set && bd_index_set)
14095     {
14096       errmsg ("error: both vrf and bd entered!");
14097       return -99;
14098     }
14099
14100   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
14101
14102   mp->is_add = is_add;
14103   mp->vni = htonl (vni);
14104   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14105   mp->is_l2 = bd_index_set;
14106
14107   /* send */
14108   S;
14109
14110   /* wait for reply */
14111   W;
14112
14113   /* notreached */
14114   return 0;
14115 }
14116
14117 uword
14118 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14119 {
14120   u32 *action = va_arg (*args, u32 *);
14121   u8 *s = 0;
14122
14123   if (unformat (input, "%s", &s))
14124     {
14125       if (!strcmp ((char *) s, "no-action"))
14126         action[0] = 0;
14127       else if (!strcmp ((char *) s, "natively-forward"))
14128         action[0] = 1;
14129       else if (!strcmp ((char *) s, "send-map-request"))
14130         action[0] = 2;
14131       else if (!strcmp ((char *) s, "drop"))
14132         action[0] = 3;
14133       else
14134         {
14135           clib_warning ("invalid action: '%s'", s);
14136           action[0] = 3;
14137         }
14138     }
14139   else
14140     return 0;
14141
14142   vec_free (s);
14143   return 1;
14144 }
14145
14146 /**
14147  * Add/del remote mapping to/from LISP control plane
14148  *
14149  * @param vam vpp API test context
14150  * @return return code
14151  */
14152 static int
14153 api_lisp_add_del_remote_mapping (vat_main_t * vam)
14154 {
14155   unformat_input_t *input = vam->input;
14156   vl_api_lisp_add_del_remote_mapping_t *mp;
14157   f64 timeout = ~0;
14158   u32 vni = 0;
14159   lisp_eid_vat_t _eid, *eid = &_eid;
14160   lisp_eid_vat_t _seid, *seid = &_seid;
14161   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14162   u32 action = ~0, p, w, data_len;
14163   ip4_address_t rloc4;
14164   ip6_address_t rloc6;
14165   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
14166
14167   memset (&rloc, 0, sizeof (rloc));
14168
14169   /* Parse args required to build the message */
14170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14171     {
14172       if (unformat (input, "del-all"))
14173         {
14174           del_all = 1;
14175         }
14176       else if (unformat (input, "del"))
14177         {
14178           is_add = 0;
14179         }
14180       else if (unformat (input, "add"))
14181         {
14182           is_add = 1;
14183         }
14184       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14185         {
14186           eid_set = 1;
14187         }
14188       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14189         {
14190           seid_set = 1;
14191         }
14192       else if (unformat (input, "vni %d", &vni))
14193         {
14194           ;
14195         }
14196       else if (unformat (input, "p %d w %d", &p, &w))
14197         {
14198           if (!curr_rloc)
14199             {
14200               errmsg ("No RLOC configured for setting priority/weight!");
14201               return -99;
14202             }
14203           curr_rloc->priority = p;
14204           curr_rloc->weight = w;
14205         }
14206       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14207         {
14208           rloc.is_ip4 = 1;
14209           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14210           vec_add1 (rlocs, rloc);
14211           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14212         }
14213       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14214         {
14215           rloc.is_ip4 = 0;
14216           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14217           vec_add1 (rlocs, rloc);
14218           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14219         }
14220       else if (unformat (input, "action %U",
14221                          unformat_negative_mapping_action, &action))
14222         {
14223           ;
14224         }
14225       else
14226         {
14227           clib_warning ("parse error '%U'", format_unformat_error, input);
14228           return -99;
14229         }
14230     }
14231
14232   if (0 == eid_set)
14233     {
14234       errmsg ("missing params!");
14235       return -99;
14236     }
14237
14238   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14239     {
14240       errmsg ("no action set for negative map-reply!");
14241       return -99;
14242     }
14243
14244   data_len = vec_len (rlocs) * sizeof (rloc_t);
14245
14246   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14247   mp->is_add = is_add;
14248   mp->vni = htonl (vni);
14249   mp->action = (u8) action;
14250   mp->is_src_dst = seid_set;
14251   mp->eid_len = eid->len;
14252   mp->seid_len = seid->len;
14253   mp->del_all = del_all;
14254   mp->eid_type = eid->type;
14255   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14256   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14257
14258   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14259   clib_memcpy (mp->rlocs, rlocs, data_len);
14260   vec_free (rlocs);
14261
14262   /* send it... */
14263   S;
14264
14265   /* Wait for a reply... */
14266   W;
14267
14268   /* NOTREACHED */
14269   return 0;
14270 }
14271
14272 /**
14273  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14274  * forwarding entries in data-plane accordingly.
14275  *
14276  * @param vam vpp API test context
14277  * @return return code
14278  */
14279 static int
14280 api_lisp_add_del_adjacency (vat_main_t * vam)
14281 {
14282   unformat_input_t *input = vam->input;
14283   vl_api_lisp_add_del_adjacency_t *mp;
14284   f64 timeout = ~0;
14285   u32 vni = 0;
14286   ip4_address_t leid4, reid4;
14287   ip6_address_t leid6, reid6;
14288   u8 reid_mac[6] = { 0 };
14289   u8 leid_mac[6] = { 0 };
14290   u8 reid_type, leid_type;
14291   u32 leid_len = 0, reid_len = 0, len;
14292   u8 is_add = 1;
14293
14294   leid_type = reid_type = (u8) ~ 0;
14295
14296   /* Parse args required to build the message */
14297   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14298     {
14299       if (unformat (input, "del"))
14300         {
14301           is_add = 0;
14302         }
14303       else if (unformat (input, "add"))
14304         {
14305           is_add = 1;
14306         }
14307       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14308                          &reid4, &len))
14309         {
14310           reid_type = 0;        /* ipv4 */
14311           reid_len = len;
14312         }
14313       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14314                          &reid6, &len))
14315         {
14316           reid_type = 1;        /* ipv6 */
14317           reid_len = len;
14318         }
14319       else if (unformat (input, "reid %U", unformat_ethernet_address,
14320                          reid_mac))
14321         {
14322           reid_type = 2;        /* mac */
14323         }
14324       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14325                          &leid4, &len))
14326         {
14327           leid_type = 0;        /* ipv4 */
14328           leid_len = len;
14329         }
14330       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14331                          &leid6, &len))
14332         {
14333           leid_type = 1;        /* ipv6 */
14334           leid_len = len;
14335         }
14336       else if (unformat (input, "leid %U", unformat_ethernet_address,
14337                          leid_mac))
14338         {
14339           leid_type = 2;        /* mac */
14340         }
14341       else if (unformat (input, "vni %d", &vni))
14342         {
14343           ;
14344         }
14345       else
14346         {
14347           errmsg ("parse error '%U'", format_unformat_error, input);
14348           return -99;
14349         }
14350     }
14351
14352   if ((u8) ~ 0 == reid_type)
14353     {
14354       errmsg ("missing params!");
14355       return -99;
14356     }
14357
14358   if (leid_type != reid_type)
14359     {
14360       errmsg ("remote and local EIDs are of different types!");
14361       return -99;
14362     }
14363
14364   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14365   mp->is_add = is_add;
14366   mp->vni = htonl (vni);
14367   mp->leid_len = leid_len;
14368   mp->reid_len = reid_len;
14369   mp->eid_type = reid_type;
14370
14371   switch (mp->eid_type)
14372     {
14373     case 0:
14374       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14375       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14376       break;
14377     case 1:
14378       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14379       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14380       break;
14381     case 2:
14382       clib_memcpy (mp->leid, leid_mac, 6);
14383       clib_memcpy (mp->reid, reid_mac, 6);
14384       break;
14385     default:
14386       errmsg ("unknown EID type %d!", mp->eid_type);
14387       return 0;
14388     }
14389
14390   /* send it... */
14391   S;
14392
14393   /* Wait for a reply... */
14394   W;
14395
14396   /* NOTREACHED */
14397   return 0;
14398 }
14399
14400 static int
14401 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14402 {
14403   unformat_input_t *input = vam->input;
14404   vl_api_lisp_gpe_add_del_iface_t *mp;
14405   f64 timeout = ~0;
14406   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14407   u32 dp_table = 0, vni = 0;
14408
14409   /* Parse args required to build the message */
14410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14411     {
14412       if (unformat (input, "up"))
14413         {
14414           action_set = 1;
14415           is_add = 1;
14416         }
14417       else if (unformat (input, "down"))
14418         {
14419           action_set = 1;
14420           is_add = 0;
14421         }
14422       else if (unformat (input, "table_id %d", &dp_table))
14423         {
14424           dp_table_set = 1;
14425         }
14426       else if (unformat (input, "bd_id %d", &dp_table))
14427         {
14428           dp_table_set = 1;
14429           is_l2 = 1;
14430         }
14431       else if (unformat (input, "vni %d", &vni))
14432         {
14433           vni_set = 1;
14434         }
14435       else
14436         break;
14437     }
14438
14439   if (action_set == 0)
14440     {
14441       errmsg ("Action not set");
14442       return -99;
14443     }
14444   if (dp_table_set == 0 || vni_set == 0)
14445     {
14446       errmsg ("vni and dp_table must be set");
14447       return -99;
14448     }
14449
14450   /* Construct the API message */
14451   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14452
14453   mp->is_add = is_add;
14454   mp->dp_table = dp_table;
14455   mp->is_l2 = is_l2;
14456   mp->vni = vni;
14457
14458   /* send it... */
14459   S;
14460
14461   /* Wait for a reply... */
14462   W;
14463
14464   /* NOTREACHED */
14465   return 0;
14466 }
14467
14468 /**
14469  * Add/del map request itr rlocs from LISP control plane and updates
14470  *
14471  * @param vam vpp API test context
14472  * @return return code
14473  */
14474 static int
14475 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14476 {
14477   unformat_input_t *input = vam->input;
14478   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14479   f64 timeout = ~0;
14480   u8 *locator_set_name = 0;
14481   u8 locator_set_name_set = 0;
14482   u8 is_add = 1;
14483
14484   /* Parse args required to build the message */
14485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14486     {
14487       if (unformat (input, "del"))
14488         {
14489           is_add = 0;
14490         }
14491       else if (unformat (input, "%_%v%_", &locator_set_name))
14492         {
14493           locator_set_name_set = 1;
14494         }
14495       else
14496         {
14497           clib_warning ("parse error '%U'", format_unformat_error, input);
14498           return -99;
14499         }
14500     }
14501
14502   if (is_add && !locator_set_name_set)
14503     {
14504       errmsg ("itr-rloc is not set!");
14505       return -99;
14506     }
14507
14508   if (is_add && vec_len (locator_set_name) > 64)
14509     {
14510       errmsg ("itr-rloc locator-set name too long");
14511       vec_free (locator_set_name);
14512       return -99;
14513     }
14514
14515   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14516   mp->is_add = is_add;
14517   if (is_add)
14518     {
14519       clib_memcpy (mp->locator_set_name, locator_set_name,
14520                    vec_len (locator_set_name));
14521     }
14522   else
14523     {
14524       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14525     }
14526   vec_free (locator_set_name);
14527
14528   /* send it... */
14529   S;
14530
14531   /* Wait for a reply... */
14532   W;
14533
14534   /* NOTREACHED */
14535   return 0;
14536 }
14537
14538 static int
14539 api_lisp_locator_dump (vat_main_t * vam)
14540 {
14541   unformat_input_t *input = vam->input;
14542   vl_api_lisp_locator_dump_t *mp;
14543   f64 timeout = ~0;
14544   u8 is_index_set = 0, is_name_set = 0;
14545   u8 *ls_name = 0;
14546   u32 ls_index = ~0;
14547
14548   /* Parse args required to build the message */
14549   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14550     {
14551       if (unformat (input, "ls_name %_%v%_", &ls_name))
14552         {
14553           is_name_set = 1;
14554         }
14555       else if (unformat (input, "ls_index %d", &ls_index))
14556         {
14557           is_index_set = 1;
14558         }
14559       else
14560         {
14561           errmsg ("parse error '%U'", format_unformat_error, input);
14562           return -99;
14563         }
14564     }
14565
14566   if (!is_index_set && !is_name_set)
14567     {
14568       errmsg ("error: expected one of index or name!");
14569       return -99;
14570     }
14571
14572   if (is_index_set && is_name_set)
14573     {
14574       errmsg ("error: only one param expected!");
14575       return -99;
14576     }
14577
14578   if (vec_len (ls_name) > 62)
14579     {
14580       errmsg ("error: locator set name too long!");
14581       return -99;
14582     }
14583
14584   if (!vam->json_output)
14585     {
14586       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14587     }
14588
14589   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14590   mp->is_index_set = is_index_set;
14591
14592   if (is_index_set)
14593     mp->ls_index = clib_host_to_net_u32 (ls_index);
14594   else
14595     {
14596       vec_add1 (ls_name, 0);
14597       strncpy ((char *) mp->ls_name, (char *) ls_name,
14598                sizeof (mp->ls_name) - 1);
14599     }
14600
14601   /* send it... */
14602   S;
14603
14604   /* Use a control ping for synchronization */
14605   {
14606     vl_api_control_ping_t *mp;
14607     M (CONTROL_PING, control_ping);
14608     S;
14609   }
14610   /* Wait for a reply... */
14611   W;
14612
14613   /* NOTREACHED */
14614   return 0;
14615 }
14616
14617 static int
14618 api_lisp_locator_set_dump (vat_main_t * vam)
14619 {
14620   vl_api_lisp_locator_set_dump_t *mp;
14621   unformat_input_t *input = vam->input;
14622   f64 timeout = ~0;
14623   u8 filter = 0;
14624
14625   /* Parse args required to build the message */
14626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14627     {
14628       if (unformat (input, "local"))
14629         {
14630           filter = 1;
14631         }
14632       else if (unformat (input, "remote"))
14633         {
14634           filter = 2;
14635         }
14636       else
14637         {
14638           errmsg ("parse error '%U'", format_unformat_error, input);
14639           return -99;
14640         }
14641     }
14642
14643   if (!vam->json_output)
14644     {
14645       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14646     }
14647
14648   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14649
14650   mp->filter = filter;
14651
14652   /* send it... */
14653   S;
14654
14655   /* Use a control ping for synchronization */
14656   {
14657     vl_api_control_ping_t *mp;
14658     M (CONTROL_PING, control_ping);
14659     S;
14660   }
14661   /* Wait for a reply... */
14662   W;
14663
14664   /* NOTREACHED */
14665   return 0;
14666 }
14667
14668 static int
14669 api_lisp_eid_table_map_dump (vat_main_t * vam)
14670 {
14671   u8 is_l2 = 0;
14672   u8 mode_set = 0;
14673   unformat_input_t *input = vam->input;
14674   vl_api_lisp_eid_table_map_dump_t *mp;
14675   f64 timeout = ~0;
14676
14677   /* Parse args required to build the message */
14678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (input, "l2"))
14681         {
14682           is_l2 = 1;
14683           mode_set = 1;
14684         }
14685       else if (unformat (input, "l3"))
14686         {
14687           is_l2 = 0;
14688           mode_set = 1;
14689         }
14690       else
14691         {
14692           errmsg ("parse error '%U'", format_unformat_error, input);
14693           return -99;
14694         }
14695     }
14696
14697   if (!mode_set)
14698     {
14699       errmsg ("expected one of 'l2' or 'l3' parameter!");
14700       return -99;
14701     }
14702
14703   if (!vam->json_output)
14704     {
14705       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14706     }
14707
14708   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14709   mp->is_l2 = is_l2;
14710
14711   /* send it... */
14712   S;
14713
14714   /* Use a control ping for synchronization */
14715   {
14716     vl_api_control_ping_t *mp;
14717     M (CONTROL_PING, control_ping);
14718     S;
14719   }
14720   /* Wait for a reply... */
14721   W;
14722
14723   /* NOTREACHED */
14724   return 0;
14725 }
14726
14727 static int
14728 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14729 {
14730   vl_api_lisp_eid_table_vni_dump_t *mp;
14731   f64 timeout = ~0;
14732
14733   if (!vam->json_output)
14734     {
14735       print (vam->ofp, "VNI");
14736     }
14737
14738   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14739
14740   /* send it... */
14741   S;
14742
14743   /* Use a control ping for synchronization */
14744   {
14745     vl_api_control_ping_t *mp;
14746     M (CONTROL_PING, control_ping);
14747     S;
14748   }
14749   /* Wait for a reply... */
14750   W;
14751
14752   /* NOTREACHED */
14753   return 0;
14754 }
14755
14756 static int
14757 api_lisp_eid_table_dump (vat_main_t * vam)
14758 {
14759   unformat_input_t *i = vam->input;
14760   vl_api_lisp_eid_table_dump_t *mp;
14761   f64 timeout = ~0;
14762   struct in_addr ip4;
14763   struct in6_addr ip6;
14764   u8 mac[6];
14765   u8 eid_type = ~0, eid_set = 0;
14766   u32 prefix_length = ~0, t, vni = 0;
14767   u8 filter = 0;
14768
14769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14770     {
14771       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14772         {
14773           eid_set = 1;
14774           eid_type = 0;
14775           prefix_length = t;
14776         }
14777       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14778         {
14779           eid_set = 1;
14780           eid_type = 1;
14781           prefix_length = t;
14782         }
14783       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14784         {
14785           eid_set = 1;
14786           eid_type = 2;
14787         }
14788       else if (unformat (i, "vni %d", &t))
14789         {
14790           vni = t;
14791         }
14792       else if (unformat (i, "local"))
14793         {
14794           filter = 1;
14795         }
14796       else if (unformat (i, "remote"))
14797         {
14798           filter = 2;
14799         }
14800       else
14801         {
14802           errmsg ("parse error '%U'", format_unformat_error, i);
14803           return -99;
14804         }
14805     }
14806
14807   if (!vam->json_output)
14808     {
14809       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14810              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14811     }
14812
14813   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14814
14815   mp->filter = filter;
14816   if (eid_set)
14817     {
14818       mp->eid_set = 1;
14819       mp->vni = htonl (vni);
14820       mp->eid_type = eid_type;
14821       switch (eid_type)
14822         {
14823         case 0:
14824           mp->prefix_length = prefix_length;
14825           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14826           break;
14827         case 1:
14828           mp->prefix_length = prefix_length;
14829           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14830           break;
14831         case 2:
14832           clib_memcpy (mp->eid, mac, sizeof (mac));
14833           break;
14834         default:
14835           errmsg ("unknown EID type %d!", eid_type);
14836           return -99;
14837         }
14838     }
14839
14840   /* send it... */
14841   S;
14842
14843   /* Use a control ping for synchronization */
14844   {
14845     vl_api_control_ping_t *mp;
14846     M (CONTROL_PING, control_ping);
14847     S;
14848   }
14849
14850   /* Wait for a reply... */
14851   W;
14852
14853   /* NOTREACHED */
14854   return 0;
14855 }
14856
14857 static int
14858 api_lisp_adjacencies_get (vat_main_t * vam)
14859 {
14860   unformat_input_t *i = vam->input;
14861   vl_api_lisp_adjacencies_get_t *mp;
14862   f64 timeout = ~0;
14863   u8 vni_set = 0;
14864   u32 vni = ~0;
14865
14866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14867     {
14868       if (unformat (i, "vni %d", &vni))
14869         {
14870           vni_set = 1;
14871         }
14872       else
14873         {
14874           errmsg ("parse error '%U'", format_unformat_error, i);
14875           return -99;
14876         }
14877     }
14878
14879   if (!vni_set)
14880     {
14881       errmsg ("vni not set!");
14882       return -99;
14883     }
14884
14885   if (!vam->json_output)
14886     {
14887       print (vam->ofp, "%s %40s", "leid", "reid");
14888     }
14889
14890   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14891   mp->vni = clib_host_to_net_u32 (vni);
14892
14893   /* send it... */
14894   S;
14895
14896   /* Wait for a reply... */
14897   W;
14898
14899   /* NOTREACHED */
14900   return 0;
14901 }
14902
14903 static int
14904 api_lisp_map_server_dump (vat_main_t * vam)
14905 {
14906   vl_api_lisp_map_server_dump_t *mp;
14907   f64 timeout = ~0;
14908
14909   if (!vam->json_output)
14910     {
14911       print (vam->ofp, "%=20s", "Map server");
14912     }
14913
14914   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14915   /* send it... */
14916   S;
14917
14918   /* Use a control ping for synchronization */
14919   {
14920     vl_api_control_ping_t *mp;
14921     M (CONTROL_PING, control_ping);
14922     S;
14923   }
14924   /* Wait for a reply... */
14925   W;
14926
14927   /* NOTREACHED */
14928   return 0;
14929 }
14930
14931 static int
14932 api_lisp_map_resolver_dump (vat_main_t * vam)
14933 {
14934   vl_api_lisp_map_resolver_dump_t *mp;
14935   f64 timeout = ~0;
14936
14937   if (!vam->json_output)
14938     {
14939       print (vam->ofp, "%=20s", "Map resolver");
14940     }
14941
14942   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14943   /* send it... */
14944   S;
14945
14946   /* Use a control ping for synchronization */
14947   {
14948     vl_api_control_ping_t *mp;
14949     M (CONTROL_PING, control_ping);
14950     S;
14951   }
14952   /* Wait for a reply... */
14953   W;
14954
14955   /* NOTREACHED */
14956   return 0;
14957 }
14958
14959 static int
14960 api_show_lisp_status (vat_main_t * vam)
14961 {
14962   vl_api_show_lisp_status_t *mp;
14963   f64 timeout = ~0;
14964
14965   if (!vam->json_output)
14966     {
14967       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14968     }
14969
14970   M (SHOW_LISP_STATUS, show_lisp_status);
14971   /* send it... */
14972   S;
14973   /* Wait for a reply... */
14974   W;
14975
14976   /* NOTREACHED */
14977   return 0;
14978 }
14979
14980 static int
14981 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14982 {
14983   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14984   f64 timeout = ~0;
14985
14986   if (!vam->json_output)
14987     {
14988       print (vam->ofp, "%=20s", "itr-rlocs:");
14989     }
14990
14991   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14992   /* send it... */
14993   S;
14994   /* Wait for a reply... */
14995   W;
14996
14997   /* NOTREACHED */
14998   return 0;
14999 }
15000
15001 static int
15002 api_af_packet_create (vat_main_t * vam)
15003 {
15004   unformat_input_t *i = vam->input;
15005   vl_api_af_packet_create_t *mp;
15006   f64 timeout;
15007   u8 *host_if_name = 0;
15008   u8 hw_addr[6];
15009   u8 random_hw_addr = 1;
15010
15011   memset (hw_addr, 0, sizeof (hw_addr));
15012
15013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15014     {
15015       if (unformat (i, "name %s", &host_if_name))
15016         vec_add1 (host_if_name, 0);
15017       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15018         random_hw_addr = 0;
15019       else
15020         break;
15021     }
15022
15023   if (!vec_len (host_if_name))
15024     {
15025       errmsg ("host-interface name must be specified");
15026       return -99;
15027     }
15028
15029   if (vec_len (host_if_name) > 64)
15030     {
15031       errmsg ("host-interface name too long");
15032       return -99;
15033     }
15034
15035   M (AF_PACKET_CREATE, af_packet_create);
15036
15037   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15038   clib_memcpy (mp->hw_addr, hw_addr, 6);
15039   mp->use_random_hw_addr = random_hw_addr;
15040   vec_free (host_if_name);
15041
15042   S;
15043   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15044   /* NOTREACHED */
15045   return 0;
15046 }
15047
15048 static int
15049 api_af_packet_delete (vat_main_t * vam)
15050 {
15051   unformat_input_t *i = vam->input;
15052   vl_api_af_packet_delete_t *mp;
15053   f64 timeout;
15054   u8 *host_if_name = 0;
15055
15056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15057     {
15058       if (unformat (i, "name %s", &host_if_name))
15059         vec_add1 (host_if_name, 0);
15060       else
15061         break;
15062     }
15063
15064   if (!vec_len (host_if_name))
15065     {
15066       errmsg ("host-interface name must be specified");
15067       return -99;
15068     }
15069
15070   if (vec_len (host_if_name) > 64)
15071     {
15072       errmsg ("host-interface name too long");
15073       return -99;
15074     }
15075
15076   M (AF_PACKET_DELETE, af_packet_delete);
15077
15078   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15079   vec_free (host_if_name);
15080
15081   S;
15082   W;
15083   /* NOTREACHED */
15084   return 0;
15085 }
15086
15087 static int
15088 api_policer_add_del (vat_main_t * vam)
15089 {
15090   unformat_input_t *i = vam->input;
15091   vl_api_policer_add_del_t *mp;
15092   f64 timeout;
15093   u8 is_add = 1;
15094   u8 *name = 0;
15095   u32 cir = 0;
15096   u32 eir = 0;
15097   u64 cb = 0;
15098   u64 eb = 0;
15099   u8 rate_type = 0;
15100   u8 round_type = 0;
15101   u8 type = 0;
15102   u8 color_aware = 0;
15103   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15104
15105   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15106   conform_action.dscp = 0;
15107   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15108   exceed_action.dscp = 0;
15109   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15110   violate_action.dscp = 0;
15111
15112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15113     {
15114       if (unformat (i, "del"))
15115         is_add = 0;
15116       else if (unformat (i, "name %s", &name))
15117         vec_add1 (name, 0);
15118       else if (unformat (i, "cir %u", &cir))
15119         ;
15120       else if (unformat (i, "eir %u", &eir))
15121         ;
15122       else if (unformat (i, "cb %u", &cb))
15123         ;
15124       else if (unformat (i, "eb %u", &eb))
15125         ;
15126       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15127                          &rate_type))
15128         ;
15129       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15130                          &round_type))
15131         ;
15132       else if (unformat (i, "type %U", unformat_policer_type, &type))
15133         ;
15134       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15135                          &conform_action))
15136         ;
15137       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15138                          &exceed_action))
15139         ;
15140       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15141                          &violate_action))
15142         ;
15143       else if (unformat (i, "color-aware"))
15144         color_aware = 1;
15145       else
15146         break;
15147     }
15148
15149   if (!vec_len (name))
15150     {
15151       errmsg ("policer name must be specified");
15152       return -99;
15153     }
15154
15155   if (vec_len (name) > 64)
15156     {
15157       errmsg ("policer name too long");
15158       return -99;
15159     }
15160
15161   M (POLICER_ADD_DEL, policer_add_del);
15162
15163   clib_memcpy (mp->name, name, vec_len (name));
15164   vec_free (name);
15165   mp->is_add = is_add;
15166   mp->cir = cir;
15167   mp->eir = eir;
15168   mp->cb = cb;
15169   mp->eb = eb;
15170   mp->rate_type = rate_type;
15171   mp->round_type = round_type;
15172   mp->type = type;
15173   mp->conform_action_type = conform_action.action_type;
15174   mp->conform_dscp = conform_action.dscp;
15175   mp->exceed_action_type = exceed_action.action_type;
15176   mp->exceed_dscp = exceed_action.dscp;
15177   mp->violate_action_type = violate_action.action_type;
15178   mp->violate_dscp = violate_action.dscp;
15179   mp->color_aware = color_aware;
15180
15181   S;
15182   W;
15183   /* NOTREACHED */
15184   return 0;
15185 }
15186
15187 static int
15188 api_policer_dump (vat_main_t * vam)
15189 {
15190   unformat_input_t *i = vam->input;
15191   vl_api_policer_dump_t *mp;
15192   f64 timeout = ~0;
15193   u8 *match_name = 0;
15194   u8 match_name_valid = 0;
15195
15196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15197     {
15198       if (unformat (i, "name %s", &match_name))
15199         {
15200           vec_add1 (match_name, 0);
15201           match_name_valid = 1;
15202         }
15203       else
15204         break;
15205     }
15206
15207   M (POLICER_DUMP, policer_dump);
15208   mp->match_name_valid = match_name_valid;
15209   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15210   vec_free (match_name);
15211   /* send it... */
15212   S;
15213
15214   /* Use a control ping for synchronization */
15215   {
15216     vl_api_control_ping_t *mp;
15217     M (CONTROL_PING, control_ping);
15218     S;
15219   }
15220   /* Wait for a reply... */
15221   W;
15222
15223   /* NOTREACHED */
15224   return 0;
15225 }
15226
15227 static int
15228 api_policer_classify_set_interface (vat_main_t * vam)
15229 {
15230   unformat_input_t *i = vam->input;
15231   vl_api_policer_classify_set_interface_t *mp;
15232   f64 timeout;
15233   u32 sw_if_index;
15234   int sw_if_index_set;
15235   u32 ip4_table_index = ~0;
15236   u32 ip6_table_index = ~0;
15237   u32 l2_table_index = ~0;
15238   u8 is_add = 1;
15239
15240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15241     {
15242       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15243         sw_if_index_set = 1;
15244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15245         sw_if_index_set = 1;
15246       else if (unformat (i, "del"))
15247         is_add = 0;
15248       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15249         ;
15250       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15251         ;
15252       else if (unformat (i, "l2-table %d", &l2_table_index))
15253         ;
15254       else
15255         {
15256           clib_warning ("parse error '%U'", format_unformat_error, i);
15257           return -99;
15258         }
15259     }
15260
15261   if (sw_if_index_set == 0)
15262     {
15263       errmsg ("missing interface name or sw_if_index");
15264       return -99;
15265     }
15266
15267   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15268
15269   mp->sw_if_index = ntohl (sw_if_index);
15270   mp->ip4_table_index = ntohl (ip4_table_index);
15271   mp->ip6_table_index = ntohl (ip6_table_index);
15272   mp->l2_table_index = ntohl (l2_table_index);
15273   mp->is_add = is_add;
15274
15275   S;
15276   W;
15277   /* NOTREACHED */
15278   return 0;
15279 }
15280
15281 static int
15282 api_policer_classify_dump (vat_main_t * vam)
15283 {
15284   unformat_input_t *i = vam->input;
15285   vl_api_policer_classify_dump_t *mp;
15286   f64 timeout = ~0;
15287   u8 type = POLICER_CLASSIFY_N_TABLES;
15288
15289   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15290     ;
15291   else
15292     {
15293       errmsg ("classify table type must be specified");
15294       return -99;
15295     }
15296
15297   if (!vam->json_output)
15298     {
15299       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15300     }
15301
15302   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15303   mp->type = type;
15304   /* send it... */
15305   S;
15306
15307   /* Use a control ping for synchronization */
15308   {
15309     vl_api_control_ping_t *mp;
15310     M (CONTROL_PING, control_ping);
15311     S;
15312   }
15313   /* Wait for a reply... */
15314   W;
15315
15316   /* NOTREACHED */
15317   return 0;
15318 }
15319
15320 static int
15321 api_netmap_create (vat_main_t * vam)
15322 {
15323   unformat_input_t *i = vam->input;
15324   vl_api_netmap_create_t *mp;
15325   f64 timeout;
15326   u8 *if_name = 0;
15327   u8 hw_addr[6];
15328   u8 random_hw_addr = 1;
15329   u8 is_pipe = 0;
15330   u8 is_master = 0;
15331
15332   memset (hw_addr, 0, sizeof (hw_addr));
15333
15334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15335     {
15336       if (unformat (i, "name %s", &if_name))
15337         vec_add1 (if_name, 0);
15338       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15339         random_hw_addr = 0;
15340       else if (unformat (i, "pipe"))
15341         is_pipe = 1;
15342       else if (unformat (i, "master"))
15343         is_master = 1;
15344       else if (unformat (i, "slave"))
15345         is_master = 0;
15346       else
15347         break;
15348     }
15349
15350   if (!vec_len (if_name))
15351     {
15352       errmsg ("interface name must be specified");
15353       return -99;
15354     }
15355
15356   if (vec_len (if_name) > 64)
15357     {
15358       errmsg ("interface name too long");
15359       return -99;
15360     }
15361
15362   M (NETMAP_CREATE, netmap_create);
15363
15364   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15365   clib_memcpy (mp->hw_addr, hw_addr, 6);
15366   mp->use_random_hw_addr = random_hw_addr;
15367   mp->is_pipe = is_pipe;
15368   mp->is_master = is_master;
15369   vec_free (if_name);
15370
15371   S;
15372   W;
15373   /* NOTREACHED */
15374   return 0;
15375 }
15376
15377 static int
15378 api_netmap_delete (vat_main_t * vam)
15379 {
15380   unformat_input_t *i = vam->input;
15381   vl_api_netmap_delete_t *mp;
15382   f64 timeout;
15383   u8 *if_name = 0;
15384
15385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15386     {
15387       if (unformat (i, "name %s", &if_name))
15388         vec_add1 (if_name, 0);
15389       else
15390         break;
15391     }
15392
15393   if (!vec_len (if_name))
15394     {
15395       errmsg ("interface name must be specified");
15396       return -99;
15397     }
15398
15399   if (vec_len (if_name) > 64)
15400     {
15401       errmsg ("interface name too long");
15402       return -99;
15403     }
15404
15405   M (NETMAP_DELETE, netmap_delete);
15406
15407   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15408   vec_free (if_name);
15409
15410   S;
15411   W;
15412   /* NOTREACHED */
15413   return 0;
15414 }
15415
15416 static void vl_api_mpls_tunnel_details_t_handler
15417   (vl_api_mpls_tunnel_details_t * mp)
15418 {
15419   vat_main_t *vam = &vat_main;
15420   i32 len = mp->mt_next_hop_n_labels;
15421   i32 i;
15422
15423   print (vam->ofp, "[%d]: via %U %d labels ",
15424          mp->tunnel_index,
15425          format_ip4_address, mp->mt_next_hop,
15426          ntohl (mp->mt_next_hop_sw_if_index));
15427   for (i = 0; i < len; i++)
15428     {
15429       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15430     }
15431   print (vam->ofp, "");
15432 }
15433
15434 static void vl_api_mpls_tunnel_details_t_handler_json
15435   (vl_api_mpls_tunnel_details_t * mp)
15436 {
15437   vat_main_t *vam = &vat_main;
15438   vat_json_node_t *node = NULL;
15439   struct in_addr ip4;
15440   i32 i;
15441   i32 len = mp->mt_next_hop_n_labels;
15442
15443   if (VAT_JSON_ARRAY != vam->json_tree.type)
15444     {
15445       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15446       vat_json_init_array (&vam->json_tree);
15447     }
15448   node = vat_json_array_add (&vam->json_tree);
15449
15450   vat_json_init_object (node);
15451   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15452   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15453   vat_json_object_add_ip4 (node, "next_hop", ip4);
15454   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15455                             ntohl (mp->mt_next_hop_sw_if_index));
15456   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15457   vat_json_object_add_uint (node, "label_count", len);
15458   for (i = 0; i < len; i++)
15459     {
15460       vat_json_object_add_uint (node, "label",
15461                                 ntohl (mp->mt_next_hop_out_labels[i]));
15462     }
15463 }
15464
15465 static int
15466 api_mpls_tunnel_dump (vat_main_t * vam)
15467 {
15468   vl_api_mpls_tunnel_dump_t *mp;
15469   f64 timeout;
15470   i32 index = -1;
15471
15472   /* Parse args required to build the message */
15473   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15474     {
15475       if (!unformat (vam->input, "tunnel_index %d", &index))
15476         {
15477           index = -1;
15478           break;
15479         }
15480     }
15481
15482   print (vam->ofp, "  tunnel_index %d", index);
15483
15484   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15485   mp->tunnel_index = htonl (index);
15486   S;
15487
15488   /* Use a control ping for synchronization */
15489   {
15490     vl_api_control_ping_t *mp;
15491     M (CONTROL_PING, control_ping);
15492     S;
15493   }
15494   W;
15495 }
15496
15497 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15498 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15499
15500 static void
15501 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15502 {
15503   vat_main_t *vam = &vat_main;
15504   int count = ntohl (mp->count);
15505   vl_api_fib_path2_t *fp;
15506   int i;
15507
15508   print (vam->ofp,
15509          "table-id %d, label %u, ess_bit %u",
15510          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15511   fp = mp->path;
15512   for (i = 0; i < count; i++)
15513     {
15514       if (fp->afi == IP46_TYPE_IP6)
15515         print (vam->ofp,
15516                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15517                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15518                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15519                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15520                format_ip6_address, fp->next_hop);
15521       else if (fp->afi == IP46_TYPE_IP4)
15522         print (vam->ofp,
15523                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15524                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15525                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15526                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15527                format_ip4_address, fp->next_hop);
15528       fp++;
15529     }
15530 }
15531
15532 static void vl_api_mpls_fib_details_t_handler_json
15533   (vl_api_mpls_fib_details_t * mp)
15534 {
15535   vat_main_t *vam = &vat_main;
15536   int count = ntohl (mp->count);
15537   vat_json_node_t *node = NULL;
15538   struct in_addr ip4;
15539   struct in6_addr ip6;
15540   vl_api_fib_path2_t *fp;
15541   int i;
15542
15543   if (VAT_JSON_ARRAY != vam->json_tree.type)
15544     {
15545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15546       vat_json_init_array (&vam->json_tree);
15547     }
15548   node = vat_json_array_add (&vam->json_tree);
15549
15550   vat_json_init_object (node);
15551   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15552   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15553   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15554   vat_json_object_add_uint (node, "path_count", count);
15555   fp = mp->path;
15556   for (i = 0; i < count; i++)
15557     {
15558       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15559       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15560       vat_json_object_add_uint (node, "is_local", fp->is_local);
15561       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15562       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15563       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15564       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15565       if (fp->afi == IP46_TYPE_IP4)
15566         {
15567           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15568           vat_json_object_add_ip4 (node, "next_hop", ip4);
15569         }
15570       else if (fp->afi == IP46_TYPE_IP6)
15571         {
15572           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15573           vat_json_object_add_ip6 (node, "next_hop", ip6);
15574         }
15575     }
15576 }
15577
15578 static int
15579 api_mpls_fib_dump (vat_main_t * vam)
15580 {
15581   vl_api_mpls_fib_dump_t *mp;
15582   f64 timeout;
15583
15584   M (MPLS_FIB_DUMP, mpls_fib_dump);
15585   S;
15586
15587   /* Use a control ping for synchronization */
15588   {
15589     vl_api_control_ping_t *mp;
15590     M (CONTROL_PING, control_ping);
15591     S;
15592   }
15593   W;
15594 }
15595
15596 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15597 #define vl_api_ip_fib_details_t_print vl_noop_handler
15598
15599 static void
15600 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15601 {
15602   vat_main_t *vam = &vat_main;
15603   int count = ntohl (mp->count);
15604   vl_api_fib_path_t *fp;
15605   int i;
15606
15607   print (vam->ofp,
15608          "table-id %d, prefix %U/%d",
15609          ntohl (mp->table_id), format_ip4_address, mp->address,
15610          mp->address_length);
15611   fp = mp->path;
15612   for (i = 0; i < count; i++)
15613     {
15614       if (fp->afi == IP46_TYPE_IP6)
15615         print (vam->ofp,
15616                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15617                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15618                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15619                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15620                format_ip6_address, fp->next_hop);
15621       else if (fp->afi == IP46_TYPE_IP4)
15622         print (vam->ofp,
15623                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15624                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15625                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15626                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15627                format_ip4_address, fp->next_hop);
15628       fp++;
15629     }
15630 }
15631
15632 static void vl_api_ip_fib_details_t_handler_json
15633   (vl_api_ip_fib_details_t * mp)
15634 {
15635   vat_main_t *vam = &vat_main;
15636   int count = ntohl (mp->count);
15637   vat_json_node_t *node = NULL;
15638   struct in_addr ip4;
15639   struct in6_addr ip6;
15640   vl_api_fib_path_t *fp;
15641   int i;
15642
15643   if (VAT_JSON_ARRAY != vam->json_tree.type)
15644     {
15645       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15646       vat_json_init_array (&vam->json_tree);
15647     }
15648   node = vat_json_array_add (&vam->json_tree);
15649
15650   vat_json_init_object (node);
15651   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15652   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15653   vat_json_object_add_ip4 (node, "prefix", ip4);
15654   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15655   vat_json_object_add_uint (node, "path_count", count);
15656   fp = mp->path;
15657   for (i = 0; i < count; i++)
15658     {
15659       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15660       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15661       vat_json_object_add_uint (node, "is_local", fp->is_local);
15662       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15663       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15664       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15665       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15666       if (fp->afi == IP46_TYPE_IP4)
15667         {
15668           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15669           vat_json_object_add_ip4 (node, "next_hop", ip4);
15670         }
15671       else if (fp->afi == IP46_TYPE_IP6)
15672         {
15673           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15674           vat_json_object_add_ip6 (node, "next_hop", ip6);
15675         }
15676     }
15677 }
15678
15679 static int
15680 api_ip_fib_dump (vat_main_t * vam)
15681 {
15682   vl_api_ip_fib_dump_t *mp;
15683   f64 timeout;
15684
15685   M (IP_FIB_DUMP, ip_fib_dump);
15686   S;
15687
15688   /* Use a control ping for synchronization */
15689   {
15690     vl_api_control_ping_t *mp;
15691     M (CONTROL_PING, control_ping);
15692     S;
15693   }
15694   W;
15695 }
15696
15697 static void vl_api_ip_neighbor_details_t_handler
15698   (vl_api_ip_neighbor_details_t * mp)
15699 {
15700   vat_main_t *vam = &vat_main;
15701
15702   print (vam->ofp, "%c %U %U",
15703          (mp->is_static) ? 'S' : 'D',
15704          format_ethernet_address, &mp->mac_address,
15705          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15706          &mp->ip_address);
15707 }
15708
15709 static void vl_api_ip_neighbor_details_t_handler_json
15710   (vl_api_ip_neighbor_details_t * mp)
15711 {
15712
15713   vat_main_t *vam = &vat_main;
15714   vat_json_node_t *node;
15715   struct in_addr ip4;
15716   struct in6_addr ip6;
15717
15718   if (VAT_JSON_ARRAY != vam->json_tree.type)
15719     {
15720       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15721       vat_json_init_array (&vam->json_tree);
15722     }
15723   node = vat_json_array_add (&vam->json_tree);
15724
15725   vat_json_init_object (node);
15726   vat_json_object_add_string_copy (node, "flag",
15727                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15728                                    "dynamic");
15729
15730   vat_json_object_add_string_copy (node, "link_layer",
15731                                    format (0, "%U", format_ethernet_address,
15732                                            &mp->mac_address));
15733
15734   if (mp->is_ipv6)
15735     {
15736       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15737       vat_json_object_add_ip6 (node, "ip_address", ip6);
15738     }
15739   else
15740     {
15741       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15742       vat_json_object_add_ip4 (node, "ip_address", ip4);
15743     }
15744 }
15745
15746 static int
15747 api_ip_neighbor_dump (vat_main_t * vam)
15748 {
15749   unformat_input_t *i = vam->input;
15750   vl_api_ip_neighbor_dump_t *mp;
15751   f64 timeout;
15752   u8 is_ipv6 = 0;
15753   u32 sw_if_index = ~0;
15754
15755   /* Parse args required to build the message */
15756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15757     {
15758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15759         ;
15760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15761         ;
15762       else if (unformat (i, "ip6"))
15763         is_ipv6 = 1;
15764       else
15765         break;
15766     }
15767
15768   if (sw_if_index == ~0)
15769     {
15770       errmsg ("missing interface name or sw_if_index");
15771       return -99;
15772     }
15773
15774   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15775   mp->is_ipv6 = (u8) is_ipv6;
15776   mp->sw_if_index = ntohl (sw_if_index);
15777   S;
15778
15779   /* Use a control ping for synchronization */
15780   {
15781     vl_api_control_ping_t *mp;
15782     M (CONTROL_PING, control_ping);
15783     S;
15784   }
15785   W;
15786 }
15787
15788 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15789 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15790
15791 static void
15792 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15793 {
15794   vat_main_t *vam = &vat_main;
15795   int count = ntohl (mp->count);
15796   vl_api_fib_path_t *fp;
15797   int i;
15798
15799   print (vam->ofp,
15800          "table-id %d, prefix %U/%d",
15801          ntohl (mp->table_id), format_ip6_address, mp->address,
15802          mp->address_length);
15803   fp = mp->path;
15804   for (i = 0; i < count; i++)
15805     {
15806       if (fp->afi == IP46_TYPE_IP6)
15807         print (vam->ofp,
15808                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15809                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15810                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15811                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15812                format_ip6_address, fp->next_hop);
15813       else if (fp->afi == IP46_TYPE_IP4)
15814         print (vam->ofp,
15815                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15816                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15817                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15818                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15819                format_ip4_address, fp->next_hop);
15820       fp++;
15821     }
15822 }
15823
15824 static void vl_api_ip6_fib_details_t_handler_json
15825   (vl_api_ip6_fib_details_t * mp)
15826 {
15827   vat_main_t *vam = &vat_main;
15828   int count = ntohl (mp->count);
15829   vat_json_node_t *node = NULL;
15830   struct in_addr ip4;
15831   struct in6_addr ip6;
15832   vl_api_fib_path_t *fp;
15833   int i;
15834
15835   if (VAT_JSON_ARRAY != vam->json_tree.type)
15836     {
15837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15838       vat_json_init_array (&vam->json_tree);
15839     }
15840   node = vat_json_array_add (&vam->json_tree);
15841
15842   vat_json_init_object (node);
15843   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15844   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15845   vat_json_object_add_ip6 (node, "prefix", ip6);
15846   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15847   vat_json_object_add_uint (node, "path_count", count);
15848   fp = mp->path;
15849   for (i = 0; i < count; i++)
15850     {
15851       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15852       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15853       vat_json_object_add_uint (node, "is_local", fp->is_local);
15854       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15855       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15856       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15857       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15858       if (fp->afi == IP46_TYPE_IP4)
15859         {
15860           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15861           vat_json_object_add_ip4 (node, "next_hop", ip4);
15862         }
15863       else if (fp->afi == IP46_TYPE_IP6)
15864         {
15865           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15866           vat_json_object_add_ip6 (node, "next_hop", ip6);
15867         }
15868     }
15869 }
15870
15871 static int
15872 api_ip6_fib_dump (vat_main_t * vam)
15873 {
15874   vl_api_ip6_fib_dump_t *mp;
15875   f64 timeout;
15876
15877   M (IP6_FIB_DUMP, ip6_fib_dump);
15878   S;
15879
15880   /* Use a control ping for synchronization */
15881   {
15882     vl_api_control_ping_t *mp;
15883     M (CONTROL_PING, control_ping);
15884     S;
15885   }
15886   W;
15887 }
15888
15889 int
15890 api_classify_table_ids (vat_main_t * vam)
15891 {
15892   vl_api_classify_table_ids_t *mp;
15893   f64 timeout;
15894
15895   /* Construct the API message */
15896   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15897   mp->context = 0;
15898
15899   S;
15900   W;
15901   /* NOTREACHED */
15902   return 0;
15903 }
15904
15905 int
15906 api_classify_table_by_interface (vat_main_t * vam)
15907 {
15908   unformat_input_t *input = vam->input;
15909   vl_api_classify_table_by_interface_t *mp;
15910   f64 timeout;
15911
15912   u32 sw_if_index = ~0;
15913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15914     {
15915       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15916         ;
15917       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15918         ;
15919       else
15920         break;
15921     }
15922   if (sw_if_index == ~0)
15923     {
15924       errmsg ("missing interface name or sw_if_index");
15925       return -99;
15926     }
15927
15928   /* Construct the API message */
15929   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15930   mp->context = 0;
15931   mp->sw_if_index = ntohl (sw_if_index);
15932
15933   S;
15934   W;
15935   /* NOTREACHED */
15936   return 0;
15937 }
15938
15939 int
15940 api_classify_table_info (vat_main_t * vam)
15941 {
15942   unformat_input_t *input = vam->input;
15943   vl_api_classify_table_info_t *mp;
15944   f64 timeout;
15945
15946   u32 table_id = ~0;
15947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15948     {
15949       if (unformat (input, "table_id %d", &table_id))
15950         ;
15951       else
15952         break;
15953     }
15954   if (table_id == ~0)
15955     {
15956       errmsg ("missing table id");
15957       return -99;
15958     }
15959
15960   /* Construct the API message */
15961   M (CLASSIFY_TABLE_INFO, classify_table_info);
15962   mp->context = 0;
15963   mp->table_id = ntohl (table_id);
15964
15965   S;
15966   W;
15967   /* NOTREACHED */
15968   return 0;
15969 }
15970
15971 int
15972 api_classify_session_dump (vat_main_t * vam)
15973 {
15974   unformat_input_t *input = vam->input;
15975   vl_api_classify_session_dump_t *mp;
15976   f64 timeout;
15977
15978   u32 table_id = ~0;
15979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15980     {
15981       if (unformat (input, "table_id %d", &table_id))
15982         ;
15983       else
15984         break;
15985     }
15986   if (table_id == ~0)
15987     {
15988       errmsg ("missing table id");
15989       return -99;
15990     }
15991
15992   /* Construct the API message */
15993   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15994   mp->context = 0;
15995   mp->table_id = ntohl (table_id);
15996   S;
15997
15998   /* Use a control ping for synchronization */
15999   {
16000     vl_api_control_ping_t *mp;
16001     M (CONTROL_PING, control_ping);
16002     S;
16003   }
16004   W;
16005   /* NOTREACHED */
16006   return 0;
16007 }
16008
16009 static void
16010 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16011 {
16012   vat_main_t *vam = &vat_main;
16013
16014   print (vam->ofp, "collector_address %U, collector_port %d, "
16015          "src_address %U, vrf_id %d, path_mtu %u, "
16016          "template_interval %u, udp_checksum %d",
16017          format_ip4_address, mp->collector_address,
16018          ntohs (mp->collector_port),
16019          format_ip4_address, mp->src_address,
16020          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16021          ntohl (mp->template_interval), mp->udp_checksum);
16022
16023   vam->retval = 0;
16024   vam->result_ready = 1;
16025 }
16026
16027 static void
16028   vl_api_ipfix_exporter_details_t_handler_json
16029   (vl_api_ipfix_exporter_details_t * mp)
16030 {
16031   vat_main_t *vam = &vat_main;
16032   vat_json_node_t node;
16033   struct in_addr collector_address;
16034   struct in_addr src_address;
16035
16036   vat_json_init_object (&node);
16037   clib_memcpy (&collector_address, &mp->collector_address,
16038                sizeof (collector_address));
16039   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16040   vat_json_object_add_uint (&node, "collector_port",
16041                             ntohs (mp->collector_port));
16042   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16043   vat_json_object_add_ip4 (&node, "src_address", src_address);
16044   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16045   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16046   vat_json_object_add_uint (&node, "template_interval",
16047                             ntohl (mp->template_interval));
16048   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16049
16050   vat_json_print (vam->ofp, &node);
16051   vat_json_free (&node);
16052   vam->retval = 0;
16053   vam->result_ready = 1;
16054 }
16055
16056 int
16057 api_ipfix_exporter_dump (vat_main_t * vam)
16058 {
16059   vl_api_ipfix_exporter_dump_t *mp;
16060   f64 timeout;
16061
16062   /* Construct the API message */
16063   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
16064   mp->context = 0;
16065
16066   S;
16067   W;
16068   /* NOTREACHED */
16069   return 0;
16070 }
16071
16072 static int
16073 api_ipfix_classify_stream_dump (vat_main_t * vam)
16074 {
16075   vl_api_ipfix_classify_stream_dump_t *mp;
16076   f64 timeout;
16077
16078   /* Construct the API message */
16079   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
16080   mp->context = 0;
16081
16082   S;
16083   W;
16084   /* NOTREACHED */
16085   return 0;
16086 }
16087
16088 static void
16089   vl_api_ipfix_classify_stream_details_t_handler
16090   (vl_api_ipfix_classify_stream_details_t * mp)
16091 {
16092   vat_main_t *vam = &vat_main;
16093   print (vam->ofp, "domain_id %d, src_port %d",
16094          ntohl (mp->domain_id), ntohs (mp->src_port));
16095   vam->retval = 0;
16096   vam->result_ready = 1;
16097 }
16098
16099 static void
16100   vl_api_ipfix_classify_stream_details_t_handler_json
16101   (vl_api_ipfix_classify_stream_details_t * mp)
16102 {
16103   vat_main_t *vam = &vat_main;
16104   vat_json_node_t node;
16105
16106   vat_json_init_object (&node);
16107   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16108   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16109
16110   vat_json_print (vam->ofp, &node);
16111   vat_json_free (&node);
16112   vam->retval = 0;
16113   vam->result_ready = 1;
16114 }
16115
16116 static int
16117 api_ipfix_classify_table_dump (vat_main_t * vam)
16118 {
16119   vl_api_ipfix_classify_table_dump_t *mp;
16120   f64 timeout;
16121
16122   if (!vam->json_output)
16123     {
16124       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16125              "transport_protocol");
16126     }
16127
16128   /* Construct the API message */
16129   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
16130
16131   /* send it... */
16132   S;
16133
16134   /* Use a control ping for synchronization */
16135   {
16136     vl_api_control_ping_t *mp;
16137     M (CONTROL_PING, control_ping);
16138     S;
16139   }
16140   W;
16141 }
16142
16143 static void
16144   vl_api_ipfix_classify_table_details_t_handler
16145   (vl_api_ipfix_classify_table_details_t * mp)
16146 {
16147   vat_main_t *vam = &vat_main;
16148   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16149          mp->transport_protocol);
16150 }
16151
16152 static void
16153   vl_api_ipfix_classify_table_details_t_handler_json
16154   (vl_api_ipfix_classify_table_details_t * mp)
16155 {
16156   vat_json_node_t *node = NULL;
16157   vat_main_t *vam = &vat_main;
16158
16159   if (VAT_JSON_ARRAY != vam->json_tree.type)
16160     {
16161       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16162       vat_json_init_array (&vam->json_tree);
16163     }
16164
16165   node = vat_json_array_add (&vam->json_tree);
16166   vat_json_init_object (node);
16167
16168   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16169   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16170   vat_json_object_add_uint (node, "transport_protocol",
16171                             mp->transport_protocol);
16172 }
16173
16174 static int
16175 api_sw_interface_span_enable_disable (vat_main_t * vam)
16176 {
16177   unformat_input_t *i = vam->input;
16178   vl_api_sw_interface_span_enable_disable_t *mp;
16179   f64 timeout;
16180   u32 src_sw_if_index = ~0;
16181   u32 dst_sw_if_index = ~0;
16182   u8 state = 3;
16183
16184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16185     {
16186       if (unformat
16187           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16188         ;
16189       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16190         ;
16191       else
16192         if (unformat
16193             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16194         ;
16195       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16196         ;
16197       else if (unformat (i, "disable"))
16198         state = 0;
16199       else if (unformat (i, "rx"))
16200         state = 1;
16201       else if (unformat (i, "tx"))
16202         state = 2;
16203       else if (unformat (i, "both"))
16204         state = 3;
16205       else
16206         break;
16207     }
16208
16209   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16210
16211   mp->sw_if_index_from = htonl (src_sw_if_index);
16212   mp->sw_if_index_to = htonl (dst_sw_if_index);
16213   mp->state = state;
16214
16215   S;
16216   W;
16217   /* NOTREACHED */
16218   return 0;
16219 }
16220
16221 static void
16222 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16223                                             * mp)
16224 {
16225   vat_main_t *vam = &vat_main;
16226   u8 *sw_if_from_name = 0;
16227   u8 *sw_if_to_name = 0;
16228   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16229   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16230   char *states[] = { "none", "rx", "tx", "both" };
16231   hash_pair_t *p;
16232
16233   /* *INDENT-OFF* */
16234   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16235   ({
16236     if ((u32) p->value[0] == sw_if_index_from)
16237       {
16238         sw_if_from_name = (u8 *)(p->key);
16239         if (sw_if_to_name)
16240           break;
16241       }
16242     if ((u32) p->value[0] == sw_if_index_to)
16243       {
16244         sw_if_to_name = (u8 *)(p->key);
16245         if (sw_if_from_name)
16246           break;
16247       }
16248   }));
16249   /* *INDENT-ON* */
16250   print (vam->ofp, "%20s => %20s (%s)",
16251          sw_if_from_name, sw_if_to_name, states[mp->state]);
16252 }
16253
16254 static void
16255   vl_api_sw_interface_span_details_t_handler_json
16256   (vl_api_sw_interface_span_details_t * mp)
16257 {
16258   vat_main_t *vam = &vat_main;
16259   vat_json_node_t *node = NULL;
16260   u8 *sw_if_from_name = 0;
16261   u8 *sw_if_to_name = 0;
16262   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16263   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16264   hash_pair_t *p;
16265
16266   /* *INDENT-OFF* */
16267   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16268   ({
16269     if ((u32) p->value[0] == sw_if_index_from)
16270       {
16271         sw_if_from_name = (u8 *)(p->key);
16272         if (sw_if_to_name)
16273           break;
16274       }
16275     if ((u32) p->value[0] == sw_if_index_to)
16276       {
16277         sw_if_to_name = (u8 *)(p->key);
16278         if (sw_if_from_name)
16279           break;
16280       }
16281   }));
16282   /* *INDENT-ON* */
16283
16284   if (VAT_JSON_ARRAY != vam->json_tree.type)
16285     {
16286       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16287       vat_json_init_array (&vam->json_tree);
16288     }
16289   node = vat_json_array_add (&vam->json_tree);
16290
16291   vat_json_init_object (node);
16292   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16293   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16294   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16295   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16296   vat_json_object_add_uint (node, "state", mp->state);
16297 }
16298
16299 static int
16300 api_sw_interface_span_dump (vat_main_t * vam)
16301 {
16302   vl_api_sw_interface_span_dump_t *mp;
16303   f64 timeout;
16304
16305   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16306   S;
16307
16308   /* Use a control ping for synchronization */
16309   {
16310     vl_api_control_ping_t *mp;
16311     M (CONTROL_PING, control_ping);
16312     S;
16313   }
16314   W;
16315 }
16316
16317 int
16318 api_pg_create_interface (vat_main_t * vam)
16319 {
16320   unformat_input_t *input = vam->input;
16321   vl_api_pg_create_interface_t *mp;
16322   f64 timeout;
16323
16324   u32 if_id = ~0;
16325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16326     {
16327       if (unformat (input, "if_id %d", &if_id))
16328         ;
16329       else
16330         break;
16331     }
16332   if (if_id == ~0)
16333     {
16334       errmsg ("missing pg interface index");
16335       return -99;
16336     }
16337
16338   /* Construct the API message */
16339   M (PG_CREATE_INTERFACE, pg_create_interface);
16340   mp->context = 0;
16341   mp->interface_id = ntohl (if_id);
16342
16343   S;
16344   W;
16345   /* NOTREACHED */
16346   return 0;
16347 }
16348
16349 int
16350 api_pg_capture (vat_main_t * vam)
16351 {
16352   unformat_input_t *input = vam->input;
16353   vl_api_pg_capture_t *mp;
16354   f64 timeout;
16355
16356   u32 if_id = ~0;
16357   u8 enable = 1;
16358   u32 count = 1;
16359   u8 pcap_file_set = 0;
16360   u8 *pcap_file = 0;
16361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16362     {
16363       if (unformat (input, "if_id %d", &if_id))
16364         ;
16365       else if (unformat (input, "pcap %s", &pcap_file))
16366         pcap_file_set = 1;
16367       else if (unformat (input, "count %d", &count))
16368         ;
16369       else if (unformat (input, "disable"))
16370         enable = 0;
16371       else
16372         break;
16373     }
16374   if (if_id == ~0)
16375     {
16376       errmsg ("missing pg interface index");
16377       return -99;
16378     }
16379   if (pcap_file_set > 0)
16380     {
16381       if (vec_len (pcap_file) > 255)
16382         {
16383           errmsg ("pcap file name is too long");
16384           return -99;
16385         }
16386     }
16387
16388   u32 name_len = vec_len (pcap_file);
16389   /* Construct the API message */
16390   M (PG_CAPTURE, pg_capture);
16391   mp->context = 0;
16392   mp->interface_id = ntohl (if_id);
16393   mp->is_enabled = enable;
16394   mp->count = ntohl (count);
16395   mp->pcap_name_length = ntohl (name_len);
16396   if (pcap_file_set != 0)
16397     {
16398       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16399     }
16400   vec_free (pcap_file);
16401
16402   S;
16403   W;
16404   /* NOTREACHED */
16405   return 0;
16406 }
16407
16408 int
16409 api_pg_enable_disable (vat_main_t * vam)
16410 {
16411   unformat_input_t *input = vam->input;
16412   vl_api_pg_enable_disable_t *mp;
16413   f64 timeout;
16414
16415   u8 enable = 1;
16416   u8 stream_name_set = 0;
16417   u8 *stream_name = 0;
16418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16419     {
16420       if (unformat (input, "stream %s", &stream_name))
16421         stream_name_set = 1;
16422       else if (unformat (input, "disable"))
16423         enable = 0;
16424       else
16425         break;
16426     }
16427
16428   if (stream_name_set > 0)
16429     {
16430       if (vec_len (stream_name) > 255)
16431         {
16432           errmsg ("stream name too long");
16433           return -99;
16434         }
16435     }
16436
16437   u32 name_len = vec_len (stream_name);
16438   /* Construct the API message */
16439   M (PG_ENABLE_DISABLE, pg_enable_disable);
16440   mp->context = 0;
16441   mp->is_enabled = enable;
16442   if (stream_name_set != 0)
16443     {
16444       mp->stream_name_length = ntohl (name_len);
16445       clib_memcpy (mp->stream_name, stream_name, name_len);
16446     }
16447   vec_free (stream_name);
16448
16449   S;
16450   W;
16451   /* NOTREACHED */
16452   return 0;
16453 }
16454
16455 int
16456 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16457 {
16458   unformat_input_t *input = vam->input;
16459   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16460   f64 timeout;
16461
16462   u16 *low_ports = 0;
16463   u16 *high_ports = 0;
16464   u16 this_low;
16465   u16 this_hi;
16466   ip4_address_t ip4_addr;
16467   ip6_address_t ip6_addr;
16468   u32 length;
16469   u32 tmp, tmp2;
16470   u8 prefix_set = 0;
16471   u32 vrf_id = ~0;
16472   u8 is_add = 1;
16473   u8 is_ipv6 = 0;
16474
16475   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16476     {
16477       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16478         {
16479           prefix_set = 1;
16480         }
16481       else
16482         if (unformat
16483             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16484         {
16485           prefix_set = 1;
16486           is_ipv6 = 1;
16487         }
16488       else if (unformat (input, "vrf %d", &vrf_id))
16489         ;
16490       else if (unformat (input, "del"))
16491         is_add = 0;
16492       else if (unformat (input, "port %d", &tmp))
16493         {
16494           if (tmp == 0 || tmp > 65535)
16495             {
16496               errmsg ("port %d out of range", tmp);
16497               return -99;
16498             }
16499           this_low = tmp;
16500           this_hi = this_low + 1;
16501           vec_add1 (low_ports, this_low);
16502           vec_add1 (high_ports, this_hi);
16503         }
16504       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16505         {
16506           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16507             {
16508               errmsg ("incorrect range parameters");
16509               return -99;
16510             }
16511           this_low = tmp;
16512           /* Note: in debug CLI +1 is added to high before
16513              passing to real fn that does "the work"
16514              (ip_source_and_port_range_check_add_del).
16515              This fn is a wrapper around the binary API fn a
16516              control plane will call, which expects this increment
16517              to have occurred. Hence letting the binary API control
16518              plane fn do the increment for consistency between VAT
16519              and other control planes.
16520            */
16521           this_hi = tmp2;
16522           vec_add1 (low_ports, this_low);
16523           vec_add1 (high_ports, this_hi);
16524         }
16525       else
16526         break;
16527     }
16528
16529   if (prefix_set == 0)
16530     {
16531       errmsg ("<address>/<mask> not specified");
16532       return -99;
16533     }
16534
16535   if (vrf_id == ~0)
16536     {
16537       errmsg ("VRF ID required, not specified");
16538       return -99;
16539     }
16540
16541   if (vrf_id == 0)
16542     {
16543       errmsg
16544         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16545       return -99;
16546     }
16547
16548   if (vec_len (low_ports) == 0)
16549     {
16550       errmsg ("At least one port or port range required");
16551       return -99;
16552     }
16553
16554   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16555      ip_source_and_port_range_check_add_del);
16556
16557   mp->is_add = is_add;
16558
16559   if (is_ipv6)
16560     {
16561       mp->is_ipv6 = 1;
16562       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16563     }
16564   else
16565     {
16566       mp->is_ipv6 = 0;
16567       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16568     }
16569
16570   mp->mask_length = length;
16571   mp->number_of_ranges = vec_len (low_ports);
16572
16573   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16574   vec_free (low_ports);
16575
16576   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16577   vec_free (high_ports);
16578
16579   mp->vrf_id = ntohl (vrf_id);
16580
16581   S;
16582   W;
16583   /* NOTREACHED */
16584   return 0;
16585 }
16586
16587 int
16588 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16589 {
16590   unformat_input_t *input = vam->input;
16591   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16592   f64 timeout;
16593   u32 sw_if_index = ~0;
16594   int vrf_set = 0;
16595   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16596   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16597   u8 is_add = 1;
16598
16599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16600     {
16601       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16602         ;
16603       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16604         ;
16605       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16606         vrf_set = 1;
16607       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16608         vrf_set = 1;
16609       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16610         vrf_set = 1;
16611       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16612         vrf_set = 1;
16613       else if (unformat (input, "del"))
16614         is_add = 0;
16615       else
16616         break;
16617     }
16618
16619   if (sw_if_index == ~0)
16620     {
16621       errmsg ("Interface required but not specified");
16622       return -99;
16623     }
16624
16625   if (vrf_set == 0)
16626     {
16627       errmsg ("VRF ID required but not specified");
16628       return -99;
16629     }
16630
16631   if (tcp_out_vrf_id == 0
16632       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16633     {
16634       errmsg
16635         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16636       return -99;
16637     }
16638
16639   /* Construct the API message */
16640   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16641      ip_source_and_port_range_check_interface_add_del);
16642
16643   mp->sw_if_index = ntohl (sw_if_index);
16644   mp->is_add = is_add;
16645   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16646   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16647   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16648   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16649
16650   /* send it... */
16651   S;
16652
16653   /* Wait for a reply... */
16654   W;
16655 }
16656
16657 static int
16658 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16659 {
16660   unformat_input_t *i = vam->input;
16661   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16662   f64 timeout;
16663   u32 local_sa_id = 0;
16664   u32 remote_sa_id = 0;
16665   ip4_address_t src_address;
16666   ip4_address_t dst_address;
16667   u8 is_add = 1;
16668
16669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16670     {
16671       if (unformat (i, "local_sa %d", &local_sa_id))
16672         ;
16673       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16674         ;
16675       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16676         ;
16677       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16678         ;
16679       else if (unformat (i, "del"))
16680         is_add = 0;
16681       else
16682         {
16683           clib_warning ("parse error '%U'", format_unformat_error, i);
16684           return -99;
16685         }
16686     }
16687
16688   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16689
16690   mp->local_sa_id = ntohl (local_sa_id);
16691   mp->remote_sa_id = ntohl (remote_sa_id);
16692   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16693   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16694   mp->is_add = is_add;
16695
16696   S;
16697   W;
16698   /* NOTREACHED */
16699   return 0;
16700 }
16701
16702 static int
16703 api_punt (vat_main_t * vam)
16704 {
16705   unformat_input_t *i = vam->input;
16706   vl_api_punt_t *mp;
16707   f64 timeout;
16708   u32 ipv = ~0;
16709   u32 protocol = ~0;
16710   u32 port = ~0;
16711   int is_add = 1;
16712
16713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16714     {
16715       if (unformat (i, "ip %d", &ipv))
16716         ;
16717       else if (unformat (i, "protocol %d", &protocol))
16718         ;
16719       else if (unformat (i, "port %d", &port))
16720         ;
16721       else if (unformat (i, "del"))
16722         is_add = 0;
16723       else
16724         {
16725           clib_warning ("parse error '%U'", format_unformat_error, i);
16726           return -99;
16727         }
16728     }
16729
16730   M (PUNT, punt);
16731
16732   mp->is_add = (u8) is_add;
16733   mp->ipv = (u8) ipv;
16734   mp->l4_protocol = (u8) protocol;
16735   mp->l4_port = htons ((u16) port);
16736
16737   S;
16738   W;
16739   /* NOTREACHED */
16740   return 0;
16741 }
16742
16743 static void vl_api_ipsec_gre_tunnel_details_t_handler
16744   (vl_api_ipsec_gre_tunnel_details_t * mp)
16745 {
16746   vat_main_t *vam = &vat_main;
16747
16748   print (vam->ofp, "%11d%15U%15U%14d%14d",
16749          ntohl (mp->sw_if_index),
16750          format_ip4_address, &mp->src_address,
16751          format_ip4_address, &mp->dst_address,
16752          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16753 }
16754
16755 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16756   (vl_api_ipsec_gre_tunnel_details_t * mp)
16757 {
16758   vat_main_t *vam = &vat_main;
16759   vat_json_node_t *node = NULL;
16760   struct in_addr ip4;
16761
16762   if (VAT_JSON_ARRAY != vam->json_tree.type)
16763     {
16764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16765       vat_json_init_array (&vam->json_tree);
16766     }
16767   node = vat_json_array_add (&vam->json_tree);
16768
16769   vat_json_init_object (node);
16770   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16771   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16772   vat_json_object_add_ip4 (node, "src_address", ip4);
16773   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16774   vat_json_object_add_ip4 (node, "dst_address", ip4);
16775   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16776   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16777 }
16778
16779 static int
16780 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16781 {
16782   unformat_input_t *i = vam->input;
16783   vl_api_ipsec_gre_tunnel_dump_t *mp;
16784   f64 timeout;
16785   u32 sw_if_index;
16786   u8 sw_if_index_set = 0;
16787
16788   /* Parse args required to build the message */
16789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16790     {
16791       if (unformat (i, "sw_if_index %d", &sw_if_index))
16792         sw_if_index_set = 1;
16793       else
16794         break;
16795     }
16796
16797   if (sw_if_index_set == 0)
16798     {
16799       sw_if_index = ~0;
16800     }
16801
16802   if (!vam->json_output)
16803     {
16804       print (vam->ofp, "%11s%15s%15s%14s%14s",
16805              "sw_if_index", "src_address", "dst_address",
16806              "local_sa_id", "remote_sa_id");
16807     }
16808
16809   /* Get list of gre-tunnel interfaces */
16810   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16811
16812   mp->sw_if_index = htonl (sw_if_index);
16813
16814   S;
16815
16816   /* Use a control ping for synchronization */
16817   {
16818     vl_api_control_ping_t *mp;
16819     M (CONTROL_PING, control_ping);
16820     S;
16821   }
16822   W;
16823 }
16824
16825 static int
16826 api_delete_subif (vat_main_t * vam)
16827 {
16828   unformat_input_t *i = vam->input;
16829   vl_api_delete_subif_t *mp;
16830   f64 timeout;
16831   u32 sw_if_index = ~0;
16832
16833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16834     {
16835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16836         ;
16837       if (unformat (i, "sw_if_index %d", &sw_if_index))
16838         ;
16839       else
16840         break;
16841     }
16842
16843   if (sw_if_index == ~0)
16844     {
16845       errmsg ("missing sw_if_index");
16846       return -99;
16847     }
16848
16849   /* Construct the API message */
16850   M (DELETE_SUBIF, delete_subif);
16851   mp->sw_if_index = ntohl (sw_if_index);
16852
16853   S;
16854   W;
16855 }
16856
16857 #define foreach_pbb_vtr_op      \
16858 _("disable",  L2_VTR_DISABLED)  \
16859 _("pop",  L2_VTR_POP_2)         \
16860 _("push",  L2_VTR_PUSH_2)
16861
16862 static int
16863 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16864 {
16865   unformat_input_t *i = vam->input;
16866   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16867   f64 timeout;
16868   u32 sw_if_index = ~0, vtr_op = ~0;
16869   u16 outer_tag = ~0;
16870   u8 dmac[6], smac[6];
16871   u8 dmac_set = 0, smac_set = 0;
16872   u16 vlanid = 0;
16873   u32 sid = ~0;
16874   u32 tmp;
16875
16876   /* Shut up coverity */
16877   memset (dmac, 0, sizeof (dmac));
16878   memset (smac, 0, sizeof (smac));
16879
16880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16881     {
16882       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16883         ;
16884       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16885         ;
16886       else if (unformat (i, "vtr_op %d", &vtr_op))
16887         ;
16888 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16889       foreach_pbb_vtr_op
16890 #undef _
16891         else if (unformat (i, "translate_pbb_stag"))
16892         {
16893           if (unformat (i, "%d", &tmp))
16894             {
16895               vtr_op = L2_VTR_TRANSLATE_2_1;
16896               outer_tag = tmp;
16897             }
16898           else
16899             {
16900               errmsg
16901                 ("translate_pbb_stag operation requires outer tag definition");
16902               return -99;
16903             }
16904         }
16905       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16906         dmac_set++;
16907       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16908         smac_set++;
16909       else if (unformat (i, "sid %d", &sid))
16910         ;
16911       else if (unformat (i, "vlanid %d", &tmp))
16912         vlanid = tmp;
16913       else
16914         {
16915           clib_warning ("parse error '%U'", format_unformat_error, i);
16916           return -99;
16917         }
16918     }
16919
16920   if ((sw_if_index == ~0) || (vtr_op == ~0))
16921     {
16922       errmsg ("missing sw_if_index or vtr operation");
16923       return -99;
16924     }
16925   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16926       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16927     {
16928       errmsg
16929         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16930       return -99;
16931     }
16932
16933   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16934   mp->sw_if_index = ntohl (sw_if_index);
16935   mp->vtr_op = ntohl (vtr_op);
16936   mp->outer_tag = ntohs (outer_tag);
16937   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16938   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16939   mp->b_vlanid = ntohs (vlanid);
16940   mp->i_sid = ntohl (sid);
16941
16942   S;
16943   W;
16944   /* NOTREACHED */
16945   return 0;
16946 }
16947
16948 static int
16949 api_flow_classify_set_interface (vat_main_t * vam)
16950 {
16951   unformat_input_t *i = vam->input;
16952   vl_api_flow_classify_set_interface_t *mp;
16953   f64 timeout;
16954   u32 sw_if_index;
16955   int sw_if_index_set;
16956   u32 ip4_table_index = ~0;
16957   u32 ip6_table_index = ~0;
16958   u8 is_add = 1;
16959
16960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16961     {
16962       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16963         sw_if_index_set = 1;
16964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16965         sw_if_index_set = 1;
16966       else if (unformat (i, "del"))
16967         is_add = 0;
16968       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16969         ;
16970       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16971         ;
16972       else
16973         {
16974           clib_warning ("parse error '%U'", format_unformat_error, i);
16975           return -99;
16976         }
16977     }
16978
16979   if (sw_if_index_set == 0)
16980     {
16981       errmsg ("missing interface name or sw_if_index");
16982       return -99;
16983     }
16984
16985   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16986
16987   mp->sw_if_index = ntohl (sw_if_index);
16988   mp->ip4_table_index = ntohl (ip4_table_index);
16989   mp->ip6_table_index = ntohl (ip6_table_index);
16990   mp->is_add = is_add;
16991
16992   S;
16993   W;
16994   /* NOTREACHED */
16995   return 0;
16996 }
16997
16998 static int
16999 api_flow_classify_dump (vat_main_t * vam)
17000 {
17001   unformat_input_t *i = vam->input;
17002   vl_api_flow_classify_dump_t *mp;
17003   f64 timeout = ~0;
17004   u8 type = FLOW_CLASSIFY_N_TABLES;
17005
17006   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17007     ;
17008   else
17009     {
17010       errmsg ("classify table type must be specified");
17011       return -99;
17012     }
17013
17014   if (!vam->json_output)
17015     {
17016       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17017     }
17018
17019   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
17020   mp->type = type;
17021   /* send it... */
17022   S;
17023
17024   /* Use a control ping for synchronization */
17025   {
17026     vl_api_control_ping_t *mp;
17027     M (CONTROL_PING, control_ping);
17028     S;
17029   }
17030   /* Wait for a reply... */
17031   W;
17032
17033   /* NOTREACHED */
17034   return 0;
17035 }
17036
17037 static int
17038 api_feature_enable_disable (vat_main_t * vam)
17039 {
17040   unformat_input_t *i = vam->input;
17041   vl_api_feature_enable_disable_t *mp;
17042   f64 timeout;
17043   u8 *arc_name = 0;
17044   u8 *feature_name = 0;
17045   u32 sw_if_index = ~0;
17046   u8 enable = 1;
17047
17048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17049     {
17050       if (unformat (i, "arc_name %s", &arc_name))
17051         ;
17052       else if (unformat (i, "feature_name %s", &feature_name))
17053         ;
17054       else
17055         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17056         ;
17057       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17058         ;
17059       else if (unformat (i, "disable"))
17060         enable = 0;
17061       else
17062         break;
17063     }
17064
17065   if (arc_name == 0)
17066     {
17067       errmsg ("missing arc name");
17068       return -99;
17069     }
17070   if (vec_len (arc_name) > 63)
17071     {
17072       errmsg ("arc name too long");
17073     }
17074
17075   if (feature_name == 0)
17076     {
17077       errmsg ("missing feature name");
17078       return -99;
17079     }
17080   if (vec_len (feature_name) > 63)
17081     {
17082       errmsg ("feature name too long");
17083     }
17084
17085   if (sw_if_index == ~0)
17086     {
17087       errmsg ("missing interface name or sw_if_index");
17088       return -99;
17089     }
17090
17091   /* Construct the API message */
17092   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
17093   mp->sw_if_index = ntohl (sw_if_index);
17094   mp->enable = enable;
17095   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17096   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17097   vec_free (arc_name);
17098   vec_free (feature_name);
17099
17100   S;
17101   W;
17102 }
17103
17104 static int
17105 api_sw_interface_tag_add_del (vat_main_t * vam)
17106 {
17107   unformat_input_t *i = vam->input;
17108   vl_api_sw_interface_tag_add_del_t *mp;
17109   f64 timeout;
17110   u32 sw_if_index = ~0;
17111   u8 *tag = 0;
17112   u8 enable = 1;
17113
17114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17115     {
17116       if (unformat (i, "tag %s", &tag))
17117         ;
17118       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17119         ;
17120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17121         ;
17122       else if (unformat (i, "del"))
17123         enable = 0;
17124       else
17125         break;
17126     }
17127
17128   if (sw_if_index == ~0)
17129     {
17130       errmsg ("missing interface name or sw_if_index");
17131       return -99;
17132     }
17133
17134   if (enable && (tag == 0))
17135     {
17136       errmsg ("no tag specified");
17137       return -99;
17138     }
17139
17140   /* Construct the API message */
17141   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
17142   mp->sw_if_index = ntohl (sw_if_index);
17143   mp->is_add = enable;
17144   if (enable)
17145     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17146   vec_free (tag);
17147
17148   S;
17149   W;
17150 }
17151
17152 static void vl_api_l2_xconnect_details_t_handler
17153   (vl_api_l2_xconnect_details_t * mp)
17154 {
17155   vat_main_t *vam = &vat_main;
17156
17157   print (vam->ofp, "%15d%15d",
17158          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17159 }
17160
17161 static void vl_api_l2_xconnect_details_t_handler_json
17162   (vl_api_l2_xconnect_details_t * mp)
17163 {
17164   vat_main_t *vam = &vat_main;
17165   vat_json_node_t *node = NULL;
17166
17167   if (VAT_JSON_ARRAY != vam->json_tree.type)
17168     {
17169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17170       vat_json_init_array (&vam->json_tree);
17171     }
17172   node = vat_json_array_add (&vam->json_tree);
17173
17174   vat_json_init_object (node);
17175   vat_json_object_add_uint (node, "rx_sw_if_index",
17176                             ntohl (mp->rx_sw_if_index));
17177   vat_json_object_add_uint (node, "tx_sw_if_index",
17178                             ntohl (mp->tx_sw_if_index));
17179 }
17180
17181 static int
17182 api_l2_xconnect_dump (vat_main_t * vam)
17183 {
17184   vl_api_l2_xconnect_dump_t *mp;
17185   f64 timeout;
17186
17187   if (!vam->json_output)
17188     {
17189       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17190     }
17191
17192   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
17193
17194   S;
17195
17196   /* Use a control ping for synchronization */
17197   {
17198     vl_api_control_ping_t *mp;
17199     M (CONTROL_PING, control_ping);
17200     S;
17201   }
17202   W;
17203 }
17204
17205 static int
17206 api_sw_interface_set_mtu (vat_main_t * vam)
17207 {
17208   unformat_input_t *i = vam->input;
17209   vl_api_sw_interface_set_mtu_t *mp;
17210   f64 timeout;
17211   u32 sw_if_index = ~0;
17212   u32 mtu = 0;
17213
17214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17215     {
17216       if (unformat (i, "mtu %d", &mtu))
17217         ;
17218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17219         ;
17220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17221         ;
17222       else
17223         break;
17224     }
17225
17226   if (sw_if_index == ~0)
17227     {
17228       errmsg ("missing interface name or sw_if_index");
17229       return -99;
17230     }
17231
17232   if (mtu == 0)
17233     {
17234       errmsg ("no mtu specified");
17235       return -99;
17236     }
17237
17238   /* Construct the API message */
17239   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17240   mp->sw_if_index = ntohl (sw_if_index);
17241   mp->mtu = ntohs ((u16) mtu);
17242
17243   S;
17244   W;
17245 }
17246
17247
17248 static int
17249 q_or_quit (vat_main_t * vam)
17250 {
17251   longjmp (vam->jump_buf, 1);
17252   return 0;                     /* not so much */
17253 }
17254
17255 static int
17256 q (vat_main_t * vam)
17257 {
17258   return q_or_quit (vam);
17259 }
17260
17261 static int
17262 quit (vat_main_t * vam)
17263 {
17264   return q_or_quit (vam);
17265 }
17266
17267 static int
17268 comment (vat_main_t * vam)
17269 {
17270   return 0;
17271 }
17272
17273 static int
17274 cmd_cmp (void *a1, void *a2)
17275 {
17276   u8 **c1 = a1;
17277   u8 **c2 = a2;
17278
17279   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17280 }
17281
17282 static int
17283 help (vat_main_t * vam)
17284 {
17285   u8 **cmds = 0;
17286   u8 *name = 0;
17287   hash_pair_t *p;
17288   unformat_input_t *i = vam->input;
17289   int j;
17290
17291   if (unformat (i, "%s", &name))
17292     {
17293       uword *hs;
17294
17295       vec_add1 (name, 0);
17296
17297       hs = hash_get_mem (vam->help_by_name, name);
17298       if (hs)
17299         print (vam->ofp, "usage: %s %s", name, hs[0]);
17300       else
17301         print (vam->ofp, "No such msg / command '%s'", name);
17302       vec_free (name);
17303       return 0;
17304     }
17305
17306   print (vam->ofp, "Help is available for the following:");
17307
17308     /* *INDENT-OFF* */
17309     hash_foreach_pair (p, vam->function_by_name,
17310     ({
17311       vec_add1 (cmds, (u8 *)(p->key));
17312     }));
17313     /* *INDENT-ON* */
17314
17315   vec_sort_with_function (cmds, cmd_cmp);
17316
17317   for (j = 0; j < vec_len (cmds); j++)
17318     print (vam->ofp, "%s", cmds[j]);
17319
17320   vec_free (cmds);
17321   return 0;
17322 }
17323
17324 static int
17325 set (vat_main_t * vam)
17326 {
17327   u8 *name = 0, *value = 0;
17328   unformat_input_t *i = vam->input;
17329
17330   if (unformat (i, "%s", &name))
17331     {
17332       /* The input buffer is a vector, not a string. */
17333       value = vec_dup (i->buffer);
17334       vec_delete (value, i->index, 0);
17335       /* Almost certainly has a trailing newline */
17336       if (value[vec_len (value) - 1] == '\n')
17337         value[vec_len (value) - 1] = 0;
17338       /* Make sure it's a proper string, one way or the other */
17339       vec_add1 (value, 0);
17340       (void) clib_macro_set_value (&vam->macro_main,
17341                                    (char *) name, (char *) value);
17342     }
17343   else
17344     errmsg ("usage: set <name> <value>");
17345
17346   vec_free (name);
17347   vec_free (value);
17348   return 0;
17349 }
17350
17351 static int
17352 unset (vat_main_t * vam)
17353 {
17354   u8 *name = 0;
17355
17356   if (unformat (vam->input, "%s", &name))
17357     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17358       errmsg ("unset: %s wasn't set", name);
17359   vec_free (name);
17360   return 0;
17361 }
17362
17363 typedef struct
17364 {
17365   u8 *name;
17366   u8 *value;
17367 } macro_sort_t;
17368
17369
17370 static int
17371 macro_sort_cmp (void *a1, void *a2)
17372 {
17373   macro_sort_t *s1 = a1;
17374   macro_sort_t *s2 = a2;
17375
17376   return strcmp ((char *) (s1->name), (char *) (s2->name));
17377 }
17378
17379 static int
17380 dump_macro_table (vat_main_t * vam)
17381 {
17382   macro_sort_t *sort_me = 0, *sm;
17383   int i;
17384   hash_pair_t *p;
17385
17386     /* *INDENT-OFF* */
17387     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17388     ({
17389       vec_add2 (sort_me, sm, 1);
17390       sm->name = (u8 *)(p->key);
17391       sm->value = (u8 *) (p->value[0]);
17392     }));
17393     /* *INDENT-ON* */
17394
17395   vec_sort_with_function (sort_me, macro_sort_cmp);
17396
17397   if (vec_len (sort_me))
17398     print (vam->ofp, "%-15s%s", "Name", "Value");
17399   else
17400     print (vam->ofp, "The macro table is empty...");
17401
17402   for (i = 0; i < vec_len (sort_me); i++)
17403     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17404   return 0;
17405 }
17406
17407 static int
17408 dump_node_table (vat_main_t * vam)
17409 {
17410   int i, j;
17411   vlib_node_t *node, *next_node;
17412
17413   if (vec_len (vam->graph_nodes) == 0)
17414     {
17415       print (vam->ofp, "Node table empty, issue get_node_graph...");
17416       return 0;
17417     }
17418
17419   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17420     {
17421       node = vam->graph_nodes[i];
17422       print (vam->ofp, "[%d] %s", i, node->name);
17423       for (j = 0; j < vec_len (node->next_nodes); j++)
17424         {
17425           if (node->next_nodes[j] != ~0)
17426             {
17427               next_node = vam->graph_nodes[node->next_nodes[j]];
17428               print (vam->ofp, "  [%d] %s", j, next_node->name);
17429             }
17430         }
17431     }
17432   return 0;
17433 }
17434
17435 static int
17436 value_sort_cmp (void *a1, void *a2)
17437 {
17438   name_sort_t *n1 = a1;
17439   name_sort_t *n2 = a2;
17440
17441   if (n1->value < n2->value)
17442     return -1;
17443   if (n1->value > n2->value)
17444     return 1;
17445   return 0;
17446 }
17447
17448
17449 static int
17450 dump_msg_api_table (vat_main_t * vam)
17451 {
17452   api_main_t *am = &api_main;
17453   name_sort_t *nses = 0, *ns;
17454   hash_pair_t *hp;
17455   int i;
17456
17457   /* *INDENT-OFF* */
17458   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17459   ({
17460     vec_add2 (nses, ns, 1);
17461     ns->name = (u8 *)(hp->key);
17462     ns->value = (u32) hp->value[0];
17463   }));
17464   /* *INDENT-ON* */
17465
17466   vec_sort_with_function (nses, value_sort_cmp);
17467
17468   for (i = 0; i < vec_len (nses); i++)
17469     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17470   vec_free (nses);
17471   return 0;
17472 }
17473
17474 static int
17475 get_msg_id (vat_main_t * vam)
17476 {
17477   u8 *name_and_crc;
17478   u32 message_index;
17479
17480   if (unformat (vam->input, "%s", &name_and_crc))
17481     {
17482       message_index = vl_api_get_msg_index (name_and_crc);
17483       if (message_index == ~0)
17484         {
17485           print (vam->ofp, " '%s' not found", name_and_crc);
17486           return 0;
17487         }
17488       print (vam->ofp, " '%s' has message index %d",
17489              name_and_crc, message_index);
17490       return 0;
17491     }
17492   errmsg ("name_and_crc required...");
17493   return 0;
17494 }
17495
17496 static int
17497 search_node_table (vat_main_t * vam)
17498 {
17499   unformat_input_t *line_input = vam->input;
17500   u8 *node_to_find;
17501   int j;
17502   vlib_node_t *node, *next_node;
17503   uword *p;
17504
17505   if (vam->graph_node_index_by_name == 0)
17506     {
17507       print (vam->ofp, "Node table empty, issue get_node_graph...");
17508       return 0;
17509     }
17510
17511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17512     {
17513       if (unformat (line_input, "%s", &node_to_find))
17514         {
17515           vec_add1 (node_to_find, 0);
17516           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17517           if (p == 0)
17518             {
17519               print (vam->ofp, "%s not found...", node_to_find);
17520               goto out;
17521             }
17522           node = vam->graph_nodes[p[0]];
17523           print (vam->ofp, "[%d] %s", p[0], node->name);
17524           for (j = 0; j < vec_len (node->next_nodes); j++)
17525             {
17526               if (node->next_nodes[j] != ~0)
17527                 {
17528                   next_node = vam->graph_nodes[node->next_nodes[j]];
17529                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17530                 }
17531             }
17532         }
17533
17534       else
17535         {
17536           clib_warning ("parse error '%U'", format_unformat_error,
17537                         line_input);
17538           return -99;
17539         }
17540
17541     out:
17542       vec_free (node_to_find);
17543
17544     }
17545
17546   return 0;
17547 }
17548
17549
17550 static int
17551 script (vat_main_t * vam)
17552 {
17553 #if (VPP_API_TEST_BUILTIN==0)
17554   u8 *s = 0;
17555   char *save_current_file;
17556   unformat_input_t save_input;
17557   jmp_buf save_jump_buf;
17558   u32 save_line_number;
17559
17560   FILE *new_fp, *save_ifp;
17561
17562   if (unformat (vam->input, "%s", &s))
17563     {
17564       new_fp = fopen ((char *) s, "r");
17565       if (new_fp == 0)
17566         {
17567           errmsg ("Couldn't open script file %s", s);
17568           vec_free (s);
17569           return -99;
17570         }
17571     }
17572   else
17573     {
17574       errmsg ("Missing script name");
17575       return -99;
17576     }
17577
17578   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17579   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17580   save_ifp = vam->ifp;
17581   save_line_number = vam->input_line_number;
17582   save_current_file = (char *) vam->current_file;
17583
17584   vam->input_line_number = 0;
17585   vam->ifp = new_fp;
17586   vam->current_file = s;
17587   do_one_file (vam);
17588
17589   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17590   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17591   vam->ifp = save_ifp;
17592   vam->input_line_number = save_line_number;
17593   vam->current_file = (u8 *) save_current_file;
17594   vec_free (s);
17595
17596   return 0;
17597 #else
17598   clib_warning ("use the exec command...");
17599   return -99;
17600 #endif
17601 }
17602
17603 static int
17604 echo (vat_main_t * vam)
17605 {
17606   print (vam->ofp, "%v", vam->input->buffer);
17607   return 0;
17608 }
17609
17610 /* List of API message constructors, CLI names map to api_xxx */
17611 #define foreach_vpe_api_msg                                             \
17612 _(create_loopback,"[mac <mac-addr>]")                                   \
17613 _(sw_interface_dump,"")                                                 \
17614 _(sw_interface_set_flags,                                               \
17615   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17616 _(sw_interface_add_del_address,                                         \
17617   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17618 _(sw_interface_set_table,                                               \
17619   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17620 _(sw_interface_set_mpls_enable,                                         \
17621   "<intfc> | sw_if_index [disable | dis]")                              \
17622 _(sw_interface_set_vpath,                                               \
17623   "<intfc> | sw_if_index <id> enable | disable")                        \
17624 _(sw_interface_set_vxlan_bypass,                                        \
17625   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17626 _(sw_interface_set_l2_xconnect,                                         \
17627   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17628   "enable | disable")                                                   \
17629 _(sw_interface_set_l2_bridge,                                           \
17630   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17631   "[shg <split-horizon-group>] [bvi]\n"                                 \
17632   "enable | disable")                                                   \
17633 _(bridge_domain_add_del,                                                \
17634   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17635 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17636 _(l2fib_add_del,                                                        \
17637   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17638 _(l2_flags,                                                             \
17639   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17640 _(bridge_flags,                                                         \
17641   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17642 _(tap_connect,                                                          \
17643   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17644 _(tap_modify,                                                           \
17645   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17646 _(tap_delete,                                                           \
17647   "<vpp-if-name> | sw_if_index <id>")                                   \
17648 _(sw_interface_tap_dump, "")                                            \
17649 _(ip_add_del_route,                                                     \
17650   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17651   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17652   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17653   "[multipath] [count <n>]")                                            \
17654 _(ip_mroute_add_del,                                                    \
17655   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
17656   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
17657 _(mpls_route_add_del,                                                   \
17658   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17659   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17660   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17661   "[multipath] [count <n>]")                                            \
17662 _(mpls_ip_bind_unbind,                                                  \
17663   "<label> <addr/len>")                                                 \
17664 _(mpls_tunnel_add_del,                                                  \
17665   " via <addr> [table-id <n>]\n"                                        \
17666   "sw_if_index <id>] [l2]  [del]")                                      \
17667 _(proxy_arp_add_del,                                                    \
17668   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17669 _(proxy_arp_intfc_enable_disable,                                       \
17670   "<intfc> | sw_if_index <id> enable | disable")                        \
17671 _(sw_interface_set_unnumbered,                                          \
17672   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17673 _(ip_neighbor_add_del,                                                  \
17674   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17675   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17676 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17677 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17678 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17679   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17680   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17681   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17682 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17683 _(reset_fib, "vrf <n> [ipv6]")                                          \
17684 _(dhcp_proxy_config,                                                    \
17685   "svr <v46-address> src <v46-address>\n"                               \
17686    "insert-cid <n> [del]")                                              \
17687 _(dhcp_proxy_config_2,                                                  \
17688   "svr <v46-address> src <v46-address>\n"                               \
17689    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17690 _(dhcp_proxy_set_vss,                                                   \
17691   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17692 _(dhcp_client_config,                                                   \
17693   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17694 _(set_ip_flow_hash,                                                     \
17695   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17696 _(sw_interface_ip6_enable_disable,                                      \
17697   "<intfc> | sw_if_index <id> enable | disable")                        \
17698 _(sw_interface_ip6_set_link_local_address,                              \
17699   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17700 _(sw_interface_ip6nd_ra_prefix,                                         \
17701   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17702   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17703   "[nolink] [isno]")                                                    \
17704 _(sw_interface_ip6nd_ra_config,                                         \
17705   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17706   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17707   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17708 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17709 _(l2_patch_add_del,                                                     \
17710   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17711   "enable | disable")                                                   \
17712 _(sr_tunnel_add_del,                                                    \
17713   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17714   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17715   "[policy <policy_name>]")                                             \
17716 _(sr_policy_add_del,                                                    \
17717   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17718 _(sr_multicast_map_add_del,                                             \
17719   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17720 _(classify_add_del_table,                                               \
17721   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17722   " [del] [del-chain] mask <mask-value>\n"                              \
17723   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17724   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17725 _(classify_add_del_session,                                             \
17726   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17727   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17728   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17729   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17730 _(classify_set_interface_ip_table,                                      \
17731   "<intfc> | sw_if_index <nn> table <nn>")                              \
17732 _(classify_set_interface_l2_tables,                                     \
17733   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17734   "  [other-table <nn>]")                                               \
17735 _(get_node_index, "node <node-name")                                    \
17736 _(add_node_next, "node <node-name> next <next-node-name>")              \
17737 _(l2tpv3_create_tunnel,                                                 \
17738   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17739   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17740   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17741 _(l2tpv3_set_tunnel_cookies,                                            \
17742   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17743   "[new_remote_cookie <nn>]\n")                                         \
17744 _(l2tpv3_interface_enable_disable,                                      \
17745   "<intfc> | sw_if_index <nn> enable | disable")                        \
17746 _(l2tpv3_set_lookup_key,                                                \
17747   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17748 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17749 _(vxlan_add_del_tunnel,                                                 \
17750   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17751   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17752   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17753 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17754 _(gre_add_del_tunnel,                                                   \
17755   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17756 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17757 _(l2_fib_clear_table, "")                                               \
17758 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17759 _(l2_interface_vlan_tag_rewrite,                                        \
17760   "<intfc> | sw_if_index <nn> \n"                                       \
17761   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17762   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17763 _(create_vhost_user_if,                                                 \
17764         "socket <filename> [server] [renumber <dev_instance>] "         \
17765         "[mac <mac_address>]")                                          \
17766 _(modify_vhost_user_if,                                                 \
17767         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17768         "[server] [renumber <dev_instance>]")                           \
17769 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17770 _(sw_interface_vhost_user_dump, "")                                     \
17771 _(show_version, "")                                                     \
17772 _(vxlan_gpe_add_del_tunnel,                                             \
17773   "local <addr> remote <addr> vni <nn>\n"                               \
17774     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17775   "[next-ethernet] [next-nsh]\n")                                       \
17776 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17777 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17778 _(interface_name_renumber,                                              \
17779   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17780 _(input_acl_set_interface,                                              \
17781   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17782   "  [l2-table <nn>] [del]")                                            \
17783 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17784 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17785 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17786 _(ip_dump, "ipv4 | ipv6")                                               \
17787 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17788 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17789   "  spid_id <n> ")                                                     \
17790 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17791   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17792   "  integ_alg <alg> integ_key <hex>")                                  \
17793 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17794   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17795   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17796   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17797 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17798 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17799 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17800   "(auth_data 0x<data> | auth_data <data>)")                            \
17801 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17802   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17803 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17804   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17805   "(local|remote)")                                                     \
17806 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17807 _(delete_loopback,"sw_if_index <nn>")                                   \
17808 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17809 _(map_add_domain,                                                       \
17810   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17811   "ip6-src <ip6addr> "                                                  \
17812   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17813 _(map_del_domain, "index <n>")                                          \
17814 _(map_add_del_rule,                                                     \
17815   "index <n> psid <n> dst <ip6addr> [del]")                             \
17816 _(map_domain_dump, "")                                                  \
17817 _(map_rule_dump, "index <map-domain>")                                  \
17818 _(want_interface_events,  "enable|disable")                             \
17819 _(want_stats,"enable|disable")                                          \
17820 _(get_first_msg_id, "client <name>")                                    \
17821 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17822 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17823   "fib-id <nn> [ip4][ip6][default]")                                    \
17824 _(get_node_graph, " ")                                                  \
17825 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17826 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17827 _(ioam_disable, "")                                                     \
17828 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17829                             " sw_if_index <sw_if_index> p <priority> "  \
17830                             "w <weight>] [del]")                        \
17831 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17832                         "iface <intf> | sw_if_index <sw_if_index> "     \
17833                         "p <priority> w <weight> [del]")                \
17834 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17835                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17836                          "locator-set <locator_name> [del]"             \
17837                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17838 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
17839   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
17840 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17841 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17842 _(lisp_gpe_enable_disable, "enable|disable")                            \
17843 _(lisp_enable_disable, "enable|disable")                                \
17844 _(lisp_map_register_enable_disable, "enable|disable")                   \
17845 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17846 _(lisp_gpe_add_del_iface, "up|down")                                    \
17847 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17848                                "[seid <seid>] "                         \
17849                                "rloc <locator> p <prio> "               \
17850                                "w <weight> [rloc <loc> ... ] "          \
17851                                "action <action> [del-all]")             \
17852 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17853                           "<local-eid>")                                \
17854 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17855 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17856 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17857 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17858 _(lisp_locator_set_dump, "[local | remote]")                            \
17859 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17860 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17861                        "[local] | [remote]")                            \
17862 _(lisp_eid_table_vni_dump, "")                                          \
17863 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17864 _(lisp_map_resolver_dump, "")                                           \
17865 _(lisp_map_server_dump, "")                                             \
17866 _(lisp_adjacencies_get, "vni <vni>")                                    \
17867 _(show_lisp_rloc_probe_state, "")                                       \
17868 _(show_lisp_map_register_state, "")                                     \
17869 _(show_lisp_status, "")                                                 \
17870 _(lisp_get_map_request_itr_rlocs, "")                                   \
17871 _(show_lisp_pitr, "")                                                   \
17872 _(show_lisp_map_request_mode, "")                                       \
17873 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17874 _(af_packet_delete, "name <host interface name>")                       \
17875 _(policer_add_del, "name <policer name> <params> [del]")                \
17876 _(policer_dump, "[name <policer name>]")                                \
17877 _(policer_classify_set_interface,                                       \
17878   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17879   "  [l2-table <nn>] [del]")                                            \
17880 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17881 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17882     "[master|slave]")                                                   \
17883 _(netmap_delete, "name <interface name>")                               \
17884 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17885 _(mpls_fib_dump, "")                                                    \
17886 _(classify_table_ids, "")                                               \
17887 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17888 _(classify_table_info, "table_id <nn>")                                 \
17889 _(classify_session_dump, "table_id <nn>")                               \
17890 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17891     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17892     "[template_interval <nn>] [udp_checksum]")                          \
17893 _(ipfix_exporter_dump, "")                                              \
17894 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17895 _(ipfix_classify_stream_dump, "")                                       \
17896 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17897 _(ipfix_classify_table_dump, "")                                        \
17898 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17899 _(sw_interface_span_dump, "")                                           \
17900 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17901 _(pg_create_interface, "if_id <nn>")                                    \
17902 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17903 _(pg_enable_disable, "[stream <id>] disable")                           \
17904 _(ip_source_and_port_range_check_add_del,                               \
17905   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17906 _(ip_source_and_port_range_check_interface_add_del,                     \
17907   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17908   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17909 _(ipsec_gre_add_del_tunnel,                                             \
17910   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17911 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17912 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17913 _(l2_interface_pbb_tag_rewrite,                                         \
17914   "<intfc> | sw_if_index <nn> \n"                                       \
17915   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17916   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17917 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17918 _(flow_classify_set_interface,                                          \
17919   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17920 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17921 _(ip_fib_dump, "")                                                      \
17922 _(ip6_fib_dump, "")                                                     \
17923 _(feature_enable_disable, "arc_name <arc_name> "                        \
17924   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17925 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17926 "[disable]")                                                            \
17927 _(l2_xconnect_dump, "")                                                 \
17928 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17929 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17930 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17931
17932 #if DPDK > 0
17933 #define foreach_vpe_dpdk_api_msg                                        \
17934 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17935   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17936   "profile <profile-id>\n")                                             \
17937 _(sw_interface_set_dpdk_hqos_subport,                                   \
17938   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17939   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17940 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17941   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
17942 #endif
17943
17944 /* List of command functions, CLI names map directly to functions */
17945 #define foreach_cli_function                                    \
17946 _(comment, "usage: comment <ignore-rest-of-line>")              \
17947 _(dump_interface_table, "usage: dump_interface_table")          \
17948 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17949 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17950 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17951 _(dump_stats_table, "usage: dump_stats_table")                  \
17952 _(dump_macro_table, "usage: dump_macro_table ")                 \
17953 _(dump_node_table, "usage: dump_node_table")                    \
17954 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17955 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17956 _(echo, "usage: echo <message>")                                \
17957 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17958 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17959 _(help, "usage: help")                                          \
17960 _(q, "usage: quit")                                             \
17961 _(quit, "usage: quit")                                          \
17962 _(search_node_table, "usage: search_node_table <name>...")      \
17963 _(set, "usage: set <variable-name> <value>")                    \
17964 _(script, "usage: script <file-name>")                          \
17965 _(unset, "usage: unset <variable-name>")
17966
17967 #define _(N,n)                                  \
17968     static void vl_api_##n##_t_handler_uni      \
17969     (vl_api_##n##_t * mp)                       \
17970     {                                           \
17971         vat_main_t * vam = &vat_main;           \
17972         if (vam->json_output) {                 \
17973             vl_api_##n##_t_handler_json(mp);    \
17974         } else {                                \
17975             vl_api_##n##_t_handler(mp);         \
17976         }                                       \
17977     }
17978 foreach_vpe_api_reply_msg;
17979 #undef _
17980
17981 #if DPDK > 0
17982 #define _(N,n)                                  \
17983     static void vl_api_##n##_t_handler_uni      \
17984     (vl_api_##n##_t * mp)                       \
17985     {                                           \
17986         vat_main_t * vam = &vat_main;           \
17987         if (vam->json_output) {                 \
17988             vl_api_##n##_t_handler_json(mp);    \
17989         } else {                                \
17990             vl_api_##n##_t_handler(mp);         \
17991         }                                       \
17992     }
17993 foreach_vpe_dpdk_api_reply_msg;
17994 #undef _
17995 #endif
17996
17997 void
17998 vat_api_hookup (vat_main_t * vam)
17999 {
18000 #define _(N,n)                                                  \
18001     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18002                            vl_api_##n##_t_handler_uni,          \
18003                            vl_noop_handler,                     \
18004                            vl_api_##n##_t_endian,               \
18005                            vl_api_##n##_t_print,                \
18006                            sizeof(vl_api_##n##_t), 1);
18007   foreach_vpe_api_reply_msg;
18008 #undef _
18009
18010 #if DPDK > 0
18011 #define _(N,n)                                                  \
18012     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18013                            vl_api_##n##_t_handler_uni,          \
18014                            vl_noop_handler,                     \
18015                            vl_api_##n##_t_endian,               \
18016                            vl_api_##n##_t_print,                \
18017                            sizeof(vl_api_##n##_t), 1);
18018   foreach_vpe_dpdk_api_reply_msg;
18019 #undef _
18020 #endif
18021
18022 #if (VPP_API_TEST_BUILTIN==0)
18023   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18024 #endif
18025
18026   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18027
18028   vam->function_by_name = hash_create_string (0, sizeof (uword));
18029
18030   vam->help_by_name = hash_create_string (0, sizeof (uword));
18031
18032   /* API messages we can send */
18033 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18034   foreach_vpe_api_msg;
18035 #undef _
18036 #if DPDK >0
18037 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18038   foreach_vpe_dpdk_api_msg;
18039 #undef _
18040 #endif
18041
18042   /* Help strings */
18043 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18044   foreach_vpe_api_msg;
18045 #undef _
18046 #if DPDK >0
18047 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18048   foreach_vpe_dpdk_api_msg;
18049 #undef _
18050 #endif
18051
18052   /* CLI functions */
18053 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18054   foreach_cli_function;
18055 #undef _
18056
18057   /* Help strings */
18058 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18059   foreach_cli_function;
18060 #undef _
18061 }
18062
18063 /*
18064  * fd.io coding-style-patch-verification: ON
18065  *
18066  * Local Variables:
18067  * eval: (c-set-style "gnu")
18068  * End:
18069  */