dhcp: multiple additions
[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   if (mp->sub_dot1ah)
918     {
919       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
920                                        format (0, "%U",
921                                                format_ethernet_address,
922                                                &mp->b_dmac));
923       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
924                                        format (0, "%U",
925                                                format_ethernet_address,
926                                                &mp->b_smac));
927       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
928       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
929     }
930 }
931
932 static void vl_api_sw_interface_set_flags_t_handler
933   (vl_api_sw_interface_set_flags_t * mp)
934 {
935   vat_main_t *vam = &vat_main;
936   if (vam->interface_event_display)
937     errmsg ("interface flags: sw_if_index %d %s %s",
938             ntohl (mp->sw_if_index),
939             mp->admin_up_down ? "admin-up" : "admin-down",
940             mp->link_up_down ? "link-up" : "link-down");
941 }
942
943 static void vl_api_sw_interface_set_flags_t_handler_json
944   (vl_api_sw_interface_set_flags_t * mp)
945 {
946   /* JSON output not supported */
947 }
948
949 static void
950 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
951 {
952   vat_main_t *vam = &vat_main;
953   i32 retval = ntohl (mp->retval);
954
955   vam->retval = retval;
956   vam->shmem_result = (u8 *) mp->reply_in_shmem;
957   vam->result_ready = 1;
958 }
959
960 static void
961 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
962 {
963   vat_main_t *vam = &vat_main;
964   vat_json_node_t node;
965   api_main_t *am = &api_main;
966   void *oldheap;
967   u8 *reply;
968
969   vat_json_init_object (&node);
970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
971   vat_json_object_add_uint (&node, "reply_in_shmem",
972                             ntohl (mp->reply_in_shmem));
973   /* Toss the shared-memory original... */
974   pthread_mutex_lock (&am->vlib_rp->mutex);
975   oldheap = svm_push_data_heap (am->vlib_rp);
976
977   reply = (u8 *) (mp->reply_in_shmem);
978   vec_free (reply);
979
980   svm_pop_heap (oldheap);
981   pthread_mutex_unlock (&am->vlib_rp->mutex);
982
983   vat_json_print (vam->ofp, &node);
984   vat_json_free (&node);
985
986   vam->retval = ntohl (mp->retval);
987   vam->result_ready = 1;
988 }
989
990 static void
991 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
992 {
993   vat_main_t *vam = &vat_main;
994   i32 retval = ntohl (mp->retval);
995
996   vam->retval = retval;
997   vam->cmd_reply = mp->reply;
998   vam->result_ready = 1;
999 }
1000
1001 static void
1002 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1003 {
1004   vat_main_t *vam = &vat_main;
1005   vat_json_node_t node;
1006
1007   vat_json_init_object (&node);
1008   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1009   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1010
1011   vat_json_print (vam->ofp, &node);
1012   vat_json_free (&node);
1013
1014   vam->retval = ntohl (mp->retval);
1015   vam->result_ready = 1;
1016 }
1017
1018 static void vl_api_classify_add_del_table_reply_t_handler
1019   (vl_api_classify_add_del_table_reply_t * mp)
1020 {
1021   vat_main_t *vam = &vat_main;
1022   i32 retval = ntohl (mp->retval);
1023   if (vam->async_mode)
1024     {
1025       vam->async_errors += (retval < 0);
1026     }
1027   else
1028     {
1029       vam->retval = retval;
1030       if (retval == 0 &&
1031           ((mp->new_table_index != 0xFFFFFFFF) ||
1032            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1033            (mp->match_n_vectors != 0xFFFFFFFF)))
1034         /*
1035          * Note: this is just barely thread-safe, depends on
1036          * the main thread spinning waiting for an answer...
1037          */
1038         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1039                 ntohl (mp->new_table_index),
1040                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1041       vam->result_ready = 1;
1042     }
1043 }
1044
1045 static void vl_api_classify_add_del_table_reply_t_handler_json
1046   (vl_api_classify_add_del_table_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_uint (&node, "new_table_index",
1054                             ntohl (mp->new_table_index));
1055   vat_json_object_add_uint (&node, "skip_n_vectors",
1056                             ntohl (mp->skip_n_vectors));
1057   vat_json_object_add_uint (&node, "match_n_vectors",
1058                             ntohl (mp->match_n_vectors));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_get_node_index_reply_t_handler
1068   (vl_api_get_node_index_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072   if (vam->async_mode)
1073     {
1074       vam->async_errors += (retval < 0);
1075     }
1076   else
1077     {
1078       vam->retval = retval;
1079       if (retval == 0)
1080         errmsg ("node index %d", ntohl (mp->node_index));
1081       vam->result_ready = 1;
1082     }
1083 }
1084
1085 static void vl_api_get_node_index_reply_t_handler_json
1086   (vl_api_get_node_index_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vat_json_init_object (&node);
1092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1093   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1094
1095   vat_json_print (vam->ofp, &node);
1096   vat_json_free (&node);
1097
1098   vam->retval = ntohl (mp->retval);
1099   vam->result_ready = 1;
1100 }
1101
1102 static void vl_api_get_next_index_reply_t_handler
1103   (vl_api_get_next_index_reply_t * mp)
1104 {
1105   vat_main_t *vam = &vat_main;
1106   i32 retval = ntohl (mp->retval);
1107   if (vam->async_mode)
1108     {
1109       vam->async_errors += (retval < 0);
1110     }
1111   else
1112     {
1113       vam->retval = retval;
1114       if (retval == 0)
1115         errmsg ("next node index %d", ntohl (mp->next_index));
1116       vam->result_ready = 1;
1117     }
1118 }
1119
1120 static void vl_api_get_next_index_reply_t_handler_json
1121   (vl_api_get_next_index_reply_t * mp)
1122 {
1123   vat_main_t *vam = &vat_main;
1124   vat_json_node_t node;
1125
1126   vat_json_init_object (&node);
1127   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1128   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1129
1130   vat_json_print (vam->ofp, &node);
1131   vat_json_free (&node);
1132
1133   vam->retval = ntohl (mp->retval);
1134   vam->result_ready = 1;
1135 }
1136
1137 static void vl_api_add_node_next_reply_t_handler
1138   (vl_api_add_node_next_reply_t * mp)
1139 {
1140   vat_main_t *vam = &vat_main;
1141   i32 retval = ntohl (mp->retval);
1142   if (vam->async_mode)
1143     {
1144       vam->async_errors += (retval < 0);
1145     }
1146   else
1147     {
1148       vam->retval = retval;
1149       if (retval == 0)
1150         errmsg ("next index %d", ntohl (mp->next_index));
1151       vam->result_ready = 1;
1152     }
1153 }
1154
1155 static void vl_api_add_node_next_reply_t_handler_json
1156   (vl_api_add_node_next_reply_t * mp)
1157 {
1158   vat_main_t *vam = &vat_main;
1159   vat_json_node_t node;
1160
1161   vat_json_init_object (&node);
1162   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1163   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1164
1165   vat_json_print (vam->ofp, &node);
1166   vat_json_free (&node);
1167
1168   vam->retval = ntohl (mp->retval);
1169   vam->result_ready = 1;
1170 }
1171
1172 static void vl_api_show_version_reply_t_handler
1173   (vl_api_show_version_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   i32 retval = ntohl (mp->retval);
1177
1178   if (retval >= 0)
1179     {
1180       errmsg ("        program: %s", mp->program);
1181       errmsg ("        version: %s", mp->version);
1182       errmsg ("     build date: %s", mp->build_date);
1183       errmsg ("build directory: %s", mp->build_directory);
1184     }
1185   vam->retval = retval;
1186   vam->result_ready = 1;
1187 }
1188
1189 static void vl_api_show_version_reply_t_handler_json
1190   (vl_api_show_version_reply_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   vat_json_node_t node;
1194
1195   vat_json_init_object (&node);
1196   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1197   vat_json_object_add_string_copy (&node, "program", mp->program);
1198   vat_json_object_add_string_copy (&node, "version", mp->version);
1199   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1200   vat_json_object_add_string_copy (&node, "build_directory",
1201                                    mp->build_directory);
1202
1203   vat_json_print (vam->ofp, &node);
1204   vat_json_free (&node);
1205
1206   vam->retval = ntohl (mp->retval);
1207   vam->result_ready = 1;
1208 }
1209
1210 static void
1211 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1212 {
1213   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1214           mp->mac_ip ? "mac/ip binding" : "address resolution",
1215           format_ip4_address, &mp->address,
1216           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1217 }
1218
1219 static void
1220 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1221 {
1222   /* JSON output not supported */
1223 }
1224
1225 static void
1226 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1227 {
1228   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1229           mp->mac_ip ? "mac/ip binding" : "address resolution",
1230           format_ip6_address, mp->address,
1231           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1232 }
1233
1234 static void
1235 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1236 {
1237   /* JSON output not supported */
1238 }
1239
1240 /*
1241  * Special-case: build the bridge domain table, maintain
1242  * the next bd id vbl.
1243  */
1244 static void vl_api_bridge_domain_details_t_handler
1245   (vl_api_bridge_domain_details_t * mp)
1246 {
1247   vat_main_t *vam = &vat_main;
1248   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1249
1250   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1251          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1252
1253   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1254          ntohl (mp->bd_id), mp->learn, mp->forward,
1255          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1256
1257   if (n_sw_ifs)
1258     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1259 }
1260
1261 static void vl_api_bridge_domain_details_t_handler_json
1262   (vl_api_bridge_domain_details_t * mp)
1263 {
1264   vat_main_t *vam = &vat_main;
1265   vat_json_node_t *node, *array = NULL;
1266
1267   if (VAT_JSON_ARRAY != vam->json_tree.type)
1268     {
1269       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1270       vat_json_init_array (&vam->json_tree);
1271     }
1272   node = vat_json_array_add (&vam->json_tree);
1273
1274   vat_json_init_object (node);
1275   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1276   vat_json_object_add_uint (node, "flood", mp->flood);
1277   vat_json_object_add_uint (node, "forward", mp->forward);
1278   vat_json_object_add_uint (node, "learn", mp->learn);
1279   vat_json_object_add_uint (node, "bvi_sw_if_index",
1280                             ntohl (mp->bvi_sw_if_index));
1281   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1282   array = vat_json_object_add (node, "sw_if");
1283   vat_json_init_array (array);
1284 }
1285
1286 /*
1287  * Special-case: build the bridge domain sw if table.
1288  */
1289 static void vl_api_bridge_domain_sw_if_details_t_handler
1290   (vl_api_bridge_domain_sw_if_details_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   hash_pair_t *p;
1294   u8 *sw_if_name = 0;
1295   u32 sw_if_index;
1296
1297   sw_if_index = ntohl (mp->sw_if_index);
1298   /* *INDENT-OFF* */
1299   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1300   ({
1301     if ((u32) p->value[0] == sw_if_index)
1302       {
1303         sw_if_name = (u8 *)(p->key);
1304         break;
1305       }
1306   }));
1307   /* *INDENT-ON* */
1308
1309   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1310          mp->shg, sw_if_name ? (char *) sw_if_name :
1311          "sw_if_index not found!");
1312 }
1313
1314 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1315   (vl_api_bridge_domain_sw_if_details_t * mp)
1316 {
1317   vat_main_t *vam = &vat_main;
1318   vat_json_node_t *node = NULL;
1319   uword last_index = 0;
1320
1321   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1322   ASSERT (vec_len (vam->json_tree.array) >= 1);
1323   last_index = vec_len (vam->json_tree.array) - 1;
1324   node = &vam->json_tree.array[last_index];
1325   node = vat_json_object_get_element (node, "sw_if");
1326   ASSERT (NULL != node);
1327   node = vat_json_array_add (node);
1328
1329   vat_json_init_object (node);
1330   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1331   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1332   vat_json_object_add_uint (node, "shg", mp->shg);
1333 }
1334
1335 static void vl_api_control_ping_reply_t_handler
1336   (vl_api_control_ping_reply_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   i32 retval = ntohl (mp->retval);
1340   if (vam->async_mode)
1341     {
1342       vam->async_errors += (retval < 0);
1343     }
1344   else
1345     {
1346       vam->retval = retval;
1347       vam->result_ready = 1;
1348     }
1349 }
1350
1351 static void vl_api_control_ping_reply_t_handler_json
1352   (vl_api_control_ping_reply_t * mp)
1353 {
1354   vat_main_t *vam = &vat_main;
1355   i32 retval = ntohl (mp->retval);
1356
1357   if (VAT_JSON_NONE != vam->json_tree.type)
1358     {
1359       vat_json_print (vam->ofp, &vam->json_tree);
1360       vat_json_free (&vam->json_tree);
1361       vam->json_tree.type = VAT_JSON_NONE;
1362     }
1363   else
1364     {
1365       /* just print [] */
1366       vat_json_init_array (&vam->json_tree);
1367       vat_json_print (vam->ofp, &vam->json_tree);
1368       vam->json_tree.type = VAT_JSON_NONE;
1369     }
1370
1371   vam->retval = retval;
1372   vam->result_ready = 1;
1373 }
1374
1375 static void
1376 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1377 {
1378   vat_main_t *vam = &vat_main;
1379   i32 retval = ntohl (mp->retval);
1380   if (vam->async_mode)
1381     {
1382       vam->async_errors += (retval < 0);
1383     }
1384   else
1385     {
1386       vam->retval = retval;
1387       vam->result_ready = 1;
1388     }
1389 }
1390
1391 static void vl_api_l2_flags_reply_t_handler_json
1392   (vl_api_l2_flags_reply_t * mp)
1393 {
1394   vat_main_t *vam = &vat_main;
1395   vat_json_node_t node;
1396
1397   vat_json_init_object (&node);
1398   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1399   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1400                             ntohl (mp->resulting_feature_bitmap));
1401
1402   vat_json_print (vam->ofp, &node);
1403   vat_json_free (&node);
1404
1405   vam->retval = ntohl (mp->retval);
1406   vam->result_ready = 1;
1407 }
1408
1409 static void vl_api_bridge_flags_reply_t_handler
1410   (vl_api_bridge_flags_reply_t * mp)
1411 {
1412   vat_main_t *vam = &vat_main;
1413   i32 retval = ntohl (mp->retval);
1414   if (vam->async_mode)
1415     {
1416       vam->async_errors += (retval < 0);
1417     }
1418   else
1419     {
1420       vam->retval = retval;
1421       vam->result_ready = 1;
1422     }
1423 }
1424
1425 static void vl_api_bridge_flags_reply_t_handler_json
1426   (vl_api_bridge_flags_reply_t * mp)
1427 {
1428   vat_main_t *vam = &vat_main;
1429   vat_json_node_t node;
1430
1431   vat_json_init_object (&node);
1432   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1433   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1434                             ntohl (mp->resulting_feature_bitmap));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_tap_connect_reply_t_handler
1444   (vl_api_tap_connect_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->sw_if_index = ntohl (mp->sw_if_index);
1456       vam->result_ready = 1;
1457     }
1458
1459 }
1460
1461 static void vl_api_tap_connect_reply_t_handler_json
1462   (vl_api_tap_connect_reply_t * mp)
1463 {
1464   vat_main_t *vam = &vat_main;
1465   vat_json_node_t node;
1466
1467   vat_json_init_object (&node);
1468   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1469   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1470
1471   vat_json_print (vam->ofp, &node);
1472   vat_json_free (&node);
1473
1474   vam->retval = ntohl (mp->retval);
1475   vam->result_ready = 1;
1476
1477 }
1478
1479 static void
1480 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1481 {
1482   vat_main_t *vam = &vat_main;
1483   i32 retval = ntohl (mp->retval);
1484   if (vam->async_mode)
1485     {
1486       vam->async_errors += (retval < 0);
1487     }
1488   else
1489     {
1490       vam->retval = retval;
1491       vam->sw_if_index = ntohl (mp->sw_if_index);
1492       vam->result_ready = 1;
1493     }
1494 }
1495
1496 static void vl_api_tap_modify_reply_t_handler_json
1497   (vl_api_tap_modify_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   vat_json_node_t node;
1501
1502   vat_json_init_object (&node);
1503   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1504   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1505
1506   vat_json_print (vam->ofp, &node);
1507   vat_json_free (&node);
1508
1509   vam->retval = ntohl (mp->retval);
1510   vam->result_ready = 1;
1511 }
1512
1513 static void
1514 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1515 {
1516   vat_main_t *vam = &vat_main;
1517   i32 retval = ntohl (mp->retval);
1518   if (vam->async_mode)
1519     {
1520       vam->async_errors += (retval < 0);
1521     }
1522   else
1523     {
1524       vam->retval = retval;
1525       vam->result_ready = 1;
1526     }
1527 }
1528
1529 static void vl_api_tap_delete_reply_t_handler_json
1530   (vl_api_tap_delete_reply_t * mp)
1531 {
1532   vat_main_t *vam = &vat_main;
1533   vat_json_node_t node;
1534
1535   vat_json_init_object (&node);
1536   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1546   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->result_ready = 1;
1558     }
1559 }
1560
1561 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1562   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1563 {
1564   vat_main_t *vam = &vat_main;
1565   vat_json_node_t node;
1566
1567   vat_json_init_object (&node);
1568   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1569   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1570                             ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1580   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1597   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613
1614 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1615   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1616 {
1617   vat_main_t *vam = &vat_main;
1618   i32 retval = ntohl (mp->retval);
1619   if (vam->async_mode)
1620     {
1621       vam->async_errors += (retval < 0);
1622     }
1623   else
1624     {
1625       vam->retval = retval;
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1631   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1648   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   i32 retval = ntohl (mp->retval);
1652   if (vam->async_mode)
1653     {
1654       vam->async_errors += (retval < 0);
1655     }
1656   else
1657     {
1658       vam->retval = retval;
1659       vam->sw_if_index = ntohl (mp->sw_if_index);
1660       vam->result_ready = 1;
1661     }
1662 }
1663
1664 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1665   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   vat_json_node_t node;
1669
1670   vat_json_init_object (&node);
1671   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1672   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1673
1674   vat_json_print (vam->ofp, &node);
1675   vat_json_free (&node);
1676
1677   vam->retval = ntohl (mp->retval);
1678   vam->result_ready = 1;
1679 }
1680
1681 static void vl_api_gre_add_del_tunnel_reply_t_handler
1682   (vl_api_gre_add_del_tunnel_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   i32 retval = ntohl (mp->retval);
1686   if (vam->async_mode)
1687     {
1688       vam->async_errors += (retval < 0);
1689     }
1690   else
1691     {
1692       vam->retval = retval;
1693       vam->sw_if_index = ntohl (mp->sw_if_index);
1694       vam->result_ready = 1;
1695     }
1696 }
1697
1698 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1699   (vl_api_gre_add_del_tunnel_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   vat_json_node_t node;
1703
1704   vat_json_init_object (&node);
1705   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1706   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1707
1708   vat_json_print (vam->ofp, &node);
1709   vat_json_free (&node);
1710
1711   vam->retval = ntohl (mp->retval);
1712   vam->result_ready = 1;
1713 }
1714
1715 static void vl_api_create_vhost_user_if_reply_t_handler
1716   (vl_api_create_vhost_user_if_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   i32 retval = ntohl (mp->retval);
1720   if (vam->async_mode)
1721     {
1722       vam->async_errors += (retval < 0);
1723     }
1724   else
1725     {
1726       vam->retval = retval;
1727       vam->sw_if_index = ntohl (mp->sw_if_index);
1728       vam->result_ready = 1;
1729     }
1730 }
1731
1732 static void vl_api_create_vhost_user_if_reply_t_handler_json
1733   (vl_api_create_vhost_user_if_reply_t * mp)
1734 {
1735   vat_main_t *vam = &vat_main;
1736   vat_json_node_t node;
1737
1738   vat_json_init_object (&node);
1739   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1740   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1741
1742   vat_json_print (vam->ofp, &node);
1743   vat_json_free (&node);
1744
1745   vam->retval = ntohl (mp->retval);
1746   vam->result_ready = 1;
1747 }
1748
1749 static void vl_api_ip_address_details_t_handler
1750   (vl_api_ip_address_details_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   static ip_address_details_t empty_ip_address_details = { {0} };
1754   ip_address_details_t *address = NULL;
1755   ip_details_t *current_ip_details = NULL;
1756   ip_details_t *details = NULL;
1757
1758   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1759
1760   if (!details || vam->current_sw_if_index >= vec_len (details)
1761       || !details[vam->current_sw_if_index].present)
1762     {
1763       errmsg ("ip address details arrived but not stored");
1764       errmsg ("ip_dump should be called first");
1765       return;
1766     }
1767
1768   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1769
1770 #define addresses (current_ip_details->addr)
1771
1772   vec_validate_init_empty (addresses, vec_len (addresses),
1773                            empty_ip_address_details);
1774
1775   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1776
1777   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1778   address->prefix_length = mp->prefix_length;
1779 #undef addresses
1780 }
1781
1782 static void vl_api_ip_address_details_t_handler_json
1783   (vl_api_ip_address_details_t * mp)
1784 {
1785   vat_main_t *vam = &vat_main;
1786   vat_json_node_t *node = NULL;
1787   struct in6_addr ip6;
1788   struct in_addr ip4;
1789
1790   if (VAT_JSON_ARRAY != vam->json_tree.type)
1791     {
1792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1793       vat_json_init_array (&vam->json_tree);
1794     }
1795   node = vat_json_array_add (&vam->json_tree);
1796
1797   vat_json_init_object (node);
1798   if (vam->is_ipv6)
1799     {
1800       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1801       vat_json_object_add_ip6 (node, "ip", ip6);
1802     }
1803   else
1804     {
1805       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1806       vat_json_object_add_ip4 (node, "ip", ip4);
1807     }
1808   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1809 }
1810
1811 static void
1812 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1813 {
1814   vat_main_t *vam = &vat_main;
1815   static ip_details_t empty_ip_details = { 0 };
1816   ip_details_t *ip = NULL;
1817   u32 sw_if_index = ~0;
1818
1819   sw_if_index = ntohl (mp->sw_if_index);
1820
1821   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1822                            sw_if_index, empty_ip_details);
1823
1824   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1825                          sw_if_index);
1826
1827   ip->present = 1;
1828 }
1829
1830 static void
1831 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1832 {
1833   vat_main_t *vam = &vat_main;
1834
1835   if (VAT_JSON_ARRAY != vam->json_tree.type)
1836     {
1837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1838       vat_json_init_array (&vam->json_tree);
1839     }
1840   vat_json_array_add_uint (&vam->json_tree,
1841                            clib_net_to_host_u32 (mp->sw_if_index));
1842 }
1843
1844 static void vl_api_map_domain_details_t_handler_json
1845   (vl_api_map_domain_details_t * mp)
1846 {
1847   vat_json_node_t *node = NULL;
1848   vat_main_t *vam = &vat_main;
1849   struct in6_addr ip6;
1850   struct in_addr ip4;
1851
1852   if (VAT_JSON_ARRAY != vam->json_tree.type)
1853     {
1854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1855       vat_json_init_array (&vam->json_tree);
1856     }
1857
1858   node = vat_json_array_add (&vam->json_tree);
1859   vat_json_init_object (node);
1860
1861   vat_json_object_add_uint (node, "domain_index",
1862                             clib_net_to_host_u32 (mp->domain_index));
1863   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1864   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1865   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1866   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1867   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1868   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1869   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1870   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1871   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1872   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1873   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1874   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1875   vat_json_object_add_uint (node, "flags", mp->flags);
1876   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1877   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1878 }
1879
1880 static void vl_api_map_domain_details_t_handler
1881   (vl_api_map_domain_details_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884
1885   if (mp->is_translation)
1886     {
1887       print (vam->ofp,
1888              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1889              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1890              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1891              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1892              clib_net_to_host_u32 (mp->domain_index));
1893     }
1894   else
1895     {
1896       print (vam->ofp,
1897              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1898              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1899              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1900              format_ip6_address, mp->ip6_src,
1901              clib_net_to_host_u32 (mp->domain_index));
1902     }
1903   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1904          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1905          mp->is_translation ? "map-t" : "");
1906 }
1907
1908 static void vl_api_map_rule_details_t_handler_json
1909   (vl_api_map_rule_details_t * mp)
1910 {
1911   struct in6_addr ip6;
1912   vat_json_node_t *node = NULL;
1913   vat_main_t *vam = &vat_main;
1914
1915   if (VAT_JSON_ARRAY != vam->json_tree.type)
1916     {
1917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1918       vat_json_init_array (&vam->json_tree);
1919     }
1920
1921   node = vat_json_array_add (&vam->json_tree);
1922   vat_json_init_object (node);
1923
1924   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1925   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1926   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1927 }
1928
1929 static void
1930 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1934          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1935 }
1936
1937 static void
1938 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1939 {
1940   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1941           "router_addr %U host_mac %U",
1942           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1943           format_ip4_address, &mp->host_address,
1944           format_ip4_address, &mp->router_address,
1945           format_ethernet_address, mp->host_mac);
1946 }
1947
1948 static void vl_api_dhcp_compl_event_t_handler_json
1949   (vl_api_dhcp_compl_event_t * mp)
1950 {
1951   /* JSON output not supported */
1952 }
1953
1954 static void
1955 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1956                               u32 counter)
1957 {
1958   vat_main_t *vam = &vat_main;
1959   static u64 default_counter = 0;
1960
1961   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1962                            NULL);
1963   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1964                            sw_if_index, default_counter);
1965   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1966 }
1967
1968 static void
1969 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1970                                 interface_counter_t counter)
1971 {
1972   vat_main_t *vam = &vat_main;
1973   static interface_counter_t default_counter = { 0, };
1974
1975   vec_validate_init_empty (vam->combined_interface_counters,
1976                            vnet_counter_type, NULL);
1977   vec_validate_init_empty (vam->combined_interface_counters
1978                            [vnet_counter_type], sw_if_index, default_counter);
1979   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1980 }
1981
1982 static void vl_api_vnet_interface_counters_t_handler
1983   (vl_api_vnet_interface_counters_t * mp)
1984 {
1985   /* not supported */
1986 }
1987
1988 static void vl_api_vnet_interface_counters_t_handler_json
1989   (vl_api_vnet_interface_counters_t * mp)
1990 {
1991   interface_counter_t counter;
1992   vlib_counter_t *v;
1993   u64 *v_packets;
1994   u64 packets;
1995   u32 count;
1996   u32 first_sw_if_index;
1997   int i;
1998
1999   count = ntohl (mp->count);
2000   first_sw_if_index = ntohl (mp->first_sw_if_index);
2001
2002   if (!mp->is_combined)
2003     {
2004       v_packets = (u64 *) & mp->data;
2005       for (i = 0; i < count; i++)
2006         {
2007           packets =
2008             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2009           set_simple_interface_counter (mp->vnet_counter_type,
2010                                         first_sw_if_index + i, packets);
2011           v_packets++;
2012         }
2013     }
2014   else
2015     {
2016       v = (vlib_counter_t *) & mp->data;
2017       for (i = 0; i < count; i++)
2018         {
2019           counter.packets =
2020             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2021           counter.bytes =
2022             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2023           set_combined_interface_counter (mp->vnet_counter_type,
2024                                           first_sw_if_index + i, counter);
2025           v++;
2026         }
2027     }
2028 }
2029
2030 static u32
2031 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2032 {
2033   vat_main_t *vam = &vat_main;
2034   u32 i;
2035
2036   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2037     {
2038       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2039         {
2040           return i;
2041         }
2042     }
2043   return ~0;
2044 }
2045
2046 static u32
2047 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2048 {
2049   vat_main_t *vam = &vat_main;
2050   u32 i;
2051
2052   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2053     {
2054       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2055         {
2056           return i;
2057         }
2058     }
2059   return ~0;
2060 }
2061
2062 static void vl_api_vnet_ip4_fib_counters_t_handler
2063   (vl_api_vnet_ip4_fib_counters_t * mp)
2064 {
2065   /* not supported */
2066 }
2067
2068 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2069   (vl_api_vnet_ip4_fib_counters_t * mp)
2070 {
2071   vat_main_t *vam = &vat_main;
2072   vl_api_ip4_fib_counter_t *v;
2073   ip4_fib_counter_t *counter;
2074   struct in_addr ip4;
2075   u32 vrf_id;
2076   u32 vrf_index;
2077   u32 count;
2078   int i;
2079
2080   vrf_id = ntohl (mp->vrf_id);
2081   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2082   if (~0 == vrf_index)
2083     {
2084       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2085       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2086       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2087       vec_validate (vam->ip4_fib_counters, vrf_index);
2088       vam->ip4_fib_counters[vrf_index] = NULL;
2089     }
2090
2091   vec_free (vam->ip4_fib_counters[vrf_index]);
2092   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2093   count = ntohl (mp->count);
2094   for (i = 0; i < count; i++)
2095     {
2096       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2097       counter = &vam->ip4_fib_counters[vrf_index][i];
2098       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2099       counter->address = ip4;
2100       counter->address_length = v->address_length;
2101       counter->packets = clib_net_to_host_u64 (v->packets);
2102       counter->bytes = clib_net_to_host_u64 (v->bytes);
2103       v++;
2104     }
2105 }
2106
2107 static void vl_api_vnet_ip4_nbr_counters_t_handler
2108   (vl_api_vnet_ip4_nbr_counters_t * mp)
2109 {
2110   /* not supported */
2111 }
2112
2113 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2114   (vl_api_vnet_ip4_nbr_counters_t * mp)
2115 {
2116   vat_main_t *vam = &vat_main;
2117   vl_api_ip4_nbr_counter_t *v;
2118   ip4_nbr_counter_t *counter;
2119   u32 sw_if_index;
2120   u32 count;
2121   int i;
2122
2123   sw_if_index = ntohl (mp->sw_if_index);
2124   count = ntohl (mp->count);
2125   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2126
2127   if (mp->begin)
2128     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2129
2130   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2131   for (i = 0; i < count; i++)
2132     {
2133       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2134       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2135       counter->address.s_addr = v->address;
2136       counter->packets = clib_net_to_host_u64 (v->packets);
2137       counter->bytes = clib_net_to_host_u64 (v->bytes);
2138       counter->linkt = v->link_type;
2139       v++;
2140     }
2141 }
2142
2143 static void vl_api_vnet_ip6_fib_counters_t_handler
2144   (vl_api_vnet_ip6_fib_counters_t * mp)
2145 {
2146   /* not supported */
2147 }
2148
2149 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2150   (vl_api_vnet_ip6_fib_counters_t * mp)
2151 {
2152   vat_main_t *vam = &vat_main;
2153   vl_api_ip6_fib_counter_t *v;
2154   ip6_fib_counter_t *counter;
2155   struct in6_addr ip6;
2156   u32 vrf_id;
2157   u32 vrf_index;
2158   u32 count;
2159   int i;
2160
2161   vrf_id = ntohl (mp->vrf_id);
2162   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2163   if (~0 == vrf_index)
2164     {
2165       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2166       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2167       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2168       vec_validate (vam->ip6_fib_counters, vrf_index);
2169       vam->ip6_fib_counters[vrf_index] = NULL;
2170     }
2171
2172   vec_free (vam->ip6_fib_counters[vrf_index]);
2173   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2174   count = ntohl (mp->count);
2175   for (i = 0; i < count; i++)
2176     {
2177       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2178       counter = &vam->ip6_fib_counters[vrf_index][i];
2179       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2180       counter->address = ip6;
2181       counter->address_length = v->address_length;
2182       counter->packets = clib_net_to_host_u64 (v->packets);
2183       counter->bytes = clib_net_to_host_u64 (v->bytes);
2184       v++;
2185     }
2186 }
2187
2188 static void vl_api_vnet_ip6_nbr_counters_t_handler
2189   (vl_api_vnet_ip6_nbr_counters_t * mp)
2190 {
2191   /* not supported */
2192 }
2193
2194 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2195   (vl_api_vnet_ip6_nbr_counters_t * mp)
2196 {
2197   vat_main_t *vam = &vat_main;
2198   vl_api_ip6_nbr_counter_t *v;
2199   ip6_nbr_counter_t *counter;
2200   struct in6_addr ip6;
2201   u32 sw_if_index;
2202   u32 count;
2203   int i;
2204
2205   sw_if_index = ntohl (mp->sw_if_index);
2206   count = ntohl (mp->count);
2207   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2208
2209   if (mp->begin)
2210     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2211
2212   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2213   for (i = 0; i < count; i++)
2214     {
2215       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2216       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2217       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2218       counter->address = ip6;
2219       counter->packets = clib_net_to_host_u64 (v->packets);
2220       counter->bytes = clib_net_to_host_u64 (v->bytes);
2221       v++;
2222     }
2223 }
2224
2225 static void vl_api_get_first_msg_id_reply_t_handler
2226   (vl_api_get_first_msg_id_reply_t * mp)
2227 {
2228   vat_main_t *vam = &vat_main;
2229   i32 retval = ntohl (mp->retval);
2230
2231   if (vam->async_mode)
2232     {
2233       vam->async_errors += (retval < 0);
2234     }
2235   else
2236     {
2237       vam->retval = retval;
2238       vam->result_ready = 1;
2239     }
2240   if (retval >= 0)
2241     {
2242       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2243     }
2244 }
2245
2246 static void vl_api_get_first_msg_id_reply_t_handler_json
2247   (vl_api_get_first_msg_id_reply_t * mp)
2248 {
2249   vat_main_t *vam = &vat_main;
2250   vat_json_node_t node;
2251
2252   vat_json_init_object (&node);
2253   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2254   vat_json_object_add_uint (&node, "first_msg_id",
2255                             (uint) ntohs (mp->first_msg_id));
2256
2257   vat_json_print (vam->ofp, &node);
2258   vat_json_free (&node);
2259
2260   vam->retval = ntohl (mp->retval);
2261   vam->result_ready = 1;
2262 }
2263
2264 static void vl_api_get_node_graph_reply_t_handler
2265   (vl_api_get_node_graph_reply_t * mp)
2266 {
2267   vat_main_t *vam = &vat_main;
2268   api_main_t *am = &api_main;
2269   i32 retval = ntohl (mp->retval);
2270   u8 *pvt_copy, *reply;
2271   void *oldheap;
2272   vlib_node_t *node;
2273   int i;
2274
2275   if (vam->async_mode)
2276     {
2277       vam->async_errors += (retval < 0);
2278     }
2279   else
2280     {
2281       vam->retval = retval;
2282       vam->result_ready = 1;
2283     }
2284
2285   /* "Should never happen..." */
2286   if (retval != 0)
2287     return;
2288
2289   reply = (u8 *) (mp->reply_in_shmem);
2290   pvt_copy = vec_dup (reply);
2291
2292   /* Toss the shared-memory original... */
2293   pthread_mutex_lock (&am->vlib_rp->mutex);
2294   oldheap = svm_push_data_heap (am->vlib_rp);
2295
2296   vec_free (reply);
2297
2298   svm_pop_heap (oldheap);
2299   pthread_mutex_unlock (&am->vlib_rp->mutex);
2300
2301   if (vam->graph_nodes)
2302     {
2303       hash_free (vam->graph_node_index_by_name);
2304
2305       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2306         {
2307           node = vam->graph_nodes[i];
2308           vec_free (node->name);
2309           vec_free (node->next_nodes);
2310           vec_free (node);
2311         }
2312       vec_free (vam->graph_nodes);
2313     }
2314
2315   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2316   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2317   vec_free (pvt_copy);
2318
2319   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2320     {
2321       node = vam->graph_nodes[i];
2322       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2323     }
2324 }
2325
2326 static void vl_api_get_node_graph_reply_t_handler_json
2327   (vl_api_get_node_graph_reply_t * mp)
2328 {
2329   vat_main_t *vam = &vat_main;
2330   api_main_t *am = &api_main;
2331   void *oldheap;
2332   vat_json_node_t node;
2333   u8 *reply;
2334
2335   /* $$$$ make this real? */
2336   vat_json_init_object (&node);
2337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2338   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2339
2340   reply = (u8 *) (mp->reply_in_shmem);
2341
2342   /* Toss the shared-memory original... */
2343   pthread_mutex_lock (&am->vlib_rp->mutex);
2344   oldheap = svm_push_data_heap (am->vlib_rp);
2345
2346   vec_free (reply);
2347
2348   svm_pop_heap (oldheap);
2349   pthread_mutex_unlock (&am->vlib_rp->mutex);
2350
2351   vat_json_print (vam->ofp, &node);
2352   vat_json_free (&node);
2353
2354   vam->retval = ntohl (mp->retval);
2355   vam->result_ready = 1;
2356 }
2357
2358 static void
2359 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2360 {
2361   vat_main_t *vam = &vat_main;
2362   u8 *s = 0;
2363
2364   if (mp->local)
2365     {
2366       s = format (s, "%=16d%=16d%=16d",
2367                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2368     }
2369   else
2370     {
2371       s = format (s, "%=16U%=16d%=16d",
2372                   mp->is_ipv6 ? format_ip6_address :
2373                   format_ip4_address,
2374                   mp->ip_address, mp->priority, mp->weight);
2375     }
2376
2377   print (vam->ofp, "%v", s);
2378   vec_free (s);
2379 }
2380
2381 static void
2382 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2383                                             mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   vat_json_node_t *node = NULL;
2387   struct in6_addr ip6;
2388   struct in_addr ip4;
2389
2390   if (VAT_JSON_ARRAY != vam->json_tree.type)
2391     {
2392       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2393       vat_json_init_array (&vam->json_tree);
2394     }
2395   node = vat_json_array_add (&vam->json_tree);
2396   vat_json_init_object (node);
2397
2398   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2399   vat_json_object_add_uint (node, "priority", mp->priority);
2400   vat_json_object_add_uint (node, "weight", mp->weight);
2401
2402   if (mp->local)
2403     vat_json_object_add_uint (node, "sw_if_index",
2404                               clib_net_to_host_u32 (mp->sw_if_index));
2405   else
2406     {
2407       if (mp->is_ipv6)
2408         {
2409           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2410           vat_json_object_add_ip6 (node, "address", ip6);
2411         }
2412       else
2413         {
2414           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2415           vat_json_object_add_ip4 (node, "address", ip4);
2416         }
2417     }
2418 }
2419
2420 static void
2421 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2422                                            mp)
2423 {
2424   vat_main_t *vam = &vat_main;
2425   u8 *ls_name = 0;
2426
2427   ls_name = format (0, "%s", mp->ls_name);
2428
2429   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2430          ls_name);
2431   vec_free (ls_name);
2432 }
2433
2434 static void
2435   vl_api_lisp_locator_set_details_t_handler_json
2436   (vl_api_lisp_locator_set_details_t * mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   vat_json_node_t *node = 0;
2440   u8 *ls_name = 0;
2441
2442   ls_name = format (0, "%s", mp->ls_name);
2443   vec_add1 (ls_name, 0);
2444
2445   if (VAT_JSON_ARRAY != vam->json_tree.type)
2446     {
2447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2448       vat_json_init_array (&vam->json_tree);
2449     }
2450   node = vat_json_array_add (&vam->json_tree);
2451
2452   vat_json_init_object (node);
2453   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2454   vat_json_object_add_uint (node, "ls_index",
2455                             clib_net_to_host_u32 (mp->ls_index));
2456   vec_free (ls_name);
2457 }
2458
2459 static u8 *
2460 format_lisp_flat_eid (u8 * s, va_list * args)
2461 {
2462   u32 type = va_arg (*args, u32);
2463   u8 *eid = va_arg (*args, u8 *);
2464   u32 eid_len = va_arg (*args, u32);
2465
2466   switch (type)
2467     {
2468     case 0:
2469       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2470     case 1:
2471       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2472     case 2:
2473       return format (s, "%U", format_ethernet_address, eid);
2474     }
2475   return 0;
2476 }
2477
2478 static u8 *
2479 format_lisp_eid_vat (u8 * s, va_list * args)
2480 {
2481   u32 type = va_arg (*args, u32);
2482   u8 *eid = va_arg (*args, u8 *);
2483   u32 eid_len = va_arg (*args, u32);
2484   u8 *seid = va_arg (*args, u8 *);
2485   u32 seid_len = va_arg (*args, u32);
2486   u32 is_src_dst = va_arg (*args, u32);
2487
2488   if (is_src_dst)
2489     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2490
2491   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2492
2493   return s;
2494 }
2495
2496 static void
2497 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2498 {
2499   vat_main_t *vam = &vat_main;
2500   u8 *s = 0, *eid = 0;
2501
2502   if (~0 == mp->locator_set_index)
2503     s = format (0, "action: %d", mp->action);
2504   else
2505     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2506
2507   eid = format (0, "%U", format_lisp_eid_vat,
2508                 mp->eid_type,
2509                 mp->eid,
2510                 mp->eid_prefix_len,
2511                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2512   vec_add1 (eid, 0);
2513
2514   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2515          clib_net_to_host_u32 (mp->vni),
2516          eid,
2517          mp->is_local ? "local" : "remote",
2518          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2519          clib_net_to_host_u16 (mp->key_id), mp->key);
2520
2521   vec_free (s);
2522   vec_free (eid);
2523 }
2524
2525 static void
2526 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2527                                               * mp)
2528 {
2529   vat_main_t *vam = &vat_main;
2530   vat_json_node_t *node = 0;
2531   u8 *eid = 0;
2532
2533   if (VAT_JSON_ARRAY != vam->json_tree.type)
2534     {
2535       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2536       vat_json_init_array (&vam->json_tree);
2537     }
2538   node = vat_json_array_add (&vam->json_tree);
2539
2540   vat_json_init_object (node);
2541   if (~0 == mp->locator_set_index)
2542     vat_json_object_add_uint (node, "action", mp->action);
2543   else
2544     vat_json_object_add_uint (node, "locator_set_index",
2545                               clib_net_to_host_u32 (mp->locator_set_index));
2546
2547   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2548   eid = format (0, "%U", format_lisp_eid_vat,
2549                 mp->eid_type,
2550                 mp->eid,
2551                 mp->eid_prefix_len,
2552                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2553   vec_add1 (eid, 0);
2554   vat_json_object_add_string_copy (node, "eid", eid);
2555   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2556   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2557   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2558
2559   if (mp->key_id)
2560     {
2561       vat_json_object_add_uint (node, "key_id",
2562                                 clib_net_to_host_u16 (mp->key_id));
2563       vat_json_object_add_string_copy (node, "key", mp->key);
2564     }
2565   vec_free (eid);
2566 }
2567
2568 static void
2569   vl_api_lisp_eid_table_map_details_t_handler
2570   (vl_api_lisp_eid_table_map_details_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573
2574   u8 *line = format (0, "%=10d%=10d",
2575                      clib_net_to_host_u32 (mp->vni),
2576                      clib_net_to_host_u32 (mp->dp_table));
2577   print (vam->ofp, "%v", line);
2578   vec_free (line);
2579 }
2580
2581 static void
2582   vl_api_lisp_eid_table_map_details_t_handler_json
2583   (vl_api_lisp_eid_table_map_details_t * mp)
2584 {
2585   vat_main_t *vam = &vat_main;
2586   vat_json_node_t *node = NULL;
2587
2588   if (VAT_JSON_ARRAY != vam->json_tree.type)
2589     {
2590       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2591       vat_json_init_array (&vam->json_tree);
2592     }
2593   node = vat_json_array_add (&vam->json_tree);
2594   vat_json_init_object (node);
2595   vat_json_object_add_uint (node, "dp_table",
2596                             clib_net_to_host_u32 (mp->dp_table));
2597   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2598 }
2599
2600 static void
2601   vl_api_lisp_eid_table_vni_details_t_handler
2602   (vl_api_lisp_eid_table_vni_details_t * mp)
2603 {
2604   vat_main_t *vam = &vat_main;
2605
2606   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2607   print (vam->ofp, "%v", line);
2608   vec_free (line);
2609 }
2610
2611 static void
2612   vl_api_lisp_eid_table_vni_details_t_handler_json
2613   (vl_api_lisp_eid_table_vni_details_t * mp)
2614 {
2615   vat_main_t *vam = &vat_main;
2616   vat_json_node_t *node = NULL;
2617
2618   if (VAT_JSON_ARRAY != vam->json_tree.type)
2619     {
2620       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2621       vat_json_init_array (&vam->json_tree);
2622     }
2623   node = vat_json_array_add (&vam->json_tree);
2624   vat_json_init_object (node);
2625   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2626 }
2627
2628 static void
2629   vl_api_show_lisp_map_register_state_reply_t_handler
2630   (vl_api_show_lisp_map_register_state_reply_t * mp)
2631 {
2632   vat_main_t *vam = &vat_main;
2633   int retval = clib_net_to_host_u32 (mp->retval);
2634
2635   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2636
2637   vam->retval = retval;
2638   vam->result_ready = 1;
2639 }
2640
2641 static void
2642   vl_api_show_lisp_map_register_state_reply_t_handler_json
2643   (vl_api_show_lisp_map_register_state_reply_t * mp)
2644 {
2645   vat_main_t *vam = &vat_main;
2646   vat_json_node_t _node, *node = &_node;
2647   int retval = clib_net_to_host_u32 (mp->retval);
2648
2649   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2650
2651   vat_json_init_object (node);
2652   vat_json_object_add_string_copy (node, "state", s);
2653
2654   vat_json_print (vam->ofp, node);
2655   vat_json_free (node);
2656
2657   vam->retval = retval;
2658   vam->result_ready = 1;
2659   vec_free (s);
2660 }
2661
2662 static void
2663   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2664   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2665 {
2666   vat_main_t *vam = &vat_main;
2667   int retval = clib_net_to_host_u32 (mp->retval);
2668
2669   if (retval)
2670     goto end;
2671
2672   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2673 end:
2674   vam->retval = retval;
2675   vam->result_ready = 1;
2676 }
2677
2678 static void
2679   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2680   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2681 {
2682   vat_main_t *vam = &vat_main;
2683   vat_json_node_t _node, *node = &_node;
2684   int retval = clib_net_to_host_u32 (mp->retval);
2685
2686   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2687   vat_json_init_object (node);
2688   vat_json_object_add_string_copy (node, "state", s);
2689
2690   vat_json_print (vam->ofp, node);
2691   vat_json_free (node);
2692
2693   vam->retval = retval;
2694   vam->result_ready = 1;
2695   vec_free (s);
2696 }
2697
2698 static void
2699 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2700 {
2701   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2702   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2703 }
2704
2705 static void
2706   gpe_fwd_entries_get_reply_t_net_to_host
2707   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2708 {
2709   u32 i;
2710
2711   mp->count = clib_net_to_host_u32 (mp->count);
2712   for (i = 0; i < mp->count; i++)
2713     {
2714       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2715     }
2716 }
2717
2718 static void
2719   vl_api_gpe_fwd_entry_path_details_t_handler
2720   (vl_api_gpe_fwd_entry_path_details_t * mp)
2721 {
2722   vat_main_t *vam = &vat_main;
2723   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2724
2725   if (mp->lcl_loc.is_ip4)
2726     format_ip_address_fcn = format_ip4_address;
2727   else
2728     format_ip_address_fcn = format_ip6_address;
2729
2730   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2731          format_ip_address_fcn, &mp->lcl_loc,
2732          format_ip_address_fcn, &mp->rmt_loc);
2733 }
2734
2735 static void
2736 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2737 {
2738   struct in6_addr ip6;
2739   struct in_addr ip4;
2740
2741   if (loc->is_ip4)
2742     {
2743       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2744       vat_json_object_add_ip4 (n, "address", ip4);
2745     }
2746   else
2747     {
2748       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2749       vat_json_object_add_ip6 (n, "address", ip6);
2750     }
2751   vat_json_object_add_uint (n, "weight", loc->weight);
2752 }
2753
2754 static void
2755   vl_api_gpe_fwd_entry_path_details_t_handler_json
2756   (vl_api_gpe_fwd_entry_path_details_t * mp)
2757 {
2758   vat_main_t *vam = &vat_main;
2759   vat_json_node_t *node = NULL;
2760   vat_json_node_t *loc_node;
2761
2762   if (VAT_JSON_ARRAY != vam->json_tree.type)
2763     {
2764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2765       vat_json_init_array (&vam->json_tree);
2766     }
2767   node = vat_json_array_add (&vam->json_tree);
2768   vat_json_init_object (node);
2769
2770   loc_node = vat_json_object_add (node, "local_locator");
2771   vat_json_init_object (loc_node);
2772   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2773
2774   loc_node = vat_json_object_add (node, "remote_locator");
2775   vat_json_init_object (loc_node);
2776   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2777 }
2778
2779 static void
2780   vl_api_gpe_fwd_entries_get_reply_t_handler
2781   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2782 {
2783   vat_main_t *vam = &vat_main;
2784   u32 i;
2785   int retval = clib_net_to_host_u32 (mp->retval);
2786   vl_api_gpe_fwd_entry_t *e;
2787
2788   if (retval)
2789     goto end;
2790
2791   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2792
2793   for (i = 0; i < mp->count; i++)
2794     {
2795       e = &mp->entries[i];
2796       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2797              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2798              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2799     }
2800
2801 end:
2802   vam->retval = retval;
2803   vam->result_ready = 1;
2804 }
2805
2806 static void
2807   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2808   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2809 {
2810   u8 *s = 0;
2811   vat_main_t *vam = &vat_main;
2812   vat_json_node_t *e = 0, root;
2813   u32 i;
2814   int retval = clib_net_to_host_u32 (mp->retval);
2815   vl_api_gpe_fwd_entry_t *fwd;
2816
2817   if (retval)
2818     goto end;
2819
2820   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2821   vat_json_init_array (&root);
2822
2823   for (i = 0; i < mp->count; i++)
2824     {
2825       e = vat_json_array_add (&root);
2826       fwd = &mp->entries[i];
2827
2828       vat_json_init_object (e);
2829       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2830       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2831
2832       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2833                   fwd->leid_prefix_len);
2834       vec_add1 (s, 0);
2835       vat_json_object_add_string_copy (e, "leid", s);
2836       vec_free (s);
2837
2838       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2839                   fwd->reid_prefix_len);
2840       vec_add1 (s, 0);
2841       vat_json_object_add_string_copy (e, "reid", s);
2842       vec_free (s);
2843     }
2844
2845   vat_json_print (vam->ofp, &root);
2846   vat_json_free (&root);
2847
2848 end:
2849   vam->retval = retval;
2850   vam->result_ready = 1;
2851 }
2852
2853 static void
2854   vl_api_lisp_adjacencies_get_reply_t_handler
2855   (vl_api_lisp_adjacencies_get_reply_t * mp)
2856 {
2857   vat_main_t *vam = &vat_main;
2858   u32 i, n;
2859   int retval = clib_net_to_host_u32 (mp->retval);
2860   vl_api_lisp_adjacency_t *a;
2861
2862   if (retval)
2863     goto end;
2864
2865   n = clib_net_to_host_u32 (mp->count);
2866
2867   for (i = 0; i < n; i++)
2868     {
2869       a = &mp->adjacencies[i];
2870       print (vam->ofp, "%U %40U",
2871              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2872              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2873     }
2874
2875 end:
2876   vam->retval = retval;
2877   vam->result_ready = 1;
2878 }
2879
2880 static void
2881   vl_api_lisp_adjacencies_get_reply_t_handler_json
2882   (vl_api_lisp_adjacencies_get_reply_t * mp)
2883 {
2884   u8 *s = 0;
2885   vat_main_t *vam = &vat_main;
2886   vat_json_node_t *e = 0, root;
2887   u32 i, n;
2888   int retval = clib_net_to_host_u32 (mp->retval);
2889   vl_api_lisp_adjacency_t *a;
2890
2891   if (retval)
2892     goto end;
2893
2894   n = clib_net_to_host_u32 (mp->count);
2895   vat_json_init_array (&root);
2896
2897   for (i = 0; i < n; i++)
2898     {
2899       e = vat_json_array_add (&root);
2900       a = &mp->adjacencies[i];
2901
2902       vat_json_init_object (e);
2903       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2904                   a->leid_prefix_len);
2905       vec_add1 (s, 0);
2906       vat_json_object_add_string_copy (e, "leid", s);
2907       vec_free (s);
2908
2909       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2910                   a->reid_prefix_len);
2911       vec_add1 (s, 0);
2912       vat_json_object_add_string_copy (e, "reid", s);
2913       vec_free (s);
2914     }
2915
2916   vat_json_print (vam->ofp, &root);
2917   vat_json_free (&root);
2918
2919 end:
2920   vam->retval = retval;
2921   vam->result_ready = 1;
2922 }
2923
2924 static void
2925 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2926                                           * mp)
2927 {
2928   vat_main_t *vam = &vat_main;
2929
2930   print (vam->ofp, "%=20U",
2931          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2932          mp->ip_address);
2933 }
2934
2935 static void
2936   vl_api_lisp_map_server_details_t_handler_json
2937   (vl_api_lisp_map_server_details_t * mp)
2938 {
2939   vat_main_t *vam = &vat_main;
2940   vat_json_node_t *node = NULL;
2941   struct in6_addr ip6;
2942   struct in_addr ip4;
2943
2944   if (VAT_JSON_ARRAY != vam->json_tree.type)
2945     {
2946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2947       vat_json_init_array (&vam->json_tree);
2948     }
2949   node = vat_json_array_add (&vam->json_tree);
2950
2951   vat_json_init_object (node);
2952   if (mp->is_ipv6)
2953     {
2954       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2955       vat_json_object_add_ip6 (node, "map-server", ip6);
2956     }
2957   else
2958     {
2959       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2960       vat_json_object_add_ip4 (node, "map-server", ip4);
2961     }
2962 }
2963
2964 static void
2965 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2966                                             * mp)
2967 {
2968   vat_main_t *vam = &vat_main;
2969
2970   print (vam->ofp, "%=20U",
2971          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2972          mp->ip_address);
2973 }
2974
2975 static void
2976   vl_api_lisp_map_resolver_details_t_handler_json
2977   (vl_api_lisp_map_resolver_details_t * mp)
2978 {
2979   vat_main_t *vam = &vat_main;
2980   vat_json_node_t *node = NULL;
2981   struct in6_addr ip6;
2982   struct in_addr ip4;
2983
2984   if (VAT_JSON_ARRAY != vam->json_tree.type)
2985     {
2986       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2987       vat_json_init_array (&vam->json_tree);
2988     }
2989   node = vat_json_array_add (&vam->json_tree);
2990
2991   vat_json_init_object (node);
2992   if (mp->is_ipv6)
2993     {
2994       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2995       vat_json_object_add_ip6 (node, "map resolver", ip6);
2996     }
2997   else
2998     {
2999       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3000       vat_json_object_add_ip4 (node, "map resolver", ip4);
3001     }
3002 }
3003
3004 static void
3005   vl_api_show_lisp_status_reply_t_handler
3006   (vl_api_show_lisp_status_reply_t * mp)
3007 {
3008   vat_main_t *vam = &vat_main;
3009   i32 retval = ntohl (mp->retval);
3010
3011   if (0 <= retval)
3012     {
3013       print (vam->ofp, "feature: %s\ngpe: %s",
3014              mp->feature_status ? "enabled" : "disabled",
3015              mp->gpe_status ? "enabled" : "disabled");
3016     }
3017
3018   vam->retval = retval;
3019   vam->result_ready = 1;
3020 }
3021
3022 static void
3023   vl_api_show_lisp_status_reply_t_handler_json
3024   (vl_api_show_lisp_status_reply_t * mp)
3025 {
3026   vat_main_t *vam = &vat_main;
3027   vat_json_node_t node;
3028   u8 *gpe_status = NULL;
3029   u8 *feature_status = NULL;
3030
3031   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3032   feature_status = format (0, "%s",
3033                            mp->feature_status ? "enabled" : "disabled");
3034   vec_add1 (gpe_status, 0);
3035   vec_add1 (feature_status, 0);
3036
3037   vat_json_init_object (&node);
3038   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3039   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3040
3041   vec_free (gpe_status);
3042   vec_free (feature_status);
3043
3044   vat_json_print (vam->ofp, &node);
3045   vat_json_free (&node);
3046
3047   vam->retval = ntohl (mp->retval);
3048   vam->result_ready = 1;
3049 }
3050
3051 static void
3052   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
3053   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
3054 {
3055   vat_main_t *vam = &vat_main;
3056   i32 retval = ntohl (mp->retval);
3057
3058   if (retval >= 0)
3059     {
3060       print (vam->ofp, "%=20s", mp->locator_set_name);
3061     }
3062
3063   vam->retval = retval;
3064   vam->result_ready = 1;
3065 }
3066
3067 static void
3068   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
3069   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
3070 {
3071   vat_main_t *vam = &vat_main;
3072   vat_json_node_t *node = NULL;
3073
3074   if (VAT_JSON_ARRAY != vam->json_tree.type)
3075     {
3076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3077       vat_json_init_array (&vam->json_tree);
3078     }
3079   node = vat_json_array_add (&vam->json_tree);
3080
3081   vat_json_init_object (node);
3082   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3083
3084   vat_json_print (vam->ofp, node);
3085   vat_json_free (node);
3086
3087   vam->retval = ntohl (mp->retval);
3088   vam->result_ready = 1;
3089 }
3090
3091 static u8 *
3092 format_lisp_map_request_mode (u8 * s, va_list * args)
3093 {
3094   u32 mode = va_arg (*args, u32);
3095
3096   switch (mode)
3097     {
3098     case 0:
3099       return format (0, "dst-only");
3100     case 1:
3101       return format (0, "src-dst");
3102     }
3103   return 0;
3104 }
3105
3106 static void
3107   vl_api_show_lisp_map_request_mode_reply_t_handler
3108   (vl_api_show_lisp_map_request_mode_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   i32 retval = ntohl (mp->retval);
3112
3113   if (0 <= retval)
3114     {
3115       u32 mode = mp->mode;
3116       print (vam->ofp, "map_request_mode: %U",
3117              format_lisp_map_request_mode, mode);
3118     }
3119
3120   vam->retval = retval;
3121   vam->result_ready = 1;
3122 }
3123
3124 static void
3125   vl_api_show_lisp_map_request_mode_reply_t_handler_json
3126   (vl_api_show_lisp_map_request_mode_reply_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129   vat_json_node_t node;
3130   u8 *s = 0;
3131   u32 mode;
3132
3133   mode = mp->mode;
3134   s = format (0, "%U", format_lisp_map_request_mode, mode);
3135   vec_add1 (s, 0);
3136
3137   vat_json_init_object (&node);
3138   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3139   vat_json_print (vam->ofp, &node);
3140   vat_json_free (&node);
3141
3142   vec_free (s);
3143   vam->retval = ntohl (mp->retval);
3144   vam->result_ready = 1;
3145 }
3146
3147 static void
3148 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
3149 {
3150   vat_main_t *vam = &vat_main;
3151   i32 retval = ntohl (mp->retval);
3152
3153   if (0 <= retval)
3154     {
3155       print (vam->ofp, "%-20s%-16s",
3156              mp->status ? "enabled" : "disabled",
3157              mp->status ? (char *) mp->locator_set_name : "");
3158     }
3159
3160   vam->retval = retval;
3161   vam->result_ready = 1;
3162 }
3163
3164 static void
3165 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
3166                                             mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169   vat_json_node_t node;
3170   u8 *status = 0;
3171
3172   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3173   vec_add1 (status, 0);
3174
3175   vat_json_init_object (&node);
3176   vat_json_object_add_string_copy (&node, "status", status);
3177   if (mp->status)
3178     {
3179       vat_json_object_add_string_copy (&node, "locator_set",
3180                                        mp->locator_set_name);
3181     }
3182
3183   vec_free (status);
3184
3185   vat_json_print (vam->ofp, &node);
3186   vat_json_free (&node);
3187
3188   vam->retval = ntohl (mp->retval);
3189   vam->result_ready = 1;
3190 }
3191
3192 static u8 *
3193 format_policer_type (u8 * s, va_list * va)
3194 {
3195   u32 i = va_arg (*va, u32);
3196
3197   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3198     s = format (s, "1r2c");
3199   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3200     s = format (s, "1r3c");
3201   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3202     s = format (s, "2r3c-2698");
3203   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3204     s = format (s, "2r3c-4115");
3205   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3206     s = format (s, "2r3c-mef5cf1");
3207   else
3208     s = format (s, "ILLEGAL");
3209   return s;
3210 }
3211
3212 static u8 *
3213 format_policer_rate_type (u8 * s, va_list * va)
3214 {
3215   u32 i = va_arg (*va, u32);
3216
3217   if (i == SSE2_QOS_RATE_KBPS)
3218     s = format (s, "kbps");
3219   else if (i == SSE2_QOS_RATE_PPS)
3220     s = format (s, "pps");
3221   else
3222     s = format (s, "ILLEGAL");
3223   return s;
3224 }
3225
3226 static u8 *
3227 format_policer_round_type (u8 * s, va_list * va)
3228 {
3229   u32 i = va_arg (*va, u32);
3230
3231   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3232     s = format (s, "closest");
3233   else if (i == SSE2_QOS_ROUND_TO_UP)
3234     s = format (s, "up");
3235   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3236     s = format (s, "down");
3237   else
3238     s = format (s, "ILLEGAL");
3239   return s;
3240 }
3241
3242 static u8 *
3243 format_policer_action_type (u8 * s, va_list * va)
3244 {
3245   u32 i = va_arg (*va, u32);
3246
3247   if (i == SSE2_QOS_ACTION_DROP)
3248     s = format (s, "drop");
3249   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3250     s = format (s, "transmit");
3251   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3252     s = format (s, "mark-and-transmit");
3253   else
3254     s = format (s, "ILLEGAL");
3255   return s;
3256 }
3257
3258 static u8 *
3259 format_dscp (u8 * s, va_list * va)
3260 {
3261   u32 i = va_arg (*va, u32);
3262   char *t = 0;
3263
3264   switch (i)
3265     {
3266 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3267       foreach_vnet_dscp
3268 #undef _
3269     default:
3270       return format (s, "ILLEGAL");
3271     }
3272   s = format (s, "%s", t);
3273   return s;
3274 }
3275
3276 static void
3277 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3278 {
3279   vat_main_t *vam = &vat_main;
3280   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3281
3282   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3283     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3284   else
3285     conform_dscp_str = format (0, "");
3286
3287   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3288     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3289   else
3290     exceed_dscp_str = format (0, "");
3291
3292   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3293     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3294   else
3295     violate_dscp_str = format (0, "");
3296
3297   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3298          "rate type %U, round type %U, %s rate, %s color-aware, "
3299          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3300          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3301          "conform action %U%s, exceed action %U%s, violate action %U%s",
3302          mp->name,
3303          format_policer_type, mp->type,
3304          ntohl (mp->cir),
3305          ntohl (mp->eir),
3306          clib_net_to_host_u64 (mp->cb),
3307          clib_net_to_host_u64 (mp->eb),
3308          format_policer_rate_type, mp->rate_type,
3309          format_policer_round_type, mp->round_type,
3310          mp->single_rate ? "single" : "dual",
3311          mp->color_aware ? "is" : "not",
3312          ntohl (mp->cir_tokens_per_period),
3313          ntohl (mp->pir_tokens_per_period),
3314          ntohl (mp->scale),
3315          ntohl (mp->current_limit),
3316          ntohl (mp->current_bucket),
3317          ntohl (mp->extended_limit),
3318          ntohl (mp->extended_bucket),
3319          clib_net_to_host_u64 (mp->last_update_time),
3320          format_policer_action_type, mp->conform_action_type,
3321          conform_dscp_str,
3322          format_policer_action_type, mp->exceed_action_type,
3323          exceed_dscp_str,
3324          format_policer_action_type, mp->violate_action_type,
3325          violate_dscp_str);
3326
3327   vec_free (conform_dscp_str);
3328   vec_free (exceed_dscp_str);
3329   vec_free (violate_dscp_str);
3330 }
3331
3332 static void vl_api_policer_details_t_handler_json
3333   (vl_api_policer_details_t * mp)
3334 {
3335   vat_main_t *vam = &vat_main;
3336   vat_json_node_t *node;
3337   u8 *rate_type_str, *round_type_str, *type_str;
3338   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3339
3340   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3341   round_type_str =
3342     format (0, "%U", format_policer_round_type, mp->round_type);
3343   type_str = format (0, "%U", format_policer_type, mp->type);
3344   conform_action_str = format (0, "%U", format_policer_action_type,
3345                                mp->conform_action_type);
3346   exceed_action_str = format (0, "%U", format_policer_action_type,
3347                               mp->exceed_action_type);
3348   violate_action_str = format (0, "%U", format_policer_action_type,
3349                                mp->violate_action_type);
3350
3351   if (VAT_JSON_ARRAY != vam->json_tree.type)
3352     {
3353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3354       vat_json_init_array (&vam->json_tree);
3355     }
3356   node = vat_json_array_add (&vam->json_tree);
3357
3358   vat_json_init_object (node);
3359   vat_json_object_add_string_copy (node, "name", mp->name);
3360   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3361   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3362   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3363   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3364   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3365   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3366   vat_json_object_add_string_copy (node, "type", type_str);
3367   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3368   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3369   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3370   vat_json_object_add_uint (node, "cir_tokens_per_period",
3371                             ntohl (mp->cir_tokens_per_period));
3372   vat_json_object_add_uint (node, "eir_tokens_per_period",
3373                             ntohl (mp->pir_tokens_per_period));
3374   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3375   vat_json_object_add_uint (node, "current_bucket",
3376                             ntohl (mp->current_bucket));
3377   vat_json_object_add_uint (node, "extended_limit",
3378                             ntohl (mp->extended_limit));
3379   vat_json_object_add_uint (node, "extended_bucket",
3380                             ntohl (mp->extended_bucket));
3381   vat_json_object_add_uint (node, "last_update_time",
3382                             ntohl (mp->last_update_time));
3383   vat_json_object_add_string_copy (node, "conform_action",
3384                                    conform_action_str);
3385   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3386     {
3387       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3388       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3389       vec_free (dscp_str);
3390     }
3391   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3392   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3393     {
3394       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3395       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3396       vec_free (dscp_str);
3397     }
3398   vat_json_object_add_string_copy (node, "violate_action",
3399                                    violate_action_str);
3400   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3401     {
3402       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3403       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3404       vec_free (dscp_str);
3405     }
3406
3407   vec_free (rate_type_str);
3408   vec_free (round_type_str);
3409   vec_free (type_str);
3410   vec_free (conform_action_str);
3411   vec_free (exceed_action_str);
3412   vec_free (violate_action_str);
3413 }
3414
3415 static void
3416 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3417                                            mp)
3418 {
3419   vat_main_t *vam = &vat_main;
3420   int i, count = ntohl (mp->count);
3421
3422   if (count > 0)
3423     print (vam->ofp, "classify table ids (%d) : ", count);
3424   for (i = 0; i < count; i++)
3425     {
3426       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3427       print (vam->ofp, (i < count - 1) ? "," : "");
3428     }
3429   vam->retval = ntohl (mp->retval);
3430   vam->result_ready = 1;
3431 }
3432
3433 static void
3434   vl_api_classify_table_ids_reply_t_handler_json
3435   (vl_api_classify_table_ids_reply_t * mp)
3436 {
3437   vat_main_t *vam = &vat_main;
3438   int i, count = ntohl (mp->count);
3439
3440   if (count > 0)
3441     {
3442       vat_json_node_t node;
3443
3444       vat_json_init_object (&node);
3445       for (i = 0; i < count; i++)
3446         {
3447           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3448         }
3449       vat_json_print (vam->ofp, &node);
3450       vat_json_free (&node);
3451     }
3452   vam->retval = ntohl (mp->retval);
3453   vam->result_ready = 1;
3454 }
3455
3456 static void
3457   vl_api_classify_table_by_interface_reply_t_handler
3458   (vl_api_classify_table_by_interface_reply_t * mp)
3459 {
3460   vat_main_t *vam = &vat_main;
3461   u32 table_id;
3462
3463   table_id = ntohl (mp->l2_table_id);
3464   if (table_id != ~0)
3465     print (vam->ofp, "l2 table id : %d", table_id);
3466   else
3467     print (vam->ofp, "l2 table id : No input ACL tables configured");
3468   table_id = ntohl (mp->ip4_table_id);
3469   if (table_id != ~0)
3470     print (vam->ofp, "ip4 table id : %d", table_id);
3471   else
3472     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3473   table_id = ntohl (mp->ip6_table_id);
3474   if (table_id != ~0)
3475     print (vam->ofp, "ip6 table id : %d", table_id);
3476   else
3477     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3478   vam->retval = ntohl (mp->retval);
3479   vam->result_ready = 1;
3480 }
3481
3482 static void
3483   vl_api_classify_table_by_interface_reply_t_handler_json
3484   (vl_api_classify_table_by_interface_reply_t * mp)
3485 {
3486   vat_main_t *vam = &vat_main;
3487   vat_json_node_t node;
3488
3489   vat_json_init_object (&node);
3490
3491   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3492   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3493   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3494
3495   vat_json_print (vam->ofp, &node);
3496   vat_json_free (&node);
3497
3498   vam->retval = ntohl (mp->retval);
3499   vam->result_ready = 1;
3500 }
3501
3502 static void vl_api_policer_add_del_reply_t_handler
3503   (vl_api_policer_add_del_reply_t * mp)
3504 {
3505   vat_main_t *vam = &vat_main;
3506   i32 retval = ntohl (mp->retval);
3507   if (vam->async_mode)
3508     {
3509       vam->async_errors += (retval < 0);
3510     }
3511   else
3512     {
3513       vam->retval = retval;
3514       vam->result_ready = 1;
3515       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3516         /*
3517          * Note: this is just barely thread-safe, depends on
3518          * the main thread spinning waiting for an answer...
3519          */
3520         errmsg ("policer index %d", ntohl (mp->policer_index));
3521     }
3522 }
3523
3524 static void vl_api_policer_add_del_reply_t_handler_json
3525   (vl_api_policer_add_del_reply_t * mp)
3526 {
3527   vat_main_t *vam = &vat_main;
3528   vat_json_node_t node;
3529
3530   vat_json_init_object (&node);
3531   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3532   vat_json_object_add_uint (&node, "policer_index",
3533                             ntohl (mp->policer_index));
3534
3535   vat_json_print (vam->ofp, &node);
3536   vat_json_free (&node);
3537
3538   vam->retval = ntohl (mp->retval);
3539   vam->result_ready = 1;
3540 }
3541
3542 /* Format hex dump. */
3543 u8 *
3544 format_hex_bytes (u8 * s, va_list * va)
3545 {
3546   u8 *bytes = va_arg (*va, u8 *);
3547   int n_bytes = va_arg (*va, int);
3548   uword i;
3549
3550   /* Print short or long form depending on byte count. */
3551   uword short_form = n_bytes <= 32;
3552   uword indent = format_get_indent (s);
3553
3554   if (n_bytes == 0)
3555     return s;
3556
3557   for (i = 0; i < n_bytes; i++)
3558     {
3559       if (!short_form && (i % 32) == 0)
3560         s = format (s, "%08x: ", i);
3561       s = format (s, "%02x", bytes[i]);
3562       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3563         s = format (s, "\n%U", format_white_space, indent);
3564     }
3565
3566   return s;
3567 }
3568
3569 static void
3570 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3571                                             * mp)
3572 {
3573   vat_main_t *vam = &vat_main;
3574   i32 retval = ntohl (mp->retval);
3575   if (retval == 0)
3576     {
3577       print (vam->ofp, "classify table info :");
3578       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3579              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3580              ntohl (mp->miss_next_index));
3581       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3582              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3583              ntohl (mp->match_n_vectors));
3584       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3585              ntohl (mp->mask_length));
3586     }
3587   vam->retval = retval;
3588   vam->result_ready = 1;
3589 }
3590
3591 static void
3592   vl_api_classify_table_info_reply_t_handler_json
3593   (vl_api_classify_table_info_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   vat_json_node_t node;
3597
3598   i32 retval = ntohl (mp->retval);
3599   if (retval == 0)
3600     {
3601       vat_json_init_object (&node);
3602
3603       vat_json_object_add_int (&node, "sessions",
3604                                ntohl (mp->active_sessions));
3605       vat_json_object_add_int (&node, "nexttbl",
3606                                ntohl (mp->next_table_index));
3607       vat_json_object_add_int (&node, "nextnode",
3608                                ntohl (mp->miss_next_index));
3609       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3610       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3611       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3612       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3613                       ntohl (mp->mask_length), 0);
3614       vat_json_object_add_string_copy (&node, "mask", s);
3615
3616       vat_json_print (vam->ofp, &node);
3617       vat_json_free (&node);
3618     }
3619   vam->retval = ntohl (mp->retval);
3620   vam->result_ready = 1;
3621 }
3622
3623 static void
3624 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3625                                            mp)
3626 {
3627   vat_main_t *vam = &vat_main;
3628
3629   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3630          ntohl (mp->hit_next_index), ntohl (mp->advance),
3631          ntohl (mp->opaque_index));
3632   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3633          ntohl (mp->match_length));
3634 }
3635
3636 static void
3637   vl_api_classify_session_details_t_handler_json
3638   (vl_api_classify_session_details_t * mp)
3639 {
3640   vat_main_t *vam = &vat_main;
3641   vat_json_node_t *node = NULL;
3642
3643   if (VAT_JSON_ARRAY != vam->json_tree.type)
3644     {
3645       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3646       vat_json_init_array (&vam->json_tree);
3647     }
3648   node = vat_json_array_add (&vam->json_tree);
3649
3650   vat_json_init_object (node);
3651   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3652   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3653   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3654   u8 *s =
3655     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3656             0);
3657   vat_json_object_add_string_copy (node, "match", s);
3658 }
3659
3660 static void vl_api_pg_create_interface_reply_t_handler
3661   (vl_api_pg_create_interface_reply_t * mp)
3662 {
3663   vat_main_t *vam = &vat_main;
3664
3665   vam->retval = ntohl (mp->retval);
3666   vam->result_ready = 1;
3667 }
3668
3669 static void vl_api_pg_create_interface_reply_t_handler_json
3670   (vl_api_pg_create_interface_reply_t * mp)
3671 {
3672   vat_main_t *vam = &vat_main;
3673   vat_json_node_t node;
3674
3675   i32 retval = ntohl (mp->retval);
3676   if (retval == 0)
3677     {
3678       vat_json_init_object (&node);
3679
3680       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3681
3682       vat_json_print (vam->ofp, &node);
3683       vat_json_free (&node);
3684     }
3685   vam->retval = ntohl (mp->retval);
3686   vam->result_ready = 1;
3687 }
3688
3689 static void vl_api_policer_classify_details_t_handler
3690   (vl_api_policer_classify_details_t * mp)
3691 {
3692   vat_main_t *vam = &vat_main;
3693
3694   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3695          ntohl (mp->table_index));
3696 }
3697
3698 static void vl_api_policer_classify_details_t_handler_json
3699   (vl_api_policer_classify_details_t * mp)
3700 {
3701   vat_main_t *vam = &vat_main;
3702   vat_json_node_t *node;
3703
3704   if (VAT_JSON_ARRAY != vam->json_tree.type)
3705     {
3706       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3707       vat_json_init_array (&vam->json_tree);
3708     }
3709   node = vat_json_array_add (&vam->json_tree);
3710
3711   vat_json_init_object (node);
3712   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3713   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3714 }
3715
3716 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3717   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3718 {
3719   vat_main_t *vam = &vat_main;
3720   i32 retval = ntohl (mp->retval);
3721   if (vam->async_mode)
3722     {
3723       vam->async_errors += (retval < 0);
3724     }
3725   else
3726     {
3727       vam->retval = retval;
3728       vam->sw_if_index = ntohl (mp->sw_if_index);
3729       vam->result_ready = 1;
3730     }
3731 }
3732
3733 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3734   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3735 {
3736   vat_main_t *vam = &vat_main;
3737   vat_json_node_t node;
3738
3739   vat_json_init_object (&node);
3740   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3741   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3742
3743   vat_json_print (vam->ofp, &node);
3744   vat_json_free (&node);
3745
3746   vam->retval = ntohl (mp->retval);
3747   vam->result_ready = 1;
3748 }
3749
3750 static void vl_api_flow_classify_details_t_handler
3751   (vl_api_flow_classify_details_t * mp)
3752 {
3753   vat_main_t *vam = &vat_main;
3754
3755   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3756          ntohl (mp->table_index));
3757 }
3758
3759 static void vl_api_flow_classify_details_t_handler_json
3760   (vl_api_flow_classify_details_t * mp)
3761 {
3762   vat_main_t *vam = &vat_main;
3763   vat_json_node_t *node;
3764
3765   if (VAT_JSON_ARRAY != vam->json_tree.type)
3766     {
3767       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3768       vat_json_init_array (&vam->json_tree);
3769     }
3770   node = vat_json_array_add (&vam->json_tree);
3771
3772   vat_json_init_object (node);
3773   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3774   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3775 }
3776
3777
3778
3779 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3780 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3781 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3782 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3783 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3784 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3785 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3786 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3787 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3788 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3789
3790 /*
3791  * Generate boilerplate reply handlers, which
3792  * dig the return value out of the xxx_reply_t API message,
3793  * stick it into vam->retval, and set vam->result_ready
3794  *
3795  * Could also do this by pointing N message decode slots at
3796  * a single function, but that could break in subtle ways.
3797  */
3798
3799 #define foreach_standard_reply_retval_handler           \
3800 _(sw_interface_set_flags_reply)                         \
3801 _(sw_interface_add_del_address_reply)                   \
3802 _(sw_interface_set_table_reply)                         \
3803 _(sw_interface_set_mpls_enable_reply)                   \
3804 _(sw_interface_set_vpath_reply)                         \
3805 _(sw_interface_set_vxlan_bypass_reply)                  \
3806 _(sw_interface_set_l2_bridge_reply)                     \
3807 _(bridge_domain_add_del_reply)                          \
3808 _(sw_interface_set_l2_xconnect_reply)                   \
3809 _(l2fib_add_del_reply)                                  \
3810 _(ip_add_del_route_reply)                               \
3811 _(ip_mroute_add_del_reply)                              \
3812 _(mpls_route_add_del_reply)                             \
3813 _(mpls_ip_bind_unbind_reply)                            \
3814 _(proxy_arp_add_del_reply)                              \
3815 _(proxy_arp_intfc_enable_disable_reply)                 \
3816 _(sw_interface_set_unnumbered_reply)                    \
3817 _(ip_neighbor_add_del_reply)                            \
3818 _(reset_vrf_reply)                                      \
3819 _(oam_add_del_reply)                                    \
3820 _(reset_fib_reply)                                      \
3821 _(dhcp_proxy_config_reply)                              \
3822 _(dhcp_proxy_set_vss_reply)                             \
3823 _(dhcp_client_config_reply)                             \
3824 _(set_ip_flow_hash_reply)                               \
3825 _(sw_interface_ip6_enable_disable_reply)                \
3826 _(sw_interface_ip6_set_link_local_address_reply)        \
3827 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3828 _(sw_interface_ip6nd_ra_config_reply)                   \
3829 _(set_arp_neighbor_limit_reply)                         \
3830 _(l2_patch_add_del_reply)                               \
3831 _(sr_tunnel_add_del_reply)                              \
3832 _(sr_policy_add_del_reply)                              \
3833 _(sr_multicast_map_add_del_reply)                       \
3834 _(classify_add_del_session_reply)                       \
3835 _(classify_set_interface_ip_table_reply)                \
3836 _(classify_set_interface_l2_tables_reply)               \
3837 _(l2tpv3_set_tunnel_cookies_reply)                      \
3838 _(l2tpv3_interface_enable_disable_reply)                \
3839 _(l2tpv3_set_lookup_key_reply)                          \
3840 _(l2_fib_clear_table_reply)                             \
3841 _(l2_interface_efp_filter_reply)                        \
3842 _(l2_interface_vlan_tag_rewrite_reply)                  \
3843 _(modify_vhost_user_if_reply)                           \
3844 _(delete_vhost_user_if_reply)                           \
3845 _(want_ip4_arp_events_reply)                            \
3846 _(want_ip6_nd_events_reply)                             \
3847 _(input_acl_set_interface_reply)                        \
3848 _(ipsec_spd_add_del_reply)                              \
3849 _(ipsec_interface_add_del_spd_reply)                    \
3850 _(ipsec_spd_add_del_entry_reply)                        \
3851 _(ipsec_sad_add_del_entry_reply)                        \
3852 _(ipsec_sa_set_key_reply)                               \
3853 _(ikev2_profile_add_del_reply)                          \
3854 _(ikev2_profile_set_auth_reply)                         \
3855 _(ikev2_profile_set_id_reply)                           \
3856 _(ikev2_profile_set_ts_reply)                           \
3857 _(ikev2_set_local_key_reply)                            \
3858 _(ikev2_set_responder_reply)                            \
3859 _(ikev2_set_ike_transforms_reply)                       \
3860 _(ikev2_set_esp_transforms_reply)                       \
3861 _(ikev2_set_sa_lifetime_reply)                          \
3862 _(ikev2_initiate_sa_init_reply)                         \
3863 _(ikev2_initiate_del_ike_sa_reply)                      \
3864 _(ikev2_initiate_del_child_sa_reply)                    \
3865 _(ikev2_initiate_rekey_child_sa_reply)                  \
3866 _(delete_loopback_reply)                                \
3867 _(bd_ip_mac_add_del_reply)                              \
3868 _(map_del_domain_reply)                                 \
3869 _(map_add_del_rule_reply)                               \
3870 _(want_interface_events_reply)                          \
3871 _(want_stats_reply)                                     \
3872 _(cop_interface_enable_disable_reply)                   \
3873 _(cop_whitelist_enable_disable_reply)                   \
3874 _(sw_interface_clear_stats_reply)                       \
3875 _(ioam_enable_reply)                              \
3876 _(ioam_disable_reply)                              \
3877 _(lisp_add_del_locator_reply)                           \
3878 _(lisp_add_del_local_eid_reply)                         \
3879 _(lisp_add_del_remote_mapping_reply)                    \
3880 _(lisp_add_del_adjacency_reply)                         \
3881 _(gpe_add_del_fwd_entry_reply)                          \
3882 _(lisp_add_del_map_resolver_reply)                      \
3883 _(lisp_add_del_map_server_reply)                        \
3884 _(gpe_enable_disable_reply)                             \
3885 _(gpe_add_del_iface_reply)                              \
3886 _(lisp_enable_disable_reply)                            \
3887 _(lisp_rloc_probe_enable_disable_reply)                 \
3888 _(lisp_map_register_enable_disable_reply)               \
3889 _(lisp_pitr_set_locator_set_reply)                      \
3890 _(lisp_map_request_mode_reply)                          \
3891 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3892 _(lisp_eid_table_add_del_map_reply)                     \
3893 _(vxlan_gpe_add_del_tunnel_reply)                       \
3894 _(af_packet_delete_reply)                               \
3895 _(policer_classify_set_interface_reply)                 \
3896 _(netmap_create_reply)                                  \
3897 _(netmap_delete_reply)                                  \
3898 _(set_ipfix_exporter_reply)                             \
3899 _(set_ipfix_classify_stream_reply)                      \
3900 _(ipfix_classify_table_add_del_reply)                   \
3901 _(flow_classify_set_interface_reply)                    \
3902 _(sw_interface_span_enable_disable_reply)               \
3903 _(pg_capture_reply)                                     \
3904 _(pg_enable_disable_reply)                              \
3905 _(ip_source_and_port_range_check_add_del_reply)         \
3906 _(ip_source_and_port_range_check_interface_add_del_reply)\
3907 _(delete_subif_reply)                                   \
3908 _(l2_interface_pbb_tag_rewrite_reply)                   \
3909 _(punt_reply)                                           \
3910 _(feature_enable_disable_reply)                         \
3911 _(sw_interface_tag_add_del_reply)                       \
3912 _(sw_interface_set_mtu_reply)
3913
3914 #if DPDK > 0
3915 #define foreach_standard_dpdk_reply_retval_handler      \
3916 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3917 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3918 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3919 #endif
3920
3921 #define _(n)                                    \
3922     static void vl_api_##n##_t_handler          \
3923     (vl_api_##n##_t * mp)                       \
3924     {                                           \
3925         vat_main_t * vam = &vat_main;           \
3926         i32 retval = ntohl(mp->retval);         \
3927         if (vam->async_mode) {                  \
3928             vam->async_errors += (retval < 0);  \
3929         } else {                                \
3930             vam->retval = retval;               \
3931             vam->result_ready = 1;              \
3932         }                                       \
3933     }
3934 foreach_standard_reply_retval_handler;
3935 #undef _
3936
3937 #define _(n)                                    \
3938     static void vl_api_##n##_t_handler_json     \
3939     (vl_api_##n##_t * mp)                       \
3940     {                                           \
3941         vat_main_t * vam = &vat_main;           \
3942         vat_json_node_t node;                   \
3943         vat_json_init_object(&node);            \
3944         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3945         vat_json_print(vam->ofp, &node);        \
3946         vam->retval = ntohl(mp->retval);        \
3947         vam->result_ready = 1;                  \
3948     }
3949 foreach_standard_reply_retval_handler;
3950 #undef _
3951
3952 #if DPDK > 0
3953 #define _(n)                                    \
3954     static void vl_api_##n##_t_handler          \
3955     (vl_api_##n##_t * mp)                       \
3956     {                                           \
3957         vat_main_t * vam = &vat_main;           \
3958         i32 retval = ntohl(mp->retval);         \
3959         if (vam->async_mode) {                  \
3960             vam->async_errors += (retval < 0);  \
3961         } else {                                \
3962             vam->retval = retval;               \
3963             vam->result_ready = 1;              \
3964         }                                       \
3965     }
3966 foreach_standard_dpdk_reply_retval_handler;
3967 #undef _
3968
3969 #define _(n)                                    \
3970     static void vl_api_##n##_t_handler_json     \
3971     (vl_api_##n##_t * mp)                       \
3972     {                                           \
3973         vat_main_t * vam = &vat_main;           \
3974         vat_json_node_t node;                   \
3975         vat_json_init_object(&node);            \
3976         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3977         vat_json_print(vam->ofp, &node);        \
3978         vam->retval = ntohl(mp->retval);        \
3979         vam->result_ready = 1;                  \
3980     }
3981 foreach_standard_dpdk_reply_retval_handler;
3982 #undef _
3983 #endif
3984
3985 /*
3986  * Table of message reply handlers, must include boilerplate handlers
3987  * we just generated
3988  */
3989
3990 #define foreach_vpe_api_reply_msg                                       \
3991 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3992 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3993 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3994 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3995 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3996 _(CLI_REPLY, cli_reply)                                                 \
3997 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3998 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3999   sw_interface_add_del_address_reply)                                   \
4000 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4001 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4002 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4003 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4004 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4005   sw_interface_set_l2_xconnect_reply)                                   \
4006 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4007   sw_interface_set_l2_bridge_reply)                                     \
4008 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4009 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4010 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4011 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4012 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4013 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4014 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4015 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4016 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4017 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4018 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4019 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4020 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4021 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4022 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4023 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4024   proxy_arp_intfc_enable_disable_reply)                                 \
4025 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4026 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4027   sw_interface_set_unnumbered_reply)                                    \
4028 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4029 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4030 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4031 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4032 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4033 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4034 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4035 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4036 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4037 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4038 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4039 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4040   sw_interface_ip6_enable_disable_reply)                                \
4041 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4042   sw_interface_ip6_set_link_local_address_reply)                        \
4043 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4044   sw_interface_ip6nd_ra_prefix_reply)                                   \
4045 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4046   sw_interface_ip6nd_ra_config_reply)                                   \
4047 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4048 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4049 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4050 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4051 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4052 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4053 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4054 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4055 classify_set_interface_ip_table_reply)                                  \
4056 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4057   classify_set_interface_l2_tables_reply)                               \
4058 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4059 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4060 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4061 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4062 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4063   l2tpv3_interface_enable_disable_reply)                                \
4064 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4065 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4066 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4067 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4068 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4069 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4070 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4071 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4072 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4073 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4074 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4075 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4076 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4077 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4078 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4079 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4080 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4081 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4082 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4083 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4084 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4085 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4086 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4087 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4088 _(IP_DETAILS, ip_details)                                               \
4089 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4090 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4091 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4092 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4093 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4094 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4095 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4096 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4097 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4098 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4099 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4100 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4101 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4102 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4103 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4104 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4105 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4106 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4107 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4108 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4109 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4110 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4111 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4112 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4113 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4114 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
4115 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4116 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4117 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4118 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4119 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4120 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4121 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4122 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4123 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4124 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4125 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4126 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4127 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4128 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4129 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
4130 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
4131 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
4132 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
4133 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
4134 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4135 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
4136 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
4137 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4138 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
4139 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
4140   lisp_map_register_enable_disable_reply)                               \
4141 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
4142   lisp_rloc_probe_enable_disable_reply)                                 \
4143 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
4144 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
4145 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
4146 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4147 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
4148 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
4149 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
4150 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
4151 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
4152 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
4153 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
4154 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
4155 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4156 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4157   gpe_fwd_entry_path_details)                                           \
4158 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
4159 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
4160   lisp_add_del_map_request_itr_rlocs_reply)                             \
4161 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
4162   lisp_get_map_request_itr_rlocs_reply)                                 \
4163 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
4164 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
4165 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
4166 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
4167   show_lisp_map_register_state_reply)                                   \
4168 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4169 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4170 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4171 _(POLICER_DETAILS, policer_details)                                     \
4172 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4173 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4174 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4175 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4176 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4177 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4178 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4179 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4180 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4181 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4182 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4183 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4184 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4185 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4186 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4187 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4188 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4189 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4190 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4191 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4192 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4193 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4194 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4195 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4196 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4197  ip_source_and_port_range_check_add_del_reply)                          \
4198 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4199  ip_source_and_port_range_check_interface_add_del_reply)                \
4200 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4201 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4202 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4203 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4204 _(PUNT_REPLY, punt_reply)                                               \
4205 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4206 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4207 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4208 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4209 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4210 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4211 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4212 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4213
4214 #if DPDK > 0
4215 #define foreach_vpe_dpdk_api_reply_msg                                  \
4216 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
4217   sw_interface_set_dpdk_hqos_pipe_reply)                                \
4218 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
4219   sw_interface_set_dpdk_hqos_subport_reply)                             \
4220 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
4221   sw_interface_set_dpdk_hqos_tctbl_reply)
4222 #endif
4223
4224 typedef struct
4225 {
4226   u8 *name;
4227   u32 value;
4228 } name_sort_t;
4229
4230
4231 #define STR_VTR_OP_CASE(op)     \
4232     case L2_VTR_ ## op:         \
4233         return "" # op;
4234
4235 static const char *
4236 str_vtr_op (u32 vtr_op)
4237 {
4238   switch (vtr_op)
4239     {
4240       STR_VTR_OP_CASE (DISABLED);
4241       STR_VTR_OP_CASE (PUSH_1);
4242       STR_VTR_OP_CASE (PUSH_2);
4243       STR_VTR_OP_CASE (POP_1);
4244       STR_VTR_OP_CASE (POP_2);
4245       STR_VTR_OP_CASE (TRANSLATE_1_1);
4246       STR_VTR_OP_CASE (TRANSLATE_1_2);
4247       STR_VTR_OP_CASE (TRANSLATE_2_1);
4248       STR_VTR_OP_CASE (TRANSLATE_2_2);
4249     }
4250
4251   return "UNKNOWN";
4252 }
4253
4254 static int
4255 dump_sub_interface_table (vat_main_t * vam)
4256 {
4257   const sw_interface_subif_t *sub = NULL;
4258
4259   if (vam->json_output)
4260     {
4261       clib_warning
4262         ("JSON output supported only for VPE API calls and dump_stats_table");
4263       return -99;
4264     }
4265
4266   print (vam->ofp,
4267          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4268          "Interface", "sw_if_index",
4269          "sub id", "dot1ad", "tags", "outer id",
4270          "inner id", "exact", "default", "outer any", "inner any");
4271
4272   vec_foreach (sub, vam->sw_if_subif_table)
4273   {
4274     print (vam->ofp,
4275            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4276            sub->interface_name,
4277            sub->sw_if_index,
4278            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4279            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4280            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4281            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4282     if (sub->vtr_op != L2_VTR_DISABLED)
4283       {
4284         print (vam->ofp,
4285                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4286                "tag1: %d tag2: %d ]",
4287                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4288                sub->vtr_tag1, sub->vtr_tag2);
4289       }
4290   }
4291
4292   return 0;
4293 }
4294
4295 static int
4296 name_sort_cmp (void *a1, void *a2)
4297 {
4298   name_sort_t *n1 = a1;
4299   name_sort_t *n2 = a2;
4300
4301   return strcmp ((char *) n1->name, (char *) n2->name);
4302 }
4303
4304 static int
4305 dump_interface_table (vat_main_t * vam)
4306 {
4307   hash_pair_t *p;
4308   name_sort_t *nses = 0, *ns;
4309
4310   if (vam->json_output)
4311     {
4312       clib_warning
4313         ("JSON output supported only for VPE API calls and dump_stats_table");
4314       return -99;
4315     }
4316
4317   /* *INDENT-OFF* */
4318   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4319   ({
4320     vec_add2 (nses, ns, 1);
4321     ns->name = (u8 *)(p->key);
4322     ns->value = (u32) p->value[0];
4323   }));
4324   /* *INDENT-ON* */
4325
4326   vec_sort_with_function (nses, name_sort_cmp);
4327
4328   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4329   vec_foreach (ns, nses)
4330   {
4331     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4332   }
4333   vec_free (nses);
4334   return 0;
4335 }
4336
4337 static int
4338 dump_ip_table (vat_main_t * vam, int is_ipv6)
4339 {
4340   const ip_details_t *det = NULL;
4341   const ip_address_details_t *address = NULL;
4342   u32 i = ~0;
4343
4344   print (vam->ofp, "%-12s", "sw_if_index");
4345
4346   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4347   {
4348     i++;
4349     if (!det->present)
4350       {
4351         continue;
4352       }
4353     print (vam->ofp, "%-12d", i);
4354     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4355     if (!det->addr)
4356       {
4357         continue;
4358       }
4359     vec_foreach (address, det->addr)
4360     {
4361       print (vam->ofp,
4362              "            %-30U%-13d",
4363              is_ipv6 ? format_ip6_address : format_ip4_address,
4364              address->ip, address->prefix_length);
4365     }
4366   }
4367
4368   return 0;
4369 }
4370
4371 static int
4372 dump_ipv4_table (vat_main_t * vam)
4373 {
4374   if (vam->json_output)
4375     {
4376       clib_warning
4377         ("JSON output supported only for VPE API calls and dump_stats_table");
4378       return -99;
4379     }
4380
4381   return dump_ip_table (vam, 0);
4382 }
4383
4384 static int
4385 dump_ipv6_table (vat_main_t * vam)
4386 {
4387   if (vam->json_output)
4388     {
4389       clib_warning
4390         ("JSON output supported only for VPE API calls and dump_stats_table");
4391       return -99;
4392     }
4393
4394   return dump_ip_table (vam, 1);
4395 }
4396
4397 static char *
4398 counter_type_to_str (u8 counter_type, u8 is_combined)
4399 {
4400   if (!is_combined)
4401     {
4402       switch (counter_type)
4403         {
4404         case VNET_INTERFACE_COUNTER_DROP:
4405           return "drop";
4406         case VNET_INTERFACE_COUNTER_PUNT:
4407           return "punt";
4408         case VNET_INTERFACE_COUNTER_IP4:
4409           return "ip4";
4410         case VNET_INTERFACE_COUNTER_IP6:
4411           return "ip6";
4412         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4413           return "rx-no-buf";
4414         case VNET_INTERFACE_COUNTER_RX_MISS:
4415           return "rx-miss";
4416         case VNET_INTERFACE_COUNTER_RX_ERROR:
4417           return "rx-error";
4418         case VNET_INTERFACE_COUNTER_TX_ERROR:
4419           return "tx-error";
4420         default:
4421           return "INVALID-COUNTER-TYPE";
4422         }
4423     }
4424   else
4425     {
4426       switch (counter_type)
4427         {
4428         case VNET_INTERFACE_COUNTER_RX:
4429           return "rx";
4430         case VNET_INTERFACE_COUNTER_TX:
4431           return "tx";
4432         default:
4433           return "INVALID-COUNTER-TYPE";
4434         }
4435     }
4436 }
4437
4438 static int
4439 dump_stats_table (vat_main_t * vam)
4440 {
4441   vat_json_node_t node;
4442   vat_json_node_t *msg_array;
4443   vat_json_node_t *msg;
4444   vat_json_node_t *counter_array;
4445   vat_json_node_t *counter;
4446   interface_counter_t c;
4447   u64 packets;
4448   ip4_fib_counter_t *c4;
4449   ip6_fib_counter_t *c6;
4450   ip4_nbr_counter_t *n4;
4451   ip6_nbr_counter_t *n6;
4452   int i, j;
4453
4454   if (!vam->json_output)
4455     {
4456       clib_warning ("dump_stats_table supported only in JSON format");
4457       return -99;
4458     }
4459
4460   vat_json_init_object (&node);
4461
4462   /* interface counters */
4463   msg_array = vat_json_object_add (&node, "interface_counters");
4464   vat_json_init_array (msg_array);
4465   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4466     {
4467       msg = vat_json_array_add (msg_array);
4468       vat_json_init_object (msg);
4469       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4470                                        (u8 *) counter_type_to_str (i, 0));
4471       vat_json_object_add_int (msg, "is_combined", 0);
4472       counter_array = vat_json_object_add (msg, "data");
4473       vat_json_init_array (counter_array);
4474       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4475         {
4476           packets = vam->simple_interface_counters[i][j];
4477           vat_json_array_add_uint (counter_array, packets);
4478         }
4479     }
4480   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4481     {
4482       msg = vat_json_array_add (msg_array);
4483       vat_json_init_object (msg);
4484       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4485                                        (u8 *) counter_type_to_str (i, 1));
4486       vat_json_object_add_int (msg, "is_combined", 1);
4487       counter_array = vat_json_object_add (msg, "data");
4488       vat_json_init_array (counter_array);
4489       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4490         {
4491           c = vam->combined_interface_counters[i][j];
4492           counter = vat_json_array_add (counter_array);
4493           vat_json_init_object (counter);
4494           vat_json_object_add_uint (counter, "packets", c.packets);
4495           vat_json_object_add_uint (counter, "bytes", c.bytes);
4496         }
4497     }
4498
4499   /* ip4 fib counters */
4500   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4501   vat_json_init_array (msg_array);
4502   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4503     {
4504       msg = vat_json_array_add (msg_array);
4505       vat_json_init_object (msg);
4506       vat_json_object_add_uint (msg, "vrf_id",
4507                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4508       counter_array = vat_json_object_add (msg, "c");
4509       vat_json_init_array (counter_array);
4510       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4511         {
4512           counter = vat_json_array_add (counter_array);
4513           vat_json_init_object (counter);
4514           c4 = &vam->ip4_fib_counters[i][j];
4515           vat_json_object_add_ip4 (counter, "address", c4->address);
4516           vat_json_object_add_uint (counter, "address_length",
4517                                     c4->address_length);
4518           vat_json_object_add_uint (counter, "packets", c4->packets);
4519           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4520         }
4521     }
4522
4523   /* ip6 fib counters */
4524   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4525   vat_json_init_array (msg_array);
4526   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4527     {
4528       msg = vat_json_array_add (msg_array);
4529       vat_json_init_object (msg);
4530       vat_json_object_add_uint (msg, "vrf_id",
4531                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4532       counter_array = vat_json_object_add (msg, "c");
4533       vat_json_init_array (counter_array);
4534       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4535         {
4536           counter = vat_json_array_add (counter_array);
4537           vat_json_init_object (counter);
4538           c6 = &vam->ip6_fib_counters[i][j];
4539           vat_json_object_add_ip6 (counter, "address", c6->address);
4540           vat_json_object_add_uint (counter, "address_length",
4541                                     c6->address_length);
4542           vat_json_object_add_uint (counter, "packets", c6->packets);
4543           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4544         }
4545     }
4546
4547   /* ip4 nbr counters */
4548   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4549   vat_json_init_array (msg_array);
4550   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4551     {
4552       msg = vat_json_array_add (msg_array);
4553       vat_json_init_object (msg);
4554       vat_json_object_add_uint (msg, "sw_if_index", i);
4555       counter_array = vat_json_object_add (msg, "c");
4556       vat_json_init_array (counter_array);
4557       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4558         {
4559           counter = vat_json_array_add (counter_array);
4560           vat_json_init_object (counter);
4561           n4 = &vam->ip4_nbr_counters[i][j];
4562           vat_json_object_add_ip4 (counter, "address", n4->address);
4563           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4564           vat_json_object_add_uint (counter, "packets", n4->packets);
4565           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4566         }
4567     }
4568
4569   /* ip6 nbr counters */
4570   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4571   vat_json_init_array (msg_array);
4572   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4573     {
4574       msg = vat_json_array_add (msg_array);
4575       vat_json_init_object (msg);
4576       vat_json_object_add_uint (msg, "sw_if_index", i);
4577       counter_array = vat_json_object_add (msg, "c");
4578       vat_json_init_array (counter_array);
4579       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4580         {
4581           counter = vat_json_array_add (counter_array);
4582           vat_json_init_object (counter);
4583           n6 = &vam->ip6_nbr_counters[i][j];
4584           vat_json_object_add_ip6 (counter, "address", n6->address);
4585           vat_json_object_add_uint (counter, "packets", n6->packets);
4586           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4587         }
4588     }
4589
4590   vat_json_print (vam->ofp, &node);
4591   vat_json_free (&node);
4592
4593   return 0;
4594 }
4595
4596 int
4597 exec (vat_main_t * vam)
4598 {
4599   api_main_t *am = &api_main;
4600   vl_api_cli_request_t *mp;
4601   f64 timeout;
4602   void *oldheap;
4603   u8 *cmd = 0;
4604   unformat_input_t *i = vam->input;
4605
4606   if (vec_len (i->buffer) == 0)
4607     return -1;
4608
4609   if (vam->exec_mode == 0 && unformat (i, "mode"))
4610     {
4611       vam->exec_mode = 1;
4612       return 0;
4613     }
4614   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4615     {
4616       vam->exec_mode = 0;
4617       return 0;
4618     }
4619
4620
4621   M (CLI_REQUEST, mp);
4622
4623   /*
4624    * Copy cmd into shared memory.
4625    * In order for the CLI command to work, it
4626    * must be a vector ending in \n, not a C-string ending
4627    * in \n\0.
4628    */
4629   pthread_mutex_lock (&am->vlib_rp->mutex);
4630   oldheap = svm_push_data_heap (am->vlib_rp);
4631
4632   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4633   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4634
4635   svm_pop_heap (oldheap);
4636   pthread_mutex_unlock (&am->vlib_rp->mutex);
4637
4638   mp->cmd_in_shmem = (u64) cmd;
4639   S (mp);
4640   timeout = vat_time_now (vam) + 10.0;
4641
4642   while (vat_time_now (vam) < timeout)
4643     {
4644       if (vam->result_ready == 1)
4645         {
4646           u8 *free_me;
4647           if (vam->shmem_result != NULL)
4648             print (vam->ofp, "%s", vam->shmem_result);
4649           pthread_mutex_lock (&am->vlib_rp->mutex);
4650           oldheap = svm_push_data_heap (am->vlib_rp);
4651
4652           free_me = (u8 *) vam->shmem_result;
4653           vec_free (free_me);
4654
4655           svm_pop_heap (oldheap);
4656           pthread_mutex_unlock (&am->vlib_rp->mutex);
4657           return 0;
4658         }
4659     }
4660   return -99;
4661 }
4662
4663 /*
4664  * Future replacement of exec() that passes CLI buffers directly in
4665  * the API messages instead of an additional shared memory area.
4666  */
4667 static int
4668 exec_inband (vat_main_t * vam)
4669 {
4670   vl_api_cli_inband_t *mp;
4671   unformat_input_t *i = vam->input;
4672   int ret;
4673
4674   if (vec_len (i->buffer) == 0)
4675     return -1;
4676
4677   if (vam->exec_mode == 0 && unformat (i, "mode"))
4678     {
4679       vam->exec_mode = 1;
4680       return 0;
4681     }
4682   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4683     {
4684       vam->exec_mode = 0;
4685       return 0;
4686     }
4687
4688   /*
4689    * In order for the CLI command to work, it
4690    * must be a vector ending in \n, not a C-string ending
4691    * in \n\0.
4692    */
4693   u32 len = vec_len (vam->input->buffer);
4694   M2 (CLI_INBAND, mp, len);
4695   clib_memcpy (mp->cmd, vam->input->buffer, len);
4696   mp->length = htonl (len);
4697
4698   S (mp);
4699   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4700   return ret;
4701 }
4702
4703 static int
4704 api_create_loopback (vat_main_t * vam)
4705 {
4706   unformat_input_t *i = vam->input;
4707   vl_api_create_loopback_t *mp;
4708   u8 mac_address[6];
4709   u8 mac_set = 0;
4710   int ret;
4711
4712   memset (mac_address, 0, sizeof (mac_address));
4713
4714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4715     {
4716       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4717         mac_set = 1;
4718       else
4719         break;
4720     }
4721
4722   /* Construct the API message */
4723   M (CREATE_LOOPBACK, mp);
4724   if (mac_set)
4725     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4726
4727   S (mp);
4728   W (ret);
4729   return ret;
4730 }
4731
4732 static int
4733 api_delete_loopback (vat_main_t * vam)
4734 {
4735   unformat_input_t *i = vam->input;
4736   vl_api_delete_loopback_t *mp;
4737   u32 sw_if_index = ~0;
4738   int ret;
4739
4740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4741     {
4742       if (unformat (i, "sw_if_index %d", &sw_if_index))
4743         ;
4744       else
4745         break;
4746     }
4747
4748   if (sw_if_index == ~0)
4749     {
4750       errmsg ("missing sw_if_index");
4751       return -99;
4752     }
4753
4754   /* Construct the API message */
4755   M (DELETE_LOOPBACK, mp);
4756   mp->sw_if_index = ntohl (sw_if_index);
4757
4758   S (mp);
4759   W (ret);
4760   return ret;
4761 }
4762
4763 static int
4764 api_want_stats (vat_main_t * vam)
4765 {
4766   unformat_input_t *i = vam->input;
4767   vl_api_want_stats_t *mp;
4768   int enable = -1;
4769   int ret;
4770
4771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4772     {
4773       if (unformat (i, "enable"))
4774         enable = 1;
4775       else if (unformat (i, "disable"))
4776         enable = 0;
4777       else
4778         break;
4779     }
4780
4781   if (enable == -1)
4782     {
4783       errmsg ("missing enable|disable");
4784       return -99;
4785     }
4786
4787   M (WANT_STATS, mp);
4788   mp->enable_disable = enable;
4789
4790   S (mp);
4791   W (ret);
4792   return ret;
4793 }
4794
4795 static int
4796 api_want_interface_events (vat_main_t * vam)
4797 {
4798   unformat_input_t *i = vam->input;
4799   vl_api_want_interface_events_t *mp;
4800   int enable = -1;
4801   int ret;
4802
4803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4804     {
4805       if (unformat (i, "enable"))
4806         enable = 1;
4807       else if (unformat (i, "disable"))
4808         enable = 0;
4809       else
4810         break;
4811     }
4812
4813   if (enable == -1)
4814     {
4815       errmsg ("missing enable|disable");
4816       return -99;
4817     }
4818
4819   M (WANT_INTERFACE_EVENTS, mp);
4820   mp->enable_disable = enable;
4821
4822   vam->interface_event_display = enable;
4823
4824   S (mp);
4825   W (ret);
4826   return ret;
4827 }
4828
4829
4830 /* Note: non-static, called once to set up the initial intfc table */
4831 int
4832 api_sw_interface_dump (vat_main_t * vam)
4833 {
4834   vl_api_sw_interface_dump_t *mp;
4835   vl_api_control_ping_t *mp_ping;
4836   hash_pair_t *p;
4837   name_sort_t *nses = 0, *ns;
4838   sw_interface_subif_t *sub = NULL;
4839   int ret;
4840
4841   /* Toss the old name table */
4842   /* *INDENT-OFF* */
4843   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4844   ({
4845     vec_add2 (nses, ns, 1);
4846     ns->name = (u8 *)(p->key);
4847     ns->value = (u32) p->value[0];
4848   }));
4849   /* *INDENT-ON* */
4850
4851   hash_free (vam->sw_if_index_by_interface_name);
4852
4853   vec_foreach (ns, nses) vec_free (ns->name);
4854
4855   vec_free (nses);
4856
4857   vec_foreach (sub, vam->sw_if_subif_table)
4858   {
4859     vec_free (sub->interface_name);
4860   }
4861   vec_free (vam->sw_if_subif_table);
4862
4863   /* recreate the interface name hash table */
4864   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4865
4866   /* Get list of ethernets */
4867   M (SW_INTERFACE_DUMP, mp);
4868   mp->name_filter_valid = 1;
4869   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4870   S (mp);
4871
4872   /* and local / loopback interfaces */
4873   M (SW_INTERFACE_DUMP, mp);
4874   mp->name_filter_valid = 1;
4875   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4876   S (mp);
4877
4878   /* and packet-generator interfaces */
4879   M (SW_INTERFACE_DUMP, mp);
4880   mp->name_filter_valid = 1;
4881   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4882   S (mp);
4883
4884   /* and vxlan-gpe tunnel interfaces */
4885   M (SW_INTERFACE_DUMP, mp);
4886   mp->name_filter_valid = 1;
4887   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4888            sizeof (mp->name_filter) - 1);
4889   S (mp);
4890
4891   /* and vxlan tunnel interfaces */
4892   M (SW_INTERFACE_DUMP, mp);
4893   mp->name_filter_valid = 1;
4894   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4895   S (mp);
4896
4897   /* and host (af_packet) interfaces */
4898   M (SW_INTERFACE_DUMP, mp);
4899   mp->name_filter_valid = 1;
4900   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4901   S (mp);
4902
4903   /* and l2tpv3 tunnel interfaces */
4904   M (SW_INTERFACE_DUMP, mp);
4905   mp->name_filter_valid = 1;
4906   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4907            sizeof (mp->name_filter) - 1);
4908   S (mp);
4909
4910   /* and GRE tunnel interfaces */
4911   M (SW_INTERFACE_DUMP, mp);
4912   mp->name_filter_valid = 1;
4913   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4914   S (mp);
4915
4916   /* and LISP-GPE interfaces */
4917   M (SW_INTERFACE_DUMP, mp);
4918   mp->name_filter_valid = 1;
4919   strncpy ((char *) mp->name_filter, "lisp_gpe",
4920            sizeof (mp->name_filter) - 1);
4921   S (mp);
4922
4923   /* and IPSEC tunnel interfaces */
4924   M (SW_INTERFACE_DUMP, mp);
4925   mp->name_filter_valid = 1;
4926   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4927   S (mp);
4928
4929   /* Use a control ping for synchronization */
4930   M (CONTROL_PING, mp_ping);
4931   S (mp_ping);
4932
4933   W (ret);
4934   return ret;
4935 }
4936
4937 static int
4938 api_sw_interface_set_flags (vat_main_t * vam)
4939 {
4940   unformat_input_t *i = vam->input;
4941   vl_api_sw_interface_set_flags_t *mp;
4942   u32 sw_if_index;
4943   u8 sw_if_index_set = 0;
4944   u8 admin_up = 0, link_up = 0;
4945   int ret;
4946
4947   /* Parse args required to build the message */
4948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4949     {
4950       if (unformat (i, "admin-up"))
4951         admin_up = 1;
4952       else if (unformat (i, "admin-down"))
4953         admin_up = 0;
4954       else if (unformat (i, "link-up"))
4955         link_up = 1;
4956       else if (unformat (i, "link-down"))
4957         link_up = 0;
4958       else
4959         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4960         sw_if_index_set = 1;
4961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4962         sw_if_index_set = 1;
4963       else
4964         break;
4965     }
4966
4967   if (sw_if_index_set == 0)
4968     {
4969       errmsg ("missing interface name or sw_if_index");
4970       return -99;
4971     }
4972
4973   /* Construct the API message */
4974   M (SW_INTERFACE_SET_FLAGS, mp);
4975   mp->sw_if_index = ntohl (sw_if_index);
4976   mp->admin_up_down = admin_up;
4977   mp->link_up_down = link_up;
4978
4979   /* send it... */
4980   S (mp);
4981
4982   /* Wait for a reply, return the good/bad news... */
4983   W (ret);
4984   return ret;
4985 }
4986
4987 static int
4988 api_sw_interface_clear_stats (vat_main_t * vam)
4989 {
4990   unformat_input_t *i = vam->input;
4991   vl_api_sw_interface_clear_stats_t *mp;
4992   u32 sw_if_index;
4993   u8 sw_if_index_set = 0;
4994   int ret;
4995
4996   /* Parse args required to build the message */
4997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4998     {
4999       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5000         sw_if_index_set = 1;
5001       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5002         sw_if_index_set = 1;
5003       else
5004         break;
5005     }
5006
5007   /* Construct the API message */
5008   M (SW_INTERFACE_CLEAR_STATS, mp);
5009
5010   if (sw_if_index_set == 1)
5011     mp->sw_if_index = ntohl (sw_if_index);
5012   else
5013     mp->sw_if_index = ~0;
5014
5015   /* send it... */
5016   S (mp);
5017
5018   /* Wait for a reply, return the good/bad news... */
5019   W (ret);
5020   return ret;
5021 }
5022
5023 #if DPDK >0
5024 static int
5025 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
5026 {
5027   unformat_input_t *i = vam->input;
5028   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
5029   u32 sw_if_index;
5030   u8 sw_if_index_set = 0;
5031   u32 subport;
5032   u8 subport_set = 0;
5033   u32 pipe;
5034   u8 pipe_set = 0;
5035   u32 profile;
5036   u8 profile_set = 0;
5037   int ret;
5038
5039   /* Parse args required to build the message */
5040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5041     {
5042       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5043         sw_if_index_set = 1;
5044       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5045         sw_if_index_set = 1;
5046       else if (unformat (i, "subport %u", &subport))
5047         subport_set = 1;
5048       else
5049         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5050         sw_if_index_set = 1;
5051       else if (unformat (i, "pipe %u", &pipe))
5052         pipe_set = 1;
5053       else if (unformat (i, "profile %u", &profile))
5054         profile_set = 1;
5055       else
5056         break;
5057     }
5058
5059   if (sw_if_index_set == 0)
5060     {
5061       errmsg ("missing interface name or sw_if_index");
5062       return -99;
5063     }
5064
5065   if (subport_set == 0)
5066     {
5067       errmsg ("missing subport ");
5068       return -99;
5069     }
5070
5071   if (pipe_set == 0)
5072     {
5073       errmsg ("missing pipe");
5074       return -99;
5075     }
5076
5077   if (profile_set == 0)
5078     {
5079       errmsg ("missing profile");
5080       return -99;
5081     }
5082
5083   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, mp);
5084
5085   mp->sw_if_index = ntohl (sw_if_index);
5086   mp->subport = ntohl (subport);
5087   mp->pipe = ntohl (pipe);
5088   mp->profile = ntohl (profile);
5089
5090
5091   S (mp);
5092   W (ret);
5093   return ret;
5094 }
5095
5096 static int
5097 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
5098 {
5099   unformat_input_t *i = vam->input;
5100   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
5101   u32 sw_if_index;
5102   u8 sw_if_index_set = 0;
5103   u32 subport;
5104   u8 subport_set = 0;
5105   u32 tb_rate = 1250000000;     /* 10GbE */
5106   u32 tb_size = 1000000;
5107   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
5108   u32 tc_period = 10;
5109   int ret;
5110
5111   /* Parse args required to build the message */
5112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5113     {
5114       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5115         sw_if_index_set = 1;
5116       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5117         sw_if_index_set = 1;
5118       else if (unformat (i, "subport %u", &subport))
5119         subport_set = 1;
5120       else
5121         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5122         sw_if_index_set = 1;
5123       else if (unformat (i, "rate %u", &tb_rate))
5124         {
5125           u32 tc_id;
5126
5127           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
5128                tc_id++)
5129             tc_rate[tc_id] = tb_rate;
5130         }
5131       else if (unformat (i, "bktsize %u", &tb_size))
5132         ;
5133       else if (unformat (i, "tc0 %u", &tc_rate[0]))
5134         ;
5135       else if (unformat (i, "tc1 %u", &tc_rate[1]))
5136         ;
5137       else if (unformat (i, "tc2 %u", &tc_rate[2]))
5138         ;
5139       else if (unformat (i, "tc3 %u", &tc_rate[3]))
5140         ;
5141       else if (unformat (i, "period %u", &tc_period))
5142         ;
5143       else
5144         break;
5145     }
5146
5147   if (sw_if_index_set == 0)
5148     {
5149       errmsg ("missing interface name or sw_if_index");
5150       return -99;
5151     }
5152
5153   if (subport_set == 0)
5154     {
5155       errmsg ("missing subport ");
5156       return -99;
5157     }
5158
5159   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, mp);
5160
5161   mp->sw_if_index = ntohl (sw_if_index);
5162   mp->subport = ntohl (subport);
5163   mp->tb_rate = ntohl (tb_rate);
5164   mp->tb_size = ntohl (tb_size);
5165   mp->tc_rate[0] = ntohl (tc_rate[0]);
5166   mp->tc_rate[1] = ntohl (tc_rate[1]);
5167   mp->tc_rate[2] = ntohl (tc_rate[2]);
5168   mp->tc_rate[3] = ntohl (tc_rate[3]);
5169   mp->tc_period = ntohl (tc_period);
5170
5171   S (mp);
5172   W (ret);
5173   return ret;
5174 }
5175
5176 static int
5177 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
5178 {
5179   unformat_input_t *i = vam->input;
5180   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
5181   u32 sw_if_index;
5182   u8 sw_if_index_set = 0;
5183   u8 entry_set = 0;
5184   u8 tc_set = 0;
5185   u8 queue_set = 0;
5186   u32 entry, tc, queue;
5187   int ret;
5188
5189   /* Parse args required to build the message */
5190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5191     {
5192       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5193         sw_if_index_set = 1;
5194       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5195         sw_if_index_set = 1;
5196       else if (unformat (i, "entry %d", &entry))
5197         entry_set = 1;
5198       else if (unformat (i, "tc %d", &tc))
5199         tc_set = 1;
5200       else if (unformat (i, "queue %d", &queue))
5201         queue_set = 1;
5202       else
5203         break;
5204     }
5205
5206   if (sw_if_index_set == 0)
5207     {
5208       errmsg ("missing interface name or sw_if_index");
5209       return -99;
5210     }
5211
5212   if (entry_set == 0)
5213     {
5214       errmsg ("missing entry ");
5215       return -99;
5216     }
5217
5218   if (tc_set == 0)
5219     {
5220       errmsg ("missing traffic class ");
5221       return -99;
5222     }
5223
5224   if (queue_set == 0)
5225     {
5226       errmsg ("missing queue ");
5227       return -99;
5228     }
5229
5230   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, mp);
5231
5232   mp->sw_if_index = ntohl (sw_if_index);
5233   mp->entry = ntohl (entry);
5234   mp->tc = ntohl (tc);
5235   mp->queue = ntohl (queue);
5236
5237   S (mp);
5238   W (ret);
5239   return ret;
5240 }
5241 #endif
5242
5243 static int
5244 api_sw_interface_add_del_address (vat_main_t * vam)
5245 {
5246   unformat_input_t *i = vam->input;
5247   vl_api_sw_interface_add_del_address_t *mp;
5248   u32 sw_if_index;
5249   u8 sw_if_index_set = 0;
5250   u8 is_add = 1, del_all = 0;
5251   u32 address_length = 0;
5252   u8 v4_address_set = 0;
5253   u8 v6_address_set = 0;
5254   ip4_address_t v4address;
5255   ip6_address_t v6address;
5256   int ret;
5257
5258   /* Parse args required to build the message */
5259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5260     {
5261       if (unformat (i, "del-all"))
5262         del_all = 1;
5263       else if (unformat (i, "del"))
5264         is_add = 0;
5265       else
5266         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5267         sw_if_index_set = 1;
5268       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5269         sw_if_index_set = 1;
5270       else if (unformat (i, "%U/%d",
5271                          unformat_ip4_address, &v4address, &address_length))
5272         v4_address_set = 1;
5273       else if (unformat (i, "%U/%d",
5274                          unformat_ip6_address, &v6address, &address_length))
5275         v6_address_set = 1;
5276       else
5277         break;
5278     }
5279
5280   if (sw_if_index_set == 0)
5281     {
5282       errmsg ("missing interface name or sw_if_index");
5283       return -99;
5284     }
5285   if (v4_address_set && v6_address_set)
5286     {
5287       errmsg ("both v4 and v6 addresses set");
5288       return -99;
5289     }
5290   if (!v4_address_set && !v6_address_set && !del_all)
5291     {
5292       errmsg ("no addresses set");
5293       return -99;
5294     }
5295
5296   /* Construct the API message */
5297   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5298
5299   mp->sw_if_index = ntohl (sw_if_index);
5300   mp->is_add = is_add;
5301   mp->del_all = del_all;
5302   if (v6_address_set)
5303     {
5304       mp->is_ipv6 = 1;
5305       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5306     }
5307   else
5308     {
5309       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5310     }
5311   mp->address_length = address_length;
5312
5313   /* send it... */
5314   S (mp);
5315
5316   /* Wait for a reply, return good/bad news  */
5317   W (ret);
5318   return ret;
5319 }
5320
5321 static int
5322 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5323 {
5324   unformat_input_t *i = vam->input;
5325   vl_api_sw_interface_set_mpls_enable_t *mp;
5326   u32 sw_if_index;
5327   u8 sw_if_index_set = 0;
5328   u8 enable = 1;
5329   int ret;
5330
5331   /* Parse args required to build the message */
5332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5333     {
5334       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5335         sw_if_index_set = 1;
5336       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5337         sw_if_index_set = 1;
5338       else if (unformat (i, "disable"))
5339         enable = 0;
5340       else if (unformat (i, "dis"))
5341         enable = 0;
5342       else
5343         break;
5344     }
5345
5346   if (sw_if_index_set == 0)
5347     {
5348       errmsg ("missing interface name or sw_if_index");
5349       return -99;
5350     }
5351
5352   /* Construct the API message */
5353   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5354
5355   mp->sw_if_index = ntohl (sw_if_index);
5356   mp->enable = enable;
5357
5358   /* send it... */
5359   S (mp);
5360
5361   /* Wait for a reply... */
5362   W (ret);
5363   return ret;
5364 }
5365
5366 static int
5367 api_sw_interface_set_table (vat_main_t * vam)
5368 {
5369   unformat_input_t *i = vam->input;
5370   vl_api_sw_interface_set_table_t *mp;
5371   u32 sw_if_index, vrf_id = 0;
5372   u8 sw_if_index_set = 0;
5373   u8 is_ipv6 = 0;
5374   int ret;
5375
5376   /* Parse args required to build the message */
5377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5378     {
5379       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5380         sw_if_index_set = 1;
5381       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5382         sw_if_index_set = 1;
5383       else if (unformat (i, "vrf %d", &vrf_id))
5384         ;
5385       else if (unformat (i, "ipv6"))
5386         is_ipv6 = 1;
5387       else
5388         break;
5389     }
5390
5391   if (sw_if_index_set == 0)
5392     {
5393       errmsg ("missing interface name or sw_if_index");
5394       return -99;
5395     }
5396
5397   /* Construct the API message */
5398   M (SW_INTERFACE_SET_TABLE, mp);
5399
5400   mp->sw_if_index = ntohl (sw_if_index);
5401   mp->is_ipv6 = is_ipv6;
5402   mp->vrf_id = ntohl (vrf_id);
5403
5404   /* send it... */
5405   S (mp);
5406
5407   /* Wait for a reply... */
5408   W (ret);
5409   return ret;
5410 }
5411
5412 static void vl_api_sw_interface_get_table_reply_t_handler
5413   (vl_api_sw_interface_get_table_reply_t * mp)
5414 {
5415   vat_main_t *vam = &vat_main;
5416
5417   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5418
5419   vam->retval = ntohl (mp->retval);
5420   vam->result_ready = 1;
5421
5422 }
5423
5424 static void vl_api_sw_interface_get_table_reply_t_handler_json
5425   (vl_api_sw_interface_get_table_reply_t * mp)
5426 {
5427   vat_main_t *vam = &vat_main;
5428   vat_json_node_t node;
5429
5430   vat_json_init_object (&node);
5431   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5432   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5433
5434   vat_json_print (vam->ofp, &node);
5435   vat_json_free (&node);
5436
5437   vam->retval = ntohl (mp->retval);
5438   vam->result_ready = 1;
5439 }
5440
5441 static int
5442 api_sw_interface_get_table (vat_main_t * vam)
5443 {
5444   unformat_input_t *i = vam->input;
5445   vl_api_sw_interface_get_table_t *mp;
5446   u32 sw_if_index;
5447   u8 sw_if_index_set = 0;
5448   u8 is_ipv6 = 0;
5449   int ret;
5450
5451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5452     {
5453       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5454         sw_if_index_set = 1;
5455       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5456         sw_if_index_set = 1;
5457       else if (unformat (i, "ipv6"))
5458         is_ipv6 = 1;
5459       else
5460         break;
5461     }
5462
5463   if (sw_if_index_set == 0)
5464     {
5465       errmsg ("missing interface name or sw_if_index");
5466       return -99;
5467     }
5468
5469   M (SW_INTERFACE_GET_TABLE, mp);
5470   mp->sw_if_index = htonl (sw_if_index);
5471   mp->is_ipv6 = is_ipv6;
5472
5473   S (mp);
5474   W (ret);
5475   return ret;
5476 }
5477
5478 static int
5479 api_sw_interface_set_vpath (vat_main_t * vam)
5480 {
5481   unformat_input_t *i = vam->input;
5482   vl_api_sw_interface_set_vpath_t *mp;
5483   u32 sw_if_index = 0;
5484   u8 sw_if_index_set = 0;
5485   u8 is_enable = 0;
5486   int ret;
5487
5488   /* Parse args required to build the message */
5489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5490     {
5491       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5492         sw_if_index_set = 1;
5493       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5494         sw_if_index_set = 1;
5495       else if (unformat (i, "enable"))
5496         is_enable = 1;
5497       else if (unformat (i, "disable"))
5498         is_enable = 0;
5499       else
5500         break;
5501     }
5502
5503   if (sw_if_index_set == 0)
5504     {
5505       errmsg ("missing interface name or sw_if_index");
5506       return -99;
5507     }
5508
5509   /* Construct the API message */
5510   M (SW_INTERFACE_SET_VPATH, mp);
5511
5512   mp->sw_if_index = ntohl (sw_if_index);
5513   mp->enable = is_enable;
5514
5515   /* send it... */
5516   S (mp);
5517
5518   /* Wait for a reply... */
5519   W (ret);
5520   return ret;
5521 }
5522
5523 static int
5524 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5525 {
5526   unformat_input_t *i = vam->input;
5527   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5528   u32 sw_if_index = 0;
5529   u8 sw_if_index_set = 0;
5530   u8 is_enable = 1;
5531   u8 is_ipv6 = 0;
5532   int ret;
5533
5534   /* Parse args required to build the message */
5535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5536     {
5537       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5538         sw_if_index_set = 1;
5539       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5540         sw_if_index_set = 1;
5541       else if (unformat (i, "enable"))
5542         is_enable = 1;
5543       else if (unformat (i, "disable"))
5544         is_enable = 0;
5545       else if (unformat (i, "ip4"))
5546         is_ipv6 = 0;
5547       else if (unformat (i, "ip6"))
5548         is_ipv6 = 1;
5549       else
5550         break;
5551     }
5552
5553   if (sw_if_index_set == 0)
5554     {
5555       errmsg ("missing interface name or sw_if_index");
5556       return -99;
5557     }
5558
5559   /* Construct the API message */
5560   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5561
5562   mp->sw_if_index = ntohl (sw_if_index);
5563   mp->enable = is_enable;
5564   mp->is_ipv6 = is_ipv6;
5565
5566   /* send it... */
5567   S (mp);
5568
5569   /* Wait for a reply... */
5570   W (ret);
5571   return ret;
5572 }
5573
5574 static int
5575 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5576 {
5577   unformat_input_t *i = vam->input;
5578   vl_api_sw_interface_set_l2_xconnect_t *mp;
5579   u32 rx_sw_if_index;
5580   u8 rx_sw_if_index_set = 0;
5581   u32 tx_sw_if_index;
5582   u8 tx_sw_if_index_set = 0;
5583   u8 enable = 1;
5584   int ret;
5585
5586   /* Parse args required to build the message */
5587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5588     {
5589       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5590         rx_sw_if_index_set = 1;
5591       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5592         tx_sw_if_index_set = 1;
5593       else if (unformat (i, "rx"))
5594         {
5595           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5596             {
5597               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5598                             &rx_sw_if_index))
5599                 rx_sw_if_index_set = 1;
5600             }
5601           else
5602             break;
5603         }
5604       else if (unformat (i, "tx"))
5605         {
5606           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5607             {
5608               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5609                             &tx_sw_if_index))
5610                 tx_sw_if_index_set = 1;
5611             }
5612           else
5613             break;
5614         }
5615       else if (unformat (i, "enable"))
5616         enable = 1;
5617       else if (unformat (i, "disable"))
5618         enable = 0;
5619       else
5620         break;
5621     }
5622
5623   if (rx_sw_if_index_set == 0)
5624     {
5625       errmsg ("missing rx interface name or rx_sw_if_index");
5626       return -99;
5627     }
5628
5629   if (enable && (tx_sw_if_index_set == 0))
5630     {
5631       errmsg ("missing tx interface name or tx_sw_if_index");
5632       return -99;
5633     }
5634
5635   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5636
5637   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5638   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5639   mp->enable = enable;
5640
5641   S (mp);
5642   W (ret);
5643   return ret;
5644 }
5645
5646 static int
5647 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5648 {
5649   unformat_input_t *i = vam->input;
5650   vl_api_sw_interface_set_l2_bridge_t *mp;
5651   u32 rx_sw_if_index;
5652   u8 rx_sw_if_index_set = 0;
5653   u32 bd_id;
5654   u8 bd_id_set = 0;
5655   u8 bvi = 0;
5656   u32 shg = 0;
5657   u8 enable = 1;
5658   int ret;
5659
5660   /* Parse args required to build the message */
5661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5662     {
5663       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5664         rx_sw_if_index_set = 1;
5665       else if (unformat (i, "bd_id %d", &bd_id))
5666         bd_id_set = 1;
5667       else
5668         if (unformat
5669             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5670         rx_sw_if_index_set = 1;
5671       else if (unformat (i, "shg %d", &shg))
5672         ;
5673       else if (unformat (i, "bvi"))
5674         bvi = 1;
5675       else if (unformat (i, "enable"))
5676         enable = 1;
5677       else if (unformat (i, "disable"))
5678         enable = 0;
5679       else
5680         break;
5681     }
5682
5683   if (rx_sw_if_index_set == 0)
5684     {
5685       errmsg ("missing rx interface name or sw_if_index");
5686       return -99;
5687     }
5688
5689   if (enable && (bd_id_set == 0))
5690     {
5691       errmsg ("missing bridge domain");
5692       return -99;
5693     }
5694
5695   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5696
5697   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5698   mp->bd_id = ntohl (bd_id);
5699   mp->shg = (u8) shg;
5700   mp->bvi = bvi;
5701   mp->enable = enable;
5702
5703   S (mp);
5704   W (ret);
5705   return ret;
5706 }
5707
5708 static int
5709 api_bridge_domain_dump (vat_main_t * vam)
5710 {
5711   unformat_input_t *i = vam->input;
5712   vl_api_bridge_domain_dump_t *mp;
5713   vl_api_control_ping_t *mp_ping;
5714   u32 bd_id = ~0;
5715   int ret;
5716
5717   /* Parse args required to build the message */
5718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5719     {
5720       if (unformat (i, "bd_id %d", &bd_id))
5721         ;
5722       else
5723         break;
5724     }
5725
5726   M (BRIDGE_DOMAIN_DUMP, mp);
5727   mp->bd_id = ntohl (bd_id);
5728   S (mp);
5729
5730   /* Use a control ping for synchronization */
5731   M (CONTROL_PING, mp_ping);
5732   S (mp_ping);
5733
5734   W (ret);
5735   return ret;
5736 }
5737
5738 static int
5739 api_bridge_domain_add_del (vat_main_t * vam)
5740 {
5741   unformat_input_t *i = vam->input;
5742   vl_api_bridge_domain_add_del_t *mp;
5743   u32 bd_id = ~0;
5744   u8 is_add = 1;
5745   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5746   u32 mac_age = 0;
5747   int ret;
5748
5749   /* Parse args required to build the message */
5750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5751     {
5752       if (unformat (i, "bd_id %d", &bd_id))
5753         ;
5754       else if (unformat (i, "flood %d", &flood))
5755         ;
5756       else if (unformat (i, "uu-flood %d", &uu_flood))
5757         ;
5758       else if (unformat (i, "forward %d", &forward))
5759         ;
5760       else if (unformat (i, "learn %d", &learn))
5761         ;
5762       else if (unformat (i, "arp-term %d", &arp_term))
5763         ;
5764       else if (unformat (i, "mac-age %d", &mac_age))
5765         ;
5766       else if (unformat (i, "del"))
5767         {
5768           is_add = 0;
5769           flood = uu_flood = forward = learn = 0;
5770         }
5771       else
5772         break;
5773     }
5774
5775   if (bd_id == ~0)
5776     {
5777       errmsg ("missing bridge domain");
5778       return -99;
5779     }
5780
5781   if (mac_age > 255)
5782     {
5783       errmsg ("mac age must be less than 256 ");
5784       return -99;
5785     }
5786
5787   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5788
5789   mp->bd_id = ntohl (bd_id);
5790   mp->flood = flood;
5791   mp->uu_flood = uu_flood;
5792   mp->forward = forward;
5793   mp->learn = learn;
5794   mp->arp_term = arp_term;
5795   mp->is_add = is_add;
5796   mp->mac_age = (u8) mac_age;
5797
5798   S (mp);
5799   W (ret);
5800   return ret;
5801 }
5802
5803 static int
5804 api_l2fib_add_del (vat_main_t * vam)
5805 {
5806   unformat_input_t *i = vam->input;
5807   vl_api_l2fib_add_del_t *mp;
5808   f64 timeout;
5809   u64 mac = 0;
5810   u8 mac_set = 0;
5811   u32 bd_id;
5812   u8 bd_id_set = 0;
5813   u32 sw_if_index = ~0;
5814   u8 sw_if_index_set = 0;
5815   u8 is_add = 1;
5816   u8 static_mac = 0;
5817   u8 filter_mac = 0;
5818   u8 bvi_mac = 0;
5819   int count = 1;
5820   f64 before = 0;
5821   int j;
5822
5823   /* Parse args required to build the message */
5824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5825     {
5826       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5827         mac_set = 1;
5828       else if (unformat (i, "bd_id %d", &bd_id))
5829         bd_id_set = 1;
5830       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5831         sw_if_index_set = 1;
5832       else if (unformat (i, "sw_if"))
5833         {
5834           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5835             {
5836               if (unformat
5837                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5838                 sw_if_index_set = 1;
5839             }
5840           else
5841             break;
5842         }
5843       else if (unformat (i, "static"))
5844         static_mac = 1;
5845       else if (unformat (i, "filter"))
5846         {
5847           filter_mac = 1;
5848           static_mac = 1;
5849         }
5850       else if (unformat (i, "bvi"))
5851         {
5852           bvi_mac = 1;
5853           static_mac = 1;
5854         }
5855       else if (unformat (i, "del"))
5856         is_add = 0;
5857       else if (unformat (i, "count %d", &count))
5858         ;
5859       else
5860         break;
5861     }
5862
5863   if (mac_set == 0)
5864     {
5865       errmsg ("missing mac address");
5866       return -99;
5867     }
5868
5869   if (bd_id_set == 0)
5870     {
5871       errmsg ("missing bridge domain");
5872       return -99;
5873     }
5874
5875   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5876     {
5877       errmsg ("missing interface name or sw_if_index");
5878       return -99;
5879     }
5880
5881   if (count > 1)
5882     {
5883       /* Turn on async mode */
5884       vam->async_mode = 1;
5885       vam->async_errors = 0;
5886       before = vat_time_now (vam);
5887     }
5888
5889   for (j = 0; j < count; j++)
5890     {
5891       M (L2FIB_ADD_DEL, mp);
5892
5893       mp->mac = mac;
5894       mp->bd_id = ntohl (bd_id);
5895       mp->is_add = is_add;
5896
5897       if (is_add)
5898         {
5899           mp->sw_if_index = ntohl (sw_if_index);
5900           mp->static_mac = static_mac;
5901           mp->filter_mac = filter_mac;
5902           mp->bvi_mac = bvi_mac;
5903         }
5904       increment_mac_address (&mac);
5905       /* send it... */
5906       S (mp);
5907     }
5908
5909   if (count > 1)
5910     {
5911       vl_api_control_ping_t *mp_ping;
5912       f64 after;
5913
5914       /* Shut off async mode */
5915       vam->async_mode = 0;
5916
5917       M (CONTROL_PING, mp_ping);
5918       S (mp_ping);
5919
5920       timeout = vat_time_now (vam) + 1.0;
5921       while (vat_time_now (vam) < timeout)
5922         if (vam->result_ready == 1)
5923           goto out;
5924       vam->retval = -99;
5925
5926     out:
5927       if (vam->retval == -99)
5928         errmsg ("timeout");
5929
5930       if (vam->async_errors > 0)
5931         {
5932           errmsg ("%d asynchronous errors", vam->async_errors);
5933           vam->retval = -98;
5934         }
5935       vam->async_errors = 0;
5936       after = vat_time_now (vam);
5937
5938       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5939              count, after - before, count / (after - before));
5940     }
5941   else
5942     {
5943       int ret;
5944
5945       /* Wait for a reply... */
5946       W (ret);
5947       return ret;
5948     }
5949   /* Return the good/bad news */
5950   return (vam->retval);
5951 }
5952
5953 static int
5954 api_l2_flags (vat_main_t * vam)
5955 {
5956   unformat_input_t *i = vam->input;
5957   vl_api_l2_flags_t *mp;
5958   u32 sw_if_index;
5959   u32 feature_bitmap = 0;
5960   u8 sw_if_index_set = 0;
5961   int ret;
5962
5963   /* Parse args required to build the message */
5964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5965     {
5966       if (unformat (i, "sw_if_index %d", &sw_if_index))
5967         sw_if_index_set = 1;
5968       else if (unformat (i, "sw_if"))
5969         {
5970           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5971             {
5972               if (unformat
5973                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5974                 sw_if_index_set = 1;
5975             }
5976           else
5977             break;
5978         }
5979       else if (unformat (i, "learn"))
5980         feature_bitmap |= L2INPUT_FEAT_LEARN;
5981       else if (unformat (i, "forward"))
5982         feature_bitmap |= L2INPUT_FEAT_FWD;
5983       else if (unformat (i, "flood"))
5984         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5985       else if (unformat (i, "uu-flood"))
5986         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5987       else
5988         break;
5989     }
5990
5991   if (sw_if_index_set == 0)
5992     {
5993       errmsg ("missing interface name or sw_if_index");
5994       return -99;
5995     }
5996
5997   M (L2_FLAGS, mp);
5998
5999   mp->sw_if_index = ntohl (sw_if_index);
6000   mp->feature_bitmap = ntohl (feature_bitmap);
6001
6002   S (mp);
6003   W (ret);
6004   return ret;
6005 }
6006
6007 static int
6008 api_bridge_flags (vat_main_t * vam)
6009 {
6010   unformat_input_t *i = vam->input;
6011   vl_api_bridge_flags_t *mp;
6012   u32 bd_id;
6013   u8 bd_id_set = 0;
6014   u8 is_set = 1;
6015   u32 flags = 0;
6016   int ret;
6017
6018   /* Parse args required to build the message */
6019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6020     {
6021       if (unformat (i, "bd_id %d", &bd_id))
6022         bd_id_set = 1;
6023       else if (unformat (i, "learn"))
6024         flags |= L2_LEARN;
6025       else if (unformat (i, "forward"))
6026         flags |= L2_FWD;
6027       else if (unformat (i, "flood"))
6028         flags |= L2_FLOOD;
6029       else if (unformat (i, "uu-flood"))
6030         flags |= L2_UU_FLOOD;
6031       else if (unformat (i, "arp-term"))
6032         flags |= L2_ARP_TERM;
6033       else if (unformat (i, "off"))
6034         is_set = 0;
6035       else if (unformat (i, "disable"))
6036         is_set = 0;
6037       else
6038         break;
6039     }
6040
6041   if (bd_id_set == 0)
6042     {
6043       errmsg ("missing bridge domain");
6044       return -99;
6045     }
6046
6047   M (BRIDGE_FLAGS, mp);
6048
6049   mp->bd_id = ntohl (bd_id);
6050   mp->feature_bitmap = ntohl (flags);
6051   mp->is_set = is_set;
6052
6053   S (mp);
6054   W (ret);
6055   return ret;
6056 }
6057
6058 static int
6059 api_bd_ip_mac_add_del (vat_main_t * vam)
6060 {
6061   unformat_input_t *i = vam->input;
6062   vl_api_bd_ip_mac_add_del_t *mp;
6063   u32 bd_id;
6064   u8 is_ipv6 = 0;
6065   u8 is_add = 1;
6066   u8 bd_id_set = 0;
6067   u8 ip_set = 0;
6068   u8 mac_set = 0;
6069   ip4_address_t v4addr;
6070   ip6_address_t v6addr;
6071   u8 macaddr[6];
6072   int ret;
6073
6074
6075   /* Parse args required to build the message */
6076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6077     {
6078       if (unformat (i, "bd_id %d", &bd_id))
6079         {
6080           bd_id_set++;
6081         }
6082       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6083         {
6084           ip_set++;
6085         }
6086       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6087         {
6088           ip_set++;
6089           is_ipv6++;
6090         }
6091       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6092         {
6093           mac_set++;
6094         }
6095       else if (unformat (i, "del"))
6096         is_add = 0;
6097       else
6098         break;
6099     }
6100
6101   if (bd_id_set == 0)
6102     {
6103       errmsg ("missing bridge domain");
6104       return -99;
6105     }
6106   else if (ip_set == 0)
6107     {
6108       errmsg ("missing IP address");
6109       return -99;
6110     }
6111   else if (mac_set == 0)
6112     {
6113       errmsg ("missing MAC address");
6114       return -99;
6115     }
6116
6117   M (BD_IP_MAC_ADD_DEL, mp);
6118
6119   mp->bd_id = ntohl (bd_id);
6120   mp->is_ipv6 = is_ipv6;
6121   mp->is_add = is_add;
6122   if (is_ipv6)
6123     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6124   else
6125     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6126   clib_memcpy (mp->mac_address, macaddr, 6);
6127   S (mp);
6128   W (ret);
6129   return ret;
6130 }
6131
6132 static int
6133 api_tap_connect (vat_main_t * vam)
6134 {
6135   unformat_input_t *i = vam->input;
6136   vl_api_tap_connect_t *mp;
6137   u8 mac_address[6];
6138   u8 random_mac = 1;
6139   u8 name_set = 0;
6140   u8 *tap_name;
6141   u8 *tag = 0;
6142   ip4_address_t ip4_address;
6143   u32 ip4_mask_width;
6144   int ip4_address_set = 0;
6145   ip6_address_t ip6_address;
6146   u32 ip6_mask_width;
6147   int ip6_address_set = 0;
6148   int ret;
6149
6150   memset (mac_address, 0, sizeof (mac_address));
6151
6152   /* Parse args required to build the message */
6153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6154     {
6155       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6156         {
6157           random_mac = 0;
6158         }
6159       else if (unformat (i, "random-mac"))
6160         random_mac = 1;
6161       else if (unformat (i, "tapname %s", &tap_name))
6162         name_set = 1;
6163       else if (unformat (i, "tag %s", &tag))
6164         ;
6165       else if (unformat (i, "address %U/%d",
6166                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6167         ip4_address_set = 1;
6168       else if (unformat (i, "address %U/%d",
6169                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6170         ip6_address_set = 1;
6171       else
6172         break;
6173     }
6174
6175   if (name_set == 0)
6176     {
6177       errmsg ("missing tap name");
6178       return -99;
6179     }
6180   if (vec_len (tap_name) > 63)
6181     {
6182       errmsg ("tap name too long");
6183       return -99;
6184     }
6185   vec_add1 (tap_name, 0);
6186
6187   if (vec_len (tag) > 63)
6188     {
6189       errmsg ("tag too long");
6190       return -99;
6191     }
6192
6193   /* Construct the API message */
6194   M (TAP_CONNECT, mp);
6195
6196   mp->use_random_mac = random_mac;
6197   clib_memcpy (mp->mac_address, mac_address, 6);
6198   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6199   if (tag)
6200     clib_memcpy (mp->tag, tag, vec_len (tag));
6201
6202   if (ip4_address_set)
6203     {
6204       mp->ip4_address_set = 1;
6205       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6206       mp->ip4_mask_width = ip4_mask_width;
6207     }
6208   if (ip6_address_set)
6209     {
6210       mp->ip6_address_set = 1;
6211       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6212       mp->ip6_mask_width = ip6_mask_width;
6213     }
6214
6215   vec_free (tap_name);
6216   vec_free (tag);
6217
6218   /* send it... */
6219   S (mp);
6220
6221   /* Wait for a reply... */
6222   W (ret);
6223   return ret;
6224 }
6225
6226 static int
6227 api_tap_modify (vat_main_t * vam)
6228 {
6229   unformat_input_t *i = vam->input;
6230   vl_api_tap_modify_t *mp;
6231   u8 mac_address[6];
6232   u8 random_mac = 1;
6233   u8 name_set = 0;
6234   u8 *tap_name;
6235   u32 sw_if_index = ~0;
6236   u8 sw_if_index_set = 0;
6237   int ret;
6238
6239   memset (mac_address, 0, sizeof (mac_address));
6240
6241   /* Parse args required to build the message */
6242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6243     {
6244       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6245         sw_if_index_set = 1;
6246       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6247         sw_if_index_set = 1;
6248       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6249         {
6250           random_mac = 0;
6251         }
6252       else if (unformat (i, "random-mac"))
6253         random_mac = 1;
6254       else if (unformat (i, "tapname %s", &tap_name))
6255         name_set = 1;
6256       else
6257         break;
6258     }
6259
6260   if (sw_if_index_set == 0)
6261     {
6262       errmsg ("missing vpp interface name");
6263       return -99;
6264     }
6265   if (name_set == 0)
6266     {
6267       errmsg ("missing tap name");
6268       return -99;
6269     }
6270   if (vec_len (tap_name) > 63)
6271     {
6272       errmsg ("tap name too long");
6273     }
6274   vec_add1 (tap_name, 0);
6275
6276   /* Construct the API message */
6277   M (TAP_MODIFY, mp);
6278
6279   mp->use_random_mac = random_mac;
6280   mp->sw_if_index = ntohl (sw_if_index);
6281   clib_memcpy (mp->mac_address, mac_address, 6);
6282   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6283   vec_free (tap_name);
6284
6285   /* send it... */
6286   S (mp);
6287
6288   /* Wait for a reply... */
6289   W (ret);
6290   return ret;
6291 }
6292
6293 static int
6294 api_tap_delete (vat_main_t * vam)
6295 {
6296   unformat_input_t *i = vam->input;
6297   vl_api_tap_delete_t *mp;
6298   u32 sw_if_index = ~0;
6299   u8 sw_if_index_set = 0;
6300   int ret;
6301
6302   /* Parse args required to build the message */
6303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6304     {
6305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6306         sw_if_index_set = 1;
6307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6308         sw_if_index_set = 1;
6309       else
6310         break;
6311     }
6312
6313   if (sw_if_index_set == 0)
6314     {
6315       errmsg ("missing vpp interface name");
6316       return -99;
6317     }
6318
6319   /* Construct the API message */
6320   M (TAP_DELETE, mp);
6321
6322   mp->sw_if_index = ntohl (sw_if_index);
6323
6324   /* send it... */
6325   S (mp);
6326
6327   /* Wait for a reply... */
6328   W (ret);
6329   return ret;
6330 }
6331
6332 static int
6333 api_ip_add_del_route (vat_main_t * vam)
6334 {
6335   unformat_input_t *i = vam->input;
6336   vl_api_ip_add_del_route_t *mp;
6337   u32 sw_if_index = ~0, vrf_id = 0;
6338   u8 is_ipv6 = 0;
6339   u8 is_local = 0, is_drop = 0;
6340   u8 is_unreach = 0, is_prohibit = 0;
6341   u8 create_vrf_if_needed = 0;
6342   u8 is_add = 1;
6343   u32 next_hop_weight = 1;
6344   u8 not_last = 0;
6345   u8 is_multipath = 0;
6346   u8 address_set = 0;
6347   u8 address_length_set = 0;
6348   u32 next_hop_table_id = 0;
6349   u32 resolve_attempts = 0;
6350   u32 dst_address_length = 0;
6351   u8 next_hop_set = 0;
6352   ip4_address_t v4_dst_address, v4_next_hop_address;
6353   ip6_address_t v6_dst_address, v6_next_hop_address;
6354   int count = 1;
6355   int j;
6356   f64 before = 0;
6357   u32 random_add_del = 0;
6358   u32 *random_vector = 0;
6359   uword *random_hash;
6360   u32 random_seed = 0xdeaddabe;
6361   u32 classify_table_index = ~0;
6362   u8 is_classify = 0;
6363   u8 resolve_host = 0, resolve_attached = 0;
6364   mpls_label_t *next_hop_out_label_stack = NULL;
6365   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6366   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6367
6368   /* Parse args required to build the message */
6369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6370     {
6371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6372         ;
6373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6374         ;
6375       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6376         {
6377           address_set = 1;
6378           is_ipv6 = 0;
6379         }
6380       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6381         {
6382           address_set = 1;
6383           is_ipv6 = 1;
6384         }
6385       else if (unformat (i, "/%d", &dst_address_length))
6386         {
6387           address_length_set = 1;
6388         }
6389
6390       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6391                                          &v4_next_hop_address))
6392         {
6393           next_hop_set = 1;
6394         }
6395       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6396                                          &v6_next_hop_address))
6397         {
6398           next_hop_set = 1;
6399         }
6400       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6401         ;
6402       else if (unformat (i, "weight %d", &next_hop_weight))
6403         ;
6404       else if (unformat (i, "drop"))
6405         {
6406           is_drop = 1;
6407         }
6408       else if (unformat (i, "null-send-unreach"))
6409         {
6410           is_unreach = 1;
6411         }
6412       else if (unformat (i, "null-send-prohibit"))
6413         {
6414           is_prohibit = 1;
6415         }
6416       else if (unformat (i, "local"))
6417         {
6418           is_local = 1;
6419         }
6420       else if (unformat (i, "classify %d", &classify_table_index))
6421         {
6422           is_classify = 1;
6423         }
6424       else if (unformat (i, "del"))
6425         is_add = 0;
6426       else if (unformat (i, "add"))
6427         is_add = 1;
6428       else if (unformat (i, "not-last"))
6429         not_last = 1;
6430       else if (unformat (i, "resolve-via-host"))
6431         resolve_host = 1;
6432       else if (unformat (i, "resolve-via-attached"))
6433         resolve_attached = 1;
6434       else if (unformat (i, "multipath"))
6435         is_multipath = 1;
6436       else if (unformat (i, "vrf %d", &vrf_id))
6437         ;
6438       else if (unformat (i, "create-vrf"))
6439         create_vrf_if_needed = 1;
6440       else if (unformat (i, "count %d", &count))
6441         ;
6442       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6443         ;
6444       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6445         ;
6446       else if (unformat (i, "out-label %d", &next_hop_out_label))
6447         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6448       else if (unformat (i, "via-label %d", &next_hop_via_label))
6449         ;
6450       else if (unformat (i, "random"))
6451         random_add_del = 1;
6452       else if (unformat (i, "seed %d", &random_seed))
6453         ;
6454       else
6455         {
6456           clib_warning ("parse error '%U'", format_unformat_error, i);
6457           return -99;
6458         }
6459     }
6460
6461   if (!next_hop_set && !is_drop && !is_local &&
6462       !is_classify && !is_unreach && !is_prohibit &&
6463       MPLS_LABEL_INVALID == next_hop_via_label)
6464     {
6465       errmsg
6466         ("next hop / local / drop / unreach / prohibit / classify not set");
6467       return -99;
6468     }
6469
6470   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6471     {
6472       errmsg ("next hop and next-hop via label set");
6473       return -99;
6474     }
6475   if (address_set == 0)
6476     {
6477       errmsg ("missing addresses");
6478       return -99;
6479     }
6480
6481   if (address_length_set == 0)
6482     {
6483       errmsg ("missing address length");
6484       return -99;
6485     }
6486
6487   /* Generate a pile of unique, random routes */
6488   if (random_add_del)
6489     {
6490       u32 this_random_address;
6491       random_hash = hash_create (count, sizeof (uword));
6492
6493       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6494       for (j = 0; j <= count; j++)
6495         {
6496           do
6497             {
6498               this_random_address = random_u32 (&random_seed);
6499               this_random_address =
6500                 clib_host_to_net_u32 (this_random_address);
6501             }
6502           while (hash_get (random_hash, this_random_address));
6503           vec_add1 (random_vector, this_random_address);
6504           hash_set (random_hash, this_random_address, 1);
6505         }
6506       hash_free (random_hash);
6507       v4_dst_address.as_u32 = random_vector[0];
6508     }
6509
6510   if (count > 1)
6511     {
6512       /* Turn on async mode */
6513       vam->async_mode = 1;
6514       vam->async_errors = 0;
6515       before = vat_time_now (vam);
6516     }
6517
6518   for (j = 0; j < count; j++)
6519     {
6520       /* Construct the API message */
6521       M2 (IP_ADD_DEL_ROUTE, mp,
6522           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6523
6524       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6525       mp->table_id = ntohl (vrf_id);
6526       mp->create_vrf_if_needed = create_vrf_if_needed;
6527
6528       mp->is_add = is_add;
6529       mp->is_drop = is_drop;
6530       mp->is_unreach = is_unreach;
6531       mp->is_prohibit = is_prohibit;
6532       mp->is_ipv6 = is_ipv6;
6533       mp->is_local = is_local;
6534       mp->is_classify = is_classify;
6535       mp->is_multipath = is_multipath;
6536       mp->is_resolve_host = resolve_host;
6537       mp->is_resolve_attached = resolve_attached;
6538       mp->not_last = not_last;
6539       mp->next_hop_weight = next_hop_weight;
6540       mp->dst_address_length = dst_address_length;
6541       mp->next_hop_table_id = ntohl (next_hop_table_id);
6542       mp->classify_table_index = ntohl (classify_table_index);
6543       mp->next_hop_via_label = ntohl (next_hop_via_label);
6544       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6545       if (0 != mp->next_hop_n_out_labels)
6546         {
6547           memcpy (mp->next_hop_out_label_stack,
6548                   next_hop_out_label_stack,
6549                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6550           vec_free (next_hop_out_label_stack);
6551         }
6552
6553       if (is_ipv6)
6554         {
6555           clib_memcpy (mp->dst_address, &v6_dst_address,
6556                        sizeof (v6_dst_address));
6557           if (next_hop_set)
6558             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6559                          sizeof (v6_next_hop_address));
6560           increment_v6_address (&v6_dst_address);
6561         }
6562       else
6563         {
6564           clib_memcpy (mp->dst_address, &v4_dst_address,
6565                        sizeof (v4_dst_address));
6566           if (next_hop_set)
6567             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6568                          sizeof (v4_next_hop_address));
6569           if (random_add_del)
6570             v4_dst_address.as_u32 = random_vector[j + 1];
6571           else
6572             increment_v4_address (&v4_dst_address);
6573         }
6574       /* send it... */
6575       S (mp);
6576       /* If we receive SIGTERM, stop now... */
6577       if (vam->do_exit)
6578         break;
6579     }
6580
6581   /* When testing multiple add/del ops, use a control-ping to sync */
6582   if (count > 1)
6583     {
6584       vl_api_control_ping_t *mp_ping;
6585       f64 after;
6586       f64 timeout;
6587
6588       /* Shut off async mode */
6589       vam->async_mode = 0;
6590
6591       M (CONTROL_PING, mp_ping);
6592       S (mp_ping);
6593
6594       timeout = vat_time_now (vam) + 1.0;
6595       while (vat_time_now (vam) < timeout)
6596         if (vam->result_ready == 1)
6597           goto out;
6598       vam->retval = -99;
6599
6600     out:
6601       if (vam->retval == -99)
6602         errmsg ("timeout");
6603
6604       if (vam->async_errors > 0)
6605         {
6606           errmsg ("%d asynchronous errors", vam->async_errors);
6607           vam->retval = -98;
6608         }
6609       vam->async_errors = 0;
6610       after = vat_time_now (vam);
6611
6612       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6613       if (j > 0)
6614         count = j;
6615
6616       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6617              count, after - before, count / (after - before));
6618     }
6619   else
6620     {
6621       int ret;
6622
6623       /* Wait for a reply... */
6624       W (ret);
6625       return ret;
6626     }
6627
6628   /* Return the good/bad news */
6629   return (vam->retval);
6630 }
6631
6632 static int
6633 api_ip_mroute_add_del (vat_main_t * vam)
6634 {
6635   unformat_input_t *i = vam->input;
6636   vl_api_ip_mroute_add_del_t *mp;
6637   u32 sw_if_index = ~0, vrf_id = 0;
6638   u8 is_ipv6 = 0;
6639   u8 is_local = 0;
6640   u8 create_vrf_if_needed = 0;
6641   u8 is_add = 1;
6642   u8 address_set = 0;
6643   u32 grp_address_length = 0;
6644   ip4_address_t v4_grp_address, v4_src_address;
6645   ip6_address_t v6_grp_address, v6_src_address;
6646   mfib_itf_flags_t iflags = 0;
6647   mfib_entry_flags_t eflags = 0;
6648   int ret;
6649
6650   /* Parse args required to build the message */
6651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6652     {
6653       if (unformat (i, "sw_if_index %d", &sw_if_index))
6654         ;
6655       else if (unformat (i, "%U %U",
6656                          unformat_ip4_address, &v4_src_address,
6657                          unformat_ip4_address, &v4_grp_address))
6658         {
6659           grp_address_length = 64;
6660           address_set = 1;
6661           is_ipv6 = 0;
6662         }
6663       else if (unformat (i, "%U %U",
6664                          unformat_ip6_address, &v6_src_address,
6665                          unformat_ip6_address, &v6_grp_address))
6666         {
6667           grp_address_length = 256;
6668           address_set = 1;
6669           is_ipv6 = 1;
6670         }
6671       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6672         {
6673           memset (&v4_src_address, 0, sizeof (v4_src_address));
6674           grp_address_length = 32;
6675           address_set = 1;
6676           is_ipv6 = 0;
6677         }
6678       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6679         {
6680           memset (&v6_src_address, 0, sizeof (v6_src_address));
6681           grp_address_length = 128;
6682           address_set = 1;
6683           is_ipv6 = 1;
6684         }
6685       else if (unformat (i, "/%d", &grp_address_length))
6686         ;
6687       else if (unformat (i, "local"))
6688         {
6689           is_local = 1;
6690         }
6691       else if (unformat (i, "del"))
6692         is_add = 0;
6693       else if (unformat (i, "add"))
6694         is_add = 1;
6695       else if (unformat (i, "vrf %d", &vrf_id))
6696         ;
6697       else if (unformat (i, "create-vrf"))
6698         create_vrf_if_needed = 1;
6699       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6700         ;
6701       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6702         ;
6703       else
6704         {
6705           clib_warning ("parse error '%U'", format_unformat_error, i);
6706           return -99;
6707         }
6708     }
6709
6710   if (address_set == 0)
6711     {
6712       errmsg ("missing addresses\n");
6713       return -99;
6714     }
6715
6716   /* Construct the API message */
6717   M (IP_MROUTE_ADD_DEL, mp);
6718
6719   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6720   mp->table_id = ntohl (vrf_id);
6721   mp->create_vrf_if_needed = create_vrf_if_needed;
6722
6723   mp->is_add = is_add;
6724   mp->is_ipv6 = is_ipv6;
6725   mp->is_local = is_local;
6726   mp->itf_flags = ntohl (iflags);
6727   mp->entry_flags = ntohl (eflags);
6728   mp->grp_address_length = grp_address_length;
6729   mp->grp_address_length = ntohs (mp->grp_address_length);
6730
6731   if (is_ipv6)
6732     {
6733       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6734       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6735     }
6736   else
6737     {
6738       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6739       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6740
6741     }
6742
6743   /* send it... */
6744   S (mp);
6745   /* Wait for a reply... */
6746   W (ret);
6747   return ret;
6748 }
6749
6750 static int
6751 api_mpls_route_add_del (vat_main_t * vam)
6752 {
6753   unformat_input_t *i = vam->input;
6754   vl_api_mpls_route_add_del_t *mp;
6755   u32 sw_if_index = ~0, table_id = 0;
6756   u8 create_table_if_needed = 0;
6757   u8 is_add = 1;
6758   u32 next_hop_weight = 1;
6759   u8 is_multipath = 0;
6760   u32 next_hop_table_id = 0;
6761   u8 next_hop_set = 0;
6762   ip4_address_t v4_next_hop_address = {
6763     .as_u32 = 0,
6764   };
6765   ip6_address_t v6_next_hop_address = { {0} };
6766   int count = 1;
6767   int j;
6768   f64 before = 0;
6769   u32 classify_table_index = ~0;
6770   u8 is_classify = 0;
6771   u8 resolve_host = 0, resolve_attached = 0;
6772   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6773   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6774   mpls_label_t *next_hop_out_label_stack = NULL;
6775   mpls_label_t local_label = MPLS_LABEL_INVALID;
6776   u8 is_eos = 0;
6777   u8 next_hop_proto_is_ip4 = 1;
6778
6779   /* Parse args required to build the message */
6780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6781     {
6782       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6783         ;
6784       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6785         ;
6786       else if (unformat (i, "%d", &local_label))
6787         ;
6788       else if (unformat (i, "eos"))
6789         is_eos = 1;
6790       else if (unformat (i, "non-eos"))
6791         is_eos = 0;
6792       else if (unformat (i, "via %U", unformat_ip4_address,
6793                          &v4_next_hop_address))
6794         {
6795           next_hop_set = 1;
6796           next_hop_proto_is_ip4 = 1;
6797         }
6798       else if (unformat (i, "via %U", unformat_ip6_address,
6799                          &v6_next_hop_address))
6800         {
6801           next_hop_set = 1;
6802           next_hop_proto_is_ip4 = 0;
6803         }
6804       else if (unformat (i, "weight %d", &next_hop_weight))
6805         ;
6806       else if (unformat (i, "create-table"))
6807         create_table_if_needed = 1;
6808       else if (unformat (i, "classify %d", &classify_table_index))
6809         {
6810           is_classify = 1;
6811         }
6812       else if (unformat (i, "del"))
6813         is_add = 0;
6814       else if (unformat (i, "add"))
6815         is_add = 1;
6816       else if (unformat (i, "resolve-via-host"))
6817         resolve_host = 1;
6818       else if (unformat (i, "resolve-via-attached"))
6819         resolve_attached = 1;
6820       else if (unformat (i, "multipath"))
6821         is_multipath = 1;
6822       else if (unformat (i, "count %d", &count))
6823         ;
6824       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6825         {
6826           next_hop_set = 1;
6827           next_hop_proto_is_ip4 = 1;
6828         }
6829       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6830         {
6831           next_hop_set = 1;
6832           next_hop_proto_is_ip4 = 0;
6833         }
6834       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6835         ;
6836       else if (unformat (i, "via-label %d", &next_hop_via_label))
6837         ;
6838       else if (unformat (i, "out-label %d", &next_hop_out_label))
6839         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6840       else
6841         {
6842           clib_warning ("parse error '%U'", format_unformat_error, i);
6843           return -99;
6844         }
6845     }
6846
6847   if (!next_hop_set && !is_classify)
6848     {
6849       errmsg ("next hop / classify not set");
6850       return -99;
6851     }
6852
6853   if (MPLS_LABEL_INVALID == local_label)
6854     {
6855       errmsg ("missing label");
6856       return -99;
6857     }
6858
6859   if (count > 1)
6860     {
6861       /* Turn on async mode */
6862       vam->async_mode = 1;
6863       vam->async_errors = 0;
6864       before = vat_time_now (vam);
6865     }
6866
6867   for (j = 0; j < count; j++)
6868     {
6869       /* Construct the API message */
6870       M2 (MPLS_ROUTE_ADD_DEL, mp,
6871           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6872
6873       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6874       mp->mr_table_id = ntohl (table_id);
6875       mp->mr_create_table_if_needed = create_table_if_needed;
6876
6877       mp->mr_is_add = is_add;
6878       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6879       mp->mr_is_classify = is_classify;
6880       mp->mr_is_multipath = is_multipath;
6881       mp->mr_is_resolve_host = resolve_host;
6882       mp->mr_is_resolve_attached = resolve_attached;
6883       mp->mr_next_hop_weight = next_hop_weight;
6884       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6885       mp->mr_classify_table_index = ntohl (classify_table_index);
6886       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6887       mp->mr_label = ntohl (local_label);
6888       mp->mr_eos = is_eos;
6889
6890       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6891       if (0 != mp->mr_next_hop_n_out_labels)
6892         {
6893           memcpy (mp->mr_next_hop_out_label_stack,
6894                   next_hop_out_label_stack,
6895                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6896           vec_free (next_hop_out_label_stack);
6897         }
6898
6899       if (next_hop_set)
6900         {
6901           if (next_hop_proto_is_ip4)
6902             {
6903               clib_memcpy (mp->mr_next_hop,
6904                            &v4_next_hop_address,
6905                            sizeof (v4_next_hop_address));
6906             }
6907           else
6908             {
6909               clib_memcpy (mp->mr_next_hop,
6910                            &v6_next_hop_address,
6911                            sizeof (v6_next_hop_address));
6912             }
6913         }
6914       local_label++;
6915
6916       /* send it... */
6917       S (mp);
6918       /* If we receive SIGTERM, stop now... */
6919       if (vam->do_exit)
6920         break;
6921     }
6922
6923   /* When testing multiple add/del ops, use a control-ping to sync */
6924   if (count > 1)
6925     {
6926       vl_api_control_ping_t *mp_ping;
6927       f64 after;
6928       f64 timeout;
6929
6930       /* Shut off async mode */
6931       vam->async_mode = 0;
6932
6933       M (CONTROL_PING, mp_ping);
6934       S (mp_ping);
6935
6936       timeout = vat_time_now (vam) + 1.0;
6937       while (vat_time_now (vam) < timeout)
6938         if (vam->result_ready == 1)
6939           goto out;
6940       vam->retval = -99;
6941
6942     out:
6943       if (vam->retval == -99)
6944         errmsg ("timeout");
6945
6946       if (vam->async_errors > 0)
6947         {
6948           errmsg ("%d asynchronous errors", vam->async_errors);
6949           vam->retval = -98;
6950         }
6951       vam->async_errors = 0;
6952       after = vat_time_now (vam);
6953
6954       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6955       if (j > 0)
6956         count = j;
6957
6958       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6959              count, after - before, count / (after - before));
6960     }
6961   else
6962     {
6963       int ret;
6964
6965       /* Wait for a reply... */
6966       W (ret);
6967       return ret;
6968     }
6969
6970   /* Return the good/bad news */
6971   return (vam->retval);
6972 }
6973
6974 static int
6975 api_mpls_ip_bind_unbind (vat_main_t * vam)
6976 {
6977   unformat_input_t *i = vam->input;
6978   vl_api_mpls_ip_bind_unbind_t *mp;
6979   u32 ip_table_id = 0;
6980   u8 create_table_if_needed = 0;
6981   u8 is_bind = 1;
6982   u8 is_ip4 = 1;
6983   ip4_address_t v4_address;
6984   ip6_address_t v6_address;
6985   u32 address_length;
6986   u8 address_set = 0;
6987   mpls_label_t local_label = MPLS_LABEL_INVALID;
6988   int ret;
6989
6990   /* Parse args required to build the message */
6991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6992     {
6993       if (unformat (i, "%U/%d", unformat_ip4_address,
6994                     &v4_address, &address_length))
6995         {
6996           is_ip4 = 1;
6997           address_set = 1;
6998         }
6999       else if (unformat (i, "%U/%d", unformat_ip6_address,
7000                          &v6_address, &address_length))
7001         {
7002           is_ip4 = 0;
7003           address_set = 1;
7004         }
7005       else if (unformat (i, "%d", &local_label))
7006         ;
7007       else if (unformat (i, "create-table"))
7008         create_table_if_needed = 1;
7009       else if (unformat (i, "table-id %d", &ip_table_id))
7010         ;
7011       else if (unformat (i, "unbind"))
7012         is_bind = 0;
7013       else if (unformat (i, "bind"))
7014         is_bind = 1;
7015       else
7016         {
7017           clib_warning ("parse error '%U'", format_unformat_error, i);
7018           return -99;
7019         }
7020     }
7021
7022   if (!address_set)
7023     {
7024       errmsg ("IP addres not set");
7025       return -99;
7026     }
7027
7028   if (MPLS_LABEL_INVALID == local_label)
7029     {
7030       errmsg ("missing label");
7031       return -99;
7032     }
7033
7034   /* Construct the API message */
7035   M (MPLS_IP_BIND_UNBIND, mp);
7036
7037   mp->mb_create_table_if_needed = create_table_if_needed;
7038   mp->mb_is_bind = is_bind;
7039   mp->mb_is_ip4 = is_ip4;
7040   mp->mb_ip_table_id = ntohl (ip_table_id);
7041   mp->mb_mpls_table_id = 0;
7042   mp->mb_label = ntohl (local_label);
7043   mp->mb_address_length = address_length;
7044
7045   if (is_ip4)
7046     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7047   else
7048     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7049
7050   /* send it... */
7051   S (mp);
7052
7053   /* Wait for a reply... */
7054   W (ret);
7055   return ret;
7056 }
7057
7058 static int
7059 api_proxy_arp_add_del (vat_main_t * vam)
7060 {
7061   unformat_input_t *i = vam->input;
7062   vl_api_proxy_arp_add_del_t *mp;
7063   u32 vrf_id = 0;
7064   u8 is_add = 1;
7065   ip4_address_t lo, hi;
7066   u8 range_set = 0;
7067   int ret;
7068
7069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7070     {
7071       if (unformat (i, "vrf %d", &vrf_id))
7072         ;
7073       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7074                          unformat_ip4_address, &hi))
7075         range_set = 1;
7076       else if (unformat (i, "del"))
7077         is_add = 0;
7078       else
7079         {
7080           clib_warning ("parse error '%U'", format_unformat_error, i);
7081           return -99;
7082         }
7083     }
7084
7085   if (range_set == 0)
7086     {
7087       errmsg ("address range not set");
7088       return -99;
7089     }
7090
7091   M (PROXY_ARP_ADD_DEL, mp);
7092
7093   mp->vrf_id = ntohl (vrf_id);
7094   mp->is_add = is_add;
7095   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7096   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7097
7098   S (mp);
7099   W (ret);
7100   return ret;
7101 }
7102
7103 static int
7104 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7105 {
7106   unformat_input_t *i = vam->input;
7107   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7108   u32 sw_if_index;
7109   u8 enable = 1;
7110   u8 sw_if_index_set = 0;
7111   int ret;
7112
7113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7114     {
7115       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7116         sw_if_index_set = 1;
7117       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7118         sw_if_index_set = 1;
7119       else if (unformat (i, "enable"))
7120         enable = 1;
7121       else if (unformat (i, "disable"))
7122         enable = 0;
7123       else
7124         {
7125           clib_warning ("parse error '%U'", format_unformat_error, i);
7126           return -99;
7127         }
7128     }
7129
7130   if (sw_if_index_set == 0)
7131     {
7132       errmsg ("missing interface name or sw_if_index");
7133       return -99;
7134     }
7135
7136   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7137
7138   mp->sw_if_index = ntohl (sw_if_index);
7139   mp->enable_disable = enable;
7140
7141   S (mp);
7142   W (ret);
7143   return ret;
7144 }
7145
7146 static int
7147 api_mpls_tunnel_add_del (vat_main_t * vam)
7148 {
7149   unformat_input_t *i = vam->input;
7150   vl_api_mpls_tunnel_add_del_t *mp;
7151
7152   u8 is_add = 1;
7153   u8 l2_only = 0;
7154   u32 sw_if_index = ~0;
7155   u32 next_hop_sw_if_index = ~0;
7156   u32 next_hop_proto_is_ip4 = 1;
7157
7158   u32 next_hop_table_id = 0;
7159   ip4_address_t v4_next_hop_address = {
7160     .as_u32 = 0,
7161   };
7162   ip6_address_t v6_next_hop_address = { {0} };
7163   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7164   int ret;
7165
7166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7167     {
7168       if (unformat (i, "add"))
7169         is_add = 1;
7170       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7171         is_add = 0;
7172       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7173         ;
7174       else if (unformat (i, "via %U",
7175                          unformat_ip4_address, &v4_next_hop_address))
7176         {
7177           next_hop_proto_is_ip4 = 1;
7178         }
7179       else if (unformat (i, "via %U",
7180                          unformat_ip6_address, &v6_next_hop_address))
7181         {
7182           next_hop_proto_is_ip4 = 0;
7183         }
7184       else if (unformat (i, "l2-only"))
7185         l2_only = 1;
7186       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7187         ;
7188       else if (unformat (i, "out-label %d", &next_hop_out_label))
7189         vec_add1 (labels, ntohl (next_hop_out_label));
7190       else
7191         {
7192           clib_warning ("parse error '%U'", format_unformat_error, i);
7193           return -99;
7194         }
7195     }
7196
7197   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7198
7199   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7200   mp->mt_sw_if_index = ntohl (sw_if_index);
7201   mp->mt_is_add = is_add;
7202   mp->mt_l2_only = l2_only;
7203   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7204   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7205
7206   mp->mt_next_hop_n_out_labels = vec_len (labels);
7207
7208   if (0 != mp->mt_next_hop_n_out_labels)
7209     {
7210       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7211                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7212       vec_free (labels);
7213     }
7214
7215   if (next_hop_proto_is_ip4)
7216     {
7217       clib_memcpy (mp->mt_next_hop,
7218                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7219     }
7220   else
7221     {
7222       clib_memcpy (mp->mt_next_hop,
7223                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7224     }
7225
7226   S (mp);
7227   W (ret);
7228   return ret;
7229 }
7230
7231 static int
7232 api_sw_interface_set_unnumbered (vat_main_t * vam)
7233 {
7234   unformat_input_t *i = vam->input;
7235   vl_api_sw_interface_set_unnumbered_t *mp;
7236   u32 sw_if_index;
7237   u32 unnum_sw_index = ~0;
7238   u8 is_add = 1;
7239   u8 sw_if_index_set = 0;
7240   int ret;
7241
7242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7243     {
7244       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7245         sw_if_index_set = 1;
7246       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7247         sw_if_index_set = 1;
7248       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7249         ;
7250       else if (unformat (i, "del"))
7251         is_add = 0;
7252       else
7253         {
7254           clib_warning ("parse error '%U'", format_unformat_error, i);
7255           return -99;
7256         }
7257     }
7258
7259   if (sw_if_index_set == 0)
7260     {
7261       errmsg ("missing interface name or sw_if_index");
7262       return -99;
7263     }
7264
7265   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7266
7267   mp->sw_if_index = ntohl (sw_if_index);
7268   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7269   mp->is_add = is_add;
7270
7271   S (mp);
7272   W (ret);
7273   return ret;
7274 }
7275
7276 static int
7277 api_ip_neighbor_add_del (vat_main_t * vam)
7278 {
7279   unformat_input_t *i = vam->input;
7280   vl_api_ip_neighbor_add_del_t *mp;
7281   u32 sw_if_index;
7282   u8 sw_if_index_set = 0;
7283   u32 vrf_id = 0;
7284   u8 is_add = 1;
7285   u8 is_static = 0;
7286   u8 mac_address[6];
7287   u8 mac_set = 0;
7288   u8 v4_address_set = 0;
7289   u8 v6_address_set = 0;
7290   ip4_address_t v4address;
7291   ip6_address_t v6address;
7292   int ret;
7293
7294   memset (mac_address, 0, sizeof (mac_address));
7295
7296   /* Parse args required to build the message */
7297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7298     {
7299       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7300         {
7301           mac_set = 1;
7302         }
7303       else if (unformat (i, "del"))
7304         is_add = 0;
7305       else
7306         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7307         sw_if_index_set = 1;
7308       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7309         sw_if_index_set = 1;
7310       else if (unformat (i, "is_static"))
7311         is_static = 1;
7312       else if (unformat (i, "vrf %d", &vrf_id))
7313         ;
7314       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7315         v4_address_set = 1;
7316       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7317         v6_address_set = 1;
7318       else
7319         {
7320           clib_warning ("parse error '%U'", format_unformat_error, i);
7321           return -99;
7322         }
7323     }
7324
7325   if (sw_if_index_set == 0)
7326     {
7327       errmsg ("missing interface name or sw_if_index");
7328       return -99;
7329     }
7330   if (v4_address_set && v6_address_set)
7331     {
7332       errmsg ("both v4 and v6 addresses set");
7333       return -99;
7334     }
7335   if (!v4_address_set && !v6_address_set)
7336     {
7337       errmsg ("no address set");
7338       return -99;
7339     }
7340
7341   /* Construct the API message */
7342   M (IP_NEIGHBOR_ADD_DEL, mp);
7343
7344   mp->sw_if_index = ntohl (sw_if_index);
7345   mp->is_add = is_add;
7346   mp->vrf_id = ntohl (vrf_id);
7347   mp->is_static = is_static;
7348   if (mac_set)
7349     clib_memcpy (mp->mac_address, mac_address, 6);
7350   if (v6_address_set)
7351     {
7352       mp->is_ipv6 = 1;
7353       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7354     }
7355   else
7356     {
7357       /* mp->is_ipv6 = 0; via memset in M macro above */
7358       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7359     }
7360
7361   /* send it... */
7362   S (mp);
7363
7364   /* Wait for a reply, return good/bad news  */
7365   W (ret);
7366   return ret;
7367 }
7368
7369 static int
7370 api_reset_vrf (vat_main_t * vam)
7371 {
7372   unformat_input_t *i = vam->input;
7373   vl_api_reset_vrf_t *mp;
7374   u32 vrf_id = 0;
7375   u8 is_ipv6 = 0;
7376   u8 vrf_id_set = 0;
7377   int ret;
7378
7379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7380     {
7381       if (unformat (i, "vrf %d", &vrf_id))
7382         vrf_id_set = 1;
7383       else if (unformat (i, "ipv6"))
7384         is_ipv6 = 1;
7385       else
7386         {
7387           clib_warning ("parse error '%U'", format_unformat_error, i);
7388           return -99;
7389         }
7390     }
7391
7392   if (vrf_id_set == 0)
7393     {
7394       errmsg ("missing vrf id");
7395       return -99;
7396     }
7397
7398   M (RESET_VRF, mp);
7399
7400   mp->vrf_id = ntohl (vrf_id);
7401   mp->is_ipv6 = is_ipv6;
7402
7403   S (mp);
7404   W (ret);
7405   return ret;
7406 }
7407
7408 static int
7409 api_create_vlan_subif (vat_main_t * vam)
7410 {
7411   unformat_input_t *i = vam->input;
7412   vl_api_create_vlan_subif_t *mp;
7413   u32 sw_if_index;
7414   u8 sw_if_index_set = 0;
7415   u32 vlan_id;
7416   u8 vlan_id_set = 0;
7417   int ret;
7418
7419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7420     {
7421       if (unformat (i, "sw_if_index %d", &sw_if_index))
7422         sw_if_index_set = 1;
7423       else
7424         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7425         sw_if_index_set = 1;
7426       else if (unformat (i, "vlan %d", &vlan_id))
7427         vlan_id_set = 1;
7428       else
7429         {
7430           clib_warning ("parse error '%U'", format_unformat_error, i);
7431           return -99;
7432         }
7433     }
7434
7435   if (sw_if_index_set == 0)
7436     {
7437       errmsg ("missing interface name or sw_if_index");
7438       return -99;
7439     }
7440
7441   if (vlan_id_set == 0)
7442     {
7443       errmsg ("missing vlan_id");
7444       return -99;
7445     }
7446   M (CREATE_VLAN_SUBIF, mp);
7447
7448   mp->sw_if_index = ntohl (sw_if_index);
7449   mp->vlan_id = ntohl (vlan_id);
7450
7451   S (mp);
7452   W (ret);
7453   return ret;
7454 }
7455
7456 #define foreach_create_subif_bit                \
7457 _(no_tags)                                      \
7458 _(one_tag)                                      \
7459 _(two_tags)                                     \
7460 _(dot1ad)                                       \
7461 _(exact_match)                                  \
7462 _(default_sub)                                  \
7463 _(outer_vlan_id_any)                            \
7464 _(inner_vlan_id_any)
7465
7466 static int
7467 api_create_subif (vat_main_t * vam)
7468 {
7469   unformat_input_t *i = vam->input;
7470   vl_api_create_subif_t *mp;
7471   u32 sw_if_index;
7472   u8 sw_if_index_set = 0;
7473   u32 sub_id;
7474   u8 sub_id_set = 0;
7475   u32 no_tags = 0;
7476   u32 one_tag = 0;
7477   u32 two_tags = 0;
7478   u32 dot1ad = 0;
7479   u32 exact_match = 0;
7480   u32 default_sub = 0;
7481   u32 outer_vlan_id_any = 0;
7482   u32 inner_vlan_id_any = 0;
7483   u32 tmp;
7484   u16 outer_vlan_id = 0;
7485   u16 inner_vlan_id = 0;
7486   int ret;
7487
7488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7489     {
7490       if (unformat (i, "sw_if_index %d", &sw_if_index))
7491         sw_if_index_set = 1;
7492       else
7493         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7494         sw_if_index_set = 1;
7495       else if (unformat (i, "sub_id %d", &sub_id))
7496         sub_id_set = 1;
7497       else if (unformat (i, "outer_vlan_id %d", &tmp))
7498         outer_vlan_id = tmp;
7499       else if (unformat (i, "inner_vlan_id %d", &tmp))
7500         inner_vlan_id = tmp;
7501
7502 #define _(a) else if (unformat (i, #a)) a = 1 ;
7503       foreach_create_subif_bit
7504 #undef _
7505         else
7506         {
7507           clib_warning ("parse error '%U'", format_unformat_error, i);
7508           return -99;
7509         }
7510     }
7511
7512   if (sw_if_index_set == 0)
7513     {
7514       errmsg ("missing interface name or sw_if_index");
7515       return -99;
7516     }
7517
7518   if (sub_id_set == 0)
7519     {
7520       errmsg ("missing sub_id");
7521       return -99;
7522     }
7523   M (CREATE_SUBIF, mp);
7524
7525   mp->sw_if_index = ntohl (sw_if_index);
7526   mp->sub_id = ntohl (sub_id);
7527
7528 #define _(a) mp->a = a;
7529   foreach_create_subif_bit;
7530 #undef _
7531
7532   mp->outer_vlan_id = ntohs (outer_vlan_id);
7533   mp->inner_vlan_id = ntohs (inner_vlan_id);
7534
7535   S (mp);
7536   W (ret);
7537   return ret;
7538 }
7539
7540 static int
7541 api_oam_add_del (vat_main_t * vam)
7542 {
7543   unformat_input_t *i = vam->input;
7544   vl_api_oam_add_del_t *mp;
7545   u32 vrf_id = 0;
7546   u8 is_add = 1;
7547   ip4_address_t src, dst;
7548   u8 src_set = 0;
7549   u8 dst_set = 0;
7550   int ret;
7551
7552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7553     {
7554       if (unformat (i, "vrf %d", &vrf_id))
7555         ;
7556       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7557         src_set = 1;
7558       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7559         dst_set = 1;
7560       else if (unformat (i, "del"))
7561         is_add = 0;
7562       else
7563         {
7564           clib_warning ("parse error '%U'", format_unformat_error, i);
7565           return -99;
7566         }
7567     }
7568
7569   if (src_set == 0)
7570     {
7571       errmsg ("missing src addr");
7572       return -99;
7573     }
7574
7575   if (dst_set == 0)
7576     {
7577       errmsg ("missing dst addr");
7578       return -99;
7579     }
7580
7581   M (OAM_ADD_DEL, mp);
7582
7583   mp->vrf_id = ntohl (vrf_id);
7584   mp->is_add = is_add;
7585   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7586   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7587
7588   S (mp);
7589   W (ret);
7590   return ret;
7591 }
7592
7593 static int
7594 api_reset_fib (vat_main_t * vam)
7595 {
7596   unformat_input_t *i = vam->input;
7597   vl_api_reset_fib_t *mp;
7598   u32 vrf_id = 0;
7599   u8 is_ipv6 = 0;
7600   u8 vrf_id_set = 0;
7601
7602   int ret;
7603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7604     {
7605       if (unformat (i, "vrf %d", &vrf_id))
7606         vrf_id_set = 1;
7607       else if (unformat (i, "ipv6"))
7608         is_ipv6 = 1;
7609       else
7610         {
7611           clib_warning ("parse error '%U'", format_unformat_error, i);
7612           return -99;
7613         }
7614     }
7615
7616   if (vrf_id_set == 0)
7617     {
7618       errmsg ("missing vrf id");
7619       return -99;
7620     }
7621
7622   M (RESET_FIB, mp);
7623
7624   mp->vrf_id = ntohl (vrf_id);
7625   mp->is_ipv6 = is_ipv6;
7626
7627   S (mp);
7628   W (ret);
7629   return ret;
7630 }
7631
7632 static int
7633 api_dhcp_proxy_config (vat_main_t * vam)
7634 {
7635   unformat_input_t *i = vam->input;
7636   vl_api_dhcp_proxy_config_t *mp;
7637   u32 rx_vrf_id = 0;
7638   u32 server_vrf_id = 0;
7639   u8 is_add = 1;
7640   u8 v4_address_set = 0;
7641   u8 v6_address_set = 0;
7642   ip4_address_t v4address;
7643   ip6_address_t v6address;
7644   u8 v4_src_address_set = 0;
7645   u8 v6_src_address_set = 0;
7646   ip4_address_t v4srcaddress;
7647   ip6_address_t v6srcaddress;
7648   int ret;
7649
7650   /* Parse args required to build the message */
7651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7652     {
7653       if (unformat (i, "del"))
7654         is_add = 0;
7655       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7656         ;
7657       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7658         ;
7659       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7660         v4_address_set = 1;
7661       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7662         v6_address_set = 1;
7663       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7664         v4_src_address_set = 1;
7665       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7666         v6_src_address_set = 1;
7667       else
7668         break;
7669     }
7670
7671   if (v4_address_set && v6_address_set)
7672     {
7673       errmsg ("both v4 and v6 server addresses set");
7674       return -99;
7675     }
7676   if (!v4_address_set && !v6_address_set)
7677     {
7678       errmsg ("no server addresses set");
7679       return -99;
7680     }
7681
7682   if (v4_src_address_set && v6_src_address_set)
7683     {
7684       errmsg ("both v4 and v6  src addresses set");
7685       return -99;
7686     }
7687   if (!v4_src_address_set && !v6_src_address_set)
7688     {
7689       errmsg ("no src addresses set");
7690       return -99;
7691     }
7692
7693   if (!(v4_src_address_set && v4_address_set) &&
7694       !(v6_src_address_set && v6_address_set))
7695     {
7696       errmsg ("no matching server and src addresses set");
7697       return -99;
7698     }
7699
7700   /* Construct the API message */
7701   M (DHCP_PROXY_CONFIG, mp);
7702
7703   mp->is_add = is_add;
7704   mp->rx_vrf_id = ntohl (rx_vrf_id);
7705   mp->server_vrf_id = ntohl (server_vrf_id);
7706   if (v6_address_set)
7707     {
7708       mp->is_ipv6 = 1;
7709       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7710       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7711     }
7712   else
7713     {
7714       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7715       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7716     }
7717
7718   /* send it... */
7719   S (mp);
7720
7721   /* Wait for a reply, return good/bad news  */
7722   W (ret);
7723   return ret;
7724 }
7725
7726 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7727 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7728
7729 static void
7730 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7731 {
7732   vat_main_t *vam = &vat_main;
7733
7734   if (mp->is_ipv6)
7735     print (vam->ofp,
7736            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7737            ntohl (mp->rx_vrf_id),
7738            ntohl (mp->server_vrf_id),
7739            format_ip6_address, mp->dhcp_server,
7740            format_ip6_address, mp->dhcp_src_address,
7741            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7742   else
7743     print (vam->ofp,
7744            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7745            ntohl (mp->rx_vrf_id),
7746            ntohl (mp->server_vrf_id),
7747            format_ip4_address, mp->dhcp_server,
7748            format_ip4_address, mp->dhcp_src_address,
7749            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7750 }
7751
7752 static void vl_api_dhcp_proxy_details_t_handler_json
7753   (vl_api_dhcp_proxy_details_t * mp)
7754 {
7755   vat_main_t *vam = &vat_main;
7756   vat_json_node_t *node = NULL;
7757   struct in_addr ip4;
7758   struct in6_addr ip6;
7759
7760   if (VAT_JSON_ARRAY != vam->json_tree.type)
7761     {
7762       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7763       vat_json_init_array (&vam->json_tree);
7764     }
7765   node = vat_json_array_add (&vam->json_tree);
7766
7767   vat_json_init_object (node);
7768   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7769   vat_json_object_add_uint (node, "server-table-id",
7770                             ntohl (mp->server_vrf_id));
7771   if (mp->is_ipv6)
7772     {
7773       clib_memcpy (&ip6, &mp->dhcp_server, sizeof (ip6));
7774       vat_json_object_add_ip6 (node, "server_address", ip6);
7775       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7776       vat_json_object_add_ip6 (node, "src_address", ip6);
7777     }
7778   else
7779     {
7780       clib_memcpy (&ip4, &mp->dhcp_server, sizeof (ip4));
7781       vat_json_object_add_ip4 (node, "server_address", ip4);
7782       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7783       vat_json_object_add_ip4 (node, "src_address", ip4);
7784     }
7785   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7786   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7787 }
7788
7789 static int
7790 api_dhcp_proxy_dump (vat_main_t * vam)
7791 {
7792   unformat_input_t *i = vam->input;
7793   vl_api_control_ping_t *mp_ping;
7794   vl_api_dhcp_proxy_dump_t *mp;
7795   u8 is_ipv6 = 0;
7796   int ret;
7797
7798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7799     {
7800       if (unformat (i, "ipv6"))
7801         is_ipv6 = 1;
7802       else
7803         {
7804           clib_warning ("parse error '%U'", format_unformat_error, i);
7805           return -99;
7806         }
7807     }
7808
7809   M (DHCP_PROXY_DUMP, mp);
7810
7811   mp->is_ip6 = is_ipv6;
7812   S (mp);
7813
7814   /* Use a control ping for synchronization */
7815   M (CONTROL_PING, mp_ping);
7816   S (mp_ping);
7817
7818   W (ret);
7819   return ret;
7820 }
7821
7822 static int
7823 api_dhcp_proxy_set_vss (vat_main_t * vam)
7824 {
7825   unformat_input_t *i = vam->input;
7826   vl_api_dhcp_proxy_set_vss_t *mp;
7827   u8 is_ipv6 = 0;
7828   u8 is_add = 1;
7829   u32 tbl_id;
7830   u8 tbl_id_set = 0;
7831   u32 oui;
7832   u8 oui_set = 0;
7833   u32 fib_id;
7834   u8 fib_id_set = 0;
7835   int ret;
7836
7837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7838     {
7839       if (unformat (i, "tbl_id %d", &tbl_id))
7840         tbl_id_set = 1;
7841       if (unformat (i, "fib_id %d", &fib_id))
7842         fib_id_set = 1;
7843       if (unformat (i, "oui %d", &oui))
7844         oui_set = 1;
7845       else if (unformat (i, "ipv6"))
7846         is_ipv6 = 1;
7847       else if (unformat (i, "del"))
7848         is_add = 0;
7849       else
7850         {
7851           clib_warning ("parse error '%U'", format_unformat_error, i);
7852           return -99;
7853         }
7854     }
7855
7856   if (tbl_id_set == 0)
7857     {
7858       errmsg ("missing tbl id");
7859       return -99;
7860     }
7861
7862   if (fib_id_set == 0)
7863     {
7864       errmsg ("missing fib id");
7865       return -99;
7866     }
7867   if (oui_set == 0)
7868     {
7869       errmsg ("missing oui");
7870       return -99;
7871     }
7872
7873   M (DHCP_PROXY_SET_VSS, mp);
7874   mp->tbl_id = ntohl (tbl_id);
7875   mp->fib_id = ntohl (fib_id);
7876   mp->oui = ntohl (oui);
7877   mp->is_ipv6 = is_ipv6;
7878   mp->is_add = is_add;
7879
7880   S (mp);
7881   W (ret);
7882   return ret;
7883 }
7884
7885 static int
7886 api_dhcp_client_config (vat_main_t * vam)
7887 {
7888   unformat_input_t *i = vam->input;
7889   vl_api_dhcp_client_config_t *mp;
7890   u32 sw_if_index;
7891   u8 sw_if_index_set = 0;
7892   u8 is_add = 1;
7893   u8 *hostname = 0;
7894   u8 disable_event = 0;
7895   int ret;
7896
7897   /* Parse args required to build the message */
7898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7899     {
7900       if (unformat (i, "del"))
7901         is_add = 0;
7902       else
7903         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7904         sw_if_index_set = 1;
7905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7906         sw_if_index_set = 1;
7907       else if (unformat (i, "hostname %s", &hostname))
7908         ;
7909       else if (unformat (i, "disable_event"))
7910         disable_event = 1;
7911       else
7912         break;
7913     }
7914
7915   if (sw_if_index_set == 0)
7916     {
7917       errmsg ("missing interface name or sw_if_index");
7918       return -99;
7919     }
7920
7921   if (vec_len (hostname) > 63)
7922     {
7923       errmsg ("hostname too long");
7924     }
7925   vec_add1 (hostname, 0);
7926
7927   /* Construct the API message */
7928   M (DHCP_CLIENT_CONFIG, mp);
7929
7930   mp->sw_if_index = ntohl (sw_if_index);
7931   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7932   vec_free (hostname);
7933   mp->is_add = is_add;
7934   mp->want_dhcp_event = disable_event ? 0 : 1;
7935   mp->pid = getpid ();
7936
7937   /* send it... */
7938   S (mp);
7939
7940   /* Wait for a reply, return good/bad news  */
7941   W (ret);
7942   return ret;
7943 }
7944
7945 static int
7946 api_set_ip_flow_hash (vat_main_t * vam)
7947 {
7948   unformat_input_t *i = vam->input;
7949   vl_api_set_ip_flow_hash_t *mp;
7950   u32 vrf_id = 0;
7951   u8 is_ipv6 = 0;
7952   u8 vrf_id_set = 0;
7953   u8 src = 0;
7954   u8 dst = 0;
7955   u8 sport = 0;
7956   u8 dport = 0;
7957   u8 proto = 0;
7958   u8 reverse = 0;
7959   int ret;
7960
7961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7962     {
7963       if (unformat (i, "vrf %d", &vrf_id))
7964         vrf_id_set = 1;
7965       else if (unformat (i, "ipv6"))
7966         is_ipv6 = 1;
7967       else if (unformat (i, "src"))
7968         src = 1;
7969       else if (unformat (i, "dst"))
7970         dst = 1;
7971       else if (unformat (i, "sport"))
7972         sport = 1;
7973       else if (unformat (i, "dport"))
7974         dport = 1;
7975       else if (unformat (i, "proto"))
7976         proto = 1;
7977       else if (unformat (i, "reverse"))
7978         reverse = 1;
7979
7980       else
7981         {
7982           clib_warning ("parse error '%U'", format_unformat_error, i);
7983           return -99;
7984         }
7985     }
7986
7987   if (vrf_id_set == 0)
7988     {
7989       errmsg ("missing vrf id");
7990       return -99;
7991     }
7992
7993   M (SET_IP_FLOW_HASH, mp);
7994   mp->src = src;
7995   mp->dst = dst;
7996   mp->sport = sport;
7997   mp->dport = dport;
7998   mp->proto = proto;
7999   mp->reverse = reverse;
8000   mp->vrf_id = ntohl (vrf_id);
8001   mp->is_ipv6 = is_ipv6;
8002
8003   S (mp);
8004   W (ret);
8005   return ret;
8006 }
8007
8008 static int
8009 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8010 {
8011   unformat_input_t *i = vam->input;
8012   vl_api_sw_interface_ip6_enable_disable_t *mp;
8013   u32 sw_if_index;
8014   u8 sw_if_index_set = 0;
8015   u8 enable = 0;
8016   int ret;
8017
8018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8019     {
8020       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8021         sw_if_index_set = 1;
8022       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8023         sw_if_index_set = 1;
8024       else if (unformat (i, "enable"))
8025         enable = 1;
8026       else if (unformat (i, "disable"))
8027         enable = 0;
8028       else
8029         {
8030           clib_warning ("parse error '%U'", format_unformat_error, i);
8031           return -99;
8032         }
8033     }
8034
8035   if (sw_if_index_set == 0)
8036     {
8037       errmsg ("missing interface name or sw_if_index");
8038       return -99;
8039     }
8040
8041   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8042
8043   mp->sw_if_index = ntohl (sw_if_index);
8044   mp->enable = enable;
8045
8046   S (mp);
8047   W (ret);
8048   return ret;
8049 }
8050
8051 static int
8052 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8053 {
8054   unformat_input_t *i = vam->input;
8055   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8056   u32 sw_if_index;
8057   u8 sw_if_index_set = 0;
8058   u8 v6_address_set = 0;
8059   ip6_address_t v6address;
8060   int ret;
8061
8062   /* Parse args required to build the message */
8063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8064     {
8065       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8066         sw_if_index_set = 1;
8067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8068         sw_if_index_set = 1;
8069       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8070         v6_address_set = 1;
8071       else
8072         break;
8073     }
8074
8075   if (sw_if_index_set == 0)
8076     {
8077       errmsg ("missing interface name or sw_if_index");
8078       return -99;
8079     }
8080   if (!v6_address_set)
8081     {
8082       errmsg ("no address set");
8083       return -99;
8084     }
8085
8086   /* Construct the API message */
8087   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8088
8089   mp->sw_if_index = ntohl (sw_if_index);
8090   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8091
8092   /* send it... */
8093   S (mp);
8094
8095   /* Wait for a reply, return good/bad news  */
8096   W (ret);
8097   return ret;
8098 }
8099
8100
8101 static int
8102 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8103 {
8104   unformat_input_t *i = vam->input;
8105   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8106   u32 sw_if_index;
8107   u8 sw_if_index_set = 0;
8108   u32 address_length = 0;
8109   u8 v6_address_set = 0;
8110   ip6_address_t v6address;
8111   u8 use_default = 0;
8112   u8 no_advertise = 0;
8113   u8 off_link = 0;
8114   u8 no_autoconfig = 0;
8115   u8 no_onlink = 0;
8116   u8 is_no = 0;
8117   u32 val_lifetime = 0;
8118   u32 pref_lifetime = 0;
8119   int ret;
8120
8121   /* Parse args required to build the message */
8122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8123     {
8124       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8125         sw_if_index_set = 1;
8126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8127         sw_if_index_set = 1;
8128       else if (unformat (i, "%U/%d",
8129                          unformat_ip6_address, &v6address, &address_length))
8130         v6_address_set = 1;
8131       else if (unformat (i, "val_life %d", &val_lifetime))
8132         ;
8133       else if (unformat (i, "pref_life %d", &pref_lifetime))
8134         ;
8135       else if (unformat (i, "def"))
8136         use_default = 1;
8137       else if (unformat (i, "noadv"))
8138         no_advertise = 1;
8139       else if (unformat (i, "offl"))
8140         off_link = 1;
8141       else if (unformat (i, "noauto"))
8142         no_autoconfig = 1;
8143       else if (unformat (i, "nolink"))
8144         no_onlink = 1;
8145       else if (unformat (i, "isno"))
8146         is_no = 1;
8147       else
8148         {
8149           clib_warning ("parse error '%U'", format_unformat_error, i);
8150           return -99;
8151         }
8152     }
8153
8154   if (sw_if_index_set == 0)
8155     {
8156       errmsg ("missing interface name or sw_if_index");
8157       return -99;
8158     }
8159   if (!v6_address_set)
8160     {
8161       errmsg ("no address set");
8162       return -99;
8163     }
8164
8165   /* Construct the API message */
8166   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8167
8168   mp->sw_if_index = ntohl (sw_if_index);
8169   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8170   mp->address_length = address_length;
8171   mp->use_default = use_default;
8172   mp->no_advertise = no_advertise;
8173   mp->off_link = off_link;
8174   mp->no_autoconfig = no_autoconfig;
8175   mp->no_onlink = no_onlink;
8176   mp->is_no = is_no;
8177   mp->val_lifetime = ntohl (val_lifetime);
8178   mp->pref_lifetime = ntohl (pref_lifetime);
8179
8180   /* send it... */
8181   S (mp);
8182
8183   /* Wait for a reply, return good/bad news  */
8184   W (ret);
8185   return ret;
8186 }
8187
8188 static int
8189 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8190 {
8191   unformat_input_t *i = vam->input;
8192   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8193   u32 sw_if_index;
8194   u8 sw_if_index_set = 0;
8195   u8 suppress = 0;
8196   u8 managed = 0;
8197   u8 other = 0;
8198   u8 ll_option = 0;
8199   u8 send_unicast = 0;
8200   u8 cease = 0;
8201   u8 is_no = 0;
8202   u8 default_router = 0;
8203   u32 max_interval = 0;
8204   u32 min_interval = 0;
8205   u32 lifetime = 0;
8206   u32 initial_count = 0;
8207   u32 initial_interval = 0;
8208   int ret;
8209
8210
8211   /* Parse args required to build the message */
8212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8213     {
8214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8215         sw_if_index_set = 1;
8216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8217         sw_if_index_set = 1;
8218       else if (unformat (i, "maxint %d", &max_interval))
8219         ;
8220       else if (unformat (i, "minint %d", &min_interval))
8221         ;
8222       else if (unformat (i, "life %d", &lifetime))
8223         ;
8224       else if (unformat (i, "count %d", &initial_count))
8225         ;
8226       else if (unformat (i, "interval %d", &initial_interval))
8227         ;
8228       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8229         suppress = 1;
8230       else if (unformat (i, "managed"))
8231         managed = 1;
8232       else if (unformat (i, "other"))
8233         other = 1;
8234       else if (unformat (i, "ll"))
8235         ll_option = 1;
8236       else if (unformat (i, "send"))
8237         send_unicast = 1;
8238       else if (unformat (i, "cease"))
8239         cease = 1;
8240       else if (unformat (i, "isno"))
8241         is_no = 1;
8242       else if (unformat (i, "def"))
8243         default_router = 1;
8244       else
8245         {
8246           clib_warning ("parse error '%U'", format_unformat_error, i);
8247           return -99;
8248         }
8249     }
8250
8251   if (sw_if_index_set == 0)
8252     {
8253       errmsg ("missing interface name or sw_if_index");
8254       return -99;
8255     }
8256
8257   /* Construct the API message */
8258   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8259
8260   mp->sw_if_index = ntohl (sw_if_index);
8261   mp->max_interval = ntohl (max_interval);
8262   mp->min_interval = ntohl (min_interval);
8263   mp->lifetime = ntohl (lifetime);
8264   mp->initial_count = ntohl (initial_count);
8265   mp->initial_interval = ntohl (initial_interval);
8266   mp->suppress = suppress;
8267   mp->managed = managed;
8268   mp->other = other;
8269   mp->ll_option = ll_option;
8270   mp->send_unicast = send_unicast;
8271   mp->cease = cease;
8272   mp->is_no = is_no;
8273   mp->default_router = default_router;
8274
8275   /* send it... */
8276   S (mp);
8277
8278   /* Wait for a reply, return good/bad news  */
8279   W (ret);
8280   return ret;
8281 }
8282
8283 static int
8284 api_set_arp_neighbor_limit (vat_main_t * vam)
8285 {
8286   unformat_input_t *i = vam->input;
8287   vl_api_set_arp_neighbor_limit_t *mp;
8288   u32 arp_nbr_limit;
8289   u8 limit_set = 0;
8290   u8 is_ipv6 = 0;
8291   int ret;
8292
8293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8294     {
8295       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8296         limit_set = 1;
8297       else if (unformat (i, "ipv6"))
8298         is_ipv6 = 1;
8299       else
8300         {
8301           clib_warning ("parse error '%U'", format_unformat_error, i);
8302           return -99;
8303         }
8304     }
8305
8306   if (limit_set == 0)
8307     {
8308       errmsg ("missing limit value");
8309       return -99;
8310     }
8311
8312   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8313
8314   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8315   mp->is_ipv6 = is_ipv6;
8316
8317   S (mp);
8318   W (ret);
8319   return ret;
8320 }
8321
8322 static int
8323 api_l2_patch_add_del (vat_main_t * vam)
8324 {
8325   unformat_input_t *i = vam->input;
8326   vl_api_l2_patch_add_del_t *mp;
8327   u32 rx_sw_if_index;
8328   u8 rx_sw_if_index_set = 0;
8329   u32 tx_sw_if_index;
8330   u8 tx_sw_if_index_set = 0;
8331   u8 is_add = 1;
8332   int ret;
8333
8334   /* Parse args required to build the message */
8335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8336     {
8337       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8338         rx_sw_if_index_set = 1;
8339       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8340         tx_sw_if_index_set = 1;
8341       else if (unformat (i, "rx"))
8342         {
8343           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8344             {
8345               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8346                             &rx_sw_if_index))
8347                 rx_sw_if_index_set = 1;
8348             }
8349           else
8350             break;
8351         }
8352       else if (unformat (i, "tx"))
8353         {
8354           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8355             {
8356               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8357                             &tx_sw_if_index))
8358                 tx_sw_if_index_set = 1;
8359             }
8360           else
8361             break;
8362         }
8363       else if (unformat (i, "del"))
8364         is_add = 0;
8365       else
8366         break;
8367     }
8368
8369   if (rx_sw_if_index_set == 0)
8370     {
8371       errmsg ("missing rx interface name or rx_sw_if_index");
8372       return -99;
8373     }
8374
8375   if (tx_sw_if_index_set == 0)
8376     {
8377       errmsg ("missing tx interface name or tx_sw_if_index");
8378       return -99;
8379     }
8380
8381   M (L2_PATCH_ADD_DEL, mp);
8382
8383   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8384   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8385   mp->is_add = is_add;
8386
8387   S (mp);
8388   W (ret);
8389   return ret;
8390 }
8391
8392 static int
8393 api_ioam_enable (vat_main_t * vam)
8394 {
8395   unformat_input_t *input = vam->input;
8396   vl_api_ioam_enable_t *mp;
8397   u32 id = 0;
8398   int has_trace_option = 0;
8399   int has_pot_option = 0;
8400   int has_seqno_option = 0;
8401   int has_analyse_option = 0;
8402   int ret;
8403
8404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8405     {
8406       if (unformat (input, "trace"))
8407         has_trace_option = 1;
8408       else if (unformat (input, "pot"))
8409         has_pot_option = 1;
8410       else if (unformat (input, "seqno"))
8411         has_seqno_option = 1;
8412       else if (unformat (input, "analyse"))
8413         has_analyse_option = 1;
8414       else
8415         break;
8416     }
8417   M (IOAM_ENABLE, mp);
8418   mp->id = htons (id);
8419   mp->seqno = has_seqno_option;
8420   mp->analyse = has_analyse_option;
8421   mp->pot_enable = has_pot_option;
8422   mp->trace_enable = has_trace_option;
8423
8424   S (mp);
8425   W (ret);
8426   return ret;
8427 }
8428
8429
8430 static int
8431 api_ioam_disable (vat_main_t * vam)
8432 {
8433   vl_api_ioam_disable_t *mp;
8434   int ret;
8435
8436   M (IOAM_DISABLE, mp);
8437   S (mp);
8438   W (ret);
8439   return ret;
8440 }
8441
8442 static int
8443 api_sr_tunnel_add_del (vat_main_t * vam)
8444 {
8445   unformat_input_t *i = vam->input;
8446   vl_api_sr_tunnel_add_del_t *mp;
8447   int is_del = 0;
8448   int pl_index;
8449   ip6_address_t src_address;
8450   int src_address_set = 0;
8451   ip6_address_t dst_address;
8452   u32 dst_mask_width;
8453   int dst_address_set = 0;
8454   u16 flags = 0;
8455   u32 rx_table_id = 0;
8456   u32 tx_table_id = 0;
8457   ip6_address_t *segments = 0;
8458   ip6_address_t *this_seg;
8459   ip6_address_t *tags = 0;
8460   ip6_address_t *this_tag;
8461   ip6_address_t next_address, tag;
8462   u8 *name = 0;
8463   u8 *policy_name = 0;
8464   int ret;
8465
8466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8467     {
8468       if (unformat (i, "del"))
8469         is_del = 1;
8470       else if (unformat (i, "name %s", &name))
8471         ;
8472       else if (unformat (i, "policy %s", &policy_name))
8473         ;
8474       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8475         ;
8476       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8477         ;
8478       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8479         src_address_set = 1;
8480       else if (unformat (i, "dst %U/%d",
8481                          unformat_ip6_address, &dst_address, &dst_mask_width))
8482         dst_address_set = 1;
8483       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8484         {
8485           vec_add2 (segments, this_seg, 1);
8486           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8487                        sizeof (*this_seg));
8488         }
8489       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8490         {
8491           vec_add2 (tags, this_tag, 1);
8492           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8493         }
8494       else if (unformat (i, "clean"))
8495         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8496       else if (unformat (i, "protected"))
8497         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8498       else if (unformat (i, "InPE %d", &pl_index))
8499         {
8500           if (pl_index <= 0 || pl_index > 4)
8501             {
8502             pl_index_range_error:
8503               errmsg ("pl index %d out of range", pl_index);
8504               return -99;
8505             }
8506           flags |=
8507             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8508         }
8509       else if (unformat (i, "EgPE %d", &pl_index))
8510         {
8511           if (pl_index <= 0 || pl_index > 4)
8512             goto pl_index_range_error;
8513           flags |=
8514             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8515         }
8516       else if (unformat (i, "OrgSrc %d", &pl_index))
8517         {
8518           if (pl_index <= 0 || pl_index > 4)
8519             goto pl_index_range_error;
8520           flags |=
8521             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8522         }
8523       else
8524         break;
8525     }
8526
8527   if (!src_address_set)
8528     {
8529       errmsg ("src address required");
8530       return -99;
8531     }
8532
8533   if (!dst_address_set)
8534     {
8535       errmsg ("dst address required");
8536       return -99;
8537     }
8538
8539   if (!segments)
8540     {
8541       errmsg ("at least one sr segment required");
8542       return -99;
8543     }
8544
8545   M2 (SR_TUNNEL_ADD_DEL, mp,
8546       vec_len (segments) * sizeof (ip6_address_t)
8547       + vec_len (tags) * sizeof (ip6_address_t));
8548
8549   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8550   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8551   mp->dst_mask_width = dst_mask_width;
8552   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8553   mp->n_segments = vec_len (segments);
8554   mp->n_tags = vec_len (tags);
8555   mp->is_add = is_del == 0;
8556   clib_memcpy (mp->segs_and_tags, segments,
8557                vec_len (segments) * sizeof (ip6_address_t));
8558   clib_memcpy (mp->segs_and_tags +
8559                vec_len (segments) * sizeof (ip6_address_t), tags,
8560                vec_len (tags) * sizeof (ip6_address_t));
8561
8562   mp->outer_vrf_id = ntohl (rx_table_id);
8563   mp->inner_vrf_id = ntohl (tx_table_id);
8564   memcpy (mp->name, name, vec_len (name));
8565   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8566
8567   vec_free (segments);
8568   vec_free (tags);
8569
8570   S (mp);
8571   W (ret);
8572   return ret;
8573 }
8574
8575 static int
8576 api_sr_policy_add_del (vat_main_t * vam)
8577 {
8578   unformat_input_t *input = vam->input;
8579   vl_api_sr_policy_add_del_t *mp;
8580   int is_del = 0;
8581   u8 *name = 0;
8582   u8 *tunnel_name = 0;
8583   u8 **tunnel_names = 0;
8584
8585   int name_set = 0;
8586   int tunnel_set = 0;
8587   int j = 0;
8588   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8589   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8590   int ret;
8591
8592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8593     {
8594       if (unformat (input, "del"))
8595         is_del = 1;
8596       else if (unformat (input, "name %s", &name))
8597         name_set = 1;
8598       else if (unformat (input, "tunnel %s", &tunnel_name))
8599         {
8600           if (tunnel_name)
8601             {
8602               vec_add1 (tunnel_names, tunnel_name);
8603               /* For serializer:
8604                  - length = #bytes to store in serial vector
8605                  - +1 = byte to store that length
8606                */
8607               tunnel_names_length += (vec_len (tunnel_name) + 1);
8608               tunnel_set = 1;
8609               tunnel_name = 0;
8610             }
8611         }
8612       else
8613         break;
8614     }
8615
8616   if (!name_set)
8617     {
8618       errmsg ("policy name required");
8619       return -99;
8620     }
8621
8622   if ((!tunnel_set) && (!is_del))
8623     {
8624       errmsg ("tunnel name required");
8625       return -99;
8626     }
8627
8628   M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
8629
8630
8631
8632   mp->is_add = !is_del;
8633
8634   memcpy (mp->name, name, vec_len (name));
8635   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8636   u8 *serial_orig = 0;
8637   vec_validate (serial_orig, tunnel_names_length);
8638   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8639   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8640
8641   for (j = 0; j < vec_len (tunnel_names); j++)
8642     {
8643       tun_name_len = vec_len (tunnel_names[j]);
8644       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8645       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8646       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8647       serial_orig += tun_name_len;      // Advance past the copy
8648     }
8649   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8650
8651   vec_free (tunnel_names);
8652   vec_free (tunnel_name);
8653
8654   S (mp);
8655   W (ret);
8656   return ret;
8657 }
8658
8659 static int
8660 api_sr_multicast_map_add_del (vat_main_t * vam)
8661 {
8662   unformat_input_t *input = vam->input;
8663   vl_api_sr_multicast_map_add_del_t *mp;
8664   int is_del = 0;
8665   ip6_address_t multicast_address;
8666   u8 *policy_name = 0;
8667   int multicast_address_set = 0;
8668   int ret;
8669
8670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8671     {
8672       if (unformat (input, "del"))
8673         is_del = 1;
8674       else
8675         if (unformat
8676             (input, "address %U", unformat_ip6_address, &multicast_address))
8677         multicast_address_set = 1;
8678       else if (unformat (input, "sr-policy %s", &policy_name))
8679         ;
8680       else
8681         break;
8682     }
8683
8684   if (!is_del && !policy_name)
8685     {
8686       errmsg ("sr-policy name required");
8687       return -99;
8688     }
8689
8690
8691   if (!multicast_address_set)
8692     {
8693       errmsg ("address required");
8694       return -99;
8695     }
8696
8697   M (SR_MULTICAST_MAP_ADD_DEL, mp);
8698
8699   mp->is_add = !is_del;
8700   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8701   clib_memcpy (mp->multicast_address, &multicast_address,
8702                sizeof (mp->multicast_address));
8703
8704
8705   vec_free (policy_name);
8706
8707   S (mp);
8708   W (ret);
8709   return ret;
8710 }
8711
8712
8713 #define foreach_tcp_proto_field                 \
8714 _(src_port)                                     \
8715 _(dst_port)
8716
8717 #define foreach_udp_proto_field                 \
8718 _(src_port)                                     \
8719 _(dst_port)
8720
8721 #define foreach_ip4_proto_field                 \
8722 _(src_address)                                  \
8723 _(dst_address)                                  \
8724 _(tos)                                          \
8725 _(length)                                       \
8726 _(fragment_id)                                  \
8727 _(ttl)                                          \
8728 _(protocol)                                     \
8729 _(checksum)
8730
8731 uword
8732 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8733 {
8734   u8 **maskp = va_arg (*args, u8 **);
8735   u8 *mask = 0;
8736   u8 found_something = 0;
8737   tcp_header_t *tcp;
8738
8739 #define _(a) u8 a=0;
8740   foreach_tcp_proto_field;
8741 #undef _
8742
8743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8744     {
8745       if (0);
8746 #define _(a) else if (unformat (input, #a)) a=1;
8747       foreach_tcp_proto_field
8748 #undef _
8749         else
8750         break;
8751     }
8752
8753 #define _(a) found_something += a;
8754   foreach_tcp_proto_field;
8755 #undef _
8756
8757   if (found_something == 0)
8758     return 0;
8759
8760   vec_validate (mask, sizeof (*tcp) - 1);
8761
8762   tcp = (tcp_header_t *) mask;
8763
8764 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8765   foreach_tcp_proto_field;
8766 #undef _
8767
8768   *maskp = mask;
8769   return 1;
8770 }
8771
8772 uword
8773 unformat_udp_mask (unformat_input_t * input, va_list * args)
8774 {
8775   u8 **maskp = va_arg (*args, u8 **);
8776   u8 *mask = 0;
8777   u8 found_something = 0;
8778   udp_header_t *udp;
8779
8780 #define _(a) u8 a=0;
8781   foreach_udp_proto_field;
8782 #undef _
8783
8784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8785     {
8786       if (0);
8787 #define _(a) else if (unformat (input, #a)) a=1;
8788       foreach_udp_proto_field
8789 #undef _
8790         else
8791         break;
8792     }
8793
8794 #define _(a) found_something += a;
8795   foreach_udp_proto_field;
8796 #undef _
8797
8798   if (found_something == 0)
8799     return 0;
8800
8801   vec_validate (mask, sizeof (*udp) - 1);
8802
8803   udp = (udp_header_t *) mask;
8804
8805 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8806   foreach_udp_proto_field;
8807 #undef _
8808
8809   *maskp = mask;
8810   return 1;
8811 }
8812
8813 typedef struct
8814 {
8815   u16 src_port, dst_port;
8816 } tcpudp_header_t;
8817
8818 uword
8819 unformat_l4_mask (unformat_input_t * input, va_list * args)
8820 {
8821   u8 **maskp = va_arg (*args, u8 **);
8822   u16 src_port = 0, dst_port = 0;
8823   tcpudp_header_t *tcpudp;
8824
8825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8826     {
8827       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8828         return 1;
8829       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8830         return 1;
8831       else if (unformat (input, "src_port"))
8832         src_port = 0xFFFF;
8833       else if (unformat (input, "dst_port"))
8834         dst_port = 0xFFFF;
8835       else
8836         return 0;
8837     }
8838
8839   if (!src_port && !dst_port)
8840     return 0;
8841
8842   u8 *mask = 0;
8843   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8844
8845   tcpudp = (tcpudp_header_t *) mask;
8846   tcpudp->src_port = src_port;
8847   tcpudp->dst_port = dst_port;
8848
8849   *maskp = mask;
8850
8851   return 1;
8852 }
8853
8854 uword
8855 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8856 {
8857   u8 **maskp = va_arg (*args, u8 **);
8858   u8 *mask = 0;
8859   u8 found_something = 0;
8860   ip4_header_t *ip;
8861
8862 #define _(a) u8 a=0;
8863   foreach_ip4_proto_field;
8864 #undef _
8865   u8 version = 0;
8866   u8 hdr_length = 0;
8867
8868
8869   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8870     {
8871       if (unformat (input, "version"))
8872         version = 1;
8873       else if (unformat (input, "hdr_length"))
8874         hdr_length = 1;
8875       else if (unformat (input, "src"))
8876         src_address = 1;
8877       else if (unformat (input, "dst"))
8878         dst_address = 1;
8879       else if (unformat (input, "proto"))
8880         protocol = 1;
8881
8882 #define _(a) else if (unformat (input, #a)) a=1;
8883       foreach_ip4_proto_field
8884 #undef _
8885         else
8886         break;
8887     }
8888
8889 #define _(a) found_something += a;
8890   foreach_ip4_proto_field;
8891 #undef _
8892
8893   if (found_something == 0)
8894     return 0;
8895
8896   vec_validate (mask, sizeof (*ip) - 1);
8897
8898   ip = (ip4_header_t *) mask;
8899
8900 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8901   foreach_ip4_proto_field;
8902 #undef _
8903
8904   ip->ip_version_and_header_length = 0;
8905
8906   if (version)
8907     ip->ip_version_and_header_length |= 0xF0;
8908
8909   if (hdr_length)
8910     ip->ip_version_and_header_length |= 0x0F;
8911
8912   *maskp = mask;
8913   return 1;
8914 }
8915
8916 #define foreach_ip6_proto_field                 \
8917 _(src_address)                                  \
8918 _(dst_address)                                  \
8919 _(payload_length)                               \
8920 _(hop_limit)                                    \
8921 _(protocol)
8922
8923 uword
8924 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8925 {
8926   u8 **maskp = va_arg (*args, u8 **);
8927   u8 *mask = 0;
8928   u8 found_something = 0;
8929   ip6_header_t *ip;
8930   u32 ip_version_traffic_class_and_flow_label;
8931
8932 #define _(a) u8 a=0;
8933   foreach_ip6_proto_field;
8934 #undef _
8935   u8 version = 0;
8936   u8 traffic_class = 0;
8937   u8 flow_label = 0;
8938
8939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8940     {
8941       if (unformat (input, "version"))
8942         version = 1;
8943       else if (unformat (input, "traffic-class"))
8944         traffic_class = 1;
8945       else if (unformat (input, "flow-label"))
8946         flow_label = 1;
8947       else if (unformat (input, "src"))
8948         src_address = 1;
8949       else if (unformat (input, "dst"))
8950         dst_address = 1;
8951       else if (unformat (input, "proto"))
8952         protocol = 1;
8953
8954 #define _(a) else if (unformat (input, #a)) a=1;
8955       foreach_ip6_proto_field
8956 #undef _
8957         else
8958         break;
8959     }
8960
8961 #define _(a) found_something += a;
8962   foreach_ip6_proto_field;
8963 #undef _
8964
8965   if (found_something == 0)
8966     return 0;
8967
8968   vec_validate (mask, sizeof (*ip) - 1);
8969
8970   ip = (ip6_header_t *) mask;
8971
8972 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8973   foreach_ip6_proto_field;
8974 #undef _
8975
8976   ip_version_traffic_class_and_flow_label = 0;
8977
8978   if (version)
8979     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8980
8981   if (traffic_class)
8982     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8983
8984   if (flow_label)
8985     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8986
8987   ip->ip_version_traffic_class_and_flow_label =
8988     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8989
8990   *maskp = mask;
8991   return 1;
8992 }
8993
8994 uword
8995 unformat_l3_mask (unformat_input_t * input, va_list * args)
8996 {
8997   u8 **maskp = va_arg (*args, u8 **);
8998
8999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9000     {
9001       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9002         return 1;
9003       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9004         return 1;
9005       else
9006         break;
9007     }
9008   return 0;
9009 }
9010
9011 uword
9012 unformat_l2_mask (unformat_input_t * input, va_list * args)
9013 {
9014   u8 **maskp = va_arg (*args, u8 **);
9015   u8 *mask = 0;
9016   u8 src = 0;
9017   u8 dst = 0;
9018   u8 proto = 0;
9019   u8 tag1 = 0;
9020   u8 tag2 = 0;
9021   u8 ignore_tag1 = 0;
9022   u8 ignore_tag2 = 0;
9023   u8 cos1 = 0;
9024   u8 cos2 = 0;
9025   u8 dot1q = 0;
9026   u8 dot1ad = 0;
9027   int len = 14;
9028
9029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9030     {
9031       if (unformat (input, "src"))
9032         src = 1;
9033       else if (unformat (input, "dst"))
9034         dst = 1;
9035       else if (unformat (input, "proto"))
9036         proto = 1;
9037       else if (unformat (input, "tag1"))
9038         tag1 = 1;
9039       else if (unformat (input, "tag2"))
9040         tag2 = 1;
9041       else if (unformat (input, "ignore-tag1"))
9042         ignore_tag1 = 1;
9043       else if (unformat (input, "ignore-tag2"))
9044         ignore_tag2 = 1;
9045       else if (unformat (input, "cos1"))
9046         cos1 = 1;
9047       else if (unformat (input, "cos2"))
9048         cos2 = 1;
9049       else if (unformat (input, "dot1q"))
9050         dot1q = 1;
9051       else if (unformat (input, "dot1ad"))
9052         dot1ad = 1;
9053       else
9054         break;
9055     }
9056   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9057        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9058     return 0;
9059
9060   if (tag1 || ignore_tag1 || cos1 || dot1q)
9061     len = 18;
9062   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9063     len = 22;
9064
9065   vec_validate (mask, len - 1);
9066
9067   if (dst)
9068     memset (mask, 0xff, 6);
9069
9070   if (src)
9071     memset (mask + 6, 0xff, 6);
9072
9073   if (tag2 || dot1ad)
9074     {
9075       /* inner vlan tag */
9076       if (tag2)
9077         {
9078           mask[19] = 0xff;
9079           mask[18] = 0x0f;
9080         }
9081       if (cos2)
9082         mask[18] |= 0xe0;
9083       if (proto)
9084         mask[21] = mask[20] = 0xff;
9085       if (tag1)
9086         {
9087           mask[15] = 0xff;
9088           mask[14] = 0x0f;
9089         }
9090       if (cos1)
9091         mask[14] |= 0xe0;
9092       *maskp = mask;
9093       return 1;
9094     }
9095   if (tag1 | dot1q)
9096     {
9097       if (tag1)
9098         {
9099           mask[15] = 0xff;
9100           mask[14] = 0x0f;
9101         }
9102       if (cos1)
9103         mask[14] |= 0xe0;
9104       if (proto)
9105         mask[16] = mask[17] = 0xff;
9106
9107       *maskp = mask;
9108       return 1;
9109     }
9110   if (cos2)
9111     mask[18] |= 0xe0;
9112   if (cos1)
9113     mask[14] |= 0xe0;
9114   if (proto)
9115     mask[12] = mask[13] = 0xff;
9116
9117   *maskp = mask;
9118   return 1;
9119 }
9120
9121 uword
9122 unformat_classify_mask (unformat_input_t * input, va_list * args)
9123 {
9124   u8 **maskp = va_arg (*args, u8 **);
9125   u32 *skipp = va_arg (*args, u32 *);
9126   u32 *matchp = va_arg (*args, u32 *);
9127   u32 match;
9128   u8 *mask = 0;
9129   u8 *l2 = 0;
9130   u8 *l3 = 0;
9131   u8 *l4 = 0;
9132   int i;
9133
9134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9135     {
9136       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9137         ;
9138       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9139         ;
9140       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9141         ;
9142       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9143         ;
9144       else
9145         break;
9146     }
9147
9148   if (l4 && !l3)
9149     {
9150       vec_free (mask);
9151       vec_free (l2);
9152       vec_free (l4);
9153       return 0;
9154     }
9155
9156   if (mask || l2 || l3 || l4)
9157     {
9158       if (l2 || l3 || l4)
9159         {
9160           /* "With a free Ethernet header in every package" */
9161           if (l2 == 0)
9162             vec_validate (l2, 13);
9163           mask = l2;
9164           if (vec_len (l3))
9165             {
9166               vec_append (mask, l3);
9167               vec_free (l3);
9168             }
9169           if (vec_len (l4))
9170             {
9171               vec_append (mask, l4);
9172               vec_free (l4);
9173             }
9174         }
9175
9176       /* Scan forward looking for the first significant mask octet */
9177       for (i = 0; i < vec_len (mask); i++)
9178         if (mask[i])
9179           break;
9180
9181       /* compute (skip, match) params */
9182       *skipp = i / sizeof (u32x4);
9183       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9184
9185       /* Pad mask to an even multiple of the vector size */
9186       while (vec_len (mask) % sizeof (u32x4))
9187         vec_add1 (mask, 0);
9188
9189       match = vec_len (mask) / sizeof (u32x4);
9190
9191       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9192         {
9193           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9194           if (*tmp || *(tmp + 1))
9195             break;
9196           match--;
9197         }
9198       if (match == 0)
9199         clib_warning ("BUG: match 0");
9200
9201       _vec_len (mask) = match * sizeof (u32x4);
9202
9203       *matchp = match;
9204       *maskp = mask;
9205
9206       return 1;
9207     }
9208
9209   return 0;
9210 }
9211
9212 #define foreach_l2_next                         \
9213 _(drop, DROP)                                   \
9214 _(ethernet, ETHERNET_INPUT)                     \
9215 _(ip4, IP4_INPUT)                               \
9216 _(ip6, IP6_INPUT)
9217
9218 uword
9219 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9220 {
9221   u32 *miss_next_indexp = va_arg (*args, u32 *);
9222   u32 next_index = 0;
9223   u32 tmp;
9224
9225 #define _(n,N) \
9226   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9227   foreach_l2_next;
9228 #undef _
9229
9230   if (unformat (input, "%d", &tmp))
9231     {
9232       next_index = tmp;
9233       goto out;
9234     }
9235
9236   return 0;
9237
9238 out:
9239   *miss_next_indexp = next_index;
9240   return 1;
9241 }
9242
9243 #define foreach_ip_next                         \
9244 _(drop, DROP)                                   \
9245 _(local, LOCAL)                                 \
9246 _(rewrite, REWRITE)
9247
9248 uword
9249 unformat_ip_next_index (unformat_input_t * input, va_list * args)
9250 {
9251   u32 *miss_next_indexp = va_arg (*args, u32 *);
9252   u32 next_index = 0;
9253   u32 tmp;
9254
9255 #define _(n,N) \
9256   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9257   foreach_ip_next;
9258 #undef _
9259
9260   if (unformat (input, "%d", &tmp))
9261     {
9262       next_index = tmp;
9263       goto out;
9264     }
9265
9266   return 0;
9267
9268 out:
9269   *miss_next_indexp = next_index;
9270   return 1;
9271 }
9272
9273 #define foreach_acl_next                        \
9274 _(deny, DENY)
9275
9276 uword
9277 unformat_acl_next_index (unformat_input_t * input, va_list * args)
9278 {
9279   u32 *miss_next_indexp = va_arg (*args, u32 *);
9280   u32 next_index = 0;
9281   u32 tmp;
9282
9283 #define _(n,N) \
9284   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9285   foreach_acl_next;
9286 #undef _
9287
9288   if (unformat (input, "permit"))
9289     {
9290       next_index = ~0;
9291       goto out;
9292     }
9293   else if (unformat (input, "%d", &tmp))
9294     {
9295       next_index = tmp;
9296       goto out;
9297     }
9298
9299   return 0;
9300
9301 out:
9302   *miss_next_indexp = next_index;
9303   return 1;
9304 }
9305
9306 uword
9307 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9308 {
9309   u32 *r = va_arg (*args, u32 *);
9310
9311   if (unformat (input, "conform-color"))
9312     *r = POLICE_CONFORM;
9313   else if (unformat (input, "exceed-color"))
9314     *r = POLICE_EXCEED;
9315   else
9316     return 0;
9317
9318   return 1;
9319 }
9320
9321 static int
9322 api_classify_add_del_table (vat_main_t * vam)
9323 {
9324   unformat_input_t *i = vam->input;
9325   vl_api_classify_add_del_table_t *mp;
9326
9327   u32 nbuckets = 2;
9328   u32 skip = ~0;
9329   u32 match = ~0;
9330   int is_add = 1;
9331   int del_chain = 0;
9332   u32 table_index = ~0;
9333   u32 next_table_index = ~0;
9334   u32 miss_next_index = ~0;
9335   u32 memory_size = 32 << 20;
9336   u8 *mask = 0;
9337   u32 current_data_flag = 0;
9338   int current_data_offset = 0;
9339   int ret;
9340
9341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9342     {
9343       if (unformat (i, "del"))
9344         is_add = 0;
9345       else if (unformat (i, "del-chain"))
9346         {
9347           is_add = 0;
9348           del_chain = 1;
9349         }
9350       else if (unformat (i, "buckets %d", &nbuckets))
9351         ;
9352       else if (unformat (i, "memory_size %d", &memory_size))
9353         ;
9354       else if (unformat (i, "skip %d", &skip))
9355         ;
9356       else if (unformat (i, "match %d", &match))
9357         ;
9358       else if (unformat (i, "table %d", &table_index))
9359         ;
9360       else if (unformat (i, "mask %U", unformat_classify_mask,
9361                          &mask, &skip, &match))
9362         ;
9363       else if (unformat (i, "next-table %d", &next_table_index))
9364         ;
9365       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
9366                          &miss_next_index))
9367         ;
9368       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9369                          &miss_next_index))
9370         ;
9371       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9372                          &miss_next_index))
9373         ;
9374       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9375         ;
9376       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9377         ;
9378       else
9379         break;
9380     }
9381
9382   if (is_add && mask == 0)
9383     {
9384       errmsg ("Mask required");
9385       return -99;
9386     }
9387
9388   if (is_add && skip == ~0)
9389     {
9390       errmsg ("skip count required");
9391       return -99;
9392     }
9393
9394   if (is_add && match == ~0)
9395     {
9396       errmsg ("match count required");
9397       return -99;
9398     }
9399
9400   if (!is_add && table_index == ~0)
9401     {
9402       errmsg ("table index required for delete");
9403       return -99;
9404     }
9405
9406   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9407
9408   mp->is_add = is_add;
9409   mp->del_chain = del_chain;
9410   mp->table_index = ntohl (table_index);
9411   mp->nbuckets = ntohl (nbuckets);
9412   mp->memory_size = ntohl (memory_size);
9413   mp->skip_n_vectors = ntohl (skip);
9414   mp->match_n_vectors = ntohl (match);
9415   mp->next_table_index = ntohl (next_table_index);
9416   mp->miss_next_index = ntohl (miss_next_index);
9417   mp->current_data_flag = ntohl (current_data_flag);
9418   mp->current_data_offset = ntohl (current_data_offset);
9419   clib_memcpy (mp->mask, mask, vec_len (mask));
9420
9421   vec_free (mask);
9422
9423   S (mp);
9424   W (ret);
9425   return ret;
9426 }
9427
9428 uword
9429 unformat_l4_match (unformat_input_t * input, va_list * args)
9430 {
9431   u8 **matchp = va_arg (*args, u8 **);
9432
9433   u8 *proto_header = 0;
9434   int src_port = 0;
9435   int dst_port = 0;
9436
9437   tcpudp_header_t h;
9438
9439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9440     {
9441       if (unformat (input, "src_port %d", &src_port))
9442         ;
9443       else if (unformat (input, "dst_port %d", &dst_port))
9444         ;
9445       else
9446         return 0;
9447     }
9448
9449   h.src_port = clib_host_to_net_u16 (src_port);
9450   h.dst_port = clib_host_to_net_u16 (dst_port);
9451   vec_validate (proto_header, sizeof (h) - 1);
9452   memcpy (proto_header, &h, sizeof (h));
9453
9454   *matchp = proto_header;
9455
9456   return 1;
9457 }
9458
9459 uword
9460 unformat_ip4_match (unformat_input_t * input, va_list * args)
9461 {
9462   u8 **matchp = va_arg (*args, u8 **);
9463   u8 *match = 0;
9464   ip4_header_t *ip;
9465   int version = 0;
9466   u32 version_val;
9467   int hdr_length = 0;
9468   u32 hdr_length_val;
9469   int src = 0, dst = 0;
9470   ip4_address_t src_val, dst_val;
9471   int proto = 0;
9472   u32 proto_val;
9473   int tos = 0;
9474   u32 tos_val;
9475   int length = 0;
9476   u32 length_val;
9477   int fragment_id = 0;
9478   u32 fragment_id_val;
9479   int ttl = 0;
9480   int ttl_val;
9481   int checksum = 0;
9482   u32 checksum_val;
9483
9484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9485     {
9486       if (unformat (input, "version %d", &version_val))
9487         version = 1;
9488       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9489         hdr_length = 1;
9490       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9491         src = 1;
9492       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9493         dst = 1;
9494       else if (unformat (input, "proto %d", &proto_val))
9495         proto = 1;
9496       else if (unformat (input, "tos %d", &tos_val))
9497         tos = 1;
9498       else if (unformat (input, "length %d", &length_val))
9499         length = 1;
9500       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9501         fragment_id = 1;
9502       else if (unformat (input, "ttl %d", &ttl_val))
9503         ttl = 1;
9504       else if (unformat (input, "checksum %d", &checksum_val))
9505         checksum = 1;
9506       else
9507         break;
9508     }
9509
9510   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9511       + ttl + checksum == 0)
9512     return 0;
9513
9514   /*
9515    * Aligned because we use the real comparison functions
9516    */
9517   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9518
9519   ip = (ip4_header_t *) match;
9520
9521   /* These are realistically matched in practice */
9522   if (src)
9523     ip->src_address.as_u32 = src_val.as_u32;
9524
9525   if (dst)
9526     ip->dst_address.as_u32 = dst_val.as_u32;
9527
9528   if (proto)
9529     ip->protocol = proto_val;
9530
9531
9532   /* These are not, but they're included for completeness */
9533   if (version)
9534     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9535
9536   if (hdr_length)
9537     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9538
9539   if (tos)
9540     ip->tos = tos_val;
9541
9542   if (length)
9543     ip->length = clib_host_to_net_u16 (length_val);
9544
9545   if (ttl)
9546     ip->ttl = ttl_val;
9547
9548   if (checksum)
9549     ip->checksum = clib_host_to_net_u16 (checksum_val);
9550
9551   *matchp = match;
9552   return 1;
9553 }
9554
9555 uword
9556 unformat_ip6_match (unformat_input_t * input, va_list * args)
9557 {
9558   u8 **matchp = va_arg (*args, u8 **);
9559   u8 *match = 0;
9560   ip6_header_t *ip;
9561   int version = 0;
9562   u32 version_val;
9563   u8 traffic_class = 0;
9564   u32 traffic_class_val = 0;
9565   u8 flow_label = 0;
9566   u8 flow_label_val;
9567   int src = 0, dst = 0;
9568   ip6_address_t src_val, dst_val;
9569   int proto = 0;
9570   u32 proto_val;
9571   int payload_length = 0;
9572   u32 payload_length_val;
9573   int hop_limit = 0;
9574   int hop_limit_val;
9575   u32 ip_version_traffic_class_and_flow_label;
9576
9577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9578     {
9579       if (unformat (input, "version %d", &version_val))
9580         version = 1;
9581       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9582         traffic_class = 1;
9583       else if (unformat (input, "flow_label %d", &flow_label_val))
9584         flow_label = 1;
9585       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9586         src = 1;
9587       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9588         dst = 1;
9589       else if (unformat (input, "proto %d", &proto_val))
9590         proto = 1;
9591       else if (unformat (input, "payload_length %d", &payload_length_val))
9592         payload_length = 1;
9593       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9594         hop_limit = 1;
9595       else
9596         break;
9597     }
9598
9599   if (version + traffic_class + flow_label + src + dst + proto +
9600       payload_length + hop_limit == 0)
9601     return 0;
9602
9603   /*
9604    * Aligned because we use the real comparison functions
9605    */
9606   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9607
9608   ip = (ip6_header_t *) match;
9609
9610   if (src)
9611     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9612
9613   if (dst)
9614     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9615
9616   if (proto)
9617     ip->protocol = proto_val;
9618
9619   ip_version_traffic_class_and_flow_label = 0;
9620
9621   if (version)
9622     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9623
9624   if (traffic_class)
9625     ip_version_traffic_class_and_flow_label |=
9626       (traffic_class_val & 0xFF) << 20;
9627
9628   if (flow_label)
9629     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9630
9631   ip->ip_version_traffic_class_and_flow_label =
9632     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9633
9634   if (payload_length)
9635     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9636
9637   if (hop_limit)
9638     ip->hop_limit = hop_limit_val;
9639
9640   *matchp = match;
9641   return 1;
9642 }
9643
9644 uword
9645 unformat_l3_match (unformat_input_t * input, va_list * args)
9646 {
9647   u8 **matchp = va_arg (*args, u8 **);
9648
9649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9650     {
9651       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9652         return 1;
9653       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9654         return 1;
9655       else
9656         break;
9657     }
9658   return 0;
9659 }
9660
9661 uword
9662 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9663 {
9664   u8 *tagp = va_arg (*args, u8 *);
9665   u32 tag;
9666
9667   if (unformat (input, "%d", &tag))
9668     {
9669       tagp[0] = (tag >> 8) & 0x0F;
9670       tagp[1] = tag & 0xFF;
9671       return 1;
9672     }
9673
9674   return 0;
9675 }
9676
9677 uword
9678 unformat_l2_match (unformat_input_t * input, va_list * args)
9679 {
9680   u8 **matchp = va_arg (*args, u8 **);
9681   u8 *match = 0;
9682   u8 src = 0;
9683   u8 src_val[6];
9684   u8 dst = 0;
9685   u8 dst_val[6];
9686   u8 proto = 0;
9687   u16 proto_val;
9688   u8 tag1 = 0;
9689   u8 tag1_val[2];
9690   u8 tag2 = 0;
9691   u8 tag2_val[2];
9692   int len = 14;
9693   u8 ignore_tag1 = 0;
9694   u8 ignore_tag2 = 0;
9695   u8 cos1 = 0;
9696   u8 cos2 = 0;
9697   u32 cos1_val = 0;
9698   u32 cos2_val = 0;
9699
9700   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9701     {
9702       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9703         src = 1;
9704       else
9705         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9706         dst = 1;
9707       else if (unformat (input, "proto %U",
9708                          unformat_ethernet_type_host_byte_order, &proto_val))
9709         proto = 1;
9710       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9711         tag1 = 1;
9712       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9713         tag2 = 1;
9714       else if (unformat (input, "ignore-tag1"))
9715         ignore_tag1 = 1;
9716       else if (unformat (input, "ignore-tag2"))
9717         ignore_tag2 = 1;
9718       else if (unformat (input, "cos1 %d", &cos1_val))
9719         cos1 = 1;
9720       else if (unformat (input, "cos2 %d", &cos2_val))
9721         cos2 = 1;
9722       else
9723         break;
9724     }
9725   if ((src + dst + proto + tag1 + tag2 +
9726        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9727     return 0;
9728
9729   if (tag1 || ignore_tag1 || cos1)
9730     len = 18;
9731   if (tag2 || ignore_tag2 || cos2)
9732     len = 22;
9733
9734   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9735
9736   if (dst)
9737     clib_memcpy (match, dst_val, 6);
9738
9739   if (src)
9740     clib_memcpy (match + 6, src_val, 6);
9741
9742   if (tag2)
9743     {
9744       /* inner vlan tag */
9745       match[19] = tag2_val[1];
9746       match[18] = tag2_val[0];
9747       if (cos2)
9748         match[18] |= (cos2_val & 0x7) << 5;
9749       if (proto)
9750         {
9751           match[21] = proto_val & 0xff;
9752           match[20] = proto_val >> 8;
9753         }
9754       if (tag1)
9755         {
9756           match[15] = tag1_val[1];
9757           match[14] = tag1_val[0];
9758         }
9759       if (cos1)
9760         match[14] |= (cos1_val & 0x7) << 5;
9761       *matchp = match;
9762       return 1;
9763     }
9764   if (tag1)
9765     {
9766       match[15] = tag1_val[1];
9767       match[14] = tag1_val[0];
9768       if (proto)
9769         {
9770           match[17] = proto_val & 0xff;
9771           match[16] = proto_val >> 8;
9772         }
9773       if (cos1)
9774         match[14] |= (cos1_val & 0x7) << 5;
9775
9776       *matchp = match;
9777       return 1;
9778     }
9779   if (cos2)
9780     match[18] |= (cos2_val & 0x7) << 5;
9781   if (cos1)
9782     match[14] |= (cos1_val & 0x7) << 5;
9783   if (proto)
9784     {
9785       match[13] = proto_val & 0xff;
9786       match[12] = proto_val >> 8;
9787     }
9788
9789   *matchp = match;
9790   return 1;
9791 }
9792
9793
9794 uword
9795 unformat_classify_match (unformat_input_t * input, va_list * args)
9796 {
9797   u8 **matchp = va_arg (*args, u8 **);
9798   u32 skip_n_vectors = va_arg (*args, u32);
9799   u32 match_n_vectors = va_arg (*args, u32);
9800
9801   u8 *match = 0;
9802   u8 *l2 = 0;
9803   u8 *l3 = 0;
9804   u8 *l4 = 0;
9805
9806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9807     {
9808       if (unformat (input, "hex %U", unformat_hex_string, &match))
9809         ;
9810       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9811         ;
9812       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9813         ;
9814       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9815         ;
9816       else
9817         break;
9818     }
9819
9820   if (l4 && !l3)
9821     {
9822       vec_free (match);
9823       vec_free (l2);
9824       vec_free (l4);
9825       return 0;
9826     }
9827
9828   if (match || l2 || l3 || l4)
9829     {
9830       if (l2 || l3 || l4)
9831         {
9832           /* "Win a free Ethernet header in every packet" */
9833           if (l2 == 0)
9834             vec_validate_aligned (l2, 13, sizeof (u32x4));
9835           match = l2;
9836           if (vec_len (l3))
9837             {
9838               vec_append_aligned (match, l3, sizeof (u32x4));
9839               vec_free (l3);
9840             }
9841           if (vec_len (l4))
9842             {
9843               vec_append_aligned (match, l4, sizeof (u32x4));
9844               vec_free (l4);
9845             }
9846         }
9847
9848       /* Make sure the vector is big enough even if key is all 0's */
9849       vec_validate_aligned
9850         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9851          sizeof (u32x4));
9852
9853       /* Set size, include skipped vectors */
9854       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9855
9856       *matchp = match;
9857
9858       return 1;
9859     }
9860
9861   return 0;
9862 }
9863
9864 static int
9865 api_classify_add_del_session (vat_main_t * vam)
9866 {
9867   unformat_input_t *i = vam->input;
9868   vl_api_classify_add_del_session_t *mp;
9869   int is_add = 1;
9870   u32 table_index = ~0;
9871   u32 hit_next_index = ~0;
9872   u32 opaque_index = ~0;
9873   u8 *match = 0;
9874   i32 advance = 0;
9875   u32 skip_n_vectors = 0;
9876   u32 match_n_vectors = 0;
9877   u32 action = 0;
9878   u32 metadata = 0;
9879   int ret;
9880
9881   /*
9882    * Warning: you have to supply skip_n and match_n
9883    * because the API client cant simply look at the classify
9884    * table object.
9885    */
9886
9887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9888     {
9889       if (unformat (i, "del"))
9890         is_add = 0;
9891       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9892                          &hit_next_index))
9893         ;
9894       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9895                          &hit_next_index))
9896         ;
9897       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9898                          &hit_next_index))
9899         ;
9900       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9901         ;
9902       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9903         ;
9904       else if (unformat (i, "opaque-index %d", &opaque_index))
9905         ;
9906       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9907         ;
9908       else if (unformat (i, "match_n %d", &match_n_vectors))
9909         ;
9910       else if (unformat (i, "match %U", unformat_classify_match,
9911                          &match, skip_n_vectors, match_n_vectors))
9912         ;
9913       else if (unformat (i, "advance %d", &advance))
9914         ;
9915       else if (unformat (i, "table-index %d", &table_index))
9916         ;
9917       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9918         action = 1;
9919       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9920         action = 2;
9921       else if (unformat (i, "action %d", &action))
9922         ;
9923       else if (unformat (i, "metadata %d", &metadata))
9924         ;
9925       else
9926         break;
9927     }
9928
9929   if (table_index == ~0)
9930     {
9931       errmsg ("Table index required");
9932       return -99;
9933     }
9934
9935   if (is_add && match == 0)
9936     {
9937       errmsg ("Match value required");
9938       return -99;
9939     }
9940
9941   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9942
9943   mp->is_add = is_add;
9944   mp->table_index = ntohl (table_index);
9945   mp->hit_next_index = ntohl (hit_next_index);
9946   mp->opaque_index = ntohl (opaque_index);
9947   mp->advance = ntohl (advance);
9948   mp->action = action;
9949   mp->metadata = ntohl (metadata);
9950   clib_memcpy (mp->match, match, vec_len (match));
9951   vec_free (match);
9952
9953   S (mp);
9954   W (ret);
9955   return ret;
9956 }
9957
9958 static int
9959 api_classify_set_interface_ip_table (vat_main_t * vam)
9960 {
9961   unformat_input_t *i = vam->input;
9962   vl_api_classify_set_interface_ip_table_t *mp;
9963   u32 sw_if_index;
9964   int sw_if_index_set;
9965   u32 table_index = ~0;
9966   u8 is_ipv6 = 0;
9967   int ret;
9968
9969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9970     {
9971       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9972         sw_if_index_set = 1;
9973       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9974         sw_if_index_set = 1;
9975       else if (unformat (i, "table %d", &table_index))
9976         ;
9977       else
9978         {
9979           clib_warning ("parse error '%U'", format_unformat_error, i);
9980           return -99;
9981         }
9982     }
9983
9984   if (sw_if_index_set == 0)
9985     {
9986       errmsg ("missing interface name or sw_if_index");
9987       return -99;
9988     }
9989
9990
9991   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9992
9993   mp->sw_if_index = ntohl (sw_if_index);
9994   mp->table_index = ntohl (table_index);
9995   mp->is_ipv6 = is_ipv6;
9996
9997   S (mp);
9998   W (ret);
9999   return ret;
10000 }
10001
10002 static int
10003 api_classify_set_interface_l2_tables (vat_main_t * vam)
10004 {
10005   unformat_input_t *i = vam->input;
10006   vl_api_classify_set_interface_l2_tables_t *mp;
10007   u32 sw_if_index;
10008   int sw_if_index_set;
10009   u32 ip4_table_index = ~0;
10010   u32 ip6_table_index = ~0;
10011   u32 other_table_index = ~0;
10012   u32 is_input = 1;
10013   int ret;
10014
10015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10016     {
10017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10018         sw_if_index_set = 1;
10019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10020         sw_if_index_set = 1;
10021       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10022         ;
10023       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10024         ;
10025       else if (unformat (i, "other-table %d", &other_table_index))
10026         ;
10027       else if (unformat (i, "is-input %d", &is_input))
10028         ;
10029       else
10030         {
10031           clib_warning ("parse error '%U'", format_unformat_error, i);
10032           return -99;
10033         }
10034     }
10035
10036   if (sw_if_index_set == 0)
10037     {
10038       errmsg ("missing interface name or sw_if_index");
10039       return -99;
10040     }
10041
10042
10043   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10044
10045   mp->sw_if_index = ntohl (sw_if_index);
10046   mp->ip4_table_index = ntohl (ip4_table_index);
10047   mp->ip6_table_index = ntohl (ip6_table_index);
10048   mp->other_table_index = ntohl (other_table_index);
10049   mp->is_input = (u8) is_input;
10050
10051   S (mp);
10052   W (ret);
10053   return ret;
10054 }
10055
10056 static int
10057 api_set_ipfix_exporter (vat_main_t * vam)
10058 {
10059   unformat_input_t *i = vam->input;
10060   vl_api_set_ipfix_exporter_t *mp;
10061   ip4_address_t collector_address;
10062   u8 collector_address_set = 0;
10063   u32 collector_port = ~0;
10064   ip4_address_t src_address;
10065   u8 src_address_set = 0;
10066   u32 vrf_id = ~0;
10067   u32 path_mtu = ~0;
10068   u32 template_interval = ~0;
10069   u8 udp_checksum = 0;
10070   int ret;
10071
10072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10073     {
10074       if (unformat (i, "collector_address %U", unformat_ip4_address,
10075                     &collector_address))
10076         collector_address_set = 1;
10077       else if (unformat (i, "collector_port %d", &collector_port))
10078         ;
10079       else if (unformat (i, "src_address %U", unformat_ip4_address,
10080                          &src_address))
10081         src_address_set = 1;
10082       else if (unformat (i, "vrf_id %d", &vrf_id))
10083         ;
10084       else if (unformat (i, "path_mtu %d", &path_mtu))
10085         ;
10086       else if (unformat (i, "template_interval %d", &template_interval))
10087         ;
10088       else if (unformat (i, "udp_checksum"))
10089         udp_checksum = 1;
10090       else
10091         break;
10092     }
10093
10094   if (collector_address_set == 0)
10095     {
10096       errmsg ("collector_address required");
10097       return -99;
10098     }
10099
10100   if (src_address_set == 0)
10101     {
10102       errmsg ("src_address required");
10103       return -99;
10104     }
10105
10106   M (SET_IPFIX_EXPORTER, mp);
10107
10108   memcpy (mp->collector_address, collector_address.data,
10109           sizeof (collector_address.data));
10110   mp->collector_port = htons ((u16) collector_port);
10111   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10112   mp->vrf_id = htonl (vrf_id);
10113   mp->path_mtu = htonl (path_mtu);
10114   mp->template_interval = htonl (template_interval);
10115   mp->udp_checksum = udp_checksum;
10116
10117   S (mp);
10118   W (ret);
10119   return ret;
10120 }
10121
10122 static int
10123 api_set_ipfix_classify_stream (vat_main_t * vam)
10124 {
10125   unformat_input_t *i = vam->input;
10126   vl_api_set_ipfix_classify_stream_t *mp;
10127   u32 domain_id = 0;
10128   u32 src_port = UDP_DST_PORT_ipfix;
10129   int ret;
10130
10131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10132     {
10133       if (unformat (i, "domain %d", &domain_id))
10134         ;
10135       else if (unformat (i, "src_port %d", &src_port))
10136         ;
10137       else
10138         {
10139           errmsg ("unknown input `%U'", format_unformat_error, i);
10140           return -99;
10141         }
10142     }
10143
10144   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10145
10146   mp->domain_id = htonl (domain_id);
10147   mp->src_port = htons ((u16) src_port);
10148
10149   S (mp);
10150   W (ret);
10151   return ret;
10152 }
10153
10154 static int
10155 api_ipfix_classify_table_add_del (vat_main_t * vam)
10156 {
10157   unformat_input_t *i = vam->input;
10158   vl_api_ipfix_classify_table_add_del_t *mp;
10159   int is_add = -1;
10160   u32 classify_table_index = ~0;
10161   u8 ip_version = 0;
10162   u8 transport_protocol = 255;
10163   int ret;
10164
10165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10166     {
10167       if (unformat (i, "add"))
10168         is_add = 1;
10169       else if (unformat (i, "del"))
10170         is_add = 0;
10171       else if (unformat (i, "table %d", &classify_table_index))
10172         ;
10173       else if (unformat (i, "ip4"))
10174         ip_version = 4;
10175       else if (unformat (i, "ip6"))
10176         ip_version = 6;
10177       else if (unformat (i, "tcp"))
10178         transport_protocol = 6;
10179       else if (unformat (i, "udp"))
10180         transport_protocol = 17;
10181       else
10182         {
10183           errmsg ("unknown input `%U'", format_unformat_error, i);
10184           return -99;
10185         }
10186     }
10187
10188   if (is_add == -1)
10189     {
10190       errmsg ("expecting: add|del");
10191       return -99;
10192     }
10193   if (classify_table_index == ~0)
10194     {
10195       errmsg ("classifier table not specified");
10196       return -99;
10197     }
10198   if (ip_version == 0)
10199     {
10200       errmsg ("IP version not specified");
10201       return -99;
10202     }
10203
10204   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10205
10206   mp->is_add = is_add;
10207   mp->table_id = htonl (classify_table_index);
10208   mp->ip_version = ip_version;
10209   mp->transport_protocol = transport_protocol;
10210
10211   S (mp);
10212   W (ret);
10213   return ret;
10214 }
10215
10216 static int
10217 api_get_node_index (vat_main_t * vam)
10218 {
10219   unformat_input_t *i = vam->input;
10220   vl_api_get_node_index_t *mp;
10221   u8 *name = 0;
10222   int ret;
10223
10224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10225     {
10226       if (unformat (i, "node %s", &name))
10227         ;
10228       else
10229         break;
10230     }
10231   if (name == 0)
10232     {
10233       errmsg ("node name required");
10234       return -99;
10235     }
10236   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10237     {
10238       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10239       return -99;
10240     }
10241
10242   M (GET_NODE_INDEX, mp);
10243   clib_memcpy (mp->node_name, name, vec_len (name));
10244   vec_free (name);
10245
10246   S (mp);
10247   W (ret);
10248   return ret;
10249 }
10250
10251 static int
10252 api_get_next_index (vat_main_t * vam)
10253 {
10254   unformat_input_t *i = vam->input;
10255   vl_api_get_next_index_t *mp;
10256   u8 *node_name = 0, *next_node_name = 0;
10257   int ret;
10258
10259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10260     {
10261       if (unformat (i, "node-name %s", &node_name))
10262         ;
10263       else if (unformat (i, "next-node-name %s", &next_node_name))
10264         break;
10265     }
10266
10267   if (node_name == 0)
10268     {
10269       errmsg ("node name required");
10270       return -99;
10271     }
10272   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10273     {
10274       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10275       return -99;
10276     }
10277
10278   if (next_node_name == 0)
10279     {
10280       errmsg ("next node name required");
10281       return -99;
10282     }
10283   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10284     {
10285       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10286       return -99;
10287     }
10288
10289   M (GET_NEXT_INDEX, mp);
10290   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10291   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10292   vec_free (node_name);
10293   vec_free (next_node_name);
10294
10295   S (mp);
10296   W (ret);
10297   return ret;
10298 }
10299
10300 static int
10301 api_add_node_next (vat_main_t * vam)
10302 {
10303   unformat_input_t *i = vam->input;
10304   vl_api_add_node_next_t *mp;
10305   u8 *name = 0;
10306   u8 *next = 0;
10307   int ret;
10308
10309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10310     {
10311       if (unformat (i, "node %s", &name))
10312         ;
10313       else if (unformat (i, "next %s", &next))
10314         ;
10315       else
10316         break;
10317     }
10318   if (name == 0)
10319     {
10320       errmsg ("node name required");
10321       return -99;
10322     }
10323   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10324     {
10325       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10326       return -99;
10327     }
10328   if (next == 0)
10329     {
10330       errmsg ("next node required");
10331       return -99;
10332     }
10333   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10334     {
10335       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10336       return -99;
10337     }
10338
10339   M (ADD_NODE_NEXT, mp);
10340   clib_memcpy (mp->node_name, name, vec_len (name));
10341   clib_memcpy (mp->next_name, next, vec_len (next));
10342   vec_free (name);
10343   vec_free (next);
10344
10345   S (mp);
10346   W (ret);
10347   return ret;
10348 }
10349
10350 static int
10351 api_l2tpv3_create_tunnel (vat_main_t * vam)
10352 {
10353   unformat_input_t *i = vam->input;
10354   ip6_address_t client_address, our_address;
10355   int client_address_set = 0;
10356   int our_address_set = 0;
10357   u32 local_session_id = 0;
10358   u32 remote_session_id = 0;
10359   u64 local_cookie = 0;
10360   u64 remote_cookie = 0;
10361   u8 l2_sublayer_present = 0;
10362   vl_api_l2tpv3_create_tunnel_t *mp;
10363   int ret;
10364
10365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10366     {
10367       if (unformat (i, "client_address %U", unformat_ip6_address,
10368                     &client_address))
10369         client_address_set = 1;
10370       else if (unformat (i, "our_address %U", unformat_ip6_address,
10371                          &our_address))
10372         our_address_set = 1;
10373       else if (unformat (i, "local_session_id %d", &local_session_id))
10374         ;
10375       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10376         ;
10377       else if (unformat (i, "local_cookie %lld", &local_cookie))
10378         ;
10379       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10380         ;
10381       else if (unformat (i, "l2-sublayer-present"))
10382         l2_sublayer_present = 1;
10383       else
10384         break;
10385     }
10386
10387   if (client_address_set == 0)
10388     {
10389       errmsg ("client_address required");
10390       return -99;
10391     }
10392
10393   if (our_address_set == 0)
10394     {
10395       errmsg ("our_address required");
10396       return -99;
10397     }
10398
10399   M (L2TPV3_CREATE_TUNNEL, mp);
10400
10401   clib_memcpy (mp->client_address, client_address.as_u8,
10402                sizeof (mp->client_address));
10403
10404   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10405
10406   mp->local_session_id = ntohl (local_session_id);
10407   mp->remote_session_id = ntohl (remote_session_id);
10408   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10409   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10410   mp->l2_sublayer_present = l2_sublayer_present;
10411   mp->is_ipv6 = 1;
10412
10413   S (mp);
10414   W (ret);
10415   return ret;
10416 }
10417
10418 static int
10419 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10420 {
10421   unformat_input_t *i = vam->input;
10422   u32 sw_if_index;
10423   u8 sw_if_index_set = 0;
10424   u64 new_local_cookie = 0;
10425   u64 new_remote_cookie = 0;
10426   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10427   int ret;
10428
10429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10430     {
10431       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10432         sw_if_index_set = 1;
10433       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10434         sw_if_index_set = 1;
10435       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10436         ;
10437       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10438         ;
10439       else
10440         break;
10441     }
10442
10443   if (sw_if_index_set == 0)
10444     {
10445       errmsg ("missing interface name or sw_if_index");
10446       return -99;
10447     }
10448
10449   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10450
10451   mp->sw_if_index = ntohl (sw_if_index);
10452   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10453   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10454
10455   S (mp);
10456   W (ret);
10457   return ret;
10458 }
10459
10460 static int
10461 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10462 {
10463   unformat_input_t *i = vam->input;
10464   vl_api_l2tpv3_interface_enable_disable_t *mp;
10465   u32 sw_if_index;
10466   u8 sw_if_index_set = 0;
10467   u8 enable_disable = 1;
10468   int ret;
10469
10470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10471     {
10472       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10473         sw_if_index_set = 1;
10474       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10475         sw_if_index_set = 1;
10476       else if (unformat (i, "enable"))
10477         enable_disable = 1;
10478       else if (unformat (i, "disable"))
10479         enable_disable = 0;
10480       else
10481         break;
10482     }
10483
10484   if (sw_if_index_set == 0)
10485     {
10486       errmsg ("missing interface name or sw_if_index");
10487       return -99;
10488     }
10489
10490   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10491
10492   mp->sw_if_index = ntohl (sw_if_index);
10493   mp->enable_disable = enable_disable;
10494
10495   S (mp);
10496   W (ret);
10497   return ret;
10498 }
10499
10500 static int
10501 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10502 {
10503   unformat_input_t *i = vam->input;
10504   vl_api_l2tpv3_set_lookup_key_t *mp;
10505   u8 key = ~0;
10506   int ret;
10507
10508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10509     {
10510       if (unformat (i, "lookup_v6_src"))
10511         key = L2T_LOOKUP_SRC_ADDRESS;
10512       else if (unformat (i, "lookup_v6_dst"))
10513         key = L2T_LOOKUP_DST_ADDRESS;
10514       else if (unformat (i, "lookup_session_id"))
10515         key = L2T_LOOKUP_SESSION_ID;
10516       else
10517         break;
10518     }
10519
10520   if (key == (u8) ~ 0)
10521     {
10522       errmsg ("l2tp session lookup key unset");
10523       return -99;
10524     }
10525
10526   M (L2TPV3_SET_LOOKUP_KEY, mp);
10527
10528   mp->key = key;
10529
10530   S (mp);
10531   W (ret);
10532   return ret;
10533 }
10534
10535 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10536   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10537 {
10538   vat_main_t *vam = &vat_main;
10539
10540   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10541          format_ip6_address, mp->our_address,
10542          format_ip6_address, mp->client_address,
10543          clib_net_to_host_u32 (mp->sw_if_index));
10544
10545   print (vam->ofp,
10546          "   local cookies %016llx %016llx remote cookie %016llx",
10547          clib_net_to_host_u64 (mp->local_cookie[0]),
10548          clib_net_to_host_u64 (mp->local_cookie[1]),
10549          clib_net_to_host_u64 (mp->remote_cookie));
10550
10551   print (vam->ofp, "   local session-id %d remote session-id %d",
10552          clib_net_to_host_u32 (mp->local_session_id),
10553          clib_net_to_host_u32 (mp->remote_session_id));
10554
10555   print (vam->ofp, "   l2 specific sublayer %s\n",
10556          mp->l2_sublayer_present ? "preset" : "absent");
10557
10558 }
10559
10560 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10561   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10562 {
10563   vat_main_t *vam = &vat_main;
10564   vat_json_node_t *node = NULL;
10565   struct in6_addr addr;
10566
10567   if (VAT_JSON_ARRAY != vam->json_tree.type)
10568     {
10569       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10570       vat_json_init_array (&vam->json_tree);
10571     }
10572   node = vat_json_array_add (&vam->json_tree);
10573
10574   vat_json_init_object (node);
10575
10576   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10577   vat_json_object_add_ip6 (node, "our_address", addr);
10578   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10579   vat_json_object_add_ip6 (node, "client_address", addr);
10580
10581   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10582   vat_json_init_array (lc);
10583   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10584   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10585   vat_json_object_add_uint (node, "remote_cookie",
10586                             clib_net_to_host_u64 (mp->remote_cookie));
10587
10588   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10589   vat_json_object_add_uint (node, "local_session_id",
10590                             clib_net_to_host_u32 (mp->local_session_id));
10591   vat_json_object_add_uint (node, "remote_session_id",
10592                             clib_net_to_host_u32 (mp->remote_session_id));
10593   vat_json_object_add_string_copy (node, "l2_sublayer",
10594                                    mp->l2_sublayer_present ? (u8 *) "present"
10595                                    : (u8 *) "absent");
10596 }
10597
10598 static int
10599 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10600 {
10601   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10602   vl_api_control_ping_t *mp_ping;
10603   int ret;
10604
10605   /* Get list of l2tpv3-tunnel interfaces */
10606   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10607   S (mp);
10608
10609   /* Use a control ping for synchronization */
10610   M (CONTROL_PING, mp_ping);
10611   S (mp_ping);
10612
10613   W (ret);
10614   return ret;
10615 }
10616
10617
10618 static void vl_api_sw_interface_tap_details_t_handler
10619   (vl_api_sw_interface_tap_details_t * mp)
10620 {
10621   vat_main_t *vam = &vat_main;
10622
10623   print (vam->ofp, "%-16s %d",
10624          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10625 }
10626
10627 static void vl_api_sw_interface_tap_details_t_handler_json
10628   (vl_api_sw_interface_tap_details_t * mp)
10629 {
10630   vat_main_t *vam = &vat_main;
10631   vat_json_node_t *node = NULL;
10632
10633   if (VAT_JSON_ARRAY != vam->json_tree.type)
10634     {
10635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10636       vat_json_init_array (&vam->json_tree);
10637     }
10638   node = vat_json_array_add (&vam->json_tree);
10639
10640   vat_json_init_object (node);
10641   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10642   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10643 }
10644
10645 static int
10646 api_sw_interface_tap_dump (vat_main_t * vam)
10647 {
10648   vl_api_sw_interface_tap_dump_t *mp;
10649   vl_api_control_ping_t *mp_ping;
10650   int ret;
10651
10652   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10653   /* Get list of tap interfaces */
10654   M (SW_INTERFACE_TAP_DUMP, mp);
10655   S (mp);
10656
10657   /* Use a control ping for synchronization */
10658   M (CONTROL_PING, mp_ping);
10659   S (mp_ping);
10660
10661   W (ret);
10662   return ret;
10663 }
10664
10665 static uword unformat_vxlan_decap_next
10666   (unformat_input_t * input, va_list * args)
10667 {
10668   u32 *result = va_arg (*args, u32 *);
10669   u32 tmp;
10670
10671   if (unformat (input, "l2"))
10672     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10673   else if (unformat (input, "%d", &tmp))
10674     *result = tmp;
10675   else
10676     return 0;
10677   return 1;
10678 }
10679
10680 static int
10681 api_vxlan_add_del_tunnel (vat_main_t * vam)
10682 {
10683   unformat_input_t *line_input = vam->input;
10684   vl_api_vxlan_add_del_tunnel_t *mp;
10685   ip46_address_t src, dst;
10686   u8 is_add = 1;
10687   u8 ipv4_set = 0, ipv6_set = 0;
10688   u8 src_set = 0;
10689   u8 dst_set = 0;
10690   u8 grp_set = 0;
10691   u32 mcast_sw_if_index = ~0;
10692   u32 encap_vrf_id = 0;
10693   u32 decap_next_index = ~0;
10694   u32 vni = 0;
10695   int ret;
10696
10697   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10698   memset (&src, 0, sizeof src);
10699   memset (&dst, 0, sizeof dst);
10700
10701   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10702     {
10703       if (unformat (line_input, "del"))
10704         is_add = 0;
10705       else
10706         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10707         {
10708           ipv4_set = 1;
10709           src_set = 1;
10710         }
10711       else
10712         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10713         {
10714           ipv4_set = 1;
10715           dst_set = 1;
10716         }
10717       else
10718         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10719         {
10720           ipv6_set = 1;
10721           src_set = 1;
10722         }
10723       else
10724         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10725         {
10726           ipv6_set = 1;
10727           dst_set = 1;
10728         }
10729       else if (unformat (line_input, "group %U %U",
10730                          unformat_ip4_address, &dst.ip4,
10731                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10732         {
10733           grp_set = dst_set = 1;
10734           ipv4_set = 1;
10735         }
10736       else if (unformat (line_input, "group %U",
10737                          unformat_ip4_address, &dst.ip4))
10738         {
10739           grp_set = dst_set = 1;
10740           ipv4_set = 1;
10741         }
10742       else if (unformat (line_input, "group %U %U",
10743                          unformat_ip6_address, &dst.ip6,
10744                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10745         {
10746           grp_set = dst_set = 1;
10747           ipv6_set = 1;
10748         }
10749       else if (unformat (line_input, "group %U",
10750                          unformat_ip6_address, &dst.ip6))
10751         {
10752           grp_set = dst_set = 1;
10753           ipv6_set = 1;
10754         }
10755       else
10756         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10757         ;
10758       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10759         ;
10760       else if (unformat (line_input, "decap-next %U",
10761                          unformat_vxlan_decap_next, &decap_next_index))
10762         ;
10763       else if (unformat (line_input, "vni %d", &vni))
10764         ;
10765       else
10766         {
10767           errmsg ("parse error '%U'", format_unformat_error, line_input);
10768           return -99;
10769         }
10770     }
10771
10772   if (src_set == 0)
10773     {
10774       errmsg ("tunnel src address not specified");
10775       return -99;
10776     }
10777   if (dst_set == 0)
10778     {
10779       errmsg ("tunnel dst address not specified");
10780       return -99;
10781     }
10782
10783   if (grp_set && !ip46_address_is_multicast (&dst))
10784     {
10785       errmsg ("tunnel group address not multicast");
10786       return -99;
10787     }
10788   if (grp_set && mcast_sw_if_index == ~0)
10789     {
10790       errmsg ("tunnel nonexistent multicast device");
10791       return -99;
10792     }
10793   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10794     {
10795       errmsg ("tunnel dst address must be unicast");
10796       return -99;
10797     }
10798
10799
10800   if (ipv4_set && ipv6_set)
10801     {
10802       errmsg ("both IPv4 and IPv6 addresses specified");
10803       return -99;
10804     }
10805
10806   if ((vni == 0) || (vni >> 24))
10807     {
10808       errmsg ("vni not specified or out of range");
10809       return -99;
10810     }
10811
10812   M (VXLAN_ADD_DEL_TUNNEL, mp);
10813
10814   if (ipv6_set)
10815     {
10816       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10817       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10818     }
10819   else
10820     {
10821       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10822       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10823     }
10824   mp->encap_vrf_id = ntohl (encap_vrf_id);
10825   mp->decap_next_index = ntohl (decap_next_index);
10826   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10827   mp->vni = ntohl (vni);
10828   mp->is_add = is_add;
10829   mp->is_ipv6 = ipv6_set;
10830
10831   S (mp);
10832   W (ret);
10833   return ret;
10834 }
10835
10836 static void vl_api_vxlan_tunnel_details_t_handler
10837   (vl_api_vxlan_tunnel_details_t * mp)
10838 {
10839   vat_main_t *vam = &vat_main;
10840   ip46_address_t src, dst;
10841
10842   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10843   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10844
10845   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10846          ntohl (mp->sw_if_index),
10847          format_ip46_address, &src, IP46_TYPE_ANY,
10848          format_ip46_address, &dst, IP46_TYPE_ANY,
10849          ntohl (mp->encap_vrf_id),
10850          ntohl (mp->decap_next_index), ntohl (mp->vni),
10851          ntohl (mp->mcast_sw_if_index));
10852 }
10853
10854 static void vl_api_vxlan_tunnel_details_t_handler_json
10855   (vl_api_vxlan_tunnel_details_t * mp)
10856 {
10857   vat_main_t *vam = &vat_main;
10858   vat_json_node_t *node = NULL;
10859
10860   if (VAT_JSON_ARRAY != vam->json_tree.type)
10861     {
10862       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10863       vat_json_init_array (&vam->json_tree);
10864     }
10865   node = vat_json_array_add (&vam->json_tree);
10866
10867   vat_json_init_object (node);
10868   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10869   if (mp->is_ipv6)
10870     {
10871       struct in6_addr ip6;
10872
10873       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10874       vat_json_object_add_ip6 (node, "src_address", ip6);
10875       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10876       vat_json_object_add_ip6 (node, "dst_address", ip6);
10877     }
10878   else
10879     {
10880       struct in_addr ip4;
10881
10882       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10883       vat_json_object_add_ip4 (node, "src_address", ip4);
10884       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10885       vat_json_object_add_ip4 (node, "dst_address", ip4);
10886     }
10887   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10888   vat_json_object_add_uint (node, "decap_next_index",
10889                             ntohl (mp->decap_next_index));
10890   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10891   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10892   vat_json_object_add_uint (node, "mcast_sw_if_index",
10893                             ntohl (mp->mcast_sw_if_index));
10894 }
10895
10896 static int
10897 api_vxlan_tunnel_dump (vat_main_t * vam)
10898 {
10899   unformat_input_t *i = vam->input;
10900   vl_api_vxlan_tunnel_dump_t *mp;
10901   vl_api_control_ping_t *mp_ping;
10902   u32 sw_if_index;
10903   u8 sw_if_index_set = 0;
10904   int ret;
10905
10906   /* Parse args required to build the message */
10907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10908     {
10909       if (unformat (i, "sw_if_index %d", &sw_if_index))
10910         sw_if_index_set = 1;
10911       else
10912         break;
10913     }
10914
10915   if (sw_if_index_set == 0)
10916     {
10917       sw_if_index = ~0;
10918     }
10919
10920   if (!vam->json_output)
10921     {
10922       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10923              "sw_if_index", "src_address", "dst_address",
10924              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10925     }
10926
10927   /* Get list of vxlan-tunnel interfaces */
10928   M (VXLAN_TUNNEL_DUMP, mp);
10929
10930   mp->sw_if_index = htonl (sw_if_index);
10931
10932   S (mp);
10933
10934   /* Use a control ping for synchronization */
10935   M (CONTROL_PING, mp_ping);
10936   S (mp_ping);
10937
10938   W (ret);
10939   return ret;
10940 }
10941
10942 static int
10943 api_gre_add_del_tunnel (vat_main_t * vam)
10944 {
10945   unformat_input_t *line_input = vam->input;
10946   vl_api_gre_add_del_tunnel_t *mp;
10947   ip4_address_t src4, dst4;
10948   u8 is_add = 1;
10949   u8 teb = 0;
10950   u8 src_set = 0;
10951   u8 dst_set = 0;
10952   u32 outer_fib_id = 0;
10953   int ret;
10954
10955   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10956     {
10957       if (unformat (line_input, "del"))
10958         is_add = 0;
10959       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10960         src_set = 1;
10961       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10962         dst_set = 1;
10963       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10964         ;
10965       else if (unformat (line_input, "teb"))
10966         teb = 1;
10967       else
10968         {
10969           errmsg ("parse error '%U'", format_unformat_error, line_input);
10970           return -99;
10971         }
10972     }
10973
10974   if (src_set == 0)
10975     {
10976       errmsg ("tunnel src address not specified");
10977       return -99;
10978     }
10979   if (dst_set == 0)
10980     {
10981       errmsg ("tunnel dst address not specified");
10982       return -99;
10983     }
10984
10985
10986   M (GRE_ADD_DEL_TUNNEL, mp);
10987
10988   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10989   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10990   mp->outer_fib_id = ntohl (outer_fib_id);
10991   mp->is_add = is_add;
10992   mp->teb = teb;
10993
10994   S (mp);
10995   W (ret);
10996   return ret;
10997 }
10998
10999 static void vl_api_gre_tunnel_details_t_handler
11000   (vl_api_gre_tunnel_details_t * mp)
11001 {
11002   vat_main_t *vam = &vat_main;
11003
11004   print (vam->ofp, "%11d%15U%15U%6d%14d",
11005          ntohl (mp->sw_if_index),
11006          format_ip4_address, &mp->src_address,
11007          format_ip4_address, &mp->dst_address,
11008          mp->teb, ntohl (mp->outer_fib_id));
11009 }
11010
11011 static void vl_api_gre_tunnel_details_t_handler_json
11012   (vl_api_gre_tunnel_details_t * mp)
11013 {
11014   vat_main_t *vam = &vat_main;
11015   vat_json_node_t *node = NULL;
11016   struct in_addr ip4;
11017
11018   if (VAT_JSON_ARRAY != vam->json_tree.type)
11019     {
11020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11021       vat_json_init_array (&vam->json_tree);
11022     }
11023   node = vat_json_array_add (&vam->json_tree);
11024
11025   vat_json_init_object (node);
11026   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11027   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11028   vat_json_object_add_ip4 (node, "src_address", ip4);
11029   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11030   vat_json_object_add_ip4 (node, "dst_address", ip4);
11031   vat_json_object_add_uint (node, "teb", mp->teb);
11032   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11033 }
11034
11035 static int
11036 api_gre_tunnel_dump (vat_main_t * vam)
11037 {
11038   unformat_input_t *i = vam->input;
11039   vl_api_gre_tunnel_dump_t *mp;
11040   vl_api_control_ping_t *mp_ping;
11041   u32 sw_if_index;
11042   u8 sw_if_index_set = 0;
11043   int ret;
11044
11045   /* Parse args required to build the message */
11046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11047     {
11048       if (unformat (i, "sw_if_index %d", &sw_if_index))
11049         sw_if_index_set = 1;
11050       else
11051         break;
11052     }
11053
11054   if (sw_if_index_set == 0)
11055     {
11056       sw_if_index = ~0;
11057     }
11058
11059   if (!vam->json_output)
11060     {
11061       print (vam->ofp, "%11s%15s%15s%6s%14s",
11062              "sw_if_index", "src_address", "dst_address", "teb",
11063              "outer_fib_id");
11064     }
11065
11066   /* Get list of gre-tunnel interfaces */
11067   M (GRE_TUNNEL_DUMP, mp);
11068
11069   mp->sw_if_index = htonl (sw_if_index);
11070
11071   S (mp);
11072
11073   /* Use a control ping for synchronization */
11074   M (CONTROL_PING, mp_ping);
11075   S (mp_ping);
11076
11077   W (ret);
11078   return ret;
11079 }
11080
11081 static int
11082 api_l2_fib_clear_table (vat_main_t * vam)
11083 {
11084 //  unformat_input_t * i = vam->input;
11085   vl_api_l2_fib_clear_table_t *mp;
11086   int ret;
11087
11088   M (L2_FIB_CLEAR_TABLE, mp);
11089
11090   S (mp);
11091   W (ret);
11092   return ret;
11093 }
11094
11095 static int
11096 api_l2_interface_efp_filter (vat_main_t * vam)
11097 {
11098   unformat_input_t *i = vam->input;
11099   vl_api_l2_interface_efp_filter_t *mp;
11100   u32 sw_if_index;
11101   u8 enable = 1;
11102   u8 sw_if_index_set = 0;
11103   int ret;
11104
11105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11106     {
11107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11108         sw_if_index_set = 1;
11109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11110         sw_if_index_set = 1;
11111       else if (unformat (i, "enable"))
11112         enable = 1;
11113       else if (unformat (i, "disable"))
11114         enable = 0;
11115       else
11116         {
11117           clib_warning ("parse error '%U'", format_unformat_error, i);
11118           return -99;
11119         }
11120     }
11121
11122   if (sw_if_index_set == 0)
11123     {
11124       errmsg ("missing sw_if_index");
11125       return -99;
11126     }
11127
11128   M (L2_INTERFACE_EFP_FILTER, mp);
11129
11130   mp->sw_if_index = ntohl (sw_if_index);
11131   mp->enable_disable = enable;
11132
11133   S (mp);
11134   W (ret);
11135   return ret;
11136 }
11137
11138 #define foreach_vtr_op                          \
11139 _("disable",  L2_VTR_DISABLED)                  \
11140 _("push-1",  L2_VTR_PUSH_1)                     \
11141 _("push-2",  L2_VTR_PUSH_2)                     \
11142 _("pop-1",  L2_VTR_POP_1)                       \
11143 _("pop-2",  L2_VTR_POP_2)                       \
11144 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11145 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11146 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11147 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11148
11149 static int
11150 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11151 {
11152   unformat_input_t *i = vam->input;
11153   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11154   u32 sw_if_index;
11155   u8 sw_if_index_set = 0;
11156   u8 vtr_op_set = 0;
11157   u32 vtr_op = 0;
11158   u32 push_dot1q = 1;
11159   u32 tag1 = ~0;
11160   u32 tag2 = ~0;
11161   int ret;
11162
11163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11164     {
11165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11166         sw_if_index_set = 1;
11167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11168         sw_if_index_set = 1;
11169       else if (unformat (i, "vtr_op %d", &vtr_op))
11170         vtr_op_set = 1;
11171 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11172       foreach_vtr_op
11173 #undef _
11174         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11175         ;
11176       else if (unformat (i, "tag1 %d", &tag1))
11177         ;
11178       else if (unformat (i, "tag2 %d", &tag2))
11179         ;
11180       else
11181         {
11182           clib_warning ("parse error '%U'", format_unformat_error, i);
11183           return -99;
11184         }
11185     }
11186
11187   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11188     {
11189       errmsg ("missing vtr operation or sw_if_index");
11190       return -99;
11191     }
11192
11193   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11194   mp->sw_if_index = ntohl (sw_if_index);
11195   mp->vtr_op = ntohl (vtr_op);
11196   mp->push_dot1q = ntohl (push_dot1q);
11197   mp->tag1 = ntohl (tag1);
11198   mp->tag2 = ntohl (tag2);
11199
11200   S (mp);
11201   W (ret);
11202   return ret;
11203 }
11204
11205 static int
11206 api_create_vhost_user_if (vat_main_t * vam)
11207 {
11208   unformat_input_t *i = vam->input;
11209   vl_api_create_vhost_user_if_t *mp;
11210   u8 *file_name;
11211   u8 is_server = 0;
11212   u8 file_name_set = 0;
11213   u32 custom_dev_instance = ~0;
11214   u8 hwaddr[6];
11215   u8 use_custom_mac = 0;
11216   u8 *tag = 0;
11217   int ret;
11218
11219   /* Shut up coverity */
11220   memset (hwaddr, 0, sizeof (hwaddr));
11221
11222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11223     {
11224       if (unformat (i, "socket %s", &file_name))
11225         {
11226           file_name_set = 1;
11227         }
11228       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11229         ;
11230       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11231         use_custom_mac = 1;
11232       else if (unformat (i, "server"))
11233         is_server = 1;
11234       else if (unformat (i, "tag %s", &tag))
11235         ;
11236       else
11237         break;
11238     }
11239
11240   if (file_name_set == 0)
11241     {
11242       errmsg ("missing socket file name");
11243       return -99;
11244     }
11245
11246   if (vec_len (file_name) > 255)
11247     {
11248       errmsg ("socket file name too long");
11249       return -99;
11250     }
11251   vec_add1 (file_name, 0);
11252
11253   M (CREATE_VHOST_USER_IF, mp);
11254
11255   mp->is_server = is_server;
11256   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11257   vec_free (file_name);
11258   if (custom_dev_instance != ~0)
11259     {
11260       mp->renumber = 1;
11261       mp->custom_dev_instance = ntohl (custom_dev_instance);
11262     }
11263   mp->use_custom_mac = use_custom_mac;
11264   clib_memcpy (mp->mac_address, hwaddr, 6);
11265   if (tag)
11266     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11267   vec_free (tag);
11268
11269   S (mp);
11270   W (ret);
11271   return ret;
11272 }
11273
11274 static int
11275 api_modify_vhost_user_if (vat_main_t * vam)
11276 {
11277   unformat_input_t *i = vam->input;
11278   vl_api_modify_vhost_user_if_t *mp;
11279   u8 *file_name;
11280   u8 is_server = 0;
11281   u8 file_name_set = 0;
11282   u32 custom_dev_instance = ~0;
11283   u8 sw_if_index_set = 0;
11284   u32 sw_if_index = (u32) ~ 0;
11285   int ret;
11286
11287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11288     {
11289       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11290         sw_if_index_set = 1;
11291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11292         sw_if_index_set = 1;
11293       else if (unformat (i, "socket %s", &file_name))
11294         {
11295           file_name_set = 1;
11296         }
11297       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11298         ;
11299       else if (unformat (i, "server"))
11300         is_server = 1;
11301       else
11302         break;
11303     }
11304
11305   if (sw_if_index_set == 0)
11306     {
11307       errmsg ("missing sw_if_index or interface name");
11308       return -99;
11309     }
11310
11311   if (file_name_set == 0)
11312     {
11313       errmsg ("missing socket file name");
11314       return -99;
11315     }
11316
11317   if (vec_len (file_name) > 255)
11318     {
11319       errmsg ("socket file name too long");
11320       return -99;
11321     }
11322   vec_add1 (file_name, 0);
11323
11324   M (MODIFY_VHOST_USER_IF, mp);
11325
11326   mp->sw_if_index = ntohl (sw_if_index);
11327   mp->is_server = is_server;
11328   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11329   vec_free (file_name);
11330   if (custom_dev_instance != ~0)
11331     {
11332       mp->renumber = 1;
11333       mp->custom_dev_instance = ntohl (custom_dev_instance);
11334     }
11335
11336   S (mp);
11337   W (ret);
11338   return ret;
11339 }
11340
11341 static int
11342 api_delete_vhost_user_if (vat_main_t * vam)
11343 {
11344   unformat_input_t *i = vam->input;
11345   vl_api_delete_vhost_user_if_t *mp;
11346   u32 sw_if_index = ~0;
11347   u8 sw_if_index_set = 0;
11348   int ret;
11349
11350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11351     {
11352       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11353         sw_if_index_set = 1;
11354       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11355         sw_if_index_set = 1;
11356       else
11357         break;
11358     }
11359
11360   if (sw_if_index_set == 0)
11361     {
11362       errmsg ("missing sw_if_index or interface name");
11363       return -99;
11364     }
11365
11366
11367   M (DELETE_VHOST_USER_IF, mp);
11368
11369   mp->sw_if_index = ntohl (sw_if_index);
11370
11371   S (mp);
11372   W (ret);
11373   return ret;
11374 }
11375
11376 static void vl_api_sw_interface_vhost_user_details_t_handler
11377   (vl_api_sw_interface_vhost_user_details_t * mp)
11378 {
11379   vat_main_t *vam = &vat_main;
11380
11381   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11382          (char *) mp->interface_name,
11383          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11384          clib_net_to_host_u64 (mp->features), mp->is_server,
11385          ntohl (mp->num_regions), (char *) mp->sock_filename);
11386   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11387 }
11388
11389 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11390   (vl_api_sw_interface_vhost_user_details_t * mp)
11391 {
11392   vat_main_t *vam = &vat_main;
11393   vat_json_node_t *node = NULL;
11394
11395   if (VAT_JSON_ARRAY != vam->json_tree.type)
11396     {
11397       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11398       vat_json_init_array (&vam->json_tree);
11399     }
11400   node = vat_json_array_add (&vam->json_tree);
11401
11402   vat_json_init_object (node);
11403   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11404   vat_json_object_add_string_copy (node, "interface_name",
11405                                    mp->interface_name);
11406   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11407                             ntohl (mp->virtio_net_hdr_sz));
11408   vat_json_object_add_uint (node, "features",
11409                             clib_net_to_host_u64 (mp->features));
11410   vat_json_object_add_uint (node, "is_server", mp->is_server);
11411   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11412   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11413   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11414 }
11415
11416 static int
11417 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11418 {
11419   vl_api_sw_interface_vhost_user_dump_t *mp;
11420   vl_api_control_ping_t *mp_ping;
11421   int ret;
11422   print (vam->ofp,
11423          "Interface name           idx hdr_sz features server regions filename");
11424
11425   /* Get list of vhost-user interfaces */
11426   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11427   S (mp);
11428
11429   /* Use a control ping for synchronization */
11430   M (CONTROL_PING, mp_ping);
11431   S (mp_ping);
11432
11433   W (ret);
11434   return ret;
11435 }
11436
11437 static int
11438 api_show_version (vat_main_t * vam)
11439 {
11440   vl_api_show_version_t *mp;
11441   int ret;
11442
11443   M (SHOW_VERSION, mp);
11444
11445   S (mp);
11446   W (ret);
11447   return ret;
11448 }
11449
11450
11451 static int
11452 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11453 {
11454   unformat_input_t *line_input = vam->input;
11455   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11456   ip4_address_t local4, remote4;
11457   ip6_address_t local6, remote6;
11458   u8 is_add = 1;
11459   u8 ipv4_set = 0, ipv6_set = 0;
11460   u8 local_set = 0;
11461   u8 remote_set = 0;
11462   u32 encap_vrf_id = 0;
11463   u32 decap_vrf_id = 0;
11464   u8 protocol = ~0;
11465   u32 vni;
11466   u8 vni_set = 0;
11467   int ret;
11468
11469   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11470     {
11471       if (unformat (line_input, "del"))
11472         is_add = 0;
11473       else if (unformat (line_input, "local %U",
11474                          unformat_ip4_address, &local4))
11475         {
11476           local_set = 1;
11477           ipv4_set = 1;
11478         }
11479       else if (unformat (line_input, "remote %U",
11480                          unformat_ip4_address, &remote4))
11481         {
11482           remote_set = 1;
11483           ipv4_set = 1;
11484         }
11485       else if (unformat (line_input, "local %U",
11486                          unformat_ip6_address, &local6))
11487         {
11488           local_set = 1;
11489           ipv6_set = 1;
11490         }
11491       else if (unformat (line_input, "remote %U",
11492                          unformat_ip6_address, &remote6))
11493         {
11494           remote_set = 1;
11495           ipv6_set = 1;
11496         }
11497       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11498         ;
11499       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11500         ;
11501       else if (unformat (line_input, "vni %d", &vni))
11502         vni_set = 1;
11503       else if (unformat (line_input, "next-ip4"))
11504         protocol = 1;
11505       else if (unformat (line_input, "next-ip6"))
11506         protocol = 2;
11507       else if (unformat (line_input, "next-ethernet"))
11508         protocol = 3;
11509       else if (unformat (line_input, "next-nsh"))
11510         protocol = 4;
11511       else
11512         {
11513           errmsg ("parse error '%U'", format_unformat_error, line_input);
11514           return -99;
11515         }
11516     }
11517
11518   if (local_set == 0)
11519     {
11520       errmsg ("tunnel local address not specified");
11521       return -99;
11522     }
11523   if (remote_set == 0)
11524     {
11525       errmsg ("tunnel remote address not specified");
11526       return -99;
11527     }
11528   if (ipv4_set && ipv6_set)
11529     {
11530       errmsg ("both IPv4 and IPv6 addresses specified");
11531       return -99;
11532     }
11533
11534   if (vni_set == 0)
11535     {
11536       errmsg ("vni not specified");
11537       return -99;
11538     }
11539
11540   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11541
11542
11543   if (ipv6_set)
11544     {
11545       clib_memcpy (&mp->local, &local6, sizeof (local6));
11546       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11547     }
11548   else
11549     {
11550       clib_memcpy (&mp->local, &local4, sizeof (local4));
11551       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11552     }
11553
11554   mp->encap_vrf_id = ntohl (encap_vrf_id);
11555   mp->decap_vrf_id = ntohl (decap_vrf_id);
11556   mp->protocol = protocol;
11557   mp->vni = ntohl (vni);
11558   mp->is_add = is_add;
11559   mp->is_ipv6 = ipv6_set;
11560
11561   S (mp);
11562   W (ret);
11563   return ret;
11564 }
11565
11566 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11567   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11568 {
11569   vat_main_t *vam = &vat_main;
11570
11571   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11572          ntohl (mp->sw_if_index),
11573          format_ip46_address, &(mp->local[0]),
11574          format_ip46_address, &(mp->remote[0]),
11575          ntohl (mp->vni),
11576          ntohl (mp->protocol),
11577          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11578 }
11579
11580 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11581   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11582 {
11583   vat_main_t *vam = &vat_main;
11584   vat_json_node_t *node = NULL;
11585   struct in_addr ip4;
11586   struct in6_addr ip6;
11587
11588   if (VAT_JSON_ARRAY != vam->json_tree.type)
11589     {
11590       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11591       vat_json_init_array (&vam->json_tree);
11592     }
11593   node = vat_json_array_add (&vam->json_tree);
11594
11595   vat_json_init_object (node);
11596   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11597   if (mp->is_ipv6)
11598     {
11599       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11600       vat_json_object_add_ip6 (node, "local", ip6);
11601       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11602       vat_json_object_add_ip6 (node, "remote", ip6);
11603     }
11604   else
11605     {
11606       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11607       vat_json_object_add_ip4 (node, "local", ip4);
11608       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11609       vat_json_object_add_ip4 (node, "remote", ip4);
11610     }
11611   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11612   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11613   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11614   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11615   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11616 }
11617
11618 static int
11619 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11620 {
11621   unformat_input_t *i = vam->input;
11622   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11623   vl_api_control_ping_t *mp_ping;
11624   u32 sw_if_index;
11625   u8 sw_if_index_set = 0;
11626   int ret;
11627
11628   /* Parse args required to build the message */
11629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11630     {
11631       if (unformat (i, "sw_if_index %d", &sw_if_index))
11632         sw_if_index_set = 1;
11633       else
11634         break;
11635     }
11636
11637   if (sw_if_index_set == 0)
11638     {
11639       sw_if_index = ~0;
11640     }
11641
11642   if (!vam->json_output)
11643     {
11644       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11645              "sw_if_index", "local", "remote", "vni",
11646              "protocol", "encap_vrf_id", "decap_vrf_id");
11647     }
11648
11649   /* Get list of vxlan-tunnel interfaces */
11650   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11651
11652   mp->sw_if_index = htonl (sw_if_index);
11653
11654   S (mp);
11655
11656   /* Use a control ping for synchronization */
11657   M (CONTROL_PING, mp_ping);
11658   S (mp_ping);
11659
11660   W (ret);
11661   return ret;
11662 }
11663
11664 u8 *
11665 format_l2_fib_mac_address (u8 * s, va_list * args)
11666 {
11667   u8 *a = va_arg (*args, u8 *);
11668
11669   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11670                  a[2], a[3], a[4], a[5], a[6], a[7]);
11671 }
11672
11673 static void vl_api_l2_fib_table_entry_t_handler
11674   (vl_api_l2_fib_table_entry_t * mp)
11675 {
11676   vat_main_t *vam = &vat_main;
11677
11678   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11679          "       %d       %d     %d",
11680          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11681          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11682          mp->bvi_mac);
11683 }
11684
11685 static void vl_api_l2_fib_table_entry_t_handler_json
11686   (vl_api_l2_fib_table_entry_t * mp)
11687 {
11688   vat_main_t *vam = &vat_main;
11689   vat_json_node_t *node = NULL;
11690
11691   if (VAT_JSON_ARRAY != vam->json_tree.type)
11692     {
11693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11694       vat_json_init_array (&vam->json_tree);
11695     }
11696   node = vat_json_array_add (&vam->json_tree);
11697
11698   vat_json_init_object (node);
11699   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11700   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11701   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11702   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11703   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11704   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11705 }
11706
11707 static int
11708 api_l2_fib_table_dump (vat_main_t * vam)
11709 {
11710   unformat_input_t *i = vam->input;
11711   vl_api_l2_fib_table_dump_t *mp;
11712   vl_api_control_ping_t *mp_ping;
11713   u32 bd_id;
11714   u8 bd_id_set = 0;
11715   int ret;
11716
11717   /* Parse args required to build the message */
11718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11719     {
11720       if (unformat (i, "bd_id %d", &bd_id))
11721         bd_id_set = 1;
11722       else
11723         break;
11724     }
11725
11726   if (bd_id_set == 0)
11727     {
11728       errmsg ("missing bridge domain");
11729       return -99;
11730     }
11731
11732   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11733
11734   /* Get list of l2 fib entries */
11735   M (L2_FIB_TABLE_DUMP, mp);
11736
11737   mp->bd_id = ntohl (bd_id);
11738   S (mp);
11739
11740   /* Use a control ping for synchronization */
11741   M (CONTROL_PING, mp_ping);
11742   S (mp_ping);
11743
11744   W (ret);
11745   return ret;
11746 }
11747
11748
11749 static int
11750 api_interface_name_renumber (vat_main_t * vam)
11751 {
11752   unformat_input_t *line_input = vam->input;
11753   vl_api_interface_name_renumber_t *mp;
11754   u32 sw_if_index = ~0;
11755   u32 new_show_dev_instance = ~0;
11756   int ret;
11757
11758   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11759     {
11760       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11761                     &sw_if_index))
11762         ;
11763       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11764         ;
11765       else if (unformat (line_input, "new_show_dev_instance %d",
11766                          &new_show_dev_instance))
11767         ;
11768       else
11769         break;
11770     }
11771
11772   if (sw_if_index == ~0)
11773     {
11774       errmsg ("missing interface name or sw_if_index");
11775       return -99;
11776     }
11777
11778   if (new_show_dev_instance == ~0)
11779     {
11780       errmsg ("missing new_show_dev_instance");
11781       return -99;
11782     }
11783
11784   M (INTERFACE_NAME_RENUMBER, mp);
11785
11786   mp->sw_if_index = ntohl (sw_if_index);
11787   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11788
11789   S (mp);
11790   W (ret);
11791   return ret;
11792 }
11793
11794 static int
11795 api_want_ip4_arp_events (vat_main_t * vam)
11796 {
11797   unformat_input_t *line_input = vam->input;
11798   vl_api_want_ip4_arp_events_t *mp;
11799   ip4_address_t address;
11800   int address_set = 0;
11801   u32 enable_disable = 1;
11802   int ret;
11803
11804   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11805     {
11806       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11807         address_set = 1;
11808       else if (unformat (line_input, "del"))
11809         enable_disable = 0;
11810       else
11811         break;
11812     }
11813
11814   if (address_set == 0)
11815     {
11816       errmsg ("missing addresses");
11817       return -99;
11818     }
11819
11820   M (WANT_IP4_ARP_EVENTS, mp);
11821   mp->enable_disable = enable_disable;
11822   mp->pid = getpid ();
11823   mp->address = address.as_u32;
11824
11825   S (mp);
11826   W (ret);
11827   return ret;
11828 }
11829
11830 static int
11831 api_want_ip6_nd_events (vat_main_t * vam)
11832 {
11833   unformat_input_t *line_input = vam->input;
11834   vl_api_want_ip6_nd_events_t *mp;
11835   ip6_address_t address;
11836   int address_set = 0;
11837   u32 enable_disable = 1;
11838   int ret;
11839
11840   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11841     {
11842       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11843         address_set = 1;
11844       else if (unformat (line_input, "del"))
11845         enable_disable = 0;
11846       else
11847         break;
11848     }
11849
11850   if (address_set == 0)
11851     {
11852       errmsg ("missing addresses");
11853       return -99;
11854     }
11855
11856   M (WANT_IP6_ND_EVENTS, mp);
11857   mp->enable_disable = enable_disable;
11858   mp->pid = getpid ();
11859   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11860
11861   S (mp);
11862   W (ret);
11863   return ret;
11864 }
11865
11866 static int
11867 api_input_acl_set_interface (vat_main_t * vam)
11868 {
11869   unformat_input_t *i = vam->input;
11870   vl_api_input_acl_set_interface_t *mp;
11871   u32 sw_if_index;
11872   int sw_if_index_set;
11873   u32 ip4_table_index = ~0;
11874   u32 ip6_table_index = ~0;
11875   u32 l2_table_index = ~0;
11876   u8 is_add = 1;
11877   int ret;
11878
11879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11880     {
11881       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11882         sw_if_index_set = 1;
11883       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11884         sw_if_index_set = 1;
11885       else if (unformat (i, "del"))
11886         is_add = 0;
11887       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11888         ;
11889       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11890         ;
11891       else if (unformat (i, "l2-table %d", &l2_table_index))
11892         ;
11893       else
11894         {
11895           clib_warning ("parse error '%U'", format_unformat_error, i);
11896           return -99;
11897         }
11898     }
11899
11900   if (sw_if_index_set == 0)
11901     {
11902       errmsg ("missing interface name or sw_if_index");
11903       return -99;
11904     }
11905
11906   M (INPUT_ACL_SET_INTERFACE, mp);
11907
11908   mp->sw_if_index = ntohl (sw_if_index);
11909   mp->ip4_table_index = ntohl (ip4_table_index);
11910   mp->ip6_table_index = ntohl (ip6_table_index);
11911   mp->l2_table_index = ntohl (l2_table_index);
11912   mp->is_add = is_add;
11913
11914   S (mp);
11915   W (ret);
11916   return ret;
11917 }
11918
11919 static int
11920 api_ip_address_dump (vat_main_t * vam)
11921 {
11922   unformat_input_t *i = vam->input;
11923   vl_api_ip_address_dump_t *mp;
11924   vl_api_control_ping_t *mp_ping;
11925   u32 sw_if_index = ~0;
11926   u8 sw_if_index_set = 0;
11927   u8 ipv4_set = 0;
11928   u8 ipv6_set = 0;
11929   int ret;
11930
11931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11932     {
11933       if (unformat (i, "sw_if_index %d", &sw_if_index))
11934         sw_if_index_set = 1;
11935       else
11936         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11937         sw_if_index_set = 1;
11938       else if (unformat (i, "ipv4"))
11939         ipv4_set = 1;
11940       else if (unformat (i, "ipv6"))
11941         ipv6_set = 1;
11942       else
11943         break;
11944     }
11945
11946   if (ipv4_set && ipv6_set)
11947     {
11948       errmsg ("ipv4 and ipv6 flags cannot be both set");
11949       return -99;
11950     }
11951
11952   if ((!ipv4_set) && (!ipv6_set))
11953     {
11954       errmsg ("no ipv4 nor ipv6 flag set");
11955       return -99;
11956     }
11957
11958   if (sw_if_index_set == 0)
11959     {
11960       errmsg ("missing interface name or sw_if_index");
11961       return -99;
11962     }
11963
11964   vam->current_sw_if_index = sw_if_index;
11965   vam->is_ipv6 = ipv6_set;
11966
11967   M (IP_ADDRESS_DUMP, mp);
11968   mp->sw_if_index = ntohl (sw_if_index);
11969   mp->is_ipv6 = ipv6_set;
11970   S (mp);
11971
11972   /* Use a control ping for synchronization */
11973   M (CONTROL_PING, mp_ping);
11974   S (mp_ping);
11975
11976   W (ret);
11977   return ret;
11978 }
11979
11980 static int
11981 api_ip_dump (vat_main_t * vam)
11982 {
11983   vl_api_ip_dump_t *mp;
11984   vl_api_control_ping_t *mp_ping;
11985   unformat_input_t *in = vam->input;
11986   int ipv4_set = 0;
11987   int ipv6_set = 0;
11988   int is_ipv6;
11989   int i;
11990   int ret;
11991
11992   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11993     {
11994       if (unformat (in, "ipv4"))
11995         ipv4_set = 1;
11996       else if (unformat (in, "ipv6"))
11997         ipv6_set = 1;
11998       else
11999         break;
12000     }
12001
12002   if (ipv4_set && ipv6_set)
12003     {
12004       errmsg ("ipv4 and ipv6 flags cannot be both set");
12005       return -99;
12006     }
12007
12008   if ((!ipv4_set) && (!ipv6_set))
12009     {
12010       errmsg ("no ipv4 nor ipv6 flag set");
12011       return -99;
12012     }
12013
12014   is_ipv6 = ipv6_set;
12015   vam->is_ipv6 = is_ipv6;
12016
12017   /* free old data */
12018   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12019     {
12020       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12021     }
12022   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12023
12024   M (IP_DUMP, mp);
12025   mp->is_ipv6 = ipv6_set;
12026   S (mp);
12027
12028   /* Use a control ping for synchronization */
12029   M (CONTROL_PING, mp_ping);
12030   S (mp_ping);
12031
12032   W (ret);
12033   return ret;
12034 }
12035
12036 static int
12037 api_ipsec_spd_add_del (vat_main_t * vam)
12038 {
12039   unformat_input_t *i = vam->input;
12040   vl_api_ipsec_spd_add_del_t *mp;
12041   u32 spd_id = ~0;
12042   u8 is_add = 1;
12043   int ret;
12044
12045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12046     {
12047       if (unformat (i, "spd_id %d", &spd_id))
12048         ;
12049       else if (unformat (i, "del"))
12050         is_add = 0;
12051       else
12052         {
12053           clib_warning ("parse error '%U'", format_unformat_error, i);
12054           return -99;
12055         }
12056     }
12057   if (spd_id == ~0)
12058     {
12059       errmsg ("spd_id must be set");
12060       return -99;
12061     }
12062
12063   M (IPSEC_SPD_ADD_DEL, mp);
12064
12065   mp->spd_id = ntohl (spd_id);
12066   mp->is_add = is_add;
12067
12068   S (mp);
12069   W (ret);
12070   return ret;
12071 }
12072
12073 static int
12074 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12075 {
12076   unformat_input_t *i = vam->input;
12077   vl_api_ipsec_interface_add_del_spd_t *mp;
12078   u32 sw_if_index;
12079   u8 sw_if_index_set = 0;
12080   u32 spd_id = (u32) ~ 0;
12081   u8 is_add = 1;
12082   int ret;
12083
12084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12085     {
12086       if (unformat (i, "del"))
12087         is_add = 0;
12088       else if (unformat (i, "spd_id %d", &spd_id))
12089         ;
12090       else
12091         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12092         sw_if_index_set = 1;
12093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12094         sw_if_index_set = 1;
12095       else
12096         {
12097           clib_warning ("parse error '%U'", format_unformat_error, i);
12098           return -99;
12099         }
12100
12101     }
12102
12103   if (spd_id == (u32) ~ 0)
12104     {
12105       errmsg ("spd_id must be set");
12106       return -99;
12107     }
12108
12109   if (sw_if_index_set == 0)
12110     {
12111       errmsg ("missing interface name or sw_if_index");
12112       return -99;
12113     }
12114
12115   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12116
12117   mp->spd_id = ntohl (spd_id);
12118   mp->sw_if_index = ntohl (sw_if_index);
12119   mp->is_add = is_add;
12120
12121   S (mp);
12122   W (ret);
12123   return ret;
12124 }
12125
12126 static int
12127 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12128 {
12129   unformat_input_t *i = vam->input;
12130   vl_api_ipsec_spd_add_del_entry_t *mp;
12131   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12132   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12133   i32 priority = 0;
12134   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12135   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12136   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12137   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12138   int ret;
12139
12140   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12141   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12142   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12143   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12144   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12145   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12146
12147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12148     {
12149       if (unformat (i, "del"))
12150         is_add = 0;
12151       if (unformat (i, "outbound"))
12152         is_outbound = 1;
12153       if (unformat (i, "inbound"))
12154         is_outbound = 0;
12155       else if (unformat (i, "spd_id %d", &spd_id))
12156         ;
12157       else if (unformat (i, "sa_id %d", &sa_id))
12158         ;
12159       else if (unformat (i, "priority %d", &priority))
12160         ;
12161       else if (unformat (i, "protocol %d", &protocol))
12162         ;
12163       else if (unformat (i, "lport_start %d", &lport_start))
12164         ;
12165       else if (unformat (i, "lport_stop %d", &lport_stop))
12166         ;
12167       else if (unformat (i, "rport_start %d", &rport_start))
12168         ;
12169       else if (unformat (i, "rport_stop %d", &rport_stop))
12170         ;
12171       else
12172         if (unformat
12173             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12174         {
12175           is_ipv6 = 0;
12176           is_ip_any = 0;
12177         }
12178       else
12179         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12180         {
12181           is_ipv6 = 0;
12182           is_ip_any = 0;
12183         }
12184       else
12185         if (unformat
12186             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12187         {
12188           is_ipv6 = 0;
12189           is_ip_any = 0;
12190         }
12191       else
12192         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12193         {
12194           is_ipv6 = 0;
12195           is_ip_any = 0;
12196         }
12197       else
12198         if (unformat
12199             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12200         {
12201           is_ipv6 = 1;
12202           is_ip_any = 0;
12203         }
12204       else
12205         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12206         {
12207           is_ipv6 = 1;
12208           is_ip_any = 0;
12209         }
12210       else
12211         if (unformat
12212             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12213         {
12214           is_ipv6 = 1;
12215           is_ip_any = 0;
12216         }
12217       else
12218         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12219         {
12220           is_ipv6 = 1;
12221           is_ip_any = 0;
12222         }
12223       else
12224         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12225         {
12226           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12227             {
12228               clib_warning ("unsupported action: 'resolve'");
12229               return -99;
12230             }
12231         }
12232       else
12233         {
12234           clib_warning ("parse error '%U'", format_unformat_error, i);
12235           return -99;
12236         }
12237
12238     }
12239
12240   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12241
12242   mp->spd_id = ntohl (spd_id);
12243   mp->priority = ntohl (priority);
12244   mp->is_outbound = is_outbound;
12245
12246   mp->is_ipv6 = is_ipv6;
12247   if (is_ipv6 || is_ip_any)
12248     {
12249       clib_memcpy (mp->remote_address_start, &raddr6_start,
12250                    sizeof (ip6_address_t));
12251       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12252                    sizeof (ip6_address_t));
12253       clib_memcpy (mp->local_address_start, &laddr6_start,
12254                    sizeof (ip6_address_t));
12255       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12256                    sizeof (ip6_address_t));
12257     }
12258   else
12259     {
12260       clib_memcpy (mp->remote_address_start, &raddr4_start,
12261                    sizeof (ip4_address_t));
12262       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12263                    sizeof (ip4_address_t));
12264       clib_memcpy (mp->local_address_start, &laddr4_start,
12265                    sizeof (ip4_address_t));
12266       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12267                    sizeof (ip4_address_t));
12268     }
12269   mp->protocol = (u8) protocol;
12270   mp->local_port_start = ntohs ((u16) lport_start);
12271   mp->local_port_stop = ntohs ((u16) lport_stop);
12272   mp->remote_port_start = ntohs ((u16) rport_start);
12273   mp->remote_port_stop = ntohs ((u16) rport_stop);
12274   mp->policy = (u8) policy;
12275   mp->sa_id = ntohl (sa_id);
12276   mp->is_add = is_add;
12277   mp->is_ip_any = is_ip_any;
12278   S (mp);
12279   W (ret);
12280   return ret;
12281 }
12282
12283 static int
12284 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12285 {
12286   unformat_input_t *i = vam->input;
12287   vl_api_ipsec_sad_add_del_entry_t *mp;
12288   u32 sad_id = 0, spi = 0;
12289   u8 *ck = 0, *ik = 0;
12290   u8 is_add = 1;
12291
12292   u8 protocol = IPSEC_PROTOCOL_AH;
12293   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12294   u32 crypto_alg = 0, integ_alg = 0;
12295   ip4_address_t tun_src4;
12296   ip4_address_t tun_dst4;
12297   ip6_address_t tun_src6;
12298   ip6_address_t tun_dst6;
12299   int ret;
12300
12301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12302     {
12303       if (unformat (i, "del"))
12304         is_add = 0;
12305       else if (unformat (i, "sad_id %d", &sad_id))
12306         ;
12307       else if (unformat (i, "spi %d", &spi))
12308         ;
12309       else if (unformat (i, "esp"))
12310         protocol = IPSEC_PROTOCOL_ESP;
12311       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12312         {
12313           is_tunnel = 1;
12314           is_tunnel_ipv6 = 0;
12315         }
12316       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12317         {
12318           is_tunnel = 1;
12319           is_tunnel_ipv6 = 0;
12320         }
12321       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12322         {
12323           is_tunnel = 1;
12324           is_tunnel_ipv6 = 1;
12325         }
12326       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12327         {
12328           is_tunnel = 1;
12329           is_tunnel_ipv6 = 1;
12330         }
12331       else
12332         if (unformat
12333             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12334         {
12335           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12336               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12337             {
12338               clib_warning ("unsupported crypto-alg: '%U'",
12339                             format_ipsec_crypto_alg, crypto_alg);
12340               return -99;
12341             }
12342         }
12343       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12344         ;
12345       else
12346         if (unformat
12347             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12348         {
12349           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12350               integ_alg >= IPSEC_INTEG_N_ALG)
12351             {
12352               clib_warning ("unsupported integ-alg: '%U'",
12353                             format_ipsec_integ_alg, integ_alg);
12354               return -99;
12355             }
12356         }
12357       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12358         ;
12359       else
12360         {
12361           clib_warning ("parse error '%U'", format_unformat_error, i);
12362           return -99;
12363         }
12364
12365     }
12366
12367   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12368
12369   mp->sad_id = ntohl (sad_id);
12370   mp->is_add = is_add;
12371   mp->protocol = protocol;
12372   mp->spi = ntohl (spi);
12373   mp->is_tunnel = is_tunnel;
12374   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12375   mp->crypto_algorithm = crypto_alg;
12376   mp->integrity_algorithm = integ_alg;
12377   mp->crypto_key_length = vec_len (ck);
12378   mp->integrity_key_length = vec_len (ik);
12379
12380   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12381     mp->crypto_key_length = sizeof (mp->crypto_key);
12382
12383   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12384     mp->integrity_key_length = sizeof (mp->integrity_key);
12385
12386   if (ck)
12387     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12388   if (ik)
12389     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12390
12391   if (is_tunnel)
12392     {
12393       if (is_tunnel_ipv6)
12394         {
12395           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12396                        sizeof (ip6_address_t));
12397           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12398                        sizeof (ip6_address_t));
12399         }
12400       else
12401         {
12402           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12403                        sizeof (ip4_address_t));
12404           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12405                        sizeof (ip4_address_t));
12406         }
12407     }
12408
12409   S (mp);
12410   W (ret);
12411   return ret;
12412 }
12413
12414 static int
12415 api_ipsec_sa_set_key (vat_main_t * vam)
12416 {
12417   unformat_input_t *i = vam->input;
12418   vl_api_ipsec_sa_set_key_t *mp;
12419   u32 sa_id;
12420   u8 *ck = 0, *ik = 0;
12421   int ret;
12422
12423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12424     {
12425       if (unformat (i, "sa_id %d", &sa_id))
12426         ;
12427       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12428         ;
12429       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12430         ;
12431       else
12432         {
12433           clib_warning ("parse error '%U'", format_unformat_error, i);
12434           return -99;
12435         }
12436     }
12437
12438   M (IPSEC_SA_SET_KEY, mp);
12439
12440   mp->sa_id = ntohl (sa_id);
12441   mp->crypto_key_length = vec_len (ck);
12442   mp->integrity_key_length = vec_len (ik);
12443
12444   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12445     mp->crypto_key_length = sizeof (mp->crypto_key);
12446
12447   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12448     mp->integrity_key_length = sizeof (mp->integrity_key);
12449
12450   if (ck)
12451     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12452   if (ik)
12453     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12454
12455   S (mp);
12456   W (ret);
12457   return ret;
12458 }
12459
12460 static int
12461 api_ikev2_profile_add_del (vat_main_t * vam)
12462 {
12463   unformat_input_t *i = vam->input;
12464   vl_api_ikev2_profile_add_del_t *mp;
12465   u8 is_add = 1;
12466   u8 *name = 0;
12467   int ret;
12468
12469   const char *valid_chars = "a-zA-Z0-9_";
12470
12471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12472     {
12473       if (unformat (i, "del"))
12474         is_add = 0;
12475       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12476         vec_add1 (name, 0);
12477       else
12478         {
12479           errmsg ("parse error '%U'", format_unformat_error, i);
12480           return -99;
12481         }
12482     }
12483
12484   if (!vec_len (name))
12485     {
12486       errmsg ("profile name must be specified");
12487       return -99;
12488     }
12489
12490   if (vec_len (name) > 64)
12491     {
12492       errmsg ("profile name too long");
12493       return -99;
12494     }
12495
12496   M (IKEV2_PROFILE_ADD_DEL, mp);
12497
12498   clib_memcpy (mp->name, name, vec_len (name));
12499   mp->is_add = is_add;
12500   vec_free (name);
12501
12502   S (mp);
12503   W (ret);
12504   return ret;
12505 }
12506
12507 static int
12508 api_ikev2_profile_set_auth (vat_main_t * vam)
12509 {
12510   unformat_input_t *i = vam->input;
12511   vl_api_ikev2_profile_set_auth_t *mp;
12512   u8 *name = 0;
12513   u8 *data = 0;
12514   u32 auth_method = 0;
12515   u8 is_hex = 0;
12516   int ret;
12517
12518   const char *valid_chars = "a-zA-Z0-9_";
12519
12520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12521     {
12522       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12523         vec_add1 (name, 0);
12524       else if (unformat (i, "auth_method %U",
12525                          unformat_ikev2_auth_method, &auth_method))
12526         ;
12527       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12528         is_hex = 1;
12529       else if (unformat (i, "auth_data %v", &data))
12530         ;
12531       else
12532         {
12533           errmsg ("parse error '%U'", format_unformat_error, i);
12534           return -99;
12535         }
12536     }
12537
12538   if (!vec_len (name))
12539     {
12540       errmsg ("profile name must be specified");
12541       return -99;
12542     }
12543
12544   if (vec_len (name) > 64)
12545     {
12546       errmsg ("profile name too long");
12547       return -99;
12548     }
12549
12550   if (!vec_len (data))
12551     {
12552       errmsg ("auth_data must be specified");
12553       return -99;
12554     }
12555
12556   if (!auth_method)
12557     {
12558       errmsg ("auth_method must be specified");
12559       return -99;
12560     }
12561
12562   M (IKEV2_PROFILE_SET_AUTH, mp);
12563
12564   mp->is_hex = is_hex;
12565   mp->auth_method = (u8) auth_method;
12566   mp->data_len = vec_len (data);
12567   clib_memcpy (mp->name, name, vec_len (name));
12568   clib_memcpy (mp->data, data, vec_len (data));
12569   vec_free (name);
12570   vec_free (data);
12571
12572   S (mp);
12573   W (ret);
12574   return ret;
12575 }
12576
12577 static int
12578 api_ikev2_profile_set_id (vat_main_t * vam)
12579 {
12580   unformat_input_t *i = vam->input;
12581   vl_api_ikev2_profile_set_id_t *mp;
12582   u8 *name = 0;
12583   u8 *data = 0;
12584   u8 is_local = 0;
12585   u32 id_type = 0;
12586   ip4_address_t ip4;
12587   int ret;
12588
12589   const char *valid_chars = "a-zA-Z0-9_";
12590
12591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12592     {
12593       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12594         vec_add1 (name, 0);
12595       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12596         ;
12597       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12598         {
12599           data = vec_new (u8, 4);
12600           clib_memcpy (data, ip4.as_u8, 4);
12601         }
12602       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12603         ;
12604       else if (unformat (i, "id_data %v", &data))
12605         ;
12606       else if (unformat (i, "local"))
12607         is_local = 1;
12608       else if (unformat (i, "remote"))
12609         is_local = 0;
12610       else
12611         {
12612           errmsg ("parse error '%U'", format_unformat_error, i);
12613           return -99;
12614         }
12615     }
12616
12617   if (!vec_len (name))
12618     {
12619       errmsg ("profile name must be specified");
12620       return -99;
12621     }
12622
12623   if (vec_len (name) > 64)
12624     {
12625       errmsg ("profile name too long");
12626       return -99;
12627     }
12628
12629   if (!vec_len (data))
12630     {
12631       errmsg ("id_data must be specified");
12632       return -99;
12633     }
12634
12635   if (!id_type)
12636     {
12637       errmsg ("id_type must be specified");
12638       return -99;
12639     }
12640
12641   M (IKEV2_PROFILE_SET_ID, mp);
12642
12643   mp->is_local = is_local;
12644   mp->id_type = (u8) id_type;
12645   mp->data_len = vec_len (data);
12646   clib_memcpy (mp->name, name, vec_len (name));
12647   clib_memcpy (mp->data, data, vec_len (data));
12648   vec_free (name);
12649   vec_free (data);
12650
12651   S (mp);
12652   W (ret);
12653   return ret;
12654 }
12655
12656 static int
12657 api_ikev2_profile_set_ts (vat_main_t * vam)
12658 {
12659   unformat_input_t *i = vam->input;
12660   vl_api_ikev2_profile_set_ts_t *mp;
12661   u8 *name = 0;
12662   u8 is_local = 0;
12663   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12664   ip4_address_t start_addr, end_addr;
12665
12666   const char *valid_chars = "a-zA-Z0-9_";
12667   int ret;
12668
12669   start_addr.as_u32 = 0;
12670   end_addr.as_u32 = (u32) ~ 0;
12671
12672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12673     {
12674       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12675         vec_add1 (name, 0);
12676       else if (unformat (i, "protocol %d", &proto))
12677         ;
12678       else if (unformat (i, "start_port %d", &start_port))
12679         ;
12680       else if (unformat (i, "end_port %d", &end_port))
12681         ;
12682       else
12683         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12684         ;
12685       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12686         ;
12687       else if (unformat (i, "local"))
12688         is_local = 1;
12689       else if (unformat (i, "remote"))
12690         is_local = 0;
12691       else
12692         {
12693           errmsg ("parse error '%U'", format_unformat_error, i);
12694           return -99;
12695         }
12696     }
12697
12698   if (!vec_len (name))
12699     {
12700       errmsg ("profile name must be specified");
12701       return -99;
12702     }
12703
12704   if (vec_len (name) > 64)
12705     {
12706       errmsg ("profile name too long");
12707       return -99;
12708     }
12709
12710   M (IKEV2_PROFILE_SET_TS, mp);
12711
12712   mp->is_local = is_local;
12713   mp->proto = (u8) proto;
12714   mp->start_port = (u16) start_port;
12715   mp->end_port = (u16) end_port;
12716   mp->start_addr = start_addr.as_u32;
12717   mp->end_addr = end_addr.as_u32;
12718   clib_memcpy (mp->name, name, vec_len (name));
12719   vec_free (name);
12720
12721   S (mp);
12722   W (ret);
12723   return ret;
12724 }
12725
12726 static int
12727 api_ikev2_set_local_key (vat_main_t * vam)
12728 {
12729   unformat_input_t *i = vam->input;
12730   vl_api_ikev2_set_local_key_t *mp;
12731   u8 *file = 0;
12732   int ret;
12733
12734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12735     {
12736       if (unformat (i, "file %v", &file))
12737         vec_add1 (file, 0);
12738       else
12739         {
12740           errmsg ("parse error '%U'", format_unformat_error, i);
12741           return -99;
12742         }
12743     }
12744
12745   if (!vec_len (file))
12746     {
12747       errmsg ("RSA key file must be specified");
12748       return -99;
12749     }
12750
12751   if (vec_len (file) > 256)
12752     {
12753       errmsg ("file name too long");
12754       return -99;
12755     }
12756
12757   M (IKEV2_SET_LOCAL_KEY, mp);
12758
12759   clib_memcpy (mp->key_file, file, vec_len (file));
12760   vec_free (file);
12761
12762   S (mp);
12763   W (ret);
12764   return ret;
12765 }
12766
12767 static int
12768 api_ikev2_set_responder (vat_main_t * vam)
12769 {
12770   unformat_input_t *i = vam->input;
12771   vl_api_ikev2_set_responder_t *mp;
12772   int ret;
12773   u8 *name = 0;
12774   u32 sw_if_index = ~0;
12775   ip4_address_t address;
12776
12777   const char *valid_chars = "a-zA-Z0-9_";
12778
12779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12780     {
12781       if (unformat
12782           (i, "%U interface %d address %U", unformat_token, valid_chars,
12783            &name, &sw_if_index, unformat_ip4_address, &address))
12784         vec_add1 (name, 0);
12785       else
12786         {
12787           errmsg ("parse error '%U'", format_unformat_error, i);
12788           return -99;
12789         }
12790     }
12791
12792   if (!vec_len (name))
12793     {
12794       errmsg ("profile name must be specified");
12795       return -99;
12796     }
12797
12798   if (vec_len (name) > 64)
12799     {
12800       errmsg ("profile name too long");
12801       return -99;
12802     }
12803
12804   M (IKEV2_SET_RESPONDER, mp);
12805
12806   clib_memcpy (mp->name, name, vec_len (name));
12807   vec_free (name);
12808
12809   mp->sw_if_index = sw_if_index;
12810   clib_memcpy (mp->address, &address, sizeof (address));
12811
12812   S (mp);
12813   W (ret);
12814   return ret;
12815 }
12816
12817 static int
12818 api_ikev2_set_ike_transforms (vat_main_t * vam)
12819 {
12820   unformat_input_t *i = vam->input;
12821   vl_api_ikev2_set_ike_transforms_t *mp;
12822   int ret;
12823   u8 *name = 0;
12824   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12825
12826   const char *valid_chars = "a-zA-Z0-9_";
12827
12828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12829     {
12830       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12831                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12832         vec_add1 (name, 0);
12833       else
12834         {
12835           errmsg ("parse error '%U'", format_unformat_error, i);
12836           return -99;
12837         }
12838     }
12839
12840   if (!vec_len (name))
12841     {
12842       errmsg ("profile name must be specified");
12843       return -99;
12844     }
12845
12846   if (vec_len (name) > 64)
12847     {
12848       errmsg ("profile name too long");
12849       return -99;
12850     }
12851
12852   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12853
12854   clib_memcpy (mp->name, name, vec_len (name));
12855   vec_free (name);
12856   mp->crypto_alg = crypto_alg;
12857   mp->crypto_key_size = crypto_key_size;
12858   mp->integ_alg = integ_alg;
12859   mp->dh_group = dh_group;
12860
12861   S (mp);
12862   W (ret);
12863   return ret;
12864 }
12865
12866
12867 static int
12868 api_ikev2_set_esp_transforms (vat_main_t * vam)
12869 {
12870   unformat_input_t *i = vam->input;
12871   vl_api_ikev2_set_esp_transforms_t *mp;
12872   int ret;
12873   u8 *name = 0;
12874   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12875
12876   const char *valid_chars = "a-zA-Z0-9_";
12877
12878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12879     {
12880       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12881                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12882         vec_add1 (name, 0);
12883       else
12884         {
12885           errmsg ("parse error '%U'", format_unformat_error, i);
12886           return -99;
12887         }
12888     }
12889
12890   if (!vec_len (name))
12891     {
12892       errmsg ("profile name must be specified");
12893       return -99;
12894     }
12895
12896   if (vec_len (name) > 64)
12897     {
12898       errmsg ("profile name too long");
12899       return -99;
12900     }
12901
12902   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12903
12904   clib_memcpy (mp->name, name, vec_len (name));
12905   vec_free (name);
12906   mp->crypto_alg = crypto_alg;
12907   mp->crypto_key_size = crypto_key_size;
12908   mp->integ_alg = integ_alg;
12909   mp->dh_group = dh_group;
12910
12911   S (mp);
12912   W (ret);
12913   return ret;
12914 }
12915
12916 static int
12917 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12918 {
12919   unformat_input_t *i = vam->input;
12920   vl_api_ikev2_set_sa_lifetime_t *mp;
12921   int ret;
12922   u8 *name = 0;
12923   u64 lifetime, lifetime_maxdata;
12924   u32 lifetime_jitter, handover;
12925
12926   const char *valid_chars = "a-zA-Z0-9_";
12927
12928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12929     {
12930       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12931                     &lifetime, &lifetime_jitter, &handover,
12932                     &lifetime_maxdata))
12933         vec_add1 (name, 0);
12934       else
12935         {
12936           errmsg ("parse error '%U'", format_unformat_error, i);
12937           return -99;
12938         }
12939     }
12940
12941   if (!vec_len (name))
12942     {
12943       errmsg ("profile name must be specified");
12944       return -99;
12945     }
12946
12947   if (vec_len (name) > 64)
12948     {
12949       errmsg ("profile name too long");
12950       return -99;
12951     }
12952
12953   M (IKEV2_SET_SA_LIFETIME, mp);
12954
12955   clib_memcpy (mp->name, name, vec_len (name));
12956   vec_free (name);
12957   mp->lifetime = lifetime;
12958   mp->lifetime_jitter = lifetime_jitter;
12959   mp->handover = handover;
12960   mp->lifetime_maxdata = lifetime_maxdata;
12961
12962   S (mp);
12963   W (ret);
12964   return ret;
12965 }
12966
12967 static int
12968 api_ikev2_initiate_sa_init (vat_main_t * vam)
12969 {
12970   unformat_input_t *i = vam->input;
12971   vl_api_ikev2_initiate_sa_init_t *mp;
12972   int ret;
12973   u8 *name = 0;
12974
12975   const char *valid_chars = "a-zA-Z0-9_";
12976
12977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12978     {
12979       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12980         vec_add1 (name, 0);
12981       else
12982         {
12983           errmsg ("parse error '%U'", format_unformat_error, i);
12984           return -99;
12985         }
12986     }
12987
12988   if (!vec_len (name))
12989     {
12990       errmsg ("profile name must be specified");
12991       return -99;
12992     }
12993
12994   if (vec_len (name) > 64)
12995     {
12996       errmsg ("profile name too long");
12997       return -99;
12998     }
12999
13000   M (IKEV2_INITIATE_SA_INIT, mp);
13001
13002   clib_memcpy (mp->name, name, vec_len (name));
13003   vec_free (name);
13004
13005   S (mp);
13006   W (ret);
13007   return ret;
13008 }
13009
13010 static int
13011 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13012 {
13013   unformat_input_t *i = vam->input;
13014   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13015   int ret;
13016   u64 ispi;
13017
13018
13019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13020     {
13021       if (unformat (i, "%lx", &ispi))
13022         ;
13023       else
13024         {
13025           errmsg ("parse error '%U'", format_unformat_error, i);
13026           return -99;
13027         }
13028     }
13029
13030   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13031
13032   mp->ispi = ispi;
13033
13034   S (mp);
13035   W (ret);
13036   return ret;
13037 }
13038
13039 static int
13040 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13041 {
13042   unformat_input_t *i = vam->input;
13043   vl_api_ikev2_initiate_del_child_sa_t *mp;
13044   int ret;
13045   u32 ispi;
13046
13047
13048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13049     {
13050       if (unformat (i, "%x", &ispi))
13051         ;
13052       else
13053         {
13054           errmsg ("parse error '%U'", format_unformat_error, i);
13055           return -99;
13056         }
13057     }
13058
13059   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13060
13061   mp->ispi = ispi;
13062
13063   S (mp);
13064   W (ret);
13065   return ret;
13066 }
13067
13068 static int
13069 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13070 {
13071   unformat_input_t *i = vam->input;
13072   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13073   int ret;
13074   u32 ispi;
13075
13076
13077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13078     {
13079       if (unformat (i, "%x", &ispi))
13080         ;
13081       else
13082         {
13083           errmsg ("parse error '%U'", format_unformat_error, i);
13084           return -99;
13085         }
13086     }
13087
13088   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13089
13090   mp->ispi = ispi;
13091
13092   S (mp);
13093   W (ret);
13094   return ret;
13095 }
13096
13097 /*
13098  * MAP
13099  */
13100 static int
13101 api_map_add_domain (vat_main_t * vam)
13102 {
13103   unformat_input_t *i = vam->input;
13104   vl_api_map_add_domain_t *mp;
13105
13106   ip4_address_t ip4_prefix;
13107   ip6_address_t ip6_prefix;
13108   ip6_address_t ip6_src;
13109   u32 num_m_args = 0;
13110   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13111     0, psid_length = 0;
13112   u8 is_translation = 0;
13113   u32 mtu = 0;
13114   u32 ip6_src_len = 128;
13115   int ret;
13116
13117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13118     {
13119       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13120                     &ip4_prefix, &ip4_prefix_len))
13121         num_m_args++;
13122       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13123                          &ip6_prefix, &ip6_prefix_len))
13124         num_m_args++;
13125       else
13126         if (unformat
13127             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13128              &ip6_src_len))
13129         num_m_args++;
13130       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13131         num_m_args++;
13132       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13133         num_m_args++;
13134       else if (unformat (i, "psid-offset %d", &psid_offset))
13135         num_m_args++;
13136       else if (unformat (i, "psid-len %d", &psid_length))
13137         num_m_args++;
13138       else if (unformat (i, "mtu %d", &mtu))
13139         num_m_args++;
13140       else if (unformat (i, "map-t"))
13141         is_translation = 1;
13142       else
13143         {
13144           clib_warning ("parse error '%U'", format_unformat_error, i);
13145           return -99;
13146         }
13147     }
13148
13149   if (num_m_args < 3)
13150     {
13151       errmsg ("mandatory argument(s) missing");
13152       return -99;
13153     }
13154
13155   /* Construct the API message */
13156   M (MAP_ADD_DOMAIN, mp);
13157
13158   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13159   mp->ip4_prefix_len = ip4_prefix_len;
13160
13161   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13162   mp->ip6_prefix_len = ip6_prefix_len;
13163
13164   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13165   mp->ip6_src_prefix_len = ip6_src_len;
13166
13167   mp->ea_bits_len = ea_bits_len;
13168   mp->psid_offset = psid_offset;
13169   mp->psid_length = psid_length;
13170   mp->is_translation = is_translation;
13171   mp->mtu = htons (mtu);
13172
13173   /* send it... */
13174   S (mp);
13175
13176   /* Wait for a reply, return good/bad news  */
13177   W (ret);
13178   return ret;
13179 }
13180
13181 static int
13182 api_map_del_domain (vat_main_t * vam)
13183 {
13184   unformat_input_t *i = vam->input;
13185   vl_api_map_del_domain_t *mp;
13186
13187   u32 num_m_args = 0;
13188   u32 index;
13189   int ret;
13190
13191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13192     {
13193       if (unformat (i, "index %d", &index))
13194         num_m_args++;
13195       else
13196         {
13197           clib_warning ("parse error '%U'", format_unformat_error, i);
13198           return -99;
13199         }
13200     }
13201
13202   if (num_m_args != 1)
13203     {
13204       errmsg ("mandatory argument(s) missing");
13205       return -99;
13206     }
13207
13208   /* Construct the API message */
13209   M (MAP_DEL_DOMAIN, mp);
13210
13211   mp->index = ntohl (index);
13212
13213   /* send it... */
13214   S (mp);
13215
13216   /* Wait for a reply, return good/bad news  */
13217   W (ret);
13218   return ret;
13219 }
13220
13221 static int
13222 api_map_add_del_rule (vat_main_t * vam)
13223 {
13224   unformat_input_t *i = vam->input;
13225   vl_api_map_add_del_rule_t *mp;
13226   u8 is_add = 1;
13227   ip6_address_t ip6_dst;
13228   u32 num_m_args = 0, index, psid = 0;
13229   int ret;
13230
13231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13232     {
13233       if (unformat (i, "index %d", &index))
13234         num_m_args++;
13235       else if (unformat (i, "psid %d", &psid))
13236         num_m_args++;
13237       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13238         num_m_args++;
13239       else if (unformat (i, "del"))
13240         {
13241           is_add = 0;
13242         }
13243       else
13244         {
13245           clib_warning ("parse error '%U'", format_unformat_error, i);
13246           return -99;
13247         }
13248     }
13249
13250   /* Construct the API message */
13251   M (MAP_ADD_DEL_RULE, mp);
13252
13253   mp->index = ntohl (index);
13254   mp->is_add = is_add;
13255   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13256   mp->psid = ntohs (psid);
13257
13258   /* send it... */
13259   S (mp);
13260
13261   /* Wait for a reply, return good/bad news  */
13262   W (ret);
13263   return ret;
13264 }
13265
13266 static int
13267 api_map_domain_dump (vat_main_t * vam)
13268 {
13269   vl_api_map_domain_dump_t *mp;
13270   vl_api_control_ping_t *mp_ping;
13271   int ret;
13272
13273   /* Construct the API message */
13274   M (MAP_DOMAIN_DUMP, mp);
13275
13276   /* send it... */
13277   S (mp);
13278
13279   /* Use a control ping for synchronization */
13280   M (CONTROL_PING, mp_ping);
13281   S (mp_ping);
13282
13283   W (ret);
13284   return ret;
13285 }
13286
13287 static int
13288 api_map_rule_dump (vat_main_t * vam)
13289 {
13290   unformat_input_t *i = vam->input;
13291   vl_api_map_rule_dump_t *mp;
13292   vl_api_control_ping_t *mp_ping;
13293   u32 domain_index = ~0;
13294   int ret;
13295
13296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13297     {
13298       if (unformat (i, "index %u", &domain_index))
13299         ;
13300       else
13301         break;
13302     }
13303
13304   if (domain_index == ~0)
13305     {
13306       clib_warning ("parse error: domain index expected");
13307       return -99;
13308     }
13309
13310   /* Construct the API message */
13311   M (MAP_RULE_DUMP, mp);
13312
13313   mp->domain_index = htonl (domain_index);
13314
13315   /* send it... */
13316   S (mp);
13317
13318   /* Use a control ping for synchronization */
13319   M (CONTROL_PING, mp_ping);
13320   S (mp_ping);
13321
13322   W (ret);
13323   return ret;
13324 }
13325
13326 static void vl_api_map_add_domain_reply_t_handler
13327   (vl_api_map_add_domain_reply_t * mp)
13328 {
13329   vat_main_t *vam = &vat_main;
13330   i32 retval = ntohl (mp->retval);
13331
13332   if (vam->async_mode)
13333     {
13334       vam->async_errors += (retval < 0);
13335     }
13336   else
13337     {
13338       vam->retval = retval;
13339       vam->result_ready = 1;
13340     }
13341 }
13342
13343 static void vl_api_map_add_domain_reply_t_handler_json
13344   (vl_api_map_add_domain_reply_t * mp)
13345 {
13346   vat_main_t *vam = &vat_main;
13347   vat_json_node_t node;
13348
13349   vat_json_init_object (&node);
13350   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13351   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13352
13353   vat_json_print (vam->ofp, &node);
13354   vat_json_free (&node);
13355
13356   vam->retval = ntohl (mp->retval);
13357   vam->result_ready = 1;
13358 }
13359
13360 static int
13361 api_get_first_msg_id (vat_main_t * vam)
13362 {
13363   vl_api_get_first_msg_id_t *mp;
13364   unformat_input_t *i = vam->input;
13365   u8 *name;
13366   u8 name_set = 0;
13367   int ret;
13368
13369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13370     {
13371       if (unformat (i, "client %s", &name))
13372         name_set = 1;
13373       else
13374         break;
13375     }
13376
13377   if (name_set == 0)
13378     {
13379       errmsg ("missing client name");
13380       return -99;
13381     }
13382   vec_add1 (name, 0);
13383
13384   if (vec_len (name) > 63)
13385     {
13386       errmsg ("client name too long");
13387       return -99;
13388     }
13389
13390   M (GET_FIRST_MSG_ID, mp);
13391   clib_memcpy (mp->name, name, vec_len (name));
13392   S (mp);
13393   W (ret);
13394   return ret;
13395 }
13396
13397 static int
13398 api_cop_interface_enable_disable (vat_main_t * vam)
13399 {
13400   unformat_input_t *line_input = vam->input;
13401   vl_api_cop_interface_enable_disable_t *mp;
13402   u32 sw_if_index = ~0;
13403   u8 enable_disable = 1;
13404   int ret;
13405
13406   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13407     {
13408       if (unformat (line_input, "disable"))
13409         enable_disable = 0;
13410       if (unformat (line_input, "enable"))
13411         enable_disable = 1;
13412       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13413                          vam, &sw_if_index))
13414         ;
13415       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13416         ;
13417       else
13418         break;
13419     }
13420
13421   if (sw_if_index == ~0)
13422     {
13423       errmsg ("missing interface name or sw_if_index");
13424       return -99;
13425     }
13426
13427   /* Construct the API message */
13428   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13429   mp->sw_if_index = ntohl (sw_if_index);
13430   mp->enable_disable = enable_disable;
13431
13432   /* send it... */
13433   S (mp);
13434   /* Wait for the reply */
13435   W (ret);
13436   return ret;
13437 }
13438
13439 static int
13440 api_cop_whitelist_enable_disable (vat_main_t * vam)
13441 {
13442   unformat_input_t *line_input = vam->input;
13443   vl_api_cop_whitelist_enable_disable_t *mp;
13444   u32 sw_if_index = ~0;
13445   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13446   u32 fib_id = 0;
13447   int ret;
13448
13449   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13450     {
13451       if (unformat (line_input, "ip4"))
13452         ip4 = 1;
13453       else if (unformat (line_input, "ip6"))
13454         ip6 = 1;
13455       else if (unformat (line_input, "default"))
13456         default_cop = 1;
13457       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13458                          vam, &sw_if_index))
13459         ;
13460       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13461         ;
13462       else if (unformat (line_input, "fib-id %d", &fib_id))
13463         ;
13464       else
13465         break;
13466     }
13467
13468   if (sw_if_index == ~0)
13469     {
13470       errmsg ("missing interface name or sw_if_index");
13471       return -99;
13472     }
13473
13474   /* Construct the API message */
13475   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13476   mp->sw_if_index = ntohl (sw_if_index);
13477   mp->fib_id = ntohl (fib_id);
13478   mp->ip4 = ip4;
13479   mp->ip6 = ip6;
13480   mp->default_cop = default_cop;
13481
13482   /* send it... */
13483   S (mp);
13484   /* Wait for the reply */
13485   W (ret);
13486   return ret;
13487 }
13488
13489 static int
13490 api_get_node_graph (vat_main_t * vam)
13491 {
13492   vl_api_get_node_graph_t *mp;
13493   int ret;
13494
13495   M (GET_NODE_GRAPH, mp);
13496
13497   /* send it... */
13498   S (mp);
13499   /* Wait for the reply */
13500   W (ret);
13501   return ret;
13502 }
13503
13504 /* *INDENT-OFF* */
13505 /** Used for parsing LISP eids */
13506 typedef CLIB_PACKED(struct{
13507   u8 addr[16];   /**< eid address */
13508   u32 len;       /**< prefix length if IP */
13509   u8 type;      /**< type of eid */
13510 }) lisp_eid_vat_t;
13511 /* *INDENT-ON* */
13512
13513 static uword
13514 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13515 {
13516   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13517
13518   memset (a, 0, sizeof (a[0]));
13519
13520   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13521     {
13522       a->type = 0;              /* ipv4 type */
13523     }
13524   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13525     {
13526       a->type = 1;              /* ipv6 type */
13527     }
13528   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13529     {
13530       a->type = 2;              /* mac type */
13531     }
13532   else
13533     {
13534       return 0;
13535     }
13536
13537   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13538     {
13539       return 0;
13540     }
13541
13542   return 1;
13543 }
13544
13545 static int
13546 lisp_eid_size_vat (u8 type)
13547 {
13548   switch (type)
13549     {
13550     case 0:
13551       return 4;
13552     case 1:
13553       return 16;
13554     case 2:
13555       return 6;
13556     }
13557   return 0;
13558 }
13559
13560 static void
13561 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13562 {
13563   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13564 }
13565
13566 static int
13567 api_lisp_add_del_locator_set (vat_main_t * vam)
13568 {
13569   unformat_input_t *input = vam->input;
13570   vl_api_lisp_add_del_locator_set_t *mp;
13571   u8 is_add = 1;
13572   u8 *locator_set_name = NULL;
13573   u8 locator_set_name_set = 0;
13574   vl_api_local_locator_t locator, *locators = 0;
13575   u32 sw_if_index, priority, weight;
13576   u32 data_len = 0;
13577
13578   int ret;
13579   /* Parse args required to build the message */
13580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13581     {
13582       if (unformat (input, "del"))
13583         {
13584           is_add = 0;
13585         }
13586       else if (unformat (input, "locator-set %s", &locator_set_name))
13587         {
13588           locator_set_name_set = 1;
13589         }
13590       else if (unformat (input, "sw_if_index %u p %u w %u",
13591                          &sw_if_index, &priority, &weight))
13592         {
13593           locator.sw_if_index = htonl (sw_if_index);
13594           locator.priority = priority;
13595           locator.weight = weight;
13596           vec_add1 (locators, locator);
13597         }
13598       else
13599         if (unformat
13600             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13601              &sw_if_index, &priority, &weight))
13602         {
13603           locator.sw_if_index = htonl (sw_if_index);
13604           locator.priority = priority;
13605           locator.weight = weight;
13606           vec_add1 (locators, locator);
13607         }
13608       else
13609         break;
13610     }
13611
13612   if (locator_set_name_set == 0)
13613     {
13614       errmsg ("missing locator-set name");
13615       vec_free (locators);
13616       return -99;
13617     }
13618
13619   if (vec_len (locator_set_name) > 64)
13620     {
13621       errmsg ("locator-set name too long");
13622       vec_free (locator_set_name);
13623       vec_free (locators);
13624       return -99;
13625     }
13626   vec_add1 (locator_set_name, 0);
13627
13628   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13629
13630   /* Construct the API message */
13631   M2 (LISP_ADD_DEL_LOCATOR_SET, mp, data_len);
13632
13633   mp->is_add = is_add;
13634   clib_memcpy (mp->locator_set_name, locator_set_name,
13635                vec_len (locator_set_name));
13636   vec_free (locator_set_name);
13637
13638   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13639   if (locators)
13640     clib_memcpy (mp->locators, locators, data_len);
13641   vec_free (locators);
13642
13643   /* send it... */
13644   S (mp);
13645
13646   /* Wait for a reply... */
13647   W (ret);
13648   return ret;
13649 }
13650
13651 static int
13652 api_lisp_add_del_locator (vat_main_t * vam)
13653 {
13654   unformat_input_t *input = vam->input;
13655   vl_api_lisp_add_del_locator_t *mp;
13656   u32 tmp_if_index = ~0;
13657   u32 sw_if_index = ~0;
13658   u8 sw_if_index_set = 0;
13659   u8 sw_if_index_if_name_set = 0;
13660   u32 priority = ~0;
13661   u8 priority_set = 0;
13662   u32 weight = ~0;
13663   u8 weight_set = 0;
13664   u8 is_add = 1;
13665   u8 *locator_set_name = NULL;
13666   u8 locator_set_name_set = 0;
13667   int ret;
13668
13669   /* Parse args required to build the message */
13670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13671     {
13672       if (unformat (input, "del"))
13673         {
13674           is_add = 0;
13675         }
13676       else if (unformat (input, "locator-set %s", &locator_set_name))
13677         {
13678           locator_set_name_set = 1;
13679         }
13680       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13681                          &tmp_if_index))
13682         {
13683           sw_if_index_if_name_set = 1;
13684           sw_if_index = tmp_if_index;
13685         }
13686       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13687         {
13688           sw_if_index_set = 1;
13689           sw_if_index = tmp_if_index;
13690         }
13691       else if (unformat (input, "p %d", &priority))
13692         {
13693           priority_set = 1;
13694         }
13695       else if (unformat (input, "w %d", &weight))
13696         {
13697           weight_set = 1;
13698         }
13699       else
13700         break;
13701     }
13702
13703   if (locator_set_name_set == 0)
13704     {
13705       errmsg ("missing locator-set name");
13706       return -99;
13707     }
13708
13709   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13710     {
13711       errmsg ("missing sw_if_index");
13712       vec_free (locator_set_name);
13713       return -99;
13714     }
13715
13716   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13717     {
13718       errmsg ("cannot use both params interface name and sw_if_index");
13719       vec_free (locator_set_name);
13720       return -99;
13721     }
13722
13723   if (priority_set == 0)
13724     {
13725       errmsg ("missing locator-set priority");
13726       vec_free (locator_set_name);
13727       return -99;
13728     }
13729
13730   if (weight_set == 0)
13731     {
13732       errmsg ("missing locator-set weight");
13733       vec_free (locator_set_name);
13734       return -99;
13735     }
13736
13737   if (vec_len (locator_set_name) > 64)
13738     {
13739       errmsg ("locator-set name too long");
13740       vec_free (locator_set_name);
13741       return -99;
13742     }
13743   vec_add1 (locator_set_name, 0);
13744
13745   /* Construct the API message */
13746   M (LISP_ADD_DEL_LOCATOR, mp);
13747
13748   mp->is_add = is_add;
13749   mp->sw_if_index = ntohl (sw_if_index);
13750   mp->priority = priority;
13751   mp->weight = weight;
13752   clib_memcpy (mp->locator_set_name, locator_set_name,
13753                vec_len (locator_set_name));
13754   vec_free (locator_set_name);
13755
13756   /* send it... */
13757   S (mp);
13758
13759   /* Wait for a reply... */
13760   W (ret);
13761   return ret;
13762 }
13763
13764 uword
13765 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13766 {
13767   u32 *key_id = va_arg (*args, u32 *);
13768   u8 *s = 0;
13769
13770   if (unformat (input, "%s", &s))
13771     {
13772       if (!strcmp ((char *) s, "sha1"))
13773         key_id[0] = HMAC_SHA_1_96;
13774       else if (!strcmp ((char *) s, "sha256"))
13775         key_id[0] = HMAC_SHA_256_128;
13776       else
13777         {
13778           clib_warning ("invalid key_id: '%s'", s);
13779           key_id[0] = HMAC_NO_KEY;
13780         }
13781     }
13782   else
13783     return 0;
13784
13785   vec_free (s);
13786   return 1;
13787 }
13788
13789 static int
13790 api_lisp_add_del_local_eid (vat_main_t * vam)
13791 {
13792   unformat_input_t *input = vam->input;
13793   vl_api_lisp_add_del_local_eid_t *mp;
13794   u8 is_add = 1;
13795   u8 eid_set = 0;
13796   lisp_eid_vat_t _eid, *eid = &_eid;
13797   u8 *locator_set_name = 0;
13798   u8 locator_set_name_set = 0;
13799   u32 vni = 0;
13800   u16 key_id = 0;
13801   u8 *key = 0;
13802   int ret;
13803
13804   /* Parse args required to build the message */
13805   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13806     {
13807       if (unformat (input, "del"))
13808         {
13809           is_add = 0;
13810         }
13811       else if (unformat (input, "vni %d", &vni))
13812         {
13813           ;
13814         }
13815       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13816         {
13817           eid_set = 1;
13818         }
13819       else if (unformat (input, "locator-set %s", &locator_set_name))
13820         {
13821           locator_set_name_set = 1;
13822         }
13823       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13824         ;
13825       else if (unformat (input, "secret-key %_%v%_", &key))
13826         ;
13827       else
13828         break;
13829     }
13830
13831   if (locator_set_name_set == 0)
13832     {
13833       errmsg ("missing locator-set name");
13834       return -99;
13835     }
13836
13837   if (0 == eid_set)
13838     {
13839       errmsg ("EID address not set!");
13840       vec_free (locator_set_name);
13841       return -99;
13842     }
13843
13844   if (key && (0 == key_id))
13845     {
13846       errmsg ("invalid key_id!");
13847       return -99;
13848     }
13849
13850   if (vec_len (key) > 64)
13851     {
13852       errmsg ("key too long");
13853       vec_free (key);
13854       return -99;
13855     }
13856
13857   if (vec_len (locator_set_name) > 64)
13858     {
13859       errmsg ("locator-set name too long");
13860       vec_free (locator_set_name);
13861       return -99;
13862     }
13863   vec_add1 (locator_set_name, 0);
13864
13865   /* Construct the API message */
13866   M (LISP_ADD_DEL_LOCAL_EID, mp);
13867
13868   mp->is_add = is_add;
13869   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13870   mp->eid_type = eid->type;
13871   mp->prefix_len = eid->len;
13872   mp->vni = clib_host_to_net_u32 (vni);
13873   mp->key_id = clib_host_to_net_u16 (key_id);
13874   clib_memcpy (mp->locator_set_name, locator_set_name,
13875                vec_len (locator_set_name));
13876   clib_memcpy (mp->key, key, vec_len (key));
13877
13878   vec_free (locator_set_name);
13879   vec_free (key);
13880
13881   /* send it... */
13882   S (mp);
13883
13884   /* Wait for a reply... */
13885   W (ret);
13886   return ret;
13887 }
13888
13889 /* *INDENT-OFF* */
13890 /** Used for transferring locators via VPP API */
13891 typedef CLIB_PACKED(struct
13892 {
13893   u8 is_ip4; /**< is locator an IPv4 address? */
13894   u8 priority; /**< locator priority */
13895   u8 weight;   /**< locator weight */
13896   u8 addr[16]; /**< IPv4/IPv6 address */
13897 }) rloc_t;
13898 /* *INDENT-ON* */
13899
13900 static int
13901 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13902 {
13903   u32 dp_table = 0, vni = 0;;
13904   unformat_input_t *input = vam->input;
13905   vl_api_gpe_add_del_fwd_entry_t *mp;
13906   u8 is_add = 1;
13907   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13908   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13909   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13910   u32 action = ~0, w;
13911   ip4_address_t rmt_rloc4, lcl_rloc4;
13912   ip6_address_t rmt_rloc6, lcl_rloc6;
13913   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13914   int ret;
13915
13916   memset (&rloc, 0, sizeof (rloc));
13917
13918   /* Parse args required to build the message */
13919   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13920     {
13921       if (unformat (input, "del"))
13922         is_add = 0;
13923       else if (unformat (input, "add"))
13924         is_add = 1;
13925       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13926         {
13927           rmt_eid_set = 1;
13928         }
13929       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13930         {
13931           lcl_eid_set = 1;
13932         }
13933       else if (unformat (input, "vrf %d", &dp_table))
13934         ;
13935       else if (unformat (input, "bd %d", &dp_table))
13936         ;
13937       else if (unformat (input, "vni %d", &vni))
13938         ;
13939       else if (unformat (input, "w %d", &w))
13940         {
13941           if (!curr_rloc)
13942             {
13943               errmsg ("No RLOC configured for setting priority/weight!");
13944               return -99;
13945             }
13946           curr_rloc->weight = w;
13947         }
13948       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13949                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13950         {
13951           rloc.is_ip4 = 1;
13952
13953           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13954           rloc.weight = 0;
13955           vec_add1 (lcl_locs, rloc);
13956
13957           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13958           vec_add1 (rmt_locs, rloc);
13959           /* weight saved in rmt loc */
13960           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13961         }
13962       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13963                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13964         {
13965           rloc.is_ip4 = 0;
13966           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13967           rloc.weight = 0;
13968           vec_add1 (lcl_locs, rloc);
13969
13970           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13971           vec_add1 (rmt_locs, rloc);
13972           /* weight saved in rmt loc */
13973           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13974         }
13975       else if (unformat (input, "action %d", &action))
13976         {
13977           ;
13978         }
13979       else
13980         {
13981           clib_warning ("parse error '%U'", format_unformat_error, input);
13982           return -99;
13983         }
13984     }
13985
13986   if (!rmt_eid_set)
13987     {
13988       errmsg ("remote eid addresses not set");
13989       return -99;
13990     }
13991
13992   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13993     {
13994       errmsg ("eid types don't match");
13995       return -99;
13996     }
13997
13998   if (0 == rmt_locs && (u32) ~ 0 == action)
13999     {
14000       errmsg ("action not set for negative mapping");
14001       return -99;
14002     }
14003
14004   /* Construct the API message */
14005   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14006       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14007
14008   mp->is_add = is_add;
14009   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14010   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14011   mp->eid_type = rmt_eid->type;
14012   mp->dp_table = clib_host_to_net_u32 (dp_table);
14013   mp->vni = clib_host_to_net_u32 (vni);
14014   mp->rmt_len = rmt_eid->len;
14015   mp->lcl_len = lcl_eid->len;
14016   mp->action = action;
14017
14018   if (0 != rmt_locs && 0 != lcl_locs)
14019     {
14020       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14021       clib_memcpy (mp->locs, lcl_locs,
14022                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14023
14024       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14025       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14026                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14027     }
14028   vec_free (lcl_locs);
14029   vec_free (rmt_locs);
14030
14031   /* send it... */
14032   S (mp);
14033
14034   /* Wait for a reply... */
14035   W (ret);
14036   return ret;
14037 }
14038
14039 static int
14040 api_lisp_add_del_map_server (vat_main_t * vam)
14041 {
14042   unformat_input_t *input = vam->input;
14043   vl_api_lisp_add_del_map_server_t *mp;
14044   u8 is_add = 1;
14045   u8 ipv4_set = 0;
14046   u8 ipv6_set = 0;
14047   ip4_address_t ipv4;
14048   ip6_address_t ipv6;
14049   int ret;
14050
14051   /* Parse args required to build the message */
14052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14053     {
14054       if (unformat (input, "del"))
14055         {
14056           is_add = 0;
14057         }
14058       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14059         {
14060           ipv4_set = 1;
14061         }
14062       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14063         {
14064           ipv6_set = 1;
14065         }
14066       else
14067         break;
14068     }
14069
14070   if (ipv4_set && ipv6_set)
14071     {
14072       errmsg ("both eid v4 and v6 addresses set");
14073       return -99;
14074     }
14075
14076   if (!ipv4_set && !ipv6_set)
14077     {
14078       errmsg ("eid addresses not set");
14079       return -99;
14080     }
14081
14082   /* Construct the API message */
14083   M (LISP_ADD_DEL_MAP_SERVER, mp);
14084
14085   mp->is_add = is_add;
14086   if (ipv6_set)
14087     {
14088       mp->is_ipv6 = 1;
14089       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14090     }
14091   else
14092     {
14093       mp->is_ipv6 = 0;
14094       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14095     }
14096
14097   /* send it... */
14098   S (mp);
14099
14100   /* Wait for a reply... */
14101   W (ret);
14102   return ret;
14103 }
14104
14105 static int
14106 api_lisp_add_del_map_resolver (vat_main_t * vam)
14107 {
14108   unformat_input_t *input = vam->input;
14109   vl_api_lisp_add_del_map_resolver_t *mp;
14110   u8 is_add = 1;
14111   u8 ipv4_set = 0;
14112   u8 ipv6_set = 0;
14113   ip4_address_t ipv4;
14114   ip6_address_t ipv6;
14115   int ret;
14116
14117   /* Parse args required to build the message */
14118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14119     {
14120       if (unformat (input, "del"))
14121         {
14122           is_add = 0;
14123         }
14124       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14125         {
14126           ipv4_set = 1;
14127         }
14128       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14129         {
14130           ipv6_set = 1;
14131         }
14132       else
14133         break;
14134     }
14135
14136   if (ipv4_set && ipv6_set)
14137     {
14138       errmsg ("both eid v4 and v6 addresses set");
14139       return -99;
14140     }
14141
14142   if (!ipv4_set && !ipv6_set)
14143     {
14144       errmsg ("eid addresses not set");
14145       return -99;
14146     }
14147
14148   /* Construct the API message */
14149   M (LISP_ADD_DEL_MAP_RESOLVER, mp);
14150
14151   mp->is_add = is_add;
14152   if (ipv6_set)
14153     {
14154       mp->is_ipv6 = 1;
14155       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14156     }
14157   else
14158     {
14159       mp->is_ipv6 = 0;
14160       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14161     }
14162
14163   /* send it... */
14164   S (mp);
14165
14166   /* Wait for a reply... */
14167   W (ret);
14168   return ret;
14169 }
14170
14171 static int
14172 api_lisp_gpe_enable_disable (vat_main_t * vam)
14173 {
14174   unformat_input_t *input = vam->input;
14175   vl_api_gpe_enable_disable_t *mp;
14176   u8 is_set = 0;
14177   u8 is_en = 1;
14178   int ret;
14179
14180   /* Parse args required to build the message */
14181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14182     {
14183       if (unformat (input, "enable"))
14184         {
14185           is_set = 1;
14186           is_en = 1;
14187         }
14188       else if (unformat (input, "disable"))
14189         {
14190           is_set = 1;
14191           is_en = 0;
14192         }
14193       else
14194         break;
14195     }
14196
14197   if (is_set == 0)
14198     {
14199       errmsg ("Value not set");
14200       return -99;
14201     }
14202
14203   /* Construct the API message */
14204   M (GPE_ENABLE_DISABLE, mp);
14205
14206   mp->is_en = is_en;
14207
14208   /* send it... */
14209   S (mp);
14210
14211   /* Wait for a reply... */
14212   W (ret);
14213   return ret;
14214 }
14215
14216 static int
14217 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
14218 {
14219   unformat_input_t *input = vam->input;
14220   vl_api_lisp_rloc_probe_enable_disable_t *mp;
14221   u8 is_set = 0;
14222   u8 is_en = 0;
14223   int ret;
14224
14225   /* Parse args required to build the message */
14226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14227     {
14228       if (unformat (input, "enable"))
14229         {
14230           is_set = 1;
14231           is_en = 1;
14232         }
14233       else if (unformat (input, "disable"))
14234         is_set = 1;
14235       else
14236         break;
14237     }
14238
14239   if (!is_set)
14240     {
14241       errmsg ("Value not set");
14242       return -99;
14243     }
14244
14245   /* Construct the API message */
14246   M (LISP_RLOC_PROBE_ENABLE_DISABLE, mp);
14247
14248   mp->is_enabled = is_en;
14249
14250   /* send it... */
14251   S (mp);
14252
14253   /* Wait for a reply... */
14254   W (ret);
14255   return ret;
14256 }
14257
14258 static int
14259 api_lisp_map_register_enable_disable (vat_main_t * vam)
14260 {
14261   unformat_input_t *input = vam->input;
14262   vl_api_lisp_map_register_enable_disable_t *mp;
14263   u8 is_set = 0;
14264   u8 is_en = 0;
14265   int ret;
14266
14267   /* Parse args required to build the message */
14268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14269     {
14270       if (unformat (input, "enable"))
14271         {
14272           is_set = 1;
14273           is_en = 1;
14274         }
14275       else if (unformat (input, "disable"))
14276         is_set = 1;
14277       else
14278         break;
14279     }
14280
14281   if (!is_set)
14282     {
14283       errmsg ("Value not set");
14284       return -99;
14285     }
14286
14287   /* Construct the API message */
14288   M (LISP_MAP_REGISTER_ENABLE_DISABLE, mp);
14289
14290   mp->is_enabled = is_en;
14291
14292   /* send it... */
14293   S (mp);
14294
14295   /* Wait for a reply... */
14296   W (ret);
14297   return ret;
14298 }
14299
14300 static int
14301 api_lisp_enable_disable (vat_main_t * vam)
14302 {
14303   unformat_input_t *input = vam->input;
14304   vl_api_lisp_enable_disable_t *mp;
14305   u8 is_set = 0;
14306   u8 is_en = 0;
14307   int ret;
14308
14309   /* Parse args required to build the message */
14310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14311     {
14312       if (unformat (input, "enable"))
14313         {
14314           is_set = 1;
14315           is_en = 1;
14316         }
14317       else if (unformat (input, "disable"))
14318         {
14319           is_set = 1;
14320         }
14321       else
14322         break;
14323     }
14324
14325   if (!is_set)
14326     {
14327       errmsg ("Value not set");
14328       return -99;
14329     }
14330
14331   /* Construct the API message */
14332   M (LISP_ENABLE_DISABLE, mp);
14333
14334   mp->is_en = is_en;
14335
14336   /* send it... */
14337   S (mp);
14338
14339   /* Wait for a reply... */
14340   W (ret);
14341   return ret;
14342 }
14343
14344 static int
14345 api_show_lisp_map_register_state (vat_main_t * vam)
14346 {
14347   vl_api_show_lisp_map_register_state_t *mp;
14348   int ret;
14349
14350   M (SHOW_LISP_MAP_REGISTER_STATE, mp);
14351
14352   /* send */
14353   S (mp);
14354
14355   /* wait for reply */
14356   W (ret);
14357   return ret;
14358 }
14359
14360 static int
14361 api_show_lisp_rloc_probe_state (vat_main_t * vam)
14362 {
14363   vl_api_show_lisp_rloc_probe_state_t *mp;
14364   int ret;
14365
14366   M (SHOW_LISP_RLOC_PROBE_STATE, mp);
14367
14368   /* send */
14369   S (mp);
14370
14371   /* wait for reply */
14372   W (ret);
14373   return ret;
14374 }
14375
14376 static int
14377 api_show_lisp_map_request_mode (vat_main_t * vam)
14378 {
14379   vl_api_show_lisp_map_request_mode_t *mp;
14380   int ret;
14381
14382   M (SHOW_LISP_MAP_REQUEST_MODE, mp);
14383
14384   /* send */
14385   S (mp);
14386
14387   /* wait for reply */
14388   W (ret);
14389   return ret;
14390 }
14391
14392 static int
14393 api_lisp_map_request_mode (vat_main_t * vam)
14394 {
14395   unformat_input_t *input = vam->input;
14396   vl_api_lisp_map_request_mode_t *mp;
14397   u8 mode = 0;
14398   int ret;
14399
14400   /* Parse args required to build the message */
14401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14402     {
14403       if (unformat (input, "dst-only"))
14404         mode = 0;
14405       else if (unformat (input, "src-dst"))
14406         mode = 1;
14407       else
14408         {
14409           errmsg ("parse error '%U'", format_unformat_error, input);
14410           return -99;
14411         }
14412     }
14413
14414   M (LISP_MAP_REQUEST_MODE, mp);
14415
14416   mp->mode = mode;
14417
14418   /* send */
14419   S (mp);
14420
14421   /* wait for reply */
14422   W (ret);
14423   return ret;
14424 }
14425
14426 /**
14427  * Enable/disable LISP proxy ITR.
14428  *
14429  * @param vam vpp API test context
14430  * @return return code
14431  */
14432 static int
14433 api_lisp_pitr_set_locator_set (vat_main_t * vam)
14434 {
14435   u8 ls_name_set = 0;
14436   unformat_input_t *input = vam->input;
14437   vl_api_lisp_pitr_set_locator_set_t *mp;
14438   u8 is_add = 1;
14439   u8 *ls_name = 0;
14440   int ret;
14441
14442   /* Parse args required to build the message */
14443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14444     {
14445       if (unformat (input, "del"))
14446         is_add = 0;
14447       else if (unformat (input, "locator-set %s", &ls_name))
14448         ls_name_set = 1;
14449       else
14450         {
14451           errmsg ("parse error '%U'", format_unformat_error, input);
14452           return -99;
14453         }
14454     }
14455
14456   if (!ls_name_set)
14457     {
14458       errmsg ("locator-set name not set!");
14459       return -99;
14460     }
14461
14462   M (LISP_PITR_SET_LOCATOR_SET, mp);
14463
14464   mp->is_add = is_add;
14465   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14466   vec_free (ls_name);
14467
14468   /* send */
14469   S (mp);
14470
14471   /* wait for reply */
14472   W (ret);
14473   return ret;
14474 }
14475
14476 static int
14477 api_show_lisp_pitr (vat_main_t * vam)
14478 {
14479   vl_api_show_lisp_pitr_t *mp;
14480   int ret;
14481
14482   if (!vam->json_output)
14483     {
14484       print (vam->ofp, "%=20s", "lisp status:");
14485     }
14486
14487   M (SHOW_LISP_PITR, mp);
14488   /* send it... */
14489   S (mp);
14490
14491   /* Wait for a reply... */
14492   W (ret);
14493   return ret;
14494 }
14495
14496 /**
14497  * Add/delete mapping between vni and vrf
14498  */
14499 static int
14500 api_lisp_eid_table_add_del_map (vat_main_t * vam)
14501 {
14502   unformat_input_t *input = vam->input;
14503   vl_api_lisp_eid_table_add_del_map_t *mp;
14504   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14505   u32 vni, vrf, bd_index;
14506   int ret;
14507
14508   /* Parse args required to build the message */
14509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14510     {
14511       if (unformat (input, "del"))
14512         is_add = 0;
14513       else if (unformat (input, "vrf %d", &vrf))
14514         vrf_set = 1;
14515       else if (unformat (input, "bd_index %d", &bd_index))
14516         bd_index_set = 1;
14517       else if (unformat (input, "vni %d", &vni))
14518         vni_set = 1;
14519       else
14520         break;
14521     }
14522
14523   if (!vni_set || (!vrf_set && !bd_index_set))
14524     {
14525       errmsg ("missing arguments!");
14526       return -99;
14527     }
14528
14529   if (vrf_set && bd_index_set)
14530     {
14531       errmsg ("error: both vrf and bd entered!");
14532       return -99;
14533     }
14534
14535   M (LISP_EID_TABLE_ADD_DEL_MAP, mp);
14536
14537   mp->is_add = is_add;
14538   mp->vni = htonl (vni);
14539   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14540   mp->is_l2 = bd_index_set;
14541
14542   /* send */
14543   S (mp);
14544
14545   /* wait for reply */
14546   W (ret);
14547   return ret;
14548 }
14549
14550 uword
14551 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14552 {
14553   u32 *action = va_arg (*args, u32 *);
14554   u8 *s = 0;
14555
14556   if (unformat (input, "%s", &s))
14557     {
14558       if (!strcmp ((char *) s, "no-action"))
14559         action[0] = 0;
14560       else if (!strcmp ((char *) s, "natively-forward"))
14561         action[0] = 1;
14562       else if (!strcmp ((char *) s, "send-map-request"))
14563         action[0] = 2;
14564       else if (!strcmp ((char *) s, "drop"))
14565         action[0] = 3;
14566       else
14567         {
14568           clib_warning ("invalid action: '%s'", s);
14569           action[0] = 3;
14570         }
14571     }
14572   else
14573     return 0;
14574
14575   vec_free (s);
14576   return 1;
14577 }
14578
14579 /**
14580  * Add/del remote mapping to/from LISP control plane
14581  *
14582  * @param vam vpp API test context
14583  * @return return code
14584  */
14585 static int
14586 api_lisp_add_del_remote_mapping (vat_main_t * vam)
14587 {
14588   unformat_input_t *input = vam->input;
14589   vl_api_lisp_add_del_remote_mapping_t *mp;
14590   u32 vni = 0;
14591   lisp_eid_vat_t _eid, *eid = &_eid;
14592   lisp_eid_vat_t _seid, *seid = &_seid;
14593   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14594   u32 action = ~0, p, w, data_len;
14595   ip4_address_t rloc4;
14596   ip6_address_t rloc6;
14597   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14598   int ret;
14599
14600   memset (&rloc, 0, sizeof (rloc));
14601
14602   /* Parse args required to build the message */
14603   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14604     {
14605       if (unformat (input, "del-all"))
14606         {
14607           del_all = 1;
14608         }
14609       else if (unformat (input, "del"))
14610         {
14611           is_add = 0;
14612         }
14613       else if (unformat (input, "add"))
14614         {
14615           is_add = 1;
14616         }
14617       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14618         {
14619           eid_set = 1;
14620         }
14621       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14622         {
14623           seid_set = 1;
14624         }
14625       else if (unformat (input, "vni %d", &vni))
14626         {
14627           ;
14628         }
14629       else if (unformat (input, "p %d w %d", &p, &w))
14630         {
14631           if (!curr_rloc)
14632             {
14633               errmsg ("No RLOC configured for setting priority/weight!");
14634               return -99;
14635             }
14636           curr_rloc->priority = p;
14637           curr_rloc->weight = w;
14638         }
14639       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14640         {
14641           rloc.is_ip4 = 1;
14642           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14643           vec_add1 (rlocs, rloc);
14644           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14645         }
14646       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14647         {
14648           rloc.is_ip4 = 0;
14649           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14650           vec_add1 (rlocs, rloc);
14651           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14652         }
14653       else if (unformat (input, "action %U",
14654                          unformat_negative_mapping_action, &action))
14655         {
14656           ;
14657         }
14658       else
14659         {
14660           clib_warning ("parse error '%U'", format_unformat_error, input);
14661           return -99;
14662         }
14663     }
14664
14665   if (0 == eid_set)
14666     {
14667       errmsg ("missing params!");
14668       return -99;
14669     }
14670
14671   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14672     {
14673       errmsg ("no action set for negative map-reply!");
14674       return -99;
14675     }
14676
14677   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14678
14679   M2 (LISP_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14680   mp->is_add = is_add;
14681   mp->vni = htonl (vni);
14682   mp->action = (u8) action;
14683   mp->is_src_dst = seid_set;
14684   mp->eid_len = eid->len;
14685   mp->seid_len = seid->len;
14686   mp->del_all = del_all;
14687   mp->eid_type = eid->type;
14688   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14689   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14690
14691   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14692   clib_memcpy (mp->rlocs, rlocs, data_len);
14693   vec_free (rlocs);
14694
14695   /* send it... */
14696   S (mp);
14697
14698   /* Wait for a reply... */
14699   W (ret);
14700   return ret;
14701 }
14702
14703 /**
14704  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14705  * forwarding entries in data-plane accordingly.
14706  *
14707  * @param vam vpp API test context
14708  * @return return code
14709  */
14710 static int
14711 api_lisp_add_del_adjacency (vat_main_t * vam)
14712 {
14713   unformat_input_t *input = vam->input;
14714   vl_api_lisp_add_del_adjacency_t *mp;
14715   u32 vni = 0;
14716   ip4_address_t leid4, reid4;
14717   ip6_address_t leid6, reid6;
14718   u8 reid_mac[6] = { 0 };
14719   u8 leid_mac[6] = { 0 };
14720   u8 reid_type, leid_type;
14721   u32 leid_len = 0, reid_len = 0, len;
14722   u8 is_add = 1;
14723   int ret;
14724
14725   leid_type = reid_type = (u8) ~ 0;
14726
14727   /* Parse args required to build the message */
14728   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14729     {
14730       if (unformat (input, "del"))
14731         {
14732           is_add = 0;
14733         }
14734       else if (unformat (input, "add"))
14735         {
14736           is_add = 1;
14737         }
14738       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14739                          &reid4, &len))
14740         {
14741           reid_type = 0;        /* ipv4 */
14742           reid_len = len;
14743         }
14744       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14745                          &reid6, &len))
14746         {
14747           reid_type = 1;        /* ipv6 */
14748           reid_len = len;
14749         }
14750       else if (unformat (input, "reid %U", unformat_ethernet_address,
14751                          reid_mac))
14752         {
14753           reid_type = 2;        /* mac */
14754         }
14755       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14756                          &leid4, &len))
14757         {
14758           leid_type = 0;        /* ipv4 */
14759           leid_len = len;
14760         }
14761       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14762                          &leid6, &len))
14763         {
14764           leid_type = 1;        /* ipv6 */
14765           leid_len = len;
14766         }
14767       else if (unformat (input, "leid %U", unformat_ethernet_address,
14768                          leid_mac))
14769         {
14770           leid_type = 2;        /* mac */
14771         }
14772       else if (unformat (input, "vni %d", &vni))
14773         {
14774           ;
14775         }
14776       else
14777         {
14778           errmsg ("parse error '%U'", format_unformat_error, input);
14779           return -99;
14780         }
14781     }
14782
14783   if ((u8) ~ 0 == reid_type)
14784     {
14785       errmsg ("missing params!");
14786       return -99;
14787     }
14788
14789   if (leid_type != reid_type)
14790     {
14791       errmsg ("remote and local EIDs are of different types!");
14792       return -99;
14793     }
14794
14795   M (LISP_ADD_DEL_ADJACENCY, mp);
14796   mp->is_add = is_add;
14797   mp->vni = htonl (vni);
14798   mp->leid_len = leid_len;
14799   mp->reid_len = reid_len;
14800   mp->eid_type = reid_type;
14801
14802   switch (mp->eid_type)
14803     {
14804     case 0:
14805       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14806       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14807       break;
14808     case 1:
14809       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14810       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14811       break;
14812     case 2:
14813       clib_memcpy (mp->leid, leid_mac, 6);
14814       clib_memcpy (mp->reid, reid_mac, 6);
14815       break;
14816     default:
14817       errmsg ("unknown EID type %d!", mp->eid_type);
14818       return 0;
14819     }
14820
14821   /* send it... */
14822   S (mp);
14823
14824   /* Wait for a reply... */
14825   W (ret);
14826   return ret;
14827 }
14828
14829 static int
14830 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14831 {
14832   unformat_input_t *input = vam->input;
14833   vl_api_gpe_add_del_iface_t *mp;
14834   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14835   u32 dp_table = 0, vni = 0;
14836   int ret;
14837
14838   /* Parse args required to build the message */
14839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14840     {
14841       if (unformat (input, "up"))
14842         {
14843           action_set = 1;
14844           is_add = 1;
14845         }
14846       else if (unformat (input, "down"))
14847         {
14848           action_set = 1;
14849           is_add = 0;
14850         }
14851       else if (unformat (input, "table_id %d", &dp_table))
14852         {
14853           dp_table_set = 1;
14854         }
14855       else if (unformat (input, "bd_id %d", &dp_table))
14856         {
14857           dp_table_set = 1;
14858           is_l2 = 1;
14859         }
14860       else if (unformat (input, "vni %d", &vni))
14861         {
14862           vni_set = 1;
14863         }
14864       else
14865         break;
14866     }
14867
14868   if (action_set == 0)
14869     {
14870       errmsg ("Action not set");
14871       return -99;
14872     }
14873   if (dp_table_set == 0 || vni_set == 0)
14874     {
14875       errmsg ("vni and dp_table must be set");
14876       return -99;
14877     }
14878
14879   /* Construct the API message */
14880   M (GPE_ADD_DEL_IFACE, mp);
14881
14882   mp->is_add = is_add;
14883   mp->dp_table = dp_table;
14884   mp->is_l2 = is_l2;
14885   mp->vni = vni;
14886
14887   /* send it... */
14888   S (mp);
14889
14890   /* Wait for a reply... */
14891   W (ret);
14892   return ret;
14893 }
14894
14895 /**
14896  * Add/del map request itr rlocs from LISP control plane and updates
14897  *
14898  * @param vam vpp API test context
14899  * @return return code
14900  */
14901 static int
14902 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14903 {
14904   unformat_input_t *input = vam->input;
14905   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14906   u8 *locator_set_name = 0;
14907   u8 locator_set_name_set = 0;
14908   u8 is_add = 1;
14909   int ret;
14910
14911   /* Parse args required to build the message */
14912   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14913     {
14914       if (unformat (input, "del"))
14915         {
14916           is_add = 0;
14917         }
14918       else if (unformat (input, "%_%v%_", &locator_set_name))
14919         {
14920           locator_set_name_set = 1;
14921         }
14922       else
14923         {
14924           clib_warning ("parse error '%U'", format_unformat_error, input);
14925           return -99;
14926         }
14927     }
14928
14929   if (is_add && !locator_set_name_set)
14930     {
14931       errmsg ("itr-rloc is not set!");
14932       return -99;
14933     }
14934
14935   if (is_add && vec_len (locator_set_name) > 64)
14936     {
14937       errmsg ("itr-rloc locator-set name too long");
14938       vec_free (locator_set_name);
14939       return -99;
14940     }
14941
14942   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14943   mp->is_add = is_add;
14944   if (is_add)
14945     {
14946       clib_memcpy (mp->locator_set_name, locator_set_name,
14947                    vec_len (locator_set_name));
14948     }
14949   else
14950     {
14951       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14952     }
14953   vec_free (locator_set_name);
14954
14955   /* send it... */
14956   S (mp);
14957
14958   /* Wait for a reply... */
14959   W (ret);
14960   return ret;
14961 }
14962
14963 static int
14964 api_lisp_locator_dump (vat_main_t * vam)
14965 {
14966   unformat_input_t *input = vam->input;
14967   vl_api_lisp_locator_dump_t *mp;
14968   vl_api_control_ping_t *mp_ping;
14969   u8 is_index_set = 0, is_name_set = 0;
14970   u8 *ls_name = 0;
14971   u32 ls_index = ~0;
14972   int ret;
14973
14974   /* Parse args required to build the message */
14975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14976     {
14977       if (unformat (input, "ls_name %_%v%_", &ls_name))
14978         {
14979           is_name_set = 1;
14980         }
14981       else if (unformat (input, "ls_index %d", &ls_index))
14982         {
14983           is_index_set = 1;
14984         }
14985       else
14986         {
14987           errmsg ("parse error '%U'", format_unformat_error, input);
14988           return -99;
14989         }
14990     }
14991
14992   if (!is_index_set && !is_name_set)
14993     {
14994       errmsg ("error: expected one of index or name!");
14995       return -99;
14996     }
14997
14998   if (is_index_set && is_name_set)
14999     {
15000       errmsg ("error: only one param expected!");
15001       return -99;
15002     }
15003
15004   if (vec_len (ls_name) > 62)
15005     {
15006       errmsg ("error: locator set name too long!");
15007       return -99;
15008     }
15009
15010   if (!vam->json_output)
15011     {
15012       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15013     }
15014
15015   M (LISP_LOCATOR_DUMP, mp);
15016   mp->is_index_set = is_index_set;
15017
15018   if (is_index_set)
15019     mp->ls_index = clib_host_to_net_u32 (ls_index);
15020   else
15021     {
15022       vec_add1 (ls_name, 0);
15023       strncpy ((char *) mp->ls_name, (char *) ls_name,
15024                sizeof (mp->ls_name) - 1);
15025     }
15026
15027   /* send it... */
15028   S (mp);
15029
15030   /* Use a control ping for synchronization */
15031   M (CONTROL_PING, mp_ping);
15032   S (mp_ping);
15033
15034   /* Wait for a reply... */
15035   W (ret);
15036   return ret;
15037 }
15038
15039 static int
15040 api_lisp_locator_set_dump (vat_main_t * vam)
15041 {
15042   vl_api_lisp_locator_set_dump_t *mp;
15043   vl_api_control_ping_t *mp_ping;
15044   unformat_input_t *input = vam->input;
15045   u8 filter = 0;
15046   int ret;
15047
15048   /* Parse args required to build the message */
15049   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15050     {
15051       if (unformat (input, "local"))
15052         {
15053           filter = 1;
15054         }
15055       else if (unformat (input, "remote"))
15056         {
15057           filter = 2;
15058         }
15059       else
15060         {
15061           errmsg ("parse error '%U'", format_unformat_error, input);
15062           return -99;
15063         }
15064     }
15065
15066   if (!vam->json_output)
15067     {
15068       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15069     }
15070
15071   M (LISP_LOCATOR_SET_DUMP, mp);
15072
15073   mp->filter = filter;
15074
15075   /* send it... */
15076   S (mp);
15077
15078   /* Use a control ping for synchronization */
15079   M (CONTROL_PING, mp_ping);
15080   S (mp_ping);
15081
15082   /* Wait for a reply... */
15083   W (ret);
15084   return ret;
15085 }
15086
15087 static int
15088 api_lisp_eid_table_map_dump (vat_main_t * vam)
15089 {
15090   u8 is_l2 = 0;
15091   u8 mode_set = 0;
15092   unformat_input_t *input = vam->input;
15093   vl_api_lisp_eid_table_map_dump_t *mp;
15094   vl_api_control_ping_t *mp_ping;
15095   int ret;
15096
15097   /* Parse args required to build the message */
15098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15099     {
15100       if (unformat (input, "l2"))
15101         {
15102           is_l2 = 1;
15103           mode_set = 1;
15104         }
15105       else if (unformat (input, "l3"))
15106         {
15107           is_l2 = 0;
15108           mode_set = 1;
15109         }
15110       else
15111         {
15112           errmsg ("parse error '%U'", format_unformat_error, input);
15113           return -99;
15114         }
15115     }
15116
15117   if (!mode_set)
15118     {
15119       errmsg ("expected one of 'l2' or 'l3' parameter!");
15120       return -99;
15121     }
15122
15123   if (!vam->json_output)
15124     {
15125       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15126     }
15127
15128   M (LISP_EID_TABLE_MAP_DUMP, mp);
15129   mp->is_l2 = is_l2;
15130
15131   /* send it... */
15132   S (mp);
15133
15134   /* Use a control ping for synchronization */
15135   M (CONTROL_PING, mp_ping);
15136   S (mp_ping);
15137
15138   /* Wait for a reply... */
15139   W (ret);
15140   return ret;
15141 }
15142
15143 static int
15144 api_lisp_eid_table_vni_dump (vat_main_t * vam)
15145 {
15146   vl_api_lisp_eid_table_vni_dump_t *mp;
15147   vl_api_control_ping_t *mp_ping;
15148   int ret;
15149
15150   if (!vam->json_output)
15151     {
15152       print (vam->ofp, "VNI");
15153     }
15154
15155   M (LISP_EID_TABLE_VNI_DUMP, mp);
15156
15157   /* send it... */
15158   S (mp);
15159
15160   /* Use a control ping for synchronization */
15161   M (CONTROL_PING, mp_ping);
15162   S (mp_ping);
15163
15164   /* Wait for a reply... */
15165   W (ret);
15166   return ret;
15167 }
15168
15169 static int
15170 api_lisp_eid_table_dump (vat_main_t * vam)
15171 {
15172   unformat_input_t *i = vam->input;
15173   vl_api_lisp_eid_table_dump_t *mp;
15174   vl_api_control_ping_t *mp_ping;
15175   struct in_addr ip4;
15176   struct in6_addr ip6;
15177   u8 mac[6];
15178   u8 eid_type = ~0, eid_set = 0;
15179   u32 prefix_length = ~0, t, vni = 0;
15180   u8 filter = 0;
15181   int ret;
15182
15183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15184     {
15185       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15186         {
15187           eid_set = 1;
15188           eid_type = 0;
15189           prefix_length = t;
15190         }
15191       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15192         {
15193           eid_set = 1;
15194           eid_type = 1;
15195           prefix_length = t;
15196         }
15197       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15198         {
15199           eid_set = 1;
15200           eid_type = 2;
15201         }
15202       else if (unformat (i, "vni %d", &t))
15203         {
15204           vni = t;
15205         }
15206       else if (unformat (i, "local"))
15207         {
15208           filter = 1;
15209         }
15210       else if (unformat (i, "remote"))
15211         {
15212           filter = 2;
15213         }
15214       else
15215         {
15216           errmsg ("parse error '%U'", format_unformat_error, i);
15217           return -99;
15218         }
15219     }
15220
15221   if (!vam->json_output)
15222     {
15223       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15224              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15225     }
15226
15227   M (LISP_EID_TABLE_DUMP, mp);
15228
15229   mp->filter = filter;
15230   if (eid_set)
15231     {
15232       mp->eid_set = 1;
15233       mp->vni = htonl (vni);
15234       mp->eid_type = eid_type;
15235       switch (eid_type)
15236         {
15237         case 0:
15238           mp->prefix_length = prefix_length;
15239           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15240           break;
15241         case 1:
15242           mp->prefix_length = prefix_length;
15243           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15244           break;
15245         case 2:
15246           clib_memcpy (mp->eid, mac, sizeof (mac));
15247           break;
15248         default:
15249           errmsg ("unknown EID type %d!", eid_type);
15250           return -99;
15251         }
15252     }
15253
15254   /* send it... */
15255   S (mp);
15256
15257   /* Use a control ping for synchronization */
15258   M (CONTROL_PING, mp_ping);
15259   S (mp_ping);
15260
15261   /* Wait for a reply... */
15262   W (ret);
15263   return ret;
15264 }
15265
15266 static int
15267 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15268 {
15269   unformat_input_t *i = vam->input;
15270   vl_api_gpe_fwd_entries_get_t *mp;
15271   u8 vni_set = 0;
15272   u32 vni = ~0;
15273   int ret;
15274
15275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15276     {
15277       if (unformat (i, "vni %d", &vni))
15278         {
15279           vni_set = 1;
15280         }
15281       else
15282         {
15283           errmsg ("parse error '%U'", format_unformat_error, i);
15284           return -99;
15285         }
15286     }
15287
15288   if (!vni_set)
15289     {
15290       errmsg ("vni not set!");
15291       return -99;
15292     }
15293
15294   if (!vam->json_output)
15295     {
15296       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15297              "leid", "reid");
15298     }
15299
15300   M (GPE_FWD_ENTRIES_GET, mp);
15301   mp->vni = clib_host_to_net_u32 (vni);
15302
15303   /* send it... */
15304   S (mp);
15305
15306   /* Wait for a reply... */
15307   W (ret);
15308   return ret;
15309 }
15310
15311 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15312 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15313 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15314 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15315
15316 static int
15317 api_lisp_adjacencies_get (vat_main_t * vam)
15318 {
15319   unformat_input_t *i = vam->input;
15320   vl_api_lisp_adjacencies_get_t *mp;
15321   u8 vni_set = 0;
15322   u32 vni = ~0;
15323   int ret;
15324
15325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15326     {
15327       if (unformat (i, "vni %d", &vni))
15328         {
15329           vni_set = 1;
15330         }
15331       else
15332         {
15333           errmsg ("parse error '%U'", format_unformat_error, i);
15334           return -99;
15335         }
15336     }
15337
15338   if (!vni_set)
15339     {
15340       errmsg ("vni not set!");
15341       return -99;
15342     }
15343
15344   if (!vam->json_output)
15345     {
15346       print (vam->ofp, "%s %40s", "leid", "reid");
15347     }
15348
15349   M (LISP_ADJACENCIES_GET, mp);
15350   mp->vni = clib_host_to_net_u32 (vni);
15351
15352   /* send it... */
15353   S (mp);
15354
15355   /* Wait for a reply... */
15356   W (ret);
15357   return ret;
15358 }
15359
15360 static int
15361 api_lisp_map_server_dump (vat_main_t * vam)
15362 {
15363   vl_api_lisp_map_server_dump_t *mp;
15364   vl_api_control_ping_t *mp_ping;
15365   int ret;
15366
15367   if (!vam->json_output)
15368     {
15369       print (vam->ofp, "%=20s", "Map server");
15370     }
15371
15372   M (LISP_MAP_SERVER_DUMP, mp);
15373   /* send it... */
15374   S (mp);
15375
15376   /* Use a control ping for synchronization */
15377   M (CONTROL_PING, mp_ping);
15378   S (mp_ping);
15379
15380   /* Wait for a reply... */
15381   W (ret);
15382   return ret;
15383 }
15384
15385 static int
15386 api_lisp_map_resolver_dump (vat_main_t * vam)
15387 {
15388   vl_api_lisp_map_resolver_dump_t *mp;
15389   vl_api_control_ping_t *mp_ping;
15390   int ret;
15391
15392   if (!vam->json_output)
15393     {
15394       print (vam->ofp, "%=20s", "Map resolver");
15395     }
15396
15397   M (LISP_MAP_RESOLVER_DUMP, mp);
15398   /* send it... */
15399   S (mp);
15400
15401   /* Use a control ping for synchronization */
15402   M (CONTROL_PING, mp_ping);
15403   S (mp_ping);
15404
15405   /* Wait for a reply... */
15406   W (ret);
15407   return ret;
15408 }
15409
15410 static int
15411 api_show_lisp_status (vat_main_t * vam)
15412 {
15413   vl_api_show_lisp_status_t *mp;
15414   int ret;
15415
15416   if (!vam->json_output)
15417     {
15418       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
15419     }
15420
15421   M (SHOW_LISP_STATUS, mp);
15422   /* send it... */
15423   S (mp);
15424   /* Wait for a reply... */
15425   W (ret);
15426   return ret;
15427 }
15428
15429 static int
15430 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15431 {
15432   vl_api_gpe_fwd_entry_path_dump_t *mp;
15433   vl_api_control_ping_t *mp_ping;
15434   unformat_input_t *i = vam->input;
15435   u32 fwd_entry_index = ~0;
15436   int ret;
15437
15438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15439     {
15440       if (unformat (i, "index %d", &fwd_entry_index))
15441         ;
15442       else
15443         break;
15444     }
15445
15446   if (~0 == fwd_entry_index)
15447     {
15448       errmsg ("no index specified!");
15449       return -99;
15450     }
15451
15452   if (!vam->json_output)
15453     {
15454       print (vam->ofp, "first line");
15455     }
15456
15457   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15458
15459   /* send it... */
15460   S (mp);
15461   /* Use a control ping for synchronization */
15462   M (CONTROL_PING, mp_ping);
15463   S (mp_ping);
15464
15465   /* Wait for a reply... */
15466   W (ret);
15467   return ret;
15468 }
15469
15470 static int
15471 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
15472 {
15473   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
15474   int ret;
15475
15476   if (!vam->json_output)
15477     {
15478       print (vam->ofp, "%=20s", "itr-rlocs:");
15479     }
15480
15481   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, mp);
15482   /* send it... */
15483   S (mp);
15484   /* Wait for a reply... */
15485   W (ret);
15486   return ret;
15487 }
15488
15489 static int
15490 api_af_packet_create (vat_main_t * vam)
15491 {
15492   unformat_input_t *i = vam->input;
15493   vl_api_af_packet_create_t *mp;
15494   u8 *host_if_name = 0;
15495   u8 hw_addr[6];
15496   u8 random_hw_addr = 1;
15497   int ret;
15498
15499   memset (hw_addr, 0, sizeof (hw_addr));
15500
15501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15502     {
15503       if (unformat (i, "name %s", &host_if_name))
15504         vec_add1 (host_if_name, 0);
15505       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15506         random_hw_addr = 0;
15507       else
15508         break;
15509     }
15510
15511   if (!vec_len (host_if_name))
15512     {
15513       errmsg ("host-interface name must be specified");
15514       return -99;
15515     }
15516
15517   if (vec_len (host_if_name) > 64)
15518     {
15519       errmsg ("host-interface name too long");
15520       return -99;
15521     }
15522
15523   M (AF_PACKET_CREATE, mp);
15524
15525   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15526   clib_memcpy (mp->hw_addr, hw_addr, 6);
15527   mp->use_random_hw_addr = random_hw_addr;
15528   vec_free (host_if_name);
15529
15530   S (mp);
15531   W2 (ret, fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15532   return ret;
15533 }
15534
15535 static int
15536 api_af_packet_delete (vat_main_t * vam)
15537 {
15538   unformat_input_t *i = vam->input;
15539   vl_api_af_packet_delete_t *mp;
15540   u8 *host_if_name = 0;
15541   int ret;
15542
15543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15544     {
15545       if (unformat (i, "name %s", &host_if_name))
15546         vec_add1 (host_if_name, 0);
15547       else
15548         break;
15549     }
15550
15551   if (!vec_len (host_if_name))
15552     {
15553       errmsg ("host-interface name must be specified");
15554       return -99;
15555     }
15556
15557   if (vec_len (host_if_name) > 64)
15558     {
15559       errmsg ("host-interface name too long");
15560       return -99;
15561     }
15562
15563   M (AF_PACKET_DELETE, mp);
15564
15565   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15566   vec_free (host_if_name);
15567
15568   S (mp);
15569   W (ret);
15570   return ret;
15571 }
15572
15573 static int
15574 api_policer_add_del (vat_main_t * vam)
15575 {
15576   unformat_input_t *i = vam->input;
15577   vl_api_policer_add_del_t *mp;
15578   u8 is_add = 1;
15579   u8 *name = 0;
15580   u32 cir = 0;
15581   u32 eir = 0;
15582   u64 cb = 0;
15583   u64 eb = 0;
15584   u8 rate_type = 0;
15585   u8 round_type = 0;
15586   u8 type = 0;
15587   u8 color_aware = 0;
15588   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15589   int ret;
15590
15591   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15592   conform_action.dscp = 0;
15593   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15594   exceed_action.dscp = 0;
15595   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15596   violate_action.dscp = 0;
15597
15598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15599     {
15600       if (unformat (i, "del"))
15601         is_add = 0;
15602       else if (unformat (i, "name %s", &name))
15603         vec_add1 (name, 0);
15604       else if (unformat (i, "cir %u", &cir))
15605         ;
15606       else if (unformat (i, "eir %u", &eir))
15607         ;
15608       else if (unformat (i, "cb %u", &cb))
15609         ;
15610       else if (unformat (i, "eb %u", &eb))
15611         ;
15612       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15613                          &rate_type))
15614         ;
15615       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15616                          &round_type))
15617         ;
15618       else if (unformat (i, "type %U", unformat_policer_type, &type))
15619         ;
15620       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15621                          &conform_action))
15622         ;
15623       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15624                          &exceed_action))
15625         ;
15626       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15627                          &violate_action))
15628         ;
15629       else if (unformat (i, "color-aware"))
15630         color_aware = 1;
15631       else
15632         break;
15633     }
15634
15635   if (!vec_len (name))
15636     {
15637       errmsg ("policer name must be specified");
15638       return -99;
15639     }
15640
15641   if (vec_len (name) > 64)
15642     {
15643       errmsg ("policer name too long");
15644       return -99;
15645     }
15646
15647   M (POLICER_ADD_DEL, mp);
15648
15649   clib_memcpy (mp->name, name, vec_len (name));
15650   vec_free (name);
15651   mp->is_add = is_add;
15652   mp->cir = cir;
15653   mp->eir = eir;
15654   mp->cb = cb;
15655   mp->eb = eb;
15656   mp->rate_type = rate_type;
15657   mp->round_type = round_type;
15658   mp->type = type;
15659   mp->conform_action_type = conform_action.action_type;
15660   mp->conform_dscp = conform_action.dscp;
15661   mp->exceed_action_type = exceed_action.action_type;
15662   mp->exceed_dscp = exceed_action.dscp;
15663   mp->violate_action_type = violate_action.action_type;
15664   mp->violate_dscp = violate_action.dscp;
15665   mp->color_aware = color_aware;
15666
15667   S (mp);
15668   W (ret);
15669   return ret;
15670 }
15671
15672 static int
15673 api_policer_dump (vat_main_t * vam)
15674 {
15675   unformat_input_t *i = vam->input;
15676   vl_api_policer_dump_t *mp;
15677   vl_api_control_ping_t *mp_ping;
15678   u8 *match_name = 0;
15679   u8 match_name_valid = 0;
15680   int ret;
15681
15682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15683     {
15684       if (unformat (i, "name %s", &match_name))
15685         {
15686           vec_add1 (match_name, 0);
15687           match_name_valid = 1;
15688         }
15689       else
15690         break;
15691     }
15692
15693   M (POLICER_DUMP, mp);
15694   mp->match_name_valid = match_name_valid;
15695   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15696   vec_free (match_name);
15697   /* send it... */
15698   S (mp);
15699
15700   /* Use a control ping for synchronization */
15701   M (CONTROL_PING, mp_ping);
15702   S (mp_ping);
15703
15704   /* Wait for a reply... */
15705   W (ret);
15706   return ret;
15707 }
15708
15709 static int
15710 api_policer_classify_set_interface (vat_main_t * vam)
15711 {
15712   unformat_input_t *i = vam->input;
15713   vl_api_policer_classify_set_interface_t *mp;
15714   u32 sw_if_index;
15715   int sw_if_index_set;
15716   u32 ip4_table_index = ~0;
15717   u32 ip6_table_index = ~0;
15718   u32 l2_table_index = ~0;
15719   u8 is_add = 1;
15720   int ret;
15721
15722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15723     {
15724       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15725         sw_if_index_set = 1;
15726       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15727         sw_if_index_set = 1;
15728       else if (unformat (i, "del"))
15729         is_add = 0;
15730       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15731         ;
15732       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15733         ;
15734       else if (unformat (i, "l2-table %d", &l2_table_index))
15735         ;
15736       else
15737         {
15738           clib_warning ("parse error '%U'", format_unformat_error, i);
15739           return -99;
15740         }
15741     }
15742
15743   if (sw_if_index_set == 0)
15744     {
15745       errmsg ("missing interface name or sw_if_index");
15746       return -99;
15747     }
15748
15749   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15750
15751   mp->sw_if_index = ntohl (sw_if_index);
15752   mp->ip4_table_index = ntohl (ip4_table_index);
15753   mp->ip6_table_index = ntohl (ip6_table_index);
15754   mp->l2_table_index = ntohl (l2_table_index);
15755   mp->is_add = is_add;
15756
15757   S (mp);
15758   W (ret);
15759   return ret;
15760 }
15761
15762 static int
15763 api_policer_classify_dump (vat_main_t * vam)
15764 {
15765   unformat_input_t *i = vam->input;
15766   vl_api_policer_classify_dump_t *mp;
15767   vl_api_control_ping_t *mp_ping;
15768   u8 type = POLICER_CLASSIFY_N_TABLES;
15769   int ret;
15770
15771   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15772     ;
15773   else
15774     {
15775       errmsg ("classify table type must be specified");
15776       return -99;
15777     }
15778
15779   if (!vam->json_output)
15780     {
15781       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15782     }
15783
15784   M (POLICER_CLASSIFY_DUMP, mp);
15785   mp->type = type;
15786   /* send it... */
15787   S (mp);
15788
15789   /* Use a control ping for synchronization */
15790   M (CONTROL_PING, mp_ping);
15791   S (mp_ping);
15792
15793   /* Wait for a reply... */
15794   W (ret);
15795   return ret;
15796 }
15797
15798 static int
15799 api_netmap_create (vat_main_t * vam)
15800 {
15801   unformat_input_t *i = vam->input;
15802   vl_api_netmap_create_t *mp;
15803   u8 *if_name = 0;
15804   u8 hw_addr[6];
15805   u8 random_hw_addr = 1;
15806   u8 is_pipe = 0;
15807   u8 is_master = 0;
15808   int ret;
15809
15810   memset (hw_addr, 0, sizeof (hw_addr));
15811
15812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15813     {
15814       if (unformat (i, "name %s", &if_name))
15815         vec_add1 (if_name, 0);
15816       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15817         random_hw_addr = 0;
15818       else if (unformat (i, "pipe"))
15819         is_pipe = 1;
15820       else if (unformat (i, "master"))
15821         is_master = 1;
15822       else if (unformat (i, "slave"))
15823         is_master = 0;
15824       else
15825         break;
15826     }
15827
15828   if (!vec_len (if_name))
15829     {
15830       errmsg ("interface name must be specified");
15831       return -99;
15832     }
15833
15834   if (vec_len (if_name) > 64)
15835     {
15836       errmsg ("interface name too long");
15837       return -99;
15838     }
15839
15840   M (NETMAP_CREATE, mp);
15841
15842   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15843   clib_memcpy (mp->hw_addr, hw_addr, 6);
15844   mp->use_random_hw_addr = random_hw_addr;
15845   mp->is_pipe = is_pipe;
15846   mp->is_master = is_master;
15847   vec_free (if_name);
15848
15849   S (mp);
15850   W (ret);
15851   return ret;
15852 }
15853
15854 static int
15855 api_netmap_delete (vat_main_t * vam)
15856 {
15857   unformat_input_t *i = vam->input;
15858   vl_api_netmap_delete_t *mp;
15859   u8 *if_name = 0;
15860   int ret;
15861
15862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15863     {
15864       if (unformat (i, "name %s", &if_name))
15865         vec_add1 (if_name, 0);
15866       else
15867         break;
15868     }
15869
15870   if (!vec_len (if_name))
15871     {
15872       errmsg ("interface name must be specified");
15873       return -99;
15874     }
15875
15876   if (vec_len (if_name) > 64)
15877     {
15878       errmsg ("interface name too long");
15879       return -99;
15880     }
15881
15882   M (NETMAP_DELETE, mp);
15883
15884   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15885   vec_free (if_name);
15886
15887   S (mp);
15888   W (ret);
15889   return ret;
15890 }
15891
15892 static void vl_api_mpls_tunnel_details_t_handler
15893   (vl_api_mpls_tunnel_details_t * mp)
15894 {
15895   vat_main_t *vam = &vat_main;
15896   i32 len = mp->mt_next_hop_n_labels;
15897   i32 i;
15898
15899   print (vam->ofp, "[%d]: via %U %d labels ",
15900          mp->tunnel_index,
15901          format_ip4_address, mp->mt_next_hop,
15902          ntohl (mp->mt_next_hop_sw_if_index));
15903   for (i = 0; i < len; i++)
15904     {
15905       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15906     }
15907   print (vam->ofp, "");
15908 }
15909
15910 static void vl_api_mpls_tunnel_details_t_handler_json
15911   (vl_api_mpls_tunnel_details_t * mp)
15912 {
15913   vat_main_t *vam = &vat_main;
15914   vat_json_node_t *node = NULL;
15915   struct in_addr ip4;
15916   i32 i;
15917   i32 len = mp->mt_next_hop_n_labels;
15918
15919   if (VAT_JSON_ARRAY != vam->json_tree.type)
15920     {
15921       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15922       vat_json_init_array (&vam->json_tree);
15923     }
15924   node = vat_json_array_add (&vam->json_tree);
15925
15926   vat_json_init_object (node);
15927   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15928   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15929   vat_json_object_add_ip4 (node, "next_hop", ip4);
15930   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15931                             ntohl (mp->mt_next_hop_sw_if_index));
15932   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15933   vat_json_object_add_uint (node, "label_count", len);
15934   for (i = 0; i < len; i++)
15935     {
15936       vat_json_object_add_uint (node, "label",
15937                                 ntohl (mp->mt_next_hop_out_labels[i]));
15938     }
15939 }
15940
15941 static int
15942 api_mpls_tunnel_dump (vat_main_t * vam)
15943 {
15944   vl_api_mpls_tunnel_dump_t *mp;
15945   vl_api_control_ping_t *mp_ping;
15946   i32 index = -1;
15947   int ret;
15948
15949   /* Parse args required to build the message */
15950   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15951     {
15952       if (!unformat (vam->input, "tunnel_index %d", &index))
15953         {
15954           index = -1;
15955           break;
15956         }
15957     }
15958
15959   print (vam->ofp, "  tunnel_index %d", index);
15960
15961   M (MPLS_TUNNEL_DUMP, mp);
15962   mp->tunnel_index = htonl (index);
15963   S (mp);
15964
15965   /* Use a control ping for synchronization */
15966   M (CONTROL_PING, mp_ping);
15967   S (mp_ping);
15968
15969   W (ret);
15970   return ret;
15971 }
15972
15973 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15974 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15975
15976 static void
15977 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15978 {
15979   vat_main_t *vam = &vat_main;
15980   int count = ntohl (mp->count);
15981   vl_api_fib_path2_t *fp;
15982   int i;
15983
15984   print (vam->ofp,
15985          "table-id %d, label %u, ess_bit %u",
15986          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15987   fp = mp->path;
15988   for (i = 0; i < count; i++)
15989     {
15990       if (fp->afi == IP46_TYPE_IP6)
15991         print (vam->ofp,
15992                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15993                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15994                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15995                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15996                format_ip6_address, fp->next_hop);
15997       else if (fp->afi == IP46_TYPE_IP4)
15998         print (vam->ofp,
15999                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16000                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16001                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16002                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16003                format_ip4_address, fp->next_hop);
16004       fp++;
16005     }
16006 }
16007
16008 static void vl_api_mpls_fib_details_t_handler_json
16009   (vl_api_mpls_fib_details_t * mp)
16010 {
16011   vat_main_t *vam = &vat_main;
16012   int count = ntohl (mp->count);
16013   vat_json_node_t *node = NULL;
16014   struct in_addr ip4;
16015   struct in6_addr ip6;
16016   vl_api_fib_path2_t *fp;
16017   int i;
16018
16019   if (VAT_JSON_ARRAY != vam->json_tree.type)
16020     {
16021       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16022       vat_json_init_array (&vam->json_tree);
16023     }
16024   node = vat_json_array_add (&vam->json_tree);
16025
16026   vat_json_init_object (node);
16027   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16028   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16029   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16030   vat_json_object_add_uint (node, "path_count", count);
16031   fp = mp->path;
16032   for (i = 0; i < count; i++)
16033     {
16034       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16035       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16036       vat_json_object_add_uint (node, "is_local", fp->is_local);
16037       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16038       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16039       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16040       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16041       if (fp->afi == IP46_TYPE_IP4)
16042         {
16043           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16044           vat_json_object_add_ip4 (node, "next_hop", ip4);
16045         }
16046       else if (fp->afi == IP46_TYPE_IP6)
16047         {
16048           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16049           vat_json_object_add_ip6 (node, "next_hop", ip6);
16050         }
16051     }
16052 }
16053
16054 static int
16055 api_mpls_fib_dump (vat_main_t * vam)
16056 {
16057   vl_api_mpls_fib_dump_t *mp;
16058   vl_api_control_ping_t *mp_ping;
16059   int ret;
16060
16061   M (MPLS_FIB_DUMP, mp);
16062   S (mp);
16063
16064   /* Use a control ping for synchronization */
16065   M (CONTROL_PING, mp_ping);
16066   S (mp_ping);
16067
16068   W (ret);
16069   return ret;
16070 }
16071
16072 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16073 #define vl_api_ip_fib_details_t_print vl_noop_handler
16074
16075 static void
16076 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16077 {
16078   vat_main_t *vam = &vat_main;
16079   int count = ntohl (mp->count);
16080   vl_api_fib_path_t *fp;
16081   int i;
16082
16083   print (vam->ofp,
16084          "table-id %d, prefix %U/%d",
16085          ntohl (mp->table_id), format_ip4_address, mp->address,
16086          mp->address_length);
16087   fp = mp->path;
16088   for (i = 0; i < count; i++)
16089     {
16090       if (fp->afi == IP46_TYPE_IP6)
16091         print (vam->ofp,
16092                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16093                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16094                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16095                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16096                format_ip6_address, fp->next_hop);
16097       else if (fp->afi == IP46_TYPE_IP4)
16098         print (vam->ofp,
16099                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16100                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16101                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16102                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16103                format_ip4_address, fp->next_hop);
16104       fp++;
16105     }
16106 }
16107
16108 static void vl_api_ip_fib_details_t_handler_json
16109   (vl_api_ip_fib_details_t * mp)
16110 {
16111   vat_main_t *vam = &vat_main;
16112   int count = ntohl (mp->count);
16113   vat_json_node_t *node = NULL;
16114   struct in_addr ip4;
16115   struct in6_addr ip6;
16116   vl_api_fib_path_t *fp;
16117   int i;
16118
16119   if (VAT_JSON_ARRAY != vam->json_tree.type)
16120     {
16121       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16122       vat_json_init_array (&vam->json_tree);
16123     }
16124   node = vat_json_array_add (&vam->json_tree);
16125
16126   vat_json_init_object (node);
16127   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16128   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16129   vat_json_object_add_ip4 (node, "prefix", ip4);
16130   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16131   vat_json_object_add_uint (node, "path_count", count);
16132   fp = mp->path;
16133   for (i = 0; i < count; i++)
16134     {
16135       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16136       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16137       vat_json_object_add_uint (node, "is_local", fp->is_local);
16138       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16139       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16140       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16141       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16142       if (fp->afi == IP46_TYPE_IP4)
16143         {
16144           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16145           vat_json_object_add_ip4 (node, "next_hop", ip4);
16146         }
16147       else if (fp->afi == IP46_TYPE_IP6)
16148         {
16149           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16150           vat_json_object_add_ip6 (node, "next_hop", ip6);
16151         }
16152     }
16153 }
16154
16155 static int
16156 api_ip_fib_dump (vat_main_t * vam)
16157 {
16158   vl_api_ip_fib_dump_t *mp;
16159   vl_api_control_ping_t *mp_ping;
16160   int ret;
16161
16162   M (IP_FIB_DUMP, mp);
16163   S (mp);
16164
16165   /* Use a control ping for synchronization */
16166   M (CONTROL_PING, mp_ping);
16167   S (mp_ping);
16168
16169   W (ret);
16170   return ret;
16171 }
16172
16173 static int
16174 api_ip_mfib_dump (vat_main_t * vam)
16175 {
16176   vl_api_ip_mfib_dump_t *mp;
16177   vl_api_control_ping_t *mp_ping;
16178   int ret;
16179
16180   M (IP_MFIB_DUMP, mp);
16181   S (mp);
16182
16183   /* Use a control ping for synchronization */
16184   M (CONTROL_PING, mp_ping);
16185   S (mp_ping);
16186
16187   W (ret);
16188   return ret;
16189 }
16190
16191 static void vl_api_ip_neighbor_details_t_handler
16192   (vl_api_ip_neighbor_details_t * mp)
16193 {
16194   vat_main_t *vam = &vat_main;
16195
16196   print (vam->ofp, "%c %U %U",
16197          (mp->is_static) ? 'S' : 'D',
16198          format_ethernet_address, &mp->mac_address,
16199          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16200          &mp->ip_address);
16201 }
16202
16203 static void vl_api_ip_neighbor_details_t_handler_json
16204   (vl_api_ip_neighbor_details_t * mp)
16205 {
16206
16207   vat_main_t *vam = &vat_main;
16208   vat_json_node_t *node;
16209   struct in_addr ip4;
16210   struct in6_addr ip6;
16211
16212   if (VAT_JSON_ARRAY != vam->json_tree.type)
16213     {
16214       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16215       vat_json_init_array (&vam->json_tree);
16216     }
16217   node = vat_json_array_add (&vam->json_tree);
16218
16219   vat_json_init_object (node);
16220   vat_json_object_add_string_copy (node, "flag",
16221                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16222                                    "dynamic");
16223
16224   vat_json_object_add_string_copy (node, "link_layer",
16225                                    format (0, "%U", format_ethernet_address,
16226                                            &mp->mac_address));
16227
16228   if (mp->is_ipv6)
16229     {
16230       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16231       vat_json_object_add_ip6 (node, "ip_address", ip6);
16232     }
16233   else
16234     {
16235       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16236       vat_json_object_add_ip4 (node, "ip_address", ip4);
16237     }
16238 }
16239
16240 static int
16241 api_ip_neighbor_dump (vat_main_t * vam)
16242 {
16243   unformat_input_t *i = vam->input;
16244   vl_api_ip_neighbor_dump_t *mp;
16245   vl_api_control_ping_t *mp_ping;
16246   u8 is_ipv6 = 0;
16247   u32 sw_if_index = ~0;
16248   int ret;
16249
16250   /* Parse args required to build the message */
16251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16252     {
16253       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16254         ;
16255       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16256         ;
16257       else if (unformat (i, "ip6"))
16258         is_ipv6 = 1;
16259       else
16260         break;
16261     }
16262
16263   if (sw_if_index == ~0)
16264     {
16265       errmsg ("missing interface name or sw_if_index");
16266       return -99;
16267     }
16268
16269   M (IP_NEIGHBOR_DUMP, mp);
16270   mp->is_ipv6 = (u8) is_ipv6;
16271   mp->sw_if_index = ntohl (sw_if_index);
16272   S (mp);
16273
16274   /* Use a control ping for synchronization */
16275   M (CONTROL_PING, mp_ping);
16276   S (mp_ping);
16277
16278   W (ret);
16279   return ret;
16280 }
16281
16282 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16283 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16284
16285 static void
16286 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16287 {
16288   vat_main_t *vam = &vat_main;
16289   int count = ntohl (mp->count);
16290   vl_api_fib_path_t *fp;
16291   int i;
16292
16293   print (vam->ofp,
16294          "table-id %d, prefix %U/%d",
16295          ntohl (mp->table_id), format_ip6_address, mp->address,
16296          mp->address_length);
16297   fp = mp->path;
16298   for (i = 0; i < count; i++)
16299     {
16300       if (fp->afi == IP46_TYPE_IP6)
16301         print (vam->ofp,
16302                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16303                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16304                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16305                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16306                format_ip6_address, fp->next_hop);
16307       else if (fp->afi == IP46_TYPE_IP4)
16308         print (vam->ofp,
16309                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16310                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16311                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16312                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16313                format_ip4_address, fp->next_hop);
16314       fp++;
16315     }
16316 }
16317
16318 static void vl_api_ip6_fib_details_t_handler_json
16319   (vl_api_ip6_fib_details_t * mp)
16320 {
16321   vat_main_t *vam = &vat_main;
16322   int count = ntohl (mp->count);
16323   vat_json_node_t *node = NULL;
16324   struct in_addr ip4;
16325   struct in6_addr ip6;
16326   vl_api_fib_path_t *fp;
16327   int i;
16328
16329   if (VAT_JSON_ARRAY != vam->json_tree.type)
16330     {
16331       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16332       vat_json_init_array (&vam->json_tree);
16333     }
16334   node = vat_json_array_add (&vam->json_tree);
16335
16336   vat_json_init_object (node);
16337   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16338   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16339   vat_json_object_add_ip6 (node, "prefix", ip6);
16340   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16341   vat_json_object_add_uint (node, "path_count", count);
16342   fp = mp->path;
16343   for (i = 0; i < count; i++)
16344     {
16345       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16346       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16347       vat_json_object_add_uint (node, "is_local", fp->is_local);
16348       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16349       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16350       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16351       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16352       if (fp->afi == IP46_TYPE_IP4)
16353         {
16354           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16355           vat_json_object_add_ip4 (node, "next_hop", ip4);
16356         }
16357       else if (fp->afi == IP46_TYPE_IP6)
16358         {
16359           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16360           vat_json_object_add_ip6 (node, "next_hop", ip6);
16361         }
16362     }
16363 }
16364
16365 static int
16366 api_ip6_fib_dump (vat_main_t * vam)
16367 {
16368   vl_api_ip6_fib_dump_t *mp;
16369   vl_api_control_ping_t *mp_ping;
16370   int ret;
16371
16372   M (IP6_FIB_DUMP, mp);
16373   S (mp);
16374
16375   /* Use a control ping for synchronization */
16376   M (CONTROL_PING, mp_ping);
16377   S (mp_ping);
16378
16379   W (ret);
16380   return ret;
16381 }
16382
16383 static int
16384 api_ip6_mfib_dump (vat_main_t * vam)
16385 {
16386   vl_api_ip6_mfib_dump_t *mp;
16387   vl_api_control_ping_t *mp_ping;
16388   int ret;
16389
16390   M (IP6_MFIB_DUMP, mp);
16391   S (mp);
16392
16393   /* Use a control ping for synchronization */
16394   M (CONTROL_PING, mp_ping);
16395   S (mp_ping);
16396
16397   W (ret);
16398   return ret;
16399 }
16400
16401 int
16402 api_classify_table_ids (vat_main_t * vam)
16403 {
16404   vl_api_classify_table_ids_t *mp;
16405   int ret;
16406
16407   /* Construct the API message */
16408   M (CLASSIFY_TABLE_IDS, mp);
16409   mp->context = 0;
16410
16411   S (mp);
16412   W (ret);
16413   return ret;
16414 }
16415
16416 int
16417 api_classify_table_by_interface (vat_main_t * vam)
16418 {
16419   unformat_input_t *input = vam->input;
16420   vl_api_classify_table_by_interface_t *mp;
16421
16422   u32 sw_if_index = ~0;
16423   int ret;
16424   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16425     {
16426       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16427         ;
16428       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16429         ;
16430       else
16431         break;
16432     }
16433   if (sw_if_index == ~0)
16434     {
16435       errmsg ("missing interface name or sw_if_index");
16436       return -99;
16437     }
16438
16439   /* Construct the API message */
16440   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16441   mp->context = 0;
16442   mp->sw_if_index = ntohl (sw_if_index);
16443
16444   S (mp);
16445   W (ret);
16446   return ret;
16447 }
16448
16449 int
16450 api_classify_table_info (vat_main_t * vam)
16451 {
16452   unformat_input_t *input = vam->input;
16453   vl_api_classify_table_info_t *mp;
16454
16455   u32 table_id = ~0;
16456   int ret;
16457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16458     {
16459       if (unformat (input, "table_id %d", &table_id))
16460         ;
16461       else
16462         break;
16463     }
16464   if (table_id == ~0)
16465     {
16466       errmsg ("missing table id");
16467       return -99;
16468     }
16469
16470   /* Construct the API message */
16471   M (CLASSIFY_TABLE_INFO, mp);
16472   mp->context = 0;
16473   mp->table_id = ntohl (table_id);
16474
16475   S (mp);
16476   W (ret);
16477   return ret;
16478 }
16479
16480 int
16481 api_classify_session_dump (vat_main_t * vam)
16482 {
16483   unformat_input_t *input = vam->input;
16484   vl_api_classify_session_dump_t *mp;
16485   vl_api_control_ping_t *mp_ping;
16486
16487   u32 table_id = ~0;
16488   int ret;
16489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16490     {
16491       if (unformat (input, "table_id %d", &table_id))
16492         ;
16493       else
16494         break;
16495     }
16496   if (table_id == ~0)
16497     {
16498       errmsg ("missing table id");
16499       return -99;
16500     }
16501
16502   /* Construct the API message */
16503   M (CLASSIFY_SESSION_DUMP, mp);
16504   mp->context = 0;
16505   mp->table_id = ntohl (table_id);
16506   S (mp);
16507
16508   /* Use a control ping for synchronization */
16509   M (CONTROL_PING, mp_ping);
16510   S (mp_ping);
16511
16512   W (ret);
16513   return ret;
16514 }
16515
16516 static void
16517 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16518 {
16519   vat_main_t *vam = &vat_main;
16520
16521   print (vam->ofp, "collector_address %U, collector_port %d, "
16522          "src_address %U, vrf_id %d, path_mtu %u, "
16523          "template_interval %u, udp_checksum %d",
16524          format_ip4_address, mp->collector_address,
16525          ntohs (mp->collector_port),
16526          format_ip4_address, mp->src_address,
16527          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16528          ntohl (mp->template_interval), mp->udp_checksum);
16529
16530   vam->retval = 0;
16531   vam->result_ready = 1;
16532 }
16533
16534 static void
16535   vl_api_ipfix_exporter_details_t_handler_json
16536   (vl_api_ipfix_exporter_details_t * mp)
16537 {
16538   vat_main_t *vam = &vat_main;
16539   vat_json_node_t node;
16540   struct in_addr collector_address;
16541   struct in_addr src_address;
16542
16543   vat_json_init_object (&node);
16544   clib_memcpy (&collector_address, &mp->collector_address,
16545                sizeof (collector_address));
16546   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16547   vat_json_object_add_uint (&node, "collector_port",
16548                             ntohs (mp->collector_port));
16549   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16550   vat_json_object_add_ip4 (&node, "src_address", src_address);
16551   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16552   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16553   vat_json_object_add_uint (&node, "template_interval",
16554                             ntohl (mp->template_interval));
16555   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16556
16557   vat_json_print (vam->ofp, &node);
16558   vat_json_free (&node);
16559   vam->retval = 0;
16560   vam->result_ready = 1;
16561 }
16562
16563 int
16564 api_ipfix_exporter_dump (vat_main_t * vam)
16565 {
16566   vl_api_ipfix_exporter_dump_t *mp;
16567   int ret;
16568
16569   /* Construct the API message */
16570   M (IPFIX_EXPORTER_DUMP, mp);
16571   mp->context = 0;
16572
16573   S (mp);
16574   W (ret);
16575   return ret;
16576 }
16577
16578 static int
16579 api_ipfix_classify_stream_dump (vat_main_t * vam)
16580 {
16581   vl_api_ipfix_classify_stream_dump_t *mp;
16582   int ret;
16583
16584   /* Construct the API message */
16585   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16586   mp->context = 0;
16587
16588   S (mp);
16589   W (ret);
16590   return ret;
16591   /* NOTREACHED */
16592   return 0;
16593 }
16594
16595 static void
16596   vl_api_ipfix_classify_stream_details_t_handler
16597   (vl_api_ipfix_classify_stream_details_t * mp)
16598 {
16599   vat_main_t *vam = &vat_main;
16600   print (vam->ofp, "domain_id %d, src_port %d",
16601          ntohl (mp->domain_id), ntohs (mp->src_port));
16602   vam->retval = 0;
16603   vam->result_ready = 1;
16604 }
16605
16606 static void
16607   vl_api_ipfix_classify_stream_details_t_handler_json
16608   (vl_api_ipfix_classify_stream_details_t * mp)
16609 {
16610   vat_main_t *vam = &vat_main;
16611   vat_json_node_t node;
16612
16613   vat_json_init_object (&node);
16614   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16615   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16616
16617   vat_json_print (vam->ofp, &node);
16618   vat_json_free (&node);
16619   vam->retval = 0;
16620   vam->result_ready = 1;
16621 }
16622
16623 static int
16624 api_ipfix_classify_table_dump (vat_main_t * vam)
16625 {
16626   vl_api_ipfix_classify_table_dump_t *mp;
16627   vl_api_control_ping_t *mp_ping;
16628   int ret;
16629
16630   if (!vam->json_output)
16631     {
16632       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16633              "transport_protocol");
16634     }
16635
16636   /* Construct the API message */
16637   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16638
16639   /* send it... */
16640   S (mp);
16641
16642   /* Use a control ping for synchronization */
16643   M (CONTROL_PING, mp_ping);
16644   S (mp_ping);
16645
16646   W (ret);
16647   return ret;
16648 }
16649
16650 static void
16651   vl_api_ipfix_classify_table_details_t_handler
16652   (vl_api_ipfix_classify_table_details_t * mp)
16653 {
16654   vat_main_t *vam = &vat_main;
16655   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16656          mp->transport_protocol);
16657 }
16658
16659 static void
16660   vl_api_ipfix_classify_table_details_t_handler_json
16661   (vl_api_ipfix_classify_table_details_t * mp)
16662 {
16663   vat_json_node_t *node = NULL;
16664   vat_main_t *vam = &vat_main;
16665
16666   if (VAT_JSON_ARRAY != vam->json_tree.type)
16667     {
16668       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16669       vat_json_init_array (&vam->json_tree);
16670     }
16671
16672   node = vat_json_array_add (&vam->json_tree);
16673   vat_json_init_object (node);
16674
16675   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16676   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16677   vat_json_object_add_uint (node, "transport_protocol",
16678                             mp->transport_protocol);
16679 }
16680
16681 static int
16682 api_sw_interface_span_enable_disable (vat_main_t * vam)
16683 {
16684   unformat_input_t *i = vam->input;
16685   vl_api_sw_interface_span_enable_disable_t *mp;
16686   u32 src_sw_if_index = ~0;
16687   u32 dst_sw_if_index = ~0;
16688   u8 state = 3;
16689   int ret;
16690
16691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16692     {
16693       if (unformat
16694           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16695         ;
16696       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16697         ;
16698       else
16699         if (unformat
16700             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16701         ;
16702       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16703         ;
16704       else if (unformat (i, "disable"))
16705         state = 0;
16706       else if (unformat (i, "rx"))
16707         state = 1;
16708       else if (unformat (i, "tx"))
16709         state = 2;
16710       else if (unformat (i, "both"))
16711         state = 3;
16712       else
16713         break;
16714     }
16715
16716   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16717
16718   mp->sw_if_index_from = htonl (src_sw_if_index);
16719   mp->sw_if_index_to = htonl (dst_sw_if_index);
16720   mp->state = state;
16721
16722   S (mp);
16723   W (ret);
16724   return ret;
16725 }
16726
16727 static void
16728 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16729                                             * mp)
16730 {
16731   vat_main_t *vam = &vat_main;
16732   u8 *sw_if_from_name = 0;
16733   u8 *sw_if_to_name = 0;
16734   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16735   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16736   char *states[] = { "none", "rx", "tx", "both" };
16737   hash_pair_t *p;
16738
16739   /* *INDENT-OFF* */
16740   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16741   ({
16742     if ((u32) p->value[0] == sw_if_index_from)
16743       {
16744         sw_if_from_name = (u8 *)(p->key);
16745         if (sw_if_to_name)
16746           break;
16747       }
16748     if ((u32) p->value[0] == sw_if_index_to)
16749       {
16750         sw_if_to_name = (u8 *)(p->key);
16751         if (sw_if_from_name)
16752           break;
16753       }
16754   }));
16755   /* *INDENT-ON* */
16756   print (vam->ofp, "%20s => %20s (%s)",
16757          sw_if_from_name, sw_if_to_name, states[mp->state]);
16758 }
16759
16760 static void
16761   vl_api_sw_interface_span_details_t_handler_json
16762   (vl_api_sw_interface_span_details_t * mp)
16763 {
16764   vat_main_t *vam = &vat_main;
16765   vat_json_node_t *node = NULL;
16766   u8 *sw_if_from_name = 0;
16767   u8 *sw_if_to_name = 0;
16768   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16769   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16770   hash_pair_t *p;
16771
16772   /* *INDENT-OFF* */
16773   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16774   ({
16775     if ((u32) p->value[0] == sw_if_index_from)
16776       {
16777         sw_if_from_name = (u8 *)(p->key);
16778         if (sw_if_to_name)
16779           break;
16780       }
16781     if ((u32) p->value[0] == sw_if_index_to)
16782       {
16783         sw_if_to_name = (u8 *)(p->key);
16784         if (sw_if_from_name)
16785           break;
16786       }
16787   }));
16788   /* *INDENT-ON* */
16789
16790   if (VAT_JSON_ARRAY != vam->json_tree.type)
16791     {
16792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16793       vat_json_init_array (&vam->json_tree);
16794     }
16795   node = vat_json_array_add (&vam->json_tree);
16796
16797   vat_json_init_object (node);
16798   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16799   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16800   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16801   if (0 != sw_if_to_name)
16802     {
16803       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16804     }
16805   vat_json_object_add_uint (node, "state", mp->state);
16806 }
16807
16808 static int
16809 api_sw_interface_span_dump (vat_main_t * vam)
16810 {
16811   vl_api_sw_interface_span_dump_t *mp;
16812   vl_api_control_ping_t *mp_ping;
16813   int ret;
16814
16815   M (SW_INTERFACE_SPAN_DUMP, mp);
16816   S (mp);
16817
16818   /* Use a control ping for synchronization */
16819   M (CONTROL_PING, mp_ping);
16820   S (mp_ping);
16821
16822   W (ret);
16823   return ret;
16824 }
16825
16826 int
16827 api_pg_create_interface (vat_main_t * vam)
16828 {
16829   unformat_input_t *input = vam->input;
16830   vl_api_pg_create_interface_t *mp;
16831
16832   u32 if_id = ~0;
16833   int ret;
16834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16835     {
16836       if (unformat (input, "if_id %d", &if_id))
16837         ;
16838       else
16839         break;
16840     }
16841   if (if_id == ~0)
16842     {
16843       errmsg ("missing pg interface index");
16844       return -99;
16845     }
16846
16847   /* Construct the API message */
16848   M (PG_CREATE_INTERFACE, mp);
16849   mp->context = 0;
16850   mp->interface_id = ntohl (if_id);
16851
16852   S (mp);
16853   W (ret);
16854   return ret;
16855 }
16856
16857 int
16858 api_pg_capture (vat_main_t * vam)
16859 {
16860   unformat_input_t *input = vam->input;
16861   vl_api_pg_capture_t *mp;
16862
16863   u32 if_id = ~0;
16864   u8 enable = 1;
16865   u32 count = 1;
16866   u8 pcap_file_set = 0;
16867   u8 *pcap_file = 0;
16868   int ret;
16869   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16870     {
16871       if (unformat (input, "if_id %d", &if_id))
16872         ;
16873       else if (unformat (input, "pcap %s", &pcap_file))
16874         pcap_file_set = 1;
16875       else if (unformat (input, "count %d", &count))
16876         ;
16877       else if (unformat (input, "disable"))
16878         enable = 0;
16879       else
16880         break;
16881     }
16882   if (if_id == ~0)
16883     {
16884       errmsg ("missing pg interface index");
16885       return -99;
16886     }
16887   if (pcap_file_set > 0)
16888     {
16889       if (vec_len (pcap_file) > 255)
16890         {
16891           errmsg ("pcap file name is too long");
16892           return -99;
16893         }
16894     }
16895
16896   u32 name_len = vec_len (pcap_file);
16897   /* Construct the API message */
16898   M (PG_CAPTURE, mp);
16899   mp->context = 0;
16900   mp->interface_id = ntohl (if_id);
16901   mp->is_enabled = enable;
16902   mp->count = ntohl (count);
16903   mp->pcap_name_length = ntohl (name_len);
16904   if (pcap_file_set != 0)
16905     {
16906       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16907     }
16908   vec_free (pcap_file);
16909
16910   S (mp);
16911   W (ret);
16912   return ret;
16913 }
16914
16915 int
16916 api_pg_enable_disable (vat_main_t * vam)
16917 {
16918   unformat_input_t *input = vam->input;
16919   vl_api_pg_enable_disable_t *mp;
16920
16921   u8 enable = 1;
16922   u8 stream_name_set = 0;
16923   u8 *stream_name = 0;
16924   int ret;
16925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16926     {
16927       if (unformat (input, "stream %s", &stream_name))
16928         stream_name_set = 1;
16929       else if (unformat (input, "disable"))
16930         enable = 0;
16931       else
16932         break;
16933     }
16934
16935   if (stream_name_set > 0)
16936     {
16937       if (vec_len (stream_name) > 255)
16938         {
16939           errmsg ("stream name too long");
16940           return -99;
16941         }
16942     }
16943
16944   u32 name_len = vec_len (stream_name);
16945   /* Construct the API message */
16946   M (PG_ENABLE_DISABLE, mp);
16947   mp->context = 0;
16948   mp->is_enabled = enable;
16949   if (stream_name_set != 0)
16950     {
16951       mp->stream_name_length = ntohl (name_len);
16952       clib_memcpy (mp->stream_name, stream_name, name_len);
16953     }
16954   vec_free (stream_name);
16955
16956   S (mp);
16957   W (ret);
16958   return ret;
16959 }
16960
16961 int
16962 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16963 {
16964   unformat_input_t *input = vam->input;
16965   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16966
16967   u16 *low_ports = 0;
16968   u16 *high_ports = 0;
16969   u16 this_low;
16970   u16 this_hi;
16971   ip4_address_t ip4_addr;
16972   ip6_address_t ip6_addr;
16973   u32 length;
16974   u32 tmp, tmp2;
16975   u8 prefix_set = 0;
16976   u32 vrf_id = ~0;
16977   u8 is_add = 1;
16978   u8 is_ipv6 = 0;
16979   int ret;
16980
16981   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16982     {
16983       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16984         {
16985           prefix_set = 1;
16986         }
16987       else
16988         if (unformat
16989             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16990         {
16991           prefix_set = 1;
16992           is_ipv6 = 1;
16993         }
16994       else if (unformat (input, "vrf %d", &vrf_id))
16995         ;
16996       else if (unformat (input, "del"))
16997         is_add = 0;
16998       else if (unformat (input, "port %d", &tmp))
16999         {
17000           if (tmp == 0 || tmp > 65535)
17001             {
17002               errmsg ("port %d out of range", tmp);
17003               return -99;
17004             }
17005           this_low = tmp;
17006           this_hi = this_low + 1;
17007           vec_add1 (low_ports, this_low);
17008           vec_add1 (high_ports, this_hi);
17009         }
17010       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17011         {
17012           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17013             {
17014               errmsg ("incorrect range parameters");
17015               return -99;
17016             }
17017           this_low = tmp;
17018           /* Note: in debug CLI +1 is added to high before
17019              passing to real fn that does "the work"
17020              (ip_source_and_port_range_check_add_del).
17021              This fn is a wrapper around the binary API fn a
17022              control plane will call, which expects this increment
17023              to have occurred. Hence letting the binary API control
17024              plane fn do the increment for consistency between VAT
17025              and other control planes.
17026            */
17027           this_hi = tmp2;
17028           vec_add1 (low_ports, this_low);
17029           vec_add1 (high_ports, this_hi);
17030         }
17031       else
17032         break;
17033     }
17034
17035   if (prefix_set == 0)
17036     {
17037       errmsg ("<address>/<mask> not specified");
17038       return -99;
17039     }
17040
17041   if (vrf_id == ~0)
17042     {
17043       errmsg ("VRF ID required, not specified");
17044       return -99;
17045     }
17046
17047   if (vrf_id == 0)
17048     {
17049       errmsg
17050         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17051       return -99;
17052     }
17053
17054   if (vec_len (low_ports) == 0)
17055     {
17056       errmsg ("At least one port or port range required");
17057       return -99;
17058     }
17059
17060   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17061
17062   mp->is_add = is_add;
17063
17064   if (is_ipv6)
17065     {
17066       mp->is_ipv6 = 1;
17067       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17068     }
17069   else
17070     {
17071       mp->is_ipv6 = 0;
17072       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17073     }
17074
17075   mp->mask_length = length;
17076   mp->number_of_ranges = vec_len (low_ports);
17077
17078   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17079   vec_free (low_ports);
17080
17081   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17082   vec_free (high_ports);
17083
17084   mp->vrf_id = ntohl (vrf_id);
17085
17086   S (mp);
17087   W (ret);
17088   return ret;
17089 }
17090
17091 int
17092 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17093 {
17094   unformat_input_t *input = vam->input;
17095   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17096   u32 sw_if_index = ~0;
17097   int vrf_set = 0;
17098   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17099   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17100   u8 is_add = 1;
17101   int ret;
17102
17103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17104     {
17105       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17106         ;
17107       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17108         ;
17109       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17110         vrf_set = 1;
17111       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17112         vrf_set = 1;
17113       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17114         vrf_set = 1;
17115       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17116         vrf_set = 1;
17117       else if (unformat (input, "del"))
17118         is_add = 0;
17119       else
17120         break;
17121     }
17122
17123   if (sw_if_index == ~0)
17124     {
17125       errmsg ("Interface required but not specified");
17126       return -99;
17127     }
17128
17129   if (vrf_set == 0)
17130     {
17131       errmsg ("VRF ID required but not specified");
17132       return -99;
17133     }
17134
17135   if (tcp_out_vrf_id == 0
17136       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17137     {
17138       errmsg
17139         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17140       return -99;
17141     }
17142
17143   /* Construct the API message */
17144   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17145
17146   mp->sw_if_index = ntohl (sw_if_index);
17147   mp->is_add = is_add;
17148   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17149   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17150   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17151   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17152
17153   /* send it... */
17154   S (mp);
17155
17156   /* Wait for a reply... */
17157   W (ret);
17158   return ret;
17159 }
17160
17161 static int
17162 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17163 {
17164   unformat_input_t *i = vam->input;
17165   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17166   u32 local_sa_id = 0;
17167   u32 remote_sa_id = 0;
17168   ip4_address_t src_address;
17169   ip4_address_t dst_address;
17170   u8 is_add = 1;
17171   int ret;
17172
17173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17174     {
17175       if (unformat (i, "local_sa %d", &local_sa_id))
17176         ;
17177       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17178         ;
17179       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17180         ;
17181       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17182         ;
17183       else if (unformat (i, "del"))
17184         is_add = 0;
17185       else
17186         {
17187           clib_warning ("parse error '%U'", format_unformat_error, i);
17188           return -99;
17189         }
17190     }
17191
17192   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17193
17194   mp->local_sa_id = ntohl (local_sa_id);
17195   mp->remote_sa_id = ntohl (remote_sa_id);
17196   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17197   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17198   mp->is_add = is_add;
17199
17200   S (mp);
17201   W (ret);
17202   return ret;
17203 }
17204
17205 static int
17206 api_punt (vat_main_t * vam)
17207 {
17208   unformat_input_t *i = vam->input;
17209   vl_api_punt_t *mp;
17210   u32 ipv = ~0;
17211   u32 protocol = ~0;
17212   u32 port = ~0;
17213   int is_add = 1;
17214   int ret;
17215
17216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17217     {
17218       if (unformat (i, "ip %d", &ipv))
17219         ;
17220       else if (unformat (i, "protocol %d", &protocol))
17221         ;
17222       else if (unformat (i, "port %d", &port))
17223         ;
17224       else if (unformat (i, "del"))
17225         is_add = 0;
17226       else
17227         {
17228           clib_warning ("parse error '%U'", format_unformat_error, i);
17229           return -99;
17230         }
17231     }
17232
17233   M (PUNT, mp);
17234
17235   mp->is_add = (u8) is_add;
17236   mp->ipv = (u8) ipv;
17237   mp->l4_protocol = (u8) protocol;
17238   mp->l4_port = htons ((u16) port);
17239
17240   S (mp);
17241   W (ret);
17242   return ret;
17243 }
17244
17245 static void vl_api_ipsec_gre_tunnel_details_t_handler
17246   (vl_api_ipsec_gre_tunnel_details_t * mp)
17247 {
17248   vat_main_t *vam = &vat_main;
17249
17250   print (vam->ofp, "%11d%15U%15U%14d%14d",
17251          ntohl (mp->sw_if_index),
17252          format_ip4_address, &mp->src_address,
17253          format_ip4_address, &mp->dst_address,
17254          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17255 }
17256
17257 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17258   (vl_api_ipsec_gre_tunnel_details_t * mp)
17259 {
17260   vat_main_t *vam = &vat_main;
17261   vat_json_node_t *node = NULL;
17262   struct in_addr ip4;
17263
17264   if (VAT_JSON_ARRAY != vam->json_tree.type)
17265     {
17266       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17267       vat_json_init_array (&vam->json_tree);
17268     }
17269   node = vat_json_array_add (&vam->json_tree);
17270
17271   vat_json_init_object (node);
17272   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17273   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17274   vat_json_object_add_ip4 (node, "src_address", ip4);
17275   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17276   vat_json_object_add_ip4 (node, "dst_address", ip4);
17277   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17278   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17279 }
17280
17281 static int
17282 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17283 {
17284   unformat_input_t *i = vam->input;
17285   vl_api_ipsec_gre_tunnel_dump_t *mp;
17286   vl_api_control_ping_t *mp_ping;
17287   u32 sw_if_index;
17288   u8 sw_if_index_set = 0;
17289   int ret;
17290
17291   /* Parse args required to build the message */
17292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17293     {
17294       if (unformat (i, "sw_if_index %d", &sw_if_index))
17295         sw_if_index_set = 1;
17296       else
17297         break;
17298     }
17299
17300   if (sw_if_index_set == 0)
17301     {
17302       sw_if_index = ~0;
17303     }
17304
17305   if (!vam->json_output)
17306     {
17307       print (vam->ofp, "%11s%15s%15s%14s%14s",
17308              "sw_if_index", "src_address", "dst_address",
17309              "local_sa_id", "remote_sa_id");
17310     }
17311
17312   /* Get list of gre-tunnel interfaces */
17313   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17314
17315   mp->sw_if_index = htonl (sw_if_index);
17316
17317   S (mp);
17318
17319   /* Use a control ping for synchronization */
17320   M (CONTROL_PING, mp_ping);
17321   S (mp_ping);
17322
17323   W (ret);
17324   return ret;
17325 }
17326
17327 static int
17328 api_delete_subif (vat_main_t * vam)
17329 {
17330   unformat_input_t *i = vam->input;
17331   vl_api_delete_subif_t *mp;
17332   u32 sw_if_index = ~0;
17333   int ret;
17334
17335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17336     {
17337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17338         ;
17339       if (unformat (i, "sw_if_index %d", &sw_if_index))
17340         ;
17341       else
17342         break;
17343     }
17344
17345   if (sw_if_index == ~0)
17346     {
17347       errmsg ("missing sw_if_index");
17348       return -99;
17349     }
17350
17351   /* Construct the API message */
17352   M (DELETE_SUBIF, mp);
17353   mp->sw_if_index = ntohl (sw_if_index);
17354
17355   S (mp);
17356   W (ret);
17357   return ret;
17358 }
17359
17360 #define foreach_pbb_vtr_op      \
17361 _("disable",  L2_VTR_DISABLED)  \
17362 _("pop",  L2_VTR_POP_2)         \
17363 _("push",  L2_VTR_PUSH_2)
17364
17365 static int
17366 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17367 {
17368   unformat_input_t *i = vam->input;
17369   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17370   u32 sw_if_index = ~0, vtr_op = ~0;
17371   u16 outer_tag = ~0;
17372   u8 dmac[6], smac[6];
17373   u8 dmac_set = 0, smac_set = 0;
17374   u16 vlanid = 0;
17375   u32 sid = ~0;
17376   u32 tmp;
17377   int ret;
17378
17379   /* Shut up coverity */
17380   memset (dmac, 0, sizeof (dmac));
17381   memset (smac, 0, sizeof (smac));
17382
17383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17384     {
17385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17386         ;
17387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17388         ;
17389       else if (unformat (i, "vtr_op %d", &vtr_op))
17390         ;
17391 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17392       foreach_pbb_vtr_op
17393 #undef _
17394         else if (unformat (i, "translate_pbb_stag"))
17395         {
17396           if (unformat (i, "%d", &tmp))
17397             {
17398               vtr_op = L2_VTR_TRANSLATE_2_1;
17399               outer_tag = tmp;
17400             }
17401           else
17402             {
17403               errmsg
17404                 ("translate_pbb_stag operation requires outer tag definition");
17405               return -99;
17406             }
17407         }
17408       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17409         dmac_set++;
17410       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17411         smac_set++;
17412       else if (unformat (i, "sid %d", &sid))
17413         ;
17414       else if (unformat (i, "vlanid %d", &tmp))
17415         vlanid = tmp;
17416       else
17417         {
17418           clib_warning ("parse error '%U'", format_unformat_error, i);
17419           return -99;
17420         }
17421     }
17422
17423   if ((sw_if_index == ~0) || (vtr_op == ~0))
17424     {
17425       errmsg ("missing sw_if_index or vtr operation");
17426       return -99;
17427     }
17428   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17429       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17430     {
17431       errmsg
17432         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17433       return -99;
17434     }
17435
17436   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17437   mp->sw_if_index = ntohl (sw_if_index);
17438   mp->vtr_op = ntohl (vtr_op);
17439   mp->outer_tag = ntohs (outer_tag);
17440   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17441   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17442   mp->b_vlanid = ntohs (vlanid);
17443   mp->i_sid = ntohl (sid);
17444
17445   S (mp);
17446   W (ret);
17447   return ret;
17448 }
17449
17450 static int
17451 api_flow_classify_set_interface (vat_main_t * vam)
17452 {
17453   unformat_input_t *i = vam->input;
17454   vl_api_flow_classify_set_interface_t *mp;
17455   u32 sw_if_index;
17456   int sw_if_index_set;
17457   u32 ip4_table_index = ~0;
17458   u32 ip6_table_index = ~0;
17459   u8 is_add = 1;
17460   int ret;
17461
17462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17463     {
17464       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17465         sw_if_index_set = 1;
17466       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17467         sw_if_index_set = 1;
17468       else if (unformat (i, "del"))
17469         is_add = 0;
17470       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17471         ;
17472       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17473         ;
17474       else
17475         {
17476           clib_warning ("parse error '%U'", format_unformat_error, i);
17477           return -99;
17478         }
17479     }
17480
17481   if (sw_if_index_set == 0)
17482     {
17483       errmsg ("missing interface name or sw_if_index");
17484       return -99;
17485     }
17486
17487   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17488
17489   mp->sw_if_index = ntohl (sw_if_index);
17490   mp->ip4_table_index = ntohl (ip4_table_index);
17491   mp->ip6_table_index = ntohl (ip6_table_index);
17492   mp->is_add = is_add;
17493
17494   S (mp);
17495   W (ret);
17496   return ret;
17497 }
17498
17499 static int
17500 api_flow_classify_dump (vat_main_t * vam)
17501 {
17502   unformat_input_t *i = vam->input;
17503   vl_api_flow_classify_dump_t *mp;
17504   vl_api_control_ping_t *mp_ping;
17505   u8 type = FLOW_CLASSIFY_N_TABLES;
17506   int ret;
17507
17508   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17509     ;
17510   else
17511     {
17512       errmsg ("classify table type must be specified");
17513       return -99;
17514     }
17515
17516   if (!vam->json_output)
17517     {
17518       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17519     }
17520
17521   M (FLOW_CLASSIFY_DUMP, mp);
17522   mp->type = type;
17523   /* send it... */
17524   S (mp);
17525
17526   /* Use a control ping for synchronization */
17527   M (CONTROL_PING, mp_ping);
17528   S (mp_ping);
17529
17530   /* Wait for a reply... */
17531   W (ret);
17532   return ret;
17533 }
17534
17535 static int
17536 api_feature_enable_disable (vat_main_t * vam)
17537 {
17538   unformat_input_t *i = vam->input;
17539   vl_api_feature_enable_disable_t *mp;
17540   u8 *arc_name = 0;
17541   u8 *feature_name = 0;
17542   u32 sw_if_index = ~0;
17543   u8 enable = 1;
17544   int ret;
17545
17546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17547     {
17548       if (unformat (i, "arc_name %s", &arc_name))
17549         ;
17550       else if (unformat (i, "feature_name %s", &feature_name))
17551         ;
17552       else
17553         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17554         ;
17555       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17556         ;
17557       else if (unformat (i, "disable"))
17558         enable = 0;
17559       else
17560         break;
17561     }
17562
17563   if (arc_name == 0)
17564     {
17565       errmsg ("missing arc name");
17566       return -99;
17567     }
17568   if (vec_len (arc_name) > 63)
17569     {
17570       errmsg ("arc name too long");
17571     }
17572
17573   if (feature_name == 0)
17574     {
17575       errmsg ("missing feature name");
17576       return -99;
17577     }
17578   if (vec_len (feature_name) > 63)
17579     {
17580       errmsg ("feature name too long");
17581     }
17582
17583   if (sw_if_index == ~0)
17584     {
17585       errmsg ("missing interface name or sw_if_index");
17586       return -99;
17587     }
17588
17589   /* Construct the API message */
17590   M (FEATURE_ENABLE_DISABLE, mp);
17591   mp->sw_if_index = ntohl (sw_if_index);
17592   mp->enable = enable;
17593   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17594   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17595   vec_free (arc_name);
17596   vec_free (feature_name);
17597
17598   S (mp);
17599   W (ret);
17600   return ret;
17601 }
17602
17603 static int
17604 api_sw_interface_tag_add_del (vat_main_t * vam)
17605 {
17606   unformat_input_t *i = vam->input;
17607   vl_api_sw_interface_tag_add_del_t *mp;
17608   u32 sw_if_index = ~0;
17609   u8 *tag = 0;
17610   u8 enable = 1;
17611   int ret;
17612
17613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17614     {
17615       if (unformat (i, "tag %s", &tag))
17616         ;
17617       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17618         ;
17619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17620         ;
17621       else if (unformat (i, "del"))
17622         enable = 0;
17623       else
17624         break;
17625     }
17626
17627   if (sw_if_index == ~0)
17628     {
17629       errmsg ("missing interface name or sw_if_index");
17630       return -99;
17631     }
17632
17633   if (enable && (tag == 0))
17634     {
17635       errmsg ("no tag specified");
17636       return -99;
17637     }
17638
17639   /* Construct the API message */
17640   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17641   mp->sw_if_index = ntohl (sw_if_index);
17642   mp->is_add = enable;
17643   if (enable)
17644     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17645   vec_free (tag);
17646
17647   S (mp);
17648   W (ret);
17649   return ret;
17650 }
17651
17652 static void vl_api_l2_xconnect_details_t_handler
17653   (vl_api_l2_xconnect_details_t * mp)
17654 {
17655   vat_main_t *vam = &vat_main;
17656
17657   print (vam->ofp, "%15d%15d",
17658          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17659 }
17660
17661 static void vl_api_l2_xconnect_details_t_handler_json
17662   (vl_api_l2_xconnect_details_t * mp)
17663 {
17664   vat_main_t *vam = &vat_main;
17665   vat_json_node_t *node = NULL;
17666
17667   if (VAT_JSON_ARRAY != vam->json_tree.type)
17668     {
17669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17670       vat_json_init_array (&vam->json_tree);
17671     }
17672   node = vat_json_array_add (&vam->json_tree);
17673
17674   vat_json_init_object (node);
17675   vat_json_object_add_uint (node, "rx_sw_if_index",
17676                             ntohl (mp->rx_sw_if_index));
17677   vat_json_object_add_uint (node, "tx_sw_if_index",
17678                             ntohl (mp->tx_sw_if_index));
17679 }
17680
17681 static int
17682 api_l2_xconnect_dump (vat_main_t * vam)
17683 {
17684   vl_api_l2_xconnect_dump_t *mp;
17685   vl_api_control_ping_t *mp_ping;
17686   int ret;
17687
17688   if (!vam->json_output)
17689     {
17690       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17691     }
17692
17693   M (L2_XCONNECT_DUMP, mp);
17694
17695   S (mp);
17696
17697   /* Use a control ping for synchronization */
17698   M (CONTROL_PING, mp_ping);
17699   S (mp_ping);
17700
17701   W (ret);
17702   return ret;
17703 }
17704
17705 static int
17706 api_sw_interface_set_mtu (vat_main_t * vam)
17707 {
17708   unformat_input_t *i = vam->input;
17709   vl_api_sw_interface_set_mtu_t *mp;
17710   u32 sw_if_index = ~0;
17711   u32 mtu = 0;
17712   int ret;
17713
17714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17715     {
17716       if (unformat (i, "mtu %d", &mtu))
17717         ;
17718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17719         ;
17720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17721         ;
17722       else
17723         break;
17724     }
17725
17726   if (sw_if_index == ~0)
17727     {
17728       errmsg ("missing interface name or sw_if_index");
17729       return -99;
17730     }
17731
17732   if (mtu == 0)
17733     {
17734       errmsg ("no mtu specified");
17735       return -99;
17736     }
17737
17738   /* Construct the API message */
17739   M (SW_INTERFACE_SET_MTU, mp);
17740   mp->sw_if_index = ntohl (sw_if_index);
17741   mp->mtu = ntohs ((u16) mtu);
17742
17743   S (mp);
17744   W (ret);
17745   return ret;
17746 }
17747
17748
17749 static int
17750 q_or_quit (vat_main_t * vam)
17751 {
17752   longjmp (vam->jump_buf, 1);
17753   return 0;                     /* not so much */
17754 }
17755
17756 static int
17757 q (vat_main_t * vam)
17758 {
17759   return q_or_quit (vam);
17760 }
17761
17762 static int
17763 quit (vat_main_t * vam)
17764 {
17765   return q_or_quit (vam);
17766 }
17767
17768 static int
17769 comment (vat_main_t * vam)
17770 {
17771   return 0;
17772 }
17773
17774 static int
17775 cmd_cmp (void *a1, void *a2)
17776 {
17777   u8 **c1 = a1;
17778   u8 **c2 = a2;
17779
17780   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17781 }
17782
17783 static int
17784 help (vat_main_t * vam)
17785 {
17786   u8 **cmds = 0;
17787   u8 *name = 0;
17788   hash_pair_t *p;
17789   unformat_input_t *i = vam->input;
17790   int j;
17791
17792   if (unformat (i, "%s", &name))
17793     {
17794       uword *hs;
17795
17796       vec_add1 (name, 0);
17797
17798       hs = hash_get_mem (vam->help_by_name, name);
17799       if (hs)
17800         print (vam->ofp, "usage: %s %s", name, hs[0]);
17801       else
17802         print (vam->ofp, "No such msg / command '%s'", name);
17803       vec_free (name);
17804       return 0;
17805     }
17806
17807   print (vam->ofp, "Help is available for the following:");
17808
17809     /* *INDENT-OFF* */
17810     hash_foreach_pair (p, vam->function_by_name,
17811     ({
17812       vec_add1 (cmds, (u8 *)(p->key));
17813     }));
17814     /* *INDENT-ON* */
17815
17816   vec_sort_with_function (cmds, cmd_cmp);
17817
17818   for (j = 0; j < vec_len (cmds); j++)
17819     print (vam->ofp, "%s", cmds[j]);
17820
17821   vec_free (cmds);
17822   return 0;
17823 }
17824
17825 static int
17826 set (vat_main_t * vam)
17827 {
17828   u8 *name = 0, *value = 0;
17829   unformat_input_t *i = vam->input;
17830
17831   if (unformat (i, "%s", &name))
17832     {
17833       /* The input buffer is a vector, not a string. */
17834       value = vec_dup (i->buffer);
17835       vec_delete (value, i->index, 0);
17836       /* Almost certainly has a trailing newline */
17837       if (value[vec_len (value) - 1] == '\n')
17838         value[vec_len (value) - 1] = 0;
17839       /* Make sure it's a proper string, one way or the other */
17840       vec_add1 (value, 0);
17841       (void) clib_macro_set_value (&vam->macro_main,
17842                                    (char *) name, (char *) value);
17843     }
17844   else
17845     errmsg ("usage: set <name> <value>");
17846
17847   vec_free (name);
17848   vec_free (value);
17849   return 0;
17850 }
17851
17852 static int
17853 unset (vat_main_t * vam)
17854 {
17855   u8 *name = 0;
17856
17857   if (unformat (vam->input, "%s", &name))
17858     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17859       errmsg ("unset: %s wasn't set", name);
17860   vec_free (name);
17861   return 0;
17862 }
17863
17864 typedef struct
17865 {
17866   u8 *name;
17867   u8 *value;
17868 } macro_sort_t;
17869
17870
17871 static int
17872 macro_sort_cmp (void *a1, void *a2)
17873 {
17874   macro_sort_t *s1 = a1;
17875   macro_sort_t *s2 = a2;
17876
17877   return strcmp ((char *) (s1->name), (char *) (s2->name));
17878 }
17879
17880 static int
17881 dump_macro_table (vat_main_t * vam)
17882 {
17883   macro_sort_t *sort_me = 0, *sm;
17884   int i;
17885   hash_pair_t *p;
17886
17887     /* *INDENT-OFF* */
17888     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17889     ({
17890       vec_add2 (sort_me, sm, 1);
17891       sm->name = (u8 *)(p->key);
17892       sm->value = (u8 *) (p->value[0]);
17893     }));
17894     /* *INDENT-ON* */
17895
17896   vec_sort_with_function (sort_me, macro_sort_cmp);
17897
17898   if (vec_len (sort_me))
17899     print (vam->ofp, "%-15s%s", "Name", "Value");
17900   else
17901     print (vam->ofp, "The macro table is empty...");
17902
17903   for (i = 0; i < vec_len (sort_me); i++)
17904     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17905   return 0;
17906 }
17907
17908 static int
17909 dump_node_table (vat_main_t * vam)
17910 {
17911   int i, j;
17912   vlib_node_t *node, *next_node;
17913
17914   if (vec_len (vam->graph_nodes) == 0)
17915     {
17916       print (vam->ofp, "Node table empty, issue get_node_graph...");
17917       return 0;
17918     }
17919
17920   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17921     {
17922       node = vam->graph_nodes[i];
17923       print (vam->ofp, "[%d] %s", i, node->name);
17924       for (j = 0; j < vec_len (node->next_nodes); j++)
17925         {
17926           if (node->next_nodes[j] != ~0)
17927             {
17928               next_node = vam->graph_nodes[node->next_nodes[j]];
17929               print (vam->ofp, "  [%d] %s", j, next_node->name);
17930             }
17931         }
17932     }
17933   return 0;
17934 }
17935
17936 static int
17937 value_sort_cmp (void *a1, void *a2)
17938 {
17939   name_sort_t *n1 = a1;
17940   name_sort_t *n2 = a2;
17941
17942   if (n1->value < n2->value)
17943     return -1;
17944   if (n1->value > n2->value)
17945     return 1;
17946   return 0;
17947 }
17948
17949
17950 static int
17951 dump_msg_api_table (vat_main_t * vam)
17952 {
17953   api_main_t *am = &api_main;
17954   name_sort_t *nses = 0, *ns;
17955   hash_pair_t *hp;
17956   int i;
17957
17958   /* *INDENT-OFF* */
17959   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17960   ({
17961     vec_add2 (nses, ns, 1);
17962     ns->name = (u8 *)(hp->key);
17963     ns->value = (u32) hp->value[0];
17964   }));
17965   /* *INDENT-ON* */
17966
17967   vec_sort_with_function (nses, value_sort_cmp);
17968
17969   for (i = 0; i < vec_len (nses); i++)
17970     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17971   vec_free (nses);
17972   return 0;
17973 }
17974
17975 static int
17976 get_msg_id (vat_main_t * vam)
17977 {
17978   u8 *name_and_crc;
17979   u32 message_index;
17980
17981   if (unformat (vam->input, "%s", &name_and_crc))
17982     {
17983       message_index = vl_api_get_msg_index (name_and_crc);
17984       if (message_index == ~0)
17985         {
17986           print (vam->ofp, " '%s' not found", name_and_crc);
17987           return 0;
17988         }
17989       print (vam->ofp, " '%s' has message index %d",
17990              name_and_crc, message_index);
17991       return 0;
17992     }
17993   errmsg ("name_and_crc required...");
17994   return 0;
17995 }
17996
17997 static int
17998 search_node_table (vat_main_t * vam)
17999 {
18000   unformat_input_t *line_input = vam->input;
18001   u8 *node_to_find;
18002   int j;
18003   vlib_node_t *node, *next_node;
18004   uword *p;
18005
18006   if (vam->graph_node_index_by_name == 0)
18007     {
18008       print (vam->ofp, "Node table empty, issue get_node_graph...");
18009       return 0;
18010     }
18011
18012   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18013     {
18014       if (unformat (line_input, "%s", &node_to_find))
18015         {
18016           vec_add1 (node_to_find, 0);
18017           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18018           if (p == 0)
18019             {
18020               print (vam->ofp, "%s not found...", node_to_find);
18021               goto out;
18022             }
18023           node = vam->graph_nodes[p[0]];
18024           print (vam->ofp, "[%d] %s", p[0], node->name);
18025           for (j = 0; j < vec_len (node->next_nodes); j++)
18026             {
18027               if (node->next_nodes[j] != ~0)
18028                 {
18029                   next_node = vam->graph_nodes[node->next_nodes[j]];
18030                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18031                 }
18032             }
18033         }
18034
18035       else
18036         {
18037           clib_warning ("parse error '%U'", format_unformat_error,
18038                         line_input);
18039           return -99;
18040         }
18041
18042     out:
18043       vec_free (node_to_find);
18044
18045     }
18046
18047   return 0;
18048 }
18049
18050
18051 static int
18052 script (vat_main_t * vam)
18053 {
18054 #if (VPP_API_TEST_BUILTIN==0)
18055   u8 *s = 0;
18056   char *save_current_file;
18057   unformat_input_t save_input;
18058   jmp_buf save_jump_buf;
18059   u32 save_line_number;
18060
18061   FILE *new_fp, *save_ifp;
18062
18063   if (unformat (vam->input, "%s", &s))
18064     {
18065       new_fp = fopen ((char *) s, "r");
18066       if (new_fp == 0)
18067         {
18068           errmsg ("Couldn't open script file %s", s);
18069           vec_free (s);
18070           return -99;
18071         }
18072     }
18073   else
18074     {
18075       errmsg ("Missing script name");
18076       return -99;
18077     }
18078
18079   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18080   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18081   save_ifp = vam->ifp;
18082   save_line_number = vam->input_line_number;
18083   save_current_file = (char *) vam->current_file;
18084
18085   vam->input_line_number = 0;
18086   vam->ifp = new_fp;
18087   vam->current_file = s;
18088   do_one_file (vam);
18089
18090   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18091   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18092   vam->ifp = save_ifp;
18093   vam->input_line_number = save_line_number;
18094   vam->current_file = (u8 *) save_current_file;
18095   vec_free (s);
18096
18097   return 0;
18098 #else
18099   clib_warning ("use the exec command...");
18100   return -99;
18101 #endif
18102 }
18103
18104 static int
18105 echo (vat_main_t * vam)
18106 {
18107   print (vam->ofp, "%v", vam->input->buffer);
18108   return 0;
18109 }
18110
18111 /* List of API message constructors, CLI names map to api_xxx */
18112 #define foreach_vpe_api_msg                                             \
18113 _(create_loopback,"[mac <mac-addr>]")                                   \
18114 _(sw_interface_dump,"")                                                 \
18115 _(sw_interface_set_flags,                                               \
18116   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18117 _(sw_interface_add_del_address,                                         \
18118   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18119 _(sw_interface_set_table,                                               \
18120   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18121 _(sw_interface_set_mpls_enable,                                         \
18122   "<intfc> | sw_if_index [disable | dis]")                              \
18123 _(sw_interface_set_vpath,                                               \
18124   "<intfc> | sw_if_index <id> enable | disable")                        \
18125 _(sw_interface_set_vxlan_bypass,                                        \
18126   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18127 _(sw_interface_set_l2_xconnect,                                         \
18128   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18129   "enable | disable")                                                   \
18130 _(sw_interface_set_l2_bridge,                                           \
18131   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18132   "[shg <split-horizon-group>] [bvi]\n"                                 \
18133   "enable | disable")                                                   \
18134 _(bridge_domain_add_del,                                                \
18135   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18136 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18137 _(l2fib_add_del,                                                        \
18138   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18139 _(l2_flags,                                                             \
18140   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18141 _(bridge_flags,                                                         \
18142   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18143 _(tap_connect,                                                          \
18144   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18145 _(tap_modify,                                                           \
18146   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18147 _(tap_delete,                                                           \
18148   "<vpp-if-name> | sw_if_index <id>")                                   \
18149 _(sw_interface_tap_dump, "")                                            \
18150 _(ip_add_del_route,                                                     \
18151   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18152   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18153   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18154   "[multipath] [count <n>]")                                            \
18155 _(ip_mroute_add_del,                                                    \
18156   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18157   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18158 _(mpls_route_add_del,                                                   \
18159   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18160   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18161   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18162   "[multipath] [count <n>]")                                            \
18163 _(mpls_ip_bind_unbind,                                                  \
18164   "<label> <addr/len>")                                                 \
18165 _(mpls_tunnel_add_del,                                                  \
18166   " via <addr> [table-id <n>]\n"                                        \
18167   "sw_if_index <id>] [l2]  [del]")                                      \
18168 _(proxy_arp_add_del,                                                    \
18169   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18170 _(proxy_arp_intfc_enable_disable,                                       \
18171   "<intfc> | sw_if_index <id> enable | disable")                        \
18172 _(sw_interface_set_unnumbered,                                          \
18173   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18174 _(ip_neighbor_add_del,                                                  \
18175   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18176   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18177 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18178 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18179 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18180   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18181   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18182   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18183 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18184 _(reset_fib, "vrf <n> [ipv6]")                                          \
18185 _(dhcp_proxy_config,                                                    \
18186   "svr <v46-address> src <v46-address>\n"                               \
18187    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18188 _(dhcp_proxy_set_vss,                                                   \
18189   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18190 _(dhcp_proxy_dump, "ip6")                                               \
18191 _(dhcp_client_config,                                                   \
18192   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18193 _(set_ip_flow_hash,                                                     \
18194   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18195 _(sw_interface_ip6_enable_disable,                                      \
18196   "<intfc> | sw_if_index <id> enable | disable")                        \
18197 _(sw_interface_ip6_set_link_local_address,                              \
18198   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18199 _(sw_interface_ip6nd_ra_prefix,                                         \
18200   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18201   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18202   "[nolink] [isno]")                                                    \
18203 _(sw_interface_ip6nd_ra_config,                                         \
18204   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18205   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18206   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18207 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18208 _(l2_patch_add_del,                                                     \
18209   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18210   "enable | disable")                                                   \
18211 _(sr_tunnel_add_del,                                                    \
18212   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
18213   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
18214   "[policy <policy_name>]")                                             \
18215 _(sr_policy_add_del,                                                    \
18216   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
18217 _(sr_multicast_map_add_del,                                             \
18218   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
18219 _(classify_add_del_table,                                               \
18220   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18221   " [del] [del-chain] mask <mask-value>\n"                              \
18222   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18223   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18224 _(classify_add_del_session,                                             \
18225   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18226   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18227   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18228   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18229 _(classify_set_interface_ip_table,                                      \
18230   "<intfc> | sw_if_index <nn> table <nn>")                              \
18231 _(classify_set_interface_l2_tables,                                     \
18232   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18233   "  [other-table <nn>]")                                               \
18234 _(get_node_index, "node <node-name")                                    \
18235 _(add_node_next, "node <node-name> next <next-node-name>")              \
18236 _(l2tpv3_create_tunnel,                                                 \
18237   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18238   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18239   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18240 _(l2tpv3_set_tunnel_cookies,                                            \
18241   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18242   "[new_remote_cookie <nn>]\n")                                         \
18243 _(l2tpv3_interface_enable_disable,                                      \
18244   "<intfc> | sw_if_index <nn> enable | disable")                        \
18245 _(l2tpv3_set_lookup_key,                                                \
18246   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18247 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18248 _(vxlan_add_del_tunnel,                                                 \
18249   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18250   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18251   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18252 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18253 _(gre_add_del_tunnel,                                                   \
18254   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18255 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18256 _(l2_fib_clear_table, "")                                               \
18257 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18258 _(l2_interface_vlan_tag_rewrite,                                        \
18259   "<intfc> | sw_if_index <nn> \n"                                       \
18260   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18261   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18262 _(create_vhost_user_if,                                                 \
18263         "socket <filename> [server] [renumber <dev_instance>] "         \
18264         "[mac <mac_address>]")                                          \
18265 _(modify_vhost_user_if,                                                 \
18266         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18267         "[server] [renumber <dev_instance>]")                           \
18268 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18269 _(sw_interface_vhost_user_dump, "")                                     \
18270 _(show_version, "")                                                     \
18271 _(vxlan_gpe_add_del_tunnel,                                             \
18272   "local <addr> remote <addr> vni <nn>\n"                               \
18273     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18274   "[next-ethernet] [next-nsh]\n")                                       \
18275 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18276 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18277 _(interface_name_renumber,                                              \
18278   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18279 _(input_acl_set_interface,                                              \
18280   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18281   "  [l2-table <nn>] [del]")                                            \
18282 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18283 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18284 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18285 _(ip_dump, "ipv4 | ipv6")                                               \
18286 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18287 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18288   "  spid_id <n> ")                                                     \
18289 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18290   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18291   "  integ_alg <alg> integ_key <hex>")                                  \
18292 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18293   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18294   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18295   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18296 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18297 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18298 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18299   "(auth_data 0x<data> | auth_data <data>)")                            \
18300 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18301   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18302 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18303   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18304   "(local|remote)")                                                     \
18305 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18306 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18307 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18308 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18309 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18310 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18311 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18312 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18313 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18314 _(delete_loopback,"sw_if_index <nn>")                                   \
18315 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18316 _(map_add_domain,                                                       \
18317   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18318   "ip6-src <ip6addr> "                                                  \
18319   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18320 _(map_del_domain, "index <n>")                                          \
18321 _(map_add_del_rule,                                                     \
18322   "index <n> psid <n> dst <ip6addr> [del]")                             \
18323 _(map_domain_dump, "")                                                  \
18324 _(map_rule_dump, "index <map-domain>")                                  \
18325 _(want_interface_events,  "enable|disable")                             \
18326 _(want_stats,"enable|disable")                                          \
18327 _(get_first_msg_id, "client <name>")                                    \
18328 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18329 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18330   "fib-id <nn> [ip4][ip6][default]")                                    \
18331 _(get_node_graph, " ")                                                  \
18332 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18333 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18334 _(ioam_disable, "")                                                     \
18335 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18336                             " sw_if_index <sw_if_index> p <priority> "  \
18337                             "w <weight>] [del]")                        \
18338 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18339                         "iface <intf> | sw_if_index <sw_if_index> "     \
18340                         "p <priority> w <weight> [del]")                \
18341 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18342                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18343                          "locator-set <locator_name> [del]"             \
18344                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18345 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18346 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18347 _(lisp_enable_disable, "enable|disable")                                \
18348 _(lisp_map_register_enable_disable, "enable|disable")                   \
18349 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18350 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18351                                "[seid <seid>] "                         \
18352                                "rloc <locator> p <prio> "               \
18353                                "w <weight> [rloc <loc> ... ] "          \
18354                                "action <action> [del-all]")             \
18355 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18356                           "<local-eid>")                                \
18357 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18358 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18359 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18360 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18361 _(lisp_locator_set_dump, "[local | remote]")                            \
18362 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18363 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18364                        "[local] | [remote]")                            \
18365 _(lisp_eid_table_vni_dump, "")                                          \
18366 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18367 _(lisp_map_resolver_dump, "")                                           \
18368 _(lisp_map_server_dump, "")                                             \
18369 _(lisp_adjacencies_get, "vni <vni>")                                    \
18370 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18371 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18372 _(lisp_gpe_add_del_iface, "up|down")                                    \
18373 _(lisp_gpe_enable_disable, "enable|disable")                            \
18374 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18375   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18376 _(show_lisp_rloc_probe_state, "")                                       \
18377 _(show_lisp_map_register_state, "")                                     \
18378 _(show_lisp_status, "")                                                 \
18379 _(lisp_get_map_request_itr_rlocs, "")                                   \
18380 _(show_lisp_pitr, "")                                                   \
18381 _(show_lisp_map_request_mode, "")                                       \
18382 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18383 _(af_packet_delete, "name <host interface name>")                       \
18384 _(policer_add_del, "name <policer name> <params> [del]")                \
18385 _(policer_dump, "[name <policer name>]")                                \
18386 _(policer_classify_set_interface,                                       \
18387   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18388   "  [l2-table <nn>] [del]")                                            \
18389 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18390 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18391     "[master|slave]")                                                   \
18392 _(netmap_delete, "name <interface name>")                               \
18393 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18394 _(mpls_fib_dump, "")                                                    \
18395 _(classify_table_ids, "")                                               \
18396 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18397 _(classify_table_info, "table_id <nn>")                                 \
18398 _(classify_session_dump, "table_id <nn>")                               \
18399 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18400     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18401     "[template_interval <nn>] [udp_checksum]")                          \
18402 _(ipfix_exporter_dump, "")                                              \
18403 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18404 _(ipfix_classify_stream_dump, "")                                       \
18405 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18406 _(ipfix_classify_table_dump, "")                                        \
18407 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18408 _(sw_interface_span_dump, "")                                           \
18409 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18410 _(pg_create_interface, "if_id <nn>")                                    \
18411 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18412 _(pg_enable_disable, "[stream <id>] disable")                           \
18413 _(ip_source_and_port_range_check_add_del,                               \
18414   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18415 _(ip_source_and_port_range_check_interface_add_del,                     \
18416   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18417   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18418 _(ipsec_gre_add_del_tunnel,                                             \
18419   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18420 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18421 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18422 _(l2_interface_pbb_tag_rewrite,                                         \
18423   "<intfc> | sw_if_index <nn> \n"                                       \
18424   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18425   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18426 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18427 _(flow_classify_set_interface,                                          \
18428   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18429 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18430 _(ip_fib_dump, "")                                                      \
18431 _(ip_mfib_dump, "")                                                     \
18432 _(ip6_fib_dump, "")                                                     \
18433 _(ip6_mfib_dump, "")                                                    \
18434 _(feature_enable_disable, "arc_name <arc_name> "                        \
18435   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18436 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18437 "[disable]")                                                            \
18438 _(l2_xconnect_dump, "")                                                 \
18439 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18440 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18441 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18442
18443 #if DPDK > 0
18444 #define foreach_vpe_dpdk_api_msg                                        \
18445 _(sw_interface_set_dpdk_hqos_pipe,                                      \
18446   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
18447   "profile <profile-id>\n")                                             \
18448 _(sw_interface_set_dpdk_hqos_subport,                                   \
18449   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
18450   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
18451 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
18452   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
18453 #endif
18454
18455 /* List of command functions, CLI names map directly to functions */
18456 #define foreach_cli_function                                    \
18457 _(comment, "usage: comment <ignore-rest-of-line>")              \
18458 _(dump_interface_table, "usage: dump_interface_table")          \
18459 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18460 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18461 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18462 _(dump_stats_table, "usage: dump_stats_table")                  \
18463 _(dump_macro_table, "usage: dump_macro_table ")                 \
18464 _(dump_node_table, "usage: dump_node_table")                    \
18465 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18466 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18467 _(echo, "usage: echo <message>")                                \
18468 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18469 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18470 _(help, "usage: help")                                          \
18471 _(q, "usage: quit")                                             \
18472 _(quit, "usage: quit")                                          \
18473 _(search_node_table, "usage: search_node_table <name>...")      \
18474 _(set, "usage: set <variable-name> <value>")                    \
18475 _(script, "usage: script <file-name>")                          \
18476 _(unset, "usage: unset <variable-name>")
18477
18478 #define _(N,n)                                  \
18479     static void vl_api_##n##_t_handler_uni      \
18480     (vl_api_##n##_t * mp)                       \
18481     {                                           \
18482         vat_main_t * vam = &vat_main;           \
18483         if (vam->json_output) {                 \
18484             vl_api_##n##_t_handler_json(mp);    \
18485         } else {                                \
18486             vl_api_##n##_t_handler(mp);         \
18487         }                                       \
18488     }
18489 foreach_vpe_api_reply_msg;
18490 #undef _
18491
18492 #if DPDK > 0
18493 #define _(N,n)                                  \
18494     static void vl_api_##n##_t_handler_uni      \
18495     (vl_api_##n##_t * mp)                       \
18496     {                                           \
18497         vat_main_t * vam = &vat_main;           \
18498         if (vam->json_output) {                 \
18499             vl_api_##n##_t_handler_json(mp);    \
18500         } else {                                \
18501             vl_api_##n##_t_handler(mp);         \
18502         }                                       \
18503     }
18504 foreach_vpe_dpdk_api_reply_msg;
18505 #undef _
18506 #endif
18507
18508 void
18509 vat_api_hookup (vat_main_t * vam)
18510 {
18511 #define _(N,n)                                                  \
18512     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18513                            vl_api_##n##_t_handler_uni,          \
18514                            vl_noop_handler,                     \
18515                            vl_api_##n##_t_endian,               \
18516                            vl_api_##n##_t_print,                \
18517                            sizeof(vl_api_##n##_t), 1);
18518   foreach_vpe_api_reply_msg;
18519 #undef _
18520
18521 #if DPDK > 0
18522 #define _(N,n)                                                  \
18523     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18524                            vl_api_##n##_t_handler_uni,          \
18525                            vl_noop_handler,                     \
18526                            vl_api_##n##_t_endian,               \
18527                            vl_api_##n##_t_print,                \
18528                            sizeof(vl_api_##n##_t), 1);
18529   foreach_vpe_dpdk_api_reply_msg;
18530 #undef _
18531 #endif
18532
18533 #if (VPP_API_TEST_BUILTIN==0)
18534   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18535 #endif
18536
18537   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18538
18539   vam->function_by_name = hash_create_string (0, sizeof (uword));
18540
18541   vam->help_by_name = hash_create_string (0, sizeof (uword));
18542
18543   /* API messages we can send */
18544 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18545   foreach_vpe_api_msg;
18546 #undef _
18547 #if DPDK >0
18548 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18549   foreach_vpe_dpdk_api_msg;
18550 #undef _
18551 #endif
18552
18553   /* Help strings */
18554 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18555   foreach_vpe_api_msg;
18556 #undef _
18557 #if DPDK >0
18558 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18559   foreach_vpe_dpdk_api_msg;
18560 #undef _
18561 #endif
18562
18563   /* CLI functions */
18564 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18565   foreach_cli_function;
18566 #undef _
18567
18568   /* Help strings */
18569 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18570   foreach_cli_function;
18571 #undef _
18572 }
18573
18574 /*
18575  * fd.io coding-style-patch-verification: ON
18576  *
18577  * Local Variables:
18578  * eval: (c-set-style "gnu")
18579  * End:
18580  */