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