Remove unnecessary block structure around CONTROL_PING messages.
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52
53 #include "vat/json_format.h"
54
55 #include <inttypes.h>
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp/api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp/api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp/api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 #define __plugin_msg_base 0
75 #include <vlibapi/vat_helper_macros.h>
76
77 f64
78 vat_time_now (vat_main_t * vam)
79 {
80 #if VPP_API_TEST_BUILTIN
81   return vlib_time_now (vam->vlib_main);
82 #else
83   return clib_time_now (&vam->clib_time);
84 #endif
85 }
86
87 void
88 errmsg (char *fmt, ...)
89 {
90   vat_main_t *vam = &vat_main;
91   va_list va;
92   u8 *s;
93
94   va_start (va, fmt);
95   s = va_format (0, fmt, &va);
96   va_end (va);
97
98   vec_add1 (s, 0);
99
100 #if VPP_API_TEST_BUILTIN
101   vlib_cli_output (vam->vlib_main, (char *) s);
102 #else
103   {
104     if (vam->ifp != stdin)
105       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
106                vam->input_line_number);
107     fformat (vam->ofp, (char *) s);
108     fflush (vam->ofp);
109   }
110 #endif
111
112   vec_free (s);
113 }
114
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 #if VPP_API_TEST_BUILTIN == 0
134 /* Parse an IP4 address %d.%d.%d.%d. */
135 uword
136 unformat_ip4_address (unformat_input_t * input, va_list * args)
137 {
138   u8 *result = va_arg (*args, u8 *);
139   unsigned a[4];
140
141   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
142     return 0;
143
144   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
145     return 0;
146
147   result[0] = a[0];
148   result[1] = a[1];
149   result[2] = a[2];
150   result[3] = a[3];
151
152   return 1;
153 }
154
155 uword
156 unformat_ethernet_address (unformat_input_t * input, va_list * args)
157 {
158   u8 *result = va_arg (*args, u8 *);
159   u32 i, a[6];
160
161   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
162                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
163     return 0;
164
165   /* Check range. */
166   for (i = 0; i < 6; i++)
167     if (a[i] >= (1 << 8))
168       return 0;
169
170   for (i = 0; i < 6; i++)
171     result[i] = a[i];
172
173   return 1;
174 }
175
176 /* Returns ethernet type as an int in host byte order. */
177 uword
178 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
179                                         va_list * args)
180 {
181   u16 *result = va_arg (*args, u16 *);
182   int type;
183
184   /* Numeric type. */
185   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
186     {
187       if (type >= (1 << 16))
188         return 0;
189       *result = type;
190       return 1;
191     }
192   return 0;
193 }
194
195 /* Parse an IP6 address. */
196 uword
197 unformat_ip6_address (unformat_input_t * input, va_list * args)
198 {
199   ip6_address_t *result = va_arg (*args, ip6_address_t *);
200   u16 hex_quads[8];
201   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
202   uword c, n_colon, double_colon_index;
203
204   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
205   double_colon_index = ARRAY_LEN (hex_quads);
206   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
207     {
208       hex_digit = 16;
209       if (c >= '0' && c <= '9')
210         hex_digit = c - '0';
211       else if (c >= 'a' && c <= 'f')
212         hex_digit = c + 10 - 'a';
213       else if (c >= 'A' && c <= 'F')
214         hex_digit = c + 10 - 'A';
215       else if (c == ':' && n_colon < 2)
216         n_colon++;
217       else
218         {
219           unformat_put_input (input);
220           break;
221         }
222
223       /* Too many hex quads. */
224       if (n_hex_quads >= ARRAY_LEN (hex_quads))
225         return 0;
226
227       if (hex_digit < 16)
228         {
229           hex_quad = (hex_quad << 4) | hex_digit;
230
231           /* Hex quad must fit in 16 bits. */
232           if (n_hex_digits >= 4)
233             return 0;
234
235           n_colon = 0;
236           n_hex_digits++;
237         }
238
239       /* Save position of :: */
240       if (n_colon == 2)
241         {
242           /* More than one :: ? */
243           if (double_colon_index < ARRAY_LEN (hex_quads))
244             return 0;
245           double_colon_index = n_hex_quads;
246         }
247
248       if (n_colon > 0 && n_hex_digits > 0)
249         {
250           hex_quads[n_hex_quads++] = hex_quad;
251           hex_quad = 0;
252           n_hex_digits = 0;
253         }
254     }
255
256   if (n_hex_digits > 0)
257     hex_quads[n_hex_quads++] = hex_quad;
258
259   {
260     word i;
261
262     /* Expand :: to appropriate number of zero hex quads. */
263     if (double_colon_index < ARRAY_LEN (hex_quads))
264       {
265         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
266
267         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
268           hex_quads[n_zero + i] = hex_quads[i];
269
270         for (i = 0; i < n_zero; i++)
271           hex_quads[double_colon_index + i] = 0;
272
273         n_hex_quads = ARRAY_LEN (hex_quads);
274       }
275
276     /* Too few hex quads given. */
277     if (n_hex_quads < ARRAY_LEN (hex_quads))
278       return 0;
279
280     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
281       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
282
283     return 1;
284   }
285 }
286
287 uword
288 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
289 {
290   u32 *r = va_arg (*args, u32 *);
291
292   if (0);
293 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
294   foreach_ipsec_policy_action
295 #undef _
296     else
297     return 0;
298   return 1;
299 }
300
301 uword
302 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
303 {
304   u32 *r = va_arg (*args, u32 *);
305
306   if (0);
307 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
308   foreach_ipsec_crypto_alg
309 #undef _
310     else
311     return 0;
312   return 1;
313 }
314
315 u8 *
316 format_ipsec_crypto_alg (u8 * s, va_list * args)
317 {
318   u32 i = va_arg (*args, u32);
319   u8 *t = 0;
320
321   switch (i)
322     {
323 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
324       foreach_ipsec_crypto_alg
325 #undef _
326     default:
327       return format (s, "unknown");
328     }
329   return format (s, "%s", t);
330 }
331
332 uword
333 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
334 {
335   u32 *r = va_arg (*args, u32 *);
336
337   if (0);
338 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
339   foreach_ipsec_integ_alg
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 u8 *
347 format_ipsec_integ_alg (u8 * s, va_list * args)
348 {
349   u32 i = va_arg (*args, u32);
350   u8 *t = 0;
351
352   switch (i)
353     {
354 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
355       foreach_ipsec_integ_alg
356 #undef _
357     default:
358       return format (s, "unknown");
359     }
360   return format (s, "%s", t);
361 }
362
363 uword
364 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
370   foreach_ikev2_auth_method
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 uword
378 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
379 {
380   u32 *r = va_arg (*args, u32 *);
381
382   if (0);
383 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
384   foreach_ikev2_id_type
385 #undef _
386     else
387     return 0;
388   return 1;
389 }
390 #endif /* VPP_API_TEST_BUILTIN */
391
392 static uword
393 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "kbps"))
398     *r = SSE2_QOS_RATE_KBPS;
399   else if (unformat (input, "pps"))
400     *r = SSE2_QOS_RATE_PPS;
401   else
402     return 0;
403   return 1;
404 }
405
406 static uword
407 unformat_policer_round_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "closest"))
412     *r = SSE2_QOS_ROUND_TO_CLOSEST;
413   else if (unformat (input, "up"))
414     *r = SSE2_QOS_ROUND_TO_UP;
415   else if (unformat (input, "down"))
416     *r = SSE2_QOS_ROUND_TO_DOWN;
417   else
418     return 0;
419   return 1;
420 }
421
422 static uword
423 unformat_policer_type (unformat_input_t * input, va_list * args)
424 {
425   u8 *r = va_arg (*args, u8 *);
426
427   if (unformat (input, "1r2c"))
428     *r = SSE2_QOS_POLICER_TYPE_1R2C;
429   else if (unformat (input, "1r3c"))
430     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
431   else if (unformat (input, "2r3c-2698"))
432     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
433   else if (unformat (input, "2r3c-4115"))
434     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
435   else if (unformat (input, "2r3c-mef5cf1"))
436     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
437   else
438     return 0;
439   return 1;
440 }
441
442 static uword
443 unformat_dscp (unformat_input_t * input, va_list * va)
444 {
445   u8 *r = va_arg (*va, u8 *);
446
447   if (0);
448 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
449   foreach_vnet_dscp
450 #undef _
451     else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_policer_action_type (unformat_input_t * input, va_list * va)
458 {
459   sse2_qos_pol_action_params_st *a
460     = va_arg (*va, sse2_qos_pol_action_params_st *);
461
462   if (unformat (input, "drop"))
463     a->action_type = SSE2_QOS_ACTION_DROP;
464   else if (unformat (input, "transmit"))
465     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
466   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
467     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
468   else
469     return 0;
470   return 1;
471 }
472
473 static uword
474 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
475 {
476   u32 *r = va_arg (*va, u32 *);
477   u32 tid;
478
479   if (unformat (input, "ip4"))
480     tid = POLICER_CLASSIFY_TABLE_IP4;
481   else if (unformat (input, "ip6"))
482     tid = POLICER_CLASSIFY_TABLE_IP6;
483   else if (unformat (input, "l2"))
484     tid = POLICER_CLASSIFY_TABLE_L2;
485   else
486     return 0;
487
488   *r = tid;
489   return 1;
490 }
491
492 static uword
493 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
494 {
495   u32 *r = va_arg (*va, u32 *);
496   u32 tid;
497
498   if (unformat (input, "ip4"))
499     tid = FLOW_CLASSIFY_TABLE_IP4;
500   else if (unformat (input, "ip6"))
501     tid = FLOW_CLASSIFY_TABLE_IP6;
502   else
503     return 0;
504
505   *r = tid;
506   return 1;
507 }
508
509 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
510 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
511 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
512 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
513
514 uword
515 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
516 {
517   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
518   mfib_itf_attribute_t attr;
519
520   old = *iflags;
521   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
522   {
523     if (unformat (input, mfib_itf_flag_long_names[attr]))
524       *iflags |= (1 << attr);
525   }
526   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
527   {
528     if (unformat (input, mfib_itf_flag_names[attr]))
529       *iflags |= (1 << attr);
530   }
531
532   return (old == *iflags ? 0 : 1);
533 }
534
535 uword
536 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
537 {
538   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
539   mfib_entry_attribute_t attr;
540
541   old = *eflags;
542   FOR_EACH_MFIB_ATTRIBUTE (attr)
543   {
544     if (unformat (input, mfib_flag_long_names[attr]))
545       *eflags |= (1 << attr);
546   }
547   FOR_EACH_MFIB_ATTRIBUTE (attr)
548   {
549     if (unformat (input, mfib_flag_names[attr]))
550       *eflags |= (1 << attr);
551   }
552
553   return (old == *eflags ? 0 : 1);
554 }
555
556 #if (VPP_API_TEST_BUILTIN==0)
557 u8 *
558 format_ip4_address (u8 * s, va_list * args)
559 {
560   u8 *a = va_arg (*args, u8 *);
561   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
562 }
563
564 u8 *
565 format_ip6_address (u8 * s, va_list * args)
566 {
567   ip6_address_t *a = va_arg (*args, ip6_address_t *);
568   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
569
570   i_max_n_zero = ARRAY_LEN (a->as_u16);
571   max_n_zeros = 0;
572   i_first_zero = i_max_n_zero;
573   n_zeros = 0;
574   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
575     {
576       u32 is_zero = a->as_u16[i] == 0;
577       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
578         {
579           i_first_zero = i;
580           n_zeros = 0;
581         }
582       n_zeros += is_zero;
583       if ((!is_zero && n_zeros > max_n_zeros)
584           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
585         {
586           i_max_n_zero = i_first_zero;
587           max_n_zeros = n_zeros;
588           i_first_zero = ARRAY_LEN (a->as_u16);
589           n_zeros = 0;
590         }
591     }
592
593   last_double_colon = 0;
594   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
595     {
596       if (i == i_max_n_zero && max_n_zeros > 1)
597         {
598           s = format (s, "::");
599           i += max_n_zeros - 1;
600           last_double_colon = 1;
601         }
602       else
603         {
604           s = format (s, "%s%x",
605                       (last_double_colon || i == 0) ? "" : ":",
606                       clib_net_to_host_u16 (a->as_u16[i]));
607           last_double_colon = 0;
608         }
609     }
610
611   return s;
612 }
613
614 /* Format an IP46 address. */
615 u8 *
616 format_ip46_address (u8 * s, va_list * args)
617 {
618   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
619   ip46_type_t type = va_arg (*args, ip46_type_t);
620   int is_ip4 = 1;
621
622   switch (type)
623     {
624     case IP46_TYPE_ANY:
625       is_ip4 = ip46_address_is_ip4 (ip46);
626       break;
627     case IP46_TYPE_IP4:
628       is_ip4 = 1;
629       break;
630     case IP46_TYPE_IP6:
631       is_ip4 = 0;
632       break;
633     }
634
635   return is_ip4 ?
636     format (s, "%U", format_ip4_address, &ip46->ip4) :
637     format (s, "%U", format_ip6_address, &ip46->ip6);
638 }
639
640 u8 *
641 format_ethernet_address (u8 * s, va_list * args)
642 {
643   u8 *a = va_arg (*args, u8 *);
644
645   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
646                  a[0], a[1], a[2], a[3], a[4], a[5]);
647 }
648 #endif
649
650 static void
651 increment_v4_address (ip4_address_t * a)
652 {
653   u32 v;
654
655   v = ntohl (a->as_u32) + 1;
656   a->as_u32 = ntohl (v);
657 }
658
659 static void
660 increment_v6_address (ip6_address_t * a)
661 {
662   u64 v0, v1;
663
664   v0 = clib_net_to_host_u64 (a->as_u64[0]);
665   v1 = clib_net_to_host_u64 (a->as_u64[1]);
666
667   v1 += 1;
668   if (v1 == 0)
669     v0 += 1;
670   a->as_u64[0] = clib_net_to_host_u64 (v0);
671   a->as_u64[1] = clib_net_to_host_u64 (v1);
672 }
673
674 static void
675 increment_mac_address (u64 * mac)
676 {
677   u64 tmp = *mac;
678
679   tmp = clib_net_to_host_u64 (tmp);
680   tmp += 1 << 16;               /* skip unused (least significant) octets */
681   tmp = clib_host_to_net_u64 (tmp);
682   *mac = tmp;
683 }
684
685 static void vl_api_create_loopback_reply_t_handler
686   (vl_api_create_loopback_reply_t * mp)
687 {
688   vat_main_t *vam = &vat_main;
689   i32 retval = ntohl (mp->retval);
690
691   vam->retval = retval;
692   vam->regenerate_interface_table = 1;
693   vam->sw_if_index = ntohl (mp->sw_if_index);
694   vam->result_ready = 1;
695 }
696
697 static void vl_api_create_loopback_reply_t_handler_json
698   (vl_api_create_loopback_reply_t * mp)
699 {
700   vat_main_t *vam = &vat_main;
701   vat_json_node_t node;
702
703   vat_json_init_object (&node);
704   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
705   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
706
707   vat_json_print (vam->ofp, &node);
708   vat_json_free (&node);
709   vam->retval = ntohl (mp->retval);
710   vam->result_ready = 1;
711 }
712
713 static void vl_api_af_packet_create_reply_t_handler
714   (vl_api_af_packet_create_reply_t * mp)
715 {
716   vat_main_t *vam = &vat_main;
717   i32 retval = ntohl (mp->retval);
718
719   vam->retval = retval;
720   vam->regenerate_interface_table = 1;
721   vam->sw_if_index = ntohl (mp->sw_if_index);
722   vam->result_ready = 1;
723 }
724
725 static void vl_api_af_packet_create_reply_t_handler_json
726   (vl_api_af_packet_create_reply_t * mp)
727 {
728   vat_main_t *vam = &vat_main;
729   vat_json_node_t node;
730
731   vat_json_init_object (&node);
732   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
733   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
734
735   vat_json_print (vam->ofp, &node);
736   vat_json_free (&node);
737
738   vam->retval = ntohl (mp->retval);
739   vam->result_ready = 1;
740 }
741
742 static void vl_api_create_vlan_subif_reply_t_handler
743   (vl_api_create_vlan_subif_reply_t * mp)
744 {
745   vat_main_t *vam = &vat_main;
746   i32 retval = ntohl (mp->retval);
747
748   vam->retval = retval;
749   vam->regenerate_interface_table = 1;
750   vam->sw_if_index = ntohl (mp->sw_if_index);
751   vam->result_ready = 1;
752 }
753
754 static void vl_api_create_vlan_subif_reply_t_handler_json
755   (vl_api_create_vlan_subif_reply_t * mp)
756 {
757   vat_main_t *vam = &vat_main;
758   vat_json_node_t node;
759
760   vat_json_init_object (&node);
761   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
762   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
763
764   vat_json_print (vam->ofp, &node);
765   vat_json_free (&node);
766
767   vam->retval = ntohl (mp->retval);
768   vam->result_ready = 1;
769 }
770
771 static void vl_api_create_subif_reply_t_handler
772   (vl_api_create_subif_reply_t * mp)
773 {
774   vat_main_t *vam = &vat_main;
775   i32 retval = ntohl (mp->retval);
776
777   vam->retval = retval;
778   vam->regenerate_interface_table = 1;
779   vam->sw_if_index = ntohl (mp->sw_if_index);
780   vam->result_ready = 1;
781 }
782
783 static void vl_api_create_subif_reply_t_handler_json
784   (vl_api_create_subif_reply_t * mp)
785 {
786   vat_main_t *vam = &vat_main;
787   vat_json_node_t node;
788
789   vat_json_init_object (&node);
790   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
791   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
792
793   vat_json_print (vam->ofp, &node);
794   vat_json_free (&node);
795
796   vam->retval = ntohl (mp->retval);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_interface_name_renumber_reply_t_handler
801   (vl_api_interface_name_renumber_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   i32 retval = ntohl (mp->retval);
805
806   vam->retval = retval;
807   vam->regenerate_interface_table = 1;
808   vam->result_ready = 1;
809 }
810
811 static void vl_api_interface_name_renumber_reply_t_handler_json
812   (vl_api_interface_name_renumber_reply_t * mp)
813 {
814   vat_main_t *vam = &vat_main;
815   vat_json_node_t node;
816
817   vat_json_init_object (&node);
818   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
819
820   vat_json_print (vam->ofp, &node);
821   vat_json_free (&node);
822
823   vam->retval = ntohl (mp->retval);
824   vam->result_ready = 1;
825 }
826
827 /*
828  * Special-case: build the interface table, maintain
829  * the next loopback sw_if_index vbl.
830  */
831 static void vl_api_sw_interface_details_t_handler
832   (vl_api_sw_interface_details_t * mp)
833 {
834   vat_main_t *vam = &vat_main;
835   u8 *s = format (0, "%s%c", mp->interface_name, 0);
836
837   hash_set_mem (vam->sw_if_index_by_interface_name, s,
838                 ntohl (mp->sw_if_index));
839
840   /* In sub interface case, fill the sub interface table entry */
841   if (mp->sw_if_index != mp->sup_sw_if_index)
842     {
843       sw_interface_subif_t *sub = NULL;
844
845       vec_add2 (vam->sw_if_subif_table, sub, 1);
846
847       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
848       strncpy ((char *) sub->interface_name, (char *) s,
849                vec_len (sub->interface_name));
850       sub->sw_if_index = ntohl (mp->sw_if_index);
851       sub->sub_id = ntohl (mp->sub_id);
852
853       sub->sub_dot1ad = mp->sub_dot1ad;
854       sub->sub_number_of_tags = mp->sub_number_of_tags;
855       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
856       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
857       sub->sub_exact_match = mp->sub_exact_match;
858       sub->sub_default = mp->sub_default;
859       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
860       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
861
862       /* vlan tag rewrite */
863       sub->vtr_op = ntohl (mp->vtr_op);
864       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
865       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
866       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
867     }
868 }
869
870 static void vl_api_sw_interface_details_t_handler_json
871   (vl_api_sw_interface_details_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t *node = NULL;
875
876   if (VAT_JSON_ARRAY != vam->json_tree.type)
877     {
878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
879       vat_json_init_array (&vam->json_tree);
880     }
881   node = vat_json_array_add (&vam->json_tree);
882
883   vat_json_init_object (node);
884   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
885   vat_json_object_add_uint (node, "sup_sw_if_index",
886                             ntohl (mp->sup_sw_if_index));
887   vat_json_object_add_uint (node, "l2_address_length",
888                             ntohl (mp->l2_address_length));
889   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
890                              sizeof (mp->l2_address));
891   vat_json_object_add_string_copy (node, "interface_name",
892                                    mp->interface_name);
893   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
894   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
895   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
896   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
897   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
898   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
899   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
900   vat_json_object_add_uint (node, "sub_number_of_tags",
901                             mp->sub_number_of_tags);
902   vat_json_object_add_uint (node, "sub_outer_vlan_id",
903                             ntohs (mp->sub_outer_vlan_id));
904   vat_json_object_add_uint (node, "sub_inner_vlan_id",
905                             ntohs (mp->sub_inner_vlan_id));
906   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
907   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
908   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
909                             mp->sub_outer_vlan_id_any);
910   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
911                             mp->sub_inner_vlan_id_any);
912   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
913   vat_json_object_add_uint (node, "vtr_push_dot1q",
914                             ntohl (mp->vtr_push_dot1q));
915   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
916   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
917 }
918
919 static void vl_api_sw_interface_set_flags_t_handler
920   (vl_api_sw_interface_set_flags_t * mp)
921 {
922   vat_main_t *vam = &vat_main;
923   if (vam->interface_event_display)
924     errmsg ("interface flags: sw_if_index %d %s %s",
925             ntohl (mp->sw_if_index),
926             mp->admin_up_down ? "admin-up" : "admin-down",
927             mp->link_up_down ? "link-up" : "link-down");
928 }
929
930 static void vl_api_sw_interface_set_flags_t_handler_json
931   (vl_api_sw_interface_set_flags_t * mp)
932 {
933   /* JSON output not supported */
934 }
935
936 static void
937 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
938 {
939   vat_main_t *vam = &vat_main;
940   i32 retval = ntohl (mp->retval);
941
942   vam->retval = retval;
943   vam->shmem_result = (u8 *) mp->reply_in_shmem;
944   vam->result_ready = 1;
945 }
946
947 static void
948 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
949 {
950   vat_main_t *vam = &vat_main;
951   vat_json_node_t node;
952   api_main_t *am = &api_main;
953   void *oldheap;
954   u8 *reply;
955
956   vat_json_init_object (&node);
957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
958   vat_json_object_add_uint (&node, "reply_in_shmem",
959                             ntohl (mp->reply_in_shmem));
960   /* Toss the shared-memory original... */
961   pthread_mutex_lock (&am->vlib_rp->mutex);
962   oldheap = svm_push_data_heap (am->vlib_rp);
963
964   reply = (u8 *) (mp->reply_in_shmem);
965   vec_free (reply);
966
967   svm_pop_heap (oldheap);
968   pthread_mutex_unlock (&am->vlib_rp->mutex);
969
970   vat_json_print (vam->ofp, &node);
971   vat_json_free (&node);
972
973   vam->retval = ntohl (mp->retval);
974   vam->result_ready = 1;
975 }
976
977 static void
978 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
979 {
980   vat_main_t *vam = &vat_main;
981   i32 retval = ntohl (mp->retval);
982
983   vam->retval = retval;
984   vam->cmd_reply = mp->reply;
985   vam->result_ready = 1;
986 }
987
988 static void
989 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
990 {
991   vat_main_t *vam = &vat_main;
992   vat_json_node_t node;
993
994   vat_json_init_object (&node);
995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
996   vat_json_object_add_string_copy (&node, "reply", mp->reply);
997
998   vat_json_print (vam->ofp, &node);
999   vat_json_free (&node);
1000
1001   vam->retval = ntohl (mp->retval);
1002   vam->result_ready = 1;
1003 }
1004
1005 static void vl_api_classify_add_del_table_reply_t_handler
1006   (vl_api_classify_add_del_table_reply_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   i32 retval = ntohl (mp->retval);
1010   if (vam->async_mode)
1011     {
1012       vam->async_errors += (retval < 0);
1013     }
1014   else
1015     {
1016       vam->retval = retval;
1017       if (retval == 0 &&
1018           ((mp->new_table_index != 0xFFFFFFFF) ||
1019            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1020            (mp->match_n_vectors != 0xFFFFFFFF)))
1021         /*
1022          * Note: this is just barely thread-safe, depends on
1023          * the main thread spinning waiting for an answer...
1024          */
1025         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1026                 ntohl (mp->new_table_index),
1027                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1028       vam->result_ready = 1;
1029     }
1030 }
1031
1032 static void vl_api_classify_add_del_table_reply_t_handler_json
1033   (vl_api_classify_add_del_table_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   vat_json_node_t node;
1037
1038   vat_json_init_object (&node);
1039   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1040   vat_json_object_add_uint (&node, "new_table_index",
1041                             ntohl (mp->new_table_index));
1042   vat_json_object_add_uint (&node, "skip_n_vectors",
1043                             ntohl (mp->skip_n_vectors));
1044   vat_json_object_add_uint (&node, "match_n_vectors",
1045                             ntohl (mp->match_n_vectors));
1046
1047   vat_json_print (vam->ofp, &node);
1048   vat_json_free (&node);
1049
1050   vam->retval = ntohl (mp->retval);
1051   vam->result_ready = 1;
1052 }
1053
1054 static void vl_api_get_node_index_reply_t_handler
1055   (vl_api_get_node_index_reply_t * mp)
1056 {
1057   vat_main_t *vam = &vat_main;
1058   i32 retval = ntohl (mp->retval);
1059   if (vam->async_mode)
1060     {
1061       vam->async_errors += (retval < 0);
1062     }
1063   else
1064     {
1065       vam->retval = retval;
1066       if (retval == 0)
1067         errmsg ("node index %d", ntohl (mp->node_index));
1068       vam->result_ready = 1;
1069     }
1070 }
1071
1072 static void vl_api_get_node_index_reply_t_handler_json
1073   (vl_api_get_node_index_reply_t * mp)
1074 {
1075   vat_main_t *vam = &vat_main;
1076   vat_json_node_t node;
1077
1078   vat_json_init_object (&node);
1079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1080   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1081
1082   vat_json_print (vam->ofp, &node);
1083   vat_json_free (&node);
1084
1085   vam->retval = ntohl (mp->retval);
1086   vam->result_ready = 1;
1087 }
1088
1089 static void vl_api_get_next_index_reply_t_handler
1090   (vl_api_get_next_index_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   i32 retval = ntohl (mp->retval);
1094   if (vam->async_mode)
1095     {
1096       vam->async_errors += (retval < 0);
1097     }
1098   else
1099     {
1100       vam->retval = retval;
1101       if (retval == 0)
1102         errmsg ("next node index %d", ntohl (mp->next_index));
1103       vam->result_ready = 1;
1104     }
1105 }
1106
1107 static void vl_api_get_next_index_reply_t_handler_json
1108   (vl_api_get_next_index_reply_t * mp)
1109 {
1110   vat_main_t *vam = &vat_main;
1111   vat_json_node_t node;
1112
1113   vat_json_init_object (&node);
1114   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1115   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1116
1117   vat_json_print (vam->ofp, &node);
1118   vat_json_free (&node);
1119
1120   vam->retval = ntohl (mp->retval);
1121   vam->result_ready = 1;
1122 }
1123
1124 static void vl_api_add_node_next_reply_t_handler
1125   (vl_api_add_node_next_reply_t * mp)
1126 {
1127   vat_main_t *vam = &vat_main;
1128   i32 retval = ntohl (mp->retval);
1129   if (vam->async_mode)
1130     {
1131       vam->async_errors += (retval < 0);
1132     }
1133   else
1134     {
1135       vam->retval = retval;
1136       if (retval == 0)
1137         errmsg ("next index %d", ntohl (mp->next_index));
1138       vam->result_ready = 1;
1139     }
1140 }
1141
1142 static void vl_api_add_node_next_reply_t_handler_json
1143   (vl_api_add_node_next_reply_t * mp)
1144 {
1145   vat_main_t *vam = &vat_main;
1146   vat_json_node_t node;
1147
1148   vat_json_init_object (&node);
1149   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1150   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1151
1152   vat_json_print (vam->ofp, &node);
1153   vat_json_free (&node);
1154
1155   vam->retval = ntohl (mp->retval);
1156   vam->result_ready = 1;
1157 }
1158
1159 static void vl_api_show_version_reply_t_handler
1160   (vl_api_show_version_reply_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   i32 retval = ntohl (mp->retval);
1164
1165   if (retval >= 0)
1166     {
1167       errmsg ("        program: %s", mp->program);
1168       errmsg ("        version: %s", mp->version);
1169       errmsg ("     build date: %s", mp->build_date);
1170       errmsg ("build directory: %s", mp->build_directory);
1171     }
1172   vam->retval = retval;
1173   vam->result_ready = 1;
1174 }
1175
1176 static void vl_api_show_version_reply_t_handler_json
1177   (vl_api_show_version_reply_t * mp)
1178 {
1179   vat_main_t *vam = &vat_main;
1180   vat_json_node_t node;
1181
1182   vat_json_init_object (&node);
1183   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1184   vat_json_object_add_string_copy (&node, "program", mp->program);
1185   vat_json_object_add_string_copy (&node, "version", mp->version);
1186   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1187   vat_json_object_add_string_copy (&node, "build_directory",
1188                                    mp->build_directory);
1189
1190   vat_json_print (vam->ofp, &node);
1191   vat_json_free (&node);
1192
1193   vam->retval = ntohl (mp->retval);
1194   vam->result_ready = 1;
1195 }
1196
1197 static void
1198 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1199 {
1200   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1201           mp->mac_ip ? "mac/ip binding" : "address resolution",
1202           format_ip4_address, &mp->address,
1203           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1204 }
1205
1206 static void
1207 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1208 {
1209   /* JSON output not supported */
1210 }
1211
1212 static void
1213 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1214 {
1215   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1216           mp->mac_ip ? "mac/ip binding" : "address resolution",
1217           format_ip6_address, mp->address,
1218           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1219 }
1220
1221 static void
1222 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1223 {
1224   /* JSON output not supported */
1225 }
1226
1227 /*
1228  * Special-case: build the bridge domain table, maintain
1229  * the next bd id vbl.
1230  */
1231 static void vl_api_bridge_domain_details_t_handler
1232   (vl_api_bridge_domain_details_t * mp)
1233 {
1234   vat_main_t *vam = &vat_main;
1235   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1236
1237   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1238          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1239
1240   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1241          ntohl (mp->bd_id), mp->learn, mp->forward,
1242          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1243
1244   if (n_sw_ifs)
1245     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1246 }
1247
1248 static void vl_api_bridge_domain_details_t_handler_json
1249   (vl_api_bridge_domain_details_t * mp)
1250 {
1251   vat_main_t *vam = &vat_main;
1252   vat_json_node_t *node, *array = NULL;
1253
1254   if (VAT_JSON_ARRAY != vam->json_tree.type)
1255     {
1256       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1257       vat_json_init_array (&vam->json_tree);
1258     }
1259   node = vat_json_array_add (&vam->json_tree);
1260
1261   vat_json_init_object (node);
1262   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1263   vat_json_object_add_uint (node, "flood", mp->flood);
1264   vat_json_object_add_uint (node, "forward", mp->forward);
1265   vat_json_object_add_uint (node, "learn", mp->learn);
1266   vat_json_object_add_uint (node, "bvi_sw_if_index",
1267                             ntohl (mp->bvi_sw_if_index));
1268   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1269   array = vat_json_object_add (node, "sw_if");
1270   vat_json_init_array (array);
1271 }
1272
1273 /*
1274  * Special-case: build the bridge domain sw if table.
1275  */
1276 static void vl_api_bridge_domain_sw_if_details_t_handler
1277   (vl_api_bridge_domain_sw_if_details_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   hash_pair_t *p;
1281   u8 *sw_if_name = 0;
1282   u32 sw_if_index;
1283
1284   sw_if_index = ntohl (mp->sw_if_index);
1285   /* *INDENT-OFF* */
1286   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1287   ({
1288     if ((u32) p->value[0] == sw_if_index)
1289       {
1290         sw_if_name = (u8 *)(p->key);
1291         break;
1292       }
1293   }));
1294   /* *INDENT-ON* */
1295
1296   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1297          mp->shg, sw_if_name ? (char *) sw_if_name :
1298          "sw_if_index not found!");
1299 }
1300
1301 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1302   (vl_api_bridge_domain_sw_if_details_t * mp)
1303 {
1304   vat_main_t *vam = &vat_main;
1305   vat_json_node_t *node = NULL;
1306   uword last_index = 0;
1307
1308   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1309   ASSERT (vec_len (vam->json_tree.array) >= 1);
1310   last_index = vec_len (vam->json_tree.array) - 1;
1311   node = &vam->json_tree.array[last_index];
1312   node = vat_json_object_get_element (node, "sw_if");
1313   ASSERT (NULL != node);
1314   node = vat_json_array_add (node);
1315
1316   vat_json_init_object (node);
1317   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1318   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1319   vat_json_object_add_uint (node, "shg", mp->shg);
1320 }
1321
1322 static void vl_api_control_ping_reply_t_handler
1323   (vl_api_control_ping_reply_t * mp)
1324 {
1325   vat_main_t *vam = &vat_main;
1326   i32 retval = ntohl (mp->retval);
1327   if (vam->async_mode)
1328     {
1329       vam->async_errors += (retval < 0);
1330     }
1331   else
1332     {
1333       vam->retval = retval;
1334       vam->result_ready = 1;
1335     }
1336 }
1337
1338 static void vl_api_control_ping_reply_t_handler_json
1339   (vl_api_control_ping_reply_t * mp)
1340 {
1341   vat_main_t *vam = &vat_main;
1342   i32 retval = ntohl (mp->retval);
1343
1344   if (VAT_JSON_NONE != vam->json_tree.type)
1345     {
1346       vat_json_print (vam->ofp, &vam->json_tree);
1347       vat_json_free (&vam->json_tree);
1348       vam->json_tree.type = VAT_JSON_NONE;
1349     }
1350   else
1351     {
1352       /* just print [] */
1353       vat_json_init_array (&vam->json_tree);
1354       vat_json_print (vam->ofp, &vam->json_tree);
1355       vam->json_tree.type = VAT_JSON_NONE;
1356     }
1357
1358   vam->retval = retval;
1359   vam->result_ready = 1;
1360 }
1361
1362 static void
1363 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1364 {
1365   vat_main_t *vam = &vat_main;
1366   i32 retval = ntohl (mp->retval);
1367   if (vam->async_mode)
1368     {
1369       vam->async_errors += (retval < 0);
1370     }
1371   else
1372     {
1373       vam->retval = retval;
1374       vam->result_ready = 1;
1375     }
1376 }
1377
1378 static void vl_api_l2_flags_reply_t_handler_json
1379   (vl_api_l2_flags_reply_t * mp)
1380 {
1381   vat_main_t *vam = &vat_main;
1382   vat_json_node_t node;
1383
1384   vat_json_init_object (&node);
1385   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1386   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1387                             ntohl (mp->resulting_feature_bitmap));
1388
1389   vat_json_print (vam->ofp, &node);
1390   vat_json_free (&node);
1391
1392   vam->retval = ntohl (mp->retval);
1393   vam->result_ready = 1;
1394 }
1395
1396 static void vl_api_bridge_flags_reply_t_handler
1397   (vl_api_bridge_flags_reply_t * mp)
1398 {
1399   vat_main_t *vam = &vat_main;
1400   i32 retval = ntohl (mp->retval);
1401   if (vam->async_mode)
1402     {
1403       vam->async_errors += (retval < 0);
1404     }
1405   else
1406     {
1407       vam->retval = retval;
1408       vam->result_ready = 1;
1409     }
1410 }
1411
1412 static void vl_api_bridge_flags_reply_t_handler_json
1413   (vl_api_bridge_flags_reply_t * mp)
1414 {
1415   vat_main_t *vam = &vat_main;
1416   vat_json_node_t node;
1417
1418   vat_json_init_object (&node);
1419   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1420   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1421                             ntohl (mp->resulting_feature_bitmap));
1422
1423   vat_json_print (vam->ofp, &node);
1424   vat_json_free (&node);
1425
1426   vam->retval = ntohl (mp->retval);
1427   vam->result_ready = 1;
1428 }
1429
1430 static void vl_api_tap_connect_reply_t_handler
1431   (vl_api_tap_connect_reply_t * mp)
1432 {
1433   vat_main_t *vam = &vat_main;
1434   i32 retval = ntohl (mp->retval);
1435   if (vam->async_mode)
1436     {
1437       vam->async_errors += (retval < 0);
1438     }
1439   else
1440     {
1441       vam->retval = retval;
1442       vam->sw_if_index = ntohl (mp->sw_if_index);
1443       vam->result_ready = 1;
1444     }
1445
1446 }
1447
1448 static void vl_api_tap_connect_reply_t_handler_json
1449   (vl_api_tap_connect_reply_t * mp)
1450 {
1451   vat_main_t *vam = &vat_main;
1452   vat_json_node_t node;
1453
1454   vat_json_init_object (&node);
1455   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1456   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1457
1458   vat_json_print (vam->ofp, &node);
1459   vat_json_free (&node);
1460
1461   vam->retval = ntohl (mp->retval);
1462   vam->result_ready = 1;
1463
1464 }
1465
1466 static void
1467 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1468 {
1469   vat_main_t *vam = &vat_main;
1470   i32 retval = ntohl (mp->retval);
1471   if (vam->async_mode)
1472     {
1473       vam->async_errors += (retval < 0);
1474     }
1475   else
1476     {
1477       vam->retval = retval;
1478       vam->sw_if_index = ntohl (mp->sw_if_index);
1479       vam->result_ready = 1;
1480     }
1481 }
1482
1483 static void vl_api_tap_modify_reply_t_handler_json
1484   (vl_api_tap_modify_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   vat_json_node_t node;
1488
1489   vat_json_init_object (&node);
1490   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1491   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1492
1493   vat_json_print (vam->ofp, &node);
1494   vat_json_free (&node);
1495
1496   vam->retval = ntohl (mp->retval);
1497   vam->result_ready = 1;
1498 }
1499
1500 static void
1501 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1502 {
1503   vat_main_t *vam = &vat_main;
1504   i32 retval = ntohl (mp->retval);
1505   if (vam->async_mode)
1506     {
1507       vam->async_errors += (retval < 0);
1508     }
1509   else
1510     {
1511       vam->retval = retval;
1512       vam->result_ready = 1;
1513     }
1514 }
1515
1516 static void vl_api_tap_delete_reply_t_handler_json
1517   (vl_api_tap_delete_reply_t * mp)
1518 {
1519   vat_main_t *vam = &vat_main;
1520   vat_json_node_t node;
1521
1522   vat_json_init_object (&node);
1523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1524
1525   vat_json_print (vam->ofp, &node);
1526   vat_json_free (&node);
1527
1528   vam->retval = ntohl (mp->retval);
1529   vam->result_ready = 1;
1530 }
1531
1532 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1533   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1534 {
1535   vat_main_t *vam = &vat_main;
1536   i32 retval = ntohl (mp->retval);
1537   if (vam->async_mode)
1538     {
1539       vam->async_errors += (retval < 0);
1540     }
1541   else
1542     {
1543       vam->retval = retval;
1544       vam->result_ready = 1;
1545     }
1546 }
1547
1548 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1549   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1550 {
1551   vat_main_t *vam = &vat_main;
1552   vat_json_node_t node;
1553
1554   vat_json_init_object (&node);
1555   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1556   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1557                             ntohl (mp->sw_if_index));
1558
1559   vat_json_print (vam->ofp, &node);
1560   vat_json_free (&node);
1561
1562   vam->retval = ntohl (mp->retval);
1563   vam->result_ready = 1;
1564 }
1565
1566 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1567   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1568 {
1569   vat_main_t *vam = &vat_main;
1570   i32 retval = ntohl (mp->retval);
1571   if (vam->async_mode)
1572     {
1573       vam->async_errors += (retval < 0);
1574     }
1575   else
1576     {
1577       vam->retval = retval;
1578       vam->sw_if_index = ntohl (mp->sw_if_index);
1579       vam->result_ready = 1;
1580     }
1581 }
1582
1583 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1584   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1585 {
1586   vat_main_t *vam = &vat_main;
1587   vat_json_node_t node;
1588
1589   vat_json_init_object (&node);
1590   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1591   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1592
1593   vat_json_print (vam->ofp, &node);
1594   vat_json_free (&node);
1595
1596   vam->retval = ntohl (mp->retval);
1597   vam->result_ready = 1;
1598 }
1599
1600
1601 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1602   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1603 {
1604   vat_main_t *vam = &vat_main;
1605   i32 retval = ntohl (mp->retval);
1606   if (vam->async_mode)
1607     {
1608       vam->async_errors += (retval < 0);
1609     }
1610   else
1611     {
1612       vam->retval = retval;
1613       vam->result_ready = 1;
1614     }
1615 }
1616
1617 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1618   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1619 {
1620   vat_main_t *vam = &vat_main;
1621   vat_json_node_t node;
1622
1623   vat_json_init_object (&node);
1624   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1625   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1626
1627   vat_json_print (vam->ofp, &node);
1628   vat_json_free (&node);
1629
1630   vam->retval = ntohl (mp->retval);
1631   vam->result_ready = 1;
1632 }
1633
1634 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1635   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1636 {
1637   vat_main_t *vam = &vat_main;
1638   i32 retval = ntohl (mp->retval);
1639   if (vam->async_mode)
1640     {
1641       vam->async_errors += (retval < 0);
1642     }
1643   else
1644     {
1645       vam->retval = retval;
1646       vam->sw_if_index = ntohl (mp->sw_if_index);
1647       vam->result_ready = 1;
1648     }
1649 }
1650
1651 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1652   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1653 {
1654   vat_main_t *vam = &vat_main;
1655   vat_json_node_t node;
1656
1657   vat_json_init_object (&node);
1658   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1659   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1660
1661   vat_json_print (vam->ofp, &node);
1662   vat_json_free (&node);
1663
1664   vam->retval = ntohl (mp->retval);
1665   vam->result_ready = 1;
1666 }
1667
1668 static void vl_api_gre_add_del_tunnel_reply_t_handler
1669   (vl_api_gre_add_del_tunnel_reply_t * mp)
1670 {
1671   vat_main_t *vam = &vat_main;
1672   i32 retval = ntohl (mp->retval);
1673   if (vam->async_mode)
1674     {
1675       vam->async_errors += (retval < 0);
1676     }
1677   else
1678     {
1679       vam->retval = retval;
1680       vam->sw_if_index = ntohl (mp->sw_if_index);
1681       vam->result_ready = 1;
1682     }
1683 }
1684
1685 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1686   (vl_api_gre_add_del_tunnel_reply_t * mp)
1687 {
1688   vat_main_t *vam = &vat_main;
1689   vat_json_node_t node;
1690
1691   vat_json_init_object (&node);
1692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1694
1695   vat_json_print (vam->ofp, &node);
1696   vat_json_free (&node);
1697
1698   vam->retval = ntohl (mp->retval);
1699   vam->result_ready = 1;
1700 }
1701
1702 static void vl_api_create_vhost_user_if_reply_t_handler
1703   (vl_api_create_vhost_user_if_reply_t * mp)
1704 {
1705   vat_main_t *vam = &vat_main;
1706   i32 retval = ntohl (mp->retval);
1707   if (vam->async_mode)
1708     {
1709       vam->async_errors += (retval < 0);
1710     }
1711   else
1712     {
1713       vam->retval = retval;
1714       vam->sw_if_index = ntohl (mp->sw_if_index);
1715       vam->result_ready = 1;
1716     }
1717 }
1718
1719 static void vl_api_create_vhost_user_if_reply_t_handler_json
1720   (vl_api_create_vhost_user_if_reply_t * mp)
1721 {
1722   vat_main_t *vam = &vat_main;
1723   vat_json_node_t node;
1724
1725   vat_json_init_object (&node);
1726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1727   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1728
1729   vat_json_print (vam->ofp, &node);
1730   vat_json_free (&node);
1731
1732   vam->retval = ntohl (mp->retval);
1733   vam->result_ready = 1;
1734 }
1735
1736 static void vl_api_ip_address_details_t_handler
1737   (vl_api_ip_address_details_t * mp)
1738 {
1739   vat_main_t *vam = &vat_main;
1740   static ip_address_details_t empty_ip_address_details = { {0} };
1741   ip_address_details_t *address = NULL;
1742   ip_details_t *current_ip_details = NULL;
1743   ip_details_t *details = NULL;
1744
1745   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1746
1747   if (!details || vam->current_sw_if_index >= vec_len (details)
1748       || !details[vam->current_sw_if_index].present)
1749     {
1750       errmsg ("ip address details arrived but not stored");
1751       errmsg ("ip_dump should be called first");
1752       return;
1753     }
1754
1755   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1756
1757 #define addresses (current_ip_details->addr)
1758
1759   vec_validate_init_empty (addresses, vec_len (addresses),
1760                            empty_ip_address_details);
1761
1762   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1763
1764   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1765   address->prefix_length = mp->prefix_length;
1766 #undef addresses
1767 }
1768
1769 static void vl_api_ip_address_details_t_handler_json
1770   (vl_api_ip_address_details_t * mp)
1771 {
1772   vat_main_t *vam = &vat_main;
1773   vat_json_node_t *node = NULL;
1774   struct in6_addr ip6;
1775   struct in_addr ip4;
1776
1777   if (VAT_JSON_ARRAY != vam->json_tree.type)
1778     {
1779       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1780       vat_json_init_array (&vam->json_tree);
1781     }
1782   node = vat_json_array_add (&vam->json_tree);
1783
1784   vat_json_init_object (node);
1785   if (vam->is_ipv6)
1786     {
1787       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1788       vat_json_object_add_ip6 (node, "ip", ip6);
1789     }
1790   else
1791     {
1792       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1793       vat_json_object_add_ip4 (node, "ip", ip4);
1794     }
1795   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1796 }
1797
1798 static void
1799 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   static ip_details_t empty_ip_details = { 0 };
1803   ip_details_t *ip = NULL;
1804   u32 sw_if_index = ~0;
1805
1806   sw_if_index = ntohl (mp->sw_if_index);
1807
1808   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1809                            sw_if_index, empty_ip_details);
1810
1811   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1812                          sw_if_index);
1813
1814   ip->present = 1;
1815 }
1816
1817 static void
1818 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1819 {
1820   vat_main_t *vam = &vat_main;
1821
1822   if (VAT_JSON_ARRAY != vam->json_tree.type)
1823     {
1824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1825       vat_json_init_array (&vam->json_tree);
1826     }
1827   vat_json_array_add_uint (&vam->json_tree,
1828                            clib_net_to_host_u32 (mp->sw_if_index));
1829 }
1830
1831 static void vl_api_map_domain_details_t_handler_json
1832   (vl_api_map_domain_details_t * mp)
1833 {
1834   vat_json_node_t *node = NULL;
1835   vat_main_t *vam = &vat_main;
1836   struct in6_addr ip6;
1837   struct in_addr ip4;
1838
1839   if (VAT_JSON_ARRAY != vam->json_tree.type)
1840     {
1841       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1842       vat_json_init_array (&vam->json_tree);
1843     }
1844
1845   node = vat_json_array_add (&vam->json_tree);
1846   vat_json_init_object (node);
1847
1848   vat_json_object_add_uint (node, "domain_index",
1849                             clib_net_to_host_u32 (mp->domain_index));
1850   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1851   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1852   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1853   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1854   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1855   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1856   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1857   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1858   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1859   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1860   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1861   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1862   vat_json_object_add_uint (node, "flags", mp->flags);
1863   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1864   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1865 }
1866
1867 static void vl_api_map_domain_details_t_handler
1868   (vl_api_map_domain_details_t * mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871
1872   if (mp->is_translation)
1873     {
1874       print (vam->ofp,
1875              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1876              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1877              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1878              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1879              clib_net_to_host_u32 (mp->domain_index));
1880     }
1881   else
1882     {
1883       print (vam->ofp,
1884              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1885              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1886              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1887              format_ip6_address, mp->ip6_src,
1888              clib_net_to_host_u32 (mp->domain_index));
1889     }
1890   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1891          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1892          mp->is_translation ? "map-t" : "");
1893 }
1894
1895 static void vl_api_map_rule_details_t_handler_json
1896   (vl_api_map_rule_details_t * mp)
1897 {
1898   struct in6_addr ip6;
1899   vat_json_node_t *node = NULL;
1900   vat_main_t *vam = &vat_main;
1901
1902   if (VAT_JSON_ARRAY != vam->json_tree.type)
1903     {
1904       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1905       vat_json_init_array (&vam->json_tree);
1906     }
1907
1908   node = vat_json_array_add (&vam->json_tree);
1909   vat_json_init_object (node);
1910
1911   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1912   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1913   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1914 }
1915
1916 static void
1917 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1921          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1922 }
1923
1924 static void
1925 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1926 {
1927   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1928           "router_addr %U host_mac %U",
1929           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1930           format_ip4_address, &mp->host_address,
1931           format_ip4_address, &mp->router_address,
1932           format_ethernet_address, mp->host_mac);
1933 }
1934
1935 static void vl_api_dhcp_compl_event_t_handler_json
1936   (vl_api_dhcp_compl_event_t * mp)
1937 {
1938   /* JSON output not supported */
1939 }
1940
1941 static void
1942 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1943                               u32 counter)
1944 {
1945   vat_main_t *vam = &vat_main;
1946   static u64 default_counter = 0;
1947
1948   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1949                            NULL);
1950   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1951                            sw_if_index, default_counter);
1952   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1953 }
1954
1955 static void
1956 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1957                                 interface_counter_t counter)
1958 {
1959   vat_main_t *vam = &vat_main;
1960   static interface_counter_t default_counter = { 0, };
1961
1962   vec_validate_init_empty (vam->combined_interface_counters,
1963                            vnet_counter_type, NULL);
1964   vec_validate_init_empty (vam->combined_interface_counters
1965                            [vnet_counter_type], sw_if_index, default_counter);
1966   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1967 }
1968
1969 static void vl_api_vnet_interface_counters_t_handler
1970   (vl_api_vnet_interface_counters_t * mp)
1971 {
1972   /* not supported */
1973 }
1974
1975 static void vl_api_vnet_interface_counters_t_handler_json
1976   (vl_api_vnet_interface_counters_t * mp)
1977 {
1978   interface_counter_t counter;
1979   vlib_counter_t *v;
1980   u64 *v_packets;
1981   u64 packets;
1982   u32 count;
1983   u32 first_sw_if_index;
1984   int i;
1985
1986   count = ntohl (mp->count);
1987   first_sw_if_index = ntohl (mp->first_sw_if_index);
1988
1989   if (!mp->is_combined)
1990     {
1991       v_packets = (u64 *) & mp->data;
1992       for (i = 0; i < count; i++)
1993         {
1994           packets =
1995             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1996           set_simple_interface_counter (mp->vnet_counter_type,
1997                                         first_sw_if_index + i, packets);
1998           v_packets++;
1999         }
2000     }
2001   else
2002     {
2003       v = (vlib_counter_t *) & mp->data;
2004       for (i = 0; i < count; i++)
2005         {
2006           counter.packets =
2007             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2008           counter.bytes =
2009             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2010           set_combined_interface_counter (mp->vnet_counter_type,
2011                                           first_sw_if_index + i, counter);
2012           v++;
2013         }
2014     }
2015 }
2016
2017 static u32
2018 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2019 {
2020   vat_main_t *vam = &vat_main;
2021   u32 i;
2022
2023   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2024     {
2025       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2026         {
2027           return i;
2028         }
2029     }
2030   return ~0;
2031 }
2032
2033 static u32
2034 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2035 {
2036   vat_main_t *vam = &vat_main;
2037   u32 i;
2038
2039   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2040     {
2041       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2042         {
2043           return i;
2044         }
2045     }
2046   return ~0;
2047 }
2048
2049 static void vl_api_vnet_ip4_fib_counters_t_handler
2050   (vl_api_vnet_ip4_fib_counters_t * mp)
2051 {
2052   /* not supported */
2053 }
2054
2055 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2056   (vl_api_vnet_ip4_fib_counters_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vl_api_ip4_fib_counter_t *v;
2060   ip4_fib_counter_t *counter;
2061   struct in_addr ip4;
2062   u32 vrf_id;
2063   u32 vrf_index;
2064   u32 count;
2065   int i;
2066
2067   vrf_id = ntohl (mp->vrf_id);
2068   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2069   if (~0 == vrf_index)
2070     {
2071       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2072       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2073       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2074       vec_validate (vam->ip4_fib_counters, vrf_index);
2075       vam->ip4_fib_counters[vrf_index] = NULL;
2076     }
2077
2078   vec_free (vam->ip4_fib_counters[vrf_index]);
2079   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2080   count = ntohl (mp->count);
2081   for (i = 0; i < count; i++)
2082     {
2083       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2084       counter = &vam->ip4_fib_counters[vrf_index][i];
2085       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2086       counter->address = ip4;
2087       counter->address_length = v->address_length;
2088       counter->packets = clib_net_to_host_u64 (v->packets);
2089       counter->bytes = clib_net_to_host_u64 (v->bytes);
2090       v++;
2091     }
2092 }
2093
2094 static void vl_api_vnet_ip4_nbr_counters_t_handler
2095   (vl_api_vnet_ip4_nbr_counters_t * mp)
2096 {
2097   /* not supported */
2098 }
2099
2100 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2101   (vl_api_vnet_ip4_nbr_counters_t * mp)
2102 {
2103   vat_main_t *vam = &vat_main;
2104   vl_api_ip4_nbr_counter_t *v;
2105   ip4_nbr_counter_t *counter;
2106   u32 sw_if_index;
2107   u32 count;
2108   int i;
2109
2110   sw_if_index = ntohl (mp->sw_if_index);
2111   count = ntohl (mp->count);
2112   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2113
2114   if (mp->begin)
2115     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2116
2117   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2118   for (i = 0; i < count; i++)
2119     {
2120       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2121       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2122       counter->address.s_addr = v->address;
2123       counter->packets = clib_net_to_host_u64 (v->packets);
2124       counter->bytes = clib_net_to_host_u64 (v->bytes);
2125       counter->linkt = v->link_type;
2126       v++;
2127     }
2128 }
2129
2130 static void vl_api_vnet_ip6_fib_counters_t_handler
2131   (vl_api_vnet_ip6_fib_counters_t * mp)
2132 {
2133   /* not supported */
2134 }
2135
2136 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2137   (vl_api_vnet_ip6_fib_counters_t * mp)
2138 {
2139   vat_main_t *vam = &vat_main;
2140   vl_api_ip6_fib_counter_t *v;
2141   ip6_fib_counter_t *counter;
2142   struct in6_addr ip6;
2143   u32 vrf_id;
2144   u32 vrf_index;
2145   u32 count;
2146   int i;
2147
2148   vrf_id = ntohl (mp->vrf_id);
2149   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2150   if (~0 == vrf_index)
2151     {
2152       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2153       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2154       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2155       vec_validate (vam->ip6_fib_counters, vrf_index);
2156       vam->ip6_fib_counters[vrf_index] = NULL;
2157     }
2158
2159   vec_free (vam->ip6_fib_counters[vrf_index]);
2160   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2161   count = ntohl (mp->count);
2162   for (i = 0; i < count; i++)
2163     {
2164       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2165       counter = &vam->ip6_fib_counters[vrf_index][i];
2166       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2167       counter->address = ip6;
2168       counter->address_length = v->address_length;
2169       counter->packets = clib_net_to_host_u64 (v->packets);
2170       counter->bytes = clib_net_to_host_u64 (v->bytes);
2171       v++;
2172     }
2173 }
2174
2175 static void vl_api_vnet_ip6_nbr_counters_t_handler
2176   (vl_api_vnet_ip6_nbr_counters_t * mp)
2177 {
2178   /* not supported */
2179 }
2180
2181 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2182   (vl_api_vnet_ip6_nbr_counters_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   vl_api_ip6_nbr_counter_t *v;
2186   ip6_nbr_counter_t *counter;
2187   struct in6_addr ip6;
2188   u32 sw_if_index;
2189   u32 count;
2190   int i;
2191
2192   sw_if_index = ntohl (mp->sw_if_index);
2193   count = ntohl (mp->count);
2194   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2195
2196   if (mp->begin)
2197     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2198
2199   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2200   for (i = 0; i < count; i++)
2201     {
2202       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2203       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2204       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2205       counter->address = ip6;
2206       counter->packets = clib_net_to_host_u64 (v->packets);
2207       counter->bytes = clib_net_to_host_u64 (v->bytes);
2208       v++;
2209     }
2210 }
2211
2212 static void vl_api_get_first_msg_id_reply_t_handler
2213   (vl_api_get_first_msg_id_reply_t * mp)
2214 {
2215   vat_main_t *vam = &vat_main;
2216   i32 retval = ntohl (mp->retval);
2217
2218   if (vam->async_mode)
2219     {
2220       vam->async_errors += (retval < 0);
2221     }
2222   else
2223     {
2224       vam->retval = retval;
2225       vam->result_ready = 1;
2226     }
2227   if (retval >= 0)
2228     {
2229       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2230     }
2231 }
2232
2233 static void vl_api_get_first_msg_id_reply_t_handler_json
2234   (vl_api_get_first_msg_id_reply_t * mp)
2235 {
2236   vat_main_t *vam = &vat_main;
2237   vat_json_node_t node;
2238
2239   vat_json_init_object (&node);
2240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2241   vat_json_object_add_uint (&node, "first_msg_id",
2242                             (uint) ntohs (mp->first_msg_id));
2243
2244   vat_json_print (vam->ofp, &node);
2245   vat_json_free (&node);
2246
2247   vam->retval = ntohl (mp->retval);
2248   vam->result_ready = 1;
2249 }
2250
2251 static void vl_api_get_node_graph_reply_t_handler
2252   (vl_api_get_node_graph_reply_t * mp)
2253 {
2254   vat_main_t *vam = &vat_main;
2255   api_main_t *am = &api_main;
2256   i32 retval = ntohl (mp->retval);
2257   u8 *pvt_copy, *reply;
2258   void *oldheap;
2259   vlib_node_t *node;
2260   int i;
2261
2262   if (vam->async_mode)
2263     {
2264       vam->async_errors += (retval < 0);
2265     }
2266   else
2267     {
2268       vam->retval = retval;
2269       vam->result_ready = 1;
2270     }
2271
2272   /* "Should never happen..." */
2273   if (retval != 0)
2274     return;
2275
2276   reply = (u8 *) (mp->reply_in_shmem);
2277   pvt_copy = vec_dup (reply);
2278
2279   /* Toss the shared-memory original... */
2280   pthread_mutex_lock (&am->vlib_rp->mutex);
2281   oldheap = svm_push_data_heap (am->vlib_rp);
2282
2283   vec_free (reply);
2284
2285   svm_pop_heap (oldheap);
2286   pthread_mutex_unlock (&am->vlib_rp->mutex);
2287
2288   if (vam->graph_nodes)
2289     {
2290       hash_free (vam->graph_node_index_by_name);
2291
2292       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2293         {
2294           node = vam->graph_nodes[i];
2295           vec_free (node->name);
2296           vec_free (node->next_nodes);
2297           vec_free (node);
2298         }
2299       vec_free (vam->graph_nodes);
2300     }
2301
2302   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2303   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2304   vec_free (pvt_copy);
2305
2306   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2307     {
2308       node = vam->graph_nodes[i];
2309       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2310     }
2311 }
2312
2313 static void vl_api_get_node_graph_reply_t_handler_json
2314   (vl_api_get_node_graph_reply_t * mp)
2315 {
2316   vat_main_t *vam = &vat_main;
2317   api_main_t *am = &api_main;
2318   void *oldheap;
2319   vat_json_node_t node;
2320   u8 *reply;
2321
2322   /* $$$$ make this real? */
2323   vat_json_init_object (&node);
2324   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2325   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2326
2327   reply = (u8 *) (mp->reply_in_shmem);
2328
2329   /* Toss the shared-memory original... */
2330   pthread_mutex_lock (&am->vlib_rp->mutex);
2331   oldheap = svm_push_data_heap (am->vlib_rp);
2332
2333   vec_free (reply);
2334
2335   svm_pop_heap (oldheap);
2336   pthread_mutex_unlock (&am->vlib_rp->mutex);
2337
2338   vat_json_print (vam->ofp, &node);
2339   vat_json_free (&node);
2340
2341   vam->retval = ntohl (mp->retval);
2342   vam->result_ready = 1;
2343 }
2344
2345 static void
2346 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2347 {
2348   vat_main_t *vam = &vat_main;
2349   u8 *s = 0;
2350
2351   if (mp->local)
2352     {
2353       s = format (s, "%=16d%=16d%=16d",
2354                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2355     }
2356   else
2357     {
2358       s = format (s, "%=16U%=16d%=16d",
2359                   mp->is_ipv6 ? format_ip6_address :
2360                   format_ip4_address,
2361                   mp->ip_address, mp->priority, mp->weight);
2362     }
2363
2364   print (vam->ofp, "%v", s);
2365   vec_free (s);
2366 }
2367
2368 static void
2369 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2370                                             mp)
2371 {
2372   vat_main_t *vam = &vat_main;
2373   vat_json_node_t *node = NULL;
2374   struct in6_addr ip6;
2375   struct in_addr ip4;
2376
2377   if (VAT_JSON_ARRAY != vam->json_tree.type)
2378     {
2379       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2380       vat_json_init_array (&vam->json_tree);
2381     }
2382   node = vat_json_array_add (&vam->json_tree);
2383   vat_json_init_object (node);
2384
2385   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2386   vat_json_object_add_uint (node, "priority", mp->priority);
2387   vat_json_object_add_uint (node, "weight", mp->weight);
2388
2389   if (mp->local)
2390     vat_json_object_add_uint (node, "sw_if_index",
2391                               clib_net_to_host_u32 (mp->sw_if_index));
2392   else
2393     {
2394       if (mp->is_ipv6)
2395         {
2396           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2397           vat_json_object_add_ip6 (node, "address", ip6);
2398         }
2399       else
2400         {
2401           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2402           vat_json_object_add_ip4 (node, "address", ip4);
2403         }
2404     }
2405 }
2406
2407 static void
2408 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2409                                            mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   u8 *ls_name = 0;
2413
2414   ls_name = format (0, "%s", mp->ls_name);
2415
2416   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2417          ls_name);
2418   vec_free (ls_name);
2419 }
2420
2421 static void
2422   vl_api_lisp_locator_set_details_t_handler_json
2423   (vl_api_lisp_locator_set_details_t * mp)
2424 {
2425   vat_main_t *vam = &vat_main;
2426   vat_json_node_t *node = 0;
2427   u8 *ls_name = 0;
2428
2429   ls_name = format (0, "%s", mp->ls_name);
2430   vec_add1 (ls_name, 0);
2431
2432   if (VAT_JSON_ARRAY != vam->json_tree.type)
2433     {
2434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2435       vat_json_init_array (&vam->json_tree);
2436     }
2437   node = vat_json_array_add (&vam->json_tree);
2438
2439   vat_json_init_object (node);
2440   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2441   vat_json_object_add_uint (node, "ls_index",
2442                             clib_net_to_host_u32 (mp->ls_index));
2443   vec_free (ls_name);
2444 }
2445
2446 static u8 *
2447 format_lisp_flat_eid (u8 * s, va_list * args)
2448 {
2449   u32 type = va_arg (*args, u32);
2450   u8 *eid = va_arg (*args, u8 *);
2451   u32 eid_len = va_arg (*args, u32);
2452
2453   switch (type)
2454     {
2455     case 0:
2456       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2457     case 1:
2458       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2459     case 2:
2460       return format (s, "%U", format_ethernet_address, eid);
2461     }
2462   return 0;
2463 }
2464
2465 static u8 *
2466 format_lisp_eid_vat (u8 * s, va_list * args)
2467 {
2468   u32 type = va_arg (*args, u32);
2469   u8 *eid = va_arg (*args, u8 *);
2470   u32 eid_len = va_arg (*args, u32);
2471   u8 *seid = va_arg (*args, u8 *);
2472   u32 seid_len = va_arg (*args, u32);
2473   u32 is_src_dst = va_arg (*args, u32);
2474
2475   if (is_src_dst)
2476     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2477
2478   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2479
2480   return s;
2481 }
2482
2483 static void
2484 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2485 {
2486   vat_main_t *vam = &vat_main;
2487   u8 *s = 0, *eid = 0;
2488
2489   if (~0 == mp->locator_set_index)
2490     s = format (0, "action: %d", mp->action);
2491   else
2492     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2493
2494   eid = format (0, "%U", format_lisp_eid_vat,
2495                 mp->eid_type,
2496                 mp->eid,
2497                 mp->eid_prefix_len,
2498                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2499   vec_add1 (eid, 0);
2500
2501   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2502          clib_net_to_host_u32 (mp->vni),
2503          eid,
2504          mp->is_local ? "local" : "remote",
2505          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2506          clib_net_to_host_u16 (mp->key_id), mp->key);
2507
2508   vec_free (s);
2509   vec_free (eid);
2510 }
2511
2512 static void
2513 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2514                                               * mp)
2515 {
2516   vat_main_t *vam = &vat_main;
2517   vat_json_node_t *node = 0;
2518   u8 *eid = 0;
2519
2520   if (VAT_JSON_ARRAY != vam->json_tree.type)
2521     {
2522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2523       vat_json_init_array (&vam->json_tree);
2524     }
2525   node = vat_json_array_add (&vam->json_tree);
2526
2527   vat_json_init_object (node);
2528   if (~0 == mp->locator_set_index)
2529     vat_json_object_add_uint (node, "action", mp->action);
2530   else
2531     vat_json_object_add_uint (node, "locator_set_index",
2532                               clib_net_to_host_u32 (mp->locator_set_index));
2533
2534   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2535   eid = format (0, "%U", format_lisp_eid_vat,
2536                 mp->eid_type,
2537                 mp->eid,
2538                 mp->eid_prefix_len,
2539                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2540   vec_add1 (eid, 0);
2541   vat_json_object_add_string_copy (node, "eid", eid);
2542   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2543   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2544   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2545
2546   if (mp->key_id)
2547     {
2548       vat_json_object_add_uint (node, "key_id",
2549                                 clib_net_to_host_u16 (mp->key_id));
2550       vat_json_object_add_string_copy (node, "key", mp->key);
2551     }
2552   vec_free (eid);
2553 }
2554
2555 static void
2556   vl_api_lisp_eid_table_map_details_t_handler
2557   (vl_api_lisp_eid_table_map_details_t * mp)
2558 {
2559   vat_main_t *vam = &vat_main;
2560
2561   u8 *line = format (0, "%=10d%=10d",
2562                      clib_net_to_host_u32 (mp->vni),
2563                      clib_net_to_host_u32 (mp->dp_table));
2564   print (vam->ofp, "%v", line);
2565   vec_free (line);
2566 }
2567
2568 static void
2569   vl_api_lisp_eid_table_map_details_t_handler_json
2570   (vl_api_lisp_eid_table_map_details_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   vat_json_node_t *node = NULL;
2574
2575   if (VAT_JSON_ARRAY != vam->json_tree.type)
2576     {
2577       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2578       vat_json_init_array (&vam->json_tree);
2579     }
2580   node = vat_json_array_add (&vam->json_tree);
2581   vat_json_init_object (node);
2582   vat_json_object_add_uint (node, "dp_table",
2583                             clib_net_to_host_u32 (mp->dp_table));
2584   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2585 }
2586
2587 static void
2588   vl_api_lisp_eid_table_vni_details_t_handler
2589   (vl_api_lisp_eid_table_vni_details_t * mp)
2590 {
2591   vat_main_t *vam = &vat_main;
2592
2593   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2594   print (vam->ofp, "%v", line);
2595   vec_free (line);
2596 }
2597
2598 static void
2599   vl_api_lisp_eid_table_vni_details_t_handler_json
2600   (vl_api_lisp_eid_table_vni_details_t * mp)
2601 {
2602   vat_main_t *vam = &vat_main;
2603   vat_json_node_t *node = NULL;
2604
2605   if (VAT_JSON_ARRAY != vam->json_tree.type)
2606     {
2607       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2608       vat_json_init_array (&vam->json_tree);
2609     }
2610   node = vat_json_array_add (&vam->json_tree);
2611   vat_json_init_object (node);
2612   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2613 }
2614
2615 static void
2616   vl_api_show_lisp_map_register_state_reply_t_handler
2617   (vl_api_show_lisp_map_register_state_reply_t * mp)
2618 {
2619   vat_main_t *vam = &vat_main;
2620   int retval = clib_net_to_host_u32 (mp->retval);
2621
2622   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2623
2624   vam->retval = retval;
2625   vam->result_ready = 1;
2626 }
2627
2628 static void
2629   vl_api_show_lisp_map_register_state_reply_t_handler_json
2630   (vl_api_show_lisp_map_register_state_reply_t * mp)
2631 {
2632   vat_main_t *vam = &vat_main;
2633   vat_json_node_t _node, *node = &_node;
2634   int retval = clib_net_to_host_u32 (mp->retval);
2635
2636   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2637
2638   vat_json_init_object (node);
2639   vat_json_object_add_string_copy (node, "state", s);
2640
2641   vat_json_print (vam->ofp, node);
2642   vat_json_free (node);
2643
2644   vam->retval = retval;
2645   vam->result_ready = 1;
2646   vec_free (s);
2647 }
2648
2649 static void
2650   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2651   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2652 {
2653   vat_main_t *vam = &vat_main;
2654   int retval = clib_net_to_host_u32 (mp->retval);
2655
2656   if (retval)
2657     goto end;
2658
2659   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2660 end:
2661   vam->retval = retval;
2662   vam->result_ready = 1;
2663 }
2664
2665 static void
2666   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2667   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2668 {
2669   vat_main_t *vam = &vat_main;
2670   vat_json_node_t _node, *node = &_node;
2671   int retval = clib_net_to_host_u32 (mp->retval);
2672
2673   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2674   vat_json_init_object (node);
2675   vat_json_object_add_string_copy (node, "state", s);
2676
2677   vat_json_print (vam->ofp, node);
2678   vat_json_free (node);
2679
2680   vam->retval = retval;
2681   vam->result_ready = 1;
2682   vec_free (s);
2683 }
2684
2685 static void
2686 api_lisp_gpe_fwd_entry_net_to_host (vl_api_lisp_gpe_fwd_entry_t * e)
2687 {
2688   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2689   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2690 }
2691
2692 static void
2693   lisp_gpe_fwd_entries_get_reply_t_net_to_host
2694   (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2695 {
2696   u32 i;
2697
2698   mp->count = clib_net_to_host_u32 (mp->count);
2699   for (i = 0; i < mp->count; i++)
2700     {
2701       api_lisp_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2702     }
2703 }
2704
2705 static void
2706   vl_api_lisp_gpe_fwd_entry_path_details_t_handler
2707   (vl_api_lisp_gpe_fwd_entry_path_details_t * mp)
2708 {
2709   vat_main_t *vam = &vat_main;
2710   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2711
2712   if (mp->lcl_loc.is_ip4)
2713     format_ip_address_fcn = format_ip4_address;
2714   else
2715     format_ip_address_fcn = format_ip6_address;
2716
2717   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2718          format_ip_address_fcn, &mp->lcl_loc,
2719          format_ip_address_fcn, &mp->rmt_loc);
2720 }
2721
2722 static void
2723 lisp_fill_locator_node (vat_json_node_t * n, vl_api_lisp_gpe_locator_t * loc)
2724 {
2725   struct in6_addr ip6;
2726   struct in_addr ip4;
2727
2728   if (loc->is_ip4)
2729     {
2730       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2731       vat_json_object_add_ip4 (n, "address", ip4);
2732     }
2733   else
2734     {
2735       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2736       vat_json_object_add_ip6 (n, "address", ip6);
2737     }
2738   vat_json_object_add_uint (n, "weight", loc->weight);
2739 }
2740
2741 static void
2742   vl_api_lisp_gpe_fwd_entry_path_details_t_handler_json
2743   (vl_api_lisp_gpe_fwd_entry_path_details_t * mp)
2744 {
2745   vat_main_t *vam = &vat_main;
2746   vat_json_node_t *node = NULL;
2747   vat_json_node_t *loc_node;
2748
2749   if (VAT_JSON_ARRAY != vam->json_tree.type)
2750     {
2751       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2752       vat_json_init_array (&vam->json_tree);
2753     }
2754   node = vat_json_array_add (&vam->json_tree);
2755   vat_json_init_object (node);
2756
2757   loc_node = vat_json_object_add (node, "local_locator");
2758   vat_json_init_object (loc_node);
2759   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2760
2761   loc_node = vat_json_object_add (node, "remote_locator");
2762   vat_json_init_object (loc_node);
2763   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2764 }
2765
2766 static void
2767   vl_api_lisp_gpe_fwd_entries_get_reply_t_handler
2768   (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2769 {
2770   vat_main_t *vam = &vat_main;
2771   u32 i;
2772   int retval = clib_net_to_host_u32 (mp->retval);
2773   vl_api_lisp_gpe_fwd_entry_t *e;
2774
2775   if (retval)
2776     goto end;
2777
2778   lisp_gpe_fwd_entries_get_reply_t_net_to_host (mp);
2779
2780   for (i = 0; i < mp->count; i++)
2781     {
2782       e = &mp->entries[i];
2783       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2784              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2785              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2786     }
2787
2788 end:
2789   vam->retval = retval;
2790   vam->result_ready = 1;
2791 }
2792
2793 static void
2794   vl_api_lisp_gpe_fwd_entries_get_reply_t_handler_json
2795   (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp)
2796 {
2797   u8 *s = 0;
2798   vat_main_t *vam = &vat_main;
2799   vat_json_node_t *e = 0, root;
2800   u32 i;
2801   int retval = clib_net_to_host_u32 (mp->retval);
2802   vl_api_lisp_gpe_fwd_entry_t *fwd;
2803
2804   if (retval)
2805     goto end;
2806
2807   lisp_gpe_fwd_entries_get_reply_t_net_to_host (mp);
2808   vat_json_init_array (&root);
2809
2810   for (i = 0; i < mp->count; i++)
2811     {
2812       e = vat_json_array_add (&root);
2813       fwd = &mp->entries[i];
2814
2815       vat_json_init_object (e);
2816       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2817       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2818
2819       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2820                   fwd->leid_prefix_len);
2821       vec_add1 (s, 0);
2822       vat_json_object_add_string_copy (e, "leid", s);
2823       vec_free (s);
2824
2825       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2826                   fwd->reid_prefix_len);
2827       vec_add1 (s, 0);
2828       vat_json_object_add_string_copy (e, "reid", s);
2829       vec_free (s);
2830     }
2831
2832   vat_json_print (vam->ofp, &root);
2833   vat_json_free (&root);
2834
2835 end:
2836   vam->retval = retval;
2837   vam->result_ready = 1;
2838 }
2839
2840 static void
2841   vl_api_lisp_adjacencies_get_reply_t_handler
2842   (vl_api_lisp_adjacencies_get_reply_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   u32 i, n;
2846   int retval = clib_net_to_host_u32 (mp->retval);
2847   vl_api_lisp_adjacency_t *a;
2848
2849   if (retval)
2850     goto end;
2851
2852   n = clib_net_to_host_u32 (mp->count);
2853
2854   for (i = 0; i < n; i++)
2855     {
2856       a = &mp->adjacencies[i];
2857       print (vam->ofp, "%U %40U",
2858              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2859              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2860     }
2861
2862 end:
2863   vam->retval = retval;
2864   vam->result_ready = 1;
2865 }
2866
2867 static void
2868   vl_api_lisp_adjacencies_get_reply_t_handler_json
2869   (vl_api_lisp_adjacencies_get_reply_t * mp)
2870 {
2871   u8 *s = 0;
2872   vat_main_t *vam = &vat_main;
2873   vat_json_node_t *e = 0, root;
2874   u32 i, n;
2875   int retval = clib_net_to_host_u32 (mp->retval);
2876   vl_api_lisp_adjacency_t *a;
2877
2878   if (retval)
2879     goto end;
2880
2881   n = clib_net_to_host_u32 (mp->count);
2882   vat_json_init_array (&root);
2883
2884   for (i = 0; i < n; i++)
2885     {
2886       e = vat_json_array_add (&root);
2887       a = &mp->adjacencies[i];
2888
2889       vat_json_init_object (e);
2890       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2891                   a->leid_prefix_len);
2892       vec_add1 (s, 0);
2893       vat_json_object_add_string_copy (e, "leid", s);
2894       vec_free (s);
2895
2896       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2897                   a->reid_prefix_len);
2898       vec_add1 (s, 0);
2899       vat_json_object_add_string_copy (e, "reid", s);
2900       vec_free (s);
2901     }
2902
2903   vat_json_print (vam->ofp, &root);
2904   vat_json_free (&root);
2905
2906 end:
2907   vam->retval = retval;
2908   vam->result_ready = 1;
2909 }
2910
2911 static void
2912 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2913                                           * mp)
2914 {
2915   vat_main_t *vam = &vat_main;
2916
2917   print (vam->ofp, "%=20U",
2918          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2919          mp->ip_address);
2920 }
2921
2922 static void
2923   vl_api_lisp_map_server_details_t_handler_json
2924   (vl_api_lisp_map_server_details_t * mp)
2925 {
2926   vat_main_t *vam = &vat_main;
2927   vat_json_node_t *node = NULL;
2928   struct in6_addr ip6;
2929   struct in_addr ip4;
2930
2931   if (VAT_JSON_ARRAY != vam->json_tree.type)
2932     {
2933       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2934       vat_json_init_array (&vam->json_tree);
2935     }
2936   node = vat_json_array_add (&vam->json_tree);
2937
2938   vat_json_init_object (node);
2939   if (mp->is_ipv6)
2940     {
2941       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2942       vat_json_object_add_ip6 (node, "map-server", ip6);
2943     }
2944   else
2945     {
2946       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2947       vat_json_object_add_ip4 (node, "map-server", ip4);
2948     }
2949 }
2950
2951 static void
2952 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2953                                             * mp)
2954 {
2955   vat_main_t *vam = &vat_main;
2956
2957   print (vam->ofp, "%=20U",
2958          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2959          mp->ip_address);
2960 }
2961
2962 static void
2963   vl_api_lisp_map_resolver_details_t_handler_json
2964   (vl_api_lisp_map_resolver_details_t * mp)
2965 {
2966   vat_main_t *vam = &vat_main;
2967   vat_json_node_t *node = NULL;
2968   struct in6_addr ip6;
2969   struct in_addr ip4;
2970
2971   if (VAT_JSON_ARRAY != vam->json_tree.type)
2972     {
2973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2974       vat_json_init_array (&vam->json_tree);
2975     }
2976   node = vat_json_array_add (&vam->json_tree);
2977
2978   vat_json_init_object (node);
2979   if (mp->is_ipv6)
2980     {
2981       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2982       vat_json_object_add_ip6 (node, "map resolver", ip6);
2983     }
2984   else
2985     {
2986       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2987       vat_json_object_add_ip4 (node, "map resolver", ip4);
2988     }
2989 }
2990
2991 static void
2992   vl_api_show_lisp_status_reply_t_handler
2993   (vl_api_show_lisp_status_reply_t * mp)
2994 {
2995   vat_main_t *vam = &vat_main;
2996   i32 retval = ntohl (mp->retval);
2997
2998   if (0 <= retval)
2999     {
3000       print (vam->ofp, "feature: %s\ngpe: %s",
3001              mp->feature_status ? "enabled" : "disabled",
3002              mp->gpe_status ? "enabled" : "disabled");
3003     }
3004
3005   vam->retval = retval;
3006   vam->result_ready = 1;
3007 }
3008
3009 static void
3010   vl_api_show_lisp_status_reply_t_handler_json
3011   (vl_api_show_lisp_status_reply_t * mp)
3012 {
3013   vat_main_t *vam = &vat_main;
3014   vat_json_node_t node;
3015   u8 *gpe_status = NULL;
3016   u8 *feature_status = NULL;
3017
3018   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3019   feature_status = format (0, "%s",
3020                            mp->feature_status ? "enabled" : "disabled");
3021   vec_add1 (gpe_status, 0);
3022   vec_add1 (feature_status, 0);
3023
3024   vat_json_init_object (&node);
3025   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3026   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3027
3028   vec_free (gpe_status);
3029   vec_free (feature_status);
3030
3031   vat_json_print (vam->ofp, &node);
3032   vat_json_free (&node);
3033
3034   vam->retval = ntohl (mp->retval);
3035   vam->result_ready = 1;
3036 }
3037
3038 static void
3039   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
3040   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
3041 {
3042   vat_main_t *vam = &vat_main;
3043   i32 retval = ntohl (mp->retval);
3044
3045   if (retval >= 0)
3046     {
3047       print (vam->ofp, "%=20s", mp->locator_set_name);
3048     }
3049
3050   vam->retval = retval;
3051   vam->result_ready = 1;
3052 }
3053
3054 static void
3055   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
3056   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
3057 {
3058   vat_main_t *vam = &vat_main;
3059   vat_json_node_t *node = NULL;
3060
3061   if (VAT_JSON_ARRAY != vam->json_tree.type)
3062     {
3063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3064       vat_json_init_array (&vam->json_tree);
3065     }
3066   node = vat_json_array_add (&vam->json_tree);
3067
3068   vat_json_init_object (node);
3069   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3070
3071   vat_json_print (vam->ofp, node);
3072   vat_json_free (node);
3073
3074   vam->retval = ntohl (mp->retval);
3075   vam->result_ready = 1;
3076 }
3077
3078 static u8 *
3079 format_lisp_map_request_mode (u8 * s, va_list * args)
3080 {
3081   u32 mode = va_arg (*args, u32);
3082
3083   switch (mode)
3084     {
3085     case 0:
3086       return format (0, "dst-only");
3087     case 1:
3088       return format (0, "src-dst");
3089     }
3090   return 0;
3091 }
3092
3093 static void
3094   vl_api_show_lisp_map_request_mode_reply_t_handler
3095   (vl_api_show_lisp_map_request_mode_reply_t * mp)
3096 {
3097   vat_main_t *vam = &vat_main;
3098   i32 retval = ntohl (mp->retval);
3099
3100   if (0 <= retval)
3101     {
3102       u32 mode = mp->mode;
3103       print (vam->ofp, "map_request_mode: %U",
3104              format_lisp_map_request_mode, mode);
3105     }
3106
3107   vam->retval = retval;
3108   vam->result_ready = 1;
3109 }
3110
3111 static void
3112   vl_api_show_lisp_map_request_mode_reply_t_handler_json
3113   (vl_api_show_lisp_map_request_mode_reply_t * mp)
3114 {
3115   vat_main_t *vam = &vat_main;
3116   vat_json_node_t node;
3117   u8 *s = 0;
3118   u32 mode;
3119
3120   mode = mp->mode;
3121   s = format (0, "%U", format_lisp_map_request_mode, mode);
3122   vec_add1 (s, 0);
3123
3124   vat_json_init_object (&node);
3125   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3126   vat_json_print (vam->ofp, &node);
3127   vat_json_free (&node);
3128
3129   vec_free (s);
3130   vam->retval = ntohl (mp->retval);
3131   vam->result_ready = 1;
3132 }
3133
3134 static void
3135 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
3136 {
3137   vat_main_t *vam = &vat_main;
3138   i32 retval = ntohl (mp->retval);
3139
3140   if (0 <= retval)
3141     {
3142       print (vam->ofp, "%-20s%-16s",
3143              mp->status ? "enabled" : "disabled",
3144              mp->status ? (char *) mp->locator_set_name : "");
3145     }
3146
3147   vam->retval = retval;
3148   vam->result_ready = 1;
3149 }
3150
3151 static void
3152 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
3153                                             mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   vat_json_node_t node;
3157   u8 *status = 0;
3158
3159   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3160   vec_add1 (status, 0);
3161
3162   vat_json_init_object (&node);
3163   vat_json_object_add_string_copy (&node, "status", status);
3164   if (mp->status)
3165     {
3166       vat_json_object_add_string_copy (&node, "locator_set",
3167                                        mp->locator_set_name);
3168     }
3169
3170   vec_free (status);
3171
3172   vat_json_print (vam->ofp, &node);
3173   vat_json_free (&node);
3174
3175   vam->retval = ntohl (mp->retval);
3176   vam->result_ready = 1;
3177 }
3178
3179 static u8 *
3180 format_policer_type (u8 * s, va_list * va)
3181 {
3182   u32 i = va_arg (*va, u32);
3183
3184   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3185     s = format (s, "1r2c");
3186   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3187     s = format (s, "1r3c");
3188   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3189     s = format (s, "2r3c-2698");
3190   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3191     s = format (s, "2r3c-4115");
3192   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3193     s = format (s, "2r3c-mef5cf1");
3194   else
3195     s = format (s, "ILLEGAL");
3196   return s;
3197 }
3198
3199 static u8 *
3200 format_policer_rate_type (u8 * s, va_list * va)
3201 {
3202   u32 i = va_arg (*va, u32);
3203
3204   if (i == SSE2_QOS_RATE_KBPS)
3205     s = format (s, "kbps");
3206   else if (i == SSE2_QOS_RATE_PPS)
3207     s = format (s, "pps");
3208   else
3209     s = format (s, "ILLEGAL");
3210   return s;
3211 }
3212
3213 static u8 *
3214 format_policer_round_type (u8 * s, va_list * va)
3215 {
3216   u32 i = va_arg (*va, u32);
3217
3218   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3219     s = format (s, "closest");
3220   else if (i == SSE2_QOS_ROUND_TO_UP)
3221     s = format (s, "up");
3222   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3223     s = format (s, "down");
3224   else
3225     s = format (s, "ILLEGAL");
3226   return s;
3227 }
3228
3229 static u8 *
3230 format_policer_action_type (u8 * s, va_list * va)
3231 {
3232   u32 i = va_arg (*va, u32);
3233
3234   if (i == SSE2_QOS_ACTION_DROP)
3235     s = format (s, "drop");
3236   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3237     s = format (s, "transmit");
3238   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3239     s = format (s, "mark-and-transmit");
3240   else
3241     s = format (s, "ILLEGAL");
3242   return s;
3243 }
3244
3245 static u8 *
3246 format_dscp (u8 * s, va_list * va)
3247 {
3248   u32 i = va_arg (*va, u32);
3249   char *t = 0;
3250
3251   switch (i)
3252     {
3253 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3254       foreach_vnet_dscp
3255 #undef _
3256     default:
3257       return format (s, "ILLEGAL");
3258     }
3259   s = format (s, "%s", t);
3260   return s;
3261 }
3262
3263 static void
3264 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3265 {
3266   vat_main_t *vam = &vat_main;
3267   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3268
3269   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3270     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3271   else
3272     conform_dscp_str = format (0, "");
3273
3274   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3275     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3276   else
3277     exceed_dscp_str = format (0, "");
3278
3279   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3280     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3281   else
3282     violate_dscp_str = format (0, "");
3283
3284   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3285          "rate type %U, round type %U, %s rate, %s color-aware, "
3286          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3287          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3288          "conform action %U%s, exceed action %U%s, violate action %U%s",
3289          mp->name,
3290          format_policer_type, mp->type,
3291          ntohl (mp->cir),
3292          ntohl (mp->eir),
3293          clib_net_to_host_u64 (mp->cb),
3294          clib_net_to_host_u64 (mp->eb),
3295          format_policer_rate_type, mp->rate_type,
3296          format_policer_round_type, mp->round_type,
3297          mp->single_rate ? "single" : "dual",
3298          mp->color_aware ? "is" : "not",
3299          ntohl (mp->cir_tokens_per_period),
3300          ntohl (mp->pir_tokens_per_period),
3301          ntohl (mp->scale),
3302          ntohl (mp->current_limit),
3303          ntohl (mp->current_bucket),
3304          ntohl (mp->extended_limit),
3305          ntohl (mp->extended_bucket),
3306          clib_net_to_host_u64 (mp->last_update_time),
3307          format_policer_action_type, mp->conform_action_type,
3308          conform_dscp_str,
3309          format_policer_action_type, mp->exceed_action_type,
3310          exceed_dscp_str,
3311          format_policer_action_type, mp->violate_action_type,
3312          violate_dscp_str);
3313
3314   vec_free (conform_dscp_str);
3315   vec_free (exceed_dscp_str);
3316   vec_free (violate_dscp_str);
3317 }
3318
3319 static void vl_api_policer_details_t_handler_json
3320   (vl_api_policer_details_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t *node;
3324   u8 *rate_type_str, *round_type_str, *type_str;
3325   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3326
3327   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3328   round_type_str =
3329     format (0, "%U", format_policer_round_type, mp->round_type);
3330   type_str = format (0, "%U", format_policer_type, mp->type);
3331   conform_action_str = format (0, "%U", format_policer_action_type,
3332                                mp->conform_action_type);
3333   exceed_action_str = format (0, "%U", format_policer_action_type,
3334                               mp->exceed_action_type);
3335   violate_action_str = format (0, "%U", format_policer_action_type,
3336                                mp->violate_action_type);
3337
3338   if (VAT_JSON_ARRAY != vam->json_tree.type)
3339     {
3340       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3341       vat_json_init_array (&vam->json_tree);
3342     }
3343   node = vat_json_array_add (&vam->json_tree);
3344
3345   vat_json_init_object (node);
3346   vat_json_object_add_string_copy (node, "name", mp->name);
3347   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3348   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3349   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3350   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3351   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3352   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3353   vat_json_object_add_string_copy (node, "type", type_str);
3354   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3355   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3356   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3357   vat_json_object_add_uint (node, "cir_tokens_per_period",
3358                             ntohl (mp->cir_tokens_per_period));
3359   vat_json_object_add_uint (node, "eir_tokens_per_period",
3360                             ntohl (mp->pir_tokens_per_period));
3361   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3362   vat_json_object_add_uint (node, "current_bucket",
3363                             ntohl (mp->current_bucket));
3364   vat_json_object_add_uint (node, "extended_limit",
3365                             ntohl (mp->extended_limit));
3366   vat_json_object_add_uint (node, "extended_bucket",
3367                             ntohl (mp->extended_bucket));
3368   vat_json_object_add_uint (node, "last_update_time",
3369                             ntohl (mp->last_update_time));
3370   vat_json_object_add_string_copy (node, "conform_action",
3371                                    conform_action_str);
3372   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3373     {
3374       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3375       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3376       vec_free (dscp_str);
3377     }
3378   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3379   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3380     {
3381       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3382       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3383       vec_free (dscp_str);
3384     }
3385   vat_json_object_add_string_copy (node, "violate_action",
3386                                    violate_action_str);
3387   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3388     {
3389       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3390       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3391       vec_free (dscp_str);
3392     }
3393
3394   vec_free (rate_type_str);
3395   vec_free (round_type_str);
3396   vec_free (type_str);
3397   vec_free (conform_action_str);
3398   vec_free (exceed_action_str);
3399   vec_free (violate_action_str);
3400 }
3401
3402 static void
3403 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3404                                            mp)
3405 {
3406   vat_main_t *vam = &vat_main;
3407   int i, count = ntohl (mp->count);
3408
3409   if (count > 0)
3410     print (vam->ofp, "classify table ids (%d) : ", count);
3411   for (i = 0; i < count; i++)
3412     {
3413       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3414       print (vam->ofp, (i < count - 1) ? "," : "");
3415     }
3416   vam->retval = ntohl (mp->retval);
3417   vam->result_ready = 1;
3418 }
3419
3420 static void
3421   vl_api_classify_table_ids_reply_t_handler_json
3422   (vl_api_classify_table_ids_reply_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   int i, count = ntohl (mp->count);
3426
3427   if (count > 0)
3428     {
3429       vat_json_node_t node;
3430
3431       vat_json_init_object (&node);
3432       for (i = 0; i < count; i++)
3433         {
3434           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3435         }
3436       vat_json_print (vam->ofp, &node);
3437       vat_json_free (&node);
3438     }
3439   vam->retval = ntohl (mp->retval);
3440   vam->result_ready = 1;
3441 }
3442
3443 static void
3444   vl_api_classify_table_by_interface_reply_t_handler
3445   (vl_api_classify_table_by_interface_reply_t * mp)
3446 {
3447   vat_main_t *vam = &vat_main;
3448   u32 table_id;
3449
3450   table_id = ntohl (mp->l2_table_id);
3451   if (table_id != ~0)
3452     print (vam->ofp, "l2 table id : %d", table_id);
3453   else
3454     print (vam->ofp, "l2 table id : No input ACL tables configured");
3455   table_id = ntohl (mp->ip4_table_id);
3456   if (table_id != ~0)
3457     print (vam->ofp, "ip4 table id : %d", table_id);
3458   else
3459     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3460   table_id = ntohl (mp->ip6_table_id);
3461   if (table_id != ~0)
3462     print (vam->ofp, "ip6 table id : %d", table_id);
3463   else
3464     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3465   vam->retval = ntohl (mp->retval);
3466   vam->result_ready = 1;
3467 }
3468
3469 static void
3470   vl_api_classify_table_by_interface_reply_t_handler_json
3471   (vl_api_classify_table_by_interface_reply_t * mp)
3472 {
3473   vat_main_t *vam = &vat_main;
3474   vat_json_node_t node;
3475
3476   vat_json_init_object (&node);
3477
3478   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3479   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3480   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3481
3482   vat_json_print (vam->ofp, &node);
3483   vat_json_free (&node);
3484
3485   vam->retval = ntohl (mp->retval);
3486   vam->result_ready = 1;
3487 }
3488
3489 static void vl_api_policer_add_del_reply_t_handler
3490   (vl_api_policer_add_del_reply_t * mp)
3491 {
3492   vat_main_t *vam = &vat_main;
3493   i32 retval = ntohl (mp->retval);
3494   if (vam->async_mode)
3495     {
3496       vam->async_errors += (retval < 0);
3497     }
3498   else
3499     {
3500       vam->retval = retval;
3501       vam->result_ready = 1;
3502       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3503         /*
3504          * Note: this is just barely thread-safe, depends on
3505          * the main thread spinning waiting for an answer...
3506          */
3507         errmsg ("policer index %d", ntohl (mp->policer_index));
3508     }
3509 }
3510
3511 static void vl_api_policer_add_del_reply_t_handler_json
3512   (vl_api_policer_add_del_reply_t * mp)
3513 {
3514   vat_main_t *vam = &vat_main;
3515   vat_json_node_t node;
3516
3517   vat_json_init_object (&node);
3518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3519   vat_json_object_add_uint (&node, "policer_index",
3520                             ntohl (mp->policer_index));
3521
3522   vat_json_print (vam->ofp, &node);
3523   vat_json_free (&node);
3524
3525   vam->retval = ntohl (mp->retval);
3526   vam->result_ready = 1;
3527 }
3528
3529 /* Format hex dump. */
3530 u8 *
3531 format_hex_bytes (u8 * s, va_list * va)
3532 {
3533   u8 *bytes = va_arg (*va, u8 *);
3534   int n_bytes = va_arg (*va, int);
3535   uword i;
3536
3537   /* Print short or long form depending on byte count. */
3538   uword short_form = n_bytes <= 32;
3539   uword indent = format_get_indent (s);
3540
3541   if (n_bytes == 0)
3542     return s;
3543
3544   for (i = 0; i < n_bytes; i++)
3545     {
3546       if (!short_form && (i % 32) == 0)
3547         s = format (s, "%08x: ", i);
3548       s = format (s, "%02x", bytes[i]);
3549       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3550         s = format (s, "\n%U", format_white_space, indent);
3551     }
3552
3553   return s;
3554 }
3555
3556 static void
3557 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3558                                             * mp)
3559 {
3560   vat_main_t *vam = &vat_main;
3561   i32 retval = ntohl (mp->retval);
3562   if (retval == 0)
3563     {
3564       print (vam->ofp, "classify table info :");
3565       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3566              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3567              ntohl (mp->miss_next_index));
3568       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3569              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3570              ntohl (mp->match_n_vectors));
3571       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3572              ntohl (mp->mask_length));
3573     }
3574   vam->retval = retval;
3575   vam->result_ready = 1;
3576 }
3577
3578 static void
3579   vl_api_classify_table_info_reply_t_handler_json
3580   (vl_api_classify_table_info_reply_t * mp)
3581 {
3582   vat_main_t *vam = &vat_main;
3583   vat_json_node_t node;
3584
3585   i32 retval = ntohl (mp->retval);
3586   if (retval == 0)
3587     {
3588       vat_json_init_object (&node);
3589
3590       vat_json_object_add_int (&node, "sessions",
3591                                ntohl (mp->active_sessions));
3592       vat_json_object_add_int (&node, "nexttbl",
3593                                ntohl (mp->next_table_index));
3594       vat_json_object_add_int (&node, "nextnode",
3595                                ntohl (mp->miss_next_index));
3596       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3597       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3598       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3599       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3600                       ntohl (mp->mask_length), 0);
3601       vat_json_object_add_string_copy (&node, "mask", s);
3602
3603       vat_json_print (vam->ofp, &node);
3604       vat_json_free (&node);
3605     }
3606   vam->retval = ntohl (mp->retval);
3607   vam->result_ready = 1;
3608 }
3609
3610 static void
3611 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3612                                            mp)
3613 {
3614   vat_main_t *vam = &vat_main;
3615
3616   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3617          ntohl (mp->hit_next_index), ntohl (mp->advance),
3618          ntohl (mp->opaque_index));
3619   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3620          ntohl (mp->match_length));
3621 }
3622
3623 static void
3624   vl_api_classify_session_details_t_handler_json
3625   (vl_api_classify_session_details_t * mp)
3626 {
3627   vat_main_t *vam = &vat_main;
3628   vat_json_node_t *node = NULL;
3629
3630   if (VAT_JSON_ARRAY != vam->json_tree.type)
3631     {
3632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3633       vat_json_init_array (&vam->json_tree);
3634     }
3635   node = vat_json_array_add (&vam->json_tree);
3636
3637   vat_json_init_object (node);
3638   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3639   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3640   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3641   u8 *s =
3642     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3643             0);
3644   vat_json_object_add_string_copy (node, "match", s);
3645 }
3646
3647 static void vl_api_pg_create_interface_reply_t_handler
3648   (vl_api_pg_create_interface_reply_t * mp)
3649 {
3650   vat_main_t *vam = &vat_main;
3651
3652   vam->retval = ntohl (mp->retval);
3653   vam->result_ready = 1;
3654 }
3655
3656 static void vl_api_pg_create_interface_reply_t_handler_json
3657   (vl_api_pg_create_interface_reply_t * mp)
3658 {
3659   vat_main_t *vam = &vat_main;
3660   vat_json_node_t node;
3661
3662   i32 retval = ntohl (mp->retval);
3663   if (retval == 0)
3664     {
3665       vat_json_init_object (&node);
3666
3667       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3668
3669       vat_json_print (vam->ofp, &node);
3670       vat_json_free (&node);
3671     }
3672   vam->retval = ntohl (mp->retval);
3673   vam->result_ready = 1;
3674 }
3675
3676 static void vl_api_policer_classify_details_t_handler
3677   (vl_api_policer_classify_details_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680
3681   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3682          ntohl (mp->table_index));
3683 }
3684
3685 static void vl_api_policer_classify_details_t_handler_json
3686   (vl_api_policer_classify_details_t * mp)
3687 {
3688   vat_main_t *vam = &vat_main;
3689   vat_json_node_t *node;
3690
3691   if (VAT_JSON_ARRAY != vam->json_tree.type)
3692     {
3693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3694       vat_json_init_array (&vam->json_tree);
3695     }
3696   node = vat_json_array_add (&vam->json_tree);
3697
3698   vat_json_init_object (node);
3699   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3700   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3701 }
3702
3703 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3704   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3705 {
3706   vat_main_t *vam = &vat_main;
3707   i32 retval = ntohl (mp->retval);
3708   if (vam->async_mode)
3709     {
3710       vam->async_errors += (retval < 0);
3711     }
3712   else
3713     {
3714       vam->retval = retval;
3715       vam->sw_if_index = ntohl (mp->sw_if_index);
3716       vam->result_ready = 1;
3717     }
3718 }
3719
3720 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3721   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3722 {
3723   vat_main_t *vam = &vat_main;
3724   vat_json_node_t node;
3725
3726   vat_json_init_object (&node);
3727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3729
3730   vat_json_print (vam->ofp, &node);
3731   vat_json_free (&node);
3732
3733   vam->retval = ntohl (mp->retval);
3734   vam->result_ready = 1;
3735 }
3736
3737 static void vl_api_flow_classify_details_t_handler
3738   (vl_api_flow_classify_details_t * mp)
3739 {
3740   vat_main_t *vam = &vat_main;
3741
3742   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3743          ntohl (mp->table_index));
3744 }
3745
3746 static void vl_api_flow_classify_details_t_handler_json
3747   (vl_api_flow_classify_details_t * mp)
3748 {
3749   vat_main_t *vam = &vat_main;
3750   vat_json_node_t *node;
3751
3752   if (VAT_JSON_ARRAY != vam->json_tree.type)
3753     {
3754       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3755       vat_json_init_array (&vam->json_tree);
3756     }
3757   node = vat_json_array_add (&vam->json_tree);
3758
3759   vat_json_init_object (node);
3760   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3761   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3762 }
3763
3764
3765
3766 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3767 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3768 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3769 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3770 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3771 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3772 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3773 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3774 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3775 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3776
3777 /*
3778  * Generate boilerplate reply handlers, which
3779  * dig the return value out of the xxx_reply_t API message,
3780  * stick it into vam->retval, and set vam->result_ready
3781  *
3782  * Could also do this by pointing N message decode slots at
3783  * a single function, but that could break in subtle ways.
3784  */
3785
3786 #define foreach_standard_reply_retval_handler           \
3787 _(sw_interface_set_flags_reply)                         \
3788 _(sw_interface_add_del_address_reply)                   \
3789 _(sw_interface_set_table_reply)                         \
3790 _(sw_interface_set_mpls_enable_reply)                   \
3791 _(sw_interface_set_vpath_reply)                         \
3792 _(sw_interface_set_vxlan_bypass_reply)                  \
3793 _(sw_interface_set_l2_bridge_reply)                     \
3794 _(bridge_domain_add_del_reply)                          \
3795 _(sw_interface_set_l2_xconnect_reply)                   \
3796 _(l2fib_add_del_reply)                                  \
3797 _(ip_add_del_route_reply)                               \
3798 _(ip_mroute_add_del_reply)                              \
3799 _(mpls_route_add_del_reply)                             \
3800 _(mpls_ip_bind_unbind_reply)                            \
3801 _(proxy_arp_add_del_reply)                              \
3802 _(proxy_arp_intfc_enable_disable_reply)                 \
3803 _(sw_interface_set_unnumbered_reply)                    \
3804 _(ip_neighbor_add_del_reply)                            \
3805 _(reset_vrf_reply)                                      \
3806 _(oam_add_del_reply)                                    \
3807 _(reset_fib_reply)                                      \
3808 _(dhcp_proxy_config_reply)                              \
3809 _(dhcp_proxy_config_2_reply)                            \
3810 _(dhcp_proxy_set_vss_reply)                             \
3811 _(dhcp_client_config_reply)                             \
3812 _(set_ip_flow_hash_reply)                               \
3813 _(sw_interface_ip6_enable_disable_reply)                \
3814 _(sw_interface_ip6_set_link_local_address_reply)        \
3815 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3816 _(sw_interface_ip6nd_ra_config_reply)                   \
3817 _(set_arp_neighbor_limit_reply)                         \
3818 _(l2_patch_add_del_reply)                               \
3819 _(sr_tunnel_add_del_reply)                              \
3820 _(sr_policy_add_del_reply)                              \
3821 _(sr_multicast_map_add_del_reply)                       \
3822 _(classify_add_del_session_reply)                       \
3823 _(classify_set_interface_ip_table_reply)                \
3824 _(classify_set_interface_l2_tables_reply)               \
3825 _(l2tpv3_set_tunnel_cookies_reply)                      \
3826 _(l2tpv3_interface_enable_disable_reply)                \
3827 _(l2tpv3_set_lookup_key_reply)                          \
3828 _(l2_fib_clear_table_reply)                             \
3829 _(l2_interface_efp_filter_reply)                        \
3830 _(l2_interface_vlan_tag_rewrite_reply)                  \
3831 _(modify_vhost_user_if_reply)                           \
3832 _(delete_vhost_user_if_reply)                           \
3833 _(want_ip4_arp_events_reply)                            \
3834 _(want_ip6_nd_events_reply)                             \
3835 _(input_acl_set_interface_reply)                        \
3836 _(ipsec_spd_add_del_reply)                              \
3837 _(ipsec_interface_add_del_spd_reply)                    \
3838 _(ipsec_spd_add_del_entry_reply)                        \
3839 _(ipsec_sad_add_del_entry_reply)                        \
3840 _(ipsec_sa_set_key_reply)                               \
3841 _(ikev2_profile_add_del_reply)                          \
3842 _(ikev2_profile_set_auth_reply)                         \
3843 _(ikev2_profile_set_id_reply)                           \
3844 _(ikev2_profile_set_ts_reply)                           \
3845 _(ikev2_set_local_key_reply)                            \
3846 _(delete_loopback_reply)                                \
3847 _(bd_ip_mac_add_del_reply)                              \
3848 _(map_del_domain_reply)                                 \
3849 _(map_add_del_rule_reply)                               \
3850 _(want_interface_events_reply)                          \
3851 _(want_stats_reply)                                     \
3852 _(cop_interface_enable_disable_reply)                   \
3853 _(cop_whitelist_enable_disable_reply)                   \
3854 _(sw_interface_clear_stats_reply)                       \
3855 _(ioam_enable_reply)                              \
3856 _(ioam_disable_reply)                              \
3857 _(lisp_add_del_locator_reply)                           \
3858 _(lisp_add_del_local_eid_reply)                         \
3859 _(lisp_add_del_remote_mapping_reply)                    \
3860 _(lisp_add_del_adjacency_reply)                         \
3861 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3862 _(lisp_add_del_map_resolver_reply)                      \
3863 _(lisp_add_del_map_server_reply)                        \
3864 _(lisp_gpe_enable_disable_reply)                        \
3865 _(lisp_gpe_add_del_iface_reply)                         \
3866 _(lisp_enable_disable_reply)                            \
3867 _(lisp_rloc_probe_enable_disable_reply)                 \
3868 _(lisp_map_register_enable_disable_reply)               \
3869 _(lisp_pitr_set_locator_set_reply)                      \
3870 _(lisp_map_request_mode_reply)                          \
3871 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3872 _(lisp_eid_table_add_del_map_reply)                     \
3873 _(vxlan_gpe_add_del_tunnel_reply)                       \
3874 _(af_packet_delete_reply)                               \
3875 _(policer_classify_set_interface_reply)                 \
3876 _(netmap_create_reply)                                  \
3877 _(netmap_delete_reply)                                  \
3878 _(set_ipfix_exporter_reply)                             \
3879 _(set_ipfix_classify_stream_reply)                      \
3880 _(ipfix_classify_table_add_del_reply)                   \
3881 _(flow_classify_set_interface_reply)                    \
3882 _(sw_interface_span_enable_disable_reply)               \
3883 _(pg_capture_reply)                                     \
3884 _(pg_enable_disable_reply)                              \
3885 _(ip_source_and_port_range_check_add_del_reply)         \
3886 _(ip_source_and_port_range_check_interface_add_del_reply)\
3887 _(delete_subif_reply)                                   \
3888 _(l2_interface_pbb_tag_rewrite_reply)                   \
3889 _(punt_reply)                                           \
3890 _(feature_enable_disable_reply)                         \
3891 _(sw_interface_tag_add_del_reply)                       \
3892 _(sw_interface_set_mtu_reply)
3893
3894 #if DPDK > 0
3895 #define foreach_standard_dpdk_reply_retval_handler      \
3896 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3897 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3898 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3899 #endif
3900
3901 #define _(n)                                    \
3902     static void vl_api_##n##_t_handler          \
3903     (vl_api_##n##_t * mp)                       \
3904     {                                           \
3905         vat_main_t * vam = &vat_main;           \
3906         i32 retval = ntohl(mp->retval);         \
3907         if (vam->async_mode) {                  \
3908             vam->async_errors += (retval < 0);  \
3909         } else {                                \
3910             vam->retval = retval;               \
3911             vam->result_ready = 1;              \
3912         }                                       \
3913     }
3914 foreach_standard_reply_retval_handler;
3915 #undef _
3916
3917 #define _(n)                                    \
3918     static void vl_api_##n##_t_handler_json     \
3919     (vl_api_##n##_t * mp)                       \
3920     {                                           \
3921         vat_main_t * vam = &vat_main;           \
3922         vat_json_node_t node;                   \
3923         vat_json_init_object(&node);            \
3924         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3925         vat_json_print(vam->ofp, &node);        \
3926         vam->retval = ntohl(mp->retval);        \
3927         vam->result_ready = 1;                  \
3928     }
3929 foreach_standard_reply_retval_handler;
3930 #undef _
3931
3932 #if DPDK > 0
3933 #define _(n)                                    \
3934     static void vl_api_##n##_t_handler          \
3935     (vl_api_##n##_t * mp)                       \
3936     {                                           \
3937         vat_main_t * vam = &vat_main;           \
3938         i32 retval = ntohl(mp->retval);         \
3939         if (vam->async_mode) {                  \
3940             vam->async_errors += (retval < 0);  \
3941         } else {                                \
3942             vam->retval = retval;               \
3943             vam->result_ready = 1;              \
3944         }                                       \
3945     }
3946 foreach_standard_dpdk_reply_retval_handler;
3947 #undef _
3948
3949 #define _(n)                                    \
3950     static void vl_api_##n##_t_handler_json     \
3951     (vl_api_##n##_t * mp)                       \
3952     {                                           \
3953         vat_main_t * vam = &vat_main;           \
3954         vat_json_node_t node;                   \
3955         vat_json_init_object(&node);            \
3956         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3957         vat_json_print(vam->ofp, &node);        \
3958         vam->retval = ntohl(mp->retval);        \
3959         vam->result_ready = 1;                  \
3960     }
3961 foreach_standard_dpdk_reply_retval_handler;
3962 #undef _
3963 #endif
3964
3965 /*
3966  * Table of message reply handlers, must include boilerplate handlers
3967  * we just generated
3968  */
3969
3970 #define foreach_vpe_api_reply_msg                                       \
3971 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3972 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3973 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3974 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3975 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3976 _(CLI_REPLY, cli_reply)                                                 \
3977 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3978 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3979   sw_interface_add_del_address_reply)                                   \
3980 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3981 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3982 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3983 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3984 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3985   sw_interface_set_l2_xconnect_reply)                                   \
3986 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3987   sw_interface_set_l2_bridge_reply)                                     \
3988 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3989 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3990 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3991 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3992 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3993 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3994 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3995 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3996 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3997 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3998 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3999 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4000 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4001 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4002 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4003 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4004   proxy_arp_intfc_enable_disable_reply)                                 \
4005 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4006 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4007   sw_interface_set_unnumbered_reply)                                    \
4008 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4009 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4010 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4011 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4012 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4013 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4014 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4015 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
4016 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4017 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4018 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4019 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4020   sw_interface_ip6_enable_disable_reply)                                \
4021 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4022   sw_interface_ip6_set_link_local_address_reply)                        \
4023 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4024   sw_interface_ip6nd_ra_prefix_reply)                                   \
4025 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4026   sw_interface_ip6nd_ra_config_reply)                                   \
4027 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4028 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4029 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4030 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4031 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4032 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4033 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4034 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4035 classify_set_interface_ip_table_reply)                                  \
4036 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4037   classify_set_interface_l2_tables_reply)                               \
4038 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4039 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4040 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4041 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4042 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4043   l2tpv3_interface_enable_disable_reply)                                \
4044 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4045 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4046 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4047 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4048 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4049 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4050 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4051 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4052 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4053 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4054 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4055 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4056 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4057 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4058 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4059 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4060 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4061 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4062 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4063 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4064 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4065 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4066 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4067 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4068 _(IP_DETAILS, ip_details)                                               \
4069 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4070 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4071 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4072 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4073 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4074 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4075 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4076 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4077 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4078 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4079 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4080 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4081 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4082 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4083 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4084 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4085 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4086 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
4087 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4088 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4089 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4090 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4091 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4092 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4093 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4094 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4095 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4096 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4097 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4098 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4099 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4100 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4101 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
4102 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
4103 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
4104 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
4105 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
4106 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
4107 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
4108 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
4109 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
4110 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
4111 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
4112   lisp_map_register_enable_disable_reply)                               \
4113 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
4114   lisp_rloc_probe_enable_disable_reply)                                 \
4115 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
4116 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
4117 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
4118 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
4119 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
4120 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
4121 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
4122 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
4123 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
4124 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
4125 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
4126 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
4127 _(LISP_GPE_FWD_ENTRIES_GET_REPLY, lisp_gpe_fwd_entries_get_reply)       \
4128 _(LISP_GPE_FWD_ENTRY_PATH_DETAILS,                                      \
4129   lisp_gpe_fwd_entry_path_details)                                      \
4130 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
4131 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
4132   lisp_add_del_map_request_itr_rlocs_reply)                             \
4133 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
4134   lisp_get_map_request_itr_rlocs_reply)                                 \
4135 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
4136 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
4137 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
4138 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
4139   show_lisp_map_register_state_reply)                                   \
4140 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4141 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4142 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4143 _(POLICER_DETAILS, policer_details)                                     \
4144 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4145 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4146 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4147 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4148 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4149 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4150 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4151 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4152 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4153 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4154 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4155 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4156 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4157 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4158 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4159 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4160 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4161 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4162 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4163 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4164 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4165 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4166 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4167 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4168 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4169  ip_source_and_port_range_check_add_del_reply)                          \
4170 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4171  ip_source_and_port_range_check_interface_add_del_reply)                \
4172 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4173 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4174 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4175 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4176 _(PUNT_REPLY, punt_reply)                                               \
4177 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4178 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4179 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4180 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4181 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4182 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4183 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4184 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4185
4186 #if DPDK > 0
4187 #define foreach_vpe_dpdk_api_reply_msg                                  \
4188 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
4189   sw_interface_set_dpdk_hqos_pipe_reply)                                \
4190 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
4191   sw_interface_set_dpdk_hqos_subport_reply)                             \
4192 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
4193   sw_interface_set_dpdk_hqos_tctbl_reply)
4194 #endif
4195
4196 typedef struct
4197 {
4198   u8 *name;
4199   u32 value;
4200 } name_sort_t;
4201
4202
4203 #define STR_VTR_OP_CASE(op)     \
4204     case L2_VTR_ ## op:         \
4205         return "" # op;
4206
4207 static const char *
4208 str_vtr_op (u32 vtr_op)
4209 {
4210   switch (vtr_op)
4211     {
4212       STR_VTR_OP_CASE (DISABLED);
4213       STR_VTR_OP_CASE (PUSH_1);
4214       STR_VTR_OP_CASE (PUSH_2);
4215       STR_VTR_OP_CASE (POP_1);
4216       STR_VTR_OP_CASE (POP_2);
4217       STR_VTR_OP_CASE (TRANSLATE_1_1);
4218       STR_VTR_OP_CASE (TRANSLATE_1_2);
4219       STR_VTR_OP_CASE (TRANSLATE_2_1);
4220       STR_VTR_OP_CASE (TRANSLATE_2_2);
4221     }
4222
4223   return "UNKNOWN";
4224 }
4225
4226 static int
4227 dump_sub_interface_table (vat_main_t * vam)
4228 {
4229   const sw_interface_subif_t *sub = NULL;
4230
4231   if (vam->json_output)
4232     {
4233       clib_warning
4234         ("JSON output supported only for VPE API calls and dump_stats_table");
4235       return -99;
4236     }
4237
4238   print (vam->ofp,
4239          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4240          "Interface", "sw_if_index",
4241          "sub id", "dot1ad", "tags", "outer id",
4242          "inner id", "exact", "default", "outer any", "inner any");
4243
4244   vec_foreach (sub, vam->sw_if_subif_table)
4245   {
4246     print (vam->ofp,
4247            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4248            sub->interface_name,
4249            sub->sw_if_index,
4250            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4251            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4252            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4253            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4254     if (sub->vtr_op != L2_VTR_DISABLED)
4255       {
4256         print (vam->ofp,
4257                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4258                "tag1: %d tag2: %d ]",
4259                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4260                sub->vtr_tag1, sub->vtr_tag2);
4261       }
4262   }
4263
4264   return 0;
4265 }
4266
4267 static int
4268 name_sort_cmp (void *a1, void *a2)
4269 {
4270   name_sort_t *n1 = a1;
4271   name_sort_t *n2 = a2;
4272
4273   return strcmp ((char *) n1->name, (char *) n2->name);
4274 }
4275
4276 static int
4277 dump_interface_table (vat_main_t * vam)
4278 {
4279   hash_pair_t *p;
4280   name_sort_t *nses = 0, *ns;
4281
4282   if (vam->json_output)
4283     {
4284       clib_warning
4285         ("JSON output supported only for VPE API calls and dump_stats_table");
4286       return -99;
4287     }
4288
4289   /* *INDENT-OFF* */
4290   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4291   ({
4292     vec_add2 (nses, ns, 1);
4293     ns->name = (u8 *)(p->key);
4294     ns->value = (u32) p->value[0];
4295   }));
4296   /* *INDENT-ON* */
4297
4298   vec_sort_with_function (nses, name_sort_cmp);
4299
4300   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4301   vec_foreach (ns, nses)
4302   {
4303     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4304   }
4305   vec_free (nses);
4306   return 0;
4307 }
4308
4309 static int
4310 dump_ip_table (vat_main_t * vam, int is_ipv6)
4311 {
4312   const ip_details_t *det = NULL;
4313   const ip_address_details_t *address = NULL;
4314   u32 i = ~0;
4315
4316   print (vam->ofp, "%-12s", "sw_if_index");
4317
4318   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4319   {
4320     i++;
4321     if (!det->present)
4322       {
4323         continue;
4324       }
4325     print (vam->ofp, "%-12d", i);
4326     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4327     if (!det->addr)
4328       {
4329         continue;
4330       }
4331     vec_foreach (address, det->addr)
4332     {
4333       print (vam->ofp,
4334              "            %-30U%-13d",
4335              is_ipv6 ? format_ip6_address : format_ip4_address,
4336              address->ip, address->prefix_length);
4337     }
4338   }
4339
4340   return 0;
4341 }
4342
4343 static int
4344 dump_ipv4_table (vat_main_t * vam)
4345 {
4346   if (vam->json_output)
4347     {
4348       clib_warning
4349         ("JSON output supported only for VPE API calls and dump_stats_table");
4350       return -99;
4351     }
4352
4353   return dump_ip_table (vam, 0);
4354 }
4355
4356 static int
4357 dump_ipv6_table (vat_main_t * vam)
4358 {
4359   if (vam->json_output)
4360     {
4361       clib_warning
4362         ("JSON output supported only for VPE API calls and dump_stats_table");
4363       return -99;
4364     }
4365
4366   return dump_ip_table (vam, 1);
4367 }
4368
4369 static char *
4370 counter_type_to_str (u8 counter_type, u8 is_combined)
4371 {
4372   if (!is_combined)
4373     {
4374       switch (counter_type)
4375         {
4376         case VNET_INTERFACE_COUNTER_DROP:
4377           return "drop";
4378         case VNET_INTERFACE_COUNTER_PUNT:
4379           return "punt";
4380         case VNET_INTERFACE_COUNTER_IP4:
4381           return "ip4";
4382         case VNET_INTERFACE_COUNTER_IP6:
4383           return "ip6";
4384         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4385           return "rx-no-buf";
4386         case VNET_INTERFACE_COUNTER_RX_MISS:
4387           return "rx-miss";
4388         case VNET_INTERFACE_COUNTER_RX_ERROR:
4389           return "rx-error";
4390         case VNET_INTERFACE_COUNTER_TX_ERROR:
4391           return "tx-error";
4392         default:
4393           return "INVALID-COUNTER-TYPE";
4394         }
4395     }
4396   else
4397     {
4398       switch (counter_type)
4399         {
4400         case VNET_INTERFACE_COUNTER_RX:
4401           return "rx";
4402         case VNET_INTERFACE_COUNTER_TX:
4403           return "tx";
4404         default:
4405           return "INVALID-COUNTER-TYPE";
4406         }
4407     }
4408 }
4409
4410 static int
4411 dump_stats_table (vat_main_t * vam)
4412 {
4413   vat_json_node_t node;
4414   vat_json_node_t *msg_array;
4415   vat_json_node_t *msg;
4416   vat_json_node_t *counter_array;
4417   vat_json_node_t *counter;
4418   interface_counter_t c;
4419   u64 packets;
4420   ip4_fib_counter_t *c4;
4421   ip6_fib_counter_t *c6;
4422   ip4_nbr_counter_t *n4;
4423   ip6_nbr_counter_t *n6;
4424   int i, j;
4425
4426   if (!vam->json_output)
4427     {
4428       clib_warning ("dump_stats_table supported only in JSON format");
4429       return -99;
4430     }
4431
4432   vat_json_init_object (&node);
4433
4434   /* interface counters */
4435   msg_array = vat_json_object_add (&node, "interface_counters");
4436   vat_json_init_array (msg_array);
4437   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4438     {
4439       msg = vat_json_array_add (msg_array);
4440       vat_json_init_object (msg);
4441       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4442                                        (u8 *) counter_type_to_str (i, 0));
4443       vat_json_object_add_int (msg, "is_combined", 0);
4444       counter_array = vat_json_object_add (msg, "data");
4445       vat_json_init_array (counter_array);
4446       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4447         {
4448           packets = vam->simple_interface_counters[i][j];
4449           vat_json_array_add_uint (counter_array, packets);
4450         }
4451     }
4452   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4453     {
4454       msg = vat_json_array_add (msg_array);
4455       vat_json_init_object (msg);
4456       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4457                                        (u8 *) counter_type_to_str (i, 1));
4458       vat_json_object_add_int (msg, "is_combined", 1);
4459       counter_array = vat_json_object_add (msg, "data");
4460       vat_json_init_array (counter_array);
4461       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4462         {
4463           c = vam->combined_interface_counters[i][j];
4464           counter = vat_json_array_add (counter_array);
4465           vat_json_init_object (counter);
4466           vat_json_object_add_uint (counter, "packets", c.packets);
4467           vat_json_object_add_uint (counter, "bytes", c.bytes);
4468         }
4469     }
4470
4471   /* ip4 fib counters */
4472   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4473   vat_json_init_array (msg_array);
4474   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4475     {
4476       msg = vat_json_array_add (msg_array);
4477       vat_json_init_object (msg);
4478       vat_json_object_add_uint (msg, "vrf_id",
4479                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4480       counter_array = vat_json_object_add (msg, "c");
4481       vat_json_init_array (counter_array);
4482       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4483         {
4484           counter = vat_json_array_add (counter_array);
4485           vat_json_init_object (counter);
4486           c4 = &vam->ip4_fib_counters[i][j];
4487           vat_json_object_add_ip4 (counter, "address", c4->address);
4488           vat_json_object_add_uint (counter, "address_length",
4489                                     c4->address_length);
4490           vat_json_object_add_uint (counter, "packets", c4->packets);
4491           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4492         }
4493     }
4494
4495   /* ip6 fib counters */
4496   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4497   vat_json_init_array (msg_array);
4498   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4499     {
4500       msg = vat_json_array_add (msg_array);
4501       vat_json_init_object (msg);
4502       vat_json_object_add_uint (msg, "vrf_id",
4503                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4504       counter_array = vat_json_object_add (msg, "c");
4505       vat_json_init_array (counter_array);
4506       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4507         {
4508           counter = vat_json_array_add (counter_array);
4509           vat_json_init_object (counter);
4510           c6 = &vam->ip6_fib_counters[i][j];
4511           vat_json_object_add_ip6 (counter, "address", c6->address);
4512           vat_json_object_add_uint (counter, "address_length",
4513                                     c6->address_length);
4514           vat_json_object_add_uint (counter, "packets", c6->packets);
4515           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4516         }
4517     }
4518
4519   /* ip4 nbr counters */
4520   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4521   vat_json_init_array (msg_array);
4522   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4523     {
4524       msg = vat_json_array_add (msg_array);
4525       vat_json_init_object (msg);
4526       vat_json_object_add_uint (msg, "sw_if_index", i);
4527       counter_array = vat_json_object_add (msg, "c");
4528       vat_json_init_array (counter_array);
4529       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4530         {
4531           counter = vat_json_array_add (counter_array);
4532           vat_json_init_object (counter);
4533           n4 = &vam->ip4_nbr_counters[i][j];
4534           vat_json_object_add_ip4 (counter, "address", n4->address);
4535           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4536           vat_json_object_add_uint (counter, "packets", n4->packets);
4537           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4538         }
4539     }
4540
4541   /* ip6 nbr counters */
4542   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4543   vat_json_init_array (msg_array);
4544   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4545     {
4546       msg = vat_json_array_add (msg_array);
4547       vat_json_init_object (msg);
4548       vat_json_object_add_uint (msg, "sw_if_index", i);
4549       counter_array = vat_json_object_add (msg, "c");
4550       vat_json_init_array (counter_array);
4551       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4552         {
4553           counter = vat_json_array_add (counter_array);
4554           vat_json_init_object (counter);
4555           n6 = &vam->ip6_nbr_counters[i][j];
4556           vat_json_object_add_ip6 (counter, "address", n6->address);
4557           vat_json_object_add_uint (counter, "packets", n6->packets);
4558           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4559         }
4560     }
4561
4562   vat_json_print (vam->ofp, &node);
4563   vat_json_free (&node);
4564
4565   return 0;
4566 }
4567
4568 int
4569 exec (vat_main_t * vam)
4570 {
4571   api_main_t *am = &api_main;
4572   vl_api_cli_request_t *mp;
4573   f64 timeout;
4574   void *oldheap;
4575   u8 *cmd = 0;
4576   unformat_input_t *i = vam->input;
4577
4578   if (vec_len (i->buffer) == 0)
4579     return -1;
4580
4581   if (vam->exec_mode == 0 && unformat (i, "mode"))
4582     {
4583       vam->exec_mode = 1;
4584       return 0;
4585     }
4586   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4587     {
4588       vam->exec_mode = 0;
4589       return 0;
4590     }
4591
4592
4593   M (CLI_REQUEST, mp);
4594
4595   /*
4596    * Copy cmd into shared memory.
4597    * In order for the CLI command to work, it
4598    * must be a vector ending in \n, not a C-string ending
4599    * in \n\0.
4600    */
4601   pthread_mutex_lock (&am->vlib_rp->mutex);
4602   oldheap = svm_push_data_heap (am->vlib_rp);
4603
4604   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4605   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4606
4607   svm_pop_heap (oldheap);
4608   pthread_mutex_unlock (&am->vlib_rp->mutex);
4609
4610   mp->cmd_in_shmem = (u64) cmd;
4611   S (mp);
4612   timeout = vat_time_now (vam) + 10.0;
4613
4614   while (vat_time_now (vam) < timeout)
4615     {
4616       if (vam->result_ready == 1)
4617         {
4618           u8 *free_me;
4619           if (vam->shmem_result != NULL)
4620             print (vam->ofp, "%s", vam->shmem_result);
4621           pthread_mutex_lock (&am->vlib_rp->mutex);
4622           oldheap = svm_push_data_heap (am->vlib_rp);
4623
4624           free_me = (u8 *) vam->shmem_result;
4625           vec_free (free_me);
4626
4627           svm_pop_heap (oldheap);
4628           pthread_mutex_unlock (&am->vlib_rp->mutex);
4629           return 0;
4630         }
4631     }
4632   return -99;
4633 }
4634
4635 /*
4636  * Future replacement of exec() that passes CLI buffers directly in
4637  * the API messages instead of an additional shared memory area.
4638  */
4639 static int
4640 exec_inband (vat_main_t * vam)
4641 {
4642   vl_api_cli_inband_t *mp;
4643   unformat_input_t *i = vam->input;
4644   int ret;
4645
4646   if (vec_len (i->buffer) == 0)
4647     return -1;
4648
4649   if (vam->exec_mode == 0 && unformat (i, "mode"))
4650     {
4651       vam->exec_mode = 1;
4652       return 0;
4653     }
4654   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4655     {
4656       vam->exec_mode = 0;
4657       return 0;
4658     }
4659
4660   /*
4661    * In order for the CLI command to work, it
4662    * must be a vector ending in \n, not a C-string ending
4663    * in \n\0.
4664    */
4665   u32 len = vec_len (vam->input->buffer);
4666   M2 (CLI_INBAND, mp, len);
4667   clib_memcpy (mp->cmd, vam->input->buffer, len);
4668   mp->length = htonl (len);
4669
4670   S (mp);
4671   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4672   return ret;
4673 }
4674
4675 static int
4676 api_create_loopback (vat_main_t * vam)
4677 {
4678   unformat_input_t *i = vam->input;
4679   vl_api_create_loopback_t *mp;
4680   u8 mac_address[6];
4681   u8 mac_set = 0;
4682   int ret;
4683
4684   memset (mac_address, 0, sizeof (mac_address));
4685
4686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4687     {
4688       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4689         mac_set = 1;
4690       else
4691         break;
4692     }
4693
4694   /* Construct the API message */
4695   M (CREATE_LOOPBACK, mp);
4696   if (mac_set)
4697     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4698
4699   S (mp);
4700   W (ret);
4701   return ret;
4702 }
4703
4704 static int
4705 api_delete_loopback (vat_main_t * vam)
4706 {
4707   unformat_input_t *i = vam->input;
4708   vl_api_delete_loopback_t *mp;
4709   u32 sw_if_index = ~0;
4710   int ret;
4711
4712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4713     {
4714       if (unformat (i, "sw_if_index %d", &sw_if_index))
4715         ;
4716       else
4717         break;
4718     }
4719
4720   if (sw_if_index == ~0)
4721     {
4722       errmsg ("missing sw_if_index");
4723       return -99;
4724     }
4725
4726   /* Construct the API message */
4727   M (DELETE_LOOPBACK, mp);
4728   mp->sw_if_index = ntohl (sw_if_index);
4729
4730   S (mp);
4731   W (ret);
4732   return ret;
4733 }
4734
4735 static int
4736 api_want_stats (vat_main_t * vam)
4737 {
4738   unformat_input_t *i = vam->input;
4739   vl_api_want_stats_t *mp;
4740   int enable = -1;
4741   int ret;
4742
4743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4744     {
4745       if (unformat (i, "enable"))
4746         enable = 1;
4747       else if (unformat (i, "disable"))
4748         enable = 0;
4749       else
4750         break;
4751     }
4752
4753   if (enable == -1)
4754     {
4755       errmsg ("missing enable|disable");
4756       return -99;
4757     }
4758
4759   M (WANT_STATS, mp);
4760   mp->enable_disable = enable;
4761
4762   S (mp);
4763   W (ret);
4764   return ret;
4765 }
4766
4767 static int
4768 api_want_interface_events (vat_main_t * vam)
4769 {
4770   unformat_input_t *i = vam->input;
4771   vl_api_want_interface_events_t *mp;
4772   int enable = -1;
4773   int ret;
4774
4775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4776     {
4777       if (unformat (i, "enable"))
4778         enable = 1;
4779       else if (unformat (i, "disable"))
4780         enable = 0;
4781       else
4782         break;
4783     }
4784
4785   if (enable == -1)
4786     {
4787       errmsg ("missing enable|disable");
4788       return -99;
4789     }
4790
4791   M (WANT_INTERFACE_EVENTS, mp);
4792   mp->enable_disable = enable;
4793
4794   vam->interface_event_display = enable;
4795
4796   S (mp);
4797   W (ret);
4798   return ret;
4799 }
4800
4801
4802 /* Note: non-static, called once to set up the initial intfc table */
4803 int
4804 api_sw_interface_dump (vat_main_t * vam)
4805 {
4806   vl_api_sw_interface_dump_t *mp;
4807   vl_api_control_ping_t *mp_ping;
4808   hash_pair_t *p;
4809   name_sort_t *nses = 0, *ns;
4810   sw_interface_subif_t *sub = NULL;
4811   int ret;
4812
4813   /* Toss the old name table */
4814   /* *INDENT-OFF* */
4815   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4816   ({
4817     vec_add2 (nses, ns, 1);
4818     ns->name = (u8 *)(p->key);
4819     ns->value = (u32) p->value[0];
4820   }));
4821   /* *INDENT-ON* */
4822
4823   hash_free (vam->sw_if_index_by_interface_name);
4824
4825   vec_foreach (ns, nses) vec_free (ns->name);
4826
4827   vec_free (nses);
4828
4829   vec_foreach (sub, vam->sw_if_subif_table)
4830   {
4831     vec_free (sub->interface_name);
4832   }
4833   vec_free (vam->sw_if_subif_table);
4834
4835   /* recreate the interface name hash table */
4836   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4837
4838   /* Get list of ethernets */
4839   M (SW_INTERFACE_DUMP, mp);
4840   mp->name_filter_valid = 1;
4841   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4842   S (mp);
4843
4844   /* and local / loopback interfaces */
4845   M (SW_INTERFACE_DUMP, mp);
4846   mp->name_filter_valid = 1;
4847   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4848   S (mp);
4849
4850   /* and packet-generator interfaces */
4851   M (SW_INTERFACE_DUMP, mp);
4852   mp->name_filter_valid = 1;
4853   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4854   S (mp);
4855
4856   /* and vxlan-gpe tunnel interfaces */
4857   M (SW_INTERFACE_DUMP, mp);
4858   mp->name_filter_valid = 1;
4859   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4860            sizeof (mp->name_filter) - 1);
4861   S (mp);
4862
4863   /* and vxlan tunnel interfaces */
4864   M (SW_INTERFACE_DUMP, mp);
4865   mp->name_filter_valid = 1;
4866   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4867   S (mp);
4868
4869   /* and host (af_packet) interfaces */
4870   M (SW_INTERFACE_DUMP, mp);
4871   mp->name_filter_valid = 1;
4872   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4873   S (mp);
4874
4875   /* and l2tpv3 tunnel interfaces */
4876   M (SW_INTERFACE_DUMP, mp);
4877   mp->name_filter_valid = 1;
4878   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4879            sizeof (mp->name_filter) - 1);
4880   S (mp);
4881
4882   /* and GRE tunnel interfaces */
4883   M (SW_INTERFACE_DUMP, mp);
4884   mp->name_filter_valid = 1;
4885   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4886   S (mp);
4887
4888   /* and LISP-GPE interfaces */
4889   M (SW_INTERFACE_DUMP, mp);
4890   mp->name_filter_valid = 1;
4891   strncpy ((char *) mp->name_filter, "lisp_gpe",
4892            sizeof (mp->name_filter) - 1);
4893   S (mp);
4894
4895   /* and IPSEC tunnel interfaces */
4896   M (SW_INTERFACE_DUMP, mp);
4897   mp->name_filter_valid = 1;
4898   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4899   S (mp);
4900
4901   /* Use a control ping for synchronization */
4902   M (CONTROL_PING, mp_ping);
4903   S (mp_ping);
4904
4905   W (ret);
4906   return ret;
4907 }
4908
4909 static int
4910 api_sw_interface_set_flags (vat_main_t * vam)
4911 {
4912   unformat_input_t *i = vam->input;
4913   vl_api_sw_interface_set_flags_t *mp;
4914   u32 sw_if_index;
4915   u8 sw_if_index_set = 0;
4916   u8 admin_up = 0, link_up = 0;
4917   int ret;
4918
4919   /* Parse args required to build the message */
4920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4921     {
4922       if (unformat (i, "admin-up"))
4923         admin_up = 1;
4924       else if (unformat (i, "admin-down"))
4925         admin_up = 0;
4926       else if (unformat (i, "link-up"))
4927         link_up = 1;
4928       else if (unformat (i, "link-down"))
4929         link_up = 0;
4930       else
4931         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4932         sw_if_index_set = 1;
4933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4934         sw_if_index_set = 1;
4935       else
4936         break;
4937     }
4938
4939   if (sw_if_index_set == 0)
4940     {
4941       errmsg ("missing interface name or sw_if_index");
4942       return -99;
4943     }
4944
4945   /* Construct the API message */
4946   M (SW_INTERFACE_SET_FLAGS, mp);
4947   mp->sw_if_index = ntohl (sw_if_index);
4948   mp->admin_up_down = admin_up;
4949   mp->link_up_down = link_up;
4950
4951   /* send it... */
4952   S (mp);
4953
4954   /* Wait for a reply, return the good/bad news... */
4955   W (ret);
4956   return ret;
4957 }
4958
4959 static int
4960 api_sw_interface_clear_stats (vat_main_t * vam)
4961 {
4962   unformat_input_t *i = vam->input;
4963   vl_api_sw_interface_clear_stats_t *mp;
4964   u32 sw_if_index;
4965   u8 sw_if_index_set = 0;
4966   int ret;
4967
4968   /* Parse args required to build the message */
4969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4970     {
4971       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4972         sw_if_index_set = 1;
4973       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4974         sw_if_index_set = 1;
4975       else
4976         break;
4977     }
4978
4979   /* Construct the API message */
4980   M (SW_INTERFACE_CLEAR_STATS, mp);
4981
4982   if (sw_if_index_set == 1)
4983     mp->sw_if_index = ntohl (sw_if_index);
4984   else
4985     mp->sw_if_index = ~0;
4986
4987   /* send it... */
4988   S (mp);
4989
4990   /* Wait for a reply, return the good/bad news... */
4991   W (ret);
4992   return ret;
4993 }
4994
4995 #if DPDK >0
4996 static int
4997 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4998 {
4999   unformat_input_t *i = vam->input;
5000   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
5001   u32 sw_if_index;
5002   u8 sw_if_index_set = 0;
5003   u32 subport;
5004   u8 subport_set = 0;
5005   u32 pipe;
5006   u8 pipe_set = 0;
5007   u32 profile;
5008   u8 profile_set = 0;
5009   int ret;
5010
5011   /* Parse args required to build the message */
5012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5013     {
5014       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5015         sw_if_index_set = 1;
5016       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5017         sw_if_index_set = 1;
5018       else if (unformat (i, "subport %u", &subport))
5019         subport_set = 1;
5020       else
5021         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5022         sw_if_index_set = 1;
5023       else if (unformat (i, "pipe %u", &pipe))
5024         pipe_set = 1;
5025       else if (unformat (i, "profile %u", &profile))
5026         profile_set = 1;
5027       else
5028         break;
5029     }
5030
5031   if (sw_if_index_set == 0)
5032     {
5033       errmsg ("missing interface name or sw_if_index");
5034       return -99;
5035     }
5036
5037   if (subport_set == 0)
5038     {
5039       errmsg ("missing subport ");
5040       return -99;
5041     }
5042
5043   if (pipe_set == 0)
5044     {
5045       errmsg ("missing pipe");
5046       return -99;
5047     }
5048
5049   if (profile_set == 0)
5050     {
5051       errmsg ("missing profile");
5052       return -99;
5053     }
5054
5055   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, mp);
5056
5057   mp->sw_if_index = ntohl (sw_if_index);
5058   mp->subport = ntohl (subport);
5059   mp->pipe = ntohl (pipe);
5060   mp->profile = ntohl (profile);
5061
5062
5063   S (mp);
5064   W (ret);
5065   return ret;
5066 }
5067
5068 static int
5069 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
5070 {
5071   unformat_input_t *i = vam->input;
5072   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
5073   u32 sw_if_index;
5074   u8 sw_if_index_set = 0;
5075   u32 subport;
5076   u8 subport_set = 0;
5077   u32 tb_rate = 1250000000;     /* 10GbE */
5078   u32 tb_size = 1000000;
5079   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
5080   u32 tc_period = 10;
5081   int ret;
5082
5083   /* Parse args required to build the message */
5084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5085     {
5086       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5087         sw_if_index_set = 1;
5088       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5089         sw_if_index_set = 1;
5090       else if (unformat (i, "subport %u", &subport))
5091         subport_set = 1;
5092       else
5093         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5094         sw_if_index_set = 1;
5095       else if (unformat (i, "rate %u", &tb_rate))
5096         {
5097           u32 tc_id;
5098
5099           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
5100                tc_id++)
5101             tc_rate[tc_id] = tb_rate;
5102         }
5103       else if (unformat (i, "bktsize %u", &tb_size))
5104         ;
5105       else if (unformat (i, "tc0 %u", &tc_rate[0]))
5106         ;
5107       else if (unformat (i, "tc1 %u", &tc_rate[1]))
5108         ;
5109       else if (unformat (i, "tc2 %u", &tc_rate[2]))
5110         ;
5111       else if (unformat (i, "tc3 %u", &tc_rate[3]))
5112         ;
5113       else if (unformat (i, "period %u", &tc_period))
5114         ;
5115       else
5116         break;
5117     }
5118
5119   if (sw_if_index_set == 0)
5120     {
5121       errmsg ("missing interface name or sw_if_index");
5122       return -99;
5123     }
5124
5125   if (subport_set == 0)
5126     {
5127       errmsg ("missing subport ");
5128       return -99;
5129     }
5130
5131   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, mp);
5132
5133   mp->sw_if_index = ntohl (sw_if_index);
5134   mp->subport = ntohl (subport);
5135   mp->tb_rate = ntohl (tb_rate);
5136   mp->tb_size = ntohl (tb_size);
5137   mp->tc_rate[0] = ntohl (tc_rate[0]);
5138   mp->tc_rate[1] = ntohl (tc_rate[1]);
5139   mp->tc_rate[2] = ntohl (tc_rate[2]);
5140   mp->tc_rate[3] = ntohl (tc_rate[3]);
5141   mp->tc_period = ntohl (tc_period);
5142
5143   S (mp);
5144   W (ret);
5145   return ret;
5146 }
5147
5148 static int
5149 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
5150 {
5151   unformat_input_t *i = vam->input;
5152   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
5153   u32 sw_if_index;
5154   u8 sw_if_index_set = 0;
5155   u8 entry_set = 0;
5156   u8 tc_set = 0;
5157   u8 queue_set = 0;
5158   u32 entry, tc, queue;
5159   int ret;
5160
5161   /* Parse args required to build the message */
5162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5163     {
5164       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5165         sw_if_index_set = 1;
5166       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5167         sw_if_index_set = 1;
5168       else if (unformat (i, "entry %d", &entry))
5169         entry_set = 1;
5170       else if (unformat (i, "tc %d", &tc))
5171         tc_set = 1;
5172       else if (unformat (i, "queue %d", &queue))
5173         queue_set = 1;
5174       else
5175         break;
5176     }
5177
5178   if (sw_if_index_set == 0)
5179     {
5180       errmsg ("missing interface name or sw_if_index");
5181       return -99;
5182     }
5183
5184   if (entry_set == 0)
5185     {
5186       errmsg ("missing entry ");
5187       return -99;
5188     }
5189
5190   if (tc_set == 0)
5191     {
5192       errmsg ("missing traffic class ");
5193       return -99;
5194     }
5195
5196   if (queue_set == 0)
5197     {
5198       errmsg ("missing queue ");
5199       return -99;
5200     }
5201
5202   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, mp);
5203
5204   mp->sw_if_index = ntohl (sw_if_index);
5205   mp->entry = ntohl (entry);
5206   mp->tc = ntohl (tc);
5207   mp->queue = ntohl (queue);
5208
5209   S (mp);
5210   W (ret);
5211   return ret;
5212 }
5213 #endif
5214
5215 static int
5216 api_sw_interface_add_del_address (vat_main_t * vam)
5217 {
5218   unformat_input_t *i = vam->input;
5219   vl_api_sw_interface_add_del_address_t *mp;
5220   u32 sw_if_index;
5221   u8 sw_if_index_set = 0;
5222   u8 is_add = 1, del_all = 0;
5223   u32 address_length = 0;
5224   u8 v4_address_set = 0;
5225   u8 v6_address_set = 0;
5226   ip4_address_t v4address;
5227   ip6_address_t v6address;
5228   int ret;
5229
5230   /* Parse args required to build the message */
5231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5232     {
5233       if (unformat (i, "del-all"))
5234         del_all = 1;
5235       else if (unformat (i, "del"))
5236         is_add = 0;
5237       else
5238         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5239         sw_if_index_set = 1;
5240       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5241         sw_if_index_set = 1;
5242       else if (unformat (i, "%U/%d",
5243                          unformat_ip4_address, &v4address, &address_length))
5244         v4_address_set = 1;
5245       else if (unformat (i, "%U/%d",
5246                          unformat_ip6_address, &v6address, &address_length))
5247         v6_address_set = 1;
5248       else
5249         break;
5250     }
5251
5252   if (sw_if_index_set == 0)
5253     {
5254       errmsg ("missing interface name or sw_if_index");
5255       return -99;
5256     }
5257   if (v4_address_set && v6_address_set)
5258     {
5259       errmsg ("both v4 and v6 addresses set");
5260       return -99;
5261     }
5262   if (!v4_address_set && !v6_address_set && !del_all)
5263     {
5264       errmsg ("no addresses set");
5265       return -99;
5266     }
5267
5268   /* Construct the API message */
5269   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5270
5271   mp->sw_if_index = ntohl (sw_if_index);
5272   mp->is_add = is_add;
5273   mp->del_all = del_all;
5274   if (v6_address_set)
5275     {
5276       mp->is_ipv6 = 1;
5277       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5278     }
5279   else
5280     {
5281       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5282     }
5283   mp->address_length = address_length;
5284
5285   /* send it... */
5286   S (mp);
5287
5288   /* Wait for a reply, return good/bad news  */
5289   W (ret);
5290   return ret;
5291 }
5292
5293 static int
5294 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5295 {
5296   unformat_input_t *i = vam->input;
5297   vl_api_sw_interface_set_mpls_enable_t *mp;
5298   u32 sw_if_index;
5299   u8 sw_if_index_set = 0;
5300   u8 enable = 1;
5301   int ret;
5302
5303   /* Parse args required to build the message */
5304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5305     {
5306       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5307         sw_if_index_set = 1;
5308       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5309         sw_if_index_set = 1;
5310       else if (unformat (i, "disable"))
5311         enable = 0;
5312       else if (unformat (i, "dis"))
5313         enable = 0;
5314       else
5315         break;
5316     }
5317
5318   if (sw_if_index_set == 0)
5319     {
5320       errmsg ("missing interface name or sw_if_index");
5321       return -99;
5322     }
5323
5324   /* Construct the API message */
5325   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5326
5327   mp->sw_if_index = ntohl (sw_if_index);
5328   mp->enable = enable;
5329
5330   /* send it... */
5331   S (mp);
5332
5333   /* Wait for a reply... */
5334   W (ret);
5335   return ret;
5336 }
5337
5338 static int
5339 api_sw_interface_set_table (vat_main_t * vam)
5340 {
5341   unformat_input_t *i = vam->input;
5342   vl_api_sw_interface_set_table_t *mp;
5343   u32 sw_if_index, vrf_id = 0;
5344   u8 sw_if_index_set = 0;
5345   u8 is_ipv6 = 0;
5346   int ret;
5347
5348   /* Parse args required to build the message */
5349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5350     {
5351       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5352         sw_if_index_set = 1;
5353       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5354         sw_if_index_set = 1;
5355       else if (unformat (i, "vrf %d", &vrf_id))
5356         ;
5357       else if (unformat (i, "ipv6"))
5358         is_ipv6 = 1;
5359       else
5360         break;
5361     }
5362
5363   if (sw_if_index_set == 0)
5364     {
5365       errmsg ("missing interface name or sw_if_index");
5366       return -99;
5367     }
5368
5369   /* Construct the API message */
5370   M (SW_INTERFACE_SET_TABLE, mp);
5371
5372   mp->sw_if_index = ntohl (sw_if_index);
5373   mp->is_ipv6 = is_ipv6;
5374   mp->vrf_id = ntohl (vrf_id);
5375
5376   /* send it... */
5377   S (mp);
5378
5379   /* Wait for a reply... */
5380   W (ret);
5381   return ret;
5382 }
5383
5384 static void vl_api_sw_interface_get_table_reply_t_handler
5385   (vl_api_sw_interface_get_table_reply_t * mp)
5386 {
5387   vat_main_t *vam = &vat_main;
5388
5389   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5390
5391   vam->retval = ntohl (mp->retval);
5392   vam->result_ready = 1;
5393
5394 }
5395
5396 static void vl_api_sw_interface_get_table_reply_t_handler_json
5397   (vl_api_sw_interface_get_table_reply_t * mp)
5398 {
5399   vat_main_t *vam = &vat_main;
5400   vat_json_node_t node;
5401
5402   vat_json_init_object (&node);
5403   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5404   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5405
5406   vat_json_print (vam->ofp, &node);
5407   vat_json_free (&node);
5408
5409   vam->retval = ntohl (mp->retval);
5410   vam->result_ready = 1;
5411 }
5412
5413 static int
5414 api_sw_interface_get_table (vat_main_t * vam)
5415 {
5416   unformat_input_t *i = vam->input;
5417   vl_api_sw_interface_get_table_t *mp;
5418   u32 sw_if_index;
5419   u8 sw_if_index_set = 0;
5420   u8 is_ipv6 = 0;
5421   int ret;
5422
5423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5424     {
5425       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5426         sw_if_index_set = 1;
5427       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5428         sw_if_index_set = 1;
5429       else if (unformat (i, "ipv6"))
5430         is_ipv6 = 1;
5431       else
5432         break;
5433     }
5434
5435   if (sw_if_index_set == 0)
5436     {
5437       errmsg ("missing interface name or sw_if_index");
5438       return -99;
5439     }
5440
5441   M (SW_INTERFACE_GET_TABLE, mp);
5442   mp->sw_if_index = htonl (sw_if_index);
5443   mp->is_ipv6 = is_ipv6;
5444
5445   S (mp);
5446   W (ret);
5447   return ret;
5448 }
5449
5450 static int
5451 api_sw_interface_set_vpath (vat_main_t * vam)
5452 {
5453   unformat_input_t *i = vam->input;
5454   vl_api_sw_interface_set_vpath_t *mp;
5455   u32 sw_if_index = 0;
5456   u8 sw_if_index_set = 0;
5457   u8 is_enable = 0;
5458   int ret;
5459
5460   /* Parse args required to build the message */
5461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5462     {
5463       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5464         sw_if_index_set = 1;
5465       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5466         sw_if_index_set = 1;
5467       else if (unformat (i, "enable"))
5468         is_enable = 1;
5469       else if (unformat (i, "disable"))
5470         is_enable = 0;
5471       else
5472         break;
5473     }
5474
5475   if (sw_if_index_set == 0)
5476     {
5477       errmsg ("missing interface name or sw_if_index");
5478       return -99;
5479     }
5480
5481   /* Construct the API message */
5482   M (SW_INTERFACE_SET_VPATH, mp);
5483
5484   mp->sw_if_index = ntohl (sw_if_index);
5485   mp->enable = is_enable;
5486
5487   /* send it... */
5488   S (mp);
5489
5490   /* Wait for a reply... */
5491   W (ret);
5492   return ret;
5493 }
5494
5495 static int
5496 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5497 {
5498   unformat_input_t *i = vam->input;
5499   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5500   u32 sw_if_index = 0;
5501   u8 sw_if_index_set = 0;
5502   u8 is_enable = 1;
5503   u8 is_ipv6 = 0;
5504   int ret;
5505
5506   /* Parse args required to build the message */
5507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5508     {
5509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5510         sw_if_index_set = 1;
5511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5512         sw_if_index_set = 1;
5513       else if (unformat (i, "enable"))
5514         is_enable = 1;
5515       else if (unformat (i, "disable"))
5516         is_enable = 0;
5517       else if (unformat (i, "ip4"))
5518         is_ipv6 = 0;
5519       else if (unformat (i, "ip6"))
5520         is_ipv6 = 1;
5521       else
5522         break;
5523     }
5524
5525   if (sw_if_index_set == 0)
5526     {
5527       errmsg ("missing interface name or sw_if_index");
5528       return -99;
5529     }
5530
5531   /* Construct the API message */
5532   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5533
5534   mp->sw_if_index = ntohl (sw_if_index);
5535   mp->enable = is_enable;
5536   mp->is_ipv6 = is_ipv6;
5537
5538   /* send it... */
5539   S (mp);
5540
5541   /* Wait for a reply... */
5542   W (ret);
5543   return ret;
5544 }
5545
5546 static int
5547 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5548 {
5549   unformat_input_t *i = vam->input;
5550   vl_api_sw_interface_set_l2_xconnect_t *mp;
5551   u32 rx_sw_if_index;
5552   u8 rx_sw_if_index_set = 0;
5553   u32 tx_sw_if_index;
5554   u8 tx_sw_if_index_set = 0;
5555   u8 enable = 1;
5556   int ret;
5557
5558   /* Parse args required to build the message */
5559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5560     {
5561       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5562         rx_sw_if_index_set = 1;
5563       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5564         tx_sw_if_index_set = 1;
5565       else if (unformat (i, "rx"))
5566         {
5567           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5568             {
5569               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5570                             &rx_sw_if_index))
5571                 rx_sw_if_index_set = 1;
5572             }
5573           else
5574             break;
5575         }
5576       else if (unformat (i, "tx"))
5577         {
5578           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5579             {
5580               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5581                             &tx_sw_if_index))
5582                 tx_sw_if_index_set = 1;
5583             }
5584           else
5585             break;
5586         }
5587       else if (unformat (i, "enable"))
5588         enable = 1;
5589       else if (unformat (i, "disable"))
5590         enable = 0;
5591       else
5592         break;
5593     }
5594
5595   if (rx_sw_if_index_set == 0)
5596     {
5597       errmsg ("missing rx interface name or rx_sw_if_index");
5598       return -99;
5599     }
5600
5601   if (enable && (tx_sw_if_index_set == 0))
5602     {
5603       errmsg ("missing tx interface name or tx_sw_if_index");
5604       return -99;
5605     }
5606
5607   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5608
5609   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5610   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5611   mp->enable = enable;
5612
5613   S (mp);
5614   W (ret);
5615   return ret;
5616 }
5617
5618 static int
5619 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5620 {
5621   unformat_input_t *i = vam->input;
5622   vl_api_sw_interface_set_l2_bridge_t *mp;
5623   u32 rx_sw_if_index;
5624   u8 rx_sw_if_index_set = 0;
5625   u32 bd_id;
5626   u8 bd_id_set = 0;
5627   u8 bvi = 0;
5628   u32 shg = 0;
5629   u8 enable = 1;
5630   int ret;
5631
5632   /* Parse args required to build the message */
5633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5634     {
5635       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5636         rx_sw_if_index_set = 1;
5637       else if (unformat (i, "bd_id %d", &bd_id))
5638         bd_id_set = 1;
5639       else
5640         if (unformat
5641             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5642         rx_sw_if_index_set = 1;
5643       else if (unformat (i, "shg %d", &shg))
5644         ;
5645       else if (unformat (i, "bvi"))
5646         bvi = 1;
5647       else if (unformat (i, "enable"))
5648         enable = 1;
5649       else if (unformat (i, "disable"))
5650         enable = 0;
5651       else
5652         break;
5653     }
5654
5655   if (rx_sw_if_index_set == 0)
5656     {
5657       errmsg ("missing rx interface name or sw_if_index");
5658       return -99;
5659     }
5660
5661   if (enable && (bd_id_set == 0))
5662     {
5663       errmsg ("missing bridge domain");
5664       return -99;
5665     }
5666
5667   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5668
5669   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5670   mp->bd_id = ntohl (bd_id);
5671   mp->shg = (u8) shg;
5672   mp->bvi = bvi;
5673   mp->enable = enable;
5674
5675   S (mp);
5676   W (ret);
5677   return ret;
5678 }
5679
5680 static int
5681 api_bridge_domain_dump (vat_main_t * vam)
5682 {
5683   unformat_input_t *i = vam->input;
5684   vl_api_bridge_domain_dump_t *mp;
5685   vl_api_control_ping_t *mp_ping;
5686   u32 bd_id = ~0;
5687   int ret;
5688
5689   /* Parse args required to build the message */
5690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5691     {
5692       if (unformat (i, "bd_id %d", &bd_id))
5693         ;
5694       else
5695         break;
5696     }
5697
5698   M (BRIDGE_DOMAIN_DUMP, mp);
5699   mp->bd_id = ntohl (bd_id);
5700   S (mp);
5701
5702   /* Use a control ping for synchronization */
5703   M (CONTROL_PING, mp_ping);
5704   S (mp_ping);
5705
5706   W (ret);
5707   return ret;
5708 }
5709
5710 static int
5711 api_bridge_domain_add_del (vat_main_t * vam)
5712 {
5713   unformat_input_t *i = vam->input;
5714   vl_api_bridge_domain_add_del_t *mp;
5715   u32 bd_id = ~0;
5716   u8 is_add = 1;
5717   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5718   u32 mac_age = 0;
5719   int ret;
5720
5721   /* Parse args required to build the message */
5722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5723     {
5724       if (unformat (i, "bd_id %d", &bd_id))
5725         ;
5726       else if (unformat (i, "flood %d", &flood))
5727         ;
5728       else if (unformat (i, "uu-flood %d", &uu_flood))
5729         ;
5730       else if (unformat (i, "forward %d", &forward))
5731         ;
5732       else if (unformat (i, "learn %d", &learn))
5733         ;
5734       else if (unformat (i, "arp-term %d", &arp_term))
5735         ;
5736       else if (unformat (i, "mac-age %d", &mac_age))
5737         ;
5738       else if (unformat (i, "del"))
5739         {
5740           is_add = 0;
5741           flood = uu_flood = forward = learn = 0;
5742         }
5743       else
5744         break;
5745     }
5746
5747   if (bd_id == ~0)
5748     {
5749       errmsg ("missing bridge domain");
5750       return -99;
5751     }
5752
5753   if (mac_age > 255)
5754     {
5755       errmsg ("mac age must be less than 256 ");
5756       return -99;
5757     }
5758
5759   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5760
5761   mp->bd_id = ntohl (bd_id);
5762   mp->flood = flood;
5763   mp->uu_flood = uu_flood;
5764   mp->forward = forward;
5765   mp->learn = learn;
5766   mp->arp_term = arp_term;
5767   mp->is_add = is_add;
5768   mp->mac_age = (u8) mac_age;
5769
5770   S (mp);
5771   W (ret);
5772   return ret;
5773 }
5774
5775 static int
5776 api_l2fib_add_del (vat_main_t * vam)
5777 {
5778   unformat_input_t *i = vam->input;
5779   vl_api_l2fib_add_del_t *mp;
5780   f64 timeout;
5781   u64 mac = 0;
5782   u8 mac_set = 0;
5783   u32 bd_id;
5784   u8 bd_id_set = 0;
5785   u32 sw_if_index = ~0;
5786   u8 sw_if_index_set = 0;
5787   u8 is_add = 1;
5788   u8 static_mac = 0;
5789   u8 filter_mac = 0;
5790   u8 bvi_mac = 0;
5791   int count = 1;
5792   f64 before = 0;
5793   int j;
5794
5795   /* Parse args required to build the message */
5796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5797     {
5798       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5799         mac_set = 1;
5800       else if (unformat (i, "bd_id %d", &bd_id))
5801         bd_id_set = 1;
5802       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5803         sw_if_index_set = 1;
5804       else if (unformat (i, "sw_if"))
5805         {
5806           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5807             {
5808               if (unformat
5809                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5810                 sw_if_index_set = 1;
5811             }
5812           else
5813             break;
5814         }
5815       else if (unformat (i, "static"))
5816         static_mac = 1;
5817       else if (unformat (i, "filter"))
5818         {
5819           filter_mac = 1;
5820           static_mac = 1;
5821         }
5822       else if (unformat (i, "bvi"))
5823         {
5824           bvi_mac = 1;
5825           static_mac = 1;
5826         }
5827       else if (unformat (i, "del"))
5828         is_add = 0;
5829       else if (unformat (i, "count %d", &count))
5830         ;
5831       else
5832         break;
5833     }
5834
5835   if (mac_set == 0)
5836     {
5837       errmsg ("missing mac address");
5838       return -99;
5839     }
5840
5841   if (bd_id_set == 0)
5842     {
5843       errmsg ("missing bridge domain");
5844       return -99;
5845     }
5846
5847   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5848     {
5849       errmsg ("missing interface name or sw_if_index");
5850       return -99;
5851     }
5852
5853   if (count > 1)
5854     {
5855       /* Turn on async mode */
5856       vam->async_mode = 1;
5857       vam->async_errors = 0;
5858       before = vat_time_now (vam);
5859     }
5860
5861   for (j = 0; j < count; j++)
5862     {
5863       M (L2FIB_ADD_DEL, mp);
5864
5865       mp->mac = mac;
5866       mp->bd_id = ntohl (bd_id);
5867       mp->is_add = is_add;
5868
5869       if (is_add)
5870         {
5871           mp->sw_if_index = ntohl (sw_if_index);
5872           mp->static_mac = static_mac;
5873           mp->filter_mac = filter_mac;
5874           mp->bvi_mac = bvi_mac;
5875         }
5876       increment_mac_address (&mac);
5877       /* send it... */
5878       S (mp);
5879     }
5880
5881   if (count > 1)
5882     {
5883       vl_api_control_ping_t *mp_ping;
5884       f64 after;
5885
5886       /* Shut off async mode */
5887       vam->async_mode = 0;
5888
5889       M (CONTROL_PING, mp_ping);
5890       S (mp_ping);
5891
5892       timeout = vat_time_now (vam) + 1.0;
5893       while (vat_time_now (vam) < timeout)
5894         if (vam->result_ready == 1)
5895           goto out;
5896       vam->retval = -99;
5897
5898     out:
5899       if (vam->retval == -99)
5900         errmsg ("timeout");
5901
5902       if (vam->async_errors > 0)
5903         {
5904           errmsg ("%d asynchronous errors", vam->async_errors);
5905           vam->retval = -98;
5906         }
5907       vam->async_errors = 0;
5908       after = vat_time_now (vam);
5909
5910       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5911              count, after - before, count / (after - before));
5912     }
5913   else
5914     {
5915       int ret;
5916
5917       /* Wait for a reply... */
5918       W (ret);
5919       return ret;
5920     }
5921   /* Return the good/bad news */
5922   return (vam->retval);
5923 }
5924
5925 static int
5926 api_l2_flags (vat_main_t * vam)
5927 {
5928   unformat_input_t *i = vam->input;
5929   vl_api_l2_flags_t *mp;
5930   u32 sw_if_index;
5931   u32 feature_bitmap = 0;
5932   u8 sw_if_index_set = 0;
5933   int ret;
5934
5935   /* Parse args required to build the message */
5936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5937     {
5938       if (unformat (i, "sw_if_index %d", &sw_if_index))
5939         sw_if_index_set = 1;
5940       else if (unformat (i, "sw_if"))
5941         {
5942           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5943             {
5944               if (unformat
5945                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5946                 sw_if_index_set = 1;
5947             }
5948           else
5949             break;
5950         }
5951       else if (unformat (i, "learn"))
5952         feature_bitmap |= L2INPUT_FEAT_LEARN;
5953       else if (unformat (i, "forward"))
5954         feature_bitmap |= L2INPUT_FEAT_FWD;
5955       else if (unformat (i, "flood"))
5956         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5957       else if (unformat (i, "uu-flood"))
5958         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5959       else
5960         break;
5961     }
5962
5963   if (sw_if_index_set == 0)
5964     {
5965       errmsg ("missing interface name or sw_if_index");
5966       return -99;
5967     }
5968
5969   M (L2_FLAGS, mp);
5970
5971   mp->sw_if_index = ntohl (sw_if_index);
5972   mp->feature_bitmap = ntohl (feature_bitmap);
5973
5974   S (mp);
5975   W (ret);
5976   return ret;
5977 }
5978
5979 static int
5980 api_bridge_flags (vat_main_t * vam)
5981 {
5982   unformat_input_t *i = vam->input;
5983   vl_api_bridge_flags_t *mp;
5984   u32 bd_id;
5985   u8 bd_id_set = 0;
5986   u8 is_set = 1;
5987   u32 flags = 0;
5988   int ret;
5989
5990   /* Parse args required to build the message */
5991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5992     {
5993       if (unformat (i, "bd_id %d", &bd_id))
5994         bd_id_set = 1;
5995       else if (unformat (i, "learn"))
5996         flags |= L2_LEARN;
5997       else if (unformat (i, "forward"))
5998         flags |= L2_FWD;
5999       else if (unformat (i, "flood"))
6000         flags |= L2_FLOOD;
6001       else if (unformat (i, "uu-flood"))
6002         flags |= L2_UU_FLOOD;
6003       else if (unformat (i, "arp-term"))
6004         flags |= L2_ARP_TERM;
6005       else if (unformat (i, "off"))
6006         is_set = 0;
6007       else if (unformat (i, "disable"))
6008         is_set = 0;
6009       else
6010         break;
6011     }
6012
6013   if (bd_id_set == 0)
6014     {
6015       errmsg ("missing bridge domain");
6016       return -99;
6017     }
6018
6019   M (BRIDGE_FLAGS, mp);
6020
6021   mp->bd_id = ntohl (bd_id);
6022   mp->feature_bitmap = ntohl (flags);
6023   mp->is_set = is_set;
6024
6025   S (mp);
6026   W (ret);
6027   return ret;
6028 }
6029
6030 static int
6031 api_bd_ip_mac_add_del (vat_main_t * vam)
6032 {
6033   unformat_input_t *i = vam->input;
6034   vl_api_bd_ip_mac_add_del_t *mp;
6035   u32 bd_id;
6036   u8 is_ipv6 = 0;
6037   u8 is_add = 1;
6038   u8 bd_id_set = 0;
6039   u8 ip_set = 0;
6040   u8 mac_set = 0;
6041   ip4_address_t v4addr;
6042   ip6_address_t v6addr;
6043   u8 macaddr[6];
6044   int ret;
6045
6046
6047   /* Parse args required to build the message */
6048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6049     {
6050       if (unformat (i, "bd_id %d", &bd_id))
6051         {
6052           bd_id_set++;
6053         }
6054       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6055         {
6056           ip_set++;
6057         }
6058       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6059         {
6060           ip_set++;
6061           is_ipv6++;
6062         }
6063       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6064         {
6065           mac_set++;
6066         }
6067       else if (unformat (i, "del"))
6068         is_add = 0;
6069       else
6070         break;
6071     }
6072
6073   if (bd_id_set == 0)
6074     {
6075       errmsg ("missing bridge domain");
6076       return -99;
6077     }
6078   else if (ip_set == 0)
6079     {
6080       errmsg ("missing IP address");
6081       return -99;
6082     }
6083   else if (mac_set == 0)
6084     {
6085       errmsg ("missing MAC address");
6086       return -99;
6087     }
6088
6089   M (BD_IP_MAC_ADD_DEL, mp);
6090
6091   mp->bd_id = ntohl (bd_id);
6092   mp->is_ipv6 = is_ipv6;
6093   mp->is_add = is_add;
6094   if (is_ipv6)
6095     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6096   else
6097     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6098   clib_memcpy (mp->mac_address, macaddr, 6);
6099   S (mp);
6100   W (ret);
6101   return ret;
6102 }
6103
6104 static int
6105 api_tap_connect (vat_main_t * vam)
6106 {
6107   unformat_input_t *i = vam->input;
6108   vl_api_tap_connect_t *mp;
6109   u8 mac_address[6];
6110   u8 random_mac = 1;
6111   u8 name_set = 0;
6112   u8 *tap_name;
6113   u8 *tag = 0;
6114   ip4_address_t ip4_address;
6115   u32 ip4_mask_width;
6116   int ip4_address_set = 0;
6117   ip6_address_t ip6_address;
6118   u32 ip6_mask_width;
6119   int ip6_address_set = 0;
6120   int ret;
6121
6122   memset (mac_address, 0, sizeof (mac_address));
6123
6124   /* Parse args required to build the message */
6125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6126     {
6127       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6128         {
6129           random_mac = 0;
6130         }
6131       else if (unformat (i, "random-mac"))
6132         random_mac = 1;
6133       else if (unformat (i, "tapname %s", &tap_name))
6134         name_set = 1;
6135       else if (unformat (i, "tag %s", &tag))
6136         ;
6137       else if (unformat (i, "address %U/%d",
6138                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6139         ip4_address_set = 1;
6140       else if (unformat (i, "address %U/%d",
6141                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6142         ip6_address_set = 1;
6143       else
6144         break;
6145     }
6146
6147   if (name_set == 0)
6148     {
6149       errmsg ("missing tap name");
6150       return -99;
6151     }
6152   if (vec_len (tap_name) > 63)
6153     {
6154       errmsg ("tap name too long");
6155       return -99;
6156     }
6157   vec_add1 (tap_name, 0);
6158
6159   if (vec_len (tag) > 63)
6160     {
6161       errmsg ("tag too long");
6162       return -99;
6163     }
6164
6165   /* Construct the API message */
6166   M (TAP_CONNECT, mp);
6167
6168   mp->use_random_mac = random_mac;
6169   clib_memcpy (mp->mac_address, mac_address, 6);
6170   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6171   if (tag)
6172     clib_memcpy (mp->tag, tag, vec_len (tag));
6173
6174   if (ip4_address_set)
6175     {
6176       mp->ip4_address_set = 1;
6177       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6178       mp->ip4_mask_width = ip4_mask_width;
6179     }
6180   if (ip6_address_set)
6181     {
6182       mp->ip6_address_set = 1;
6183       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6184       mp->ip6_mask_width = ip6_mask_width;
6185     }
6186
6187   vec_free (tap_name);
6188   vec_free (tag);
6189
6190   /* send it... */
6191   S (mp);
6192
6193   /* Wait for a reply... */
6194   W (ret);
6195   return ret;
6196 }
6197
6198 static int
6199 api_tap_modify (vat_main_t * vam)
6200 {
6201   unformat_input_t *i = vam->input;
6202   vl_api_tap_modify_t *mp;
6203   u8 mac_address[6];
6204   u8 random_mac = 1;
6205   u8 name_set = 0;
6206   u8 *tap_name;
6207   u32 sw_if_index = ~0;
6208   u8 sw_if_index_set = 0;
6209   int ret;
6210
6211   memset (mac_address, 0, sizeof (mac_address));
6212
6213   /* Parse args required to build the message */
6214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6215     {
6216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6217         sw_if_index_set = 1;
6218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6219         sw_if_index_set = 1;
6220       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6221         {
6222           random_mac = 0;
6223         }
6224       else if (unformat (i, "random-mac"))
6225         random_mac = 1;
6226       else if (unformat (i, "tapname %s", &tap_name))
6227         name_set = 1;
6228       else
6229         break;
6230     }
6231
6232   if (sw_if_index_set == 0)
6233     {
6234       errmsg ("missing vpp interface name");
6235       return -99;
6236     }
6237   if (name_set == 0)
6238     {
6239       errmsg ("missing tap name");
6240       return -99;
6241     }
6242   if (vec_len (tap_name) > 63)
6243     {
6244       errmsg ("tap name too long");
6245     }
6246   vec_add1 (tap_name, 0);
6247
6248   /* Construct the API message */
6249   M (TAP_MODIFY, mp);
6250
6251   mp->use_random_mac = random_mac;
6252   mp->sw_if_index = ntohl (sw_if_index);
6253   clib_memcpy (mp->mac_address, mac_address, 6);
6254   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6255   vec_free (tap_name);
6256
6257   /* send it... */
6258   S (mp);
6259
6260   /* Wait for a reply... */
6261   W (ret);
6262   return ret;
6263 }
6264
6265 static int
6266 api_tap_delete (vat_main_t * vam)
6267 {
6268   unformat_input_t *i = vam->input;
6269   vl_api_tap_delete_t *mp;
6270   u32 sw_if_index = ~0;
6271   u8 sw_if_index_set = 0;
6272   int ret;
6273
6274   /* Parse args required to build the message */
6275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6276     {
6277       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6278         sw_if_index_set = 1;
6279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6280         sw_if_index_set = 1;
6281       else
6282         break;
6283     }
6284
6285   if (sw_if_index_set == 0)
6286     {
6287       errmsg ("missing vpp interface name");
6288       return -99;
6289     }
6290
6291   /* Construct the API message */
6292   M (TAP_DELETE, mp);
6293
6294   mp->sw_if_index = ntohl (sw_if_index);
6295
6296   /* send it... */
6297   S (mp);
6298
6299   /* Wait for a reply... */
6300   W (ret);
6301   return ret;
6302 }
6303
6304 static int
6305 api_ip_add_del_route (vat_main_t * vam)
6306 {
6307   unformat_input_t *i = vam->input;
6308   vl_api_ip_add_del_route_t *mp;
6309   u32 sw_if_index = ~0, vrf_id = 0;
6310   u8 is_ipv6 = 0;
6311   u8 is_local = 0, is_drop = 0;
6312   u8 is_unreach = 0, is_prohibit = 0;
6313   u8 create_vrf_if_needed = 0;
6314   u8 is_add = 1;
6315   u32 next_hop_weight = 1;
6316   u8 not_last = 0;
6317   u8 is_multipath = 0;
6318   u8 address_set = 0;
6319   u8 address_length_set = 0;
6320   u32 next_hop_table_id = 0;
6321   u32 resolve_attempts = 0;
6322   u32 dst_address_length = 0;
6323   u8 next_hop_set = 0;
6324   ip4_address_t v4_dst_address, v4_next_hop_address;
6325   ip6_address_t v6_dst_address, v6_next_hop_address;
6326   int count = 1;
6327   int j;
6328   f64 before = 0;
6329   u32 random_add_del = 0;
6330   u32 *random_vector = 0;
6331   uword *random_hash;
6332   u32 random_seed = 0xdeaddabe;
6333   u32 classify_table_index = ~0;
6334   u8 is_classify = 0;
6335   u8 resolve_host = 0, resolve_attached = 0;
6336   mpls_label_t *next_hop_out_label_stack = NULL;
6337   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6338   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6339
6340   /* Parse args required to build the message */
6341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6342     {
6343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6344         ;
6345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6346         ;
6347       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6348         {
6349           address_set = 1;
6350           is_ipv6 = 0;
6351         }
6352       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6353         {
6354           address_set = 1;
6355           is_ipv6 = 1;
6356         }
6357       else if (unformat (i, "/%d", &dst_address_length))
6358         {
6359           address_length_set = 1;
6360         }
6361
6362       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6363                                          &v4_next_hop_address))
6364         {
6365           next_hop_set = 1;
6366         }
6367       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6368                                          &v6_next_hop_address))
6369         {
6370           next_hop_set = 1;
6371         }
6372       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6373         ;
6374       else if (unformat (i, "weight %d", &next_hop_weight))
6375         ;
6376       else if (unformat (i, "drop"))
6377         {
6378           is_drop = 1;
6379         }
6380       else if (unformat (i, "null-send-unreach"))
6381         {
6382           is_unreach = 1;
6383         }
6384       else if (unformat (i, "null-send-prohibit"))
6385         {
6386           is_prohibit = 1;
6387         }
6388       else if (unformat (i, "local"))
6389         {
6390           is_local = 1;
6391         }
6392       else if (unformat (i, "classify %d", &classify_table_index))
6393         {
6394           is_classify = 1;
6395         }
6396       else if (unformat (i, "del"))
6397         is_add = 0;
6398       else if (unformat (i, "add"))
6399         is_add = 1;
6400       else if (unformat (i, "not-last"))
6401         not_last = 1;
6402       else if (unformat (i, "resolve-via-host"))
6403         resolve_host = 1;
6404       else if (unformat (i, "resolve-via-attached"))
6405         resolve_attached = 1;
6406       else if (unformat (i, "multipath"))
6407         is_multipath = 1;
6408       else if (unformat (i, "vrf %d", &vrf_id))
6409         ;
6410       else if (unformat (i, "create-vrf"))
6411         create_vrf_if_needed = 1;
6412       else if (unformat (i, "count %d", &count))
6413         ;
6414       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6415         ;
6416       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6417         ;
6418       else if (unformat (i, "out-label %d", &next_hop_out_label))
6419         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6420       else if (unformat (i, "via-label %d", &next_hop_via_label))
6421         ;
6422       else if (unformat (i, "random"))
6423         random_add_del = 1;
6424       else if (unformat (i, "seed %d", &random_seed))
6425         ;
6426       else
6427         {
6428           clib_warning ("parse error '%U'", format_unformat_error, i);
6429           return -99;
6430         }
6431     }
6432
6433   if (!next_hop_set && !is_drop && !is_local &&
6434       !is_classify && !is_unreach && !is_prohibit &&
6435       MPLS_LABEL_INVALID == next_hop_via_label)
6436     {
6437       errmsg
6438         ("next hop / local / drop / unreach / prohibit / classify not set");
6439       return -99;
6440     }
6441
6442   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6443     {
6444       errmsg ("next hop and next-hop via label set");
6445       return -99;
6446     }
6447   if (address_set == 0)
6448     {
6449       errmsg ("missing addresses");
6450       return -99;
6451     }
6452
6453   if (address_length_set == 0)
6454     {
6455       errmsg ("missing address length");
6456       return -99;
6457     }
6458
6459   /* Generate a pile of unique, random routes */
6460   if (random_add_del)
6461     {
6462       u32 this_random_address;
6463       random_hash = hash_create (count, sizeof (uword));
6464
6465       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6466       for (j = 0; j <= count; j++)
6467         {
6468           do
6469             {
6470               this_random_address = random_u32 (&random_seed);
6471               this_random_address =
6472                 clib_host_to_net_u32 (this_random_address);
6473             }
6474           while (hash_get (random_hash, this_random_address));
6475           vec_add1 (random_vector, this_random_address);
6476           hash_set (random_hash, this_random_address, 1);
6477         }
6478       hash_free (random_hash);
6479       v4_dst_address.as_u32 = random_vector[0];
6480     }
6481
6482   if (count > 1)
6483     {
6484       /* Turn on async mode */
6485       vam->async_mode = 1;
6486       vam->async_errors = 0;
6487       before = vat_time_now (vam);
6488     }
6489
6490   for (j = 0; j < count; j++)
6491     {
6492       /* Construct the API message */
6493       M2 (IP_ADD_DEL_ROUTE, mp,
6494           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6495
6496       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6497       mp->table_id = ntohl (vrf_id);
6498       mp->create_vrf_if_needed = create_vrf_if_needed;
6499
6500       mp->is_add = is_add;
6501       mp->is_drop = is_drop;
6502       mp->is_unreach = is_unreach;
6503       mp->is_prohibit = is_prohibit;
6504       mp->is_ipv6 = is_ipv6;
6505       mp->is_local = is_local;
6506       mp->is_classify = is_classify;
6507       mp->is_multipath = is_multipath;
6508       mp->is_resolve_host = resolve_host;
6509       mp->is_resolve_attached = resolve_attached;
6510       mp->not_last = not_last;
6511       mp->next_hop_weight = next_hop_weight;
6512       mp->dst_address_length = dst_address_length;
6513       mp->next_hop_table_id = ntohl (next_hop_table_id);
6514       mp->classify_table_index = ntohl (classify_table_index);
6515       mp->next_hop_via_label = ntohl (next_hop_via_label);
6516       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6517       if (0 != mp->next_hop_n_out_labels)
6518         {
6519           memcpy (mp->next_hop_out_label_stack,
6520                   next_hop_out_label_stack,
6521                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6522           vec_free (next_hop_out_label_stack);
6523         }
6524
6525       if (is_ipv6)
6526         {
6527           clib_memcpy (mp->dst_address, &v6_dst_address,
6528                        sizeof (v6_dst_address));
6529           if (next_hop_set)
6530             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6531                          sizeof (v6_next_hop_address));
6532           increment_v6_address (&v6_dst_address);
6533         }
6534       else
6535         {
6536           clib_memcpy (mp->dst_address, &v4_dst_address,
6537                        sizeof (v4_dst_address));
6538           if (next_hop_set)
6539             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6540                          sizeof (v4_next_hop_address));
6541           if (random_add_del)
6542             v4_dst_address.as_u32 = random_vector[j + 1];
6543           else
6544             increment_v4_address (&v4_dst_address);
6545         }
6546       /* send it... */
6547       S (mp);
6548       /* If we receive SIGTERM, stop now... */
6549       if (vam->do_exit)
6550         break;
6551     }
6552
6553   /* When testing multiple add/del ops, use a control-ping to sync */
6554   if (count > 1)
6555     {
6556       vl_api_control_ping_t *mp_ping;
6557       f64 after;
6558       f64 timeout;
6559
6560       /* Shut off async mode */
6561       vam->async_mode = 0;
6562
6563       M (CONTROL_PING, mp_ping);
6564       S (mp_ping);
6565
6566       timeout = vat_time_now (vam) + 1.0;
6567       while (vat_time_now (vam) < timeout)
6568         if (vam->result_ready == 1)
6569           goto out;
6570       vam->retval = -99;
6571
6572     out:
6573       if (vam->retval == -99)
6574         errmsg ("timeout");
6575
6576       if (vam->async_errors > 0)
6577         {
6578           errmsg ("%d asynchronous errors", vam->async_errors);
6579           vam->retval = -98;
6580         }
6581       vam->async_errors = 0;
6582       after = vat_time_now (vam);
6583
6584       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6585       if (j > 0)
6586         count = j;
6587
6588       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6589              count, after - before, count / (after - before));
6590     }
6591   else
6592     {
6593       int ret;
6594
6595       /* Wait for a reply... */
6596       W (ret);
6597       return ret;
6598     }
6599
6600   /* Return the good/bad news */
6601   return (vam->retval);
6602 }
6603
6604 static int
6605 api_ip_mroute_add_del (vat_main_t * vam)
6606 {
6607   unformat_input_t *i = vam->input;
6608   vl_api_ip_mroute_add_del_t *mp;
6609   u32 sw_if_index = ~0, vrf_id = 0;
6610   u8 is_ipv6 = 0;
6611   u8 is_local = 0;
6612   u8 create_vrf_if_needed = 0;
6613   u8 is_add = 1;
6614   u8 address_set = 0;
6615   u32 grp_address_length = 0;
6616   ip4_address_t v4_grp_address, v4_src_address;
6617   ip6_address_t v6_grp_address, v6_src_address;
6618   mfib_itf_flags_t iflags = 0;
6619   mfib_entry_flags_t eflags = 0;
6620   int ret;
6621
6622   /* Parse args required to build the message */
6623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6624     {
6625       if (unformat (i, "sw_if_index %d", &sw_if_index))
6626         ;
6627       else if (unformat (i, "%U %U",
6628                          unformat_ip4_address, &v4_src_address,
6629                          unformat_ip4_address, &v4_grp_address))
6630         {
6631           grp_address_length = 64;
6632           address_set = 1;
6633           is_ipv6 = 0;
6634         }
6635       else if (unformat (i, "%U %U",
6636                          unformat_ip6_address, &v6_src_address,
6637                          unformat_ip6_address, &v6_grp_address))
6638         {
6639           grp_address_length = 256;
6640           address_set = 1;
6641           is_ipv6 = 1;
6642         }
6643       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6644         {
6645           memset (&v4_src_address, 0, sizeof (v4_src_address));
6646           grp_address_length = 32;
6647           address_set = 1;
6648           is_ipv6 = 0;
6649         }
6650       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6651         {
6652           memset (&v6_src_address, 0, sizeof (v6_src_address));
6653           grp_address_length = 128;
6654           address_set = 1;
6655           is_ipv6 = 1;
6656         }
6657       else if (unformat (i, "/%d", &grp_address_length))
6658         ;
6659       else if (unformat (i, "local"))
6660         {
6661           is_local = 1;
6662         }
6663       else if (unformat (i, "del"))
6664         is_add = 0;
6665       else if (unformat (i, "add"))
6666         is_add = 1;
6667       else if (unformat (i, "vrf %d", &vrf_id))
6668         ;
6669       else if (unformat (i, "create-vrf"))
6670         create_vrf_if_needed = 1;
6671       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6672         ;
6673       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6674         ;
6675       else
6676         {
6677           clib_warning ("parse error '%U'", format_unformat_error, i);
6678           return -99;
6679         }
6680     }
6681
6682   if (address_set == 0)
6683     {
6684       errmsg ("missing addresses\n");
6685       return -99;
6686     }
6687
6688   /* Construct the API message */
6689   M (IP_MROUTE_ADD_DEL, mp);
6690
6691   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6692   mp->table_id = ntohl (vrf_id);
6693   mp->create_vrf_if_needed = create_vrf_if_needed;
6694
6695   mp->is_add = is_add;
6696   mp->is_ipv6 = is_ipv6;
6697   mp->is_local = is_local;
6698   mp->itf_flags = ntohl (iflags);
6699   mp->entry_flags = ntohl (eflags);
6700   mp->grp_address_length = grp_address_length;
6701   mp->grp_address_length = ntohs (mp->grp_address_length);
6702
6703   if (is_ipv6)
6704     {
6705       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6706       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6707     }
6708   else
6709     {
6710       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6711       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6712
6713     }
6714
6715   /* send it... */
6716   S (mp);
6717   /* Wait for a reply... */
6718   W (ret);
6719   return ret;
6720 }
6721
6722 static int
6723 api_mpls_route_add_del (vat_main_t * vam)
6724 {
6725   unformat_input_t *i = vam->input;
6726   vl_api_mpls_route_add_del_t *mp;
6727   u32 sw_if_index = ~0, table_id = 0;
6728   u8 create_table_if_needed = 0;
6729   u8 is_add = 1;
6730   u32 next_hop_weight = 1;
6731   u8 is_multipath = 0;
6732   u32 next_hop_table_id = 0;
6733   u8 next_hop_set = 0;
6734   ip4_address_t v4_next_hop_address = {
6735     .as_u32 = 0,
6736   };
6737   ip6_address_t v6_next_hop_address = { {0} };
6738   int count = 1;
6739   int j;
6740   f64 before = 0;
6741   u32 classify_table_index = ~0;
6742   u8 is_classify = 0;
6743   u8 resolve_host = 0, resolve_attached = 0;
6744   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6745   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6746   mpls_label_t *next_hop_out_label_stack = NULL;
6747   mpls_label_t local_label = MPLS_LABEL_INVALID;
6748   u8 is_eos = 0;
6749   u8 next_hop_proto_is_ip4 = 1;
6750
6751   /* Parse args required to build the message */
6752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6753     {
6754       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6755         ;
6756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6757         ;
6758       else if (unformat (i, "%d", &local_label))
6759         ;
6760       else if (unformat (i, "eos"))
6761         is_eos = 1;
6762       else if (unformat (i, "non-eos"))
6763         is_eos = 0;
6764       else if (unformat (i, "via %U", unformat_ip4_address,
6765                          &v4_next_hop_address))
6766         {
6767           next_hop_set = 1;
6768           next_hop_proto_is_ip4 = 1;
6769         }
6770       else if (unformat (i, "via %U", unformat_ip6_address,
6771                          &v6_next_hop_address))
6772         {
6773           next_hop_set = 1;
6774           next_hop_proto_is_ip4 = 0;
6775         }
6776       else if (unformat (i, "weight %d", &next_hop_weight))
6777         ;
6778       else if (unformat (i, "create-table"))
6779         create_table_if_needed = 1;
6780       else if (unformat (i, "classify %d", &classify_table_index))
6781         {
6782           is_classify = 1;
6783         }
6784       else if (unformat (i, "del"))
6785         is_add = 0;
6786       else if (unformat (i, "add"))
6787         is_add = 1;
6788       else if (unformat (i, "resolve-via-host"))
6789         resolve_host = 1;
6790       else if (unformat (i, "resolve-via-attached"))
6791         resolve_attached = 1;
6792       else if (unformat (i, "multipath"))
6793         is_multipath = 1;
6794       else if (unformat (i, "count %d", &count))
6795         ;
6796       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6797         {
6798           next_hop_set = 1;
6799           next_hop_proto_is_ip4 = 1;
6800         }
6801       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6802         {
6803           next_hop_set = 1;
6804           next_hop_proto_is_ip4 = 0;
6805         }
6806       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6807         ;
6808       else if (unformat (i, "via-label %d", &next_hop_via_label))
6809         ;
6810       else if (unformat (i, "out-label %d", &next_hop_out_label))
6811         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6812       else
6813         {
6814           clib_warning ("parse error '%U'", format_unformat_error, i);
6815           return -99;
6816         }
6817     }
6818
6819   if (!next_hop_set && !is_classify)
6820     {
6821       errmsg ("next hop / classify not set");
6822       return -99;
6823     }
6824
6825   if (MPLS_LABEL_INVALID == local_label)
6826     {
6827       errmsg ("missing label");
6828       return -99;
6829     }
6830
6831   if (count > 1)
6832     {
6833       /* Turn on async mode */
6834       vam->async_mode = 1;
6835       vam->async_errors = 0;
6836       before = vat_time_now (vam);
6837     }
6838
6839   for (j = 0; j < count; j++)
6840     {
6841       /* Construct the API message */
6842       M2 (MPLS_ROUTE_ADD_DEL, mp,
6843           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6844
6845       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6846       mp->mr_table_id = ntohl (table_id);
6847       mp->mr_create_table_if_needed = create_table_if_needed;
6848
6849       mp->mr_is_add = is_add;
6850       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6851       mp->mr_is_classify = is_classify;
6852       mp->mr_is_multipath = is_multipath;
6853       mp->mr_is_resolve_host = resolve_host;
6854       mp->mr_is_resolve_attached = resolve_attached;
6855       mp->mr_next_hop_weight = next_hop_weight;
6856       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6857       mp->mr_classify_table_index = ntohl (classify_table_index);
6858       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6859       mp->mr_label = ntohl (local_label);
6860       mp->mr_eos = is_eos;
6861
6862       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6863       if (0 != mp->mr_next_hop_n_out_labels)
6864         {
6865           memcpy (mp->mr_next_hop_out_label_stack,
6866                   next_hop_out_label_stack,
6867                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6868           vec_free (next_hop_out_label_stack);
6869         }
6870
6871       if (next_hop_set)
6872         {
6873           if (next_hop_proto_is_ip4)
6874             {
6875               clib_memcpy (mp->mr_next_hop,
6876                            &v4_next_hop_address,
6877                            sizeof (v4_next_hop_address));
6878             }
6879           else
6880             {
6881               clib_memcpy (mp->mr_next_hop,
6882                            &v6_next_hop_address,
6883                            sizeof (v6_next_hop_address));
6884             }
6885         }
6886       local_label++;
6887
6888       /* send it... */
6889       S (mp);
6890       /* If we receive SIGTERM, stop now... */
6891       if (vam->do_exit)
6892         break;
6893     }
6894
6895   /* When testing multiple add/del ops, use a control-ping to sync */
6896   if (count > 1)
6897     {
6898       vl_api_control_ping_t *mp_ping;
6899       f64 after;
6900       f64 timeout;
6901
6902       /* Shut off async mode */
6903       vam->async_mode = 0;
6904
6905       M (CONTROL_PING, mp_ping);
6906       S (mp_ping);
6907
6908       timeout = vat_time_now (vam) + 1.0;
6909       while (vat_time_now (vam) < timeout)
6910         if (vam->result_ready == 1)
6911           goto out;
6912       vam->retval = -99;
6913
6914     out:
6915       if (vam->retval == -99)
6916         errmsg ("timeout");
6917
6918       if (vam->async_errors > 0)
6919         {
6920           errmsg ("%d asynchronous errors", vam->async_errors);
6921           vam->retval = -98;
6922         }
6923       vam->async_errors = 0;
6924       after = vat_time_now (vam);
6925
6926       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6927       if (j > 0)
6928         count = j;
6929
6930       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6931              count, after - before, count / (after - before));
6932     }
6933   else
6934     {
6935       int ret;
6936
6937       /* Wait for a reply... */
6938       W (ret);
6939       return ret;
6940     }
6941
6942   /* Return the good/bad news */
6943   return (vam->retval);
6944 }
6945
6946 static int
6947 api_mpls_ip_bind_unbind (vat_main_t * vam)
6948 {
6949   unformat_input_t *i = vam->input;
6950   vl_api_mpls_ip_bind_unbind_t *mp;
6951   u32 ip_table_id = 0;
6952   u8 create_table_if_needed = 0;
6953   u8 is_bind = 1;
6954   u8 is_ip4 = 1;
6955   ip4_address_t v4_address;
6956   ip6_address_t v6_address;
6957   u32 address_length;
6958   u8 address_set = 0;
6959   mpls_label_t local_label = MPLS_LABEL_INVALID;
6960   int ret;
6961
6962   /* Parse args required to build the message */
6963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6964     {
6965       if (unformat (i, "%U/%d", unformat_ip4_address,
6966                     &v4_address, &address_length))
6967         {
6968           is_ip4 = 1;
6969           address_set = 1;
6970         }
6971       else if (unformat (i, "%U/%d", unformat_ip6_address,
6972                          &v6_address, &address_length))
6973         {
6974           is_ip4 = 0;
6975           address_set = 1;
6976         }
6977       else if (unformat (i, "%d", &local_label))
6978         ;
6979       else if (unformat (i, "create-table"))
6980         create_table_if_needed = 1;
6981       else if (unformat (i, "table-id %d", &ip_table_id))
6982         ;
6983       else if (unformat (i, "unbind"))
6984         is_bind = 0;
6985       else if (unformat (i, "bind"))
6986         is_bind = 1;
6987       else
6988         {
6989           clib_warning ("parse error '%U'", format_unformat_error, i);
6990           return -99;
6991         }
6992     }
6993
6994   if (!address_set)
6995     {
6996       errmsg ("IP addres not set");
6997       return -99;
6998     }
6999
7000   if (MPLS_LABEL_INVALID == local_label)
7001     {
7002       errmsg ("missing label");
7003       return -99;
7004     }
7005
7006   /* Construct the API message */
7007   M (MPLS_IP_BIND_UNBIND, mp);
7008
7009   mp->mb_create_table_if_needed = create_table_if_needed;
7010   mp->mb_is_bind = is_bind;
7011   mp->mb_is_ip4 = is_ip4;
7012   mp->mb_ip_table_id = ntohl (ip_table_id);
7013   mp->mb_mpls_table_id = 0;
7014   mp->mb_label = ntohl (local_label);
7015   mp->mb_address_length = address_length;
7016
7017   if (is_ip4)
7018     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7019   else
7020     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7021
7022   /* send it... */
7023   S (mp);
7024
7025   /* Wait for a reply... */
7026   W (ret);
7027   return ret;
7028 }
7029
7030 static int
7031 api_proxy_arp_add_del (vat_main_t * vam)
7032 {
7033   unformat_input_t *i = vam->input;
7034   vl_api_proxy_arp_add_del_t *mp;
7035   u32 vrf_id = 0;
7036   u8 is_add = 1;
7037   ip4_address_t lo, hi;
7038   u8 range_set = 0;
7039   int ret;
7040
7041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7042     {
7043       if (unformat (i, "vrf %d", &vrf_id))
7044         ;
7045       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7046                          unformat_ip4_address, &hi))
7047         range_set = 1;
7048       else if (unformat (i, "del"))
7049         is_add = 0;
7050       else
7051         {
7052           clib_warning ("parse error '%U'", format_unformat_error, i);
7053           return -99;
7054         }
7055     }
7056
7057   if (range_set == 0)
7058     {
7059       errmsg ("address range not set");
7060       return -99;
7061     }
7062
7063   M (PROXY_ARP_ADD_DEL, mp);
7064
7065   mp->vrf_id = ntohl (vrf_id);
7066   mp->is_add = is_add;
7067   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7068   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7069
7070   S (mp);
7071   W (ret);
7072   return ret;
7073 }
7074
7075 static int
7076 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7077 {
7078   unformat_input_t *i = vam->input;
7079   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7080   u32 sw_if_index;
7081   u8 enable = 1;
7082   u8 sw_if_index_set = 0;
7083   int ret;
7084
7085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7086     {
7087       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7088         sw_if_index_set = 1;
7089       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7090         sw_if_index_set = 1;
7091       else if (unformat (i, "enable"))
7092         enable = 1;
7093       else if (unformat (i, "disable"))
7094         enable = 0;
7095       else
7096         {
7097           clib_warning ("parse error '%U'", format_unformat_error, i);
7098           return -99;
7099         }
7100     }
7101
7102   if (sw_if_index_set == 0)
7103     {
7104       errmsg ("missing interface name or sw_if_index");
7105       return -99;
7106     }
7107
7108   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7109
7110   mp->sw_if_index = ntohl (sw_if_index);
7111   mp->enable_disable = enable;
7112
7113   S (mp);
7114   W (ret);
7115   return ret;
7116 }
7117
7118 static int
7119 api_mpls_tunnel_add_del (vat_main_t * vam)
7120 {
7121   unformat_input_t *i = vam->input;
7122   vl_api_mpls_tunnel_add_del_t *mp;
7123
7124   u8 is_add = 1;
7125   u8 l2_only = 0;
7126   u32 sw_if_index = ~0;
7127   u32 next_hop_sw_if_index = ~0;
7128   u32 next_hop_proto_is_ip4 = 1;
7129
7130   u32 next_hop_table_id = 0;
7131   ip4_address_t v4_next_hop_address = {
7132     .as_u32 = 0,
7133   };
7134   ip6_address_t v6_next_hop_address = { {0} };
7135   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7136   int ret;
7137
7138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7139     {
7140       if (unformat (i, "add"))
7141         is_add = 1;
7142       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7143         is_add = 0;
7144       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7145         ;
7146       else if (unformat (i, "via %U",
7147                          unformat_ip4_address, &v4_next_hop_address))
7148         {
7149           next_hop_proto_is_ip4 = 1;
7150         }
7151       else if (unformat (i, "via %U",
7152                          unformat_ip6_address, &v6_next_hop_address))
7153         {
7154           next_hop_proto_is_ip4 = 0;
7155         }
7156       else if (unformat (i, "l2-only"))
7157         l2_only = 1;
7158       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7159         ;
7160       else if (unformat (i, "out-label %d", &next_hop_out_label))
7161         vec_add1 (labels, ntohl (next_hop_out_label));
7162       else
7163         {
7164           clib_warning ("parse error '%U'", format_unformat_error, i);
7165           return -99;
7166         }
7167     }
7168
7169   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7170
7171   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7172   mp->mt_sw_if_index = ntohl (sw_if_index);
7173   mp->mt_is_add = is_add;
7174   mp->mt_l2_only = l2_only;
7175   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7176   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7177
7178   mp->mt_next_hop_n_out_labels = vec_len (labels);
7179
7180   if (0 != mp->mt_next_hop_n_out_labels)
7181     {
7182       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7183                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7184       vec_free (labels);
7185     }
7186
7187   if (next_hop_proto_is_ip4)
7188     {
7189       clib_memcpy (mp->mt_next_hop,
7190                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7191     }
7192   else
7193     {
7194       clib_memcpy (mp->mt_next_hop,
7195                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7196     }
7197
7198   S (mp);
7199   W (ret);
7200   return ret;
7201 }
7202
7203 static int
7204 api_sw_interface_set_unnumbered (vat_main_t * vam)
7205 {
7206   unformat_input_t *i = vam->input;
7207   vl_api_sw_interface_set_unnumbered_t *mp;
7208   u32 sw_if_index;
7209   u32 unnum_sw_index = ~0;
7210   u8 is_add = 1;
7211   u8 sw_if_index_set = 0;
7212   int ret;
7213
7214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7215     {
7216       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7217         sw_if_index_set = 1;
7218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7219         sw_if_index_set = 1;
7220       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7221         ;
7222       else if (unformat (i, "del"))
7223         is_add = 0;
7224       else
7225         {
7226           clib_warning ("parse error '%U'", format_unformat_error, i);
7227           return -99;
7228         }
7229     }
7230
7231   if (sw_if_index_set == 0)
7232     {
7233       errmsg ("missing interface name or sw_if_index");
7234       return -99;
7235     }
7236
7237   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7238
7239   mp->sw_if_index = ntohl (sw_if_index);
7240   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7241   mp->is_add = is_add;
7242
7243   S (mp);
7244   W (ret);
7245   return ret;
7246 }
7247
7248 static int
7249 api_ip_neighbor_add_del (vat_main_t * vam)
7250 {
7251   unformat_input_t *i = vam->input;
7252   vl_api_ip_neighbor_add_del_t *mp;
7253   u32 sw_if_index;
7254   u8 sw_if_index_set = 0;
7255   u32 vrf_id = 0;
7256   u8 is_add = 1;
7257   u8 is_static = 0;
7258   u8 mac_address[6];
7259   u8 mac_set = 0;
7260   u8 v4_address_set = 0;
7261   u8 v6_address_set = 0;
7262   ip4_address_t v4address;
7263   ip6_address_t v6address;
7264   int ret;
7265
7266   memset (mac_address, 0, sizeof (mac_address));
7267
7268   /* Parse args required to build the message */
7269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7270     {
7271       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7272         {
7273           mac_set = 1;
7274         }
7275       else if (unformat (i, "del"))
7276         is_add = 0;
7277       else
7278         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7279         sw_if_index_set = 1;
7280       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7281         sw_if_index_set = 1;
7282       else if (unformat (i, "is_static"))
7283         is_static = 1;
7284       else if (unformat (i, "vrf %d", &vrf_id))
7285         ;
7286       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7287         v4_address_set = 1;
7288       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7289         v6_address_set = 1;
7290       else
7291         {
7292           clib_warning ("parse error '%U'", format_unformat_error, i);
7293           return -99;
7294         }
7295     }
7296
7297   if (sw_if_index_set == 0)
7298     {
7299       errmsg ("missing interface name or sw_if_index");
7300       return -99;
7301     }
7302   if (v4_address_set && v6_address_set)
7303     {
7304       errmsg ("both v4 and v6 addresses set");
7305       return -99;
7306     }
7307   if (!v4_address_set && !v6_address_set)
7308     {
7309       errmsg ("no address set");
7310       return -99;
7311     }
7312
7313   /* Construct the API message */
7314   M (IP_NEIGHBOR_ADD_DEL, mp);
7315
7316   mp->sw_if_index = ntohl (sw_if_index);
7317   mp->is_add = is_add;
7318   mp->vrf_id = ntohl (vrf_id);
7319   mp->is_static = is_static;
7320   if (mac_set)
7321     clib_memcpy (mp->mac_address, mac_address, 6);
7322   if (v6_address_set)
7323     {
7324       mp->is_ipv6 = 1;
7325       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7326     }
7327   else
7328     {
7329       /* mp->is_ipv6 = 0; via memset in M macro above */
7330       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7331     }
7332
7333   /* send it... */
7334   S (mp);
7335
7336   /* Wait for a reply, return good/bad news  */
7337   W (ret);
7338   return ret;
7339 }
7340
7341 static int
7342 api_reset_vrf (vat_main_t * vam)
7343 {
7344   unformat_input_t *i = vam->input;
7345   vl_api_reset_vrf_t *mp;
7346   u32 vrf_id = 0;
7347   u8 is_ipv6 = 0;
7348   u8 vrf_id_set = 0;
7349   int ret;
7350
7351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7352     {
7353       if (unformat (i, "vrf %d", &vrf_id))
7354         vrf_id_set = 1;
7355       else if (unformat (i, "ipv6"))
7356         is_ipv6 = 1;
7357       else
7358         {
7359           clib_warning ("parse error '%U'", format_unformat_error, i);
7360           return -99;
7361         }
7362     }
7363
7364   if (vrf_id_set == 0)
7365     {
7366       errmsg ("missing vrf id");
7367       return -99;
7368     }
7369
7370   M (RESET_VRF, mp);
7371
7372   mp->vrf_id = ntohl (vrf_id);
7373   mp->is_ipv6 = is_ipv6;
7374
7375   S (mp);
7376   W (ret);
7377   return ret;
7378 }
7379
7380 static int
7381 api_create_vlan_subif (vat_main_t * vam)
7382 {
7383   unformat_input_t *i = vam->input;
7384   vl_api_create_vlan_subif_t *mp;
7385   u32 sw_if_index;
7386   u8 sw_if_index_set = 0;
7387   u32 vlan_id;
7388   u8 vlan_id_set = 0;
7389   int ret;
7390
7391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7392     {
7393       if (unformat (i, "sw_if_index %d", &sw_if_index))
7394         sw_if_index_set = 1;
7395       else
7396         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7397         sw_if_index_set = 1;
7398       else if (unformat (i, "vlan %d", &vlan_id))
7399         vlan_id_set = 1;
7400       else
7401         {
7402           clib_warning ("parse error '%U'", format_unformat_error, i);
7403           return -99;
7404         }
7405     }
7406
7407   if (sw_if_index_set == 0)
7408     {
7409       errmsg ("missing interface name or sw_if_index");
7410       return -99;
7411     }
7412
7413   if (vlan_id_set == 0)
7414     {
7415       errmsg ("missing vlan_id");
7416       return -99;
7417     }
7418   M (CREATE_VLAN_SUBIF, mp);
7419
7420   mp->sw_if_index = ntohl (sw_if_index);
7421   mp->vlan_id = ntohl (vlan_id);
7422
7423   S (mp);
7424   W (ret);
7425   return ret;
7426 }
7427
7428 #define foreach_create_subif_bit                \
7429 _(no_tags)                                      \
7430 _(one_tag)                                      \
7431 _(two_tags)                                     \
7432 _(dot1ad)                                       \
7433 _(exact_match)                                  \
7434 _(default_sub)                                  \
7435 _(outer_vlan_id_any)                            \
7436 _(inner_vlan_id_any)
7437
7438 static int
7439 api_create_subif (vat_main_t * vam)
7440 {
7441   unformat_input_t *i = vam->input;
7442   vl_api_create_subif_t *mp;
7443   u32 sw_if_index;
7444   u8 sw_if_index_set = 0;
7445   u32 sub_id;
7446   u8 sub_id_set = 0;
7447   u32 no_tags = 0;
7448   u32 one_tag = 0;
7449   u32 two_tags = 0;
7450   u32 dot1ad = 0;
7451   u32 exact_match = 0;
7452   u32 default_sub = 0;
7453   u32 outer_vlan_id_any = 0;
7454   u32 inner_vlan_id_any = 0;
7455   u32 tmp;
7456   u16 outer_vlan_id = 0;
7457   u16 inner_vlan_id = 0;
7458   int ret;
7459
7460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7461     {
7462       if (unformat (i, "sw_if_index %d", &sw_if_index))
7463         sw_if_index_set = 1;
7464       else
7465         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7466         sw_if_index_set = 1;
7467       else if (unformat (i, "sub_id %d", &sub_id))
7468         sub_id_set = 1;
7469       else if (unformat (i, "outer_vlan_id %d", &tmp))
7470         outer_vlan_id = tmp;
7471       else if (unformat (i, "inner_vlan_id %d", &tmp))
7472         inner_vlan_id = tmp;
7473
7474 #define _(a) else if (unformat (i, #a)) a = 1 ;
7475       foreach_create_subif_bit
7476 #undef _
7477         else
7478         {
7479           clib_warning ("parse error '%U'", format_unformat_error, i);
7480           return -99;
7481         }
7482     }
7483
7484   if (sw_if_index_set == 0)
7485     {
7486       errmsg ("missing interface name or sw_if_index");
7487       return -99;
7488     }
7489
7490   if (sub_id_set == 0)
7491     {
7492       errmsg ("missing sub_id");
7493       return -99;
7494     }
7495   M (CREATE_SUBIF, mp);
7496
7497   mp->sw_if_index = ntohl (sw_if_index);
7498   mp->sub_id = ntohl (sub_id);
7499
7500 #define _(a) mp->a = a;
7501   foreach_create_subif_bit;
7502 #undef _
7503
7504   mp->outer_vlan_id = ntohs (outer_vlan_id);
7505   mp->inner_vlan_id = ntohs (inner_vlan_id);
7506
7507   S (mp);
7508   W (ret);
7509   return ret;
7510 }
7511
7512 static int
7513 api_oam_add_del (vat_main_t * vam)
7514 {
7515   unformat_input_t *i = vam->input;
7516   vl_api_oam_add_del_t *mp;
7517   u32 vrf_id = 0;
7518   u8 is_add = 1;
7519   ip4_address_t src, dst;
7520   u8 src_set = 0;
7521   u8 dst_set = 0;
7522   int ret;
7523
7524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7525     {
7526       if (unformat (i, "vrf %d", &vrf_id))
7527         ;
7528       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7529         src_set = 1;
7530       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7531         dst_set = 1;
7532       else if (unformat (i, "del"))
7533         is_add = 0;
7534       else
7535         {
7536           clib_warning ("parse error '%U'", format_unformat_error, i);
7537           return -99;
7538         }
7539     }
7540
7541   if (src_set == 0)
7542     {
7543       errmsg ("missing src addr");
7544       return -99;
7545     }
7546
7547   if (dst_set == 0)
7548     {
7549       errmsg ("missing dst addr");
7550       return -99;
7551     }
7552
7553   M (OAM_ADD_DEL, mp);
7554
7555   mp->vrf_id = ntohl (vrf_id);
7556   mp->is_add = is_add;
7557   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7558   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7559
7560   S (mp);
7561   W (ret);
7562   return ret;
7563 }
7564
7565 static int
7566 api_reset_fib (vat_main_t * vam)
7567 {
7568   unformat_input_t *i = vam->input;
7569   vl_api_reset_fib_t *mp;
7570   u32 vrf_id = 0;
7571   u8 is_ipv6 = 0;
7572   u8 vrf_id_set = 0;
7573
7574   int ret;
7575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7576     {
7577       if (unformat (i, "vrf %d", &vrf_id))
7578         vrf_id_set = 1;
7579       else if (unformat (i, "ipv6"))
7580         is_ipv6 = 1;
7581       else
7582         {
7583           clib_warning ("parse error '%U'", format_unformat_error, i);
7584           return -99;
7585         }
7586     }
7587
7588   if (vrf_id_set == 0)
7589     {
7590       errmsg ("missing vrf id");
7591       return -99;
7592     }
7593
7594   M (RESET_FIB, mp);
7595
7596   mp->vrf_id = ntohl (vrf_id);
7597   mp->is_ipv6 = is_ipv6;
7598
7599   S (mp);
7600   W (ret);
7601   return ret;
7602 }
7603
7604 static int
7605 api_dhcp_proxy_config (vat_main_t * vam)
7606 {
7607   unformat_input_t *i = vam->input;
7608   vl_api_dhcp_proxy_config_t *mp;
7609   u32 vrf_id = 0;
7610   u8 is_add = 1;
7611   u8 insert_cid = 1;
7612   u8 v4_address_set = 0;
7613   u8 v6_address_set = 0;
7614   ip4_address_t v4address;
7615   ip6_address_t v6address;
7616   u8 v4_src_address_set = 0;
7617   u8 v6_src_address_set = 0;
7618   ip4_address_t v4srcaddress;
7619   ip6_address_t v6srcaddress;
7620   int ret;
7621
7622   /* Parse args required to build the message */
7623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7624     {
7625       if (unformat (i, "del"))
7626         is_add = 0;
7627       else if (unformat (i, "vrf %d", &vrf_id))
7628         ;
7629       else if (unformat (i, "insert-cid %d", &insert_cid))
7630         ;
7631       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7632         v4_address_set = 1;
7633       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7634         v6_address_set = 1;
7635       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7636         v4_src_address_set = 1;
7637       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7638         v6_src_address_set = 1;
7639       else
7640         break;
7641     }
7642
7643   if (v4_address_set && v6_address_set)
7644     {
7645       errmsg ("both v4 and v6 server addresses set");
7646       return -99;
7647     }
7648   if (!v4_address_set && !v6_address_set)
7649     {
7650       errmsg ("no server addresses set");
7651       return -99;
7652     }
7653
7654   if (v4_src_address_set && v6_src_address_set)
7655     {
7656       errmsg ("both v4 and v6  src addresses set");
7657       return -99;
7658     }
7659   if (!v4_src_address_set && !v6_src_address_set)
7660     {
7661       errmsg ("no src addresses set");
7662       return -99;
7663     }
7664
7665   if (!(v4_src_address_set && v4_address_set) &&
7666       !(v6_src_address_set && v6_address_set))
7667     {
7668       errmsg ("no matching server and src addresses set");
7669       return -99;
7670     }
7671
7672   /* Construct the API message */
7673   M (DHCP_PROXY_CONFIG, mp);
7674
7675   mp->insert_circuit_id = insert_cid;
7676   mp->is_add = is_add;
7677   mp->vrf_id = ntohl (vrf_id);
7678   if (v6_address_set)
7679     {
7680       mp->is_ipv6 = 1;
7681       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7682       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7683     }
7684   else
7685     {
7686       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7687       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7688     }
7689
7690   /* send it... */
7691   S (mp);
7692
7693   /* Wait for a reply, return good/bad news  */
7694   W (ret);
7695   return ret;
7696 }
7697
7698 static int
7699 api_dhcp_proxy_config_2 (vat_main_t * vam)
7700 {
7701   unformat_input_t *i = vam->input;
7702   vl_api_dhcp_proxy_config_2_t *mp;
7703   u32 rx_vrf_id = 0;
7704   u32 server_vrf_id = 0;
7705   u8 is_add = 1;
7706   u8 insert_cid = 1;
7707   u8 v4_address_set = 0;
7708   u8 v6_address_set = 0;
7709   ip4_address_t v4address;
7710   ip6_address_t v6address;
7711   u8 v4_src_address_set = 0;
7712   u8 v6_src_address_set = 0;
7713   ip4_address_t v4srcaddress;
7714   ip6_address_t v6srcaddress;
7715   int ret;
7716
7717   /* Parse args required to build the message */
7718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7719     {
7720       if (unformat (i, "del"))
7721         is_add = 0;
7722       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7723         ;
7724       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7725         ;
7726       else if (unformat (i, "insert-cid %d", &insert_cid))
7727         ;
7728       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7729         v4_address_set = 1;
7730       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7731         v6_address_set = 1;
7732       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7733         v4_src_address_set = 1;
7734       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7735         v6_src_address_set = 1;
7736       else
7737         break;
7738     }
7739
7740   if (v4_address_set && v6_address_set)
7741     {
7742       errmsg ("both v4 and v6 server addresses set");
7743       return -99;
7744     }
7745   if (!v4_address_set && !v6_address_set)
7746     {
7747       errmsg ("no server addresses set");
7748       return -99;
7749     }
7750
7751   if (v4_src_address_set && v6_src_address_set)
7752     {
7753       errmsg ("both v4 and v6  src addresses set");
7754       return -99;
7755     }
7756   if (!v4_src_address_set && !v6_src_address_set)
7757     {
7758       errmsg ("no src addresses set");
7759       return -99;
7760     }
7761
7762   if (!(v4_src_address_set && v4_address_set) &&
7763       !(v6_src_address_set && v6_address_set))
7764     {
7765       errmsg ("no matching server and src addresses set");
7766       return -99;
7767     }
7768
7769   /* Construct the API message */
7770   M (DHCP_PROXY_CONFIG_2, mp);
7771
7772   mp->insert_circuit_id = insert_cid;
7773   mp->is_add = is_add;
7774   mp->rx_vrf_id = ntohl (rx_vrf_id);
7775   mp->server_vrf_id = ntohl (server_vrf_id);
7776   if (v6_address_set)
7777     {
7778       mp->is_ipv6 = 1;
7779       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7780       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7781     }
7782   else
7783     {
7784       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7785       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7786     }
7787
7788   /* send it... */
7789   S (mp);
7790
7791   /* Wait for a reply, return good/bad news  */
7792   W (ret);
7793   return ret;
7794 }
7795
7796 static int
7797 api_dhcp_proxy_set_vss (vat_main_t * vam)
7798 {
7799   unformat_input_t *i = vam->input;
7800   vl_api_dhcp_proxy_set_vss_t *mp;
7801   u8 is_ipv6 = 0;
7802   u8 is_add = 1;
7803   u32 tbl_id;
7804   u8 tbl_id_set = 0;
7805   u32 oui;
7806   u8 oui_set = 0;
7807   u32 fib_id;
7808   u8 fib_id_set = 0;
7809   int ret;
7810
7811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7812     {
7813       if (unformat (i, "tbl_id %d", &tbl_id))
7814         tbl_id_set = 1;
7815       if (unformat (i, "fib_id %d", &fib_id))
7816         fib_id_set = 1;
7817       if (unformat (i, "oui %d", &oui))
7818         oui_set = 1;
7819       else if (unformat (i, "ipv6"))
7820         is_ipv6 = 1;
7821       else if (unformat (i, "del"))
7822         is_add = 0;
7823       else
7824         {
7825           clib_warning ("parse error '%U'", format_unformat_error, i);
7826           return -99;
7827         }
7828     }
7829
7830   if (tbl_id_set == 0)
7831     {
7832       errmsg ("missing tbl id");
7833       return -99;
7834     }
7835
7836   if (fib_id_set == 0)
7837     {
7838       errmsg ("missing fib id");
7839       return -99;
7840     }
7841   if (oui_set == 0)
7842     {
7843       errmsg ("missing oui");
7844       return -99;
7845     }
7846
7847   M (DHCP_PROXY_SET_VSS, mp);
7848   mp->tbl_id = ntohl (tbl_id);
7849   mp->fib_id = ntohl (fib_id);
7850   mp->oui = ntohl (oui);
7851   mp->is_ipv6 = is_ipv6;
7852   mp->is_add = is_add;
7853
7854   S (mp);
7855   W (ret);
7856   return ret;
7857 }
7858
7859 static int
7860 api_dhcp_client_config (vat_main_t * vam)
7861 {
7862   unformat_input_t *i = vam->input;
7863   vl_api_dhcp_client_config_t *mp;
7864   u32 sw_if_index;
7865   u8 sw_if_index_set = 0;
7866   u8 is_add = 1;
7867   u8 *hostname = 0;
7868   u8 disable_event = 0;
7869   int ret;
7870
7871   /* Parse args required to build the message */
7872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7873     {
7874       if (unformat (i, "del"))
7875         is_add = 0;
7876       else
7877         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7878         sw_if_index_set = 1;
7879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7880         sw_if_index_set = 1;
7881       else if (unformat (i, "hostname %s", &hostname))
7882         ;
7883       else if (unformat (i, "disable_event"))
7884         disable_event = 1;
7885       else
7886         break;
7887     }
7888
7889   if (sw_if_index_set == 0)
7890     {
7891       errmsg ("missing interface name or sw_if_index");
7892       return -99;
7893     }
7894
7895   if (vec_len (hostname) > 63)
7896     {
7897       errmsg ("hostname too long");
7898     }
7899   vec_add1 (hostname, 0);
7900
7901   /* Construct the API message */
7902   M (DHCP_CLIENT_CONFIG, mp);
7903
7904   mp->sw_if_index = ntohl (sw_if_index);
7905   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7906   vec_free (hostname);
7907   mp->is_add = is_add;
7908   mp->want_dhcp_event = disable_event ? 0 : 1;
7909   mp->pid = getpid ();
7910
7911   /* send it... */
7912   S (mp);
7913
7914   /* Wait for a reply, return good/bad news  */
7915   W (ret);
7916   return ret;
7917 }
7918
7919 static int
7920 api_set_ip_flow_hash (vat_main_t * vam)
7921 {
7922   unformat_input_t *i = vam->input;
7923   vl_api_set_ip_flow_hash_t *mp;
7924   u32 vrf_id = 0;
7925   u8 is_ipv6 = 0;
7926   u8 vrf_id_set = 0;
7927   u8 src = 0;
7928   u8 dst = 0;
7929   u8 sport = 0;
7930   u8 dport = 0;
7931   u8 proto = 0;
7932   u8 reverse = 0;
7933   int ret;
7934
7935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7936     {
7937       if (unformat (i, "vrf %d", &vrf_id))
7938         vrf_id_set = 1;
7939       else if (unformat (i, "ipv6"))
7940         is_ipv6 = 1;
7941       else if (unformat (i, "src"))
7942         src = 1;
7943       else if (unformat (i, "dst"))
7944         dst = 1;
7945       else if (unformat (i, "sport"))
7946         sport = 1;
7947       else if (unformat (i, "dport"))
7948         dport = 1;
7949       else if (unformat (i, "proto"))
7950         proto = 1;
7951       else if (unformat (i, "reverse"))
7952         reverse = 1;
7953
7954       else
7955         {
7956           clib_warning ("parse error '%U'", format_unformat_error, i);
7957           return -99;
7958         }
7959     }
7960
7961   if (vrf_id_set == 0)
7962     {
7963       errmsg ("missing vrf id");
7964       return -99;
7965     }
7966
7967   M (SET_IP_FLOW_HASH, mp);
7968   mp->src = src;
7969   mp->dst = dst;
7970   mp->sport = sport;
7971   mp->dport = dport;
7972   mp->proto = proto;
7973   mp->reverse = reverse;
7974   mp->vrf_id = ntohl (vrf_id);
7975   mp->is_ipv6 = is_ipv6;
7976
7977   S (mp);
7978   W (ret);
7979   return ret;
7980 }
7981
7982 static int
7983 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7984 {
7985   unformat_input_t *i = vam->input;
7986   vl_api_sw_interface_ip6_enable_disable_t *mp;
7987   u32 sw_if_index;
7988   u8 sw_if_index_set = 0;
7989   u8 enable = 0;
7990   int ret;
7991
7992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7993     {
7994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7995         sw_if_index_set = 1;
7996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7997         sw_if_index_set = 1;
7998       else if (unformat (i, "enable"))
7999         enable = 1;
8000       else if (unformat (i, "disable"))
8001         enable = 0;
8002       else
8003         {
8004           clib_warning ("parse error '%U'", format_unformat_error, i);
8005           return -99;
8006         }
8007     }
8008
8009   if (sw_if_index_set == 0)
8010     {
8011       errmsg ("missing interface name or sw_if_index");
8012       return -99;
8013     }
8014
8015   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8016
8017   mp->sw_if_index = ntohl (sw_if_index);
8018   mp->enable = enable;
8019
8020   S (mp);
8021   W (ret);
8022   return ret;
8023 }
8024
8025 static int
8026 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8027 {
8028   unformat_input_t *i = vam->input;
8029   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8030   u32 sw_if_index;
8031   u8 sw_if_index_set = 0;
8032   u8 v6_address_set = 0;
8033   ip6_address_t v6address;
8034   int ret;
8035
8036   /* Parse args required to build the message */
8037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8038     {
8039       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8040         sw_if_index_set = 1;
8041       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8042         sw_if_index_set = 1;
8043       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8044         v6_address_set = 1;
8045       else
8046         break;
8047     }
8048
8049   if (sw_if_index_set == 0)
8050     {
8051       errmsg ("missing interface name or sw_if_index");
8052       return -99;
8053     }
8054   if (!v6_address_set)
8055     {
8056       errmsg ("no address set");
8057       return -99;
8058     }
8059
8060   /* Construct the API message */
8061   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8062
8063   mp->sw_if_index = ntohl (sw_if_index);
8064   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8065
8066   /* send it... */
8067   S (mp);
8068
8069   /* Wait for a reply, return good/bad news  */
8070   W (ret);
8071   return ret;
8072 }
8073
8074
8075 static int
8076 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8077 {
8078   unformat_input_t *i = vam->input;
8079   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8080   u32 sw_if_index;
8081   u8 sw_if_index_set = 0;
8082   u32 address_length = 0;
8083   u8 v6_address_set = 0;
8084   ip6_address_t v6address;
8085   u8 use_default = 0;
8086   u8 no_advertise = 0;
8087   u8 off_link = 0;
8088   u8 no_autoconfig = 0;
8089   u8 no_onlink = 0;
8090   u8 is_no = 0;
8091   u32 val_lifetime = 0;
8092   u32 pref_lifetime = 0;
8093   int ret;
8094
8095   /* Parse args required to build the message */
8096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8097     {
8098       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8099         sw_if_index_set = 1;
8100       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8101         sw_if_index_set = 1;
8102       else if (unformat (i, "%U/%d",
8103                          unformat_ip6_address, &v6address, &address_length))
8104         v6_address_set = 1;
8105       else if (unformat (i, "val_life %d", &val_lifetime))
8106         ;
8107       else if (unformat (i, "pref_life %d", &pref_lifetime))
8108         ;
8109       else if (unformat (i, "def"))
8110         use_default = 1;
8111       else if (unformat (i, "noadv"))
8112         no_advertise = 1;
8113       else if (unformat (i, "offl"))
8114         off_link = 1;
8115       else if (unformat (i, "noauto"))
8116         no_autoconfig = 1;
8117       else if (unformat (i, "nolink"))
8118         no_onlink = 1;
8119       else if (unformat (i, "isno"))
8120         is_no = 1;
8121       else
8122         {
8123           clib_warning ("parse error '%U'", format_unformat_error, i);
8124           return -99;
8125         }
8126     }
8127
8128   if (sw_if_index_set == 0)
8129     {
8130       errmsg ("missing interface name or sw_if_index");
8131       return -99;
8132     }
8133   if (!v6_address_set)
8134     {
8135       errmsg ("no address set");
8136       return -99;
8137     }
8138
8139   /* Construct the API message */
8140   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8141
8142   mp->sw_if_index = ntohl (sw_if_index);
8143   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8144   mp->address_length = address_length;
8145   mp->use_default = use_default;
8146   mp->no_advertise = no_advertise;
8147   mp->off_link = off_link;
8148   mp->no_autoconfig = no_autoconfig;
8149   mp->no_onlink = no_onlink;
8150   mp->is_no = is_no;
8151   mp->val_lifetime = ntohl (val_lifetime);
8152   mp->pref_lifetime = ntohl (pref_lifetime);
8153
8154   /* send it... */
8155   S (mp);
8156
8157   /* Wait for a reply, return good/bad news  */
8158   W (ret);
8159   return ret;
8160 }
8161
8162 static int
8163 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8164 {
8165   unformat_input_t *i = vam->input;
8166   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8167   u32 sw_if_index;
8168   u8 sw_if_index_set = 0;
8169   u8 suppress = 0;
8170   u8 managed = 0;
8171   u8 other = 0;
8172   u8 ll_option = 0;
8173   u8 send_unicast = 0;
8174   u8 cease = 0;
8175   u8 is_no = 0;
8176   u8 default_router = 0;
8177   u32 max_interval = 0;
8178   u32 min_interval = 0;
8179   u32 lifetime = 0;
8180   u32 initial_count = 0;
8181   u32 initial_interval = 0;
8182   int ret;
8183
8184
8185   /* Parse args required to build the message */
8186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8187     {
8188       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8189         sw_if_index_set = 1;
8190       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8191         sw_if_index_set = 1;
8192       else if (unformat (i, "maxint %d", &max_interval))
8193         ;
8194       else if (unformat (i, "minint %d", &min_interval))
8195         ;
8196       else if (unformat (i, "life %d", &lifetime))
8197         ;
8198       else if (unformat (i, "count %d", &initial_count))
8199         ;
8200       else if (unformat (i, "interval %d", &initial_interval))
8201         ;
8202       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8203         suppress = 1;
8204       else if (unformat (i, "managed"))
8205         managed = 1;
8206       else if (unformat (i, "other"))
8207         other = 1;
8208       else if (unformat (i, "ll"))
8209         ll_option = 1;
8210       else if (unformat (i, "send"))
8211         send_unicast = 1;
8212       else if (unformat (i, "cease"))
8213         cease = 1;
8214       else if (unformat (i, "isno"))
8215         is_no = 1;
8216       else if (unformat (i, "def"))
8217         default_router = 1;
8218       else
8219         {
8220           clib_warning ("parse error '%U'", format_unformat_error, i);
8221           return -99;
8222         }
8223     }
8224
8225   if (sw_if_index_set == 0)
8226     {
8227       errmsg ("missing interface name or sw_if_index");
8228       return -99;
8229     }
8230
8231   /* Construct the API message */
8232   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8233
8234   mp->sw_if_index = ntohl (sw_if_index);
8235   mp->max_interval = ntohl (max_interval);
8236   mp->min_interval = ntohl (min_interval);
8237   mp->lifetime = ntohl (lifetime);
8238   mp->initial_count = ntohl (initial_count);
8239   mp->initial_interval = ntohl (initial_interval);
8240   mp->suppress = suppress;
8241   mp->managed = managed;
8242   mp->other = other;
8243   mp->ll_option = ll_option;
8244   mp->send_unicast = send_unicast;
8245   mp->cease = cease;
8246   mp->is_no = is_no;
8247   mp->default_router = default_router;
8248
8249   /* send it... */
8250   S (mp);
8251
8252   /* Wait for a reply, return good/bad news  */
8253   W (ret);
8254   return ret;
8255 }
8256
8257 static int
8258 api_set_arp_neighbor_limit (vat_main_t * vam)
8259 {
8260   unformat_input_t *i = vam->input;
8261   vl_api_set_arp_neighbor_limit_t *mp;
8262   u32 arp_nbr_limit;
8263   u8 limit_set = 0;
8264   u8 is_ipv6 = 0;
8265   int ret;
8266
8267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8268     {
8269       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8270         limit_set = 1;
8271       else if (unformat (i, "ipv6"))
8272         is_ipv6 = 1;
8273       else
8274         {
8275           clib_warning ("parse error '%U'", format_unformat_error, i);
8276           return -99;
8277         }
8278     }
8279
8280   if (limit_set == 0)
8281     {
8282       errmsg ("missing limit value");
8283       return -99;
8284     }
8285
8286   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8287
8288   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8289   mp->is_ipv6 = is_ipv6;
8290
8291   S (mp);
8292   W (ret);
8293   return ret;
8294 }
8295
8296 static int
8297 api_l2_patch_add_del (vat_main_t * vam)
8298 {
8299   unformat_input_t *i = vam->input;
8300   vl_api_l2_patch_add_del_t *mp;
8301   u32 rx_sw_if_index;
8302   u8 rx_sw_if_index_set = 0;
8303   u32 tx_sw_if_index;
8304   u8 tx_sw_if_index_set = 0;
8305   u8 is_add = 1;
8306   int ret;
8307
8308   /* Parse args required to build the message */
8309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8310     {
8311       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8312         rx_sw_if_index_set = 1;
8313       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8314         tx_sw_if_index_set = 1;
8315       else if (unformat (i, "rx"))
8316         {
8317           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8318             {
8319               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8320                             &rx_sw_if_index))
8321                 rx_sw_if_index_set = 1;
8322             }
8323           else
8324             break;
8325         }
8326       else if (unformat (i, "tx"))
8327         {
8328           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8329             {
8330               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8331                             &tx_sw_if_index))
8332                 tx_sw_if_index_set = 1;
8333             }
8334           else
8335             break;
8336         }
8337       else if (unformat (i, "del"))
8338         is_add = 0;
8339       else
8340         break;
8341     }
8342
8343   if (rx_sw_if_index_set == 0)
8344     {
8345       errmsg ("missing rx interface name or rx_sw_if_index");
8346       return -99;
8347     }
8348
8349   if (tx_sw_if_index_set == 0)
8350     {
8351       errmsg ("missing tx interface name or tx_sw_if_index");
8352       return -99;
8353     }
8354
8355   M (L2_PATCH_ADD_DEL, mp);
8356
8357   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8358   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8359   mp->is_add = is_add;
8360
8361   S (mp);
8362   W (ret);
8363   return ret;
8364 }
8365
8366 static int
8367 api_ioam_enable (vat_main_t * vam)
8368 {
8369   unformat_input_t *input = vam->input;
8370   vl_api_ioam_enable_t *mp;
8371   u32 id = 0;
8372   int has_trace_option = 0;
8373   int has_pot_option = 0;
8374   int has_seqno_option = 0;
8375   int has_analyse_option = 0;
8376   int ret;
8377
8378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8379     {
8380       if (unformat (input, "trace"))
8381         has_trace_option = 1;
8382       else if (unformat (input, "pot"))
8383         has_pot_option = 1;
8384       else if (unformat (input, "seqno"))
8385         has_seqno_option = 1;
8386       else if (unformat (input, "analyse"))
8387         has_analyse_option = 1;
8388       else
8389         break;
8390     }
8391   M (IOAM_ENABLE, mp);
8392   mp->id = htons (id);
8393   mp->seqno = has_seqno_option;
8394   mp->analyse = has_analyse_option;
8395   mp->pot_enable = has_pot_option;
8396   mp->trace_enable = has_trace_option;
8397
8398   S (mp);
8399   W (ret);
8400   return ret;
8401 }
8402
8403
8404 static int
8405 api_ioam_disable (vat_main_t * vam)
8406 {
8407   vl_api_ioam_disable_t *mp;
8408   int ret;
8409
8410   M (IOAM_DISABLE, mp);
8411   S (mp);
8412   W (ret);
8413   return ret;
8414 }
8415
8416 static int
8417 api_sr_tunnel_add_del (vat_main_t * vam)
8418 {
8419   unformat_input_t *i = vam->input;
8420   vl_api_sr_tunnel_add_del_t *mp;
8421   int is_del = 0;
8422   int pl_index;
8423   ip6_address_t src_address;
8424   int src_address_set = 0;
8425   ip6_address_t dst_address;
8426   u32 dst_mask_width;
8427   int dst_address_set = 0;
8428   u16 flags = 0;
8429   u32 rx_table_id = 0;
8430   u32 tx_table_id = 0;
8431   ip6_address_t *segments = 0;
8432   ip6_address_t *this_seg;
8433   ip6_address_t *tags = 0;
8434   ip6_address_t *this_tag;
8435   ip6_address_t next_address, tag;
8436   u8 *name = 0;
8437   u8 *policy_name = 0;
8438   int ret;
8439
8440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8441     {
8442       if (unformat (i, "del"))
8443         is_del = 1;
8444       else if (unformat (i, "name %s", &name))
8445         ;
8446       else if (unformat (i, "policy %s", &policy_name))
8447         ;
8448       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8449         ;
8450       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8451         ;
8452       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8453         src_address_set = 1;
8454       else if (unformat (i, "dst %U/%d",
8455                          unformat_ip6_address, &dst_address, &dst_mask_width))
8456         dst_address_set = 1;
8457       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8458         {
8459           vec_add2 (segments, this_seg, 1);
8460           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8461                        sizeof (*this_seg));
8462         }
8463       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8464         {
8465           vec_add2 (tags, this_tag, 1);
8466           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8467         }
8468       else if (unformat (i, "clean"))
8469         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8470       else if (unformat (i, "protected"))
8471         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8472       else if (unformat (i, "InPE %d", &pl_index))
8473         {
8474           if (pl_index <= 0 || pl_index > 4)
8475             {
8476             pl_index_range_error:
8477               errmsg ("pl index %d out of range", pl_index);
8478               return -99;
8479             }
8480           flags |=
8481             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8482         }
8483       else if (unformat (i, "EgPE %d", &pl_index))
8484         {
8485           if (pl_index <= 0 || pl_index > 4)
8486             goto pl_index_range_error;
8487           flags |=
8488             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8489         }
8490       else if (unformat (i, "OrgSrc %d", &pl_index))
8491         {
8492           if (pl_index <= 0 || pl_index > 4)
8493             goto pl_index_range_error;
8494           flags |=
8495             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8496         }
8497       else
8498         break;
8499     }
8500
8501   if (!src_address_set)
8502     {
8503       errmsg ("src address required");
8504       return -99;
8505     }
8506
8507   if (!dst_address_set)
8508     {
8509       errmsg ("dst address required");
8510       return -99;
8511     }
8512
8513   if (!segments)
8514     {
8515       errmsg ("at least one sr segment required");
8516       return -99;
8517     }
8518
8519   M2 (SR_TUNNEL_ADD_DEL, mp,
8520       vec_len (segments) * sizeof (ip6_address_t)
8521       + vec_len (tags) * sizeof (ip6_address_t));
8522
8523   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8524   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8525   mp->dst_mask_width = dst_mask_width;
8526   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8527   mp->n_segments = vec_len (segments);
8528   mp->n_tags = vec_len (tags);
8529   mp->is_add = is_del == 0;
8530   clib_memcpy (mp->segs_and_tags, segments,
8531                vec_len (segments) * sizeof (ip6_address_t));
8532   clib_memcpy (mp->segs_and_tags +
8533                vec_len (segments) * sizeof (ip6_address_t), tags,
8534                vec_len (tags) * sizeof (ip6_address_t));
8535
8536   mp->outer_vrf_id = ntohl (rx_table_id);
8537   mp->inner_vrf_id = ntohl (tx_table_id);
8538   memcpy (mp->name, name, vec_len (name));
8539   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8540
8541   vec_free (segments);
8542   vec_free (tags);
8543
8544   S (mp);
8545   W (ret);
8546   return ret;
8547 }
8548
8549 static int
8550 api_sr_policy_add_del (vat_main_t * vam)
8551 {
8552   unformat_input_t *input = vam->input;
8553   vl_api_sr_policy_add_del_t *mp;
8554   int is_del = 0;
8555   u8 *name = 0;
8556   u8 *tunnel_name = 0;
8557   u8 **tunnel_names = 0;
8558
8559   int name_set = 0;
8560   int tunnel_set = 0;
8561   int j = 0;
8562   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8563   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8564   int ret;
8565
8566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8567     {
8568       if (unformat (input, "del"))
8569         is_del = 1;
8570       else if (unformat (input, "name %s", &name))
8571         name_set = 1;
8572       else if (unformat (input, "tunnel %s", &tunnel_name))
8573         {
8574           if (tunnel_name)
8575             {
8576               vec_add1 (tunnel_names, tunnel_name);
8577               /* For serializer:
8578                  - length = #bytes to store in serial vector
8579                  - +1 = byte to store that length
8580                */
8581               tunnel_names_length += (vec_len (tunnel_name) + 1);
8582               tunnel_set = 1;
8583               tunnel_name = 0;
8584             }
8585         }
8586       else
8587         break;
8588     }
8589
8590   if (!name_set)
8591     {
8592       errmsg ("policy name required");
8593       return -99;
8594     }
8595
8596   if ((!tunnel_set) && (!is_del))
8597     {
8598       errmsg ("tunnel name required");
8599       return -99;
8600     }
8601
8602   M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
8603
8604
8605
8606   mp->is_add = !is_del;
8607
8608   memcpy (mp->name, name, vec_len (name));
8609   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8610   u8 *serial_orig = 0;
8611   vec_validate (serial_orig, tunnel_names_length);
8612   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8613   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8614
8615   for (j = 0; j < vec_len (tunnel_names); j++)
8616     {
8617       tun_name_len = vec_len (tunnel_names[j]);
8618       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8619       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8620       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8621       serial_orig += tun_name_len;      // Advance past the copy
8622     }
8623   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8624
8625   vec_free (tunnel_names);
8626   vec_free (tunnel_name);
8627
8628   S (mp);
8629   W (ret);
8630   return ret;
8631 }
8632
8633 static int
8634 api_sr_multicast_map_add_del (vat_main_t * vam)
8635 {
8636   unformat_input_t *input = vam->input;
8637   vl_api_sr_multicast_map_add_del_t *mp;
8638   int is_del = 0;
8639   ip6_address_t multicast_address;
8640   u8 *policy_name = 0;
8641   int multicast_address_set = 0;
8642   int ret;
8643
8644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8645     {
8646       if (unformat (input, "del"))
8647         is_del = 1;
8648       else
8649         if (unformat
8650             (input, "address %U", unformat_ip6_address, &multicast_address))
8651         multicast_address_set = 1;
8652       else if (unformat (input, "sr-policy %s", &policy_name))
8653         ;
8654       else
8655         break;
8656     }
8657
8658   if (!is_del && !policy_name)
8659     {
8660       errmsg ("sr-policy name required");
8661       return -99;
8662     }
8663
8664
8665   if (!multicast_address_set)
8666     {
8667       errmsg ("address required");
8668       return -99;
8669     }
8670
8671   M (SR_MULTICAST_MAP_ADD_DEL, mp);
8672
8673   mp->is_add = !is_del;
8674   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8675   clib_memcpy (mp->multicast_address, &multicast_address,
8676                sizeof (mp->multicast_address));
8677
8678
8679   vec_free (policy_name);
8680
8681   S (mp);
8682   W (ret);
8683   return ret;
8684 }
8685
8686
8687 #define foreach_tcp_proto_field                 \
8688 _(src_port)                                     \
8689 _(dst_port)
8690
8691 #define foreach_udp_proto_field                 \
8692 _(src_port)                                     \
8693 _(dst_port)
8694
8695 #define foreach_ip4_proto_field                 \
8696 _(src_address)                                  \
8697 _(dst_address)                                  \
8698 _(tos)                                          \
8699 _(length)                                       \
8700 _(fragment_id)                                  \
8701 _(ttl)                                          \
8702 _(protocol)                                     \
8703 _(checksum)
8704
8705 uword
8706 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8707 {
8708   u8 **maskp = va_arg (*args, u8 **);
8709   u8 *mask = 0;
8710   u8 found_something = 0;
8711   tcp_header_t *tcp;
8712
8713 #define _(a) u8 a=0;
8714   foreach_tcp_proto_field;
8715 #undef _
8716
8717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8718     {
8719       if (0);
8720 #define _(a) else if (unformat (input, #a)) a=1;
8721       foreach_tcp_proto_field
8722 #undef _
8723         else
8724         break;
8725     }
8726
8727 #define _(a) found_something += a;
8728   foreach_tcp_proto_field;
8729 #undef _
8730
8731   if (found_something == 0)
8732     return 0;
8733
8734   vec_validate (mask, sizeof (*tcp) - 1);
8735
8736   tcp = (tcp_header_t *) mask;
8737
8738 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8739   foreach_tcp_proto_field;
8740 #undef _
8741
8742   *maskp = mask;
8743   return 1;
8744 }
8745
8746 uword
8747 unformat_udp_mask (unformat_input_t * input, va_list * args)
8748 {
8749   u8 **maskp = va_arg (*args, u8 **);
8750   u8 *mask = 0;
8751   u8 found_something = 0;
8752   udp_header_t *udp;
8753
8754 #define _(a) u8 a=0;
8755   foreach_udp_proto_field;
8756 #undef _
8757
8758   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8759     {
8760       if (0);
8761 #define _(a) else if (unformat (input, #a)) a=1;
8762       foreach_udp_proto_field
8763 #undef _
8764         else
8765         break;
8766     }
8767
8768 #define _(a) found_something += a;
8769   foreach_udp_proto_field;
8770 #undef _
8771
8772   if (found_something == 0)
8773     return 0;
8774
8775   vec_validate (mask, sizeof (*udp) - 1);
8776
8777   udp = (udp_header_t *) mask;
8778
8779 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8780   foreach_udp_proto_field;
8781 #undef _
8782
8783   *maskp = mask;
8784   return 1;
8785 }
8786
8787 typedef struct
8788 {
8789   u16 src_port, dst_port;
8790 } tcpudp_header_t;
8791
8792 uword
8793 unformat_l4_mask (unformat_input_t * input, va_list * args)
8794 {
8795   u8 **maskp = va_arg (*args, u8 **);
8796   u16 src_port = 0, dst_port = 0;
8797   tcpudp_header_t *tcpudp;
8798
8799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8800     {
8801       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8802         return 1;
8803       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8804         return 1;
8805       else if (unformat (input, "src_port"))
8806         src_port = 0xFFFF;
8807       else if (unformat (input, "dst_port"))
8808         dst_port = 0xFFFF;
8809       else
8810         return 0;
8811     }
8812
8813   if (!src_port && !dst_port)
8814     return 0;
8815
8816   u8 *mask = 0;
8817   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8818
8819   tcpudp = (tcpudp_header_t *) mask;
8820   tcpudp->src_port = src_port;
8821   tcpudp->dst_port = dst_port;
8822
8823   *maskp = mask;
8824
8825   return 1;
8826 }
8827
8828 uword
8829 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8830 {
8831   u8 **maskp = va_arg (*args, u8 **);
8832   u8 *mask = 0;
8833   u8 found_something = 0;
8834   ip4_header_t *ip;
8835
8836 #define _(a) u8 a=0;
8837   foreach_ip4_proto_field;
8838 #undef _
8839   u8 version = 0;
8840   u8 hdr_length = 0;
8841
8842
8843   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8844     {
8845       if (unformat (input, "version"))
8846         version = 1;
8847       else if (unformat (input, "hdr_length"))
8848         hdr_length = 1;
8849       else if (unformat (input, "src"))
8850         src_address = 1;
8851       else if (unformat (input, "dst"))
8852         dst_address = 1;
8853       else if (unformat (input, "proto"))
8854         protocol = 1;
8855
8856 #define _(a) else if (unformat (input, #a)) a=1;
8857       foreach_ip4_proto_field
8858 #undef _
8859         else
8860         break;
8861     }
8862
8863 #define _(a) found_something += a;
8864   foreach_ip4_proto_field;
8865 #undef _
8866
8867   if (found_something == 0)
8868     return 0;
8869
8870   vec_validate (mask, sizeof (*ip) - 1);
8871
8872   ip = (ip4_header_t *) mask;
8873
8874 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8875   foreach_ip4_proto_field;
8876 #undef _
8877
8878   ip->ip_version_and_header_length = 0;
8879
8880   if (version)
8881     ip->ip_version_and_header_length |= 0xF0;
8882
8883   if (hdr_length)
8884     ip->ip_version_and_header_length |= 0x0F;
8885
8886   *maskp = mask;
8887   return 1;
8888 }
8889
8890 #define foreach_ip6_proto_field                 \
8891 _(src_address)                                  \
8892 _(dst_address)                                  \
8893 _(payload_length)                               \
8894 _(hop_limit)                                    \
8895 _(protocol)
8896
8897 uword
8898 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8899 {
8900   u8 **maskp = va_arg (*args, u8 **);
8901   u8 *mask = 0;
8902   u8 found_something = 0;
8903   ip6_header_t *ip;
8904   u32 ip_version_traffic_class_and_flow_label;
8905
8906 #define _(a) u8 a=0;
8907   foreach_ip6_proto_field;
8908 #undef _
8909   u8 version = 0;
8910   u8 traffic_class = 0;
8911   u8 flow_label = 0;
8912
8913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8914     {
8915       if (unformat (input, "version"))
8916         version = 1;
8917       else if (unformat (input, "traffic-class"))
8918         traffic_class = 1;
8919       else if (unformat (input, "flow-label"))
8920         flow_label = 1;
8921       else if (unformat (input, "src"))
8922         src_address = 1;
8923       else if (unformat (input, "dst"))
8924         dst_address = 1;
8925       else if (unformat (input, "proto"))
8926         protocol = 1;
8927
8928 #define _(a) else if (unformat (input, #a)) a=1;
8929       foreach_ip6_proto_field
8930 #undef _
8931         else
8932         break;
8933     }
8934
8935 #define _(a) found_something += a;
8936   foreach_ip6_proto_field;
8937 #undef _
8938
8939   if (found_something == 0)
8940     return 0;
8941
8942   vec_validate (mask, sizeof (*ip) - 1);
8943
8944   ip = (ip6_header_t *) mask;
8945
8946 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8947   foreach_ip6_proto_field;
8948 #undef _
8949
8950   ip_version_traffic_class_and_flow_label = 0;
8951
8952   if (version)
8953     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8954
8955   if (traffic_class)
8956     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8957
8958   if (flow_label)
8959     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8960
8961   ip->ip_version_traffic_class_and_flow_label =
8962     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8963
8964   *maskp = mask;
8965   return 1;
8966 }
8967
8968 uword
8969 unformat_l3_mask (unformat_input_t * input, va_list * args)
8970 {
8971   u8 **maskp = va_arg (*args, u8 **);
8972
8973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8974     {
8975       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8976         return 1;
8977       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8978         return 1;
8979       else
8980         break;
8981     }
8982   return 0;
8983 }
8984
8985 uword
8986 unformat_l2_mask (unformat_input_t * input, va_list * args)
8987 {
8988   u8 **maskp = va_arg (*args, u8 **);
8989   u8 *mask = 0;
8990   u8 src = 0;
8991   u8 dst = 0;
8992   u8 proto = 0;
8993   u8 tag1 = 0;
8994   u8 tag2 = 0;
8995   u8 ignore_tag1 = 0;
8996   u8 ignore_tag2 = 0;
8997   u8 cos1 = 0;
8998   u8 cos2 = 0;
8999   u8 dot1q = 0;
9000   u8 dot1ad = 0;
9001   int len = 14;
9002
9003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9004     {
9005       if (unformat (input, "src"))
9006         src = 1;
9007       else if (unformat (input, "dst"))
9008         dst = 1;
9009       else if (unformat (input, "proto"))
9010         proto = 1;
9011       else if (unformat (input, "tag1"))
9012         tag1 = 1;
9013       else if (unformat (input, "tag2"))
9014         tag2 = 1;
9015       else if (unformat (input, "ignore-tag1"))
9016         ignore_tag1 = 1;
9017       else if (unformat (input, "ignore-tag2"))
9018         ignore_tag2 = 1;
9019       else if (unformat (input, "cos1"))
9020         cos1 = 1;
9021       else if (unformat (input, "cos2"))
9022         cos2 = 1;
9023       else if (unformat (input, "dot1q"))
9024         dot1q = 1;
9025       else if (unformat (input, "dot1ad"))
9026         dot1ad = 1;
9027       else
9028         break;
9029     }
9030   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9031        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9032     return 0;
9033
9034   if (tag1 || ignore_tag1 || cos1 || dot1q)
9035     len = 18;
9036   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9037     len = 22;
9038
9039   vec_validate (mask, len - 1);
9040
9041   if (dst)
9042     memset (mask, 0xff, 6);
9043
9044   if (src)
9045     memset (mask + 6, 0xff, 6);
9046
9047   if (tag2 || dot1ad)
9048     {
9049       /* inner vlan tag */
9050       if (tag2)
9051         {
9052           mask[19] = 0xff;
9053           mask[18] = 0x0f;
9054         }
9055       if (cos2)
9056         mask[18] |= 0xe0;
9057       if (proto)
9058         mask[21] = mask[20] = 0xff;
9059       if (tag1)
9060         {
9061           mask[15] = 0xff;
9062           mask[14] = 0x0f;
9063         }
9064       if (cos1)
9065         mask[14] |= 0xe0;
9066       *maskp = mask;
9067       return 1;
9068     }
9069   if (tag1 | dot1q)
9070     {
9071       if (tag1)
9072         {
9073           mask[15] = 0xff;
9074           mask[14] = 0x0f;
9075         }
9076       if (cos1)
9077         mask[14] |= 0xe0;
9078       if (proto)
9079         mask[16] = mask[17] = 0xff;
9080
9081       *maskp = mask;
9082       return 1;
9083     }
9084   if (cos2)
9085     mask[18] |= 0xe0;
9086   if (cos1)
9087     mask[14] |= 0xe0;
9088   if (proto)
9089     mask[12] = mask[13] = 0xff;
9090
9091   *maskp = mask;
9092   return 1;
9093 }
9094
9095 uword
9096 unformat_classify_mask (unformat_input_t * input, va_list * args)
9097 {
9098   u8 **maskp = va_arg (*args, u8 **);
9099   u32 *skipp = va_arg (*args, u32 *);
9100   u32 *matchp = va_arg (*args, u32 *);
9101   u32 match;
9102   u8 *mask = 0;
9103   u8 *l2 = 0;
9104   u8 *l3 = 0;
9105   u8 *l4 = 0;
9106   int i;
9107
9108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9109     {
9110       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9111         ;
9112       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9113         ;
9114       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9115         ;
9116       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9117         ;
9118       else
9119         break;
9120     }
9121
9122   if (l4 && !l3)
9123     {
9124       vec_free (mask);
9125       vec_free (l2);
9126       vec_free (l4);
9127       return 0;
9128     }
9129
9130   if (mask || l2 || l3 || l4)
9131     {
9132       if (l2 || l3 || l4)
9133         {
9134           /* "With a free Ethernet header in every package" */
9135           if (l2 == 0)
9136             vec_validate (l2, 13);
9137           mask = l2;
9138           if (vec_len (l3))
9139             {
9140               vec_append (mask, l3);
9141               vec_free (l3);
9142             }
9143           if (vec_len (l4))
9144             {
9145               vec_append (mask, l4);
9146               vec_free (l4);
9147             }
9148         }
9149
9150       /* Scan forward looking for the first significant mask octet */
9151       for (i = 0; i < vec_len (mask); i++)
9152         if (mask[i])
9153           break;
9154
9155       /* compute (skip, match) params */
9156       *skipp = i / sizeof (u32x4);
9157       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9158
9159       /* Pad mask to an even multiple of the vector size */
9160       while (vec_len (mask) % sizeof (u32x4))
9161         vec_add1 (mask, 0);
9162
9163       match = vec_len (mask) / sizeof (u32x4);
9164
9165       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9166         {
9167           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9168           if (*tmp || *(tmp + 1))
9169             break;
9170           match--;
9171         }
9172       if (match == 0)
9173         clib_warning ("BUG: match 0");
9174
9175       _vec_len (mask) = match * sizeof (u32x4);
9176
9177       *matchp = match;
9178       *maskp = mask;
9179
9180       return 1;
9181     }
9182
9183   return 0;
9184 }
9185
9186 #define foreach_l2_next                         \
9187 _(drop, DROP)                                   \
9188 _(ethernet, ETHERNET_INPUT)                     \
9189 _(ip4, IP4_INPUT)                               \
9190 _(ip6, IP6_INPUT)
9191
9192 uword
9193 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9194 {
9195   u32 *miss_next_indexp = va_arg (*args, u32 *);
9196   u32 next_index = 0;
9197   u32 tmp;
9198
9199 #define _(n,N) \
9200   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9201   foreach_l2_next;
9202 #undef _
9203
9204   if (unformat (input, "%d", &tmp))
9205     {
9206       next_index = tmp;
9207       goto out;
9208     }
9209
9210   return 0;
9211
9212 out:
9213   *miss_next_indexp = next_index;
9214   return 1;
9215 }
9216
9217 #define foreach_ip_next                         \
9218 _(drop, DROP)                                   \
9219 _(local, LOCAL)                                 \
9220 _(rewrite, REWRITE)
9221
9222 uword
9223 unformat_ip_next_index (unformat_input_t * input, va_list * args)
9224 {
9225   u32 *miss_next_indexp = va_arg (*args, u32 *);
9226   u32 next_index = 0;
9227   u32 tmp;
9228
9229 #define _(n,N) \
9230   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9231   foreach_ip_next;
9232 #undef _
9233
9234   if (unformat (input, "%d", &tmp))
9235     {
9236       next_index = tmp;
9237       goto out;
9238     }
9239
9240   return 0;
9241
9242 out:
9243   *miss_next_indexp = next_index;
9244   return 1;
9245 }
9246
9247 #define foreach_acl_next                        \
9248 _(deny, DENY)
9249
9250 uword
9251 unformat_acl_next_index (unformat_input_t * input, va_list * args)
9252 {
9253   u32 *miss_next_indexp = va_arg (*args, u32 *);
9254   u32 next_index = 0;
9255   u32 tmp;
9256
9257 #define _(n,N) \
9258   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9259   foreach_acl_next;
9260 #undef _
9261
9262   if (unformat (input, "permit"))
9263     {
9264       next_index = ~0;
9265       goto out;
9266     }
9267   else if (unformat (input, "%d", &tmp))
9268     {
9269       next_index = tmp;
9270       goto out;
9271     }
9272
9273   return 0;
9274
9275 out:
9276   *miss_next_indexp = next_index;
9277   return 1;
9278 }
9279
9280 uword
9281 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9282 {
9283   u32 *r = va_arg (*args, u32 *);
9284
9285   if (unformat (input, "conform-color"))
9286     *r = POLICE_CONFORM;
9287   else if (unformat (input, "exceed-color"))
9288     *r = POLICE_EXCEED;
9289   else
9290     return 0;
9291
9292   return 1;
9293 }
9294
9295 static int
9296 api_classify_add_del_table (vat_main_t * vam)
9297 {
9298   unformat_input_t *i = vam->input;
9299   vl_api_classify_add_del_table_t *mp;
9300
9301   u32 nbuckets = 2;
9302   u32 skip = ~0;
9303   u32 match = ~0;
9304   int is_add = 1;
9305   int del_chain = 0;
9306   u32 table_index = ~0;
9307   u32 next_table_index = ~0;
9308   u32 miss_next_index = ~0;
9309   u32 memory_size = 32 << 20;
9310   u8 *mask = 0;
9311   u32 current_data_flag = 0;
9312   int current_data_offset = 0;
9313   int ret;
9314
9315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9316     {
9317       if (unformat (i, "del"))
9318         is_add = 0;
9319       else if (unformat (i, "del-chain"))
9320         {
9321           is_add = 0;
9322           del_chain = 1;
9323         }
9324       else if (unformat (i, "buckets %d", &nbuckets))
9325         ;
9326       else if (unformat (i, "memory_size %d", &memory_size))
9327         ;
9328       else if (unformat (i, "skip %d", &skip))
9329         ;
9330       else if (unformat (i, "match %d", &match))
9331         ;
9332       else if (unformat (i, "table %d", &table_index))
9333         ;
9334       else if (unformat (i, "mask %U", unformat_classify_mask,
9335                          &mask, &skip, &match))
9336         ;
9337       else if (unformat (i, "next-table %d", &next_table_index))
9338         ;
9339       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
9340                          &miss_next_index))
9341         ;
9342       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9343                          &miss_next_index))
9344         ;
9345       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9346                          &miss_next_index))
9347         ;
9348       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9349         ;
9350       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9351         ;
9352       else
9353         break;
9354     }
9355
9356   if (is_add && mask == 0)
9357     {
9358       errmsg ("Mask required");
9359       return -99;
9360     }
9361
9362   if (is_add && skip == ~0)
9363     {
9364       errmsg ("skip count required");
9365       return -99;
9366     }
9367
9368   if (is_add && match == ~0)
9369     {
9370       errmsg ("match count required");
9371       return -99;
9372     }
9373
9374   if (!is_add && table_index == ~0)
9375     {
9376       errmsg ("table index required for delete");
9377       return -99;
9378     }
9379
9380   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9381
9382   mp->is_add = is_add;
9383   mp->del_chain = del_chain;
9384   mp->table_index = ntohl (table_index);
9385   mp->nbuckets = ntohl (nbuckets);
9386   mp->memory_size = ntohl (memory_size);
9387   mp->skip_n_vectors = ntohl (skip);
9388   mp->match_n_vectors = ntohl (match);
9389   mp->next_table_index = ntohl (next_table_index);
9390   mp->miss_next_index = ntohl (miss_next_index);
9391   mp->current_data_flag = ntohl (current_data_flag);
9392   mp->current_data_offset = ntohl (current_data_offset);
9393   clib_memcpy (mp->mask, mask, vec_len (mask));
9394
9395   vec_free (mask);
9396
9397   S (mp);
9398   W (ret);
9399   return ret;
9400 }
9401
9402 uword
9403 unformat_l4_match (unformat_input_t * input, va_list * args)
9404 {
9405   u8 **matchp = va_arg (*args, u8 **);
9406
9407   u8 *proto_header = 0;
9408   int src_port = 0;
9409   int dst_port = 0;
9410
9411   tcpudp_header_t h;
9412
9413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9414     {
9415       if (unformat (input, "src_port %d", &src_port))
9416         ;
9417       else if (unformat (input, "dst_port %d", &dst_port))
9418         ;
9419       else
9420         return 0;
9421     }
9422
9423   h.src_port = clib_host_to_net_u16 (src_port);
9424   h.dst_port = clib_host_to_net_u16 (dst_port);
9425   vec_validate (proto_header, sizeof (h) - 1);
9426   memcpy (proto_header, &h, sizeof (h));
9427
9428   *matchp = proto_header;
9429
9430   return 1;
9431 }
9432
9433 uword
9434 unformat_ip4_match (unformat_input_t * input, va_list * args)
9435 {
9436   u8 **matchp = va_arg (*args, u8 **);
9437   u8 *match = 0;
9438   ip4_header_t *ip;
9439   int version = 0;
9440   u32 version_val;
9441   int hdr_length = 0;
9442   u32 hdr_length_val;
9443   int src = 0, dst = 0;
9444   ip4_address_t src_val, dst_val;
9445   int proto = 0;
9446   u32 proto_val;
9447   int tos = 0;
9448   u32 tos_val;
9449   int length = 0;
9450   u32 length_val;
9451   int fragment_id = 0;
9452   u32 fragment_id_val;
9453   int ttl = 0;
9454   int ttl_val;
9455   int checksum = 0;
9456   u32 checksum_val;
9457
9458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9459     {
9460       if (unformat (input, "version %d", &version_val))
9461         version = 1;
9462       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9463         hdr_length = 1;
9464       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9465         src = 1;
9466       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9467         dst = 1;
9468       else if (unformat (input, "proto %d", &proto_val))
9469         proto = 1;
9470       else if (unformat (input, "tos %d", &tos_val))
9471         tos = 1;
9472       else if (unformat (input, "length %d", &length_val))
9473         length = 1;
9474       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9475         fragment_id = 1;
9476       else if (unformat (input, "ttl %d", &ttl_val))
9477         ttl = 1;
9478       else if (unformat (input, "checksum %d", &checksum_val))
9479         checksum = 1;
9480       else
9481         break;
9482     }
9483
9484   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9485       + ttl + checksum == 0)
9486     return 0;
9487
9488   /*
9489    * Aligned because we use the real comparison functions
9490    */
9491   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9492
9493   ip = (ip4_header_t *) match;
9494
9495   /* These are realistically matched in practice */
9496   if (src)
9497     ip->src_address.as_u32 = src_val.as_u32;
9498
9499   if (dst)
9500     ip->dst_address.as_u32 = dst_val.as_u32;
9501
9502   if (proto)
9503     ip->protocol = proto_val;
9504
9505
9506   /* These are not, but they're included for completeness */
9507   if (version)
9508     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9509
9510   if (hdr_length)
9511     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9512
9513   if (tos)
9514     ip->tos = tos_val;
9515
9516   if (length)
9517     ip->length = clib_host_to_net_u16 (length_val);
9518
9519   if (ttl)
9520     ip->ttl = ttl_val;
9521
9522   if (checksum)
9523     ip->checksum = clib_host_to_net_u16 (checksum_val);
9524
9525   *matchp = match;
9526   return 1;
9527 }
9528
9529 uword
9530 unformat_ip6_match (unformat_input_t * input, va_list * args)
9531 {
9532   u8 **matchp = va_arg (*args, u8 **);
9533   u8 *match = 0;
9534   ip6_header_t *ip;
9535   int version = 0;
9536   u32 version_val;
9537   u8 traffic_class = 0;
9538   u32 traffic_class_val = 0;
9539   u8 flow_label = 0;
9540   u8 flow_label_val;
9541   int src = 0, dst = 0;
9542   ip6_address_t src_val, dst_val;
9543   int proto = 0;
9544   u32 proto_val;
9545   int payload_length = 0;
9546   u32 payload_length_val;
9547   int hop_limit = 0;
9548   int hop_limit_val;
9549   u32 ip_version_traffic_class_and_flow_label;
9550
9551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9552     {
9553       if (unformat (input, "version %d", &version_val))
9554         version = 1;
9555       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9556         traffic_class = 1;
9557       else if (unformat (input, "flow_label %d", &flow_label_val))
9558         flow_label = 1;
9559       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9560         src = 1;
9561       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9562         dst = 1;
9563       else if (unformat (input, "proto %d", &proto_val))
9564         proto = 1;
9565       else if (unformat (input, "payload_length %d", &payload_length_val))
9566         payload_length = 1;
9567       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9568         hop_limit = 1;
9569       else
9570         break;
9571     }
9572
9573   if (version + traffic_class + flow_label + src + dst + proto +
9574       payload_length + hop_limit == 0)
9575     return 0;
9576
9577   /*
9578    * Aligned because we use the real comparison functions
9579    */
9580   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9581
9582   ip = (ip6_header_t *) match;
9583
9584   if (src)
9585     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9586
9587   if (dst)
9588     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9589
9590   if (proto)
9591     ip->protocol = proto_val;
9592
9593   ip_version_traffic_class_and_flow_label = 0;
9594
9595   if (version)
9596     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9597
9598   if (traffic_class)
9599     ip_version_traffic_class_and_flow_label |=
9600       (traffic_class_val & 0xFF) << 20;
9601
9602   if (flow_label)
9603     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9604
9605   ip->ip_version_traffic_class_and_flow_label =
9606     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9607
9608   if (payload_length)
9609     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9610
9611   if (hop_limit)
9612     ip->hop_limit = hop_limit_val;
9613
9614   *matchp = match;
9615   return 1;
9616 }
9617
9618 uword
9619 unformat_l3_match (unformat_input_t * input, va_list * args)
9620 {
9621   u8 **matchp = va_arg (*args, u8 **);
9622
9623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9624     {
9625       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9626         return 1;
9627       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9628         return 1;
9629       else
9630         break;
9631     }
9632   return 0;
9633 }
9634
9635 uword
9636 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9637 {
9638   u8 *tagp = va_arg (*args, u8 *);
9639   u32 tag;
9640
9641   if (unformat (input, "%d", &tag))
9642     {
9643       tagp[0] = (tag >> 8) & 0x0F;
9644       tagp[1] = tag & 0xFF;
9645       return 1;
9646     }
9647
9648   return 0;
9649 }
9650
9651 uword
9652 unformat_l2_match (unformat_input_t * input, va_list * args)
9653 {
9654   u8 **matchp = va_arg (*args, u8 **);
9655   u8 *match = 0;
9656   u8 src = 0;
9657   u8 src_val[6];
9658   u8 dst = 0;
9659   u8 dst_val[6];
9660   u8 proto = 0;
9661   u16 proto_val;
9662   u8 tag1 = 0;
9663   u8 tag1_val[2];
9664   u8 tag2 = 0;
9665   u8 tag2_val[2];
9666   int len = 14;
9667   u8 ignore_tag1 = 0;
9668   u8 ignore_tag2 = 0;
9669   u8 cos1 = 0;
9670   u8 cos2 = 0;
9671   u32 cos1_val = 0;
9672   u32 cos2_val = 0;
9673
9674   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9675     {
9676       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9677         src = 1;
9678       else
9679         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9680         dst = 1;
9681       else if (unformat (input, "proto %U",
9682                          unformat_ethernet_type_host_byte_order, &proto_val))
9683         proto = 1;
9684       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9685         tag1 = 1;
9686       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9687         tag2 = 1;
9688       else if (unformat (input, "ignore-tag1"))
9689         ignore_tag1 = 1;
9690       else if (unformat (input, "ignore-tag2"))
9691         ignore_tag2 = 1;
9692       else if (unformat (input, "cos1 %d", &cos1_val))
9693         cos1 = 1;
9694       else if (unformat (input, "cos2 %d", &cos2_val))
9695         cos2 = 1;
9696       else
9697         break;
9698     }
9699   if ((src + dst + proto + tag1 + tag2 +
9700        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9701     return 0;
9702
9703   if (tag1 || ignore_tag1 || cos1)
9704     len = 18;
9705   if (tag2 || ignore_tag2 || cos2)
9706     len = 22;
9707
9708   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9709
9710   if (dst)
9711     clib_memcpy (match, dst_val, 6);
9712
9713   if (src)
9714     clib_memcpy (match + 6, src_val, 6);
9715
9716   if (tag2)
9717     {
9718       /* inner vlan tag */
9719       match[19] = tag2_val[1];
9720       match[18] = tag2_val[0];
9721       if (cos2)
9722         match[18] |= (cos2_val & 0x7) << 5;
9723       if (proto)
9724         {
9725           match[21] = proto_val & 0xff;
9726           match[20] = proto_val >> 8;
9727         }
9728       if (tag1)
9729         {
9730           match[15] = tag1_val[1];
9731           match[14] = tag1_val[0];
9732         }
9733       if (cos1)
9734         match[14] |= (cos1_val & 0x7) << 5;
9735       *matchp = match;
9736       return 1;
9737     }
9738   if (tag1)
9739     {
9740       match[15] = tag1_val[1];
9741       match[14] = tag1_val[0];
9742       if (proto)
9743         {
9744           match[17] = proto_val & 0xff;
9745           match[16] = proto_val >> 8;
9746         }
9747       if (cos1)
9748         match[14] |= (cos1_val & 0x7) << 5;
9749
9750       *matchp = match;
9751       return 1;
9752     }
9753   if (cos2)
9754     match[18] |= (cos2_val & 0x7) << 5;
9755   if (cos1)
9756     match[14] |= (cos1_val & 0x7) << 5;
9757   if (proto)
9758     {
9759       match[13] = proto_val & 0xff;
9760       match[12] = proto_val >> 8;
9761     }
9762
9763   *matchp = match;
9764   return 1;
9765 }
9766
9767
9768 uword
9769 unformat_classify_match (unformat_input_t * input, va_list * args)
9770 {
9771   u8 **matchp = va_arg (*args, u8 **);
9772   u32 skip_n_vectors = va_arg (*args, u32);
9773   u32 match_n_vectors = va_arg (*args, u32);
9774
9775   u8 *match = 0;
9776   u8 *l2 = 0;
9777   u8 *l3 = 0;
9778   u8 *l4 = 0;
9779
9780   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9781     {
9782       if (unformat (input, "hex %U", unformat_hex_string, &match))
9783         ;
9784       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9785         ;
9786       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9787         ;
9788       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9789         ;
9790       else
9791         break;
9792     }
9793
9794   if (l4 && !l3)
9795     {
9796       vec_free (match);
9797       vec_free (l2);
9798       vec_free (l4);
9799       return 0;
9800     }
9801
9802   if (match || l2 || l3 || l4)
9803     {
9804       if (l2 || l3 || l4)
9805         {
9806           /* "Win a free Ethernet header in every packet" */
9807           if (l2 == 0)
9808             vec_validate_aligned (l2, 13, sizeof (u32x4));
9809           match = l2;
9810           if (vec_len (l3))
9811             {
9812               vec_append_aligned (match, l3, sizeof (u32x4));
9813               vec_free (l3);
9814             }
9815           if (vec_len (l4))
9816             {
9817               vec_append_aligned (match, l4, sizeof (u32x4));
9818               vec_free (l4);
9819             }
9820         }
9821
9822       /* Make sure the vector is big enough even if key is all 0's */
9823       vec_validate_aligned
9824         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9825          sizeof (u32x4));
9826
9827       /* Set size, include skipped vectors */
9828       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9829
9830       *matchp = match;
9831
9832       return 1;
9833     }
9834
9835   return 0;
9836 }
9837
9838 static int
9839 api_classify_add_del_session (vat_main_t * vam)
9840 {
9841   unformat_input_t *i = vam->input;
9842   vl_api_classify_add_del_session_t *mp;
9843   int is_add = 1;
9844   u32 table_index = ~0;
9845   u32 hit_next_index = ~0;
9846   u32 opaque_index = ~0;
9847   u8 *match = 0;
9848   i32 advance = 0;
9849   u32 skip_n_vectors = 0;
9850   u32 match_n_vectors = 0;
9851   u32 action = 0;
9852   u32 metadata = 0;
9853   int ret;
9854
9855   /*
9856    * Warning: you have to supply skip_n and match_n
9857    * because the API client cant simply look at the classify
9858    * table object.
9859    */
9860
9861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9862     {
9863       if (unformat (i, "del"))
9864         is_add = 0;
9865       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9866                          &hit_next_index))
9867         ;
9868       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9869                          &hit_next_index))
9870         ;
9871       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9872                          &hit_next_index))
9873         ;
9874       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9875         ;
9876       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9877         ;
9878       else if (unformat (i, "opaque-index %d", &opaque_index))
9879         ;
9880       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9881         ;
9882       else if (unformat (i, "match_n %d", &match_n_vectors))
9883         ;
9884       else if (unformat (i, "match %U", unformat_classify_match,
9885                          &match, skip_n_vectors, match_n_vectors))
9886         ;
9887       else if (unformat (i, "advance %d", &advance))
9888         ;
9889       else if (unformat (i, "table-index %d", &table_index))
9890         ;
9891       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9892         action = 1;
9893       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9894         action = 2;
9895       else if (unformat (i, "action %d", &action))
9896         ;
9897       else if (unformat (i, "metadata %d", &metadata))
9898         ;
9899       else
9900         break;
9901     }
9902
9903   if (table_index == ~0)
9904     {
9905       errmsg ("Table index required");
9906       return -99;
9907     }
9908
9909   if (is_add && match == 0)
9910     {
9911       errmsg ("Match value required");
9912       return -99;
9913     }
9914
9915   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9916
9917   mp->is_add = is_add;
9918   mp->table_index = ntohl (table_index);
9919   mp->hit_next_index = ntohl (hit_next_index);
9920   mp->opaque_index = ntohl (opaque_index);
9921   mp->advance = ntohl (advance);
9922   mp->action = action;
9923   mp->metadata = ntohl (metadata);
9924   clib_memcpy (mp->match, match, vec_len (match));
9925   vec_free (match);
9926
9927   S (mp);
9928   W (ret);
9929   return ret;
9930 }
9931
9932 static int
9933 api_classify_set_interface_ip_table (vat_main_t * vam)
9934 {
9935   unformat_input_t *i = vam->input;
9936   vl_api_classify_set_interface_ip_table_t *mp;
9937   u32 sw_if_index;
9938   int sw_if_index_set;
9939   u32 table_index = ~0;
9940   u8 is_ipv6 = 0;
9941   int ret;
9942
9943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9944     {
9945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9946         sw_if_index_set = 1;
9947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9948         sw_if_index_set = 1;
9949       else if (unformat (i, "table %d", &table_index))
9950         ;
9951       else
9952         {
9953           clib_warning ("parse error '%U'", format_unformat_error, i);
9954           return -99;
9955         }
9956     }
9957
9958   if (sw_if_index_set == 0)
9959     {
9960       errmsg ("missing interface name or sw_if_index");
9961       return -99;
9962     }
9963
9964
9965   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9966
9967   mp->sw_if_index = ntohl (sw_if_index);
9968   mp->table_index = ntohl (table_index);
9969   mp->is_ipv6 = is_ipv6;
9970
9971   S (mp);
9972   W (ret);
9973   return ret;
9974 }
9975
9976 static int
9977 api_classify_set_interface_l2_tables (vat_main_t * vam)
9978 {
9979   unformat_input_t *i = vam->input;
9980   vl_api_classify_set_interface_l2_tables_t *mp;
9981   u32 sw_if_index;
9982   int sw_if_index_set;
9983   u32 ip4_table_index = ~0;
9984   u32 ip6_table_index = ~0;
9985   u32 other_table_index = ~0;
9986   u32 is_input = 1;
9987   int ret;
9988
9989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9990     {
9991       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9992         sw_if_index_set = 1;
9993       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9994         sw_if_index_set = 1;
9995       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9996         ;
9997       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9998         ;
9999       else if (unformat (i, "other-table %d", &other_table_index))
10000         ;
10001       else if (unformat (i, "is-input %d", &is_input))
10002         ;
10003       else
10004         {
10005           clib_warning ("parse error '%U'", format_unformat_error, i);
10006           return -99;
10007         }
10008     }
10009
10010   if (sw_if_index_set == 0)
10011     {
10012       errmsg ("missing interface name or sw_if_index");
10013       return -99;
10014     }
10015
10016
10017   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10018
10019   mp->sw_if_index = ntohl (sw_if_index);
10020   mp->ip4_table_index = ntohl (ip4_table_index);
10021   mp->ip6_table_index = ntohl (ip6_table_index);
10022   mp->other_table_index = ntohl (other_table_index);
10023   mp->is_input = (u8) is_input;
10024
10025   S (mp);
10026   W (ret);
10027   return ret;
10028 }
10029
10030 static int
10031 api_set_ipfix_exporter (vat_main_t * vam)
10032 {
10033   unformat_input_t *i = vam->input;
10034   vl_api_set_ipfix_exporter_t *mp;
10035   ip4_address_t collector_address;
10036   u8 collector_address_set = 0;
10037   u32 collector_port = ~0;
10038   ip4_address_t src_address;
10039   u8 src_address_set = 0;
10040   u32 vrf_id = ~0;
10041   u32 path_mtu = ~0;
10042   u32 template_interval = ~0;
10043   u8 udp_checksum = 0;
10044   int ret;
10045
10046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10047     {
10048       if (unformat (i, "collector_address %U", unformat_ip4_address,
10049                     &collector_address))
10050         collector_address_set = 1;
10051       else if (unformat (i, "collector_port %d", &collector_port))
10052         ;
10053       else if (unformat (i, "src_address %U", unformat_ip4_address,
10054                          &src_address))
10055         src_address_set = 1;
10056       else if (unformat (i, "vrf_id %d", &vrf_id))
10057         ;
10058       else if (unformat (i, "path_mtu %d", &path_mtu))
10059         ;
10060       else if (unformat (i, "template_interval %d", &template_interval))
10061         ;
10062       else if (unformat (i, "udp_checksum"))
10063         udp_checksum = 1;
10064       else
10065         break;
10066     }
10067
10068   if (collector_address_set == 0)
10069     {
10070       errmsg ("collector_address required");
10071       return -99;
10072     }
10073
10074   if (src_address_set == 0)
10075     {
10076       errmsg ("src_address required");
10077       return -99;
10078     }
10079
10080   M (SET_IPFIX_EXPORTER, mp);
10081
10082   memcpy (mp->collector_address, collector_address.data,
10083           sizeof (collector_address.data));
10084   mp->collector_port = htons ((u16) collector_port);
10085   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10086   mp->vrf_id = htonl (vrf_id);
10087   mp->path_mtu = htonl (path_mtu);
10088   mp->template_interval = htonl (template_interval);
10089   mp->udp_checksum = udp_checksum;
10090
10091   S (mp);
10092   W (ret);
10093   return ret;
10094 }
10095
10096 static int
10097 api_set_ipfix_classify_stream (vat_main_t * vam)
10098 {
10099   unformat_input_t *i = vam->input;
10100   vl_api_set_ipfix_classify_stream_t *mp;
10101   u32 domain_id = 0;
10102   u32 src_port = UDP_DST_PORT_ipfix;
10103   int ret;
10104
10105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10106     {
10107       if (unformat (i, "domain %d", &domain_id))
10108         ;
10109       else if (unformat (i, "src_port %d", &src_port))
10110         ;
10111       else
10112         {
10113           errmsg ("unknown input `%U'", format_unformat_error, i);
10114           return -99;
10115         }
10116     }
10117
10118   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10119
10120   mp->domain_id = htonl (domain_id);
10121   mp->src_port = htons ((u16) src_port);
10122
10123   S (mp);
10124   W (ret);
10125   return ret;
10126 }
10127
10128 static int
10129 api_ipfix_classify_table_add_del (vat_main_t * vam)
10130 {
10131   unformat_input_t *i = vam->input;
10132   vl_api_ipfix_classify_table_add_del_t *mp;
10133   int is_add = -1;
10134   u32 classify_table_index = ~0;
10135   u8 ip_version = 0;
10136   u8 transport_protocol = 255;
10137   int ret;
10138
10139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10140     {
10141       if (unformat (i, "add"))
10142         is_add = 1;
10143       else if (unformat (i, "del"))
10144         is_add = 0;
10145       else if (unformat (i, "table %d", &classify_table_index))
10146         ;
10147       else if (unformat (i, "ip4"))
10148         ip_version = 4;
10149       else if (unformat (i, "ip6"))
10150         ip_version = 6;
10151       else if (unformat (i, "tcp"))
10152         transport_protocol = 6;
10153       else if (unformat (i, "udp"))
10154         transport_protocol = 17;
10155       else
10156         {
10157           errmsg ("unknown input `%U'", format_unformat_error, i);
10158           return -99;
10159         }
10160     }
10161
10162   if (is_add == -1)
10163     {
10164       errmsg ("expecting: add|del");
10165       return -99;
10166     }
10167   if (classify_table_index == ~0)
10168     {
10169       errmsg ("classifier table not specified");
10170       return -99;
10171     }
10172   if (ip_version == 0)
10173     {
10174       errmsg ("IP version not specified");
10175       return -99;
10176     }
10177
10178   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10179
10180   mp->is_add = is_add;
10181   mp->table_id = htonl (classify_table_index);
10182   mp->ip_version = ip_version;
10183   mp->transport_protocol = transport_protocol;
10184
10185   S (mp);
10186   W (ret);
10187   return ret;
10188 }
10189
10190 static int
10191 api_get_node_index (vat_main_t * vam)
10192 {
10193   unformat_input_t *i = vam->input;
10194   vl_api_get_node_index_t *mp;
10195   u8 *name = 0;
10196   int ret;
10197
10198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10199     {
10200       if (unformat (i, "node %s", &name))
10201         ;
10202       else
10203         break;
10204     }
10205   if (name == 0)
10206     {
10207       errmsg ("node name required");
10208       return -99;
10209     }
10210   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10211     {
10212       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10213       return -99;
10214     }
10215
10216   M (GET_NODE_INDEX, mp);
10217   clib_memcpy (mp->node_name, name, vec_len (name));
10218   vec_free (name);
10219
10220   S (mp);
10221   W (ret);
10222   return ret;
10223 }
10224
10225 static int
10226 api_get_next_index (vat_main_t * vam)
10227 {
10228   unformat_input_t *i = vam->input;
10229   vl_api_get_next_index_t *mp;
10230   u8 *node_name = 0, *next_node_name = 0;
10231   int ret;
10232
10233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10234     {
10235       if (unformat (i, "node-name %s", &node_name))
10236         ;
10237       else if (unformat (i, "next-node-name %s", &next_node_name))
10238         break;
10239     }
10240
10241   if (node_name == 0)
10242     {
10243       errmsg ("node name required");
10244       return -99;
10245     }
10246   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10247     {
10248       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10249       return -99;
10250     }
10251
10252   if (next_node_name == 0)
10253     {
10254       errmsg ("next node name required");
10255       return -99;
10256     }
10257   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10258     {
10259       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10260       return -99;
10261     }
10262
10263   M (GET_NEXT_INDEX, mp);
10264   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10265   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10266   vec_free (node_name);
10267   vec_free (next_node_name);
10268
10269   S (mp);
10270   W (ret);
10271   return ret;
10272 }
10273
10274 static int
10275 api_add_node_next (vat_main_t * vam)
10276 {
10277   unformat_input_t *i = vam->input;
10278   vl_api_add_node_next_t *mp;
10279   u8 *name = 0;
10280   u8 *next = 0;
10281   int ret;
10282
10283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10284     {
10285       if (unformat (i, "node %s", &name))
10286         ;
10287       else if (unformat (i, "next %s", &next))
10288         ;
10289       else
10290         break;
10291     }
10292   if (name == 0)
10293     {
10294       errmsg ("node name required");
10295       return -99;
10296     }
10297   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10298     {
10299       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10300       return -99;
10301     }
10302   if (next == 0)
10303     {
10304       errmsg ("next node required");
10305       return -99;
10306     }
10307   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10308     {
10309       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10310       return -99;
10311     }
10312
10313   M (ADD_NODE_NEXT, mp);
10314   clib_memcpy (mp->node_name, name, vec_len (name));
10315   clib_memcpy (mp->next_name, next, vec_len (next));
10316   vec_free (name);
10317   vec_free (next);
10318
10319   S (mp);
10320   W (ret);
10321   return ret;
10322 }
10323
10324 static int
10325 api_l2tpv3_create_tunnel (vat_main_t * vam)
10326 {
10327   unformat_input_t *i = vam->input;
10328   ip6_address_t client_address, our_address;
10329   int client_address_set = 0;
10330   int our_address_set = 0;
10331   u32 local_session_id = 0;
10332   u32 remote_session_id = 0;
10333   u64 local_cookie = 0;
10334   u64 remote_cookie = 0;
10335   u8 l2_sublayer_present = 0;
10336   vl_api_l2tpv3_create_tunnel_t *mp;
10337   int ret;
10338
10339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10340     {
10341       if (unformat (i, "client_address %U", unformat_ip6_address,
10342                     &client_address))
10343         client_address_set = 1;
10344       else if (unformat (i, "our_address %U", unformat_ip6_address,
10345                          &our_address))
10346         our_address_set = 1;
10347       else if (unformat (i, "local_session_id %d", &local_session_id))
10348         ;
10349       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10350         ;
10351       else if (unformat (i, "local_cookie %lld", &local_cookie))
10352         ;
10353       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10354         ;
10355       else if (unformat (i, "l2-sublayer-present"))
10356         l2_sublayer_present = 1;
10357       else
10358         break;
10359     }
10360
10361   if (client_address_set == 0)
10362     {
10363       errmsg ("client_address required");
10364       return -99;
10365     }
10366
10367   if (our_address_set == 0)
10368     {
10369       errmsg ("our_address required");
10370       return -99;
10371     }
10372
10373   M (L2TPV3_CREATE_TUNNEL, mp);
10374
10375   clib_memcpy (mp->client_address, client_address.as_u8,
10376                sizeof (mp->client_address));
10377
10378   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10379
10380   mp->local_session_id = ntohl (local_session_id);
10381   mp->remote_session_id = ntohl (remote_session_id);
10382   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10383   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10384   mp->l2_sublayer_present = l2_sublayer_present;
10385   mp->is_ipv6 = 1;
10386
10387   S (mp);
10388   W (ret);
10389   return ret;
10390 }
10391
10392 static int
10393 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10394 {
10395   unformat_input_t *i = vam->input;
10396   u32 sw_if_index;
10397   u8 sw_if_index_set = 0;
10398   u64 new_local_cookie = 0;
10399   u64 new_remote_cookie = 0;
10400   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10401   int ret;
10402
10403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10404     {
10405       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10406         sw_if_index_set = 1;
10407       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10408         sw_if_index_set = 1;
10409       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10410         ;
10411       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10412         ;
10413       else
10414         break;
10415     }
10416
10417   if (sw_if_index_set == 0)
10418     {
10419       errmsg ("missing interface name or sw_if_index");
10420       return -99;
10421     }
10422
10423   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10424
10425   mp->sw_if_index = ntohl (sw_if_index);
10426   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10427   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10428
10429   S (mp);
10430   W (ret);
10431   return ret;
10432 }
10433
10434 static int
10435 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10436 {
10437   unformat_input_t *i = vam->input;
10438   vl_api_l2tpv3_interface_enable_disable_t *mp;
10439   u32 sw_if_index;
10440   u8 sw_if_index_set = 0;
10441   u8 enable_disable = 1;
10442   int ret;
10443
10444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10445     {
10446       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10447         sw_if_index_set = 1;
10448       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10449         sw_if_index_set = 1;
10450       else if (unformat (i, "enable"))
10451         enable_disable = 1;
10452       else if (unformat (i, "disable"))
10453         enable_disable = 0;
10454       else
10455         break;
10456     }
10457
10458   if (sw_if_index_set == 0)
10459     {
10460       errmsg ("missing interface name or sw_if_index");
10461       return -99;
10462     }
10463
10464   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10465
10466   mp->sw_if_index = ntohl (sw_if_index);
10467   mp->enable_disable = enable_disable;
10468
10469   S (mp);
10470   W (ret);
10471   return ret;
10472 }
10473
10474 static int
10475 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10476 {
10477   unformat_input_t *i = vam->input;
10478   vl_api_l2tpv3_set_lookup_key_t *mp;
10479   u8 key = ~0;
10480   int ret;
10481
10482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10483     {
10484       if (unformat (i, "lookup_v6_src"))
10485         key = L2T_LOOKUP_SRC_ADDRESS;
10486       else if (unformat (i, "lookup_v6_dst"))
10487         key = L2T_LOOKUP_DST_ADDRESS;
10488       else if (unformat (i, "lookup_session_id"))
10489         key = L2T_LOOKUP_SESSION_ID;
10490       else
10491         break;
10492     }
10493
10494   if (key == (u8) ~ 0)
10495     {
10496       errmsg ("l2tp session lookup key unset");
10497       return -99;
10498     }
10499
10500   M (L2TPV3_SET_LOOKUP_KEY, mp);
10501
10502   mp->key = key;
10503
10504   S (mp);
10505   W (ret);
10506   return ret;
10507 }
10508
10509 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10510   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10511 {
10512   vat_main_t *vam = &vat_main;
10513
10514   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10515          format_ip6_address, mp->our_address,
10516          format_ip6_address, mp->client_address,
10517          clib_net_to_host_u32 (mp->sw_if_index));
10518
10519   print (vam->ofp,
10520          "   local cookies %016llx %016llx remote cookie %016llx",
10521          clib_net_to_host_u64 (mp->local_cookie[0]),
10522          clib_net_to_host_u64 (mp->local_cookie[1]),
10523          clib_net_to_host_u64 (mp->remote_cookie));
10524
10525   print (vam->ofp, "   local session-id %d remote session-id %d",
10526          clib_net_to_host_u32 (mp->local_session_id),
10527          clib_net_to_host_u32 (mp->remote_session_id));
10528
10529   print (vam->ofp, "   l2 specific sublayer %s\n",
10530          mp->l2_sublayer_present ? "preset" : "absent");
10531
10532 }
10533
10534 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10535   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10536 {
10537   vat_main_t *vam = &vat_main;
10538   vat_json_node_t *node = NULL;
10539   struct in6_addr addr;
10540
10541   if (VAT_JSON_ARRAY != vam->json_tree.type)
10542     {
10543       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10544       vat_json_init_array (&vam->json_tree);
10545     }
10546   node = vat_json_array_add (&vam->json_tree);
10547
10548   vat_json_init_object (node);
10549
10550   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10551   vat_json_object_add_ip6 (node, "our_address", addr);
10552   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10553   vat_json_object_add_ip6 (node, "client_address", addr);
10554
10555   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10556   vat_json_init_array (lc);
10557   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10558   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10559   vat_json_object_add_uint (node, "remote_cookie",
10560                             clib_net_to_host_u64 (mp->remote_cookie));
10561
10562   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10563   vat_json_object_add_uint (node, "local_session_id",
10564                             clib_net_to_host_u32 (mp->local_session_id));
10565   vat_json_object_add_uint (node, "remote_session_id",
10566                             clib_net_to_host_u32 (mp->remote_session_id));
10567   vat_json_object_add_string_copy (node, "l2_sublayer",
10568                                    mp->l2_sublayer_present ? (u8 *) "present"
10569                                    : (u8 *) "absent");
10570 }
10571
10572 static int
10573 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10574 {
10575   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10576   vl_api_control_ping_t *mp_ping;
10577   int ret;
10578
10579   /* Get list of l2tpv3-tunnel interfaces */
10580   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10581   S (mp);
10582
10583   /* Use a control ping for synchronization */
10584   M (CONTROL_PING, mp_ping);
10585   S (mp_ping);
10586
10587   W (ret);
10588   return ret;
10589 }
10590
10591
10592 static void vl_api_sw_interface_tap_details_t_handler
10593   (vl_api_sw_interface_tap_details_t * mp)
10594 {
10595   vat_main_t *vam = &vat_main;
10596
10597   print (vam->ofp, "%-16s %d",
10598          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10599 }
10600
10601 static void vl_api_sw_interface_tap_details_t_handler_json
10602   (vl_api_sw_interface_tap_details_t * mp)
10603 {
10604   vat_main_t *vam = &vat_main;
10605   vat_json_node_t *node = NULL;
10606
10607   if (VAT_JSON_ARRAY != vam->json_tree.type)
10608     {
10609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10610       vat_json_init_array (&vam->json_tree);
10611     }
10612   node = vat_json_array_add (&vam->json_tree);
10613
10614   vat_json_init_object (node);
10615   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10616   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10617 }
10618
10619 static int
10620 api_sw_interface_tap_dump (vat_main_t * vam)
10621 {
10622   vl_api_sw_interface_tap_dump_t *mp;
10623   vl_api_control_ping_t *mp_ping;
10624   int ret;
10625
10626   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10627   /* Get list of tap interfaces */
10628   M (SW_INTERFACE_TAP_DUMP, mp);
10629   S (mp);
10630
10631   /* Use a control ping for synchronization */
10632   M (CONTROL_PING, mp_ping);
10633   S (mp_ping);
10634
10635   W (ret);
10636   return ret;
10637 }
10638
10639 static uword unformat_vxlan_decap_next
10640   (unformat_input_t * input, va_list * args)
10641 {
10642   u32 *result = va_arg (*args, u32 *);
10643   u32 tmp;
10644
10645   if (unformat (input, "l2"))
10646     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10647   else if (unformat (input, "%d", &tmp))
10648     *result = tmp;
10649   else
10650     return 0;
10651   return 1;
10652 }
10653
10654 static int
10655 api_vxlan_add_del_tunnel (vat_main_t * vam)
10656 {
10657   unformat_input_t *line_input = vam->input;
10658   vl_api_vxlan_add_del_tunnel_t *mp;
10659   ip46_address_t src, dst;
10660   u8 is_add = 1;
10661   u8 ipv4_set = 0, ipv6_set = 0;
10662   u8 src_set = 0;
10663   u8 dst_set = 0;
10664   u8 grp_set = 0;
10665   u32 mcast_sw_if_index = ~0;
10666   u32 encap_vrf_id = 0;
10667   u32 decap_next_index = ~0;
10668   u32 vni = 0;
10669   int ret;
10670
10671   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10672   memset (&src, 0, sizeof src);
10673   memset (&dst, 0, sizeof dst);
10674
10675   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10676     {
10677       if (unformat (line_input, "del"))
10678         is_add = 0;
10679       else
10680         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10681         {
10682           ipv4_set = 1;
10683           src_set = 1;
10684         }
10685       else
10686         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10687         {
10688           ipv4_set = 1;
10689           dst_set = 1;
10690         }
10691       else
10692         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10693         {
10694           ipv6_set = 1;
10695           src_set = 1;
10696         }
10697       else
10698         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10699         {
10700           ipv6_set = 1;
10701           dst_set = 1;
10702         }
10703       else if (unformat (line_input, "group %U %U",
10704                          unformat_ip4_address, &dst.ip4,
10705                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10706         {
10707           grp_set = dst_set = 1;
10708           ipv4_set = 1;
10709         }
10710       else if (unformat (line_input, "group %U",
10711                          unformat_ip4_address, &dst.ip4))
10712         {
10713           grp_set = dst_set = 1;
10714           ipv4_set = 1;
10715         }
10716       else if (unformat (line_input, "group %U %U",
10717                          unformat_ip6_address, &dst.ip6,
10718                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10719         {
10720           grp_set = dst_set = 1;
10721           ipv6_set = 1;
10722         }
10723       else if (unformat (line_input, "group %U",
10724                          unformat_ip6_address, &dst.ip6))
10725         {
10726           grp_set = dst_set = 1;
10727           ipv6_set = 1;
10728         }
10729       else
10730         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10731         ;
10732       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10733         ;
10734       else if (unformat (line_input, "decap-next %U",
10735                          unformat_vxlan_decap_next, &decap_next_index))
10736         ;
10737       else if (unformat (line_input, "vni %d", &vni))
10738         ;
10739       else
10740         {
10741           errmsg ("parse error '%U'", format_unformat_error, line_input);
10742           return -99;
10743         }
10744     }
10745
10746   if (src_set == 0)
10747     {
10748       errmsg ("tunnel src address not specified");
10749       return -99;
10750     }
10751   if (dst_set == 0)
10752     {
10753       errmsg ("tunnel dst address not specified");
10754       return -99;
10755     }
10756
10757   if (grp_set && !ip46_address_is_multicast (&dst))
10758     {
10759       errmsg ("tunnel group address not multicast");
10760       return -99;
10761     }
10762   if (grp_set && mcast_sw_if_index == ~0)
10763     {
10764       errmsg ("tunnel nonexistent multicast device");
10765       return -99;
10766     }
10767   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10768     {
10769       errmsg ("tunnel dst address must be unicast");
10770       return -99;
10771     }
10772
10773
10774   if (ipv4_set && ipv6_set)
10775     {
10776       errmsg ("both IPv4 and IPv6 addresses specified");
10777       return -99;
10778     }
10779
10780   if ((vni == 0) || (vni >> 24))
10781     {
10782       errmsg ("vni not specified or out of range");
10783       return -99;
10784     }
10785
10786   M (VXLAN_ADD_DEL_TUNNEL, mp);
10787
10788   if (ipv6_set)
10789     {
10790       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10791       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10792     }
10793   else
10794     {
10795       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10796       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10797     }
10798   mp->encap_vrf_id = ntohl (encap_vrf_id);
10799   mp->decap_next_index = ntohl (decap_next_index);
10800   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10801   mp->vni = ntohl (vni);
10802   mp->is_add = is_add;
10803   mp->is_ipv6 = ipv6_set;
10804
10805   S (mp);
10806   W (ret);
10807   return ret;
10808 }
10809
10810 static void vl_api_vxlan_tunnel_details_t_handler
10811   (vl_api_vxlan_tunnel_details_t * mp)
10812 {
10813   vat_main_t *vam = &vat_main;
10814   ip46_address_t src, dst;
10815
10816   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10817   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10818
10819   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10820          ntohl (mp->sw_if_index),
10821          format_ip46_address, &src, IP46_TYPE_ANY,
10822          format_ip46_address, &dst, IP46_TYPE_ANY,
10823          ntohl (mp->encap_vrf_id),
10824          ntohl (mp->decap_next_index), ntohl (mp->vni),
10825          ntohl (mp->mcast_sw_if_index));
10826 }
10827
10828 static void vl_api_vxlan_tunnel_details_t_handler_json
10829   (vl_api_vxlan_tunnel_details_t * mp)
10830 {
10831   vat_main_t *vam = &vat_main;
10832   vat_json_node_t *node = NULL;
10833
10834   if (VAT_JSON_ARRAY != vam->json_tree.type)
10835     {
10836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10837       vat_json_init_array (&vam->json_tree);
10838     }
10839   node = vat_json_array_add (&vam->json_tree);
10840
10841   vat_json_init_object (node);
10842   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10843   if (mp->is_ipv6)
10844     {
10845       struct in6_addr ip6;
10846
10847       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10848       vat_json_object_add_ip6 (node, "src_address", ip6);
10849       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10850       vat_json_object_add_ip6 (node, "dst_address", ip6);
10851     }
10852   else
10853     {
10854       struct in_addr ip4;
10855
10856       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10857       vat_json_object_add_ip4 (node, "src_address", ip4);
10858       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10859       vat_json_object_add_ip4 (node, "dst_address", ip4);
10860     }
10861   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10862   vat_json_object_add_uint (node, "decap_next_index",
10863                             ntohl (mp->decap_next_index));
10864   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10865   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10866   vat_json_object_add_uint (node, "mcast_sw_if_index",
10867                             ntohl (mp->mcast_sw_if_index));
10868 }
10869
10870 static int
10871 api_vxlan_tunnel_dump (vat_main_t * vam)
10872 {
10873   unformat_input_t *i = vam->input;
10874   vl_api_vxlan_tunnel_dump_t *mp;
10875   vl_api_control_ping_t *mp_ping;
10876   u32 sw_if_index;
10877   u8 sw_if_index_set = 0;
10878   int ret;
10879
10880   /* Parse args required to build the message */
10881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10882     {
10883       if (unformat (i, "sw_if_index %d", &sw_if_index))
10884         sw_if_index_set = 1;
10885       else
10886         break;
10887     }
10888
10889   if (sw_if_index_set == 0)
10890     {
10891       sw_if_index = ~0;
10892     }
10893
10894   if (!vam->json_output)
10895     {
10896       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10897              "sw_if_index", "src_address", "dst_address",
10898              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10899     }
10900
10901   /* Get list of vxlan-tunnel interfaces */
10902   M (VXLAN_TUNNEL_DUMP, mp);
10903
10904   mp->sw_if_index = htonl (sw_if_index);
10905
10906   S (mp);
10907
10908   /* Use a control ping for synchronization */
10909   M (CONTROL_PING, mp_ping);
10910   S (mp_ping);
10911
10912   W (ret);
10913   return ret;
10914 }
10915
10916 static int
10917 api_gre_add_del_tunnel (vat_main_t * vam)
10918 {
10919   unformat_input_t *line_input = vam->input;
10920   vl_api_gre_add_del_tunnel_t *mp;
10921   ip4_address_t src4, dst4;
10922   u8 is_add = 1;
10923   u8 teb = 0;
10924   u8 src_set = 0;
10925   u8 dst_set = 0;
10926   u32 outer_fib_id = 0;
10927   int ret;
10928
10929   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10930     {
10931       if (unformat (line_input, "del"))
10932         is_add = 0;
10933       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10934         src_set = 1;
10935       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10936         dst_set = 1;
10937       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10938         ;
10939       else if (unformat (line_input, "teb"))
10940         teb = 1;
10941       else
10942         {
10943           errmsg ("parse error '%U'", format_unformat_error, line_input);
10944           return -99;
10945         }
10946     }
10947
10948   if (src_set == 0)
10949     {
10950       errmsg ("tunnel src address not specified");
10951       return -99;
10952     }
10953   if (dst_set == 0)
10954     {
10955       errmsg ("tunnel dst address not specified");
10956       return -99;
10957     }
10958
10959
10960   M (GRE_ADD_DEL_TUNNEL, mp);
10961
10962   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10963   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10964   mp->outer_fib_id = ntohl (outer_fib_id);
10965   mp->is_add = is_add;
10966   mp->teb = teb;
10967
10968   S (mp);
10969   W (ret);
10970   return ret;
10971 }
10972
10973 static void vl_api_gre_tunnel_details_t_handler
10974   (vl_api_gre_tunnel_details_t * mp)
10975 {
10976   vat_main_t *vam = &vat_main;
10977
10978   print (vam->ofp, "%11d%15U%15U%6d%14d",
10979          ntohl (mp->sw_if_index),
10980          format_ip4_address, &mp->src_address,
10981          format_ip4_address, &mp->dst_address,
10982          mp->teb, ntohl (mp->outer_fib_id));
10983 }
10984
10985 static void vl_api_gre_tunnel_details_t_handler_json
10986   (vl_api_gre_tunnel_details_t * mp)
10987 {
10988   vat_main_t *vam = &vat_main;
10989   vat_json_node_t *node = NULL;
10990   struct in_addr ip4;
10991
10992   if (VAT_JSON_ARRAY != vam->json_tree.type)
10993     {
10994       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10995       vat_json_init_array (&vam->json_tree);
10996     }
10997   node = vat_json_array_add (&vam->json_tree);
10998
10999   vat_json_init_object (node);
11000   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11001   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11002   vat_json_object_add_ip4 (node, "src_address", ip4);
11003   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11004   vat_json_object_add_ip4 (node, "dst_address", ip4);
11005   vat_json_object_add_uint (node, "teb", mp->teb);
11006   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11007 }
11008
11009 static int
11010 api_gre_tunnel_dump (vat_main_t * vam)
11011 {
11012   unformat_input_t *i = vam->input;
11013   vl_api_gre_tunnel_dump_t *mp;
11014   vl_api_control_ping_t *mp_ping;
11015   u32 sw_if_index;
11016   u8 sw_if_index_set = 0;
11017   int ret;
11018
11019   /* Parse args required to build the message */
11020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11021     {
11022       if (unformat (i, "sw_if_index %d", &sw_if_index))
11023         sw_if_index_set = 1;
11024       else
11025         break;
11026     }
11027
11028   if (sw_if_index_set == 0)
11029     {
11030       sw_if_index = ~0;
11031     }
11032
11033   if (!vam->json_output)
11034     {
11035       print (vam->ofp, "%11s%15s%15s%6s%14s",
11036              "sw_if_index", "src_address", "dst_address", "teb",
11037              "outer_fib_id");
11038     }
11039
11040   /* Get list of gre-tunnel interfaces */
11041   M (GRE_TUNNEL_DUMP, mp);
11042
11043   mp->sw_if_index = htonl (sw_if_index);
11044
11045   S (mp);
11046
11047   /* Use a control ping for synchronization */
11048   M (CONTROL_PING, mp_ping);
11049   S (mp_ping);
11050
11051   W (ret);
11052   return ret;
11053 }
11054
11055 static int
11056 api_l2_fib_clear_table (vat_main_t * vam)
11057 {
11058 //  unformat_input_t * i = vam->input;
11059   vl_api_l2_fib_clear_table_t *mp;
11060   int ret;
11061
11062   M (L2_FIB_CLEAR_TABLE, mp);
11063
11064   S (mp);
11065   W (ret);
11066   return ret;
11067 }
11068
11069 static int
11070 api_l2_interface_efp_filter (vat_main_t * vam)
11071 {
11072   unformat_input_t *i = vam->input;
11073   vl_api_l2_interface_efp_filter_t *mp;
11074   u32 sw_if_index;
11075   u8 enable = 1;
11076   u8 sw_if_index_set = 0;
11077   int ret;
11078
11079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11080     {
11081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11082         sw_if_index_set = 1;
11083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11084         sw_if_index_set = 1;
11085       else if (unformat (i, "enable"))
11086         enable = 1;
11087       else if (unformat (i, "disable"))
11088         enable = 0;
11089       else
11090         {
11091           clib_warning ("parse error '%U'", format_unformat_error, i);
11092           return -99;
11093         }
11094     }
11095
11096   if (sw_if_index_set == 0)
11097     {
11098       errmsg ("missing sw_if_index");
11099       return -99;
11100     }
11101
11102   M (L2_INTERFACE_EFP_FILTER, mp);
11103
11104   mp->sw_if_index = ntohl (sw_if_index);
11105   mp->enable_disable = enable;
11106
11107   S (mp);
11108   W (ret);
11109   return ret;
11110 }
11111
11112 #define foreach_vtr_op                          \
11113 _("disable",  L2_VTR_DISABLED)                  \
11114 _("push-1",  L2_VTR_PUSH_1)                     \
11115 _("push-2",  L2_VTR_PUSH_2)                     \
11116 _("pop-1",  L2_VTR_POP_1)                       \
11117 _("pop-2",  L2_VTR_POP_2)                       \
11118 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11119 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11120 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11121 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11122
11123 static int
11124 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11125 {
11126   unformat_input_t *i = vam->input;
11127   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11128   u32 sw_if_index;
11129   u8 sw_if_index_set = 0;
11130   u8 vtr_op_set = 0;
11131   u32 vtr_op = 0;
11132   u32 push_dot1q = 1;
11133   u32 tag1 = ~0;
11134   u32 tag2 = ~0;
11135   int ret;
11136
11137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11138     {
11139       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11140         sw_if_index_set = 1;
11141       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11142         sw_if_index_set = 1;
11143       else if (unformat (i, "vtr_op %d", &vtr_op))
11144         vtr_op_set = 1;
11145 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11146       foreach_vtr_op
11147 #undef _
11148         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11149         ;
11150       else if (unformat (i, "tag1 %d", &tag1))
11151         ;
11152       else if (unformat (i, "tag2 %d", &tag2))
11153         ;
11154       else
11155         {
11156           clib_warning ("parse error '%U'", format_unformat_error, i);
11157           return -99;
11158         }
11159     }
11160
11161   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11162     {
11163       errmsg ("missing vtr operation or sw_if_index");
11164       return -99;
11165     }
11166
11167   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11168   mp->sw_if_index = ntohl (sw_if_index);
11169   mp->vtr_op = ntohl (vtr_op);
11170   mp->push_dot1q = ntohl (push_dot1q);
11171   mp->tag1 = ntohl (tag1);
11172   mp->tag2 = ntohl (tag2);
11173
11174   S (mp);
11175   W (ret);
11176   return ret;
11177 }
11178
11179 static int
11180 api_create_vhost_user_if (vat_main_t * vam)
11181 {
11182   unformat_input_t *i = vam->input;
11183   vl_api_create_vhost_user_if_t *mp;
11184   u8 *file_name;
11185   u8 is_server = 0;
11186   u8 file_name_set = 0;
11187   u32 custom_dev_instance = ~0;
11188   u8 hwaddr[6];
11189   u8 use_custom_mac = 0;
11190   u8 *tag = 0;
11191   int ret;
11192
11193   /* Shut up coverity */
11194   memset (hwaddr, 0, sizeof (hwaddr));
11195
11196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11197     {
11198       if (unformat (i, "socket %s", &file_name))
11199         {
11200           file_name_set = 1;
11201         }
11202       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11203         ;
11204       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11205         use_custom_mac = 1;
11206       else if (unformat (i, "server"))
11207         is_server = 1;
11208       else if (unformat (i, "tag %s", &tag))
11209         ;
11210       else
11211         break;
11212     }
11213
11214   if (file_name_set == 0)
11215     {
11216       errmsg ("missing socket file name");
11217       return -99;
11218     }
11219
11220   if (vec_len (file_name) > 255)
11221     {
11222       errmsg ("socket file name too long");
11223       return -99;
11224     }
11225   vec_add1 (file_name, 0);
11226
11227   M (CREATE_VHOST_USER_IF, mp);
11228
11229   mp->is_server = is_server;
11230   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11231   vec_free (file_name);
11232   if (custom_dev_instance != ~0)
11233     {
11234       mp->renumber = 1;
11235       mp->custom_dev_instance = ntohl (custom_dev_instance);
11236     }
11237   mp->use_custom_mac = use_custom_mac;
11238   clib_memcpy (mp->mac_address, hwaddr, 6);
11239   if (tag)
11240     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11241   vec_free (tag);
11242
11243   S (mp);
11244   W (ret);
11245   return ret;
11246 }
11247
11248 static int
11249 api_modify_vhost_user_if (vat_main_t * vam)
11250 {
11251   unformat_input_t *i = vam->input;
11252   vl_api_modify_vhost_user_if_t *mp;
11253   u8 *file_name;
11254   u8 is_server = 0;
11255   u8 file_name_set = 0;
11256   u32 custom_dev_instance = ~0;
11257   u8 sw_if_index_set = 0;
11258   u32 sw_if_index = (u32) ~ 0;
11259   int ret;
11260
11261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11262     {
11263       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11264         sw_if_index_set = 1;
11265       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11266         sw_if_index_set = 1;
11267       else if (unformat (i, "socket %s", &file_name))
11268         {
11269           file_name_set = 1;
11270         }
11271       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11272         ;
11273       else if (unformat (i, "server"))
11274         is_server = 1;
11275       else
11276         break;
11277     }
11278
11279   if (sw_if_index_set == 0)
11280     {
11281       errmsg ("missing sw_if_index or interface name");
11282       return -99;
11283     }
11284
11285   if (file_name_set == 0)
11286     {
11287       errmsg ("missing socket file name");
11288       return -99;
11289     }
11290
11291   if (vec_len (file_name) > 255)
11292     {
11293       errmsg ("socket file name too long");
11294       return -99;
11295     }
11296   vec_add1 (file_name, 0);
11297
11298   M (MODIFY_VHOST_USER_IF, mp);
11299
11300   mp->sw_if_index = ntohl (sw_if_index);
11301   mp->is_server = is_server;
11302   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11303   vec_free (file_name);
11304   if (custom_dev_instance != ~0)
11305     {
11306       mp->renumber = 1;
11307       mp->custom_dev_instance = ntohl (custom_dev_instance);
11308     }
11309
11310   S (mp);
11311   W (ret);
11312   return ret;
11313 }
11314
11315 static int
11316 api_delete_vhost_user_if (vat_main_t * vam)
11317 {
11318   unformat_input_t *i = vam->input;
11319   vl_api_delete_vhost_user_if_t *mp;
11320   u32 sw_if_index = ~0;
11321   u8 sw_if_index_set = 0;
11322   int ret;
11323
11324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11325     {
11326       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11327         sw_if_index_set = 1;
11328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11329         sw_if_index_set = 1;
11330       else
11331         break;
11332     }
11333
11334   if (sw_if_index_set == 0)
11335     {
11336       errmsg ("missing sw_if_index or interface name");
11337       return -99;
11338     }
11339
11340
11341   M (DELETE_VHOST_USER_IF, mp);
11342
11343   mp->sw_if_index = ntohl (sw_if_index);
11344
11345   S (mp);
11346   W (ret);
11347   return ret;
11348 }
11349
11350 static void vl_api_sw_interface_vhost_user_details_t_handler
11351   (vl_api_sw_interface_vhost_user_details_t * mp)
11352 {
11353   vat_main_t *vam = &vat_main;
11354
11355   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11356          (char *) mp->interface_name,
11357          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11358          clib_net_to_host_u64 (mp->features), mp->is_server,
11359          ntohl (mp->num_regions), (char *) mp->sock_filename);
11360   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11361 }
11362
11363 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11364   (vl_api_sw_interface_vhost_user_details_t * mp)
11365 {
11366   vat_main_t *vam = &vat_main;
11367   vat_json_node_t *node = NULL;
11368
11369   if (VAT_JSON_ARRAY != vam->json_tree.type)
11370     {
11371       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11372       vat_json_init_array (&vam->json_tree);
11373     }
11374   node = vat_json_array_add (&vam->json_tree);
11375
11376   vat_json_init_object (node);
11377   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11378   vat_json_object_add_string_copy (node, "interface_name",
11379                                    mp->interface_name);
11380   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11381                             ntohl (mp->virtio_net_hdr_sz));
11382   vat_json_object_add_uint (node, "features",
11383                             clib_net_to_host_u64 (mp->features));
11384   vat_json_object_add_uint (node, "is_server", mp->is_server);
11385   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11386   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11387   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11388 }
11389
11390 static int
11391 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11392 {
11393   vl_api_sw_interface_vhost_user_dump_t *mp;
11394   vl_api_control_ping_t *mp_ping;
11395   int ret;
11396   print (vam->ofp,
11397          "Interface name           idx hdr_sz features server regions filename");
11398
11399   /* Get list of vhost-user interfaces */
11400   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11401   S (mp);
11402
11403   /* Use a control ping for synchronization */
11404   M (CONTROL_PING, mp_ping);
11405   S (mp_ping);
11406
11407   W (ret);
11408   return ret;
11409 }
11410
11411 static int
11412 api_show_version (vat_main_t * vam)
11413 {
11414   vl_api_show_version_t *mp;
11415   int ret;
11416
11417   M (SHOW_VERSION, mp);
11418
11419   S (mp);
11420   W (ret);
11421   return ret;
11422 }
11423
11424
11425 static int
11426 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11427 {
11428   unformat_input_t *line_input = vam->input;
11429   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11430   ip4_address_t local4, remote4;
11431   ip6_address_t local6, remote6;
11432   u8 is_add = 1;
11433   u8 ipv4_set = 0, ipv6_set = 0;
11434   u8 local_set = 0;
11435   u8 remote_set = 0;
11436   u32 encap_vrf_id = 0;
11437   u32 decap_vrf_id = 0;
11438   u8 protocol = ~0;
11439   u32 vni;
11440   u8 vni_set = 0;
11441   int ret;
11442
11443   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11444     {
11445       if (unformat (line_input, "del"))
11446         is_add = 0;
11447       else if (unformat (line_input, "local %U",
11448                          unformat_ip4_address, &local4))
11449         {
11450           local_set = 1;
11451           ipv4_set = 1;
11452         }
11453       else if (unformat (line_input, "remote %U",
11454                          unformat_ip4_address, &remote4))
11455         {
11456           remote_set = 1;
11457           ipv4_set = 1;
11458         }
11459       else if (unformat (line_input, "local %U",
11460                          unformat_ip6_address, &local6))
11461         {
11462           local_set = 1;
11463           ipv6_set = 1;
11464         }
11465       else if (unformat (line_input, "remote %U",
11466                          unformat_ip6_address, &remote6))
11467         {
11468           remote_set = 1;
11469           ipv6_set = 1;
11470         }
11471       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11472         ;
11473       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11474         ;
11475       else if (unformat (line_input, "vni %d", &vni))
11476         vni_set = 1;
11477       else if (unformat (line_input, "next-ip4"))
11478         protocol = 1;
11479       else if (unformat (line_input, "next-ip6"))
11480         protocol = 2;
11481       else if (unformat (line_input, "next-ethernet"))
11482         protocol = 3;
11483       else if (unformat (line_input, "next-nsh"))
11484         protocol = 4;
11485       else
11486         {
11487           errmsg ("parse error '%U'", format_unformat_error, line_input);
11488           return -99;
11489         }
11490     }
11491
11492   if (local_set == 0)
11493     {
11494       errmsg ("tunnel local address not specified");
11495       return -99;
11496     }
11497   if (remote_set == 0)
11498     {
11499       errmsg ("tunnel remote address not specified");
11500       return -99;
11501     }
11502   if (ipv4_set && ipv6_set)
11503     {
11504       errmsg ("both IPv4 and IPv6 addresses specified");
11505       return -99;
11506     }
11507
11508   if (vni_set == 0)
11509     {
11510       errmsg ("vni not specified");
11511       return -99;
11512     }
11513
11514   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11515
11516
11517   if (ipv6_set)
11518     {
11519       clib_memcpy (&mp->local, &local6, sizeof (local6));
11520       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11521     }
11522   else
11523     {
11524       clib_memcpy (&mp->local, &local4, sizeof (local4));
11525       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11526     }
11527
11528   mp->encap_vrf_id = ntohl (encap_vrf_id);
11529   mp->decap_vrf_id = ntohl (decap_vrf_id);
11530   mp->protocol = protocol;
11531   mp->vni = ntohl (vni);
11532   mp->is_add = is_add;
11533   mp->is_ipv6 = ipv6_set;
11534
11535   S (mp);
11536   W (ret);
11537   return ret;
11538 }
11539
11540 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11541   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11542 {
11543   vat_main_t *vam = &vat_main;
11544
11545   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11546          ntohl (mp->sw_if_index),
11547          format_ip46_address, &(mp->local[0]),
11548          format_ip46_address, &(mp->remote[0]),
11549          ntohl (mp->vni),
11550          ntohl (mp->protocol),
11551          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11552 }
11553
11554 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11555   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11556 {
11557   vat_main_t *vam = &vat_main;
11558   vat_json_node_t *node = NULL;
11559   struct in_addr ip4;
11560   struct in6_addr ip6;
11561
11562   if (VAT_JSON_ARRAY != vam->json_tree.type)
11563     {
11564       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11565       vat_json_init_array (&vam->json_tree);
11566     }
11567   node = vat_json_array_add (&vam->json_tree);
11568
11569   vat_json_init_object (node);
11570   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11571   if (mp->is_ipv6)
11572     {
11573       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11574       vat_json_object_add_ip6 (node, "local", ip6);
11575       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11576       vat_json_object_add_ip6 (node, "remote", ip6);
11577     }
11578   else
11579     {
11580       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11581       vat_json_object_add_ip4 (node, "local", ip4);
11582       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11583       vat_json_object_add_ip4 (node, "remote", ip4);
11584     }
11585   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11586   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11587   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11588   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11589   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11590 }
11591
11592 static int
11593 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11594 {
11595   unformat_input_t *i = vam->input;
11596   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11597   vl_api_control_ping_t *mp_ping;
11598   u32 sw_if_index;
11599   u8 sw_if_index_set = 0;
11600   int ret;
11601
11602   /* Parse args required to build the message */
11603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11604     {
11605       if (unformat (i, "sw_if_index %d", &sw_if_index))
11606         sw_if_index_set = 1;
11607       else
11608         break;
11609     }
11610
11611   if (sw_if_index_set == 0)
11612     {
11613       sw_if_index = ~0;
11614     }
11615
11616   if (!vam->json_output)
11617     {
11618       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11619              "sw_if_index", "local", "remote", "vni",
11620              "protocol", "encap_vrf_id", "decap_vrf_id");
11621     }
11622
11623   /* Get list of vxlan-tunnel interfaces */
11624   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11625
11626   mp->sw_if_index = htonl (sw_if_index);
11627
11628   S (mp);
11629
11630   /* Use a control ping for synchronization */
11631   M (CONTROL_PING, mp_ping);
11632   S (mp_ping);
11633
11634   W (ret);
11635   return ret;
11636 }
11637
11638 u8 *
11639 format_l2_fib_mac_address (u8 * s, va_list * args)
11640 {
11641   u8 *a = va_arg (*args, u8 *);
11642
11643   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11644                  a[2], a[3], a[4], a[5], a[6], a[7]);
11645 }
11646
11647 static void vl_api_l2_fib_table_entry_t_handler
11648   (vl_api_l2_fib_table_entry_t * mp)
11649 {
11650   vat_main_t *vam = &vat_main;
11651
11652   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11653          "       %d       %d     %d",
11654          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11655          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11656          mp->bvi_mac);
11657 }
11658
11659 static void vl_api_l2_fib_table_entry_t_handler_json
11660   (vl_api_l2_fib_table_entry_t * mp)
11661 {
11662   vat_main_t *vam = &vat_main;
11663   vat_json_node_t *node = NULL;
11664
11665   if (VAT_JSON_ARRAY != vam->json_tree.type)
11666     {
11667       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11668       vat_json_init_array (&vam->json_tree);
11669     }
11670   node = vat_json_array_add (&vam->json_tree);
11671
11672   vat_json_init_object (node);
11673   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11674   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11675   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11676   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11677   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11678   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11679 }
11680
11681 static int
11682 api_l2_fib_table_dump (vat_main_t * vam)
11683 {
11684   unformat_input_t *i = vam->input;
11685   vl_api_l2_fib_table_dump_t *mp;
11686   vl_api_control_ping_t *mp_ping;
11687   u32 bd_id;
11688   u8 bd_id_set = 0;
11689   int ret;
11690
11691   /* Parse args required to build the message */
11692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11693     {
11694       if (unformat (i, "bd_id %d", &bd_id))
11695         bd_id_set = 1;
11696       else
11697         break;
11698     }
11699
11700   if (bd_id_set == 0)
11701     {
11702       errmsg ("missing bridge domain");
11703       return -99;
11704     }
11705
11706   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11707
11708   /* Get list of l2 fib entries */
11709   M (L2_FIB_TABLE_DUMP, mp);
11710
11711   mp->bd_id = ntohl (bd_id);
11712   S (mp);
11713
11714   /* Use a control ping for synchronization */
11715   M (CONTROL_PING, mp_ping);
11716   S (mp_ping);
11717
11718   W (ret);
11719   return ret;
11720 }
11721
11722
11723 static int
11724 api_interface_name_renumber (vat_main_t * vam)
11725 {
11726   unformat_input_t *line_input = vam->input;
11727   vl_api_interface_name_renumber_t *mp;
11728   u32 sw_if_index = ~0;
11729   u32 new_show_dev_instance = ~0;
11730   int ret;
11731
11732   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11733     {
11734       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11735                     &sw_if_index))
11736         ;
11737       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11738         ;
11739       else if (unformat (line_input, "new_show_dev_instance %d",
11740                          &new_show_dev_instance))
11741         ;
11742       else
11743         break;
11744     }
11745
11746   if (sw_if_index == ~0)
11747     {
11748       errmsg ("missing interface name or sw_if_index");
11749       return -99;
11750     }
11751
11752   if (new_show_dev_instance == ~0)
11753     {
11754       errmsg ("missing new_show_dev_instance");
11755       return -99;
11756     }
11757
11758   M (INTERFACE_NAME_RENUMBER, mp);
11759
11760   mp->sw_if_index = ntohl (sw_if_index);
11761   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11762
11763   S (mp);
11764   W (ret);
11765   return ret;
11766 }
11767
11768 static int
11769 api_want_ip4_arp_events (vat_main_t * vam)
11770 {
11771   unformat_input_t *line_input = vam->input;
11772   vl_api_want_ip4_arp_events_t *mp;
11773   ip4_address_t address;
11774   int address_set = 0;
11775   u32 enable_disable = 1;
11776   int ret;
11777
11778   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11779     {
11780       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11781         address_set = 1;
11782       else if (unformat (line_input, "del"))
11783         enable_disable = 0;
11784       else
11785         break;
11786     }
11787
11788   if (address_set == 0)
11789     {
11790       errmsg ("missing addresses");
11791       return -99;
11792     }
11793
11794   M (WANT_IP4_ARP_EVENTS, mp);
11795   mp->enable_disable = enable_disable;
11796   mp->pid = getpid ();
11797   mp->address = address.as_u32;
11798
11799   S (mp);
11800   W (ret);
11801   return ret;
11802 }
11803
11804 static int
11805 api_want_ip6_nd_events (vat_main_t * vam)
11806 {
11807   unformat_input_t *line_input = vam->input;
11808   vl_api_want_ip6_nd_events_t *mp;
11809   ip6_address_t address;
11810   int address_set = 0;
11811   u32 enable_disable = 1;
11812   int ret;
11813
11814   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11815     {
11816       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11817         address_set = 1;
11818       else if (unformat (line_input, "del"))
11819         enable_disable = 0;
11820       else
11821         break;
11822     }
11823
11824   if (address_set == 0)
11825     {
11826       errmsg ("missing addresses");
11827       return -99;
11828     }
11829
11830   M (WANT_IP6_ND_EVENTS, mp);
11831   mp->enable_disable = enable_disable;
11832   mp->pid = getpid ();
11833   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11834
11835   S (mp);
11836   W (ret);
11837   return ret;
11838 }
11839
11840 static int
11841 api_input_acl_set_interface (vat_main_t * vam)
11842 {
11843   unformat_input_t *i = vam->input;
11844   vl_api_input_acl_set_interface_t *mp;
11845   u32 sw_if_index;
11846   int sw_if_index_set;
11847   u32 ip4_table_index = ~0;
11848   u32 ip6_table_index = ~0;
11849   u32 l2_table_index = ~0;
11850   u8 is_add = 1;
11851   int ret;
11852
11853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11854     {
11855       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11856         sw_if_index_set = 1;
11857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11858         sw_if_index_set = 1;
11859       else if (unformat (i, "del"))
11860         is_add = 0;
11861       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11862         ;
11863       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11864         ;
11865       else if (unformat (i, "l2-table %d", &l2_table_index))
11866         ;
11867       else
11868         {
11869           clib_warning ("parse error '%U'", format_unformat_error, i);
11870           return -99;
11871         }
11872     }
11873
11874   if (sw_if_index_set == 0)
11875     {
11876       errmsg ("missing interface name or sw_if_index");
11877       return -99;
11878     }
11879
11880   M (INPUT_ACL_SET_INTERFACE, mp);
11881
11882   mp->sw_if_index = ntohl (sw_if_index);
11883   mp->ip4_table_index = ntohl (ip4_table_index);
11884   mp->ip6_table_index = ntohl (ip6_table_index);
11885   mp->l2_table_index = ntohl (l2_table_index);
11886   mp->is_add = is_add;
11887
11888   S (mp);
11889   W (ret);
11890   return ret;
11891 }
11892
11893 static int
11894 api_ip_address_dump (vat_main_t * vam)
11895 {
11896   unformat_input_t *i = vam->input;
11897   vl_api_ip_address_dump_t *mp;
11898   vl_api_control_ping_t *mp_ping;
11899   u32 sw_if_index = ~0;
11900   u8 sw_if_index_set = 0;
11901   u8 ipv4_set = 0;
11902   u8 ipv6_set = 0;
11903   int ret;
11904
11905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11906     {
11907       if (unformat (i, "sw_if_index %d", &sw_if_index))
11908         sw_if_index_set = 1;
11909       else
11910         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11911         sw_if_index_set = 1;
11912       else if (unformat (i, "ipv4"))
11913         ipv4_set = 1;
11914       else if (unformat (i, "ipv6"))
11915         ipv6_set = 1;
11916       else
11917         break;
11918     }
11919
11920   if (ipv4_set && ipv6_set)
11921     {
11922       errmsg ("ipv4 and ipv6 flags cannot be both set");
11923       return -99;
11924     }
11925
11926   if ((!ipv4_set) && (!ipv6_set))
11927     {
11928       errmsg ("no ipv4 nor ipv6 flag set");
11929       return -99;
11930     }
11931
11932   if (sw_if_index_set == 0)
11933     {
11934       errmsg ("missing interface name or sw_if_index");
11935       return -99;
11936     }
11937
11938   vam->current_sw_if_index = sw_if_index;
11939   vam->is_ipv6 = ipv6_set;
11940
11941   M (IP_ADDRESS_DUMP, mp);
11942   mp->sw_if_index = ntohl (sw_if_index);
11943   mp->is_ipv6 = ipv6_set;
11944   S (mp);
11945
11946   /* Use a control ping for synchronization */
11947   M (CONTROL_PING, mp_ping);
11948   S (mp_ping);
11949
11950   W (ret);
11951   return ret;
11952 }
11953
11954 static int
11955 api_ip_dump (vat_main_t * vam)
11956 {
11957   vl_api_ip_dump_t *mp;
11958   vl_api_control_ping_t *mp_ping;
11959   unformat_input_t *in = vam->input;
11960   int ipv4_set = 0;
11961   int ipv6_set = 0;
11962   int is_ipv6;
11963   int i;
11964   int ret;
11965
11966   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11967     {
11968       if (unformat (in, "ipv4"))
11969         ipv4_set = 1;
11970       else if (unformat (in, "ipv6"))
11971         ipv6_set = 1;
11972       else
11973         break;
11974     }
11975
11976   if (ipv4_set && ipv6_set)
11977     {
11978       errmsg ("ipv4 and ipv6 flags cannot be both set");
11979       return -99;
11980     }
11981
11982   if ((!ipv4_set) && (!ipv6_set))
11983     {
11984       errmsg ("no ipv4 nor ipv6 flag set");
11985       return -99;
11986     }
11987
11988   is_ipv6 = ipv6_set;
11989   vam->is_ipv6 = is_ipv6;
11990
11991   /* free old data */
11992   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11993     {
11994       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11995     }
11996   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11997
11998   M (IP_DUMP, mp);
11999   mp->is_ipv6 = ipv6_set;
12000   S (mp);
12001
12002   /* Use a control ping for synchronization */
12003   M (CONTROL_PING, mp_ping);
12004   S (mp_ping);
12005
12006   W (ret);
12007   return ret;
12008 }
12009
12010 static int
12011 api_ipsec_spd_add_del (vat_main_t * vam)
12012 {
12013   unformat_input_t *i = vam->input;
12014   vl_api_ipsec_spd_add_del_t *mp;
12015   u32 spd_id = ~0;
12016   u8 is_add = 1;
12017   int ret;
12018
12019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12020     {
12021       if (unformat (i, "spd_id %d", &spd_id))
12022         ;
12023       else if (unformat (i, "del"))
12024         is_add = 0;
12025       else
12026         {
12027           clib_warning ("parse error '%U'", format_unformat_error, i);
12028           return -99;
12029         }
12030     }
12031   if (spd_id == ~0)
12032     {
12033       errmsg ("spd_id must be set");
12034       return -99;
12035     }
12036
12037   M (IPSEC_SPD_ADD_DEL, mp);
12038
12039   mp->spd_id = ntohl (spd_id);
12040   mp->is_add = is_add;
12041
12042   S (mp);
12043   W (ret);
12044   return ret;
12045 }
12046
12047 static int
12048 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12049 {
12050   unformat_input_t *i = vam->input;
12051   vl_api_ipsec_interface_add_del_spd_t *mp;
12052   u32 sw_if_index;
12053   u8 sw_if_index_set = 0;
12054   u32 spd_id = (u32) ~ 0;
12055   u8 is_add = 1;
12056   int ret;
12057
12058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12059     {
12060       if (unformat (i, "del"))
12061         is_add = 0;
12062       else if (unformat (i, "spd_id %d", &spd_id))
12063         ;
12064       else
12065         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12066         sw_if_index_set = 1;
12067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12068         sw_if_index_set = 1;
12069       else
12070         {
12071           clib_warning ("parse error '%U'", format_unformat_error, i);
12072           return -99;
12073         }
12074
12075     }
12076
12077   if (spd_id == (u32) ~ 0)
12078     {
12079       errmsg ("spd_id must be set");
12080       return -99;
12081     }
12082
12083   if (sw_if_index_set == 0)
12084     {
12085       errmsg ("missing interface name or sw_if_index");
12086       return -99;
12087     }
12088
12089   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12090
12091   mp->spd_id = ntohl (spd_id);
12092   mp->sw_if_index = ntohl (sw_if_index);
12093   mp->is_add = is_add;
12094
12095   S (mp);
12096   W (ret);
12097   return ret;
12098 }
12099
12100 static int
12101 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12102 {
12103   unformat_input_t *i = vam->input;
12104   vl_api_ipsec_spd_add_del_entry_t *mp;
12105   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12106   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12107   i32 priority = 0;
12108   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12109   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12110   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12111   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12112   int ret;
12113
12114   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12115   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12116   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12117   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12118   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12119   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12120
12121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12122     {
12123       if (unformat (i, "del"))
12124         is_add = 0;
12125       if (unformat (i, "outbound"))
12126         is_outbound = 1;
12127       if (unformat (i, "inbound"))
12128         is_outbound = 0;
12129       else if (unformat (i, "spd_id %d", &spd_id))
12130         ;
12131       else if (unformat (i, "sa_id %d", &sa_id))
12132         ;
12133       else if (unformat (i, "priority %d", &priority))
12134         ;
12135       else if (unformat (i, "protocol %d", &protocol))
12136         ;
12137       else if (unformat (i, "lport_start %d", &lport_start))
12138         ;
12139       else if (unformat (i, "lport_stop %d", &lport_stop))
12140         ;
12141       else if (unformat (i, "rport_start %d", &rport_start))
12142         ;
12143       else if (unformat (i, "rport_stop %d", &rport_stop))
12144         ;
12145       else
12146         if (unformat
12147             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12148         {
12149           is_ipv6 = 0;
12150           is_ip_any = 0;
12151         }
12152       else
12153         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12154         {
12155           is_ipv6 = 0;
12156           is_ip_any = 0;
12157         }
12158       else
12159         if (unformat
12160             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12161         {
12162           is_ipv6 = 0;
12163           is_ip_any = 0;
12164         }
12165       else
12166         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12167         {
12168           is_ipv6 = 0;
12169           is_ip_any = 0;
12170         }
12171       else
12172         if (unformat
12173             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12174         {
12175           is_ipv6 = 1;
12176           is_ip_any = 0;
12177         }
12178       else
12179         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12180         {
12181           is_ipv6 = 1;
12182           is_ip_any = 0;
12183         }
12184       else
12185         if (unformat
12186             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12187         {
12188           is_ipv6 = 1;
12189           is_ip_any = 0;
12190         }
12191       else
12192         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12193         {
12194           is_ipv6 = 1;
12195           is_ip_any = 0;
12196         }
12197       else
12198         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12199         {
12200           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12201             {
12202               clib_warning ("unsupported action: 'resolve'");
12203               return -99;
12204             }
12205         }
12206       else
12207         {
12208           clib_warning ("parse error '%U'", format_unformat_error, i);
12209           return -99;
12210         }
12211
12212     }
12213
12214   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12215
12216   mp->spd_id = ntohl (spd_id);
12217   mp->priority = ntohl (priority);
12218   mp->is_outbound = is_outbound;
12219
12220   mp->is_ipv6 = is_ipv6;
12221   if (is_ipv6 || is_ip_any)
12222     {
12223       clib_memcpy (mp->remote_address_start, &raddr6_start,
12224                    sizeof (ip6_address_t));
12225       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12226                    sizeof (ip6_address_t));
12227       clib_memcpy (mp->local_address_start, &laddr6_start,
12228                    sizeof (ip6_address_t));
12229       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12230                    sizeof (ip6_address_t));
12231     }
12232   else
12233     {
12234       clib_memcpy (mp->remote_address_start, &raddr4_start,
12235                    sizeof (ip4_address_t));
12236       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12237                    sizeof (ip4_address_t));
12238       clib_memcpy (mp->local_address_start, &laddr4_start,
12239                    sizeof (ip4_address_t));
12240       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12241                    sizeof (ip4_address_t));
12242     }
12243   mp->protocol = (u8) protocol;
12244   mp->local_port_start = ntohs ((u16) lport_start);
12245   mp->local_port_stop = ntohs ((u16) lport_stop);
12246   mp->remote_port_start = ntohs ((u16) rport_start);
12247   mp->remote_port_stop = ntohs ((u16) rport_stop);
12248   mp->policy = (u8) policy;
12249   mp->sa_id = ntohl (sa_id);
12250   mp->is_add = is_add;
12251   mp->is_ip_any = is_ip_any;
12252   S (mp);
12253   W (ret);
12254   return ret;
12255 }
12256
12257 static int
12258 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12259 {
12260   unformat_input_t *i = vam->input;
12261   vl_api_ipsec_sad_add_del_entry_t *mp;
12262   u32 sad_id = 0, spi = 0;
12263   u8 *ck = 0, *ik = 0;
12264   u8 is_add = 1;
12265
12266   u8 protocol = IPSEC_PROTOCOL_AH;
12267   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12268   u32 crypto_alg = 0, integ_alg = 0;
12269   ip4_address_t tun_src4;
12270   ip4_address_t tun_dst4;
12271   ip6_address_t tun_src6;
12272   ip6_address_t tun_dst6;
12273   int ret;
12274
12275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12276     {
12277       if (unformat (i, "del"))
12278         is_add = 0;
12279       else if (unformat (i, "sad_id %d", &sad_id))
12280         ;
12281       else if (unformat (i, "spi %d", &spi))
12282         ;
12283       else if (unformat (i, "esp"))
12284         protocol = IPSEC_PROTOCOL_ESP;
12285       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12286         {
12287           is_tunnel = 1;
12288           is_tunnel_ipv6 = 0;
12289         }
12290       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12291         {
12292           is_tunnel = 1;
12293           is_tunnel_ipv6 = 0;
12294         }
12295       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12296         {
12297           is_tunnel = 1;
12298           is_tunnel_ipv6 = 1;
12299         }
12300       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12301         {
12302           is_tunnel = 1;
12303           is_tunnel_ipv6 = 1;
12304         }
12305       else
12306         if (unformat
12307             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12308         {
12309           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12310               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12311             {
12312               clib_warning ("unsupported crypto-alg: '%U'",
12313                             format_ipsec_crypto_alg, crypto_alg);
12314               return -99;
12315             }
12316         }
12317       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12318         ;
12319       else
12320         if (unformat
12321             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12322         {
12323           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12324               integ_alg >= IPSEC_INTEG_N_ALG)
12325             {
12326               clib_warning ("unsupported integ-alg: '%U'",
12327                             format_ipsec_integ_alg, integ_alg);
12328               return -99;
12329             }
12330         }
12331       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12332         ;
12333       else
12334         {
12335           clib_warning ("parse error '%U'", format_unformat_error, i);
12336           return -99;
12337         }
12338
12339     }
12340
12341   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12342
12343   mp->sad_id = ntohl (sad_id);
12344   mp->is_add = is_add;
12345   mp->protocol = protocol;
12346   mp->spi = ntohl (spi);
12347   mp->is_tunnel = is_tunnel;
12348   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12349   mp->crypto_algorithm = crypto_alg;
12350   mp->integrity_algorithm = integ_alg;
12351   mp->crypto_key_length = vec_len (ck);
12352   mp->integrity_key_length = vec_len (ik);
12353
12354   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12355     mp->crypto_key_length = sizeof (mp->crypto_key);
12356
12357   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12358     mp->integrity_key_length = sizeof (mp->integrity_key);
12359
12360   if (ck)
12361     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12362   if (ik)
12363     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12364
12365   if (is_tunnel)
12366     {
12367       if (is_tunnel_ipv6)
12368         {
12369           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12370                        sizeof (ip6_address_t));
12371           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12372                        sizeof (ip6_address_t));
12373         }
12374       else
12375         {
12376           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12377                        sizeof (ip4_address_t));
12378           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12379                        sizeof (ip4_address_t));
12380         }
12381     }
12382
12383   S (mp);
12384   W (ret);
12385   return ret;
12386 }
12387
12388 static int
12389 api_ipsec_sa_set_key (vat_main_t * vam)
12390 {
12391   unformat_input_t *i = vam->input;
12392   vl_api_ipsec_sa_set_key_t *mp;
12393   u32 sa_id;
12394   u8 *ck = 0, *ik = 0;
12395   int ret;
12396
12397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12398     {
12399       if (unformat (i, "sa_id %d", &sa_id))
12400         ;
12401       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12402         ;
12403       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12404         ;
12405       else
12406         {
12407           clib_warning ("parse error '%U'", format_unformat_error, i);
12408           return -99;
12409         }
12410     }
12411
12412   M (IPSEC_SA_SET_KEY, mp);
12413
12414   mp->sa_id = ntohl (sa_id);
12415   mp->crypto_key_length = vec_len (ck);
12416   mp->integrity_key_length = vec_len (ik);
12417
12418   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12419     mp->crypto_key_length = sizeof (mp->crypto_key);
12420
12421   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12422     mp->integrity_key_length = sizeof (mp->integrity_key);
12423
12424   if (ck)
12425     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12426   if (ik)
12427     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12428
12429   S (mp);
12430   W (ret);
12431   return ret;
12432 }
12433
12434 static int
12435 api_ikev2_profile_add_del (vat_main_t * vam)
12436 {
12437   unformat_input_t *i = vam->input;
12438   vl_api_ikev2_profile_add_del_t *mp;
12439   u8 is_add = 1;
12440   u8 *name = 0;
12441   int ret;
12442
12443   const char *valid_chars = "a-zA-Z0-9_";
12444
12445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12446     {
12447       if (unformat (i, "del"))
12448         is_add = 0;
12449       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12450         vec_add1 (name, 0);
12451       else
12452         {
12453           errmsg ("parse error '%U'", format_unformat_error, i);
12454           return -99;
12455         }
12456     }
12457
12458   if (!vec_len (name))
12459     {
12460       errmsg ("profile name must be specified");
12461       return -99;
12462     }
12463
12464   if (vec_len (name) > 64)
12465     {
12466       errmsg ("profile name too long");
12467       return -99;
12468     }
12469
12470   M (IKEV2_PROFILE_ADD_DEL, mp);
12471
12472   clib_memcpy (mp->name, name, vec_len (name));
12473   mp->is_add = is_add;
12474   vec_free (name);
12475
12476   S (mp);
12477   W (ret);
12478   return ret;
12479 }
12480
12481 static int
12482 api_ikev2_profile_set_auth (vat_main_t * vam)
12483 {
12484   unformat_input_t *i = vam->input;
12485   vl_api_ikev2_profile_set_auth_t *mp;
12486   u8 *name = 0;
12487   u8 *data = 0;
12488   u32 auth_method = 0;
12489   u8 is_hex = 0;
12490   int ret;
12491
12492   const char *valid_chars = "a-zA-Z0-9_";
12493
12494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12495     {
12496       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12497         vec_add1 (name, 0);
12498       else if (unformat (i, "auth_method %U",
12499                          unformat_ikev2_auth_method, &auth_method))
12500         ;
12501       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12502         is_hex = 1;
12503       else if (unformat (i, "auth_data %v", &data))
12504         ;
12505       else
12506         {
12507           errmsg ("parse error '%U'", format_unformat_error, i);
12508           return -99;
12509         }
12510     }
12511
12512   if (!vec_len (name))
12513     {
12514       errmsg ("profile name must be specified");
12515       return -99;
12516     }
12517
12518   if (vec_len (name) > 64)
12519     {
12520       errmsg ("profile name too long");
12521       return -99;
12522     }
12523
12524   if (!vec_len (data))
12525     {
12526       errmsg ("auth_data must be specified");
12527       return -99;
12528     }
12529
12530   if (!auth_method)
12531     {
12532       errmsg ("auth_method must be specified");
12533       return -99;
12534     }
12535
12536   M (IKEV2_PROFILE_SET_AUTH, mp);
12537
12538   mp->is_hex = is_hex;
12539   mp->auth_method = (u8) auth_method;
12540   mp->data_len = vec_len (data);
12541   clib_memcpy (mp->name, name, vec_len (name));
12542   clib_memcpy (mp->data, data, vec_len (data));
12543   vec_free (name);
12544   vec_free (data);
12545
12546   S (mp);
12547   W (ret);
12548   return ret;
12549 }
12550
12551 static int
12552 api_ikev2_profile_set_id (vat_main_t * vam)
12553 {
12554   unformat_input_t *i = vam->input;
12555   vl_api_ikev2_profile_set_id_t *mp;
12556   u8 *name = 0;
12557   u8 *data = 0;
12558   u8 is_local = 0;
12559   u32 id_type = 0;
12560   ip4_address_t ip4;
12561   int ret;
12562
12563   const char *valid_chars = "a-zA-Z0-9_";
12564
12565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12566     {
12567       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12568         vec_add1 (name, 0);
12569       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12570         ;
12571       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12572         {
12573           data = vec_new (u8, 4);
12574           clib_memcpy (data, ip4.as_u8, 4);
12575         }
12576       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12577         ;
12578       else if (unformat (i, "id_data %v", &data))
12579         ;
12580       else if (unformat (i, "local"))
12581         is_local = 1;
12582       else if (unformat (i, "remote"))
12583         is_local = 0;
12584       else
12585         {
12586           errmsg ("parse error '%U'", format_unformat_error, i);
12587           return -99;
12588         }
12589     }
12590
12591   if (!vec_len (name))
12592     {
12593       errmsg ("profile name must be specified");
12594       return -99;
12595     }
12596
12597   if (vec_len (name) > 64)
12598     {
12599       errmsg ("profile name too long");
12600       return -99;
12601     }
12602
12603   if (!vec_len (data))
12604     {
12605       errmsg ("id_data must be specified");
12606       return -99;
12607     }
12608
12609   if (!id_type)
12610     {
12611       errmsg ("id_type must be specified");
12612       return -99;
12613     }
12614
12615   M (IKEV2_PROFILE_SET_ID, mp);
12616
12617   mp->is_local = is_local;
12618   mp->id_type = (u8) id_type;
12619   mp->data_len = vec_len (data);
12620   clib_memcpy (mp->name, name, vec_len (name));
12621   clib_memcpy (mp->data, data, vec_len (data));
12622   vec_free (name);
12623   vec_free (data);
12624
12625   S (mp);
12626   W (ret);
12627   return ret;
12628 }
12629
12630 static int
12631 api_ikev2_profile_set_ts (vat_main_t * vam)
12632 {
12633   unformat_input_t *i = vam->input;
12634   vl_api_ikev2_profile_set_ts_t *mp;
12635   u8 *name = 0;
12636   u8 is_local = 0;
12637   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12638   ip4_address_t start_addr, end_addr;
12639
12640   const char *valid_chars = "a-zA-Z0-9_";
12641   int ret;
12642
12643   start_addr.as_u32 = 0;
12644   end_addr.as_u32 = (u32) ~ 0;
12645
12646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12647     {
12648       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12649         vec_add1 (name, 0);
12650       else if (unformat (i, "protocol %d", &proto))
12651         ;
12652       else if (unformat (i, "start_port %d", &start_port))
12653         ;
12654       else if (unformat (i, "end_port %d", &end_port))
12655         ;
12656       else
12657         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12658         ;
12659       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12660         ;
12661       else if (unformat (i, "local"))
12662         is_local = 1;
12663       else if (unformat (i, "remote"))
12664         is_local = 0;
12665       else
12666         {
12667           errmsg ("parse error '%U'", format_unformat_error, i);
12668           return -99;
12669         }
12670     }
12671
12672   if (!vec_len (name))
12673     {
12674       errmsg ("profile name must be specified");
12675       return -99;
12676     }
12677
12678   if (vec_len (name) > 64)
12679     {
12680       errmsg ("profile name too long");
12681       return -99;
12682     }
12683
12684   M (IKEV2_PROFILE_SET_TS, mp);
12685
12686   mp->is_local = is_local;
12687   mp->proto = (u8) proto;
12688   mp->start_port = (u16) start_port;
12689   mp->end_port = (u16) end_port;
12690   mp->start_addr = start_addr.as_u32;
12691   mp->end_addr = end_addr.as_u32;
12692   clib_memcpy (mp->name, name, vec_len (name));
12693   vec_free (name);
12694
12695   S (mp);
12696   W (ret);
12697   return ret;
12698 }
12699
12700 static int
12701 api_ikev2_set_local_key (vat_main_t * vam)
12702 {
12703   unformat_input_t *i = vam->input;
12704   vl_api_ikev2_set_local_key_t *mp;
12705   u8 *file = 0;
12706   int ret;
12707
12708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12709     {
12710       if (unformat (i, "file %v", &file))
12711         vec_add1 (file, 0);
12712       else
12713         {
12714           errmsg ("parse error '%U'", format_unformat_error, i);
12715           return -99;
12716         }
12717     }
12718
12719   if (!vec_len (file))
12720     {
12721       errmsg ("RSA key file must be specified");
12722       return -99;
12723     }
12724
12725   if (vec_len (file) > 256)
12726     {
12727       errmsg ("file name too long");
12728       return -99;
12729     }
12730
12731   M (IKEV2_SET_LOCAL_KEY, mp);
12732
12733   clib_memcpy (mp->key_file, file, vec_len (file));
12734   vec_free (file);
12735
12736   S (mp);
12737   W (ret);
12738   return ret;
12739 }
12740
12741 /*
12742  * MAP
12743  */
12744 static int
12745 api_map_add_domain (vat_main_t * vam)
12746 {
12747   unformat_input_t *i = vam->input;
12748   vl_api_map_add_domain_t *mp;
12749
12750   ip4_address_t ip4_prefix;
12751   ip6_address_t ip6_prefix;
12752   ip6_address_t ip6_src;
12753   u32 num_m_args = 0;
12754   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12755     0, psid_length = 0;
12756   u8 is_translation = 0;
12757   u32 mtu = 0;
12758   u32 ip6_src_len = 128;
12759   int ret;
12760
12761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12762     {
12763       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12764                     &ip4_prefix, &ip4_prefix_len))
12765         num_m_args++;
12766       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12767                          &ip6_prefix, &ip6_prefix_len))
12768         num_m_args++;
12769       else
12770         if (unformat
12771             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12772              &ip6_src_len))
12773         num_m_args++;
12774       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12775         num_m_args++;
12776       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12777         num_m_args++;
12778       else if (unformat (i, "psid-offset %d", &psid_offset))
12779         num_m_args++;
12780       else if (unformat (i, "psid-len %d", &psid_length))
12781         num_m_args++;
12782       else if (unformat (i, "mtu %d", &mtu))
12783         num_m_args++;
12784       else if (unformat (i, "map-t"))
12785         is_translation = 1;
12786       else
12787         {
12788           clib_warning ("parse error '%U'", format_unformat_error, i);
12789           return -99;
12790         }
12791     }
12792
12793   if (num_m_args < 3)
12794     {
12795       errmsg ("mandatory argument(s) missing");
12796       return -99;
12797     }
12798
12799   /* Construct the API message */
12800   M (MAP_ADD_DOMAIN, mp);
12801
12802   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12803   mp->ip4_prefix_len = ip4_prefix_len;
12804
12805   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12806   mp->ip6_prefix_len = ip6_prefix_len;
12807
12808   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12809   mp->ip6_src_prefix_len = ip6_src_len;
12810
12811   mp->ea_bits_len = ea_bits_len;
12812   mp->psid_offset = psid_offset;
12813   mp->psid_length = psid_length;
12814   mp->is_translation = is_translation;
12815   mp->mtu = htons (mtu);
12816
12817   /* send it... */
12818   S (mp);
12819
12820   /* Wait for a reply, return good/bad news  */
12821   W (ret);
12822   return ret;
12823 }
12824
12825 static int
12826 api_map_del_domain (vat_main_t * vam)
12827 {
12828   unformat_input_t *i = vam->input;
12829   vl_api_map_del_domain_t *mp;
12830
12831   u32 num_m_args = 0;
12832   u32 index;
12833   int ret;
12834
12835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12836     {
12837       if (unformat (i, "index %d", &index))
12838         num_m_args++;
12839       else
12840         {
12841           clib_warning ("parse error '%U'", format_unformat_error, i);
12842           return -99;
12843         }
12844     }
12845
12846   if (num_m_args != 1)
12847     {
12848       errmsg ("mandatory argument(s) missing");
12849       return -99;
12850     }
12851
12852   /* Construct the API message */
12853   M (MAP_DEL_DOMAIN, mp);
12854
12855   mp->index = ntohl (index);
12856
12857   /* send it... */
12858   S (mp);
12859
12860   /* Wait for a reply, return good/bad news  */
12861   W (ret);
12862   return ret;
12863 }
12864
12865 static int
12866 api_map_add_del_rule (vat_main_t * vam)
12867 {
12868   unformat_input_t *i = vam->input;
12869   vl_api_map_add_del_rule_t *mp;
12870   u8 is_add = 1;
12871   ip6_address_t ip6_dst;
12872   u32 num_m_args = 0, index, psid = 0;
12873   int ret;
12874
12875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12876     {
12877       if (unformat (i, "index %d", &index))
12878         num_m_args++;
12879       else if (unformat (i, "psid %d", &psid))
12880         num_m_args++;
12881       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12882         num_m_args++;
12883       else if (unformat (i, "del"))
12884         {
12885           is_add = 0;
12886         }
12887       else
12888         {
12889           clib_warning ("parse error '%U'", format_unformat_error, i);
12890           return -99;
12891         }
12892     }
12893
12894   /* Construct the API message */
12895   M (MAP_ADD_DEL_RULE, mp);
12896
12897   mp->index = ntohl (index);
12898   mp->is_add = is_add;
12899   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12900   mp->psid = ntohs (psid);
12901
12902   /* send it... */
12903   S (mp);
12904
12905   /* Wait for a reply, return good/bad news  */
12906   W (ret);
12907   return ret;
12908 }
12909
12910 static int
12911 api_map_domain_dump (vat_main_t * vam)
12912 {
12913   vl_api_map_domain_dump_t *mp;
12914   vl_api_control_ping_t *mp_ping;
12915   int ret;
12916
12917   /* Construct the API message */
12918   M (MAP_DOMAIN_DUMP, mp);
12919
12920   /* send it... */
12921   S (mp);
12922
12923   /* Use a control ping for synchronization */
12924   M (CONTROL_PING, mp_ping);
12925   S (mp_ping);
12926
12927   W (ret);
12928   return ret;
12929 }
12930
12931 static int
12932 api_map_rule_dump (vat_main_t * vam)
12933 {
12934   unformat_input_t *i = vam->input;
12935   vl_api_map_rule_dump_t *mp;
12936   vl_api_control_ping_t *mp_ping;
12937   u32 domain_index = ~0;
12938   int ret;
12939
12940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12941     {
12942       if (unformat (i, "index %u", &domain_index))
12943         ;
12944       else
12945         break;
12946     }
12947
12948   if (domain_index == ~0)
12949     {
12950       clib_warning ("parse error: domain index expected");
12951       return -99;
12952     }
12953
12954   /* Construct the API message */
12955   M (MAP_RULE_DUMP, mp);
12956
12957   mp->domain_index = htonl (domain_index);
12958
12959   /* send it... */
12960   S (mp);
12961
12962   /* Use a control ping for synchronization */
12963   M (CONTROL_PING, mp_ping);
12964   S (mp_ping);
12965
12966   W (ret);
12967   return ret;
12968 }
12969
12970 static void vl_api_map_add_domain_reply_t_handler
12971   (vl_api_map_add_domain_reply_t * mp)
12972 {
12973   vat_main_t *vam = &vat_main;
12974   i32 retval = ntohl (mp->retval);
12975
12976   if (vam->async_mode)
12977     {
12978       vam->async_errors += (retval < 0);
12979     }
12980   else
12981     {
12982       vam->retval = retval;
12983       vam->result_ready = 1;
12984     }
12985 }
12986
12987 static void vl_api_map_add_domain_reply_t_handler_json
12988   (vl_api_map_add_domain_reply_t * mp)
12989 {
12990   vat_main_t *vam = &vat_main;
12991   vat_json_node_t node;
12992
12993   vat_json_init_object (&node);
12994   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12995   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12996
12997   vat_json_print (vam->ofp, &node);
12998   vat_json_free (&node);
12999
13000   vam->retval = ntohl (mp->retval);
13001   vam->result_ready = 1;
13002 }
13003
13004 static int
13005 api_get_first_msg_id (vat_main_t * vam)
13006 {
13007   vl_api_get_first_msg_id_t *mp;
13008   unformat_input_t *i = vam->input;
13009   u8 *name;
13010   u8 name_set = 0;
13011   int ret;
13012
13013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13014     {
13015       if (unformat (i, "client %s", &name))
13016         name_set = 1;
13017       else
13018         break;
13019     }
13020
13021   if (name_set == 0)
13022     {
13023       errmsg ("missing client name");
13024       return -99;
13025     }
13026   vec_add1 (name, 0);
13027
13028   if (vec_len (name) > 63)
13029     {
13030       errmsg ("client name too long");
13031       return -99;
13032     }
13033
13034   M (GET_FIRST_MSG_ID, mp);
13035   clib_memcpy (mp->name, name, vec_len (name));
13036   S (mp);
13037   W (ret);
13038   return ret;
13039 }
13040
13041 static int
13042 api_cop_interface_enable_disable (vat_main_t * vam)
13043 {
13044   unformat_input_t *line_input = vam->input;
13045   vl_api_cop_interface_enable_disable_t *mp;
13046   u32 sw_if_index = ~0;
13047   u8 enable_disable = 1;
13048   int ret;
13049
13050   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13051     {
13052       if (unformat (line_input, "disable"))
13053         enable_disable = 0;
13054       if (unformat (line_input, "enable"))
13055         enable_disable = 1;
13056       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13057                          vam, &sw_if_index))
13058         ;
13059       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13060         ;
13061       else
13062         break;
13063     }
13064
13065   if (sw_if_index == ~0)
13066     {
13067       errmsg ("missing interface name or sw_if_index");
13068       return -99;
13069     }
13070
13071   /* Construct the API message */
13072   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13073   mp->sw_if_index = ntohl (sw_if_index);
13074   mp->enable_disable = enable_disable;
13075
13076   /* send it... */
13077   S (mp);
13078   /* Wait for the reply */
13079   W (ret);
13080   return ret;
13081 }
13082
13083 static int
13084 api_cop_whitelist_enable_disable (vat_main_t * vam)
13085 {
13086   unformat_input_t *line_input = vam->input;
13087   vl_api_cop_whitelist_enable_disable_t *mp;
13088   u32 sw_if_index = ~0;
13089   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13090   u32 fib_id = 0;
13091   int ret;
13092
13093   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13094     {
13095       if (unformat (line_input, "ip4"))
13096         ip4 = 1;
13097       else if (unformat (line_input, "ip6"))
13098         ip6 = 1;
13099       else if (unformat (line_input, "default"))
13100         default_cop = 1;
13101       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13102                          vam, &sw_if_index))
13103         ;
13104       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13105         ;
13106       else if (unformat (line_input, "fib-id %d", &fib_id))
13107         ;
13108       else
13109         break;
13110     }
13111
13112   if (sw_if_index == ~0)
13113     {
13114       errmsg ("missing interface name or sw_if_index");
13115       return -99;
13116     }
13117
13118   /* Construct the API message */
13119   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13120   mp->sw_if_index = ntohl (sw_if_index);
13121   mp->fib_id = ntohl (fib_id);
13122   mp->ip4 = ip4;
13123   mp->ip6 = ip6;
13124   mp->default_cop = default_cop;
13125
13126   /* send it... */
13127   S (mp);
13128   /* Wait for the reply */
13129   W (ret);
13130   return ret;
13131 }
13132
13133 static int
13134 api_get_node_graph (vat_main_t * vam)
13135 {
13136   vl_api_get_node_graph_t *mp;
13137   int ret;
13138
13139   M (GET_NODE_GRAPH, mp);
13140
13141   /* send it... */
13142   S (mp);
13143   /* Wait for the reply */
13144   W (ret);
13145   return ret;
13146 }
13147
13148 /* *INDENT-OFF* */
13149 /** Used for parsing LISP eids */
13150 typedef CLIB_PACKED(struct{
13151   u8 addr[16];   /**< eid address */
13152   u32 len;       /**< prefix length if IP */
13153   u8 type;      /**< type of eid */
13154 }) lisp_eid_vat_t;
13155 /* *INDENT-ON* */
13156
13157 static uword
13158 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13159 {
13160   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13161
13162   memset (a, 0, sizeof (a[0]));
13163
13164   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13165     {
13166       a->type = 0;              /* ipv4 type */
13167     }
13168   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13169     {
13170       a->type = 1;              /* ipv6 type */
13171     }
13172   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13173     {
13174       a->type = 2;              /* mac type */
13175     }
13176   else
13177     {
13178       return 0;
13179     }
13180
13181   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13182     {
13183       return 0;
13184     }
13185
13186   return 1;
13187 }
13188
13189 static int
13190 lisp_eid_size_vat (u8 type)
13191 {
13192   switch (type)
13193     {
13194     case 0:
13195       return 4;
13196     case 1:
13197       return 16;
13198     case 2:
13199       return 6;
13200     }
13201   return 0;
13202 }
13203
13204 static void
13205 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13206 {
13207   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13208 }
13209
13210 static int
13211 api_lisp_add_del_locator_set (vat_main_t * vam)
13212 {
13213   unformat_input_t *input = vam->input;
13214   vl_api_lisp_add_del_locator_set_t *mp;
13215   u8 is_add = 1;
13216   u8 *locator_set_name = NULL;
13217   u8 locator_set_name_set = 0;
13218   vl_api_local_locator_t locator, *locators = 0;
13219   u32 sw_if_index, priority, weight;
13220   u32 data_len = 0;
13221
13222   int ret;
13223   /* Parse args required to build the message */
13224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13225     {
13226       if (unformat (input, "del"))
13227         {
13228           is_add = 0;
13229         }
13230       else if (unformat (input, "locator-set %s", &locator_set_name))
13231         {
13232           locator_set_name_set = 1;
13233         }
13234       else if (unformat (input, "sw_if_index %u p %u w %u",
13235                          &sw_if_index, &priority, &weight))
13236         {
13237           locator.sw_if_index = htonl (sw_if_index);
13238           locator.priority = priority;
13239           locator.weight = weight;
13240           vec_add1 (locators, locator);
13241         }
13242       else
13243         if (unformat
13244             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13245              &sw_if_index, &priority, &weight))
13246         {
13247           locator.sw_if_index = htonl (sw_if_index);
13248           locator.priority = priority;
13249           locator.weight = weight;
13250           vec_add1 (locators, locator);
13251         }
13252       else
13253         break;
13254     }
13255
13256   if (locator_set_name_set == 0)
13257     {
13258       errmsg ("missing locator-set name");
13259       vec_free (locators);
13260       return -99;
13261     }
13262
13263   if (vec_len (locator_set_name) > 64)
13264     {
13265       errmsg ("locator-set name too long");
13266       vec_free (locator_set_name);
13267       vec_free (locators);
13268       return -99;
13269     }
13270   vec_add1 (locator_set_name, 0);
13271
13272   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13273
13274   /* Construct the API message */
13275   M2 (LISP_ADD_DEL_LOCATOR_SET, mp, data_len);
13276
13277   mp->is_add = is_add;
13278   clib_memcpy (mp->locator_set_name, locator_set_name,
13279                vec_len (locator_set_name));
13280   vec_free (locator_set_name);
13281
13282   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13283   if (locators)
13284     clib_memcpy (mp->locators, locators, data_len);
13285   vec_free (locators);
13286
13287   /* send it... */
13288   S (mp);
13289
13290   /* Wait for a reply... */
13291   W (ret);
13292   return ret;
13293 }
13294
13295 static int
13296 api_lisp_add_del_locator (vat_main_t * vam)
13297 {
13298   unformat_input_t *input = vam->input;
13299   vl_api_lisp_add_del_locator_t *mp;
13300   u32 tmp_if_index = ~0;
13301   u32 sw_if_index = ~0;
13302   u8 sw_if_index_set = 0;
13303   u8 sw_if_index_if_name_set = 0;
13304   u32 priority = ~0;
13305   u8 priority_set = 0;
13306   u32 weight = ~0;
13307   u8 weight_set = 0;
13308   u8 is_add = 1;
13309   u8 *locator_set_name = NULL;
13310   u8 locator_set_name_set = 0;
13311   int ret;
13312
13313   /* Parse args required to build the message */
13314   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13315     {
13316       if (unformat (input, "del"))
13317         {
13318           is_add = 0;
13319         }
13320       else if (unformat (input, "locator-set %s", &locator_set_name))
13321         {
13322           locator_set_name_set = 1;
13323         }
13324       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13325                          &tmp_if_index))
13326         {
13327           sw_if_index_if_name_set = 1;
13328           sw_if_index = tmp_if_index;
13329         }
13330       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13331         {
13332           sw_if_index_set = 1;
13333           sw_if_index = tmp_if_index;
13334         }
13335       else if (unformat (input, "p %d", &priority))
13336         {
13337           priority_set = 1;
13338         }
13339       else if (unformat (input, "w %d", &weight))
13340         {
13341           weight_set = 1;
13342         }
13343       else
13344         break;
13345     }
13346
13347   if (locator_set_name_set == 0)
13348     {
13349       errmsg ("missing locator-set name");
13350       return -99;
13351     }
13352
13353   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13354     {
13355       errmsg ("missing sw_if_index");
13356       vec_free (locator_set_name);
13357       return -99;
13358     }
13359
13360   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13361     {
13362       errmsg ("cannot use both params interface name and sw_if_index");
13363       vec_free (locator_set_name);
13364       return -99;
13365     }
13366
13367   if (priority_set == 0)
13368     {
13369       errmsg ("missing locator-set priority");
13370       vec_free (locator_set_name);
13371       return -99;
13372     }
13373
13374   if (weight_set == 0)
13375     {
13376       errmsg ("missing locator-set weight");
13377       vec_free (locator_set_name);
13378       return -99;
13379     }
13380
13381   if (vec_len (locator_set_name) > 64)
13382     {
13383       errmsg ("locator-set name too long");
13384       vec_free (locator_set_name);
13385       return -99;
13386     }
13387   vec_add1 (locator_set_name, 0);
13388
13389   /* Construct the API message */
13390   M (LISP_ADD_DEL_LOCATOR, mp);
13391
13392   mp->is_add = is_add;
13393   mp->sw_if_index = ntohl (sw_if_index);
13394   mp->priority = priority;
13395   mp->weight = weight;
13396   clib_memcpy (mp->locator_set_name, locator_set_name,
13397                vec_len (locator_set_name));
13398   vec_free (locator_set_name);
13399
13400   /* send it... */
13401   S (mp);
13402
13403   /* Wait for a reply... */
13404   W (ret);
13405   return ret;
13406 }
13407
13408 uword
13409 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13410 {
13411   u32 *key_id = va_arg (*args, u32 *);
13412   u8 *s = 0;
13413
13414   if (unformat (input, "%s", &s))
13415     {
13416       if (!strcmp ((char *) s, "sha1"))
13417         key_id[0] = HMAC_SHA_1_96;
13418       else if (!strcmp ((char *) s, "sha256"))
13419         key_id[0] = HMAC_SHA_256_128;
13420       else
13421         {
13422           clib_warning ("invalid key_id: '%s'", s);
13423           key_id[0] = HMAC_NO_KEY;
13424         }
13425     }
13426   else
13427     return 0;
13428
13429   vec_free (s);
13430   return 1;
13431 }
13432
13433 static int
13434 api_lisp_add_del_local_eid (vat_main_t * vam)
13435 {
13436   unformat_input_t *input = vam->input;
13437   vl_api_lisp_add_del_local_eid_t *mp;
13438   u8 is_add = 1;
13439   u8 eid_set = 0;
13440   lisp_eid_vat_t _eid, *eid = &_eid;
13441   u8 *locator_set_name = 0;
13442   u8 locator_set_name_set = 0;
13443   u32 vni = 0;
13444   u16 key_id = 0;
13445   u8 *key = 0;
13446   int ret;
13447
13448   /* Parse args required to build the message */
13449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13450     {
13451       if (unformat (input, "del"))
13452         {
13453           is_add = 0;
13454         }
13455       else if (unformat (input, "vni %d", &vni))
13456         {
13457           ;
13458         }
13459       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13460         {
13461           eid_set = 1;
13462         }
13463       else if (unformat (input, "locator-set %s", &locator_set_name))
13464         {
13465           locator_set_name_set = 1;
13466         }
13467       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13468         ;
13469       else if (unformat (input, "secret-key %_%v%_", &key))
13470         ;
13471       else
13472         break;
13473     }
13474
13475   if (locator_set_name_set == 0)
13476     {
13477       errmsg ("missing locator-set name");
13478       return -99;
13479     }
13480
13481   if (0 == eid_set)
13482     {
13483       errmsg ("EID address not set!");
13484       vec_free (locator_set_name);
13485       return -99;
13486     }
13487
13488   if (key && (0 == key_id))
13489     {
13490       errmsg ("invalid key_id!");
13491       return -99;
13492     }
13493
13494   if (vec_len (key) > 64)
13495     {
13496       errmsg ("key too long");
13497       vec_free (key);
13498       return -99;
13499     }
13500
13501   if (vec_len (locator_set_name) > 64)
13502     {
13503       errmsg ("locator-set name too long");
13504       vec_free (locator_set_name);
13505       return -99;
13506     }
13507   vec_add1 (locator_set_name, 0);
13508
13509   /* Construct the API message */
13510   M (LISP_ADD_DEL_LOCAL_EID, mp);
13511
13512   mp->is_add = is_add;
13513   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13514   mp->eid_type = eid->type;
13515   mp->prefix_len = eid->len;
13516   mp->vni = clib_host_to_net_u32 (vni);
13517   mp->key_id = clib_host_to_net_u16 (key_id);
13518   clib_memcpy (mp->locator_set_name, locator_set_name,
13519                vec_len (locator_set_name));
13520   clib_memcpy (mp->key, key, vec_len (key));
13521
13522   vec_free (locator_set_name);
13523   vec_free (key);
13524
13525   /* send it... */
13526   S (mp);
13527
13528   /* Wait for a reply... */
13529   W (ret);
13530   return ret;
13531 }
13532
13533 /* *INDENT-OFF* */
13534 /** Used for transferring locators via VPP API */
13535 typedef CLIB_PACKED(struct
13536 {
13537   u8 is_ip4; /**< is locator an IPv4 address? */
13538   u8 priority; /**< locator priority */
13539   u8 weight;   /**< locator weight */
13540   u8 addr[16]; /**< IPv4/IPv6 address */
13541 }) rloc_t;
13542 /* *INDENT-ON* */
13543
13544 static int
13545 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13546 {
13547   u32 dp_table = 0, vni = 0;;
13548   unformat_input_t *input = vam->input;
13549   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13550   u8 is_add = 1;
13551   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13552   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13553   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13554   u32 action = ~0, w;
13555   ip4_address_t rmt_rloc4, lcl_rloc4;
13556   ip6_address_t rmt_rloc6, lcl_rloc6;
13557   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13558     0;
13559   int ret;
13560
13561   memset (&rloc, 0, sizeof (rloc));
13562
13563   /* Parse args required to build the message */
13564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13565     {
13566       if (unformat (input, "del"))
13567         is_add = 0;
13568       else if (unformat (input, "add"))
13569         is_add = 1;
13570       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13571         {
13572           rmt_eid_set = 1;
13573         }
13574       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13575         {
13576           lcl_eid_set = 1;
13577         }
13578       else if (unformat (input, "vrf %d", &dp_table))
13579         ;
13580       else if (unformat (input, "bd %d", &dp_table))
13581         ;
13582       else if (unformat (input, "vni %d", &vni))
13583         ;
13584       else if (unformat (input, "w %d", &w))
13585         {
13586           if (!curr_rloc)
13587             {
13588               errmsg ("No RLOC configured for setting priority/weight!");
13589               return -99;
13590             }
13591           curr_rloc->weight = w;
13592         }
13593       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13594                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13595         {
13596           rloc.is_ip4 = 1;
13597
13598           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13599           rloc.weight = 0;
13600           vec_add1 (lcl_locs, rloc);
13601
13602           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13603           vec_add1 (rmt_locs, rloc);
13604           /* weight saved in rmt loc */
13605           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13606         }
13607       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13608                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13609         {
13610           rloc.is_ip4 = 0;
13611           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13612           rloc.weight = 0;
13613           vec_add1 (lcl_locs, rloc);
13614
13615           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13616           vec_add1 (rmt_locs, rloc);
13617           /* weight saved in rmt loc */
13618           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13619         }
13620       else if (unformat (input, "action %d", &action))
13621         {
13622           ;
13623         }
13624       else
13625         {
13626           clib_warning ("parse error '%U'", format_unformat_error, input);
13627           return -99;
13628         }
13629     }
13630
13631   if (!rmt_eid_set)
13632     {
13633       errmsg ("remote eid addresses not set");
13634       return -99;
13635     }
13636
13637   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13638     {
13639       errmsg ("eid types don't match");
13640       return -99;
13641     }
13642
13643   if (0 == rmt_locs && (u32) ~ 0 == action)
13644     {
13645       errmsg ("action not set for negative mapping");
13646       return -99;
13647     }
13648
13649   /* Construct the API message */
13650   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, mp,
13651       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13652
13653   mp->is_add = is_add;
13654   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13655   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13656   mp->eid_type = rmt_eid->type;
13657   mp->dp_table = clib_host_to_net_u32 (dp_table);
13658   mp->vni = clib_host_to_net_u32 (vni);
13659   mp->rmt_len = rmt_eid->len;
13660   mp->lcl_len = lcl_eid->len;
13661   mp->action = action;
13662
13663   if (0 != rmt_locs && 0 != lcl_locs)
13664     {
13665       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13666       clib_memcpy (mp->locs, lcl_locs,
13667                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13668
13669       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13670       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13671                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13672     }
13673   vec_free (lcl_locs);
13674   vec_free (rmt_locs);
13675
13676   /* send it... */
13677   S (mp);
13678
13679   /* Wait for a reply... */
13680   W (ret);
13681   return ret;
13682 }
13683
13684 static int
13685 api_lisp_add_del_map_server (vat_main_t * vam)
13686 {
13687   unformat_input_t *input = vam->input;
13688   vl_api_lisp_add_del_map_server_t *mp;
13689   u8 is_add = 1;
13690   u8 ipv4_set = 0;
13691   u8 ipv6_set = 0;
13692   ip4_address_t ipv4;
13693   ip6_address_t ipv6;
13694   int ret;
13695
13696   /* Parse args required to build the message */
13697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13698     {
13699       if (unformat (input, "del"))
13700         {
13701           is_add = 0;
13702         }
13703       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13704         {
13705           ipv4_set = 1;
13706         }
13707       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13708         {
13709           ipv6_set = 1;
13710         }
13711       else
13712         break;
13713     }
13714
13715   if (ipv4_set && ipv6_set)
13716     {
13717       errmsg ("both eid v4 and v6 addresses set");
13718       return -99;
13719     }
13720
13721   if (!ipv4_set && !ipv6_set)
13722     {
13723       errmsg ("eid addresses not set");
13724       return -99;
13725     }
13726
13727   /* Construct the API message */
13728   M (LISP_ADD_DEL_MAP_SERVER, mp);
13729
13730   mp->is_add = is_add;
13731   if (ipv6_set)
13732     {
13733       mp->is_ipv6 = 1;
13734       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13735     }
13736   else
13737     {
13738       mp->is_ipv6 = 0;
13739       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13740     }
13741
13742   /* send it... */
13743   S (mp);
13744
13745   /* Wait for a reply... */
13746   W (ret);
13747   return ret;
13748 }
13749
13750 static int
13751 api_lisp_add_del_map_resolver (vat_main_t * vam)
13752 {
13753   unformat_input_t *input = vam->input;
13754   vl_api_lisp_add_del_map_resolver_t *mp;
13755   u8 is_add = 1;
13756   u8 ipv4_set = 0;
13757   u8 ipv6_set = 0;
13758   ip4_address_t ipv4;
13759   ip6_address_t ipv6;
13760   int ret;
13761
13762   /* Parse args required to build the message */
13763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13764     {
13765       if (unformat (input, "del"))
13766         {
13767           is_add = 0;
13768         }
13769       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13770         {
13771           ipv4_set = 1;
13772         }
13773       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13774         {
13775           ipv6_set = 1;
13776         }
13777       else
13778         break;
13779     }
13780
13781   if (ipv4_set && ipv6_set)
13782     {
13783       errmsg ("both eid v4 and v6 addresses set");
13784       return -99;
13785     }
13786
13787   if (!ipv4_set && !ipv6_set)
13788     {
13789       errmsg ("eid addresses not set");
13790       return -99;
13791     }
13792
13793   /* Construct the API message */
13794   M (LISP_ADD_DEL_MAP_RESOLVER, mp);
13795
13796   mp->is_add = is_add;
13797   if (ipv6_set)
13798     {
13799       mp->is_ipv6 = 1;
13800       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13801     }
13802   else
13803     {
13804       mp->is_ipv6 = 0;
13805       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13806     }
13807
13808   /* send it... */
13809   S (mp);
13810
13811   /* Wait for a reply... */
13812   W (ret);
13813   return ret;
13814 }
13815
13816 static int
13817 api_lisp_gpe_enable_disable (vat_main_t * vam)
13818 {
13819   unformat_input_t *input = vam->input;
13820   vl_api_lisp_gpe_enable_disable_t *mp;
13821   u8 is_set = 0;
13822   u8 is_en = 1;
13823   int ret;
13824
13825   /* Parse args required to build the message */
13826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13827     {
13828       if (unformat (input, "enable"))
13829         {
13830           is_set = 1;
13831           is_en = 1;
13832         }
13833       else if (unformat (input, "disable"))
13834         {
13835           is_set = 1;
13836           is_en = 0;
13837         }
13838       else
13839         break;
13840     }
13841
13842   if (is_set == 0)
13843     {
13844       errmsg ("Value not set");
13845       return -99;
13846     }
13847
13848   /* Construct the API message */
13849   M (LISP_GPE_ENABLE_DISABLE, mp);
13850
13851   mp->is_en = is_en;
13852
13853   /* send it... */
13854   S (mp);
13855
13856   /* Wait for a reply... */
13857   W (ret);
13858   return ret;
13859 }
13860
13861 static int
13862 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13863 {
13864   unformat_input_t *input = vam->input;
13865   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13866   u8 is_set = 0;
13867   u8 is_en = 0;
13868   int ret;
13869
13870   /* Parse args required to build the message */
13871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13872     {
13873       if (unformat (input, "enable"))
13874         {
13875           is_set = 1;
13876           is_en = 1;
13877         }
13878       else if (unformat (input, "disable"))
13879         is_set = 1;
13880       else
13881         break;
13882     }
13883
13884   if (!is_set)
13885     {
13886       errmsg ("Value not set");
13887       return -99;
13888     }
13889
13890   /* Construct the API message */
13891   M (LISP_RLOC_PROBE_ENABLE_DISABLE, mp);
13892
13893   mp->is_enabled = is_en;
13894
13895   /* send it... */
13896   S (mp);
13897
13898   /* Wait for a reply... */
13899   W (ret);
13900   return ret;
13901 }
13902
13903 static int
13904 api_lisp_map_register_enable_disable (vat_main_t * vam)
13905 {
13906   unformat_input_t *input = vam->input;
13907   vl_api_lisp_map_register_enable_disable_t *mp;
13908   u8 is_set = 0;
13909   u8 is_en = 0;
13910   int ret;
13911
13912   /* Parse args required to build the message */
13913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13914     {
13915       if (unformat (input, "enable"))
13916         {
13917           is_set = 1;
13918           is_en = 1;
13919         }
13920       else if (unformat (input, "disable"))
13921         is_set = 1;
13922       else
13923         break;
13924     }
13925
13926   if (!is_set)
13927     {
13928       errmsg ("Value not set");
13929       return -99;
13930     }
13931
13932   /* Construct the API message */
13933   M (LISP_MAP_REGISTER_ENABLE_DISABLE, mp);
13934
13935   mp->is_enabled = is_en;
13936
13937   /* send it... */
13938   S (mp);
13939
13940   /* Wait for a reply... */
13941   W (ret);
13942   return ret;
13943 }
13944
13945 static int
13946 api_lisp_enable_disable (vat_main_t * vam)
13947 {
13948   unformat_input_t *input = vam->input;
13949   vl_api_lisp_enable_disable_t *mp;
13950   u8 is_set = 0;
13951   u8 is_en = 0;
13952   int ret;
13953
13954   /* Parse args required to build the message */
13955   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13956     {
13957       if (unformat (input, "enable"))
13958         {
13959           is_set = 1;
13960           is_en = 1;
13961         }
13962       else if (unformat (input, "disable"))
13963         {
13964           is_set = 1;
13965         }
13966       else
13967         break;
13968     }
13969
13970   if (!is_set)
13971     {
13972       errmsg ("Value not set");
13973       return -99;
13974     }
13975
13976   /* Construct the API message */
13977   M (LISP_ENABLE_DISABLE, mp);
13978
13979   mp->is_en = is_en;
13980
13981   /* send it... */
13982   S (mp);
13983
13984   /* Wait for a reply... */
13985   W (ret);
13986   return ret;
13987 }
13988
13989 static int
13990 api_show_lisp_map_register_state (vat_main_t * vam)
13991 {
13992   vl_api_show_lisp_map_register_state_t *mp;
13993   int ret;
13994
13995   M (SHOW_LISP_MAP_REGISTER_STATE, mp);
13996
13997   /* send */
13998   S (mp);
13999
14000   /* wait for reply */
14001   W (ret);
14002   return ret;
14003 }
14004
14005 static int
14006 api_show_lisp_rloc_probe_state (vat_main_t * vam)
14007 {
14008   vl_api_show_lisp_rloc_probe_state_t *mp;
14009   int ret;
14010
14011   M (SHOW_LISP_RLOC_PROBE_STATE, mp);
14012
14013   /* send */
14014   S (mp);
14015
14016   /* wait for reply */
14017   W (ret);
14018   return ret;
14019 }
14020
14021 static int
14022 api_show_lisp_map_request_mode (vat_main_t * vam)
14023 {
14024   vl_api_show_lisp_map_request_mode_t *mp;
14025   int ret;
14026
14027   M (SHOW_LISP_MAP_REQUEST_MODE, mp);
14028
14029   /* send */
14030   S (mp);
14031
14032   /* wait for reply */
14033   W (ret);
14034   return ret;
14035 }
14036
14037 static int
14038 api_lisp_map_request_mode (vat_main_t * vam)
14039 {
14040   unformat_input_t *input = vam->input;
14041   vl_api_lisp_map_request_mode_t *mp;
14042   u8 mode = 0;
14043   int ret;
14044
14045   /* Parse args required to build the message */
14046   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14047     {
14048       if (unformat (input, "dst-only"))
14049         mode = 0;
14050       else if (unformat (input, "src-dst"))
14051         mode = 1;
14052       else
14053         {
14054           errmsg ("parse error '%U'", format_unformat_error, input);
14055           return -99;
14056         }
14057     }
14058
14059   M (LISP_MAP_REQUEST_MODE, mp);
14060
14061   mp->mode = mode;
14062
14063   /* send */
14064   S (mp);
14065
14066   /* wait for reply */
14067   W (ret);
14068   return ret;
14069 }
14070
14071 /**
14072  * Enable/disable LISP proxy ITR.
14073  *
14074  * @param vam vpp API test context
14075  * @return return code
14076  */
14077 static int
14078 api_lisp_pitr_set_locator_set (vat_main_t * vam)
14079 {
14080   u8 ls_name_set = 0;
14081   unformat_input_t *input = vam->input;
14082   vl_api_lisp_pitr_set_locator_set_t *mp;
14083   u8 is_add = 1;
14084   u8 *ls_name = 0;
14085   int ret;
14086
14087   /* Parse args required to build the message */
14088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14089     {
14090       if (unformat (input, "del"))
14091         is_add = 0;
14092       else if (unformat (input, "locator-set %s", &ls_name))
14093         ls_name_set = 1;
14094       else
14095         {
14096           errmsg ("parse error '%U'", format_unformat_error, input);
14097           return -99;
14098         }
14099     }
14100
14101   if (!ls_name_set)
14102     {
14103       errmsg ("locator-set name not set!");
14104       return -99;
14105     }
14106
14107   M (LISP_PITR_SET_LOCATOR_SET, mp);
14108
14109   mp->is_add = is_add;
14110   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14111   vec_free (ls_name);
14112
14113   /* send */
14114   S (mp);
14115
14116   /* wait for reply */
14117   W (ret);
14118   return ret;
14119 }
14120
14121 static int
14122 api_show_lisp_pitr (vat_main_t * vam)
14123 {
14124   vl_api_show_lisp_pitr_t *mp;
14125   int ret;
14126
14127   if (!vam->json_output)
14128     {
14129       print (vam->ofp, "%=20s", "lisp status:");
14130     }
14131
14132   M (SHOW_LISP_PITR, mp);
14133   /* send it... */
14134   S (mp);
14135
14136   /* Wait for a reply... */
14137   W (ret);
14138   return ret;
14139 }
14140
14141 /**
14142  * Add/delete mapping between vni and vrf
14143  */
14144 static int
14145 api_lisp_eid_table_add_del_map (vat_main_t * vam)
14146 {
14147   unformat_input_t *input = vam->input;
14148   vl_api_lisp_eid_table_add_del_map_t *mp;
14149   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14150   u32 vni, vrf, bd_index;
14151   int ret;
14152
14153   /* Parse args required to build the message */
14154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14155     {
14156       if (unformat (input, "del"))
14157         is_add = 0;
14158       else if (unformat (input, "vrf %d", &vrf))
14159         vrf_set = 1;
14160       else if (unformat (input, "bd_index %d", &bd_index))
14161         bd_index_set = 1;
14162       else if (unformat (input, "vni %d", &vni))
14163         vni_set = 1;
14164       else
14165         break;
14166     }
14167
14168   if (!vni_set || (!vrf_set && !bd_index_set))
14169     {
14170       errmsg ("missing arguments!");
14171       return -99;
14172     }
14173
14174   if (vrf_set && bd_index_set)
14175     {
14176       errmsg ("error: both vrf and bd entered!");
14177       return -99;
14178     }
14179
14180   M (LISP_EID_TABLE_ADD_DEL_MAP, mp);
14181
14182   mp->is_add = is_add;
14183   mp->vni = htonl (vni);
14184   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14185   mp->is_l2 = bd_index_set;
14186
14187   /* send */
14188   S (mp);
14189
14190   /* wait for reply */
14191   W (ret);
14192   return ret;
14193 }
14194
14195 uword
14196 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14197 {
14198   u32 *action = va_arg (*args, u32 *);
14199   u8 *s = 0;
14200
14201   if (unformat (input, "%s", &s))
14202     {
14203       if (!strcmp ((char *) s, "no-action"))
14204         action[0] = 0;
14205       else if (!strcmp ((char *) s, "natively-forward"))
14206         action[0] = 1;
14207       else if (!strcmp ((char *) s, "send-map-request"))
14208         action[0] = 2;
14209       else if (!strcmp ((char *) s, "drop"))
14210         action[0] = 3;
14211       else
14212         {
14213           clib_warning ("invalid action: '%s'", s);
14214           action[0] = 3;
14215         }
14216     }
14217   else
14218     return 0;
14219
14220   vec_free (s);
14221   return 1;
14222 }
14223
14224 /**
14225  * Add/del remote mapping to/from LISP control plane
14226  *
14227  * @param vam vpp API test context
14228  * @return return code
14229  */
14230 static int
14231 api_lisp_add_del_remote_mapping (vat_main_t * vam)
14232 {
14233   unformat_input_t *input = vam->input;
14234   vl_api_lisp_add_del_remote_mapping_t *mp;
14235   u32 vni = 0;
14236   lisp_eid_vat_t _eid, *eid = &_eid;
14237   lisp_eid_vat_t _seid, *seid = &_seid;
14238   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14239   u32 action = ~0, p, w, data_len;
14240   ip4_address_t rloc4;
14241   ip6_address_t rloc6;
14242   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14243   int ret;
14244
14245   memset (&rloc, 0, sizeof (rloc));
14246
14247   /* Parse args required to build the message */
14248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14249     {
14250       if (unformat (input, "del-all"))
14251         {
14252           del_all = 1;
14253         }
14254       else if (unformat (input, "del"))
14255         {
14256           is_add = 0;
14257         }
14258       else if (unformat (input, "add"))
14259         {
14260           is_add = 1;
14261         }
14262       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14263         {
14264           eid_set = 1;
14265         }
14266       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14267         {
14268           seid_set = 1;
14269         }
14270       else if (unformat (input, "vni %d", &vni))
14271         {
14272           ;
14273         }
14274       else if (unformat (input, "p %d w %d", &p, &w))
14275         {
14276           if (!curr_rloc)
14277             {
14278               errmsg ("No RLOC configured for setting priority/weight!");
14279               return -99;
14280             }
14281           curr_rloc->priority = p;
14282           curr_rloc->weight = w;
14283         }
14284       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14285         {
14286           rloc.is_ip4 = 1;
14287           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14288           vec_add1 (rlocs, rloc);
14289           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14290         }
14291       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14292         {
14293           rloc.is_ip4 = 0;
14294           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14295           vec_add1 (rlocs, rloc);
14296           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14297         }
14298       else if (unformat (input, "action %U",
14299                          unformat_negative_mapping_action, &action))
14300         {
14301           ;
14302         }
14303       else
14304         {
14305           clib_warning ("parse error '%U'", format_unformat_error, input);
14306           return -99;
14307         }
14308     }
14309
14310   if (0 == eid_set)
14311     {
14312       errmsg ("missing params!");
14313       return -99;
14314     }
14315
14316   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14317     {
14318       errmsg ("no action set for negative map-reply!");
14319       return -99;
14320     }
14321
14322   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14323
14324   M2 (LISP_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14325   mp->is_add = is_add;
14326   mp->vni = htonl (vni);
14327   mp->action = (u8) action;
14328   mp->is_src_dst = seid_set;
14329   mp->eid_len = eid->len;
14330   mp->seid_len = seid->len;
14331   mp->del_all = del_all;
14332   mp->eid_type = eid->type;
14333   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14334   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14335
14336   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14337   clib_memcpy (mp->rlocs, rlocs, data_len);
14338   vec_free (rlocs);
14339
14340   /* send it... */
14341   S (mp);
14342
14343   /* Wait for a reply... */
14344   W (ret);
14345   return ret;
14346 }
14347
14348 /**
14349  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14350  * forwarding entries in data-plane accordingly.
14351  *
14352  * @param vam vpp API test context
14353  * @return return code
14354  */
14355 static int
14356 api_lisp_add_del_adjacency (vat_main_t * vam)
14357 {
14358   unformat_input_t *input = vam->input;
14359   vl_api_lisp_add_del_adjacency_t *mp;
14360   u32 vni = 0;
14361   ip4_address_t leid4, reid4;
14362   ip6_address_t leid6, reid6;
14363   u8 reid_mac[6] = { 0 };
14364   u8 leid_mac[6] = { 0 };
14365   u8 reid_type, leid_type;
14366   u32 leid_len = 0, reid_len = 0, len;
14367   u8 is_add = 1;
14368   int ret;
14369
14370   leid_type = reid_type = (u8) ~ 0;
14371
14372   /* Parse args required to build the message */
14373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14374     {
14375       if (unformat (input, "del"))
14376         {
14377           is_add = 0;
14378         }
14379       else if (unformat (input, "add"))
14380         {
14381           is_add = 1;
14382         }
14383       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14384                          &reid4, &len))
14385         {
14386           reid_type = 0;        /* ipv4 */
14387           reid_len = len;
14388         }
14389       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14390                          &reid6, &len))
14391         {
14392           reid_type = 1;        /* ipv6 */
14393           reid_len = len;
14394         }
14395       else if (unformat (input, "reid %U", unformat_ethernet_address,
14396                          reid_mac))
14397         {
14398           reid_type = 2;        /* mac */
14399         }
14400       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14401                          &leid4, &len))
14402         {
14403           leid_type = 0;        /* ipv4 */
14404           leid_len = len;
14405         }
14406       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14407                          &leid6, &len))
14408         {
14409           leid_type = 1;        /* ipv6 */
14410           leid_len = len;
14411         }
14412       else if (unformat (input, "leid %U", unformat_ethernet_address,
14413                          leid_mac))
14414         {
14415           leid_type = 2;        /* mac */
14416         }
14417       else if (unformat (input, "vni %d", &vni))
14418         {
14419           ;
14420         }
14421       else
14422         {
14423           errmsg ("parse error '%U'", format_unformat_error, input);
14424           return -99;
14425         }
14426     }
14427
14428   if ((u8) ~ 0 == reid_type)
14429     {
14430       errmsg ("missing params!");
14431       return -99;
14432     }
14433
14434   if (leid_type != reid_type)
14435     {
14436       errmsg ("remote and local EIDs are of different types!");
14437       return -99;
14438     }
14439
14440   M (LISP_ADD_DEL_ADJACENCY, mp);
14441   mp->is_add = is_add;
14442   mp->vni = htonl (vni);
14443   mp->leid_len = leid_len;
14444   mp->reid_len = reid_len;
14445   mp->eid_type = reid_type;
14446
14447   switch (mp->eid_type)
14448     {
14449     case 0:
14450       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14451       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14452       break;
14453     case 1:
14454       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14455       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14456       break;
14457     case 2:
14458       clib_memcpy (mp->leid, leid_mac, 6);
14459       clib_memcpy (mp->reid, reid_mac, 6);
14460       break;
14461     default:
14462       errmsg ("unknown EID type %d!", mp->eid_type);
14463       return 0;
14464     }
14465
14466   /* send it... */
14467   S (mp);
14468
14469   /* Wait for a reply... */
14470   W (ret);
14471   return ret;
14472 }
14473
14474 static int
14475 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14476 {
14477   unformat_input_t *input = vam->input;
14478   vl_api_lisp_gpe_add_del_iface_t *mp;
14479   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14480   u32 dp_table = 0, vni = 0;
14481   int ret;
14482
14483   /* Parse args required to build the message */
14484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14485     {
14486       if (unformat (input, "up"))
14487         {
14488           action_set = 1;
14489           is_add = 1;
14490         }
14491       else if (unformat (input, "down"))
14492         {
14493           action_set = 1;
14494           is_add = 0;
14495         }
14496       else if (unformat (input, "table_id %d", &dp_table))
14497         {
14498           dp_table_set = 1;
14499         }
14500       else if (unformat (input, "bd_id %d", &dp_table))
14501         {
14502           dp_table_set = 1;
14503           is_l2 = 1;
14504         }
14505       else if (unformat (input, "vni %d", &vni))
14506         {
14507           vni_set = 1;
14508         }
14509       else
14510         break;
14511     }
14512
14513   if (action_set == 0)
14514     {
14515       errmsg ("Action not set");
14516       return -99;
14517     }
14518   if (dp_table_set == 0 || vni_set == 0)
14519     {
14520       errmsg ("vni and dp_table must be set");
14521       return -99;
14522     }
14523
14524   /* Construct the API message */
14525   M (LISP_GPE_ADD_DEL_IFACE, mp);
14526
14527   mp->is_add = is_add;
14528   mp->dp_table = dp_table;
14529   mp->is_l2 = is_l2;
14530   mp->vni = vni;
14531
14532   /* send it... */
14533   S (mp);
14534
14535   /* Wait for a reply... */
14536   W (ret);
14537   return ret;
14538 }
14539
14540 /**
14541  * Add/del map request itr rlocs from LISP control plane and updates
14542  *
14543  * @param vam vpp API test context
14544  * @return return code
14545  */
14546 static int
14547 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14548 {
14549   unformat_input_t *input = vam->input;
14550   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14551   u8 *locator_set_name = 0;
14552   u8 locator_set_name_set = 0;
14553   u8 is_add = 1;
14554   int ret;
14555
14556   /* Parse args required to build the message */
14557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14558     {
14559       if (unformat (input, "del"))
14560         {
14561           is_add = 0;
14562         }
14563       else if (unformat (input, "%_%v%_", &locator_set_name))
14564         {
14565           locator_set_name_set = 1;
14566         }
14567       else
14568         {
14569           clib_warning ("parse error '%U'", format_unformat_error, input);
14570           return -99;
14571         }
14572     }
14573
14574   if (is_add && !locator_set_name_set)
14575     {
14576       errmsg ("itr-rloc is not set!");
14577       return -99;
14578     }
14579
14580   if (is_add && vec_len (locator_set_name) > 64)
14581     {
14582       errmsg ("itr-rloc locator-set name too long");
14583       vec_free (locator_set_name);
14584       return -99;
14585     }
14586
14587   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14588   mp->is_add = is_add;
14589   if (is_add)
14590     {
14591       clib_memcpy (mp->locator_set_name, locator_set_name,
14592                    vec_len (locator_set_name));
14593     }
14594   else
14595     {
14596       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14597     }
14598   vec_free (locator_set_name);
14599
14600   /* send it... */
14601   S (mp);
14602
14603   /* Wait for a reply... */
14604   W (ret);
14605   return ret;
14606 }
14607
14608 static int
14609 api_lisp_locator_dump (vat_main_t * vam)
14610 {
14611   unformat_input_t *input = vam->input;
14612   vl_api_lisp_locator_dump_t *mp;
14613   vl_api_control_ping_t *mp_ping;
14614   u8 is_index_set = 0, is_name_set = 0;
14615   u8 *ls_name = 0;
14616   u32 ls_index = ~0;
14617   int ret;
14618
14619   /* Parse args required to build the message */
14620   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14621     {
14622       if (unformat (input, "ls_name %_%v%_", &ls_name))
14623         {
14624           is_name_set = 1;
14625         }
14626       else if (unformat (input, "ls_index %d", &ls_index))
14627         {
14628           is_index_set = 1;
14629         }
14630       else
14631         {
14632           errmsg ("parse error '%U'", format_unformat_error, input);
14633           return -99;
14634         }
14635     }
14636
14637   if (!is_index_set && !is_name_set)
14638     {
14639       errmsg ("error: expected one of index or name!");
14640       return -99;
14641     }
14642
14643   if (is_index_set && is_name_set)
14644     {
14645       errmsg ("error: only one param expected!");
14646       return -99;
14647     }
14648
14649   if (vec_len (ls_name) > 62)
14650     {
14651       errmsg ("error: locator set name too long!");
14652       return -99;
14653     }
14654
14655   if (!vam->json_output)
14656     {
14657       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14658     }
14659
14660   M (LISP_LOCATOR_DUMP, mp);
14661   mp->is_index_set = is_index_set;
14662
14663   if (is_index_set)
14664     mp->ls_index = clib_host_to_net_u32 (ls_index);
14665   else
14666     {
14667       vec_add1 (ls_name, 0);
14668       strncpy ((char *) mp->ls_name, (char *) ls_name,
14669                sizeof (mp->ls_name) - 1);
14670     }
14671
14672   /* send it... */
14673   S (mp);
14674
14675   /* Use a control ping for synchronization */
14676   M (CONTROL_PING, mp_ping);
14677   S (mp_ping);
14678
14679   /* Wait for a reply... */
14680   W (ret);
14681   return ret;
14682 }
14683
14684 static int
14685 api_lisp_locator_set_dump (vat_main_t * vam)
14686 {
14687   vl_api_lisp_locator_set_dump_t *mp;
14688   vl_api_control_ping_t *mp_ping;
14689   unformat_input_t *input = vam->input;
14690   u8 filter = 0;
14691   int ret;
14692
14693   /* Parse args required to build the message */
14694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14695     {
14696       if (unformat (input, "local"))
14697         {
14698           filter = 1;
14699         }
14700       else if (unformat (input, "remote"))
14701         {
14702           filter = 2;
14703         }
14704       else
14705         {
14706           errmsg ("parse error '%U'", format_unformat_error, input);
14707           return -99;
14708         }
14709     }
14710
14711   if (!vam->json_output)
14712     {
14713       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14714     }
14715
14716   M (LISP_LOCATOR_SET_DUMP, mp);
14717
14718   mp->filter = filter;
14719
14720   /* send it... */
14721   S (mp);
14722
14723   /* Use a control ping for synchronization */
14724   M (CONTROL_PING, mp_ping);
14725   S (mp_ping);
14726
14727   /* Wait for a reply... */
14728   W (ret);
14729   return ret;
14730 }
14731
14732 static int
14733 api_lisp_eid_table_map_dump (vat_main_t * vam)
14734 {
14735   u8 is_l2 = 0;
14736   u8 mode_set = 0;
14737   unformat_input_t *input = vam->input;
14738   vl_api_lisp_eid_table_map_dump_t *mp;
14739   vl_api_control_ping_t *mp_ping;
14740   int ret;
14741
14742   /* Parse args required to build the message */
14743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14744     {
14745       if (unformat (input, "l2"))
14746         {
14747           is_l2 = 1;
14748           mode_set = 1;
14749         }
14750       else if (unformat (input, "l3"))
14751         {
14752           is_l2 = 0;
14753           mode_set = 1;
14754         }
14755       else
14756         {
14757           errmsg ("parse error '%U'", format_unformat_error, input);
14758           return -99;
14759         }
14760     }
14761
14762   if (!mode_set)
14763     {
14764       errmsg ("expected one of 'l2' or 'l3' parameter!");
14765       return -99;
14766     }
14767
14768   if (!vam->json_output)
14769     {
14770       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14771     }
14772
14773   M (LISP_EID_TABLE_MAP_DUMP, mp);
14774   mp->is_l2 = is_l2;
14775
14776   /* send it... */
14777   S (mp);
14778
14779   /* Use a control ping for synchronization */
14780   M (CONTROL_PING, mp_ping);
14781   S (mp_ping);
14782
14783   /* Wait for a reply... */
14784   W (ret);
14785   return ret;
14786 }
14787
14788 static int
14789 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14790 {
14791   vl_api_lisp_eid_table_vni_dump_t *mp;
14792   vl_api_control_ping_t *mp_ping;
14793   int ret;
14794
14795   if (!vam->json_output)
14796     {
14797       print (vam->ofp, "VNI");
14798     }
14799
14800   M (LISP_EID_TABLE_VNI_DUMP, mp);
14801
14802   /* send it... */
14803   S (mp);
14804
14805   /* Use a control ping for synchronization */
14806   M (CONTROL_PING, mp_ping);
14807   S (mp_ping);
14808
14809   /* Wait for a reply... */
14810   W (ret);
14811   return ret;
14812 }
14813
14814 static int
14815 api_lisp_eid_table_dump (vat_main_t * vam)
14816 {
14817   unformat_input_t *i = vam->input;
14818   vl_api_lisp_eid_table_dump_t *mp;
14819   vl_api_control_ping_t *mp_ping;
14820   struct in_addr ip4;
14821   struct in6_addr ip6;
14822   u8 mac[6];
14823   u8 eid_type = ~0, eid_set = 0;
14824   u32 prefix_length = ~0, t, vni = 0;
14825   u8 filter = 0;
14826   int ret;
14827
14828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14829     {
14830       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14831         {
14832           eid_set = 1;
14833           eid_type = 0;
14834           prefix_length = t;
14835         }
14836       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14837         {
14838           eid_set = 1;
14839           eid_type = 1;
14840           prefix_length = t;
14841         }
14842       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14843         {
14844           eid_set = 1;
14845           eid_type = 2;
14846         }
14847       else if (unformat (i, "vni %d", &t))
14848         {
14849           vni = t;
14850         }
14851       else if (unformat (i, "local"))
14852         {
14853           filter = 1;
14854         }
14855       else if (unformat (i, "remote"))
14856         {
14857           filter = 2;
14858         }
14859       else
14860         {
14861           errmsg ("parse error '%U'", format_unformat_error, i);
14862           return -99;
14863         }
14864     }
14865
14866   if (!vam->json_output)
14867     {
14868       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14869              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14870     }
14871
14872   M (LISP_EID_TABLE_DUMP, mp);
14873
14874   mp->filter = filter;
14875   if (eid_set)
14876     {
14877       mp->eid_set = 1;
14878       mp->vni = htonl (vni);
14879       mp->eid_type = eid_type;
14880       switch (eid_type)
14881         {
14882         case 0:
14883           mp->prefix_length = prefix_length;
14884           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14885           break;
14886         case 1:
14887           mp->prefix_length = prefix_length;
14888           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14889           break;
14890         case 2:
14891           clib_memcpy (mp->eid, mac, sizeof (mac));
14892           break;
14893         default:
14894           errmsg ("unknown EID type %d!", eid_type);
14895           return -99;
14896         }
14897     }
14898
14899   /* send it... */
14900   S (mp);
14901
14902   /* Use a control ping for synchronization */
14903   M (CONTROL_PING, mp_ping);
14904   S (mp_ping);
14905
14906   /* Wait for a reply... */
14907   W (ret);
14908   return ret;
14909 }
14910
14911 static int
14912 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
14913 {
14914   unformat_input_t *i = vam->input;
14915   vl_api_lisp_gpe_fwd_entries_get_t *mp;
14916   u8 vni_set = 0;
14917   u32 vni = ~0;
14918   int ret;
14919
14920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14921     {
14922       if (unformat (i, "vni %d", &vni))
14923         {
14924           vni_set = 1;
14925         }
14926       else
14927         {
14928           errmsg ("parse error '%U'", format_unformat_error, i);
14929           return -99;
14930         }
14931     }
14932
14933   if (!vni_set)
14934     {
14935       errmsg ("vni not set!");
14936       return -99;
14937     }
14938
14939   if (!vam->json_output)
14940     {
14941       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
14942              "leid", "reid");
14943     }
14944
14945   M (LISP_GPE_FWD_ENTRIES_GET, mp);
14946   mp->vni = clib_host_to_net_u32 (vni);
14947
14948   /* send it... */
14949   S (mp);
14950
14951   /* Wait for a reply... */
14952   W (ret);
14953   return ret;
14954 }
14955
14956 #define vl_api_lisp_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
14957 #define vl_api_lisp_gpe_fwd_entries_get_reply_t_print vl_noop_handler
14958 #define vl_api_lisp_gpe_fwd_entry_path_details_t_endian vl_noop_handler
14959 #define vl_api_lisp_gpe_fwd_entry_path_details_t_print vl_noop_handler
14960
14961 static int
14962 api_lisp_adjacencies_get (vat_main_t * vam)
14963 {
14964   unformat_input_t *i = vam->input;
14965   vl_api_lisp_adjacencies_get_t *mp;
14966   u8 vni_set = 0;
14967   u32 vni = ~0;
14968   int ret;
14969
14970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14971     {
14972       if (unformat (i, "vni %d", &vni))
14973         {
14974           vni_set = 1;
14975         }
14976       else
14977         {
14978           errmsg ("parse error '%U'", format_unformat_error, i);
14979           return -99;
14980         }
14981     }
14982
14983   if (!vni_set)
14984     {
14985       errmsg ("vni not set!");
14986       return -99;
14987     }
14988
14989   if (!vam->json_output)
14990     {
14991       print (vam->ofp, "%s %40s", "leid", "reid");
14992     }
14993
14994   M (LISP_ADJACENCIES_GET, mp);
14995   mp->vni = clib_host_to_net_u32 (vni);
14996
14997   /* send it... */
14998   S (mp);
14999
15000   /* Wait for a reply... */
15001   W (ret);
15002   return ret;
15003 }
15004
15005 static int
15006 api_lisp_map_server_dump (vat_main_t * vam)
15007 {
15008   vl_api_lisp_map_server_dump_t *mp;
15009   vl_api_control_ping_t *mp_ping;
15010   int ret;
15011
15012   if (!vam->json_output)
15013     {
15014       print (vam->ofp, "%=20s", "Map server");
15015     }
15016
15017   M (LISP_MAP_SERVER_DUMP, mp);
15018   /* send it... */
15019   S (mp);
15020
15021   /* Use a control ping for synchronization */
15022   M (CONTROL_PING, mp_ping);
15023   S (mp_ping);
15024
15025   /* Wait for a reply... */
15026   W (ret);
15027   return ret;
15028 }
15029
15030 static int
15031 api_lisp_map_resolver_dump (vat_main_t * vam)
15032 {
15033   vl_api_lisp_map_resolver_dump_t *mp;
15034   vl_api_control_ping_t *mp_ping;
15035   int ret;
15036
15037   if (!vam->json_output)
15038     {
15039       print (vam->ofp, "%=20s", "Map resolver");
15040     }
15041
15042   M (LISP_MAP_RESOLVER_DUMP, mp);
15043   /* send it... */
15044   S (mp);
15045
15046   /* Use a control ping for synchronization */
15047   M (CONTROL_PING, mp_ping);
15048   S (mp_ping);
15049
15050   /* Wait for a reply... */
15051   W (ret);
15052   return ret;
15053 }
15054
15055 static int
15056 api_show_lisp_status (vat_main_t * vam)
15057 {
15058   vl_api_show_lisp_status_t *mp;
15059   int ret;
15060
15061   if (!vam->json_output)
15062     {
15063       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
15064     }
15065
15066   M (SHOW_LISP_STATUS, mp);
15067   /* send it... */
15068   S (mp);
15069   /* Wait for a reply... */
15070   W (ret);
15071   return ret;
15072 }
15073
15074 static int
15075 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15076 {
15077   vl_api_lisp_gpe_fwd_entry_path_dump_t *mp;
15078   vl_api_control_ping_t *mp_ping;
15079   unformat_input_t *i = vam->input;
15080   u32 fwd_entry_index = ~0;
15081   int ret;
15082
15083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15084     {
15085       if (unformat (i, "index %d", &fwd_entry_index))
15086         ;
15087       else
15088         break;
15089     }
15090
15091   if (~0 == fwd_entry_index)
15092     {
15093       errmsg ("no index specified!");
15094       return -99;
15095     }
15096
15097   if (!vam->json_output)
15098     {
15099       print (vam->ofp, "first line");
15100     }
15101
15102   M (LISP_GPE_FWD_ENTRY_PATH_DUMP, mp);
15103
15104   /* send it... */
15105   S (mp);
15106   /* Use a control ping for synchronization */
15107   M (CONTROL_PING, mp_ping);
15108   S (mp_ping);
15109
15110   /* Wait for a reply... */
15111   W (ret);
15112   return ret;
15113 }
15114
15115 static int
15116 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
15117 {
15118   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
15119   int ret;
15120
15121   if (!vam->json_output)
15122     {
15123       print (vam->ofp, "%=20s", "itr-rlocs:");
15124     }
15125
15126   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, mp);
15127   /* send it... */
15128   S (mp);
15129   /* Wait for a reply... */
15130   W (ret);
15131   return ret;
15132 }
15133
15134 static int
15135 api_af_packet_create (vat_main_t * vam)
15136 {
15137   unformat_input_t *i = vam->input;
15138   vl_api_af_packet_create_t *mp;
15139   u8 *host_if_name = 0;
15140   u8 hw_addr[6];
15141   u8 random_hw_addr = 1;
15142   int ret;
15143
15144   memset (hw_addr, 0, sizeof (hw_addr));
15145
15146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15147     {
15148       if (unformat (i, "name %s", &host_if_name))
15149         vec_add1 (host_if_name, 0);
15150       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15151         random_hw_addr = 0;
15152       else
15153         break;
15154     }
15155
15156   if (!vec_len (host_if_name))
15157     {
15158       errmsg ("host-interface name must be specified");
15159       return -99;
15160     }
15161
15162   if (vec_len (host_if_name) > 64)
15163     {
15164       errmsg ("host-interface name too long");
15165       return -99;
15166     }
15167
15168   M (AF_PACKET_CREATE, mp);
15169
15170   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15171   clib_memcpy (mp->hw_addr, hw_addr, 6);
15172   mp->use_random_hw_addr = random_hw_addr;
15173   vec_free (host_if_name);
15174
15175   S (mp);
15176   W2 (ret, fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15177   return ret;
15178 }
15179
15180 static int
15181 api_af_packet_delete (vat_main_t * vam)
15182 {
15183   unformat_input_t *i = vam->input;
15184   vl_api_af_packet_delete_t *mp;
15185   u8 *host_if_name = 0;
15186   int ret;
15187
15188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15189     {
15190       if (unformat (i, "name %s", &host_if_name))
15191         vec_add1 (host_if_name, 0);
15192       else
15193         break;
15194     }
15195
15196   if (!vec_len (host_if_name))
15197     {
15198       errmsg ("host-interface name must be specified");
15199       return -99;
15200     }
15201
15202   if (vec_len (host_if_name) > 64)
15203     {
15204       errmsg ("host-interface name too long");
15205       return -99;
15206     }
15207
15208   M (AF_PACKET_DELETE, mp);
15209
15210   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15211   vec_free (host_if_name);
15212
15213   S (mp);
15214   W (ret);
15215   return ret;
15216 }
15217
15218 static int
15219 api_policer_add_del (vat_main_t * vam)
15220 {
15221   unformat_input_t *i = vam->input;
15222   vl_api_policer_add_del_t *mp;
15223   u8 is_add = 1;
15224   u8 *name = 0;
15225   u32 cir = 0;
15226   u32 eir = 0;
15227   u64 cb = 0;
15228   u64 eb = 0;
15229   u8 rate_type = 0;
15230   u8 round_type = 0;
15231   u8 type = 0;
15232   u8 color_aware = 0;
15233   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15234   int ret;
15235
15236   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15237   conform_action.dscp = 0;
15238   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15239   exceed_action.dscp = 0;
15240   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15241   violate_action.dscp = 0;
15242
15243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15244     {
15245       if (unformat (i, "del"))
15246         is_add = 0;
15247       else if (unformat (i, "name %s", &name))
15248         vec_add1 (name, 0);
15249       else if (unformat (i, "cir %u", &cir))
15250         ;
15251       else if (unformat (i, "eir %u", &eir))
15252         ;
15253       else if (unformat (i, "cb %u", &cb))
15254         ;
15255       else if (unformat (i, "eb %u", &eb))
15256         ;
15257       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15258                          &rate_type))
15259         ;
15260       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15261                          &round_type))
15262         ;
15263       else if (unformat (i, "type %U", unformat_policer_type, &type))
15264         ;
15265       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15266                          &conform_action))
15267         ;
15268       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15269                          &exceed_action))
15270         ;
15271       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15272                          &violate_action))
15273         ;
15274       else if (unformat (i, "color-aware"))
15275         color_aware = 1;
15276       else
15277         break;
15278     }
15279
15280   if (!vec_len (name))
15281     {
15282       errmsg ("policer name must be specified");
15283       return -99;
15284     }
15285
15286   if (vec_len (name) > 64)
15287     {
15288       errmsg ("policer name too long");
15289       return -99;
15290     }
15291
15292   M (POLICER_ADD_DEL, mp);
15293
15294   clib_memcpy (mp->name, name, vec_len (name));
15295   vec_free (name);
15296   mp->is_add = is_add;
15297   mp->cir = cir;
15298   mp->eir = eir;
15299   mp->cb = cb;
15300   mp->eb = eb;
15301   mp->rate_type = rate_type;
15302   mp->round_type = round_type;
15303   mp->type = type;
15304   mp->conform_action_type = conform_action.action_type;
15305   mp->conform_dscp = conform_action.dscp;
15306   mp->exceed_action_type = exceed_action.action_type;
15307   mp->exceed_dscp = exceed_action.dscp;
15308   mp->violate_action_type = violate_action.action_type;
15309   mp->violate_dscp = violate_action.dscp;
15310   mp->color_aware = color_aware;
15311
15312   S (mp);
15313   W (ret);
15314   return ret;
15315 }
15316
15317 static int
15318 api_policer_dump (vat_main_t * vam)
15319 {
15320   unformat_input_t *i = vam->input;
15321   vl_api_policer_dump_t *mp;
15322   vl_api_control_ping_t *mp_ping;
15323   u8 *match_name = 0;
15324   u8 match_name_valid = 0;
15325   int ret;
15326
15327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15328     {
15329       if (unformat (i, "name %s", &match_name))
15330         {
15331           vec_add1 (match_name, 0);
15332           match_name_valid = 1;
15333         }
15334       else
15335         break;
15336     }
15337
15338   M (POLICER_DUMP, mp);
15339   mp->match_name_valid = match_name_valid;
15340   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15341   vec_free (match_name);
15342   /* send it... */
15343   S (mp);
15344
15345   /* Use a control ping for synchronization */
15346   M (CONTROL_PING, mp_ping);
15347   S (mp_ping);
15348
15349   /* Wait for a reply... */
15350   W (ret);
15351   return ret;
15352 }
15353
15354 static int
15355 api_policer_classify_set_interface (vat_main_t * vam)
15356 {
15357   unformat_input_t *i = vam->input;
15358   vl_api_policer_classify_set_interface_t *mp;
15359   u32 sw_if_index;
15360   int sw_if_index_set;
15361   u32 ip4_table_index = ~0;
15362   u32 ip6_table_index = ~0;
15363   u32 l2_table_index = ~0;
15364   u8 is_add = 1;
15365   int ret;
15366
15367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15368     {
15369       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15370         sw_if_index_set = 1;
15371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15372         sw_if_index_set = 1;
15373       else if (unformat (i, "del"))
15374         is_add = 0;
15375       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15376         ;
15377       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15378         ;
15379       else if (unformat (i, "l2-table %d", &l2_table_index))
15380         ;
15381       else
15382         {
15383           clib_warning ("parse error '%U'", format_unformat_error, i);
15384           return -99;
15385         }
15386     }
15387
15388   if (sw_if_index_set == 0)
15389     {
15390       errmsg ("missing interface name or sw_if_index");
15391       return -99;
15392     }
15393
15394   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15395
15396   mp->sw_if_index = ntohl (sw_if_index);
15397   mp->ip4_table_index = ntohl (ip4_table_index);
15398   mp->ip6_table_index = ntohl (ip6_table_index);
15399   mp->l2_table_index = ntohl (l2_table_index);
15400   mp->is_add = is_add;
15401
15402   S (mp);
15403   W (ret);
15404   return ret;
15405 }
15406
15407 static int
15408 api_policer_classify_dump (vat_main_t * vam)
15409 {
15410   unformat_input_t *i = vam->input;
15411   vl_api_policer_classify_dump_t *mp;
15412   vl_api_control_ping_t *mp_ping;
15413   u8 type = POLICER_CLASSIFY_N_TABLES;
15414   int ret;
15415
15416   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15417     ;
15418   else
15419     {
15420       errmsg ("classify table type must be specified");
15421       return -99;
15422     }
15423
15424   if (!vam->json_output)
15425     {
15426       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15427     }
15428
15429   M (POLICER_CLASSIFY_DUMP, mp);
15430   mp->type = type;
15431   /* send it... */
15432   S (mp);
15433
15434   /* Use a control ping for synchronization */
15435   M (CONTROL_PING, mp_ping);
15436   S (mp_ping);
15437
15438   /* Wait for a reply... */
15439   W (ret);
15440   return ret;
15441 }
15442
15443 static int
15444 api_netmap_create (vat_main_t * vam)
15445 {
15446   unformat_input_t *i = vam->input;
15447   vl_api_netmap_create_t *mp;
15448   u8 *if_name = 0;
15449   u8 hw_addr[6];
15450   u8 random_hw_addr = 1;
15451   u8 is_pipe = 0;
15452   u8 is_master = 0;
15453   int ret;
15454
15455   memset (hw_addr, 0, sizeof (hw_addr));
15456
15457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15458     {
15459       if (unformat (i, "name %s", &if_name))
15460         vec_add1 (if_name, 0);
15461       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15462         random_hw_addr = 0;
15463       else if (unformat (i, "pipe"))
15464         is_pipe = 1;
15465       else if (unformat (i, "master"))
15466         is_master = 1;
15467       else if (unformat (i, "slave"))
15468         is_master = 0;
15469       else
15470         break;
15471     }
15472
15473   if (!vec_len (if_name))
15474     {
15475       errmsg ("interface name must be specified");
15476       return -99;
15477     }
15478
15479   if (vec_len (if_name) > 64)
15480     {
15481       errmsg ("interface name too long");
15482       return -99;
15483     }
15484
15485   M (NETMAP_CREATE, mp);
15486
15487   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15488   clib_memcpy (mp->hw_addr, hw_addr, 6);
15489   mp->use_random_hw_addr = random_hw_addr;
15490   mp->is_pipe = is_pipe;
15491   mp->is_master = is_master;
15492   vec_free (if_name);
15493
15494   S (mp);
15495   W (ret);
15496   return ret;
15497 }
15498
15499 static int
15500 api_netmap_delete (vat_main_t * vam)
15501 {
15502   unformat_input_t *i = vam->input;
15503   vl_api_netmap_delete_t *mp;
15504   u8 *if_name = 0;
15505   int ret;
15506
15507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15508     {
15509       if (unformat (i, "name %s", &if_name))
15510         vec_add1 (if_name, 0);
15511       else
15512         break;
15513     }
15514
15515   if (!vec_len (if_name))
15516     {
15517       errmsg ("interface name must be specified");
15518       return -99;
15519     }
15520
15521   if (vec_len (if_name) > 64)
15522     {
15523       errmsg ("interface name too long");
15524       return -99;
15525     }
15526
15527   M (NETMAP_DELETE, mp);
15528
15529   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15530   vec_free (if_name);
15531
15532   S (mp);
15533   W (ret);
15534   return ret;
15535 }
15536
15537 static void vl_api_mpls_tunnel_details_t_handler
15538   (vl_api_mpls_tunnel_details_t * mp)
15539 {
15540   vat_main_t *vam = &vat_main;
15541   i32 len = mp->mt_next_hop_n_labels;
15542   i32 i;
15543
15544   print (vam->ofp, "[%d]: via %U %d labels ",
15545          mp->tunnel_index,
15546          format_ip4_address, mp->mt_next_hop,
15547          ntohl (mp->mt_next_hop_sw_if_index));
15548   for (i = 0; i < len; i++)
15549     {
15550       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15551     }
15552   print (vam->ofp, "");
15553 }
15554
15555 static void vl_api_mpls_tunnel_details_t_handler_json
15556   (vl_api_mpls_tunnel_details_t * mp)
15557 {
15558   vat_main_t *vam = &vat_main;
15559   vat_json_node_t *node = NULL;
15560   struct in_addr ip4;
15561   i32 i;
15562   i32 len = mp->mt_next_hop_n_labels;
15563
15564   if (VAT_JSON_ARRAY != vam->json_tree.type)
15565     {
15566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15567       vat_json_init_array (&vam->json_tree);
15568     }
15569   node = vat_json_array_add (&vam->json_tree);
15570
15571   vat_json_init_object (node);
15572   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15573   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15574   vat_json_object_add_ip4 (node, "next_hop", ip4);
15575   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15576                             ntohl (mp->mt_next_hop_sw_if_index));
15577   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15578   vat_json_object_add_uint (node, "label_count", len);
15579   for (i = 0; i < len; i++)
15580     {
15581       vat_json_object_add_uint (node, "label",
15582                                 ntohl (mp->mt_next_hop_out_labels[i]));
15583     }
15584 }
15585
15586 static int
15587 api_mpls_tunnel_dump (vat_main_t * vam)
15588 {
15589   vl_api_mpls_tunnel_dump_t *mp;
15590   vl_api_control_ping_t *mp_ping;
15591   i32 index = -1;
15592   int ret;
15593
15594   /* Parse args required to build the message */
15595   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15596     {
15597       if (!unformat (vam->input, "tunnel_index %d", &index))
15598         {
15599           index = -1;
15600           break;
15601         }
15602     }
15603
15604   print (vam->ofp, "  tunnel_index %d", index);
15605
15606   M (MPLS_TUNNEL_DUMP, mp);
15607   mp->tunnel_index = htonl (index);
15608   S (mp);
15609
15610   /* Use a control ping for synchronization */
15611   M (CONTROL_PING, mp_ping);
15612   S (mp_ping);
15613
15614   W (ret);
15615   return ret;
15616 }
15617
15618 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15619 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15620
15621 static void
15622 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15623 {
15624   vat_main_t *vam = &vat_main;
15625   int count = ntohl (mp->count);
15626   vl_api_fib_path2_t *fp;
15627   int i;
15628
15629   print (vam->ofp,
15630          "table-id %d, label %u, ess_bit %u",
15631          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15632   fp = mp->path;
15633   for (i = 0; i < count; i++)
15634     {
15635       if (fp->afi == IP46_TYPE_IP6)
15636         print (vam->ofp,
15637                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15638                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15639                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15640                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15641                format_ip6_address, fp->next_hop);
15642       else if (fp->afi == IP46_TYPE_IP4)
15643         print (vam->ofp,
15644                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15645                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15646                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15647                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15648                format_ip4_address, fp->next_hop);
15649       fp++;
15650     }
15651 }
15652
15653 static void vl_api_mpls_fib_details_t_handler_json
15654   (vl_api_mpls_fib_details_t * mp)
15655 {
15656   vat_main_t *vam = &vat_main;
15657   int count = ntohl (mp->count);
15658   vat_json_node_t *node = NULL;
15659   struct in_addr ip4;
15660   struct in6_addr ip6;
15661   vl_api_fib_path2_t *fp;
15662   int i;
15663
15664   if (VAT_JSON_ARRAY != vam->json_tree.type)
15665     {
15666       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15667       vat_json_init_array (&vam->json_tree);
15668     }
15669   node = vat_json_array_add (&vam->json_tree);
15670
15671   vat_json_init_object (node);
15672   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15673   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15674   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15675   vat_json_object_add_uint (node, "path_count", count);
15676   fp = mp->path;
15677   for (i = 0; i < count; i++)
15678     {
15679       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15680       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15681       vat_json_object_add_uint (node, "is_local", fp->is_local);
15682       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15683       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15684       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15685       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15686       if (fp->afi == IP46_TYPE_IP4)
15687         {
15688           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15689           vat_json_object_add_ip4 (node, "next_hop", ip4);
15690         }
15691       else if (fp->afi == IP46_TYPE_IP6)
15692         {
15693           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15694           vat_json_object_add_ip6 (node, "next_hop", ip6);
15695         }
15696     }
15697 }
15698
15699 static int
15700 api_mpls_fib_dump (vat_main_t * vam)
15701 {
15702   vl_api_mpls_fib_dump_t *mp;
15703   vl_api_control_ping_t *mp_ping;
15704   int ret;
15705
15706   M (MPLS_FIB_DUMP, mp);
15707   S (mp);
15708
15709   /* Use a control ping for synchronization */
15710   M (CONTROL_PING, mp_ping);
15711   S (mp_ping);
15712
15713   W (ret);
15714   return ret;
15715 }
15716
15717 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15718 #define vl_api_ip_fib_details_t_print vl_noop_handler
15719
15720 static void
15721 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15722 {
15723   vat_main_t *vam = &vat_main;
15724   int count = ntohl (mp->count);
15725   vl_api_fib_path_t *fp;
15726   int i;
15727
15728   print (vam->ofp,
15729          "table-id %d, prefix %U/%d",
15730          ntohl (mp->table_id), format_ip4_address, mp->address,
15731          mp->address_length);
15732   fp = mp->path;
15733   for (i = 0; i < count; i++)
15734     {
15735       if (fp->afi == IP46_TYPE_IP6)
15736         print (vam->ofp,
15737                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15738                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15739                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15740                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15741                format_ip6_address, fp->next_hop);
15742       else if (fp->afi == IP46_TYPE_IP4)
15743         print (vam->ofp,
15744                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15745                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15746                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15747                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15748                format_ip4_address, fp->next_hop);
15749       fp++;
15750     }
15751 }
15752
15753 static void vl_api_ip_fib_details_t_handler_json
15754   (vl_api_ip_fib_details_t * mp)
15755 {
15756   vat_main_t *vam = &vat_main;
15757   int count = ntohl (mp->count);
15758   vat_json_node_t *node = NULL;
15759   struct in_addr ip4;
15760   struct in6_addr ip6;
15761   vl_api_fib_path_t *fp;
15762   int i;
15763
15764   if (VAT_JSON_ARRAY != vam->json_tree.type)
15765     {
15766       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15767       vat_json_init_array (&vam->json_tree);
15768     }
15769   node = vat_json_array_add (&vam->json_tree);
15770
15771   vat_json_init_object (node);
15772   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15773   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15774   vat_json_object_add_ip4 (node, "prefix", ip4);
15775   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15776   vat_json_object_add_uint (node, "path_count", count);
15777   fp = mp->path;
15778   for (i = 0; i < count; i++)
15779     {
15780       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15781       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15782       vat_json_object_add_uint (node, "is_local", fp->is_local);
15783       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15784       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15785       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15786       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15787       if (fp->afi == IP46_TYPE_IP4)
15788         {
15789           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15790           vat_json_object_add_ip4 (node, "next_hop", ip4);
15791         }
15792       else if (fp->afi == IP46_TYPE_IP6)
15793         {
15794           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15795           vat_json_object_add_ip6 (node, "next_hop", ip6);
15796         }
15797     }
15798 }
15799
15800 static int
15801 api_ip_fib_dump (vat_main_t * vam)
15802 {
15803   vl_api_ip_fib_dump_t *mp;
15804   vl_api_control_ping_t *mp_ping;
15805   int ret;
15806
15807   M (IP_FIB_DUMP, mp);
15808   S (mp);
15809
15810   /* Use a control ping for synchronization */
15811   M (CONTROL_PING, mp_ping);
15812   S (mp_ping);
15813
15814   W (ret);
15815   return ret;
15816 }
15817
15818 static void vl_api_ip_neighbor_details_t_handler
15819   (vl_api_ip_neighbor_details_t * mp)
15820 {
15821   vat_main_t *vam = &vat_main;
15822
15823   print (vam->ofp, "%c %U %U",
15824          (mp->is_static) ? 'S' : 'D',
15825          format_ethernet_address, &mp->mac_address,
15826          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15827          &mp->ip_address);
15828 }
15829
15830 static void vl_api_ip_neighbor_details_t_handler_json
15831   (vl_api_ip_neighbor_details_t * mp)
15832 {
15833
15834   vat_main_t *vam = &vat_main;
15835   vat_json_node_t *node;
15836   struct in_addr ip4;
15837   struct in6_addr ip6;
15838
15839   if (VAT_JSON_ARRAY != vam->json_tree.type)
15840     {
15841       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15842       vat_json_init_array (&vam->json_tree);
15843     }
15844   node = vat_json_array_add (&vam->json_tree);
15845
15846   vat_json_init_object (node);
15847   vat_json_object_add_string_copy (node, "flag",
15848                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15849                                    "dynamic");
15850
15851   vat_json_object_add_string_copy (node, "link_layer",
15852                                    format (0, "%U", format_ethernet_address,
15853                                            &mp->mac_address));
15854
15855   if (mp->is_ipv6)
15856     {
15857       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15858       vat_json_object_add_ip6 (node, "ip_address", ip6);
15859     }
15860   else
15861     {
15862       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15863       vat_json_object_add_ip4 (node, "ip_address", ip4);
15864     }
15865 }
15866
15867 static int
15868 api_ip_neighbor_dump (vat_main_t * vam)
15869 {
15870   unformat_input_t *i = vam->input;
15871   vl_api_ip_neighbor_dump_t *mp;
15872   vl_api_control_ping_t *mp_ping;
15873   u8 is_ipv6 = 0;
15874   u32 sw_if_index = ~0;
15875   int ret;
15876
15877   /* Parse args required to build the message */
15878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15879     {
15880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15881         ;
15882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15883         ;
15884       else if (unformat (i, "ip6"))
15885         is_ipv6 = 1;
15886       else
15887         break;
15888     }
15889
15890   if (sw_if_index == ~0)
15891     {
15892       errmsg ("missing interface name or sw_if_index");
15893       return -99;
15894     }
15895
15896   M (IP_NEIGHBOR_DUMP, mp);
15897   mp->is_ipv6 = (u8) is_ipv6;
15898   mp->sw_if_index = ntohl (sw_if_index);
15899   S (mp);
15900
15901   /* Use a control ping for synchronization */
15902   M (CONTROL_PING, mp_ping);
15903   S (mp_ping);
15904
15905   W (ret);
15906   return ret;
15907 }
15908
15909 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15910 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15911
15912 static void
15913 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15914 {
15915   vat_main_t *vam = &vat_main;
15916   int count = ntohl (mp->count);
15917   vl_api_fib_path_t *fp;
15918   int i;
15919
15920   print (vam->ofp,
15921          "table-id %d, prefix %U/%d",
15922          ntohl (mp->table_id), format_ip6_address, mp->address,
15923          mp->address_length);
15924   fp = mp->path;
15925   for (i = 0; i < count; i++)
15926     {
15927       if (fp->afi == IP46_TYPE_IP6)
15928         print (vam->ofp,
15929                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15930                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15931                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15932                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15933                format_ip6_address, fp->next_hop);
15934       else if (fp->afi == IP46_TYPE_IP4)
15935         print (vam->ofp,
15936                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15937                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15938                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15939                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15940                format_ip4_address, fp->next_hop);
15941       fp++;
15942     }
15943 }
15944
15945 static void vl_api_ip6_fib_details_t_handler_json
15946   (vl_api_ip6_fib_details_t * mp)
15947 {
15948   vat_main_t *vam = &vat_main;
15949   int count = ntohl (mp->count);
15950   vat_json_node_t *node = NULL;
15951   struct in_addr ip4;
15952   struct in6_addr ip6;
15953   vl_api_fib_path_t *fp;
15954   int i;
15955
15956   if (VAT_JSON_ARRAY != vam->json_tree.type)
15957     {
15958       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15959       vat_json_init_array (&vam->json_tree);
15960     }
15961   node = vat_json_array_add (&vam->json_tree);
15962
15963   vat_json_init_object (node);
15964   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15965   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15966   vat_json_object_add_ip6 (node, "prefix", ip6);
15967   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15968   vat_json_object_add_uint (node, "path_count", count);
15969   fp = mp->path;
15970   for (i = 0; i < count; i++)
15971     {
15972       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15973       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15974       vat_json_object_add_uint (node, "is_local", fp->is_local);
15975       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15976       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15977       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15978       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15979       if (fp->afi == IP46_TYPE_IP4)
15980         {
15981           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15982           vat_json_object_add_ip4 (node, "next_hop", ip4);
15983         }
15984       else if (fp->afi == IP46_TYPE_IP6)
15985         {
15986           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15987           vat_json_object_add_ip6 (node, "next_hop", ip6);
15988         }
15989     }
15990 }
15991
15992 static int
15993 api_ip6_fib_dump (vat_main_t * vam)
15994 {
15995   vl_api_ip6_fib_dump_t *mp;
15996   vl_api_control_ping_t *mp_ping;
15997   int ret;
15998
15999   M (IP6_FIB_DUMP, mp);
16000   S (mp);
16001
16002   /* Use a control ping for synchronization */
16003   M (CONTROL_PING, mp_ping);
16004   S (mp_ping);
16005
16006   W (ret);
16007   return ret;
16008 }
16009
16010 int
16011 api_classify_table_ids (vat_main_t * vam)
16012 {
16013   vl_api_classify_table_ids_t *mp;
16014   int ret;
16015
16016   /* Construct the API message */
16017   M (CLASSIFY_TABLE_IDS, mp);
16018   mp->context = 0;
16019
16020   S (mp);
16021   W (ret);
16022   return ret;
16023 }
16024
16025 int
16026 api_classify_table_by_interface (vat_main_t * vam)
16027 {
16028   unformat_input_t *input = vam->input;
16029   vl_api_classify_table_by_interface_t *mp;
16030
16031   u32 sw_if_index = ~0;
16032   int ret;
16033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16034     {
16035       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16036         ;
16037       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16038         ;
16039       else
16040         break;
16041     }
16042   if (sw_if_index == ~0)
16043     {
16044       errmsg ("missing interface name or sw_if_index");
16045       return -99;
16046     }
16047
16048   /* Construct the API message */
16049   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16050   mp->context = 0;
16051   mp->sw_if_index = ntohl (sw_if_index);
16052
16053   S (mp);
16054   W (ret);
16055   return ret;
16056 }
16057
16058 int
16059 api_classify_table_info (vat_main_t * vam)
16060 {
16061   unformat_input_t *input = vam->input;
16062   vl_api_classify_table_info_t *mp;
16063
16064   u32 table_id = ~0;
16065   int ret;
16066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16067     {
16068       if (unformat (input, "table_id %d", &table_id))
16069         ;
16070       else
16071         break;
16072     }
16073   if (table_id == ~0)
16074     {
16075       errmsg ("missing table id");
16076       return -99;
16077     }
16078
16079   /* Construct the API message */
16080   M (CLASSIFY_TABLE_INFO, mp);
16081   mp->context = 0;
16082   mp->table_id = ntohl (table_id);
16083
16084   S (mp);
16085   W (ret);
16086   return ret;
16087 }
16088
16089 int
16090 api_classify_session_dump (vat_main_t * vam)
16091 {
16092   unformat_input_t *input = vam->input;
16093   vl_api_classify_session_dump_t *mp;
16094   vl_api_control_ping_t *mp_ping;
16095
16096   u32 table_id = ~0;
16097   int ret;
16098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16099     {
16100       if (unformat (input, "table_id %d", &table_id))
16101         ;
16102       else
16103         break;
16104     }
16105   if (table_id == ~0)
16106     {
16107       errmsg ("missing table id");
16108       return -99;
16109     }
16110
16111   /* Construct the API message */
16112   M (CLASSIFY_SESSION_DUMP, mp);
16113   mp->context = 0;
16114   mp->table_id = ntohl (table_id);
16115   S (mp);
16116
16117   /* Use a control ping for synchronization */
16118   M (CONTROL_PING, mp_ping);
16119   S (mp_ping);
16120
16121   W (ret);
16122   return ret;
16123 }
16124
16125 static void
16126 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16127 {
16128   vat_main_t *vam = &vat_main;
16129
16130   print (vam->ofp, "collector_address %U, collector_port %d, "
16131          "src_address %U, vrf_id %d, path_mtu %u, "
16132          "template_interval %u, udp_checksum %d",
16133          format_ip4_address, mp->collector_address,
16134          ntohs (mp->collector_port),
16135          format_ip4_address, mp->src_address,
16136          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16137          ntohl (mp->template_interval), mp->udp_checksum);
16138
16139   vam->retval = 0;
16140   vam->result_ready = 1;
16141 }
16142
16143 static void
16144   vl_api_ipfix_exporter_details_t_handler_json
16145   (vl_api_ipfix_exporter_details_t * mp)
16146 {
16147   vat_main_t *vam = &vat_main;
16148   vat_json_node_t node;
16149   struct in_addr collector_address;
16150   struct in_addr src_address;
16151
16152   vat_json_init_object (&node);
16153   clib_memcpy (&collector_address, &mp->collector_address,
16154                sizeof (collector_address));
16155   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16156   vat_json_object_add_uint (&node, "collector_port",
16157                             ntohs (mp->collector_port));
16158   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16159   vat_json_object_add_ip4 (&node, "src_address", src_address);
16160   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16161   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16162   vat_json_object_add_uint (&node, "template_interval",
16163                             ntohl (mp->template_interval));
16164   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16165
16166   vat_json_print (vam->ofp, &node);
16167   vat_json_free (&node);
16168   vam->retval = 0;
16169   vam->result_ready = 1;
16170 }
16171
16172 int
16173 api_ipfix_exporter_dump (vat_main_t * vam)
16174 {
16175   vl_api_ipfix_exporter_dump_t *mp;
16176   int ret;
16177
16178   /* Construct the API message */
16179   M (IPFIX_EXPORTER_DUMP, mp);
16180   mp->context = 0;
16181
16182   S (mp);
16183   W (ret);
16184   return ret;
16185 }
16186
16187 static int
16188 api_ipfix_classify_stream_dump (vat_main_t * vam)
16189 {
16190   vl_api_ipfix_classify_stream_dump_t *mp;
16191   int ret;
16192
16193   /* Construct the API message */
16194   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16195   mp->context = 0;
16196
16197   S (mp);
16198   W (ret);
16199   return ret;
16200   /* NOTREACHED */
16201   return 0;
16202 }
16203
16204 static void
16205   vl_api_ipfix_classify_stream_details_t_handler
16206   (vl_api_ipfix_classify_stream_details_t * mp)
16207 {
16208   vat_main_t *vam = &vat_main;
16209   print (vam->ofp, "domain_id %d, src_port %d",
16210          ntohl (mp->domain_id), ntohs (mp->src_port));
16211   vam->retval = 0;
16212   vam->result_ready = 1;
16213 }
16214
16215 static void
16216   vl_api_ipfix_classify_stream_details_t_handler_json
16217   (vl_api_ipfix_classify_stream_details_t * mp)
16218 {
16219   vat_main_t *vam = &vat_main;
16220   vat_json_node_t node;
16221
16222   vat_json_init_object (&node);
16223   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16224   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16225
16226   vat_json_print (vam->ofp, &node);
16227   vat_json_free (&node);
16228   vam->retval = 0;
16229   vam->result_ready = 1;
16230 }
16231
16232 static int
16233 api_ipfix_classify_table_dump (vat_main_t * vam)
16234 {
16235   vl_api_ipfix_classify_table_dump_t *mp;
16236   vl_api_control_ping_t *mp_ping;
16237   int ret;
16238
16239   if (!vam->json_output)
16240     {
16241       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16242              "transport_protocol");
16243     }
16244
16245   /* Construct the API message */
16246   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16247
16248   /* send it... */
16249   S (mp);
16250
16251   /* Use a control ping for synchronization */
16252   M (CONTROL_PING, mp_ping);
16253   S (mp_ping);
16254
16255   W (ret);
16256   return ret;
16257 }
16258
16259 static void
16260   vl_api_ipfix_classify_table_details_t_handler
16261   (vl_api_ipfix_classify_table_details_t * mp)
16262 {
16263   vat_main_t *vam = &vat_main;
16264   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16265          mp->transport_protocol);
16266 }
16267
16268 static void
16269   vl_api_ipfix_classify_table_details_t_handler_json
16270   (vl_api_ipfix_classify_table_details_t * mp)
16271 {
16272   vat_json_node_t *node = NULL;
16273   vat_main_t *vam = &vat_main;
16274
16275   if (VAT_JSON_ARRAY != vam->json_tree.type)
16276     {
16277       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16278       vat_json_init_array (&vam->json_tree);
16279     }
16280
16281   node = vat_json_array_add (&vam->json_tree);
16282   vat_json_init_object (node);
16283
16284   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16285   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16286   vat_json_object_add_uint (node, "transport_protocol",
16287                             mp->transport_protocol);
16288 }
16289
16290 static int
16291 api_sw_interface_span_enable_disable (vat_main_t * vam)
16292 {
16293   unformat_input_t *i = vam->input;
16294   vl_api_sw_interface_span_enable_disable_t *mp;
16295   u32 src_sw_if_index = ~0;
16296   u32 dst_sw_if_index = ~0;
16297   u8 state = 3;
16298   int ret;
16299
16300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16301     {
16302       if (unformat
16303           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16304         ;
16305       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16306         ;
16307       else
16308         if (unformat
16309             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16310         ;
16311       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16312         ;
16313       else if (unformat (i, "disable"))
16314         state = 0;
16315       else if (unformat (i, "rx"))
16316         state = 1;
16317       else if (unformat (i, "tx"))
16318         state = 2;
16319       else if (unformat (i, "both"))
16320         state = 3;
16321       else
16322         break;
16323     }
16324
16325   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16326
16327   mp->sw_if_index_from = htonl (src_sw_if_index);
16328   mp->sw_if_index_to = htonl (dst_sw_if_index);
16329   mp->state = state;
16330
16331   S (mp);
16332   W (ret);
16333   return ret;
16334 }
16335
16336 static void
16337 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16338                                             * mp)
16339 {
16340   vat_main_t *vam = &vat_main;
16341   u8 *sw_if_from_name = 0;
16342   u8 *sw_if_to_name = 0;
16343   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16344   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16345   char *states[] = { "none", "rx", "tx", "both" };
16346   hash_pair_t *p;
16347
16348   /* *INDENT-OFF* */
16349   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16350   ({
16351     if ((u32) p->value[0] == sw_if_index_from)
16352       {
16353         sw_if_from_name = (u8 *)(p->key);
16354         if (sw_if_to_name)
16355           break;
16356       }
16357     if ((u32) p->value[0] == sw_if_index_to)
16358       {
16359         sw_if_to_name = (u8 *)(p->key);
16360         if (sw_if_from_name)
16361           break;
16362       }
16363   }));
16364   /* *INDENT-ON* */
16365   print (vam->ofp, "%20s => %20s (%s)",
16366          sw_if_from_name, sw_if_to_name, states[mp->state]);
16367 }
16368
16369 static void
16370   vl_api_sw_interface_span_details_t_handler_json
16371   (vl_api_sw_interface_span_details_t * mp)
16372 {
16373   vat_main_t *vam = &vat_main;
16374   vat_json_node_t *node = NULL;
16375   u8 *sw_if_from_name = 0;
16376   u8 *sw_if_to_name = 0;
16377   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16378   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16379   hash_pair_t *p;
16380
16381   /* *INDENT-OFF* */
16382   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16383   ({
16384     if ((u32) p->value[0] == sw_if_index_from)
16385       {
16386         sw_if_from_name = (u8 *)(p->key);
16387         if (sw_if_to_name)
16388           break;
16389       }
16390     if ((u32) p->value[0] == sw_if_index_to)
16391       {
16392         sw_if_to_name = (u8 *)(p->key);
16393         if (sw_if_from_name)
16394           break;
16395       }
16396   }));
16397   /* *INDENT-ON* */
16398
16399   if (VAT_JSON_ARRAY != vam->json_tree.type)
16400     {
16401       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16402       vat_json_init_array (&vam->json_tree);
16403     }
16404   node = vat_json_array_add (&vam->json_tree);
16405
16406   vat_json_init_object (node);
16407   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16408   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16409   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16410   if (0 != sw_if_to_name)
16411     {
16412       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16413     }
16414   vat_json_object_add_uint (node, "state", mp->state);
16415 }
16416
16417 static int
16418 api_sw_interface_span_dump (vat_main_t * vam)
16419 {
16420   vl_api_sw_interface_span_dump_t *mp;
16421   vl_api_control_ping_t *mp_ping;
16422   int ret;
16423
16424   M (SW_INTERFACE_SPAN_DUMP, mp);
16425   S (mp);
16426
16427   /* Use a control ping for synchronization */
16428   M (CONTROL_PING, mp_ping);
16429   S (mp_ping);
16430
16431   W (ret);
16432   return ret;
16433 }
16434
16435 int
16436 api_pg_create_interface (vat_main_t * vam)
16437 {
16438   unformat_input_t *input = vam->input;
16439   vl_api_pg_create_interface_t *mp;
16440
16441   u32 if_id = ~0;
16442   int ret;
16443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16444     {
16445       if (unformat (input, "if_id %d", &if_id))
16446         ;
16447       else
16448         break;
16449     }
16450   if (if_id == ~0)
16451     {
16452       errmsg ("missing pg interface index");
16453       return -99;
16454     }
16455
16456   /* Construct the API message */
16457   M (PG_CREATE_INTERFACE, mp);
16458   mp->context = 0;
16459   mp->interface_id = ntohl (if_id);
16460
16461   S (mp);
16462   W (ret);
16463   return ret;
16464 }
16465
16466 int
16467 api_pg_capture (vat_main_t * vam)
16468 {
16469   unformat_input_t *input = vam->input;
16470   vl_api_pg_capture_t *mp;
16471
16472   u32 if_id = ~0;
16473   u8 enable = 1;
16474   u32 count = 1;
16475   u8 pcap_file_set = 0;
16476   u8 *pcap_file = 0;
16477   int ret;
16478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16479     {
16480       if (unformat (input, "if_id %d", &if_id))
16481         ;
16482       else if (unformat (input, "pcap %s", &pcap_file))
16483         pcap_file_set = 1;
16484       else if (unformat (input, "count %d", &count))
16485         ;
16486       else if (unformat (input, "disable"))
16487         enable = 0;
16488       else
16489         break;
16490     }
16491   if (if_id == ~0)
16492     {
16493       errmsg ("missing pg interface index");
16494       return -99;
16495     }
16496   if (pcap_file_set > 0)
16497     {
16498       if (vec_len (pcap_file) > 255)
16499         {
16500           errmsg ("pcap file name is too long");
16501           return -99;
16502         }
16503     }
16504
16505   u32 name_len = vec_len (pcap_file);
16506   /* Construct the API message */
16507   M (PG_CAPTURE, mp);
16508   mp->context = 0;
16509   mp->interface_id = ntohl (if_id);
16510   mp->is_enabled = enable;
16511   mp->count = ntohl (count);
16512   mp->pcap_name_length = ntohl (name_len);
16513   if (pcap_file_set != 0)
16514     {
16515       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16516     }
16517   vec_free (pcap_file);
16518
16519   S (mp);
16520   W (ret);
16521   return ret;
16522 }
16523
16524 int
16525 api_pg_enable_disable (vat_main_t * vam)
16526 {
16527   unformat_input_t *input = vam->input;
16528   vl_api_pg_enable_disable_t *mp;
16529
16530   u8 enable = 1;
16531   u8 stream_name_set = 0;
16532   u8 *stream_name = 0;
16533   int ret;
16534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16535     {
16536       if (unformat (input, "stream %s", &stream_name))
16537         stream_name_set = 1;
16538       else if (unformat (input, "disable"))
16539         enable = 0;
16540       else
16541         break;
16542     }
16543
16544   if (stream_name_set > 0)
16545     {
16546       if (vec_len (stream_name) > 255)
16547         {
16548           errmsg ("stream name too long");
16549           return -99;
16550         }
16551     }
16552
16553   u32 name_len = vec_len (stream_name);
16554   /* Construct the API message */
16555   M (PG_ENABLE_DISABLE, mp);
16556   mp->context = 0;
16557   mp->is_enabled = enable;
16558   if (stream_name_set != 0)
16559     {
16560       mp->stream_name_length = ntohl (name_len);
16561       clib_memcpy (mp->stream_name, stream_name, name_len);
16562     }
16563   vec_free (stream_name);
16564
16565   S (mp);
16566   W (ret);
16567   return ret;
16568 }
16569
16570 int
16571 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16572 {
16573   unformat_input_t *input = vam->input;
16574   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16575
16576   u16 *low_ports = 0;
16577   u16 *high_ports = 0;
16578   u16 this_low;
16579   u16 this_hi;
16580   ip4_address_t ip4_addr;
16581   ip6_address_t ip6_addr;
16582   u32 length;
16583   u32 tmp, tmp2;
16584   u8 prefix_set = 0;
16585   u32 vrf_id = ~0;
16586   u8 is_add = 1;
16587   u8 is_ipv6 = 0;
16588   int ret;
16589
16590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16591     {
16592       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16593         {
16594           prefix_set = 1;
16595         }
16596       else
16597         if (unformat
16598             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16599         {
16600           prefix_set = 1;
16601           is_ipv6 = 1;
16602         }
16603       else if (unformat (input, "vrf %d", &vrf_id))
16604         ;
16605       else if (unformat (input, "del"))
16606         is_add = 0;
16607       else if (unformat (input, "port %d", &tmp))
16608         {
16609           if (tmp == 0 || tmp > 65535)
16610             {
16611               errmsg ("port %d out of range", tmp);
16612               return -99;
16613             }
16614           this_low = tmp;
16615           this_hi = this_low + 1;
16616           vec_add1 (low_ports, this_low);
16617           vec_add1 (high_ports, this_hi);
16618         }
16619       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16620         {
16621           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16622             {
16623               errmsg ("incorrect range parameters");
16624               return -99;
16625             }
16626           this_low = tmp;
16627           /* Note: in debug CLI +1 is added to high before
16628              passing to real fn that does "the work"
16629              (ip_source_and_port_range_check_add_del).
16630              This fn is a wrapper around the binary API fn a
16631              control plane will call, which expects this increment
16632              to have occurred. Hence letting the binary API control
16633              plane fn do the increment for consistency between VAT
16634              and other control planes.
16635            */
16636           this_hi = tmp2;
16637           vec_add1 (low_ports, this_low);
16638           vec_add1 (high_ports, this_hi);
16639         }
16640       else
16641         break;
16642     }
16643
16644   if (prefix_set == 0)
16645     {
16646       errmsg ("<address>/<mask> not specified");
16647       return -99;
16648     }
16649
16650   if (vrf_id == ~0)
16651     {
16652       errmsg ("VRF ID required, not specified");
16653       return -99;
16654     }
16655
16656   if (vrf_id == 0)
16657     {
16658       errmsg
16659         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16660       return -99;
16661     }
16662
16663   if (vec_len (low_ports) == 0)
16664     {
16665       errmsg ("At least one port or port range required");
16666       return -99;
16667     }
16668
16669   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
16670
16671   mp->is_add = is_add;
16672
16673   if (is_ipv6)
16674     {
16675       mp->is_ipv6 = 1;
16676       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16677     }
16678   else
16679     {
16680       mp->is_ipv6 = 0;
16681       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16682     }
16683
16684   mp->mask_length = length;
16685   mp->number_of_ranges = vec_len (low_ports);
16686
16687   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16688   vec_free (low_ports);
16689
16690   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16691   vec_free (high_ports);
16692
16693   mp->vrf_id = ntohl (vrf_id);
16694
16695   S (mp);
16696   W (ret);
16697   return ret;
16698 }
16699
16700 int
16701 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16702 {
16703   unformat_input_t *input = vam->input;
16704   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16705   u32 sw_if_index = ~0;
16706   int vrf_set = 0;
16707   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16708   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16709   u8 is_add = 1;
16710   int ret;
16711
16712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16713     {
16714       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16715         ;
16716       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16717         ;
16718       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16719         vrf_set = 1;
16720       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16721         vrf_set = 1;
16722       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16723         vrf_set = 1;
16724       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16725         vrf_set = 1;
16726       else if (unformat (input, "del"))
16727         is_add = 0;
16728       else
16729         break;
16730     }
16731
16732   if (sw_if_index == ~0)
16733     {
16734       errmsg ("Interface required but not specified");
16735       return -99;
16736     }
16737
16738   if (vrf_set == 0)
16739     {
16740       errmsg ("VRF ID required but not specified");
16741       return -99;
16742     }
16743
16744   if (tcp_out_vrf_id == 0
16745       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16746     {
16747       errmsg
16748         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16749       return -99;
16750     }
16751
16752   /* Construct the API message */
16753   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
16754
16755   mp->sw_if_index = ntohl (sw_if_index);
16756   mp->is_add = is_add;
16757   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16758   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16759   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16760   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16761
16762   /* send it... */
16763   S (mp);
16764
16765   /* Wait for a reply... */
16766   W (ret);
16767   return ret;
16768 }
16769
16770 static int
16771 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16772 {
16773   unformat_input_t *i = vam->input;
16774   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16775   u32 local_sa_id = 0;
16776   u32 remote_sa_id = 0;
16777   ip4_address_t src_address;
16778   ip4_address_t dst_address;
16779   u8 is_add = 1;
16780   int ret;
16781
16782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16783     {
16784       if (unformat (i, "local_sa %d", &local_sa_id))
16785         ;
16786       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16787         ;
16788       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16789         ;
16790       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16791         ;
16792       else if (unformat (i, "del"))
16793         is_add = 0;
16794       else
16795         {
16796           clib_warning ("parse error '%U'", format_unformat_error, i);
16797           return -99;
16798         }
16799     }
16800
16801   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
16802
16803   mp->local_sa_id = ntohl (local_sa_id);
16804   mp->remote_sa_id = ntohl (remote_sa_id);
16805   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16806   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16807   mp->is_add = is_add;
16808
16809   S (mp);
16810   W (ret);
16811   return ret;
16812 }
16813
16814 static int
16815 api_punt (vat_main_t * vam)
16816 {
16817   unformat_input_t *i = vam->input;
16818   vl_api_punt_t *mp;
16819   u32 ipv = ~0;
16820   u32 protocol = ~0;
16821   u32 port = ~0;
16822   int is_add = 1;
16823   int ret;
16824
16825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16826     {
16827       if (unformat (i, "ip %d", &ipv))
16828         ;
16829       else if (unformat (i, "protocol %d", &protocol))
16830         ;
16831       else if (unformat (i, "port %d", &port))
16832         ;
16833       else if (unformat (i, "del"))
16834         is_add = 0;
16835       else
16836         {
16837           clib_warning ("parse error '%U'", format_unformat_error, i);
16838           return -99;
16839         }
16840     }
16841
16842   M (PUNT, mp);
16843
16844   mp->is_add = (u8) is_add;
16845   mp->ipv = (u8) ipv;
16846   mp->l4_protocol = (u8) protocol;
16847   mp->l4_port = htons ((u16) port);
16848
16849   S (mp);
16850   W (ret);
16851   return ret;
16852 }
16853
16854 static void vl_api_ipsec_gre_tunnel_details_t_handler
16855   (vl_api_ipsec_gre_tunnel_details_t * mp)
16856 {
16857   vat_main_t *vam = &vat_main;
16858
16859   print (vam->ofp, "%11d%15U%15U%14d%14d",
16860          ntohl (mp->sw_if_index),
16861          format_ip4_address, &mp->src_address,
16862          format_ip4_address, &mp->dst_address,
16863          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16864 }
16865
16866 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16867   (vl_api_ipsec_gre_tunnel_details_t * mp)
16868 {
16869   vat_main_t *vam = &vat_main;
16870   vat_json_node_t *node = NULL;
16871   struct in_addr ip4;
16872
16873   if (VAT_JSON_ARRAY != vam->json_tree.type)
16874     {
16875       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16876       vat_json_init_array (&vam->json_tree);
16877     }
16878   node = vat_json_array_add (&vam->json_tree);
16879
16880   vat_json_init_object (node);
16881   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16882   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16883   vat_json_object_add_ip4 (node, "src_address", ip4);
16884   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16885   vat_json_object_add_ip4 (node, "dst_address", ip4);
16886   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16887   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16888 }
16889
16890 static int
16891 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16892 {
16893   unformat_input_t *i = vam->input;
16894   vl_api_ipsec_gre_tunnel_dump_t *mp;
16895   vl_api_control_ping_t *mp_ping;
16896   u32 sw_if_index;
16897   u8 sw_if_index_set = 0;
16898   int ret;
16899
16900   /* Parse args required to build the message */
16901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16902     {
16903       if (unformat (i, "sw_if_index %d", &sw_if_index))
16904         sw_if_index_set = 1;
16905       else
16906         break;
16907     }
16908
16909   if (sw_if_index_set == 0)
16910     {
16911       sw_if_index = ~0;
16912     }
16913
16914   if (!vam->json_output)
16915     {
16916       print (vam->ofp, "%11s%15s%15s%14s%14s",
16917              "sw_if_index", "src_address", "dst_address",
16918              "local_sa_id", "remote_sa_id");
16919     }
16920
16921   /* Get list of gre-tunnel interfaces */
16922   M (IPSEC_GRE_TUNNEL_DUMP, mp);
16923
16924   mp->sw_if_index = htonl (sw_if_index);
16925
16926   S (mp);
16927
16928   /* Use a control ping for synchronization */
16929   M (CONTROL_PING, mp_ping);
16930   S (mp_ping);
16931
16932   W (ret);
16933   return ret;
16934 }
16935
16936 static int
16937 api_delete_subif (vat_main_t * vam)
16938 {
16939   unformat_input_t *i = vam->input;
16940   vl_api_delete_subif_t *mp;
16941   u32 sw_if_index = ~0;
16942   int ret;
16943
16944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16945     {
16946       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16947         ;
16948       if (unformat (i, "sw_if_index %d", &sw_if_index))
16949         ;
16950       else
16951         break;
16952     }
16953
16954   if (sw_if_index == ~0)
16955     {
16956       errmsg ("missing sw_if_index");
16957       return -99;
16958     }
16959
16960   /* Construct the API message */
16961   M (DELETE_SUBIF, mp);
16962   mp->sw_if_index = ntohl (sw_if_index);
16963
16964   S (mp);
16965   W (ret);
16966   return ret;
16967 }
16968
16969 #define foreach_pbb_vtr_op      \
16970 _("disable",  L2_VTR_DISABLED)  \
16971 _("pop",  L2_VTR_POP_2)         \
16972 _("push",  L2_VTR_PUSH_2)
16973
16974 static int
16975 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16976 {
16977   unformat_input_t *i = vam->input;
16978   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16979   u32 sw_if_index = ~0, vtr_op = ~0;
16980   u16 outer_tag = ~0;
16981   u8 dmac[6], smac[6];
16982   u8 dmac_set = 0, smac_set = 0;
16983   u16 vlanid = 0;
16984   u32 sid = ~0;
16985   u32 tmp;
16986   int ret;
16987
16988   /* Shut up coverity */
16989   memset (dmac, 0, sizeof (dmac));
16990   memset (smac, 0, sizeof (smac));
16991
16992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16993     {
16994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16995         ;
16996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16997         ;
16998       else if (unformat (i, "vtr_op %d", &vtr_op))
16999         ;
17000 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17001       foreach_pbb_vtr_op
17002 #undef _
17003         else if (unformat (i, "translate_pbb_stag"))
17004         {
17005           if (unformat (i, "%d", &tmp))
17006             {
17007               vtr_op = L2_VTR_TRANSLATE_2_1;
17008               outer_tag = tmp;
17009             }
17010           else
17011             {
17012               errmsg
17013                 ("translate_pbb_stag operation requires outer tag definition");
17014               return -99;
17015             }
17016         }
17017       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17018         dmac_set++;
17019       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17020         smac_set++;
17021       else if (unformat (i, "sid %d", &sid))
17022         ;
17023       else if (unformat (i, "vlanid %d", &tmp))
17024         vlanid = tmp;
17025       else
17026         {
17027           clib_warning ("parse error '%U'", format_unformat_error, i);
17028           return -99;
17029         }
17030     }
17031
17032   if ((sw_if_index == ~0) || (vtr_op == ~0))
17033     {
17034       errmsg ("missing sw_if_index or vtr operation");
17035       return -99;
17036     }
17037   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17038       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17039     {
17040       errmsg
17041         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17042       return -99;
17043     }
17044
17045   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17046   mp->sw_if_index = ntohl (sw_if_index);
17047   mp->vtr_op = ntohl (vtr_op);
17048   mp->outer_tag = ntohs (outer_tag);
17049   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17050   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17051   mp->b_vlanid = ntohs (vlanid);
17052   mp->i_sid = ntohl (sid);
17053
17054   S (mp);
17055   W (ret);
17056   return ret;
17057 }
17058
17059 static int
17060 api_flow_classify_set_interface (vat_main_t * vam)
17061 {
17062   unformat_input_t *i = vam->input;
17063   vl_api_flow_classify_set_interface_t *mp;
17064   u32 sw_if_index;
17065   int sw_if_index_set;
17066   u32 ip4_table_index = ~0;
17067   u32 ip6_table_index = ~0;
17068   u8 is_add = 1;
17069   int ret;
17070
17071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17072     {
17073       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17074         sw_if_index_set = 1;
17075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17076         sw_if_index_set = 1;
17077       else if (unformat (i, "del"))
17078         is_add = 0;
17079       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17080         ;
17081       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17082         ;
17083       else
17084         {
17085           clib_warning ("parse error '%U'", format_unformat_error, i);
17086           return -99;
17087         }
17088     }
17089
17090   if (sw_if_index_set == 0)
17091     {
17092       errmsg ("missing interface name or sw_if_index");
17093       return -99;
17094     }
17095
17096   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17097
17098   mp->sw_if_index = ntohl (sw_if_index);
17099   mp->ip4_table_index = ntohl (ip4_table_index);
17100   mp->ip6_table_index = ntohl (ip6_table_index);
17101   mp->is_add = is_add;
17102
17103   S (mp);
17104   W (ret);
17105   return ret;
17106 }
17107
17108 static int
17109 api_flow_classify_dump (vat_main_t * vam)
17110 {
17111   unformat_input_t *i = vam->input;
17112   vl_api_flow_classify_dump_t *mp;
17113   vl_api_control_ping_t *mp_ping;
17114   u8 type = FLOW_CLASSIFY_N_TABLES;
17115   int ret;
17116
17117   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17118     ;
17119   else
17120     {
17121       errmsg ("classify table type must be specified");
17122       return -99;
17123     }
17124
17125   if (!vam->json_output)
17126     {
17127       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17128     }
17129
17130   M (FLOW_CLASSIFY_DUMP, mp);
17131   mp->type = type;
17132   /* send it... */
17133   S (mp);
17134
17135   /* Use a control ping for synchronization */
17136   M (CONTROL_PING, mp_ping);
17137   S (mp_ping);
17138
17139   /* Wait for a reply... */
17140   W (ret);
17141   return ret;
17142 }
17143
17144 static int
17145 api_feature_enable_disable (vat_main_t * vam)
17146 {
17147   unformat_input_t *i = vam->input;
17148   vl_api_feature_enable_disable_t *mp;
17149   u8 *arc_name = 0;
17150   u8 *feature_name = 0;
17151   u32 sw_if_index = ~0;
17152   u8 enable = 1;
17153   int ret;
17154
17155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17156     {
17157       if (unformat (i, "arc_name %s", &arc_name))
17158         ;
17159       else if (unformat (i, "feature_name %s", &feature_name))
17160         ;
17161       else
17162         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17163         ;
17164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17165         ;
17166       else if (unformat (i, "disable"))
17167         enable = 0;
17168       else
17169         break;
17170     }
17171
17172   if (arc_name == 0)
17173     {
17174       errmsg ("missing arc name");
17175       return -99;
17176     }
17177   if (vec_len (arc_name) > 63)
17178     {
17179       errmsg ("arc name too long");
17180     }
17181
17182   if (feature_name == 0)
17183     {
17184       errmsg ("missing feature name");
17185       return -99;
17186     }
17187   if (vec_len (feature_name) > 63)
17188     {
17189       errmsg ("feature name too long");
17190     }
17191
17192   if (sw_if_index == ~0)
17193     {
17194       errmsg ("missing interface name or sw_if_index");
17195       return -99;
17196     }
17197
17198   /* Construct the API message */
17199   M (FEATURE_ENABLE_DISABLE, mp);
17200   mp->sw_if_index = ntohl (sw_if_index);
17201   mp->enable = enable;
17202   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17203   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17204   vec_free (arc_name);
17205   vec_free (feature_name);
17206
17207   S (mp);
17208   W (ret);
17209   return ret;
17210 }
17211
17212 static int
17213 api_sw_interface_tag_add_del (vat_main_t * vam)
17214 {
17215   unformat_input_t *i = vam->input;
17216   vl_api_sw_interface_tag_add_del_t *mp;
17217   u32 sw_if_index = ~0;
17218   u8 *tag = 0;
17219   u8 enable = 1;
17220   int ret;
17221
17222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17223     {
17224       if (unformat (i, "tag %s", &tag))
17225         ;
17226       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17227         ;
17228       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17229         ;
17230       else if (unformat (i, "del"))
17231         enable = 0;
17232       else
17233         break;
17234     }
17235
17236   if (sw_if_index == ~0)
17237     {
17238       errmsg ("missing interface name or sw_if_index");
17239       return -99;
17240     }
17241
17242   if (enable && (tag == 0))
17243     {
17244       errmsg ("no tag specified");
17245       return -99;
17246     }
17247
17248   /* Construct the API message */
17249   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17250   mp->sw_if_index = ntohl (sw_if_index);
17251   mp->is_add = enable;
17252   if (enable)
17253     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17254   vec_free (tag);
17255
17256   S (mp);
17257   W (ret);
17258   return ret;
17259 }
17260
17261 static void vl_api_l2_xconnect_details_t_handler
17262   (vl_api_l2_xconnect_details_t * mp)
17263 {
17264   vat_main_t *vam = &vat_main;
17265
17266   print (vam->ofp, "%15d%15d",
17267          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17268 }
17269
17270 static void vl_api_l2_xconnect_details_t_handler_json
17271   (vl_api_l2_xconnect_details_t * mp)
17272 {
17273   vat_main_t *vam = &vat_main;
17274   vat_json_node_t *node = NULL;
17275
17276   if (VAT_JSON_ARRAY != vam->json_tree.type)
17277     {
17278       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17279       vat_json_init_array (&vam->json_tree);
17280     }
17281   node = vat_json_array_add (&vam->json_tree);
17282
17283   vat_json_init_object (node);
17284   vat_json_object_add_uint (node, "rx_sw_if_index",
17285                             ntohl (mp->rx_sw_if_index));
17286   vat_json_object_add_uint (node, "tx_sw_if_index",
17287                             ntohl (mp->tx_sw_if_index));
17288 }
17289
17290 static int
17291 api_l2_xconnect_dump (vat_main_t * vam)
17292 {
17293   vl_api_l2_xconnect_dump_t *mp;
17294   vl_api_control_ping_t *mp_ping;
17295   int ret;
17296
17297   if (!vam->json_output)
17298     {
17299       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17300     }
17301
17302   M (L2_XCONNECT_DUMP, mp);
17303
17304   S (mp);
17305
17306   /* Use a control ping for synchronization */
17307   M (CONTROL_PING, mp_ping);
17308   S (mp_ping);
17309
17310   W (ret);
17311   return ret;
17312 }
17313
17314 static int
17315 api_sw_interface_set_mtu (vat_main_t * vam)
17316 {
17317   unformat_input_t *i = vam->input;
17318   vl_api_sw_interface_set_mtu_t *mp;
17319   u32 sw_if_index = ~0;
17320   u32 mtu = 0;
17321   int ret;
17322
17323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17324     {
17325       if (unformat (i, "mtu %d", &mtu))
17326         ;
17327       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17328         ;
17329       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17330         ;
17331       else
17332         break;
17333     }
17334
17335   if (sw_if_index == ~0)
17336     {
17337       errmsg ("missing interface name or sw_if_index");
17338       return -99;
17339     }
17340
17341   if (mtu == 0)
17342     {
17343       errmsg ("no mtu specified");
17344       return -99;
17345     }
17346
17347   /* Construct the API message */
17348   M (SW_INTERFACE_SET_MTU, mp);
17349   mp->sw_if_index = ntohl (sw_if_index);
17350   mp->mtu = ntohs ((u16) mtu);
17351
17352   S (mp);
17353   W (ret);
17354   return ret;
17355 }
17356
17357
17358 static int
17359 q_or_quit (vat_main_t * vam)
17360 {
17361   longjmp (vam->jump_buf, 1);
17362   return 0;                     /* not so much */
17363 }
17364
17365 static int
17366 q (vat_main_t * vam)
17367 {
17368   return q_or_quit (vam);
17369 }
17370
17371 static int
17372 quit (vat_main_t * vam)
17373 {
17374   return q_or_quit (vam);
17375 }
17376
17377 static int
17378 comment (vat_main_t * vam)
17379 {
17380   return 0;
17381 }
17382
17383 static int
17384 cmd_cmp (void *a1, void *a2)
17385 {
17386   u8 **c1 = a1;
17387   u8 **c2 = a2;
17388
17389   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17390 }
17391
17392 static int
17393 help (vat_main_t * vam)
17394 {
17395   u8 **cmds = 0;
17396   u8 *name = 0;
17397   hash_pair_t *p;
17398   unformat_input_t *i = vam->input;
17399   int j;
17400
17401   if (unformat (i, "%s", &name))
17402     {
17403       uword *hs;
17404
17405       vec_add1 (name, 0);
17406
17407       hs = hash_get_mem (vam->help_by_name, name);
17408       if (hs)
17409         print (vam->ofp, "usage: %s %s", name, hs[0]);
17410       else
17411         print (vam->ofp, "No such msg / command '%s'", name);
17412       vec_free (name);
17413       return 0;
17414     }
17415
17416   print (vam->ofp, "Help is available for the following:");
17417
17418     /* *INDENT-OFF* */
17419     hash_foreach_pair (p, vam->function_by_name,
17420     ({
17421       vec_add1 (cmds, (u8 *)(p->key));
17422     }));
17423     /* *INDENT-ON* */
17424
17425   vec_sort_with_function (cmds, cmd_cmp);
17426
17427   for (j = 0; j < vec_len (cmds); j++)
17428     print (vam->ofp, "%s", cmds[j]);
17429
17430   vec_free (cmds);
17431   return 0;
17432 }
17433
17434 static int
17435 set (vat_main_t * vam)
17436 {
17437   u8 *name = 0, *value = 0;
17438   unformat_input_t *i = vam->input;
17439
17440   if (unformat (i, "%s", &name))
17441     {
17442       /* The input buffer is a vector, not a string. */
17443       value = vec_dup (i->buffer);
17444       vec_delete (value, i->index, 0);
17445       /* Almost certainly has a trailing newline */
17446       if (value[vec_len (value) - 1] == '\n')
17447         value[vec_len (value) - 1] = 0;
17448       /* Make sure it's a proper string, one way or the other */
17449       vec_add1 (value, 0);
17450       (void) clib_macro_set_value (&vam->macro_main,
17451                                    (char *) name, (char *) value);
17452     }
17453   else
17454     errmsg ("usage: set <name> <value>");
17455
17456   vec_free (name);
17457   vec_free (value);
17458   return 0;
17459 }
17460
17461 static int
17462 unset (vat_main_t * vam)
17463 {
17464   u8 *name = 0;
17465
17466   if (unformat (vam->input, "%s", &name))
17467     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17468       errmsg ("unset: %s wasn't set", name);
17469   vec_free (name);
17470   return 0;
17471 }
17472
17473 typedef struct
17474 {
17475   u8 *name;
17476   u8 *value;
17477 } macro_sort_t;
17478
17479
17480 static int
17481 macro_sort_cmp (void *a1, void *a2)
17482 {
17483   macro_sort_t *s1 = a1;
17484   macro_sort_t *s2 = a2;
17485
17486   return strcmp ((char *) (s1->name), (char *) (s2->name));
17487 }
17488
17489 static int
17490 dump_macro_table (vat_main_t * vam)
17491 {
17492   macro_sort_t *sort_me = 0, *sm;
17493   int i;
17494   hash_pair_t *p;
17495
17496     /* *INDENT-OFF* */
17497     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17498     ({
17499       vec_add2 (sort_me, sm, 1);
17500       sm->name = (u8 *)(p->key);
17501       sm->value = (u8 *) (p->value[0]);
17502     }));
17503     /* *INDENT-ON* */
17504
17505   vec_sort_with_function (sort_me, macro_sort_cmp);
17506
17507   if (vec_len (sort_me))
17508     print (vam->ofp, "%-15s%s", "Name", "Value");
17509   else
17510     print (vam->ofp, "The macro table is empty...");
17511
17512   for (i = 0; i < vec_len (sort_me); i++)
17513     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17514   return 0;
17515 }
17516
17517 static int
17518 dump_node_table (vat_main_t * vam)
17519 {
17520   int i, j;
17521   vlib_node_t *node, *next_node;
17522
17523   if (vec_len (vam->graph_nodes) == 0)
17524     {
17525       print (vam->ofp, "Node table empty, issue get_node_graph...");
17526       return 0;
17527     }
17528
17529   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17530     {
17531       node = vam->graph_nodes[i];
17532       print (vam->ofp, "[%d] %s", i, node->name);
17533       for (j = 0; j < vec_len (node->next_nodes); j++)
17534         {
17535           if (node->next_nodes[j] != ~0)
17536             {
17537               next_node = vam->graph_nodes[node->next_nodes[j]];
17538               print (vam->ofp, "  [%d] %s", j, next_node->name);
17539             }
17540         }
17541     }
17542   return 0;
17543 }
17544
17545 static int
17546 value_sort_cmp (void *a1, void *a2)
17547 {
17548   name_sort_t *n1 = a1;
17549   name_sort_t *n2 = a2;
17550
17551   if (n1->value < n2->value)
17552     return -1;
17553   if (n1->value > n2->value)
17554     return 1;
17555   return 0;
17556 }
17557
17558
17559 static int
17560 dump_msg_api_table (vat_main_t * vam)
17561 {
17562   api_main_t *am = &api_main;
17563   name_sort_t *nses = 0, *ns;
17564   hash_pair_t *hp;
17565   int i;
17566
17567   /* *INDENT-OFF* */
17568   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17569   ({
17570     vec_add2 (nses, ns, 1);
17571     ns->name = (u8 *)(hp->key);
17572     ns->value = (u32) hp->value[0];
17573   }));
17574   /* *INDENT-ON* */
17575
17576   vec_sort_with_function (nses, value_sort_cmp);
17577
17578   for (i = 0; i < vec_len (nses); i++)
17579     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17580   vec_free (nses);
17581   return 0;
17582 }
17583
17584 static int
17585 get_msg_id (vat_main_t * vam)
17586 {
17587   u8 *name_and_crc;
17588   u32 message_index;
17589
17590   if (unformat (vam->input, "%s", &name_and_crc))
17591     {
17592       message_index = vl_api_get_msg_index (name_and_crc);
17593       if (message_index == ~0)
17594         {
17595           print (vam->ofp, " '%s' not found", name_and_crc);
17596           return 0;
17597         }
17598       print (vam->ofp, " '%s' has message index %d",
17599              name_and_crc, message_index);
17600       return 0;
17601     }
17602   errmsg ("name_and_crc required...");
17603   return 0;
17604 }
17605
17606 static int
17607 search_node_table (vat_main_t * vam)
17608 {
17609   unformat_input_t *line_input = vam->input;
17610   u8 *node_to_find;
17611   int j;
17612   vlib_node_t *node, *next_node;
17613   uword *p;
17614
17615   if (vam->graph_node_index_by_name == 0)
17616     {
17617       print (vam->ofp, "Node table empty, issue get_node_graph...");
17618       return 0;
17619     }
17620
17621   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17622     {
17623       if (unformat (line_input, "%s", &node_to_find))
17624         {
17625           vec_add1 (node_to_find, 0);
17626           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17627           if (p == 0)
17628             {
17629               print (vam->ofp, "%s not found...", node_to_find);
17630               goto out;
17631             }
17632           node = vam->graph_nodes[p[0]];
17633           print (vam->ofp, "[%d] %s", p[0], node->name);
17634           for (j = 0; j < vec_len (node->next_nodes); j++)
17635             {
17636               if (node->next_nodes[j] != ~0)
17637                 {
17638                   next_node = vam->graph_nodes[node->next_nodes[j]];
17639                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17640                 }
17641             }
17642         }
17643
17644       else
17645         {
17646           clib_warning ("parse error '%U'", format_unformat_error,
17647                         line_input);
17648           return -99;
17649         }
17650
17651     out:
17652       vec_free (node_to_find);
17653
17654     }
17655
17656   return 0;
17657 }
17658
17659
17660 static int
17661 script (vat_main_t * vam)
17662 {
17663 #if (VPP_API_TEST_BUILTIN==0)
17664   u8 *s = 0;
17665   char *save_current_file;
17666   unformat_input_t save_input;
17667   jmp_buf save_jump_buf;
17668   u32 save_line_number;
17669
17670   FILE *new_fp, *save_ifp;
17671
17672   if (unformat (vam->input, "%s", &s))
17673     {
17674       new_fp = fopen ((char *) s, "r");
17675       if (new_fp == 0)
17676         {
17677           errmsg ("Couldn't open script file %s", s);
17678           vec_free (s);
17679           return -99;
17680         }
17681     }
17682   else
17683     {
17684       errmsg ("Missing script name");
17685       return -99;
17686     }
17687
17688   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17689   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17690   save_ifp = vam->ifp;
17691   save_line_number = vam->input_line_number;
17692   save_current_file = (char *) vam->current_file;
17693
17694   vam->input_line_number = 0;
17695   vam->ifp = new_fp;
17696   vam->current_file = s;
17697   do_one_file (vam);
17698
17699   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17700   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17701   vam->ifp = save_ifp;
17702   vam->input_line_number = save_line_number;
17703   vam->current_file = (u8 *) save_current_file;
17704   vec_free (s);
17705
17706   return 0;
17707 #else
17708   clib_warning ("use the exec command...");
17709   return -99;
17710 #endif
17711 }
17712
17713 static int
17714 echo (vat_main_t * vam)
17715 {
17716   print (vam->ofp, "%v", vam->input->buffer);
17717   return 0;
17718 }
17719
17720 /* List of API message constructors, CLI names map to api_xxx */
17721 #define foreach_vpe_api_msg                                             \
17722 _(create_loopback,"[mac <mac-addr>]")                                   \
17723 _(sw_interface_dump,"")                                                 \
17724 _(sw_interface_set_flags,                                               \
17725   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17726 _(sw_interface_add_del_address,                                         \
17727   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17728 _(sw_interface_set_table,                                               \
17729   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17730 _(sw_interface_set_mpls_enable,                                         \
17731   "<intfc> | sw_if_index [disable | dis]")                              \
17732 _(sw_interface_set_vpath,                                               \
17733   "<intfc> | sw_if_index <id> enable | disable")                        \
17734 _(sw_interface_set_vxlan_bypass,                                        \
17735   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
17736 _(sw_interface_set_l2_xconnect,                                         \
17737   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17738   "enable | disable")                                                   \
17739 _(sw_interface_set_l2_bridge,                                           \
17740   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17741   "[shg <split-horizon-group>] [bvi]\n"                                 \
17742   "enable | disable")                                                   \
17743 _(bridge_domain_add_del,                                                \
17744   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17745 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17746 _(l2fib_add_del,                                                        \
17747   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17748 _(l2_flags,                                                             \
17749   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17750 _(bridge_flags,                                                         \
17751   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17752 _(tap_connect,                                                          \
17753   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17754 _(tap_modify,                                                           \
17755   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17756 _(tap_delete,                                                           \
17757   "<vpp-if-name> | sw_if_index <id>")                                   \
17758 _(sw_interface_tap_dump, "")                                            \
17759 _(ip_add_del_route,                                                     \
17760   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17761   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17762   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17763   "[multipath] [count <n>]")                                            \
17764 _(ip_mroute_add_del,                                                    \
17765   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
17766   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
17767 _(mpls_route_add_del,                                                   \
17768   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17769   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17770   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17771   "[multipath] [count <n>]")                                            \
17772 _(mpls_ip_bind_unbind,                                                  \
17773   "<label> <addr/len>")                                                 \
17774 _(mpls_tunnel_add_del,                                                  \
17775   " via <addr> [table-id <n>]\n"                                        \
17776   "sw_if_index <id>] [l2]  [del]")                                      \
17777 _(proxy_arp_add_del,                                                    \
17778   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17779 _(proxy_arp_intfc_enable_disable,                                       \
17780   "<intfc> | sw_if_index <id> enable | disable")                        \
17781 _(sw_interface_set_unnumbered,                                          \
17782   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17783 _(ip_neighbor_add_del,                                                  \
17784   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17785   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17786 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17787 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17788 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17789   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17790   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17791   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17792 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17793 _(reset_fib, "vrf <n> [ipv6]")                                          \
17794 _(dhcp_proxy_config,                                                    \
17795   "svr <v46-address> src <v46-address>\n"                               \
17796    "insert-cid <n> [del]")                                              \
17797 _(dhcp_proxy_config_2,                                                  \
17798   "svr <v46-address> src <v46-address>\n"                               \
17799    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17800 _(dhcp_proxy_set_vss,                                                   \
17801   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17802 _(dhcp_client_config,                                                   \
17803   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17804 _(set_ip_flow_hash,                                                     \
17805   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17806 _(sw_interface_ip6_enable_disable,                                      \
17807   "<intfc> | sw_if_index <id> enable | disable")                        \
17808 _(sw_interface_ip6_set_link_local_address,                              \
17809   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17810 _(sw_interface_ip6nd_ra_prefix,                                         \
17811   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17812   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17813   "[nolink] [isno]")                                                    \
17814 _(sw_interface_ip6nd_ra_config,                                         \
17815   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17816   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17817   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17818 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17819 _(l2_patch_add_del,                                                     \
17820   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17821   "enable | disable")                                                   \
17822 _(sr_tunnel_add_del,                                                    \
17823   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17824   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17825   "[policy <policy_name>]")                                             \
17826 _(sr_policy_add_del,                                                    \
17827   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17828 _(sr_multicast_map_add_del,                                             \
17829   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17830 _(classify_add_del_table,                                               \
17831   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17832   " [del] [del-chain] mask <mask-value>\n"                              \
17833   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17834   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17835 _(classify_add_del_session,                                             \
17836   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17837   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17838   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17839   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17840 _(classify_set_interface_ip_table,                                      \
17841   "<intfc> | sw_if_index <nn> table <nn>")                              \
17842 _(classify_set_interface_l2_tables,                                     \
17843   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17844   "  [other-table <nn>]")                                               \
17845 _(get_node_index, "node <node-name")                                    \
17846 _(add_node_next, "node <node-name> next <next-node-name>")              \
17847 _(l2tpv3_create_tunnel,                                                 \
17848   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17849   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17850   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17851 _(l2tpv3_set_tunnel_cookies,                                            \
17852   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17853   "[new_remote_cookie <nn>]\n")                                         \
17854 _(l2tpv3_interface_enable_disable,                                      \
17855   "<intfc> | sw_if_index <nn> enable | disable")                        \
17856 _(l2tpv3_set_lookup_key,                                                \
17857   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17858 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17859 _(vxlan_add_del_tunnel,                                                 \
17860   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17861   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17862   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17863 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17864 _(gre_add_del_tunnel,                                                   \
17865   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17866 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17867 _(l2_fib_clear_table, "")                                               \
17868 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17869 _(l2_interface_vlan_tag_rewrite,                                        \
17870   "<intfc> | sw_if_index <nn> \n"                                       \
17871   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17872   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17873 _(create_vhost_user_if,                                                 \
17874         "socket <filename> [server] [renumber <dev_instance>] "         \
17875         "[mac <mac_address>]")                                          \
17876 _(modify_vhost_user_if,                                                 \
17877         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17878         "[server] [renumber <dev_instance>]")                           \
17879 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17880 _(sw_interface_vhost_user_dump, "")                                     \
17881 _(show_version, "")                                                     \
17882 _(vxlan_gpe_add_del_tunnel,                                             \
17883   "local <addr> remote <addr> vni <nn>\n"                               \
17884     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17885   "[next-ethernet] [next-nsh]\n")                                       \
17886 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17887 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17888 _(interface_name_renumber,                                              \
17889   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17890 _(input_acl_set_interface,                                              \
17891   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17892   "  [l2-table <nn>] [del]")                                            \
17893 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17894 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17895 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17896 _(ip_dump, "ipv4 | ipv6")                                               \
17897 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17898 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17899   "  spid_id <n> ")                                                     \
17900 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17901   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17902   "  integ_alg <alg> integ_key <hex>")                                  \
17903 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17904   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17905   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17906   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17907 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17908 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17909 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17910   "(auth_data 0x<data> | auth_data <data>)")                            \
17911 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17912   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17913 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17914   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17915   "(local|remote)")                                                     \
17916 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17917 _(delete_loopback,"sw_if_index <nn>")                                   \
17918 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17919 _(map_add_domain,                                                       \
17920   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17921   "ip6-src <ip6addr> "                                                  \
17922   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17923 _(map_del_domain, "index <n>")                                          \
17924 _(map_add_del_rule,                                                     \
17925   "index <n> psid <n> dst <ip6addr> [del]")                             \
17926 _(map_domain_dump, "")                                                  \
17927 _(map_rule_dump, "index <map-domain>")                                  \
17928 _(want_interface_events,  "enable|disable")                             \
17929 _(want_stats,"enable|disable")                                          \
17930 _(get_first_msg_id, "client <name>")                                    \
17931 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17932 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17933   "fib-id <nn> [ip4][ip6][default]")                                    \
17934 _(get_node_graph, " ")                                                  \
17935 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17936 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17937 _(ioam_disable, "")                                                     \
17938 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17939                             " sw_if_index <sw_if_index> p <priority> "  \
17940                             "w <weight>] [del]")                        \
17941 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17942                         "iface <intf> | sw_if_index <sw_if_index> "     \
17943                         "p <priority> w <weight> [del]")                \
17944 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17945                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17946                          "locator-set <locator_name> [del]"             \
17947                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17948 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
17949   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
17950 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17951 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17952 _(lisp_gpe_enable_disable, "enable|disable")                            \
17953 _(lisp_enable_disable, "enable|disable")                                \
17954 _(lisp_map_register_enable_disable, "enable|disable")                   \
17955 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17956 _(lisp_gpe_add_del_iface, "up|down")                                    \
17957 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17958                                "[seid <seid>] "                         \
17959                                "rloc <locator> p <prio> "               \
17960                                "w <weight> [rloc <loc> ... ] "          \
17961                                "action <action> [del-all]")             \
17962 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17963                           "<local-eid>")                                \
17964 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17965 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17966 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17967 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17968 _(lisp_locator_set_dump, "[local | remote]")                            \
17969 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17970 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17971                        "[local] | [remote]")                            \
17972 _(lisp_eid_table_vni_dump, "")                                          \
17973 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17974 _(lisp_map_resolver_dump, "")                                           \
17975 _(lisp_map_server_dump, "")                                             \
17976 _(lisp_adjacencies_get, "vni <vni>")                                    \
17977 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
17978 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
17979 _(show_lisp_rloc_probe_state, "")                                       \
17980 _(show_lisp_map_register_state, "")                                     \
17981 _(show_lisp_status, "")                                                 \
17982 _(lisp_get_map_request_itr_rlocs, "")                                   \
17983 _(show_lisp_pitr, "")                                                   \
17984 _(show_lisp_map_request_mode, "")                                       \
17985 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17986 _(af_packet_delete, "name <host interface name>")                       \
17987 _(policer_add_del, "name <policer name> <params> [del]")                \
17988 _(policer_dump, "[name <policer name>]")                                \
17989 _(policer_classify_set_interface,                                       \
17990   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17991   "  [l2-table <nn>] [del]")                                            \
17992 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17993 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17994     "[master|slave]")                                                   \
17995 _(netmap_delete, "name <interface name>")                               \
17996 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17997 _(mpls_fib_dump, "")                                                    \
17998 _(classify_table_ids, "")                                               \
17999 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18000 _(classify_table_info, "table_id <nn>")                                 \
18001 _(classify_session_dump, "table_id <nn>")                               \
18002 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18003     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18004     "[template_interval <nn>] [udp_checksum]")                          \
18005 _(ipfix_exporter_dump, "")                                              \
18006 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18007 _(ipfix_classify_stream_dump, "")                                       \
18008 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18009 _(ipfix_classify_table_dump, "")                                        \
18010 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18011 _(sw_interface_span_dump, "")                                           \
18012 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18013 _(pg_create_interface, "if_id <nn>")                                    \
18014 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18015 _(pg_enable_disable, "[stream <id>] disable")                           \
18016 _(ip_source_and_port_range_check_add_del,                               \
18017   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18018 _(ip_source_and_port_range_check_interface_add_del,                     \
18019   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18020   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18021 _(ipsec_gre_add_del_tunnel,                                             \
18022   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18023 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18024 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18025 _(l2_interface_pbb_tag_rewrite,                                         \
18026   "<intfc> | sw_if_index <nn> \n"                                       \
18027   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18028   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18029 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18030 _(flow_classify_set_interface,                                          \
18031   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18032 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18033 _(ip_fib_dump, "")                                                      \
18034 _(ip6_fib_dump, "")                                                     \
18035 _(feature_enable_disable, "arc_name <arc_name> "                        \
18036   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18037 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18038 "[disable]")                                                            \
18039 _(l2_xconnect_dump, "")                                                 \
18040 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18041 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18042 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18043
18044 #if DPDK > 0
18045 #define foreach_vpe_dpdk_api_msg                                        \
18046 _(sw_interface_set_dpdk_hqos_pipe,                                      \
18047   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
18048   "profile <profile-id>\n")                                             \
18049 _(sw_interface_set_dpdk_hqos_subport,                                   \
18050   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
18051   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
18052 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
18053   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
18054 #endif
18055
18056 /* List of command functions, CLI names map directly to functions */
18057 #define foreach_cli_function                                    \
18058 _(comment, "usage: comment <ignore-rest-of-line>")              \
18059 _(dump_interface_table, "usage: dump_interface_table")          \
18060 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18061 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18062 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18063 _(dump_stats_table, "usage: dump_stats_table")                  \
18064 _(dump_macro_table, "usage: dump_macro_table ")                 \
18065 _(dump_node_table, "usage: dump_node_table")                    \
18066 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18067 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18068 _(echo, "usage: echo <message>")                                \
18069 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18070 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18071 _(help, "usage: help")                                          \
18072 _(q, "usage: quit")                                             \
18073 _(quit, "usage: quit")                                          \
18074 _(search_node_table, "usage: search_node_table <name>...")      \
18075 _(set, "usage: set <variable-name> <value>")                    \
18076 _(script, "usage: script <file-name>")                          \
18077 _(unset, "usage: unset <variable-name>")
18078
18079 #define _(N,n)                                  \
18080     static void vl_api_##n##_t_handler_uni      \
18081     (vl_api_##n##_t * mp)                       \
18082     {                                           \
18083         vat_main_t * vam = &vat_main;           \
18084         if (vam->json_output) {                 \
18085             vl_api_##n##_t_handler_json(mp);    \
18086         } else {                                \
18087             vl_api_##n##_t_handler(mp);         \
18088         }                                       \
18089     }
18090 foreach_vpe_api_reply_msg;
18091 #undef _
18092
18093 #if DPDK > 0
18094 #define _(N,n)                                  \
18095     static void vl_api_##n##_t_handler_uni      \
18096     (vl_api_##n##_t * mp)                       \
18097     {                                           \
18098         vat_main_t * vam = &vat_main;           \
18099         if (vam->json_output) {                 \
18100             vl_api_##n##_t_handler_json(mp);    \
18101         } else {                                \
18102             vl_api_##n##_t_handler(mp);         \
18103         }                                       \
18104     }
18105 foreach_vpe_dpdk_api_reply_msg;
18106 #undef _
18107 #endif
18108
18109 void
18110 vat_api_hookup (vat_main_t * vam)
18111 {
18112 #define _(N,n)                                                  \
18113     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18114                            vl_api_##n##_t_handler_uni,          \
18115                            vl_noop_handler,                     \
18116                            vl_api_##n##_t_endian,               \
18117                            vl_api_##n##_t_print,                \
18118                            sizeof(vl_api_##n##_t), 1);
18119   foreach_vpe_api_reply_msg;
18120 #undef _
18121
18122 #if DPDK > 0
18123 #define _(N,n)                                                  \
18124     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18125                            vl_api_##n##_t_handler_uni,          \
18126                            vl_noop_handler,                     \
18127                            vl_api_##n##_t_endian,               \
18128                            vl_api_##n##_t_print,                \
18129                            sizeof(vl_api_##n##_t), 1);
18130   foreach_vpe_dpdk_api_reply_msg;
18131 #undef _
18132 #endif
18133
18134 #if (VPP_API_TEST_BUILTIN==0)
18135   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18136 #endif
18137
18138   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18139
18140   vam->function_by_name = hash_create_string (0, sizeof (uword));
18141
18142   vam->help_by_name = hash_create_string (0, sizeof (uword));
18143
18144   /* API messages we can send */
18145 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18146   foreach_vpe_api_msg;
18147 #undef _
18148 #if DPDK >0
18149 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18150   foreach_vpe_dpdk_api_msg;
18151 #undef _
18152 #endif
18153
18154   /* Help strings */
18155 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18156   foreach_vpe_api_msg;
18157 #undef _
18158 #if DPDK >0
18159 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18160   foreach_vpe_dpdk_api_msg;
18161 #undef _
18162 #endif
18163
18164   /* CLI functions */
18165 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18166   foreach_cli_function;
18167 #undef _
18168
18169   /* Help strings */
18170 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18171   foreach_cli_function;
18172 #undef _
18173 }
18174
18175 /*
18176  * fd.io coding-style-patch-verification: ON
18177  *
18178  * Local Variables:
18179  * eval: (c-set-style "gnu")
18180  * End:
18181  */