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