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