Add Overlay Network Engine API
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52
53 #include "vat/json_format.h"
54
55 #include <inttypes.h>
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp/api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp/api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp/api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 #define __plugin_msg_base 0
75 #include <vlibapi/vat_helper_macros.h>
76
77 f64
78 vat_time_now (vat_main_t * vam)
79 {
80 #if VPP_API_TEST_BUILTIN
81   return vlib_time_now (vam->vlib_main);
82 #else
83   return clib_time_now (&vam->clib_time);
84 #endif
85 }
86
87 void
88 errmsg (char *fmt, ...)
89 {
90   vat_main_t *vam = &vat_main;
91   va_list va;
92   u8 *s;
93
94   va_start (va, fmt);
95   s = va_format (0, fmt, &va);
96   va_end (va);
97
98   vec_add1 (s, 0);
99
100 #if VPP_API_TEST_BUILTIN
101   vlib_cli_output (vam->vlib_main, (char *) s);
102 #else
103   {
104     if (vam->ifp != stdin)
105       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
106                vam->input_line_number);
107     fformat (vam->ofp, (char *) s);
108     fflush (vam->ofp);
109   }
110 #endif
111
112   vec_free (s);
113 }
114
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 #if VPP_API_TEST_BUILTIN == 0
134 /* Parse an IP4 address %d.%d.%d.%d. */
135 uword
136 unformat_ip4_address (unformat_input_t * input, va_list * args)
137 {
138   u8 *result = va_arg (*args, u8 *);
139   unsigned a[4];
140
141   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
142     return 0;
143
144   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
145     return 0;
146
147   result[0] = a[0];
148   result[1] = a[1];
149   result[2] = a[2];
150   result[3] = a[3];
151
152   return 1;
153 }
154
155 uword
156 unformat_ethernet_address (unformat_input_t * input, va_list * args)
157 {
158   u8 *result = va_arg (*args, u8 *);
159   u32 i, a[6];
160
161   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
162                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
163     return 0;
164
165   /* Check range. */
166   for (i = 0; i < 6; i++)
167     if (a[i] >= (1 << 8))
168       return 0;
169
170   for (i = 0; i < 6; i++)
171     result[i] = a[i];
172
173   return 1;
174 }
175
176 /* Returns ethernet type as an int in host byte order. */
177 uword
178 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
179                                         va_list * args)
180 {
181   u16 *result = va_arg (*args, u16 *);
182   int type;
183
184   /* Numeric type. */
185   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
186     {
187       if (type >= (1 << 16))
188         return 0;
189       *result = type;
190       return 1;
191     }
192   return 0;
193 }
194
195 /* Parse an IP6 address. */
196 uword
197 unformat_ip6_address (unformat_input_t * input, va_list * args)
198 {
199   ip6_address_t *result = va_arg (*args, ip6_address_t *);
200   u16 hex_quads[8];
201   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
202   uword c, n_colon, double_colon_index;
203
204   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
205   double_colon_index = ARRAY_LEN (hex_quads);
206   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
207     {
208       hex_digit = 16;
209       if (c >= '0' && c <= '9')
210         hex_digit = c - '0';
211       else if (c >= 'a' && c <= 'f')
212         hex_digit = c + 10 - 'a';
213       else if (c >= 'A' && c <= 'F')
214         hex_digit = c + 10 - 'A';
215       else if (c == ':' && n_colon < 2)
216         n_colon++;
217       else
218         {
219           unformat_put_input (input);
220           break;
221         }
222
223       /* Too many hex quads. */
224       if (n_hex_quads >= ARRAY_LEN (hex_quads))
225         return 0;
226
227       if (hex_digit < 16)
228         {
229           hex_quad = (hex_quad << 4) | hex_digit;
230
231           /* Hex quad must fit in 16 bits. */
232           if (n_hex_digits >= 4)
233             return 0;
234
235           n_colon = 0;
236           n_hex_digits++;
237         }
238
239       /* Save position of :: */
240       if (n_colon == 2)
241         {
242           /* More than one :: ? */
243           if (double_colon_index < ARRAY_LEN (hex_quads))
244             return 0;
245           double_colon_index = n_hex_quads;
246         }
247
248       if (n_colon > 0 && n_hex_digits > 0)
249         {
250           hex_quads[n_hex_quads++] = hex_quad;
251           hex_quad = 0;
252           n_hex_digits = 0;
253         }
254     }
255
256   if (n_hex_digits > 0)
257     hex_quads[n_hex_quads++] = hex_quad;
258
259   {
260     word i;
261
262     /* Expand :: to appropriate number of zero hex quads. */
263     if (double_colon_index < ARRAY_LEN (hex_quads))
264       {
265         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
266
267         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
268           hex_quads[n_zero + i] = hex_quads[i];
269
270         for (i = 0; i < n_zero; i++)
271           hex_quads[double_colon_index + i] = 0;
272
273         n_hex_quads = ARRAY_LEN (hex_quads);
274       }
275
276     /* Too few hex quads given. */
277     if (n_hex_quads < ARRAY_LEN (hex_quads))
278       return 0;
279
280     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
281       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
282
283     return 1;
284   }
285 }
286
287 uword
288 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
289 {
290   u32 *r = va_arg (*args, u32 *);
291
292   if (0);
293 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
294   foreach_ipsec_policy_action
295 #undef _
296     else
297     return 0;
298   return 1;
299 }
300
301 uword
302 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
303 {
304   u32 *r = va_arg (*args, u32 *);
305
306   if (0);
307 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
308   foreach_ipsec_crypto_alg
309 #undef _
310     else
311     return 0;
312   return 1;
313 }
314
315 u8 *
316 format_ipsec_crypto_alg (u8 * s, va_list * args)
317 {
318   u32 i = va_arg (*args, u32);
319   u8 *t = 0;
320
321   switch (i)
322     {
323 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
324       foreach_ipsec_crypto_alg
325 #undef _
326     default:
327       return format (s, "unknown");
328     }
329   return format (s, "%s", t);
330 }
331
332 uword
333 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
334 {
335   u32 *r = va_arg (*args, u32 *);
336
337   if (0);
338 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
339   foreach_ipsec_integ_alg
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 u8 *
347 format_ipsec_integ_alg (u8 * s, va_list * args)
348 {
349   u32 i = va_arg (*args, u32);
350   u8 *t = 0;
351
352   switch (i)
353     {
354 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
355       foreach_ipsec_integ_alg
356 #undef _
357     default:
358       return format (s, "unknown");
359     }
360   return format (s, "%s", t);
361 }
362
363 uword
364 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
370   foreach_ikev2_auth_method
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 uword
378 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
379 {
380   u32 *r = va_arg (*args, u32 *);
381
382   if (0);
383 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
384   foreach_ikev2_id_type
385 #undef _
386     else
387     return 0;
388   return 1;
389 }
390 #endif /* VPP_API_TEST_BUILTIN */
391
392 static uword
393 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "kbps"))
398     *r = SSE2_QOS_RATE_KBPS;
399   else if (unformat (input, "pps"))
400     *r = SSE2_QOS_RATE_PPS;
401   else
402     return 0;
403   return 1;
404 }
405
406 static uword
407 unformat_policer_round_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "closest"))
412     *r = SSE2_QOS_ROUND_TO_CLOSEST;
413   else if (unformat (input, "up"))
414     *r = SSE2_QOS_ROUND_TO_UP;
415   else if (unformat (input, "down"))
416     *r = SSE2_QOS_ROUND_TO_DOWN;
417   else
418     return 0;
419   return 1;
420 }
421
422 static uword
423 unformat_policer_type (unformat_input_t * input, va_list * args)
424 {
425   u8 *r = va_arg (*args, u8 *);
426
427   if (unformat (input, "1r2c"))
428     *r = SSE2_QOS_POLICER_TYPE_1R2C;
429   else if (unformat (input, "1r3c"))
430     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
431   else if (unformat (input, "2r3c-2698"))
432     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
433   else if (unformat (input, "2r3c-4115"))
434     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
435   else if (unformat (input, "2r3c-mef5cf1"))
436     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
437   else
438     return 0;
439   return 1;
440 }
441
442 static uword
443 unformat_dscp (unformat_input_t * input, va_list * va)
444 {
445   u8 *r = va_arg (*va, u8 *);
446
447   if (0);
448 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
449   foreach_vnet_dscp
450 #undef _
451     else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_policer_action_type (unformat_input_t * input, va_list * va)
458 {
459   sse2_qos_pol_action_params_st *a
460     = va_arg (*va, sse2_qos_pol_action_params_st *);
461
462   if (unformat (input, "drop"))
463     a->action_type = SSE2_QOS_ACTION_DROP;
464   else if (unformat (input, "transmit"))
465     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
466   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
467     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
468   else
469     return 0;
470   return 1;
471 }
472
473 static uword
474 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
475 {
476   u32 *r = va_arg (*va, u32 *);
477   u32 tid;
478
479   if (unformat (input, "ip4"))
480     tid = POLICER_CLASSIFY_TABLE_IP4;
481   else if (unformat (input, "ip6"))
482     tid = POLICER_CLASSIFY_TABLE_IP6;
483   else if (unformat (input, "l2"))
484     tid = POLICER_CLASSIFY_TABLE_L2;
485   else
486     return 0;
487
488   *r = tid;
489   return 1;
490 }
491
492 static uword
493 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
494 {
495   u32 *r = va_arg (*va, u32 *);
496   u32 tid;
497
498   if (unformat (input, "ip4"))
499     tid = FLOW_CLASSIFY_TABLE_IP4;
500   else if (unformat (input, "ip6"))
501     tid = FLOW_CLASSIFY_TABLE_IP6;
502   else
503     return 0;
504
505   *r = tid;
506   return 1;
507 }
508
509 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
510 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
511 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
512 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
513
514 uword
515 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
516 {
517   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
518   mfib_itf_attribute_t attr;
519
520   old = *iflags;
521   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
522   {
523     if (unformat (input, mfib_itf_flag_long_names[attr]))
524       *iflags |= (1 << attr);
525   }
526   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
527   {
528     if (unformat (input, mfib_itf_flag_names[attr]))
529       *iflags |= (1 << attr);
530   }
531
532   return (old == *iflags ? 0 : 1);
533 }
534
535 uword
536 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
537 {
538   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
539   mfib_entry_attribute_t attr;
540
541   old = *eflags;
542   FOR_EACH_MFIB_ATTRIBUTE (attr)
543   {
544     if (unformat (input, mfib_flag_long_names[attr]))
545       *eflags |= (1 << attr);
546   }
547   FOR_EACH_MFIB_ATTRIBUTE (attr)
548   {
549     if (unformat (input, mfib_flag_names[attr]))
550       *eflags |= (1 << attr);
551   }
552
553   return (old == *eflags ? 0 : 1);
554 }
555
556 #if (VPP_API_TEST_BUILTIN==0)
557 u8 *
558 format_ip4_address (u8 * s, va_list * args)
559 {
560   u8 *a = va_arg (*args, u8 *);
561   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
562 }
563
564 u8 *
565 format_ip6_address (u8 * s, va_list * args)
566 {
567   ip6_address_t *a = va_arg (*args, ip6_address_t *);
568   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
569
570   i_max_n_zero = ARRAY_LEN (a->as_u16);
571   max_n_zeros = 0;
572   i_first_zero = i_max_n_zero;
573   n_zeros = 0;
574   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
575     {
576       u32 is_zero = a->as_u16[i] == 0;
577       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
578         {
579           i_first_zero = i;
580           n_zeros = 0;
581         }
582       n_zeros += is_zero;
583       if ((!is_zero && n_zeros > max_n_zeros)
584           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
585         {
586           i_max_n_zero = i_first_zero;
587           max_n_zeros = n_zeros;
588           i_first_zero = ARRAY_LEN (a->as_u16);
589           n_zeros = 0;
590         }
591     }
592
593   last_double_colon = 0;
594   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
595     {
596       if (i == i_max_n_zero && max_n_zeros > 1)
597         {
598           s = format (s, "::");
599           i += max_n_zeros - 1;
600           last_double_colon = 1;
601         }
602       else
603         {
604           s = format (s, "%s%x",
605                       (last_double_colon || i == 0) ? "" : ":",
606                       clib_net_to_host_u16 (a->as_u16[i]));
607           last_double_colon = 0;
608         }
609     }
610
611   return s;
612 }
613
614 /* Format an IP46 address. */
615 u8 *
616 format_ip46_address (u8 * s, va_list * args)
617 {
618   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
619   ip46_type_t type = va_arg (*args, ip46_type_t);
620   int is_ip4 = 1;
621
622   switch (type)
623     {
624     case IP46_TYPE_ANY:
625       is_ip4 = ip46_address_is_ip4 (ip46);
626       break;
627     case IP46_TYPE_IP4:
628       is_ip4 = 1;
629       break;
630     case IP46_TYPE_IP6:
631       is_ip4 = 0;
632       break;
633     }
634
635   return is_ip4 ?
636     format (s, "%U", format_ip4_address, &ip46->ip4) :
637     format (s, "%U", format_ip6_address, &ip46->ip6);
638 }
639
640 u8 *
641 format_ethernet_address (u8 * s, va_list * args)
642 {
643   u8 *a = va_arg (*args, u8 *);
644
645   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
646                  a[0], a[1], a[2], a[3], a[4], a[5]);
647 }
648 #endif
649
650 static void
651 increment_v4_address (ip4_address_t * a)
652 {
653   u32 v;
654
655   v = ntohl (a->as_u32) + 1;
656   a->as_u32 = ntohl (v);
657 }
658
659 static void
660 increment_v6_address (ip6_address_t * a)
661 {
662   u64 v0, v1;
663
664   v0 = clib_net_to_host_u64 (a->as_u64[0]);
665   v1 = clib_net_to_host_u64 (a->as_u64[1]);
666
667   v1 += 1;
668   if (v1 == 0)
669     v0 += 1;
670   a->as_u64[0] = clib_net_to_host_u64 (v0);
671   a->as_u64[1] = clib_net_to_host_u64 (v1);
672 }
673
674 static void
675 increment_mac_address (u64 * mac)
676 {
677   u64 tmp = *mac;
678
679   tmp = clib_net_to_host_u64 (tmp);
680   tmp += 1 << 16;               /* skip unused (least significant) octets */
681   tmp = clib_host_to_net_u64 (tmp);
682   *mac = tmp;
683 }
684
685 static void vl_api_create_loopback_reply_t_handler
686   (vl_api_create_loopback_reply_t * mp)
687 {
688   vat_main_t *vam = &vat_main;
689   i32 retval = ntohl (mp->retval);
690
691   vam->retval = retval;
692   vam->regenerate_interface_table = 1;
693   vam->sw_if_index = ntohl (mp->sw_if_index);
694   vam->result_ready = 1;
695 }
696
697 static void vl_api_create_loopback_reply_t_handler_json
698   (vl_api_create_loopback_reply_t * mp)
699 {
700   vat_main_t *vam = &vat_main;
701   vat_json_node_t node;
702
703   vat_json_init_object (&node);
704   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
705   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
706
707   vat_json_print (vam->ofp, &node);
708   vat_json_free (&node);
709   vam->retval = ntohl (mp->retval);
710   vam->result_ready = 1;
711 }
712
713 static void vl_api_af_packet_create_reply_t_handler
714   (vl_api_af_packet_create_reply_t * mp)
715 {
716   vat_main_t *vam = &vat_main;
717   i32 retval = ntohl (mp->retval);
718
719   vam->retval = retval;
720   vam->regenerate_interface_table = 1;
721   vam->sw_if_index = ntohl (mp->sw_if_index);
722   vam->result_ready = 1;
723 }
724
725 static void vl_api_af_packet_create_reply_t_handler_json
726   (vl_api_af_packet_create_reply_t * mp)
727 {
728   vat_main_t *vam = &vat_main;
729   vat_json_node_t node;
730
731   vat_json_init_object (&node);
732   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
733   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
734
735   vat_json_print (vam->ofp, &node);
736   vat_json_free (&node);
737
738   vam->retval = ntohl (mp->retval);
739   vam->result_ready = 1;
740 }
741
742 static void vl_api_create_vlan_subif_reply_t_handler
743   (vl_api_create_vlan_subif_reply_t * mp)
744 {
745   vat_main_t *vam = &vat_main;
746   i32 retval = ntohl (mp->retval);
747
748   vam->retval = retval;
749   vam->regenerate_interface_table = 1;
750   vam->sw_if_index = ntohl (mp->sw_if_index);
751   vam->result_ready = 1;
752 }
753
754 static void vl_api_create_vlan_subif_reply_t_handler_json
755   (vl_api_create_vlan_subif_reply_t * mp)
756 {
757   vat_main_t *vam = &vat_main;
758   vat_json_node_t node;
759
760   vat_json_init_object (&node);
761   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
762   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
763
764   vat_json_print (vam->ofp, &node);
765   vat_json_free (&node);
766
767   vam->retval = ntohl (mp->retval);
768   vam->result_ready = 1;
769 }
770
771 static void vl_api_create_subif_reply_t_handler
772   (vl_api_create_subif_reply_t * mp)
773 {
774   vat_main_t *vam = &vat_main;
775   i32 retval = ntohl (mp->retval);
776
777   vam->retval = retval;
778   vam->regenerate_interface_table = 1;
779   vam->sw_if_index = ntohl (mp->sw_if_index);
780   vam->result_ready = 1;
781 }
782
783 static void vl_api_create_subif_reply_t_handler_json
784   (vl_api_create_subif_reply_t * mp)
785 {
786   vat_main_t *vam = &vat_main;
787   vat_json_node_t node;
788
789   vat_json_init_object (&node);
790   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
791   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
792
793   vat_json_print (vam->ofp, &node);
794   vat_json_free (&node);
795
796   vam->retval = ntohl (mp->retval);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_interface_name_renumber_reply_t_handler
801   (vl_api_interface_name_renumber_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   i32 retval = ntohl (mp->retval);
805
806   vam->retval = retval;
807   vam->regenerate_interface_table = 1;
808   vam->result_ready = 1;
809 }
810
811 static void vl_api_interface_name_renumber_reply_t_handler_json
812   (vl_api_interface_name_renumber_reply_t * mp)
813 {
814   vat_main_t *vam = &vat_main;
815   vat_json_node_t node;
816
817   vat_json_init_object (&node);
818   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
819
820   vat_json_print (vam->ofp, &node);
821   vat_json_free (&node);
822
823   vam->retval = ntohl (mp->retval);
824   vam->result_ready = 1;
825 }
826
827 /*
828  * Special-case: build the interface table, maintain
829  * the next loopback sw_if_index vbl.
830  */
831 static void vl_api_sw_interface_details_t_handler
832   (vl_api_sw_interface_details_t * mp)
833 {
834   vat_main_t *vam = &vat_main;
835   u8 *s = format (0, "%s%c", mp->interface_name, 0);
836
837   hash_set_mem (vam->sw_if_index_by_interface_name, s,
838                 ntohl (mp->sw_if_index));
839
840   /* In sub interface case, fill the sub interface table entry */
841   if (mp->sw_if_index != mp->sup_sw_if_index)
842     {
843       sw_interface_subif_t *sub = NULL;
844
845       vec_add2 (vam->sw_if_subif_table, sub, 1);
846
847       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
848       strncpy ((char *) sub->interface_name, (char *) s,
849                vec_len (sub->interface_name));
850       sub->sw_if_index = ntohl (mp->sw_if_index);
851       sub->sub_id = ntohl (mp->sub_id);
852
853       sub->sub_dot1ad = mp->sub_dot1ad;
854       sub->sub_number_of_tags = mp->sub_number_of_tags;
855       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
856       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
857       sub->sub_exact_match = mp->sub_exact_match;
858       sub->sub_default = mp->sub_default;
859       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
860       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
861
862       /* vlan tag rewrite */
863       sub->vtr_op = ntohl (mp->vtr_op);
864       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
865       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
866       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
867     }
868 }
869
870 static void vl_api_sw_interface_details_t_handler_json
871   (vl_api_sw_interface_details_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t *node = NULL;
875
876   if (VAT_JSON_ARRAY != vam->json_tree.type)
877     {
878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
879       vat_json_init_array (&vam->json_tree);
880     }
881   node = vat_json_array_add (&vam->json_tree);
882
883   vat_json_init_object (node);
884   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
885   vat_json_object_add_uint (node, "sup_sw_if_index",
886                             ntohl (mp->sup_sw_if_index));
887   vat_json_object_add_uint (node, "l2_address_length",
888                             ntohl (mp->l2_address_length));
889   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
890                              sizeof (mp->l2_address));
891   vat_json_object_add_string_copy (node, "interface_name",
892                                    mp->interface_name);
893   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
894   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
895   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
896   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
897   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
898   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
899   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
900   vat_json_object_add_uint (node, "sub_number_of_tags",
901                             mp->sub_number_of_tags);
902   vat_json_object_add_uint (node, "sub_outer_vlan_id",
903                             ntohs (mp->sub_outer_vlan_id));
904   vat_json_object_add_uint (node, "sub_inner_vlan_id",
905                             ntohs (mp->sub_inner_vlan_id));
906   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
907   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
908   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
909                             mp->sub_outer_vlan_id_any);
910   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
911                             mp->sub_inner_vlan_id_any);
912   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
913   vat_json_object_add_uint (node, "vtr_push_dot1q",
914                             ntohl (mp->vtr_push_dot1q));
915   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
916   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
917   if (mp->sub_dot1ah)
918     {
919       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
920                                        format (0, "%U",
921                                                format_ethernet_address,
922                                                &mp->b_dmac));
923       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
924                                        format (0, "%U",
925                                                format_ethernet_address,
926                                                &mp->b_smac));
927       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
928       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
929     }
930 }
931
932 static void vl_api_sw_interface_set_flags_t_handler
933   (vl_api_sw_interface_set_flags_t * mp)
934 {
935   vat_main_t *vam = &vat_main;
936   if (vam->interface_event_display)
937     errmsg ("interface flags: sw_if_index %d %s %s",
938             ntohl (mp->sw_if_index),
939             mp->admin_up_down ? "admin-up" : "admin-down",
940             mp->link_up_down ? "link-up" : "link-down");
941 }
942
943 static void vl_api_sw_interface_set_flags_t_handler_json
944   (vl_api_sw_interface_set_flags_t * mp)
945 {
946   /* JSON output not supported */
947 }
948
949 static void
950 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
951 {
952   vat_main_t *vam = &vat_main;
953   i32 retval = ntohl (mp->retval);
954
955   vam->retval = retval;
956   vam->shmem_result = (u8 *) mp->reply_in_shmem;
957   vam->result_ready = 1;
958 }
959
960 static void
961 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
962 {
963   vat_main_t *vam = &vat_main;
964   vat_json_node_t node;
965   api_main_t *am = &api_main;
966   void *oldheap;
967   u8 *reply;
968
969   vat_json_init_object (&node);
970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
971   vat_json_object_add_uint (&node, "reply_in_shmem",
972                             ntohl (mp->reply_in_shmem));
973   /* Toss the shared-memory original... */
974   pthread_mutex_lock (&am->vlib_rp->mutex);
975   oldheap = svm_push_data_heap (am->vlib_rp);
976
977   reply = (u8 *) (mp->reply_in_shmem);
978   vec_free (reply);
979
980   svm_pop_heap (oldheap);
981   pthread_mutex_unlock (&am->vlib_rp->mutex);
982
983   vat_json_print (vam->ofp, &node);
984   vat_json_free (&node);
985
986   vam->retval = ntohl (mp->retval);
987   vam->result_ready = 1;
988 }
989
990 static void
991 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
992 {
993   vat_main_t *vam = &vat_main;
994   i32 retval = ntohl (mp->retval);
995
996   vam->retval = retval;
997   vam->cmd_reply = mp->reply;
998   vam->result_ready = 1;
999 }
1000
1001 static void
1002 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1003 {
1004   vat_main_t *vam = &vat_main;
1005   vat_json_node_t node;
1006
1007   vat_json_init_object (&node);
1008   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1009   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1010
1011   vat_json_print (vam->ofp, &node);
1012   vat_json_free (&node);
1013
1014   vam->retval = ntohl (mp->retval);
1015   vam->result_ready = 1;
1016 }
1017
1018 static void vl_api_classify_add_del_table_reply_t_handler
1019   (vl_api_classify_add_del_table_reply_t * mp)
1020 {
1021   vat_main_t *vam = &vat_main;
1022   i32 retval = ntohl (mp->retval);
1023   if (vam->async_mode)
1024     {
1025       vam->async_errors += (retval < 0);
1026     }
1027   else
1028     {
1029       vam->retval = retval;
1030       if (retval == 0 &&
1031           ((mp->new_table_index != 0xFFFFFFFF) ||
1032            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1033            (mp->match_n_vectors != 0xFFFFFFFF)))
1034         /*
1035          * Note: this is just barely thread-safe, depends on
1036          * the main thread spinning waiting for an answer...
1037          */
1038         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1039                 ntohl (mp->new_table_index),
1040                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1041       vam->result_ready = 1;
1042     }
1043 }
1044
1045 static void vl_api_classify_add_del_table_reply_t_handler_json
1046   (vl_api_classify_add_del_table_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_uint (&node, "new_table_index",
1054                             ntohl (mp->new_table_index));
1055   vat_json_object_add_uint (&node, "skip_n_vectors",
1056                             ntohl (mp->skip_n_vectors));
1057   vat_json_object_add_uint (&node, "match_n_vectors",
1058                             ntohl (mp->match_n_vectors));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_get_node_index_reply_t_handler
1068   (vl_api_get_node_index_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072   if (vam->async_mode)
1073     {
1074       vam->async_errors += (retval < 0);
1075     }
1076   else
1077     {
1078       vam->retval = retval;
1079       if (retval == 0)
1080         errmsg ("node index %d", ntohl (mp->node_index));
1081       vam->result_ready = 1;
1082     }
1083 }
1084
1085 static void vl_api_get_node_index_reply_t_handler_json
1086   (vl_api_get_node_index_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vat_json_init_object (&node);
1092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1093   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1094
1095   vat_json_print (vam->ofp, &node);
1096   vat_json_free (&node);
1097
1098   vam->retval = ntohl (mp->retval);
1099   vam->result_ready = 1;
1100 }
1101
1102 static void vl_api_get_next_index_reply_t_handler
1103   (vl_api_get_next_index_reply_t * mp)
1104 {
1105   vat_main_t *vam = &vat_main;
1106   i32 retval = ntohl (mp->retval);
1107   if (vam->async_mode)
1108     {
1109       vam->async_errors += (retval < 0);
1110     }
1111   else
1112     {
1113       vam->retval = retval;
1114       if (retval == 0)
1115         errmsg ("next node index %d", ntohl (mp->next_index));
1116       vam->result_ready = 1;
1117     }
1118 }
1119
1120 static void vl_api_get_next_index_reply_t_handler_json
1121   (vl_api_get_next_index_reply_t * mp)
1122 {
1123   vat_main_t *vam = &vat_main;
1124   vat_json_node_t node;
1125
1126   vat_json_init_object (&node);
1127   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1128   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1129
1130   vat_json_print (vam->ofp, &node);
1131   vat_json_free (&node);
1132
1133   vam->retval = ntohl (mp->retval);
1134   vam->result_ready = 1;
1135 }
1136
1137 static void vl_api_add_node_next_reply_t_handler
1138   (vl_api_add_node_next_reply_t * mp)
1139 {
1140   vat_main_t *vam = &vat_main;
1141   i32 retval = ntohl (mp->retval);
1142   if (vam->async_mode)
1143     {
1144       vam->async_errors += (retval < 0);
1145     }
1146   else
1147     {
1148       vam->retval = retval;
1149       if (retval == 0)
1150         errmsg ("next index %d", ntohl (mp->next_index));
1151       vam->result_ready = 1;
1152     }
1153 }
1154
1155 static void vl_api_add_node_next_reply_t_handler_json
1156   (vl_api_add_node_next_reply_t * mp)
1157 {
1158   vat_main_t *vam = &vat_main;
1159   vat_json_node_t node;
1160
1161   vat_json_init_object (&node);
1162   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1163   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1164
1165   vat_json_print (vam->ofp, &node);
1166   vat_json_free (&node);
1167
1168   vam->retval = ntohl (mp->retval);
1169   vam->result_ready = 1;
1170 }
1171
1172 static void vl_api_show_version_reply_t_handler
1173   (vl_api_show_version_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   i32 retval = ntohl (mp->retval);
1177
1178   if (retval >= 0)
1179     {
1180       errmsg ("        program: %s", mp->program);
1181       errmsg ("        version: %s", mp->version);
1182       errmsg ("     build date: %s", mp->build_date);
1183       errmsg ("build directory: %s", mp->build_directory);
1184     }
1185   vam->retval = retval;
1186   vam->result_ready = 1;
1187 }
1188
1189 static void vl_api_show_version_reply_t_handler_json
1190   (vl_api_show_version_reply_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   vat_json_node_t node;
1194
1195   vat_json_init_object (&node);
1196   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1197   vat_json_object_add_string_copy (&node, "program", mp->program);
1198   vat_json_object_add_string_copy (&node, "version", mp->version);
1199   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1200   vat_json_object_add_string_copy (&node, "build_directory",
1201                                    mp->build_directory);
1202
1203   vat_json_print (vam->ofp, &node);
1204   vat_json_free (&node);
1205
1206   vam->retval = ntohl (mp->retval);
1207   vam->result_ready = 1;
1208 }
1209
1210 static void
1211 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1212 {
1213   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1214           mp->mac_ip ? "mac/ip binding" : "address resolution",
1215           format_ip4_address, &mp->address,
1216           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1217 }
1218
1219 static void
1220 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1221 {
1222   /* JSON output not supported */
1223 }
1224
1225 static void
1226 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1227 {
1228   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1229           mp->mac_ip ? "mac/ip binding" : "address resolution",
1230           format_ip6_address, mp->address,
1231           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1232 }
1233
1234 static void
1235 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1236 {
1237   /* JSON output not supported */
1238 }
1239
1240 /*
1241  * Special-case: build the bridge domain table, maintain
1242  * the next bd id vbl.
1243  */
1244 static void vl_api_bridge_domain_details_t_handler
1245   (vl_api_bridge_domain_details_t * mp)
1246 {
1247   vat_main_t *vam = &vat_main;
1248   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1249
1250   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1251          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1252
1253   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1254          ntohl (mp->bd_id), mp->learn, mp->forward,
1255          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1256
1257   if (n_sw_ifs)
1258     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1259 }
1260
1261 static void vl_api_bridge_domain_details_t_handler_json
1262   (vl_api_bridge_domain_details_t * mp)
1263 {
1264   vat_main_t *vam = &vat_main;
1265   vat_json_node_t *node, *array = NULL;
1266
1267   if (VAT_JSON_ARRAY != vam->json_tree.type)
1268     {
1269       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1270       vat_json_init_array (&vam->json_tree);
1271     }
1272   node = vat_json_array_add (&vam->json_tree);
1273
1274   vat_json_init_object (node);
1275   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1276   vat_json_object_add_uint (node, "flood", mp->flood);
1277   vat_json_object_add_uint (node, "forward", mp->forward);
1278   vat_json_object_add_uint (node, "learn", mp->learn);
1279   vat_json_object_add_uint (node, "bvi_sw_if_index",
1280                             ntohl (mp->bvi_sw_if_index));
1281   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1282   array = vat_json_object_add (node, "sw_if");
1283   vat_json_init_array (array);
1284 }
1285
1286 /*
1287  * Special-case: build the bridge domain sw if table.
1288  */
1289 static void vl_api_bridge_domain_sw_if_details_t_handler
1290   (vl_api_bridge_domain_sw_if_details_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   hash_pair_t *p;
1294   u8 *sw_if_name = 0;
1295   u32 sw_if_index;
1296
1297   sw_if_index = ntohl (mp->sw_if_index);
1298   /* *INDENT-OFF* */
1299   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1300   ({
1301     if ((u32) p->value[0] == sw_if_index)
1302       {
1303         sw_if_name = (u8 *)(p->key);
1304         break;
1305       }
1306   }));
1307   /* *INDENT-ON* */
1308
1309   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1310          mp->shg, sw_if_name ? (char *) sw_if_name :
1311          "sw_if_index not found!");
1312 }
1313
1314 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1315   (vl_api_bridge_domain_sw_if_details_t * mp)
1316 {
1317   vat_main_t *vam = &vat_main;
1318   vat_json_node_t *node = NULL;
1319   uword last_index = 0;
1320
1321   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1322   ASSERT (vec_len (vam->json_tree.array) >= 1);
1323   last_index = vec_len (vam->json_tree.array) - 1;
1324   node = &vam->json_tree.array[last_index];
1325   node = vat_json_object_get_element (node, "sw_if");
1326   ASSERT (NULL != node);
1327   node = vat_json_array_add (node);
1328
1329   vat_json_init_object (node);
1330   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1331   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1332   vat_json_object_add_uint (node, "shg", mp->shg);
1333 }
1334
1335 static void vl_api_control_ping_reply_t_handler
1336   (vl_api_control_ping_reply_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   i32 retval = ntohl (mp->retval);
1340   if (vam->async_mode)
1341     {
1342       vam->async_errors += (retval < 0);
1343     }
1344   else
1345     {
1346       vam->retval = retval;
1347       vam->result_ready = 1;
1348     }
1349 }
1350
1351 static void vl_api_control_ping_reply_t_handler_json
1352   (vl_api_control_ping_reply_t * mp)
1353 {
1354   vat_main_t *vam = &vat_main;
1355   i32 retval = ntohl (mp->retval);
1356
1357   if (VAT_JSON_NONE != vam->json_tree.type)
1358     {
1359       vat_json_print (vam->ofp, &vam->json_tree);
1360       vat_json_free (&vam->json_tree);
1361       vam->json_tree.type = VAT_JSON_NONE;
1362     }
1363   else
1364     {
1365       /* just print [] */
1366       vat_json_init_array (&vam->json_tree);
1367       vat_json_print (vam->ofp, &vam->json_tree);
1368       vam->json_tree.type = VAT_JSON_NONE;
1369     }
1370
1371   vam->retval = retval;
1372   vam->result_ready = 1;
1373 }
1374
1375 static void
1376 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1377 {
1378   vat_main_t *vam = &vat_main;
1379   i32 retval = ntohl (mp->retval);
1380   if (vam->async_mode)
1381     {
1382       vam->async_errors += (retval < 0);
1383     }
1384   else
1385     {
1386       vam->retval = retval;
1387       vam->result_ready = 1;
1388     }
1389 }
1390
1391 static void vl_api_l2_flags_reply_t_handler_json
1392   (vl_api_l2_flags_reply_t * mp)
1393 {
1394   vat_main_t *vam = &vat_main;
1395   vat_json_node_t node;
1396
1397   vat_json_init_object (&node);
1398   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1399   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1400                             ntohl (mp->resulting_feature_bitmap));
1401
1402   vat_json_print (vam->ofp, &node);
1403   vat_json_free (&node);
1404
1405   vam->retval = ntohl (mp->retval);
1406   vam->result_ready = 1;
1407 }
1408
1409 static void vl_api_bridge_flags_reply_t_handler
1410   (vl_api_bridge_flags_reply_t * mp)
1411 {
1412   vat_main_t *vam = &vat_main;
1413   i32 retval = ntohl (mp->retval);
1414   if (vam->async_mode)
1415     {
1416       vam->async_errors += (retval < 0);
1417     }
1418   else
1419     {
1420       vam->retval = retval;
1421       vam->result_ready = 1;
1422     }
1423 }
1424
1425 static void vl_api_bridge_flags_reply_t_handler_json
1426   (vl_api_bridge_flags_reply_t * mp)
1427 {
1428   vat_main_t *vam = &vat_main;
1429   vat_json_node_t node;
1430
1431   vat_json_init_object (&node);
1432   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1433   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1434                             ntohl (mp->resulting_feature_bitmap));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_tap_connect_reply_t_handler
1444   (vl_api_tap_connect_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->sw_if_index = ntohl (mp->sw_if_index);
1456       vam->result_ready = 1;
1457     }
1458
1459 }
1460
1461 static void vl_api_tap_connect_reply_t_handler_json
1462   (vl_api_tap_connect_reply_t * mp)
1463 {
1464   vat_main_t *vam = &vat_main;
1465   vat_json_node_t node;
1466
1467   vat_json_init_object (&node);
1468   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1469   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1470
1471   vat_json_print (vam->ofp, &node);
1472   vat_json_free (&node);
1473
1474   vam->retval = ntohl (mp->retval);
1475   vam->result_ready = 1;
1476
1477 }
1478
1479 static void
1480 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1481 {
1482   vat_main_t *vam = &vat_main;
1483   i32 retval = ntohl (mp->retval);
1484   if (vam->async_mode)
1485     {
1486       vam->async_errors += (retval < 0);
1487     }
1488   else
1489     {
1490       vam->retval = retval;
1491       vam->sw_if_index = ntohl (mp->sw_if_index);
1492       vam->result_ready = 1;
1493     }
1494 }
1495
1496 static void vl_api_tap_modify_reply_t_handler_json
1497   (vl_api_tap_modify_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   vat_json_node_t node;
1501
1502   vat_json_init_object (&node);
1503   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1504   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1505
1506   vat_json_print (vam->ofp, &node);
1507   vat_json_free (&node);
1508
1509   vam->retval = ntohl (mp->retval);
1510   vam->result_ready = 1;
1511 }
1512
1513 static void
1514 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1515 {
1516   vat_main_t *vam = &vat_main;
1517   i32 retval = ntohl (mp->retval);
1518   if (vam->async_mode)
1519     {
1520       vam->async_errors += (retval < 0);
1521     }
1522   else
1523     {
1524       vam->retval = retval;
1525       vam->result_ready = 1;
1526     }
1527 }
1528
1529 static void vl_api_tap_delete_reply_t_handler_json
1530   (vl_api_tap_delete_reply_t * mp)
1531 {
1532   vat_main_t *vam = &vat_main;
1533   vat_json_node_t node;
1534
1535   vat_json_init_object (&node);
1536   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1546   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->result_ready = 1;
1558     }
1559 }
1560
1561 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1562   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1563 {
1564   vat_main_t *vam = &vat_main;
1565   vat_json_node_t node;
1566
1567   vat_json_init_object (&node);
1568   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1569   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1570                             ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1580   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1597   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613
1614 static void vl_api_one_add_del_locator_set_reply_t_handler
1615   (vl_api_one_add_del_locator_set_reply_t * mp)
1616 {
1617   vat_main_t *vam = &vat_main;
1618   i32 retval = ntohl (mp->retval);
1619   if (vam->async_mode)
1620     {
1621       vam->async_errors += (retval < 0);
1622     }
1623   else
1624     {
1625       vam->retval = retval;
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1631   (vl_api_one_add_del_locator_set_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1648   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   i32 retval = ntohl (mp->retval);
1652   if (vam->async_mode)
1653     {
1654       vam->async_errors += (retval < 0);
1655     }
1656   else
1657     {
1658       vam->retval = retval;
1659       vam->sw_if_index = ntohl (mp->sw_if_index);
1660       vam->result_ready = 1;
1661     }
1662 }
1663
1664 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1665   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   vat_json_node_t node;
1669
1670   vat_json_init_object (&node);
1671   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1672   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1673
1674   vat_json_print (vam->ofp, &node);
1675   vat_json_free (&node);
1676
1677   vam->retval = ntohl (mp->retval);
1678   vam->result_ready = 1;
1679 }
1680
1681 static void vl_api_gre_add_del_tunnel_reply_t_handler
1682   (vl_api_gre_add_del_tunnel_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   i32 retval = ntohl (mp->retval);
1686   if (vam->async_mode)
1687     {
1688       vam->async_errors += (retval < 0);
1689     }
1690   else
1691     {
1692       vam->retval = retval;
1693       vam->sw_if_index = ntohl (mp->sw_if_index);
1694       vam->result_ready = 1;
1695     }
1696 }
1697
1698 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1699   (vl_api_gre_add_del_tunnel_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   vat_json_node_t node;
1703
1704   vat_json_init_object (&node);
1705   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1706   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1707
1708   vat_json_print (vam->ofp, &node);
1709   vat_json_free (&node);
1710
1711   vam->retval = ntohl (mp->retval);
1712   vam->result_ready = 1;
1713 }
1714
1715 static void vl_api_create_vhost_user_if_reply_t_handler
1716   (vl_api_create_vhost_user_if_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   i32 retval = ntohl (mp->retval);
1720   if (vam->async_mode)
1721     {
1722       vam->async_errors += (retval < 0);
1723     }
1724   else
1725     {
1726       vam->retval = retval;
1727       vam->sw_if_index = ntohl (mp->sw_if_index);
1728       vam->result_ready = 1;
1729     }
1730 }
1731
1732 static void vl_api_create_vhost_user_if_reply_t_handler_json
1733   (vl_api_create_vhost_user_if_reply_t * mp)
1734 {
1735   vat_main_t *vam = &vat_main;
1736   vat_json_node_t node;
1737
1738   vat_json_init_object (&node);
1739   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1740   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1741
1742   vat_json_print (vam->ofp, &node);
1743   vat_json_free (&node);
1744
1745   vam->retval = ntohl (mp->retval);
1746   vam->result_ready = 1;
1747 }
1748
1749 static void vl_api_ip_address_details_t_handler
1750   (vl_api_ip_address_details_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   static ip_address_details_t empty_ip_address_details = { {0} };
1754   ip_address_details_t *address = NULL;
1755   ip_details_t *current_ip_details = NULL;
1756   ip_details_t *details = NULL;
1757
1758   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1759
1760   if (!details || vam->current_sw_if_index >= vec_len (details)
1761       || !details[vam->current_sw_if_index].present)
1762     {
1763       errmsg ("ip address details arrived but not stored");
1764       errmsg ("ip_dump should be called first");
1765       return;
1766     }
1767
1768   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1769
1770 #define addresses (current_ip_details->addr)
1771
1772   vec_validate_init_empty (addresses, vec_len (addresses),
1773                            empty_ip_address_details);
1774
1775   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1776
1777   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1778   address->prefix_length = mp->prefix_length;
1779 #undef addresses
1780 }
1781
1782 static void vl_api_ip_address_details_t_handler_json
1783   (vl_api_ip_address_details_t * mp)
1784 {
1785   vat_main_t *vam = &vat_main;
1786   vat_json_node_t *node = NULL;
1787   struct in6_addr ip6;
1788   struct in_addr ip4;
1789
1790   if (VAT_JSON_ARRAY != vam->json_tree.type)
1791     {
1792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1793       vat_json_init_array (&vam->json_tree);
1794     }
1795   node = vat_json_array_add (&vam->json_tree);
1796
1797   vat_json_init_object (node);
1798   if (vam->is_ipv6)
1799     {
1800       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1801       vat_json_object_add_ip6 (node, "ip", ip6);
1802     }
1803   else
1804     {
1805       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1806       vat_json_object_add_ip4 (node, "ip", ip4);
1807     }
1808   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1809 }
1810
1811 static void
1812 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1813 {
1814   vat_main_t *vam = &vat_main;
1815   static ip_details_t empty_ip_details = { 0 };
1816   ip_details_t *ip = NULL;
1817   u32 sw_if_index = ~0;
1818
1819   sw_if_index = ntohl (mp->sw_if_index);
1820
1821   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1822                            sw_if_index, empty_ip_details);
1823
1824   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1825                          sw_if_index);
1826
1827   ip->present = 1;
1828 }
1829
1830 static void
1831 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1832 {
1833   vat_main_t *vam = &vat_main;
1834
1835   if (VAT_JSON_ARRAY != vam->json_tree.type)
1836     {
1837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1838       vat_json_init_array (&vam->json_tree);
1839     }
1840   vat_json_array_add_uint (&vam->json_tree,
1841                            clib_net_to_host_u32 (mp->sw_if_index));
1842 }
1843
1844 static void vl_api_map_domain_details_t_handler_json
1845   (vl_api_map_domain_details_t * mp)
1846 {
1847   vat_json_node_t *node = NULL;
1848   vat_main_t *vam = &vat_main;
1849   struct in6_addr ip6;
1850   struct in_addr ip4;
1851
1852   if (VAT_JSON_ARRAY != vam->json_tree.type)
1853     {
1854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1855       vat_json_init_array (&vam->json_tree);
1856     }
1857
1858   node = vat_json_array_add (&vam->json_tree);
1859   vat_json_init_object (node);
1860
1861   vat_json_object_add_uint (node, "domain_index",
1862                             clib_net_to_host_u32 (mp->domain_index));
1863   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1864   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1865   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1866   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1867   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1868   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1869   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1870   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1871   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1872   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1873   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1874   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1875   vat_json_object_add_uint (node, "flags", mp->flags);
1876   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1877   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1878 }
1879
1880 static void vl_api_map_domain_details_t_handler
1881   (vl_api_map_domain_details_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884
1885   if (mp->is_translation)
1886     {
1887       print (vam->ofp,
1888              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1889              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1890              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1891              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1892              clib_net_to_host_u32 (mp->domain_index));
1893     }
1894   else
1895     {
1896       print (vam->ofp,
1897              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1898              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1899              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1900              format_ip6_address, mp->ip6_src,
1901              clib_net_to_host_u32 (mp->domain_index));
1902     }
1903   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1904          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1905          mp->is_translation ? "map-t" : "");
1906 }
1907
1908 static void vl_api_map_rule_details_t_handler_json
1909   (vl_api_map_rule_details_t * mp)
1910 {
1911   struct in6_addr ip6;
1912   vat_json_node_t *node = NULL;
1913   vat_main_t *vam = &vat_main;
1914
1915   if (VAT_JSON_ARRAY != vam->json_tree.type)
1916     {
1917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1918       vat_json_init_array (&vam->json_tree);
1919     }
1920
1921   node = vat_json_array_add (&vam->json_tree);
1922   vat_json_init_object (node);
1923
1924   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1925   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1926   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1927 }
1928
1929 static void
1930 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1934          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1935 }
1936
1937 static void
1938 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1939 {
1940   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1941           "router_addr %U host_mac %U",
1942           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1943           format_ip4_address, &mp->host_address,
1944           format_ip4_address, &mp->router_address,
1945           format_ethernet_address, mp->host_mac);
1946 }
1947
1948 static void vl_api_dhcp_compl_event_t_handler_json
1949   (vl_api_dhcp_compl_event_t * mp)
1950 {
1951   /* JSON output not supported */
1952 }
1953
1954 static void
1955 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1956                               u32 counter)
1957 {
1958   vat_main_t *vam = &vat_main;
1959   static u64 default_counter = 0;
1960
1961   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1962                            NULL);
1963   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1964                            sw_if_index, default_counter);
1965   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1966 }
1967
1968 static void
1969 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1970                                 interface_counter_t counter)
1971 {
1972   vat_main_t *vam = &vat_main;
1973   static interface_counter_t default_counter = { 0, };
1974
1975   vec_validate_init_empty (vam->combined_interface_counters,
1976                            vnet_counter_type, NULL);
1977   vec_validate_init_empty (vam->combined_interface_counters
1978                            [vnet_counter_type], sw_if_index, default_counter);
1979   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1980 }
1981
1982 static void vl_api_vnet_interface_counters_t_handler
1983   (vl_api_vnet_interface_counters_t * mp)
1984 {
1985   /* not supported */
1986 }
1987
1988 static void vl_api_vnet_interface_counters_t_handler_json
1989   (vl_api_vnet_interface_counters_t * mp)
1990 {
1991   interface_counter_t counter;
1992   vlib_counter_t *v;
1993   u64 *v_packets;
1994   u64 packets;
1995   u32 count;
1996   u32 first_sw_if_index;
1997   int i;
1998
1999   count = ntohl (mp->count);
2000   first_sw_if_index = ntohl (mp->first_sw_if_index);
2001
2002   if (!mp->is_combined)
2003     {
2004       v_packets = (u64 *) & mp->data;
2005       for (i = 0; i < count; i++)
2006         {
2007           packets =
2008             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2009           set_simple_interface_counter (mp->vnet_counter_type,
2010                                         first_sw_if_index + i, packets);
2011           v_packets++;
2012         }
2013     }
2014   else
2015     {
2016       v = (vlib_counter_t *) & mp->data;
2017       for (i = 0; i < count; i++)
2018         {
2019           counter.packets =
2020             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2021           counter.bytes =
2022             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2023           set_combined_interface_counter (mp->vnet_counter_type,
2024                                           first_sw_if_index + i, counter);
2025           v++;
2026         }
2027     }
2028 }
2029
2030 static u32
2031 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2032 {
2033   vat_main_t *vam = &vat_main;
2034   u32 i;
2035
2036   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2037     {
2038       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2039         {
2040           return i;
2041         }
2042     }
2043   return ~0;
2044 }
2045
2046 static u32
2047 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2048 {
2049   vat_main_t *vam = &vat_main;
2050   u32 i;
2051
2052   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2053     {
2054       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2055         {
2056           return i;
2057         }
2058     }
2059   return ~0;
2060 }
2061
2062 static void vl_api_vnet_ip4_fib_counters_t_handler
2063   (vl_api_vnet_ip4_fib_counters_t * mp)
2064 {
2065   /* not supported */
2066 }
2067
2068 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2069   (vl_api_vnet_ip4_fib_counters_t * mp)
2070 {
2071   vat_main_t *vam = &vat_main;
2072   vl_api_ip4_fib_counter_t *v;
2073   ip4_fib_counter_t *counter;
2074   struct in_addr ip4;
2075   u32 vrf_id;
2076   u32 vrf_index;
2077   u32 count;
2078   int i;
2079
2080   vrf_id = ntohl (mp->vrf_id);
2081   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2082   if (~0 == vrf_index)
2083     {
2084       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2085       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2086       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2087       vec_validate (vam->ip4_fib_counters, vrf_index);
2088       vam->ip4_fib_counters[vrf_index] = NULL;
2089     }
2090
2091   vec_free (vam->ip4_fib_counters[vrf_index]);
2092   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2093   count = ntohl (mp->count);
2094   for (i = 0; i < count; i++)
2095     {
2096       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2097       counter = &vam->ip4_fib_counters[vrf_index][i];
2098       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2099       counter->address = ip4;
2100       counter->address_length = v->address_length;
2101       counter->packets = clib_net_to_host_u64 (v->packets);
2102       counter->bytes = clib_net_to_host_u64 (v->bytes);
2103       v++;
2104     }
2105 }
2106
2107 static void vl_api_vnet_ip4_nbr_counters_t_handler
2108   (vl_api_vnet_ip4_nbr_counters_t * mp)
2109 {
2110   /* not supported */
2111 }
2112
2113 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2114   (vl_api_vnet_ip4_nbr_counters_t * mp)
2115 {
2116   vat_main_t *vam = &vat_main;
2117   vl_api_ip4_nbr_counter_t *v;
2118   ip4_nbr_counter_t *counter;
2119   u32 sw_if_index;
2120   u32 count;
2121   int i;
2122
2123   sw_if_index = ntohl (mp->sw_if_index);
2124   count = ntohl (mp->count);
2125   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2126
2127   if (mp->begin)
2128     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2129
2130   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2131   for (i = 0; i < count; i++)
2132     {
2133       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2134       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2135       counter->address.s_addr = v->address;
2136       counter->packets = clib_net_to_host_u64 (v->packets);
2137       counter->bytes = clib_net_to_host_u64 (v->bytes);
2138       counter->linkt = v->link_type;
2139       v++;
2140     }
2141 }
2142
2143 static void vl_api_vnet_ip6_fib_counters_t_handler
2144   (vl_api_vnet_ip6_fib_counters_t * mp)
2145 {
2146   /* not supported */
2147 }
2148
2149 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2150   (vl_api_vnet_ip6_fib_counters_t * mp)
2151 {
2152   vat_main_t *vam = &vat_main;
2153   vl_api_ip6_fib_counter_t *v;
2154   ip6_fib_counter_t *counter;
2155   struct in6_addr ip6;
2156   u32 vrf_id;
2157   u32 vrf_index;
2158   u32 count;
2159   int i;
2160
2161   vrf_id = ntohl (mp->vrf_id);
2162   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2163   if (~0 == vrf_index)
2164     {
2165       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2166       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2167       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2168       vec_validate (vam->ip6_fib_counters, vrf_index);
2169       vam->ip6_fib_counters[vrf_index] = NULL;
2170     }
2171
2172   vec_free (vam->ip6_fib_counters[vrf_index]);
2173   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2174   count = ntohl (mp->count);
2175   for (i = 0; i < count; i++)
2176     {
2177       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2178       counter = &vam->ip6_fib_counters[vrf_index][i];
2179       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2180       counter->address = ip6;
2181       counter->address_length = v->address_length;
2182       counter->packets = clib_net_to_host_u64 (v->packets);
2183       counter->bytes = clib_net_to_host_u64 (v->bytes);
2184       v++;
2185     }
2186 }
2187
2188 static void vl_api_vnet_ip6_nbr_counters_t_handler
2189   (vl_api_vnet_ip6_nbr_counters_t * mp)
2190 {
2191   /* not supported */
2192 }
2193
2194 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2195   (vl_api_vnet_ip6_nbr_counters_t * mp)
2196 {
2197   vat_main_t *vam = &vat_main;
2198   vl_api_ip6_nbr_counter_t *v;
2199   ip6_nbr_counter_t *counter;
2200   struct in6_addr ip6;
2201   u32 sw_if_index;
2202   u32 count;
2203   int i;
2204
2205   sw_if_index = ntohl (mp->sw_if_index);
2206   count = ntohl (mp->count);
2207   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2208
2209   if (mp->begin)
2210     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2211
2212   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2213   for (i = 0; i < count; i++)
2214     {
2215       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2216       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2217       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2218       counter->address = ip6;
2219       counter->packets = clib_net_to_host_u64 (v->packets);
2220       counter->bytes = clib_net_to_host_u64 (v->bytes);
2221       v++;
2222     }
2223 }
2224
2225 static void vl_api_get_first_msg_id_reply_t_handler
2226   (vl_api_get_first_msg_id_reply_t * mp)
2227 {
2228   vat_main_t *vam = &vat_main;
2229   i32 retval = ntohl (mp->retval);
2230
2231   if (vam->async_mode)
2232     {
2233       vam->async_errors += (retval < 0);
2234     }
2235   else
2236     {
2237       vam->retval = retval;
2238       vam->result_ready = 1;
2239     }
2240   if (retval >= 0)
2241     {
2242       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2243     }
2244 }
2245
2246 static void vl_api_get_first_msg_id_reply_t_handler_json
2247   (vl_api_get_first_msg_id_reply_t * mp)
2248 {
2249   vat_main_t *vam = &vat_main;
2250   vat_json_node_t node;
2251
2252   vat_json_init_object (&node);
2253   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2254   vat_json_object_add_uint (&node, "first_msg_id",
2255                             (uint) ntohs (mp->first_msg_id));
2256
2257   vat_json_print (vam->ofp, &node);
2258   vat_json_free (&node);
2259
2260   vam->retval = ntohl (mp->retval);
2261   vam->result_ready = 1;
2262 }
2263
2264 static void vl_api_get_node_graph_reply_t_handler
2265   (vl_api_get_node_graph_reply_t * mp)
2266 {
2267   vat_main_t *vam = &vat_main;
2268   api_main_t *am = &api_main;
2269   i32 retval = ntohl (mp->retval);
2270   u8 *pvt_copy, *reply;
2271   void *oldheap;
2272   vlib_node_t *node;
2273   int i;
2274
2275   if (vam->async_mode)
2276     {
2277       vam->async_errors += (retval < 0);
2278     }
2279   else
2280     {
2281       vam->retval = retval;
2282       vam->result_ready = 1;
2283     }
2284
2285   /* "Should never happen..." */
2286   if (retval != 0)
2287     return;
2288
2289   reply = (u8 *) (mp->reply_in_shmem);
2290   pvt_copy = vec_dup (reply);
2291
2292   /* Toss the shared-memory original... */
2293   pthread_mutex_lock (&am->vlib_rp->mutex);
2294   oldheap = svm_push_data_heap (am->vlib_rp);
2295
2296   vec_free (reply);
2297
2298   svm_pop_heap (oldheap);
2299   pthread_mutex_unlock (&am->vlib_rp->mutex);
2300
2301   if (vam->graph_nodes)
2302     {
2303       hash_free (vam->graph_node_index_by_name);
2304
2305       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2306         {
2307           node = vam->graph_nodes[i];
2308           vec_free (node->name);
2309           vec_free (node->next_nodes);
2310           vec_free (node);
2311         }
2312       vec_free (vam->graph_nodes);
2313     }
2314
2315   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2316   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2317   vec_free (pvt_copy);
2318
2319   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2320     {
2321       node = vam->graph_nodes[i];
2322       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2323     }
2324 }
2325
2326 static void vl_api_get_node_graph_reply_t_handler_json
2327   (vl_api_get_node_graph_reply_t * mp)
2328 {
2329   vat_main_t *vam = &vat_main;
2330   api_main_t *am = &api_main;
2331   void *oldheap;
2332   vat_json_node_t node;
2333   u8 *reply;
2334
2335   /* $$$$ make this real? */
2336   vat_json_init_object (&node);
2337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2338   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2339
2340   reply = (u8 *) (mp->reply_in_shmem);
2341
2342   /* Toss the shared-memory original... */
2343   pthread_mutex_lock (&am->vlib_rp->mutex);
2344   oldheap = svm_push_data_heap (am->vlib_rp);
2345
2346   vec_free (reply);
2347
2348   svm_pop_heap (oldheap);
2349   pthread_mutex_unlock (&am->vlib_rp->mutex);
2350
2351   vat_json_print (vam->ofp, &node);
2352   vat_json_free (&node);
2353
2354   vam->retval = ntohl (mp->retval);
2355   vam->result_ready = 1;
2356 }
2357
2358 static void
2359 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2360 {
2361   vat_main_t *vam = &vat_main;
2362   u8 *s = 0;
2363
2364   if (mp->local)
2365     {
2366       s = format (s, "%=16d%=16d%=16d",
2367                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2368     }
2369   else
2370     {
2371       s = format (s, "%=16U%=16d%=16d",
2372                   mp->is_ipv6 ? format_ip6_address :
2373                   format_ip4_address,
2374                   mp->ip_address, mp->priority, mp->weight);
2375     }
2376
2377   print (vam->ofp, "%v", s);
2378   vec_free (s);
2379 }
2380
2381 static void
2382 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2383 {
2384   vat_main_t *vam = &vat_main;
2385   vat_json_node_t *node = NULL;
2386   struct in6_addr ip6;
2387   struct in_addr ip4;
2388
2389   if (VAT_JSON_ARRAY != vam->json_tree.type)
2390     {
2391       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2392       vat_json_init_array (&vam->json_tree);
2393     }
2394   node = vat_json_array_add (&vam->json_tree);
2395   vat_json_init_object (node);
2396
2397   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2398   vat_json_object_add_uint (node, "priority", mp->priority);
2399   vat_json_object_add_uint (node, "weight", mp->weight);
2400
2401   if (mp->local)
2402     vat_json_object_add_uint (node, "sw_if_index",
2403                               clib_net_to_host_u32 (mp->sw_if_index));
2404   else
2405     {
2406       if (mp->is_ipv6)
2407         {
2408           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2409           vat_json_object_add_ip6 (node, "address", ip6);
2410         }
2411       else
2412         {
2413           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2414           vat_json_object_add_ip4 (node, "address", ip4);
2415         }
2416     }
2417 }
2418
2419 static void
2420 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2421                                           mp)
2422 {
2423   vat_main_t *vam = &vat_main;
2424   u8 *ls_name = 0;
2425
2426   ls_name = format (0, "%s", mp->ls_name);
2427
2428   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2429          ls_name);
2430   vec_free (ls_name);
2431 }
2432
2433 static void
2434   vl_api_one_locator_set_details_t_handler_json
2435   (vl_api_one_locator_set_details_t * mp)
2436 {
2437   vat_main_t *vam = &vat_main;
2438   vat_json_node_t *node = 0;
2439   u8 *ls_name = 0;
2440
2441   ls_name = format (0, "%s", mp->ls_name);
2442   vec_add1 (ls_name, 0);
2443
2444   if (VAT_JSON_ARRAY != vam->json_tree.type)
2445     {
2446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2447       vat_json_init_array (&vam->json_tree);
2448     }
2449   node = vat_json_array_add (&vam->json_tree);
2450
2451   vat_json_init_object (node);
2452   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2453   vat_json_object_add_uint (node, "ls_index",
2454                             clib_net_to_host_u32 (mp->ls_index));
2455   vec_free (ls_name);
2456 }
2457
2458 static u8 *
2459 format_lisp_flat_eid (u8 * s, va_list * args)
2460 {
2461   u32 type = va_arg (*args, u32);
2462   u8 *eid = va_arg (*args, u8 *);
2463   u32 eid_len = va_arg (*args, u32);
2464
2465   switch (type)
2466     {
2467     case 0:
2468       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2469     case 1:
2470       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2471     case 2:
2472       return format (s, "%U", format_ethernet_address, eid);
2473     }
2474   return 0;
2475 }
2476
2477 static u8 *
2478 format_lisp_eid_vat (u8 * s, va_list * args)
2479 {
2480   u32 type = va_arg (*args, u32);
2481   u8 *eid = va_arg (*args, u8 *);
2482   u32 eid_len = va_arg (*args, u32);
2483   u8 *seid = va_arg (*args, u8 *);
2484   u32 seid_len = va_arg (*args, u32);
2485   u32 is_src_dst = va_arg (*args, u32);
2486
2487   if (is_src_dst)
2488     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2489
2490   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2491
2492   return s;
2493 }
2494
2495 static void
2496 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   u8 *s = 0, *eid = 0;
2500
2501   if (~0 == mp->locator_set_index)
2502     s = format (0, "action: %d", mp->action);
2503   else
2504     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2505
2506   eid = format (0, "%U", format_lisp_eid_vat,
2507                 mp->eid_type,
2508                 mp->eid,
2509                 mp->eid_prefix_len,
2510                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2511   vec_add1 (eid, 0);
2512
2513   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2514          clib_net_to_host_u32 (mp->vni),
2515          eid,
2516          mp->is_local ? "local" : "remote",
2517          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2518          clib_net_to_host_u16 (mp->key_id), mp->key);
2519
2520   vec_free (s);
2521   vec_free (eid);
2522 }
2523
2524 static void
2525 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2526                                              * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   vat_json_node_t *node = 0;
2530   u8 *eid = 0;
2531
2532   if (VAT_JSON_ARRAY != vam->json_tree.type)
2533     {
2534       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2535       vat_json_init_array (&vam->json_tree);
2536     }
2537   node = vat_json_array_add (&vam->json_tree);
2538
2539   vat_json_init_object (node);
2540   if (~0 == mp->locator_set_index)
2541     vat_json_object_add_uint (node, "action", mp->action);
2542   else
2543     vat_json_object_add_uint (node, "locator_set_index",
2544                               clib_net_to_host_u32 (mp->locator_set_index));
2545
2546   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2547   eid = format (0, "%U", format_lisp_eid_vat,
2548                 mp->eid_type,
2549                 mp->eid,
2550                 mp->eid_prefix_len,
2551                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2552   vec_add1 (eid, 0);
2553   vat_json_object_add_string_copy (node, "eid", eid);
2554   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2555   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2556   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2557
2558   if (mp->key_id)
2559     {
2560       vat_json_object_add_uint (node, "key_id",
2561                                 clib_net_to_host_u16 (mp->key_id));
2562       vat_json_object_add_string_copy (node, "key", mp->key);
2563     }
2564   vec_free (eid);
2565 }
2566
2567 static void
2568   vl_api_one_eid_table_map_details_t_handler
2569   (vl_api_one_eid_table_map_details_t * mp)
2570 {
2571   vat_main_t *vam = &vat_main;
2572
2573   u8 *line = format (0, "%=10d%=10d",
2574                      clib_net_to_host_u32 (mp->vni),
2575                      clib_net_to_host_u32 (mp->dp_table));
2576   print (vam->ofp, "%v", line);
2577   vec_free (line);
2578 }
2579
2580 static void
2581   vl_api_one_eid_table_map_details_t_handler_json
2582   (vl_api_one_eid_table_map_details_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   vat_json_node_t *node = NULL;
2586
2587   if (VAT_JSON_ARRAY != vam->json_tree.type)
2588     {
2589       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2590       vat_json_init_array (&vam->json_tree);
2591     }
2592   node = vat_json_array_add (&vam->json_tree);
2593   vat_json_init_object (node);
2594   vat_json_object_add_uint (node, "dp_table",
2595                             clib_net_to_host_u32 (mp->dp_table));
2596   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2597 }
2598
2599 static void
2600   vl_api_one_eid_table_vni_details_t_handler
2601   (vl_api_one_eid_table_vni_details_t * mp)
2602 {
2603   vat_main_t *vam = &vat_main;
2604
2605   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2606   print (vam->ofp, "%v", line);
2607   vec_free (line);
2608 }
2609
2610 static void
2611   vl_api_one_eid_table_vni_details_t_handler_json
2612   (vl_api_one_eid_table_vni_details_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   vat_json_node_t *node = NULL;
2616
2617   if (VAT_JSON_ARRAY != vam->json_tree.type)
2618     {
2619       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2620       vat_json_init_array (&vam->json_tree);
2621     }
2622   node = vat_json_array_add (&vam->json_tree);
2623   vat_json_init_object (node);
2624   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2625 }
2626
2627 static void
2628   vl_api_show_one_map_register_state_reply_t_handler
2629   (vl_api_show_one_map_register_state_reply_t * mp)
2630 {
2631   vat_main_t *vam = &vat_main;
2632   int retval = clib_net_to_host_u32 (mp->retval);
2633
2634   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2635
2636   vam->retval = retval;
2637   vam->result_ready = 1;
2638 }
2639
2640 static void
2641   vl_api_show_one_map_register_state_reply_t_handler_json
2642   (vl_api_show_one_map_register_state_reply_t * mp)
2643 {
2644   vat_main_t *vam = &vat_main;
2645   vat_json_node_t _node, *node = &_node;
2646   int retval = clib_net_to_host_u32 (mp->retval);
2647
2648   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2649
2650   vat_json_init_object (node);
2651   vat_json_object_add_string_copy (node, "state", s);
2652
2653   vat_json_print (vam->ofp, node);
2654   vat_json_free (node);
2655
2656   vam->retval = retval;
2657   vam->result_ready = 1;
2658   vec_free (s);
2659 }
2660
2661 static void
2662   vl_api_show_one_rloc_probe_state_reply_t_handler
2663   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2664 {
2665   vat_main_t *vam = &vat_main;
2666   int retval = clib_net_to_host_u32 (mp->retval);
2667
2668   if (retval)
2669     goto end;
2670
2671   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2672 end:
2673   vam->retval = retval;
2674   vam->result_ready = 1;
2675 }
2676
2677 static void
2678   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2679   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2680 {
2681   vat_main_t *vam = &vat_main;
2682   vat_json_node_t _node, *node = &_node;
2683   int retval = clib_net_to_host_u32 (mp->retval);
2684
2685   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2686   vat_json_init_object (node);
2687   vat_json_object_add_string_copy (node, "state", s);
2688
2689   vat_json_print (vam->ofp, node);
2690   vat_json_free (node);
2691
2692   vam->retval = retval;
2693   vam->result_ready = 1;
2694   vec_free (s);
2695 }
2696
2697 static void
2698 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2699 {
2700   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2701   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2702 }
2703
2704 static void
2705   gpe_fwd_entries_get_reply_t_net_to_host
2706   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2707 {
2708   u32 i;
2709
2710   mp->count = clib_net_to_host_u32 (mp->count);
2711   for (i = 0; i < mp->count; i++)
2712     {
2713       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2714     }
2715 }
2716
2717 static void
2718   vl_api_gpe_fwd_entry_path_details_t_handler
2719   (vl_api_gpe_fwd_entry_path_details_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2723
2724   if (mp->lcl_loc.is_ip4)
2725     format_ip_address_fcn = format_ip4_address;
2726   else
2727     format_ip_address_fcn = format_ip6_address;
2728
2729   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2730          format_ip_address_fcn, &mp->lcl_loc,
2731          format_ip_address_fcn, &mp->rmt_loc);
2732 }
2733
2734 static void
2735 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2736 {
2737   struct in6_addr ip6;
2738   struct in_addr ip4;
2739
2740   if (loc->is_ip4)
2741     {
2742       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2743       vat_json_object_add_ip4 (n, "address", ip4);
2744     }
2745   else
2746     {
2747       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2748       vat_json_object_add_ip6 (n, "address", ip6);
2749     }
2750   vat_json_object_add_uint (n, "weight", loc->weight);
2751 }
2752
2753 static void
2754   vl_api_gpe_fwd_entry_path_details_t_handler_json
2755   (vl_api_gpe_fwd_entry_path_details_t * mp)
2756 {
2757   vat_main_t *vam = &vat_main;
2758   vat_json_node_t *node = NULL;
2759   vat_json_node_t *loc_node;
2760
2761   if (VAT_JSON_ARRAY != vam->json_tree.type)
2762     {
2763       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2764       vat_json_init_array (&vam->json_tree);
2765     }
2766   node = vat_json_array_add (&vam->json_tree);
2767   vat_json_init_object (node);
2768
2769   loc_node = vat_json_object_add (node, "local_locator");
2770   vat_json_init_object (loc_node);
2771   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2772
2773   loc_node = vat_json_object_add (node, "remote_locator");
2774   vat_json_init_object (loc_node);
2775   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2776 }
2777
2778 static void
2779   vl_api_gpe_fwd_entries_get_reply_t_handler
2780   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2781 {
2782   vat_main_t *vam = &vat_main;
2783   u32 i;
2784   int retval = clib_net_to_host_u32 (mp->retval);
2785   vl_api_gpe_fwd_entry_t *e;
2786
2787   if (retval)
2788     goto end;
2789
2790   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2791
2792   for (i = 0; i < mp->count; i++)
2793     {
2794       e = &mp->entries[i];
2795       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2796              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2797              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2798     }
2799
2800 end:
2801   vam->retval = retval;
2802   vam->result_ready = 1;
2803 }
2804
2805 static void
2806   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2807   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2808 {
2809   u8 *s = 0;
2810   vat_main_t *vam = &vat_main;
2811   vat_json_node_t *e = 0, root;
2812   u32 i;
2813   int retval = clib_net_to_host_u32 (mp->retval);
2814   vl_api_gpe_fwd_entry_t *fwd;
2815
2816   if (retval)
2817     goto end;
2818
2819   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2820   vat_json_init_array (&root);
2821
2822   for (i = 0; i < mp->count; i++)
2823     {
2824       e = vat_json_array_add (&root);
2825       fwd = &mp->entries[i];
2826
2827       vat_json_init_object (e);
2828       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2829       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2830
2831       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2832                   fwd->leid_prefix_len);
2833       vec_add1 (s, 0);
2834       vat_json_object_add_string_copy (e, "leid", s);
2835       vec_free (s);
2836
2837       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2838                   fwd->reid_prefix_len);
2839       vec_add1 (s, 0);
2840       vat_json_object_add_string_copy (e, "reid", s);
2841       vec_free (s);
2842     }
2843
2844   vat_json_print (vam->ofp, &root);
2845   vat_json_free (&root);
2846
2847 end:
2848   vam->retval = retval;
2849   vam->result_ready = 1;
2850 }
2851
2852 static void
2853   vl_api_one_adjacencies_get_reply_t_handler
2854   (vl_api_one_adjacencies_get_reply_t * mp)
2855 {
2856   vat_main_t *vam = &vat_main;
2857   u32 i, n;
2858   int retval = clib_net_to_host_u32 (mp->retval);
2859   vl_api_one_adjacency_t *a;
2860
2861   if (retval)
2862     goto end;
2863
2864   n = clib_net_to_host_u32 (mp->count);
2865
2866   for (i = 0; i < n; i++)
2867     {
2868       a = &mp->adjacencies[i];
2869       print (vam->ofp, "%U %40U",
2870              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2871              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2872     }
2873
2874 end:
2875   vam->retval = retval;
2876   vam->result_ready = 1;
2877 }
2878
2879 static void
2880   vl_api_one_adjacencies_get_reply_t_handler_json
2881   (vl_api_one_adjacencies_get_reply_t * mp)
2882 {
2883   u8 *s = 0;
2884   vat_main_t *vam = &vat_main;
2885   vat_json_node_t *e = 0, root;
2886   u32 i, n;
2887   int retval = clib_net_to_host_u32 (mp->retval);
2888   vl_api_one_adjacency_t *a;
2889
2890   if (retval)
2891     goto end;
2892
2893   n = clib_net_to_host_u32 (mp->count);
2894   vat_json_init_array (&root);
2895
2896   for (i = 0; i < n; i++)
2897     {
2898       e = vat_json_array_add (&root);
2899       a = &mp->adjacencies[i];
2900
2901       vat_json_init_object (e);
2902       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2903                   a->leid_prefix_len);
2904       vec_add1 (s, 0);
2905       vat_json_object_add_string_copy (e, "leid", s);
2906       vec_free (s);
2907
2908       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2909                   a->reid_prefix_len);
2910       vec_add1 (s, 0);
2911       vat_json_object_add_string_copy (e, "reid", s);
2912       vec_free (s);
2913     }
2914
2915   vat_json_print (vam->ofp, &root);
2916   vat_json_free (&root);
2917
2918 end:
2919   vam->retval = retval;
2920   vam->result_ready = 1;
2921 }
2922
2923 static void
2924 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
2925 {
2926   vat_main_t *vam = &vat_main;
2927
2928   print (vam->ofp, "%=20U",
2929          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2930          mp->ip_address);
2931 }
2932
2933 static void
2934   vl_api_one_map_server_details_t_handler_json
2935   (vl_api_one_map_server_details_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   vat_json_node_t *node = NULL;
2939   struct in6_addr ip6;
2940   struct in_addr ip4;
2941
2942   if (VAT_JSON_ARRAY != vam->json_tree.type)
2943     {
2944       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2945       vat_json_init_array (&vam->json_tree);
2946     }
2947   node = vat_json_array_add (&vam->json_tree);
2948
2949   vat_json_init_object (node);
2950   if (mp->is_ipv6)
2951     {
2952       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2953       vat_json_object_add_ip6 (node, "map-server", ip6);
2954     }
2955   else
2956     {
2957       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2958       vat_json_object_add_ip4 (node, "map-server", ip4);
2959     }
2960 }
2961
2962 static void
2963 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
2964                                            * mp)
2965 {
2966   vat_main_t *vam = &vat_main;
2967
2968   print (vam->ofp, "%=20U",
2969          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2970          mp->ip_address);
2971 }
2972
2973 static void
2974   vl_api_one_map_resolver_details_t_handler_json
2975   (vl_api_one_map_resolver_details_t * mp)
2976 {
2977   vat_main_t *vam = &vat_main;
2978   vat_json_node_t *node = NULL;
2979   struct in6_addr ip6;
2980   struct in_addr ip4;
2981
2982   if (VAT_JSON_ARRAY != vam->json_tree.type)
2983     {
2984       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2985       vat_json_init_array (&vam->json_tree);
2986     }
2987   node = vat_json_array_add (&vam->json_tree);
2988
2989   vat_json_init_object (node);
2990   if (mp->is_ipv6)
2991     {
2992       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2993       vat_json_object_add_ip6 (node, "map resolver", ip6);
2994     }
2995   else
2996     {
2997       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2998       vat_json_object_add_ip4 (node, "map resolver", ip4);
2999     }
3000 }
3001
3002 static void
3003 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3004 {
3005   vat_main_t *vam = &vat_main;
3006   i32 retval = ntohl (mp->retval);
3007
3008   if (0 <= retval)
3009     {
3010       print (vam->ofp, "feature: %s\ngpe: %s",
3011              mp->feature_status ? "enabled" : "disabled",
3012              mp->gpe_status ? "enabled" : "disabled");
3013     }
3014
3015   vam->retval = retval;
3016   vam->result_ready = 1;
3017 }
3018
3019 static void
3020   vl_api_show_one_status_reply_t_handler_json
3021   (vl_api_show_one_status_reply_t * mp)
3022 {
3023   vat_main_t *vam = &vat_main;
3024   vat_json_node_t node;
3025   u8 *gpe_status = NULL;
3026   u8 *feature_status = NULL;
3027
3028   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3029   feature_status = format (0, "%s",
3030                            mp->feature_status ? "enabled" : "disabled");
3031   vec_add1 (gpe_status, 0);
3032   vec_add1 (feature_status, 0);
3033
3034   vat_json_init_object (&node);
3035   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3036   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3037
3038   vec_free (gpe_status);
3039   vec_free (feature_status);
3040
3041   vat_json_print (vam->ofp, &node);
3042   vat_json_free (&node);
3043
3044   vam->retval = ntohl (mp->retval);
3045   vam->result_ready = 1;
3046 }
3047
3048 static void
3049   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3050   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3051 {
3052   vat_main_t *vam = &vat_main;
3053   i32 retval = ntohl (mp->retval);
3054
3055   if (retval >= 0)
3056     {
3057       print (vam->ofp, "%=20s", mp->locator_set_name);
3058     }
3059
3060   vam->retval = retval;
3061   vam->result_ready = 1;
3062 }
3063
3064 static void
3065   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3066   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3067 {
3068   vat_main_t *vam = &vat_main;
3069   vat_json_node_t *node = NULL;
3070
3071   if (VAT_JSON_ARRAY != vam->json_tree.type)
3072     {
3073       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3074       vat_json_init_array (&vam->json_tree);
3075     }
3076   node = vat_json_array_add (&vam->json_tree);
3077
3078   vat_json_init_object (node);
3079   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3080
3081   vat_json_print (vam->ofp, node);
3082   vat_json_free (node);
3083
3084   vam->retval = ntohl (mp->retval);
3085   vam->result_ready = 1;
3086 }
3087
3088 static u8 *
3089 format_lisp_map_request_mode (u8 * s, va_list * args)
3090 {
3091   u32 mode = va_arg (*args, u32);
3092
3093   switch (mode)
3094     {
3095     case 0:
3096       return format (0, "dst-only");
3097     case 1:
3098       return format (0, "src-dst");
3099     }
3100   return 0;
3101 }
3102
3103 static void
3104   vl_api_show_one_map_request_mode_reply_t_handler
3105   (vl_api_show_one_map_request_mode_reply_t * mp)
3106 {
3107   vat_main_t *vam = &vat_main;
3108   i32 retval = ntohl (mp->retval);
3109
3110   if (0 <= retval)
3111     {
3112       u32 mode = mp->mode;
3113       print (vam->ofp, "map_request_mode: %U",
3114              format_lisp_map_request_mode, mode);
3115     }
3116
3117   vam->retval = retval;
3118   vam->result_ready = 1;
3119 }
3120
3121 static void
3122   vl_api_show_one_map_request_mode_reply_t_handler_json
3123   (vl_api_show_one_map_request_mode_reply_t * mp)
3124 {
3125   vat_main_t *vam = &vat_main;
3126   vat_json_node_t node;
3127   u8 *s = 0;
3128   u32 mode;
3129
3130   mode = mp->mode;
3131   s = format (0, "%U", format_lisp_map_request_mode, mode);
3132   vec_add1 (s, 0);
3133
3134   vat_json_init_object (&node);
3135   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3136   vat_json_print (vam->ofp, &node);
3137   vat_json_free (&node);
3138
3139   vec_free (s);
3140   vam->retval = ntohl (mp->retval);
3141   vam->result_ready = 1;
3142 }
3143
3144 static void
3145 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3146 {
3147   vat_main_t *vam = &vat_main;
3148   i32 retval = ntohl (mp->retval);
3149
3150   if (0 <= retval)
3151     {
3152       print (vam->ofp, "%-20s%-16s",
3153              mp->status ? "enabled" : "disabled",
3154              mp->status ? (char *) mp->locator_set_name : "");
3155     }
3156
3157   vam->retval = retval;
3158   vam->result_ready = 1;
3159 }
3160
3161 static void
3162 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3163 {
3164   vat_main_t *vam = &vat_main;
3165   vat_json_node_t node;
3166   u8 *status = 0;
3167
3168   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3169   vec_add1 (status, 0);
3170
3171   vat_json_init_object (&node);
3172   vat_json_object_add_string_copy (&node, "status", status);
3173   if (mp->status)
3174     {
3175       vat_json_object_add_string_copy (&node, "locator_set",
3176                                        mp->locator_set_name);
3177     }
3178
3179   vec_free (status);
3180
3181   vat_json_print (vam->ofp, &node);
3182   vat_json_free (&node);
3183
3184   vam->retval = ntohl (mp->retval);
3185   vam->result_ready = 1;
3186 }
3187
3188 static u8 *
3189 format_policer_type (u8 * s, va_list * va)
3190 {
3191   u32 i = va_arg (*va, u32);
3192
3193   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3194     s = format (s, "1r2c");
3195   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3196     s = format (s, "1r3c");
3197   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3198     s = format (s, "2r3c-2698");
3199   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3200     s = format (s, "2r3c-4115");
3201   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3202     s = format (s, "2r3c-mef5cf1");
3203   else
3204     s = format (s, "ILLEGAL");
3205   return s;
3206 }
3207
3208 static u8 *
3209 format_policer_rate_type (u8 * s, va_list * va)
3210 {
3211   u32 i = va_arg (*va, u32);
3212
3213   if (i == SSE2_QOS_RATE_KBPS)
3214     s = format (s, "kbps");
3215   else if (i == SSE2_QOS_RATE_PPS)
3216     s = format (s, "pps");
3217   else
3218     s = format (s, "ILLEGAL");
3219   return s;
3220 }
3221
3222 static u8 *
3223 format_policer_round_type (u8 * s, va_list * va)
3224 {
3225   u32 i = va_arg (*va, u32);
3226
3227   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3228     s = format (s, "closest");
3229   else if (i == SSE2_QOS_ROUND_TO_UP)
3230     s = format (s, "up");
3231   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3232     s = format (s, "down");
3233   else
3234     s = format (s, "ILLEGAL");
3235   return s;
3236 }
3237
3238 static u8 *
3239 format_policer_action_type (u8 * s, va_list * va)
3240 {
3241   u32 i = va_arg (*va, u32);
3242
3243   if (i == SSE2_QOS_ACTION_DROP)
3244     s = format (s, "drop");
3245   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3246     s = format (s, "transmit");
3247   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3248     s = format (s, "mark-and-transmit");
3249   else
3250     s = format (s, "ILLEGAL");
3251   return s;
3252 }
3253
3254 static u8 *
3255 format_dscp (u8 * s, va_list * va)
3256 {
3257   u32 i = va_arg (*va, u32);
3258   char *t = 0;
3259
3260   switch (i)
3261     {
3262 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3263       foreach_vnet_dscp
3264 #undef _
3265     default:
3266       return format (s, "ILLEGAL");
3267     }
3268   s = format (s, "%s", t);
3269   return s;
3270 }
3271
3272 static void
3273 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3277
3278   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3279     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3280   else
3281     conform_dscp_str = format (0, "");
3282
3283   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3284     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3285   else
3286     exceed_dscp_str = format (0, "");
3287
3288   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3289     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3290   else
3291     violate_dscp_str = format (0, "");
3292
3293   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3294          "rate type %U, round type %U, %s rate, %s color-aware, "
3295          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3296          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3297          "conform action %U%s, exceed action %U%s, violate action %U%s",
3298          mp->name,
3299          format_policer_type, mp->type,
3300          ntohl (mp->cir),
3301          ntohl (mp->eir),
3302          clib_net_to_host_u64 (mp->cb),
3303          clib_net_to_host_u64 (mp->eb),
3304          format_policer_rate_type, mp->rate_type,
3305          format_policer_round_type, mp->round_type,
3306          mp->single_rate ? "single" : "dual",
3307          mp->color_aware ? "is" : "not",
3308          ntohl (mp->cir_tokens_per_period),
3309          ntohl (mp->pir_tokens_per_period),
3310          ntohl (mp->scale),
3311          ntohl (mp->current_limit),
3312          ntohl (mp->current_bucket),
3313          ntohl (mp->extended_limit),
3314          ntohl (mp->extended_bucket),
3315          clib_net_to_host_u64 (mp->last_update_time),
3316          format_policer_action_type, mp->conform_action_type,
3317          conform_dscp_str,
3318          format_policer_action_type, mp->exceed_action_type,
3319          exceed_dscp_str,
3320          format_policer_action_type, mp->violate_action_type,
3321          violate_dscp_str);
3322
3323   vec_free (conform_dscp_str);
3324   vec_free (exceed_dscp_str);
3325   vec_free (violate_dscp_str);
3326 }
3327
3328 static void vl_api_policer_details_t_handler_json
3329   (vl_api_policer_details_t * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332   vat_json_node_t *node;
3333   u8 *rate_type_str, *round_type_str, *type_str;
3334   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3335
3336   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3337   round_type_str =
3338     format (0, "%U", format_policer_round_type, mp->round_type);
3339   type_str = format (0, "%U", format_policer_type, mp->type);
3340   conform_action_str = format (0, "%U", format_policer_action_type,
3341                                mp->conform_action_type);
3342   exceed_action_str = format (0, "%U", format_policer_action_type,
3343                               mp->exceed_action_type);
3344   violate_action_str = format (0, "%U", format_policer_action_type,
3345                                mp->violate_action_type);
3346
3347   if (VAT_JSON_ARRAY != vam->json_tree.type)
3348     {
3349       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3350       vat_json_init_array (&vam->json_tree);
3351     }
3352   node = vat_json_array_add (&vam->json_tree);
3353
3354   vat_json_init_object (node);
3355   vat_json_object_add_string_copy (node, "name", mp->name);
3356   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3357   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3358   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3359   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3360   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3361   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3362   vat_json_object_add_string_copy (node, "type", type_str);
3363   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3364   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3365   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3366   vat_json_object_add_uint (node, "cir_tokens_per_period",
3367                             ntohl (mp->cir_tokens_per_period));
3368   vat_json_object_add_uint (node, "eir_tokens_per_period",
3369                             ntohl (mp->pir_tokens_per_period));
3370   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3371   vat_json_object_add_uint (node, "current_bucket",
3372                             ntohl (mp->current_bucket));
3373   vat_json_object_add_uint (node, "extended_limit",
3374                             ntohl (mp->extended_limit));
3375   vat_json_object_add_uint (node, "extended_bucket",
3376                             ntohl (mp->extended_bucket));
3377   vat_json_object_add_uint (node, "last_update_time",
3378                             ntohl (mp->last_update_time));
3379   vat_json_object_add_string_copy (node, "conform_action",
3380                                    conform_action_str);
3381   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3382     {
3383       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3384       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3385       vec_free (dscp_str);
3386     }
3387   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3388   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3389     {
3390       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3391       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3392       vec_free (dscp_str);
3393     }
3394   vat_json_object_add_string_copy (node, "violate_action",
3395                                    violate_action_str);
3396   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3397     {
3398       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3399       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3400       vec_free (dscp_str);
3401     }
3402
3403   vec_free (rate_type_str);
3404   vec_free (round_type_str);
3405   vec_free (type_str);
3406   vec_free (conform_action_str);
3407   vec_free (exceed_action_str);
3408   vec_free (violate_action_str);
3409 }
3410
3411 static void
3412 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3413                                            mp)
3414 {
3415   vat_main_t *vam = &vat_main;
3416   int i, count = ntohl (mp->count);
3417
3418   if (count > 0)
3419     print (vam->ofp, "classify table ids (%d) : ", count);
3420   for (i = 0; i < count; i++)
3421     {
3422       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3423       print (vam->ofp, (i < count - 1) ? "," : "");
3424     }
3425   vam->retval = ntohl (mp->retval);
3426   vam->result_ready = 1;
3427 }
3428
3429 static void
3430   vl_api_classify_table_ids_reply_t_handler_json
3431   (vl_api_classify_table_ids_reply_t * mp)
3432 {
3433   vat_main_t *vam = &vat_main;
3434   int i, count = ntohl (mp->count);
3435
3436   if (count > 0)
3437     {
3438       vat_json_node_t node;
3439
3440       vat_json_init_object (&node);
3441       for (i = 0; i < count; i++)
3442         {
3443           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3444         }
3445       vat_json_print (vam->ofp, &node);
3446       vat_json_free (&node);
3447     }
3448   vam->retval = ntohl (mp->retval);
3449   vam->result_ready = 1;
3450 }
3451
3452 static void
3453   vl_api_classify_table_by_interface_reply_t_handler
3454   (vl_api_classify_table_by_interface_reply_t * mp)
3455 {
3456   vat_main_t *vam = &vat_main;
3457   u32 table_id;
3458
3459   table_id = ntohl (mp->l2_table_id);
3460   if (table_id != ~0)
3461     print (vam->ofp, "l2 table id : %d", table_id);
3462   else
3463     print (vam->ofp, "l2 table id : No input ACL tables configured");
3464   table_id = ntohl (mp->ip4_table_id);
3465   if (table_id != ~0)
3466     print (vam->ofp, "ip4 table id : %d", table_id);
3467   else
3468     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3469   table_id = ntohl (mp->ip6_table_id);
3470   if (table_id != ~0)
3471     print (vam->ofp, "ip6 table id : %d", table_id);
3472   else
3473     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3474   vam->retval = ntohl (mp->retval);
3475   vam->result_ready = 1;
3476 }
3477
3478 static void
3479   vl_api_classify_table_by_interface_reply_t_handler_json
3480   (vl_api_classify_table_by_interface_reply_t * mp)
3481 {
3482   vat_main_t *vam = &vat_main;
3483   vat_json_node_t node;
3484
3485   vat_json_init_object (&node);
3486
3487   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3488   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3489   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3490
3491   vat_json_print (vam->ofp, &node);
3492   vat_json_free (&node);
3493
3494   vam->retval = ntohl (mp->retval);
3495   vam->result_ready = 1;
3496 }
3497
3498 static void vl_api_policer_add_del_reply_t_handler
3499   (vl_api_policer_add_del_reply_t * mp)
3500 {
3501   vat_main_t *vam = &vat_main;
3502   i32 retval = ntohl (mp->retval);
3503   if (vam->async_mode)
3504     {
3505       vam->async_errors += (retval < 0);
3506     }
3507   else
3508     {
3509       vam->retval = retval;
3510       vam->result_ready = 1;
3511       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3512         /*
3513          * Note: this is just barely thread-safe, depends on
3514          * the main thread spinning waiting for an answer...
3515          */
3516         errmsg ("policer index %d", ntohl (mp->policer_index));
3517     }
3518 }
3519
3520 static void vl_api_policer_add_del_reply_t_handler_json
3521   (vl_api_policer_add_del_reply_t * mp)
3522 {
3523   vat_main_t *vam = &vat_main;
3524   vat_json_node_t node;
3525
3526   vat_json_init_object (&node);
3527   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3528   vat_json_object_add_uint (&node, "policer_index",
3529                             ntohl (mp->policer_index));
3530
3531   vat_json_print (vam->ofp, &node);
3532   vat_json_free (&node);
3533
3534   vam->retval = ntohl (mp->retval);
3535   vam->result_ready = 1;
3536 }
3537
3538 /* Format hex dump. */
3539 u8 *
3540 format_hex_bytes (u8 * s, va_list * va)
3541 {
3542   u8 *bytes = va_arg (*va, u8 *);
3543   int n_bytes = va_arg (*va, int);
3544   uword i;
3545
3546   /* Print short or long form depending on byte count. */
3547   uword short_form = n_bytes <= 32;
3548   uword indent = format_get_indent (s);
3549
3550   if (n_bytes == 0)
3551     return s;
3552
3553   for (i = 0; i < n_bytes; i++)
3554     {
3555       if (!short_form && (i % 32) == 0)
3556         s = format (s, "%08x: ", i);
3557       s = format (s, "%02x", bytes[i]);
3558       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3559         s = format (s, "\n%U", format_white_space, indent);
3560     }
3561
3562   return s;
3563 }
3564
3565 static void
3566 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3567                                             * mp)
3568 {
3569   vat_main_t *vam = &vat_main;
3570   i32 retval = ntohl (mp->retval);
3571   if (retval == 0)
3572     {
3573       print (vam->ofp, "classify table info :");
3574       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3575              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3576              ntohl (mp->miss_next_index));
3577       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3578              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3579              ntohl (mp->match_n_vectors));
3580       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3581              ntohl (mp->mask_length));
3582     }
3583   vam->retval = retval;
3584   vam->result_ready = 1;
3585 }
3586
3587 static void
3588   vl_api_classify_table_info_reply_t_handler_json
3589   (vl_api_classify_table_info_reply_t * mp)
3590 {
3591   vat_main_t *vam = &vat_main;
3592   vat_json_node_t node;
3593
3594   i32 retval = ntohl (mp->retval);
3595   if (retval == 0)
3596     {
3597       vat_json_init_object (&node);
3598
3599       vat_json_object_add_int (&node, "sessions",
3600                                ntohl (mp->active_sessions));
3601       vat_json_object_add_int (&node, "nexttbl",
3602                                ntohl (mp->next_table_index));
3603       vat_json_object_add_int (&node, "nextnode",
3604                                ntohl (mp->miss_next_index));
3605       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3606       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3607       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3608       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3609                       ntohl (mp->mask_length), 0);
3610       vat_json_object_add_string_copy (&node, "mask", s);
3611
3612       vat_json_print (vam->ofp, &node);
3613       vat_json_free (&node);
3614     }
3615   vam->retval = ntohl (mp->retval);
3616   vam->result_ready = 1;
3617 }
3618
3619 static void
3620 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3621                                            mp)
3622 {
3623   vat_main_t *vam = &vat_main;
3624
3625   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3626          ntohl (mp->hit_next_index), ntohl (mp->advance),
3627          ntohl (mp->opaque_index));
3628   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3629          ntohl (mp->match_length));
3630 }
3631
3632 static void
3633   vl_api_classify_session_details_t_handler_json
3634   (vl_api_classify_session_details_t * mp)
3635 {
3636   vat_main_t *vam = &vat_main;
3637   vat_json_node_t *node = NULL;
3638
3639   if (VAT_JSON_ARRAY != vam->json_tree.type)
3640     {
3641       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3642       vat_json_init_array (&vam->json_tree);
3643     }
3644   node = vat_json_array_add (&vam->json_tree);
3645
3646   vat_json_init_object (node);
3647   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3648   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3649   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3650   u8 *s =
3651     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3652             0);
3653   vat_json_object_add_string_copy (node, "match", s);
3654 }
3655
3656 static void vl_api_pg_create_interface_reply_t_handler
3657   (vl_api_pg_create_interface_reply_t * mp)
3658 {
3659   vat_main_t *vam = &vat_main;
3660
3661   vam->retval = ntohl (mp->retval);
3662   vam->result_ready = 1;
3663 }
3664
3665 static void vl_api_pg_create_interface_reply_t_handler_json
3666   (vl_api_pg_create_interface_reply_t * mp)
3667 {
3668   vat_main_t *vam = &vat_main;
3669   vat_json_node_t node;
3670
3671   i32 retval = ntohl (mp->retval);
3672   if (retval == 0)
3673     {
3674       vat_json_init_object (&node);
3675
3676       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3677
3678       vat_json_print (vam->ofp, &node);
3679       vat_json_free (&node);
3680     }
3681   vam->retval = ntohl (mp->retval);
3682   vam->result_ready = 1;
3683 }
3684
3685 static void vl_api_policer_classify_details_t_handler
3686   (vl_api_policer_classify_details_t * mp)
3687 {
3688   vat_main_t *vam = &vat_main;
3689
3690   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3691          ntohl (mp->table_index));
3692 }
3693
3694 static void vl_api_policer_classify_details_t_handler_json
3695   (vl_api_policer_classify_details_t * mp)
3696 {
3697   vat_main_t *vam = &vat_main;
3698   vat_json_node_t *node;
3699
3700   if (VAT_JSON_ARRAY != vam->json_tree.type)
3701     {
3702       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3703       vat_json_init_array (&vam->json_tree);
3704     }
3705   node = vat_json_array_add (&vam->json_tree);
3706
3707   vat_json_init_object (node);
3708   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3709   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3710 }
3711
3712 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3713   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3714 {
3715   vat_main_t *vam = &vat_main;
3716   i32 retval = ntohl (mp->retval);
3717   if (vam->async_mode)
3718     {
3719       vam->async_errors += (retval < 0);
3720     }
3721   else
3722     {
3723       vam->retval = retval;
3724       vam->sw_if_index = ntohl (mp->sw_if_index);
3725       vam->result_ready = 1;
3726     }
3727 }
3728
3729 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3730   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3731 {
3732   vat_main_t *vam = &vat_main;
3733   vat_json_node_t node;
3734
3735   vat_json_init_object (&node);
3736   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3737   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3738
3739   vat_json_print (vam->ofp, &node);
3740   vat_json_free (&node);
3741
3742   vam->retval = ntohl (mp->retval);
3743   vam->result_ready = 1;
3744 }
3745
3746 static void vl_api_flow_classify_details_t_handler
3747   (vl_api_flow_classify_details_t * mp)
3748 {
3749   vat_main_t *vam = &vat_main;
3750
3751   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3752          ntohl (mp->table_index));
3753 }
3754
3755 static void vl_api_flow_classify_details_t_handler_json
3756   (vl_api_flow_classify_details_t * mp)
3757 {
3758   vat_main_t *vam = &vat_main;
3759   vat_json_node_t *node;
3760
3761   if (VAT_JSON_ARRAY != vam->json_tree.type)
3762     {
3763       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3764       vat_json_init_array (&vam->json_tree);
3765     }
3766   node = vat_json_array_add (&vam->json_tree);
3767
3768   vat_json_init_object (node);
3769   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3770   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3771 }
3772
3773
3774
3775 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3776 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3777 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3778 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3779 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3780 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3781 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3782 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3783 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3784 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3785
3786 /*
3787  * Generate boilerplate reply handlers, which
3788  * dig the return value out of the xxx_reply_t API message,
3789  * stick it into vam->retval, and set vam->result_ready
3790  *
3791  * Could also do this by pointing N message decode slots at
3792  * a single function, but that could break in subtle ways.
3793  */
3794
3795 #define foreach_standard_reply_retval_handler           \
3796 _(sw_interface_set_flags_reply)                         \
3797 _(sw_interface_add_del_address_reply)                   \
3798 _(sw_interface_set_table_reply)                         \
3799 _(sw_interface_set_mpls_enable_reply)                   \
3800 _(sw_interface_set_vpath_reply)                         \
3801 _(sw_interface_set_vxlan_bypass_reply)                  \
3802 _(sw_interface_set_l2_bridge_reply)                     \
3803 _(bridge_domain_add_del_reply)                          \
3804 _(sw_interface_set_l2_xconnect_reply)                   \
3805 _(l2fib_add_del_reply)                                  \
3806 _(ip_add_del_route_reply)                               \
3807 _(ip_mroute_add_del_reply)                              \
3808 _(mpls_route_add_del_reply)                             \
3809 _(mpls_ip_bind_unbind_reply)                            \
3810 _(proxy_arp_add_del_reply)                              \
3811 _(proxy_arp_intfc_enable_disable_reply)                 \
3812 _(sw_interface_set_unnumbered_reply)                    \
3813 _(ip_neighbor_add_del_reply)                            \
3814 _(reset_vrf_reply)                                      \
3815 _(oam_add_del_reply)                                    \
3816 _(reset_fib_reply)                                      \
3817 _(dhcp_proxy_config_reply)                              \
3818 _(dhcp_proxy_set_vss_reply)                             \
3819 _(dhcp_client_config_reply)                             \
3820 _(set_ip_flow_hash_reply)                               \
3821 _(sw_interface_ip6_enable_disable_reply)                \
3822 _(sw_interface_ip6_set_link_local_address_reply)        \
3823 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3824 _(sw_interface_ip6nd_ra_config_reply)                   \
3825 _(set_arp_neighbor_limit_reply)                         \
3826 _(l2_patch_add_del_reply)                               \
3827 _(sr_tunnel_add_del_reply)                              \
3828 _(sr_policy_add_del_reply)                              \
3829 _(sr_multicast_map_add_del_reply)                       \
3830 _(classify_add_del_session_reply)                       \
3831 _(classify_set_interface_ip_table_reply)                \
3832 _(classify_set_interface_l2_tables_reply)               \
3833 _(l2tpv3_set_tunnel_cookies_reply)                      \
3834 _(l2tpv3_interface_enable_disable_reply)                \
3835 _(l2tpv3_set_lookup_key_reply)                          \
3836 _(l2_fib_clear_table_reply)                             \
3837 _(l2_interface_efp_filter_reply)                        \
3838 _(l2_interface_vlan_tag_rewrite_reply)                  \
3839 _(modify_vhost_user_if_reply)                           \
3840 _(delete_vhost_user_if_reply)                           \
3841 _(want_ip4_arp_events_reply)                            \
3842 _(want_ip6_nd_events_reply)                             \
3843 _(input_acl_set_interface_reply)                        \
3844 _(ipsec_spd_add_del_reply)                              \
3845 _(ipsec_interface_add_del_spd_reply)                    \
3846 _(ipsec_spd_add_del_entry_reply)                        \
3847 _(ipsec_sad_add_del_entry_reply)                        \
3848 _(ipsec_sa_set_key_reply)                               \
3849 _(ikev2_profile_add_del_reply)                          \
3850 _(ikev2_profile_set_auth_reply)                         \
3851 _(ikev2_profile_set_id_reply)                           \
3852 _(ikev2_profile_set_ts_reply)                           \
3853 _(ikev2_set_local_key_reply)                            \
3854 _(ikev2_set_responder_reply)                            \
3855 _(ikev2_set_ike_transforms_reply)                       \
3856 _(ikev2_set_esp_transforms_reply)                       \
3857 _(ikev2_set_sa_lifetime_reply)                          \
3858 _(ikev2_initiate_sa_init_reply)                         \
3859 _(ikev2_initiate_del_ike_sa_reply)                      \
3860 _(ikev2_initiate_del_child_sa_reply)                    \
3861 _(ikev2_initiate_rekey_child_sa_reply)                  \
3862 _(delete_loopback_reply)                                \
3863 _(bd_ip_mac_add_del_reply)                              \
3864 _(map_del_domain_reply)                                 \
3865 _(map_add_del_rule_reply)                               \
3866 _(want_interface_events_reply)                          \
3867 _(want_stats_reply)                                     \
3868 _(cop_interface_enable_disable_reply)                   \
3869 _(cop_whitelist_enable_disable_reply)                   \
3870 _(sw_interface_clear_stats_reply)                       \
3871 _(ioam_enable_reply)                              \
3872 _(ioam_disable_reply)                              \
3873 _(one_add_del_locator_reply)                            \
3874 _(one_add_del_local_eid_reply)                          \
3875 _(one_add_del_remote_mapping_reply)                     \
3876 _(one_add_del_adjacency_reply)                          \
3877 _(one_add_del_map_resolver_reply)                       \
3878 _(one_add_del_map_server_reply)                         \
3879 _(one_enable_disable_reply)                             \
3880 _(one_rloc_probe_enable_disable_reply)                  \
3881 _(one_map_register_enable_disable_reply)                \
3882 _(one_pitr_set_locator_set_reply)                       \
3883 _(one_map_request_mode_reply)                           \
3884 _(one_add_del_map_request_itr_rlocs_reply)              \
3885 _(one_eid_table_add_del_map_reply)                      \
3886 _(gpe_add_del_fwd_entry_reply)                          \
3887 _(gpe_enable_disable_reply)                             \
3888 _(gpe_add_del_iface_reply)                              \
3889 _(vxlan_gpe_add_del_tunnel_reply)                       \
3890 _(af_packet_delete_reply)                               \
3891 _(policer_classify_set_interface_reply)                 \
3892 _(netmap_create_reply)                                  \
3893 _(netmap_delete_reply)                                  \
3894 _(set_ipfix_exporter_reply)                             \
3895 _(set_ipfix_classify_stream_reply)                      \
3896 _(ipfix_classify_table_add_del_reply)                   \
3897 _(flow_classify_set_interface_reply)                    \
3898 _(sw_interface_span_enable_disable_reply)               \
3899 _(pg_capture_reply)                                     \
3900 _(pg_enable_disable_reply)                              \
3901 _(ip_source_and_port_range_check_add_del_reply)         \
3902 _(ip_source_and_port_range_check_interface_add_del_reply)\
3903 _(delete_subif_reply)                                   \
3904 _(l2_interface_pbb_tag_rewrite_reply)                   \
3905 _(punt_reply)                                           \
3906 _(feature_enable_disable_reply)                         \
3907 _(sw_interface_tag_add_del_reply)                       \
3908 _(sw_interface_set_mtu_reply)
3909
3910 #if DPDK > 0
3911 #define foreach_standard_dpdk_reply_retval_handler      \
3912 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3913 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3914 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3915 #endif
3916
3917 #define _(n)                                    \
3918     static void vl_api_##n##_t_handler          \
3919     (vl_api_##n##_t * mp)                       \
3920     {                                           \
3921         vat_main_t * vam = &vat_main;           \
3922         i32 retval = ntohl(mp->retval);         \
3923         if (vam->async_mode) {                  \
3924             vam->async_errors += (retval < 0);  \
3925         } else {                                \
3926             vam->retval = retval;               \
3927             vam->result_ready = 1;              \
3928         }                                       \
3929     }
3930 foreach_standard_reply_retval_handler;
3931 #undef _
3932
3933 #define _(n)                                    \
3934     static void vl_api_##n##_t_handler_json     \
3935     (vl_api_##n##_t * mp)                       \
3936     {                                           \
3937         vat_main_t * vam = &vat_main;           \
3938         vat_json_node_t node;                   \
3939         vat_json_init_object(&node);            \
3940         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3941         vat_json_print(vam->ofp, &node);        \
3942         vam->retval = ntohl(mp->retval);        \
3943         vam->result_ready = 1;                  \
3944     }
3945 foreach_standard_reply_retval_handler;
3946 #undef _
3947
3948 #if DPDK > 0
3949 #define _(n)                                    \
3950     static void vl_api_##n##_t_handler          \
3951     (vl_api_##n##_t * mp)                       \
3952     {                                           \
3953         vat_main_t * vam = &vat_main;           \
3954         i32 retval = ntohl(mp->retval);         \
3955         if (vam->async_mode) {                  \
3956             vam->async_errors += (retval < 0);  \
3957         } else {                                \
3958             vam->retval = retval;               \
3959             vam->result_ready = 1;              \
3960         }                                       \
3961     }
3962 foreach_standard_dpdk_reply_retval_handler;
3963 #undef _
3964
3965 #define _(n)                                    \
3966     static void vl_api_##n##_t_handler_json     \
3967     (vl_api_##n##_t * mp)                       \
3968     {                                           \
3969         vat_main_t * vam = &vat_main;           \
3970         vat_json_node_t node;                   \
3971         vat_json_init_object(&node);            \
3972         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3973         vat_json_print(vam->ofp, &node);        \
3974         vam->retval = ntohl(mp->retval);        \
3975         vam->result_ready = 1;                  \
3976     }
3977 foreach_standard_dpdk_reply_retval_handler;
3978 #undef _
3979 #endif
3980
3981 /*
3982  * Table of message reply handlers, must include boilerplate handlers
3983  * we just generated
3984  */
3985
3986 #define foreach_vpe_api_reply_msg                                       \
3987 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3988 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3989 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3990 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3991 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3992 _(CLI_REPLY, cli_reply)                                                 \
3993 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3994 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3995   sw_interface_add_del_address_reply)                                   \
3996 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3997 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3998 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3999 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4000 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4001   sw_interface_set_l2_xconnect_reply)                                   \
4002 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4003   sw_interface_set_l2_bridge_reply)                                     \
4004 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4005 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4006 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4007 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4008 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4009 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4010 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4011 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4012 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4013 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4014 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4015 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4016 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4017 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4018 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4019 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4020   proxy_arp_intfc_enable_disable_reply)                                 \
4021 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4022 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4023   sw_interface_set_unnumbered_reply)                                    \
4024 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4025 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4026 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4027 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4028 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4029 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4030 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4031 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4032 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4033 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4034 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4035 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4036   sw_interface_ip6_enable_disable_reply)                                \
4037 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4038   sw_interface_ip6_set_link_local_address_reply)                        \
4039 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4040   sw_interface_ip6nd_ra_prefix_reply)                                   \
4041 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4042   sw_interface_ip6nd_ra_config_reply)                                   \
4043 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4044 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4045 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
4046 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
4047 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
4048 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4049 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4050 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4051 classify_set_interface_ip_table_reply)                                  \
4052 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4053   classify_set_interface_l2_tables_reply)                               \
4054 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4055 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4056 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4057 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4058 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4059   l2tpv3_interface_enable_disable_reply)                                \
4060 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4061 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4062 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4063 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4064 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4065 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4066 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4067 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4068 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4069 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4070 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4071 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4072 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4073 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4074 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4075 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4076 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4077 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4078 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4079 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4080 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4081 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4082 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4083 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4084 _(IP_DETAILS, ip_details)                                               \
4085 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4086 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4087 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4088 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4089 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4090 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4091 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4092 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4093 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4094 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4095 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4096 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4097 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4098 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4099 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4100 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4101 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4102 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4103 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4104 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4105 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4106 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4107 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4108 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4109 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4110 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
4111 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4112 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4113 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4114 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4115 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4116 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4117 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4118 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4119 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4120 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4121 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4122 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4123 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4124 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4125 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4126 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4127 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4128 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4129 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4130 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4131 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4132 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4133 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4134   one_map_register_enable_disable_reply)                                \
4135 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4136   one_rloc_probe_enable_disable_reply)                                  \
4137 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4138 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4139 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4140 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4141 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4142 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4143 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4144 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4145 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4146 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4147 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4148 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4149 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4150 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4151 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4152 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4153   gpe_fwd_entry_path_details)                                           \
4154 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4155 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4156   one_add_del_map_request_itr_rlocs_reply)                              \
4157 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4158   one_get_map_request_itr_rlocs_reply)                                  \
4159 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4160 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4161 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4162 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4163   show_one_map_register_state_reply)                                    \
4164 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4165 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4166 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4167 _(POLICER_DETAILS, policer_details)                                     \
4168 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4169 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4170 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4171 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4172 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4173 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4174 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4175 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4176 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4177 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4178 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4179 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4180 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4181 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4182 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4183 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4184 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4185 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4186 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4187 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4188 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4189 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4190 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4191 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4192 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4193  ip_source_and_port_range_check_add_del_reply)                          \
4194 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4195  ip_source_and_port_range_check_interface_add_del_reply)                \
4196 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4197 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4198 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4199 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4200 _(PUNT_REPLY, punt_reply)                                               \
4201 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4202 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4203 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4204 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4205 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4206 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4207 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4208 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4209
4210 #if DPDK > 0
4211 #define foreach_vpe_dpdk_api_reply_msg                                  \
4212 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
4213   sw_interface_set_dpdk_hqos_pipe_reply)                                \
4214 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
4215   sw_interface_set_dpdk_hqos_subport_reply)                             \
4216 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
4217   sw_interface_set_dpdk_hqos_tctbl_reply)
4218 #endif
4219
4220 typedef struct
4221 {
4222   u8 *name;
4223   u32 value;
4224 } name_sort_t;
4225
4226
4227 #define STR_VTR_OP_CASE(op)     \
4228     case L2_VTR_ ## op:         \
4229         return "" # op;
4230
4231 static const char *
4232 str_vtr_op (u32 vtr_op)
4233 {
4234   switch (vtr_op)
4235     {
4236       STR_VTR_OP_CASE (DISABLED);
4237       STR_VTR_OP_CASE (PUSH_1);
4238       STR_VTR_OP_CASE (PUSH_2);
4239       STR_VTR_OP_CASE (POP_1);
4240       STR_VTR_OP_CASE (POP_2);
4241       STR_VTR_OP_CASE (TRANSLATE_1_1);
4242       STR_VTR_OP_CASE (TRANSLATE_1_2);
4243       STR_VTR_OP_CASE (TRANSLATE_2_1);
4244       STR_VTR_OP_CASE (TRANSLATE_2_2);
4245     }
4246
4247   return "UNKNOWN";
4248 }
4249
4250 static int
4251 dump_sub_interface_table (vat_main_t * vam)
4252 {
4253   const sw_interface_subif_t *sub = NULL;
4254
4255   if (vam->json_output)
4256     {
4257       clib_warning
4258         ("JSON output supported only for VPE API calls and dump_stats_table");
4259       return -99;
4260     }
4261
4262   print (vam->ofp,
4263          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4264          "Interface", "sw_if_index",
4265          "sub id", "dot1ad", "tags", "outer id",
4266          "inner id", "exact", "default", "outer any", "inner any");
4267
4268   vec_foreach (sub, vam->sw_if_subif_table)
4269   {
4270     print (vam->ofp,
4271            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4272            sub->interface_name,
4273            sub->sw_if_index,
4274            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4275            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4276            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4277            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4278     if (sub->vtr_op != L2_VTR_DISABLED)
4279       {
4280         print (vam->ofp,
4281                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4282                "tag1: %d tag2: %d ]",
4283                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4284                sub->vtr_tag1, sub->vtr_tag2);
4285       }
4286   }
4287
4288   return 0;
4289 }
4290
4291 static int
4292 name_sort_cmp (void *a1, void *a2)
4293 {
4294   name_sort_t *n1 = a1;
4295   name_sort_t *n2 = a2;
4296
4297   return strcmp ((char *) n1->name, (char *) n2->name);
4298 }
4299
4300 static int
4301 dump_interface_table (vat_main_t * vam)
4302 {
4303   hash_pair_t *p;
4304   name_sort_t *nses = 0, *ns;
4305
4306   if (vam->json_output)
4307     {
4308       clib_warning
4309         ("JSON output supported only for VPE API calls and dump_stats_table");
4310       return -99;
4311     }
4312
4313   /* *INDENT-OFF* */
4314   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4315   ({
4316     vec_add2 (nses, ns, 1);
4317     ns->name = (u8 *)(p->key);
4318     ns->value = (u32) p->value[0];
4319   }));
4320   /* *INDENT-ON* */
4321
4322   vec_sort_with_function (nses, name_sort_cmp);
4323
4324   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4325   vec_foreach (ns, nses)
4326   {
4327     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4328   }
4329   vec_free (nses);
4330   return 0;
4331 }
4332
4333 static int
4334 dump_ip_table (vat_main_t * vam, int is_ipv6)
4335 {
4336   const ip_details_t *det = NULL;
4337   const ip_address_details_t *address = NULL;
4338   u32 i = ~0;
4339
4340   print (vam->ofp, "%-12s", "sw_if_index");
4341
4342   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4343   {
4344     i++;
4345     if (!det->present)
4346       {
4347         continue;
4348       }
4349     print (vam->ofp, "%-12d", i);
4350     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4351     if (!det->addr)
4352       {
4353         continue;
4354       }
4355     vec_foreach (address, det->addr)
4356     {
4357       print (vam->ofp,
4358              "            %-30U%-13d",
4359              is_ipv6 ? format_ip6_address : format_ip4_address,
4360              address->ip, address->prefix_length);
4361     }
4362   }
4363
4364   return 0;
4365 }
4366
4367 static int
4368 dump_ipv4_table (vat_main_t * vam)
4369 {
4370   if (vam->json_output)
4371     {
4372       clib_warning
4373         ("JSON output supported only for VPE API calls and dump_stats_table");
4374       return -99;
4375     }
4376
4377   return dump_ip_table (vam, 0);
4378 }
4379
4380 static int
4381 dump_ipv6_table (vat_main_t * vam)
4382 {
4383   if (vam->json_output)
4384     {
4385       clib_warning
4386         ("JSON output supported only for VPE API calls and dump_stats_table");
4387       return -99;
4388     }
4389
4390   return dump_ip_table (vam, 1);
4391 }
4392
4393 static char *
4394 counter_type_to_str (u8 counter_type, u8 is_combined)
4395 {
4396   if (!is_combined)
4397     {
4398       switch (counter_type)
4399         {
4400         case VNET_INTERFACE_COUNTER_DROP:
4401           return "drop";
4402         case VNET_INTERFACE_COUNTER_PUNT:
4403           return "punt";
4404         case VNET_INTERFACE_COUNTER_IP4:
4405           return "ip4";
4406         case VNET_INTERFACE_COUNTER_IP6:
4407           return "ip6";
4408         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4409           return "rx-no-buf";
4410         case VNET_INTERFACE_COUNTER_RX_MISS:
4411           return "rx-miss";
4412         case VNET_INTERFACE_COUNTER_RX_ERROR:
4413           return "rx-error";
4414         case VNET_INTERFACE_COUNTER_TX_ERROR:
4415           return "tx-error";
4416         default:
4417           return "INVALID-COUNTER-TYPE";
4418         }
4419     }
4420   else
4421     {
4422       switch (counter_type)
4423         {
4424         case VNET_INTERFACE_COUNTER_RX:
4425           return "rx";
4426         case VNET_INTERFACE_COUNTER_TX:
4427           return "tx";
4428         default:
4429           return "INVALID-COUNTER-TYPE";
4430         }
4431     }
4432 }
4433
4434 static int
4435 dump_stats_table (vat_main_t * vam)
4436 {
4437   vat_json_node_t node;
4438   vat_json_node_t *msg_array;
4439   vat_json_node_t *msg;
4440   vat_json_node_t *counter_array;
4441   vat_json_node_t *counter;
4442   interface_counter_t c;
4443   u64 packets;
4444   ip4_fib_counter_t *c4;
4445   ip6_fib_counter_t *c6;
4446   ip4_nbr_counter_t *n4;
4447   ip6_nbr_counter_t *n6;
4448   int i, j;
4449
4450   if (!vam->json_output)
4451     {
4452       clib_warning ("dump_stats_table supported only in JSON format");
4453       return -99;
4454     }
4455
4456   vat_json_init_object (&node);
4457
4458   /* interface counters */
4459   msg_array = vat_json_object_add (&node, "interface_counters");
4460   vat_json_init_array (msg_array);
4461   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4462     {
4463       msg = vat_json_array_add (msg_array);
4464       vat_json_init_object (msg);
4465       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4466                                        (u8 *) counter_type_to_str (i, 0));
4467       vat_json_object_add_int (msg, "is_combined", 0);
4468       counter_array = vat_json_object_add (msg, "data");
4469       vat_json_init_array (counter_array);
4470       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4471         {
4472           packets = vam->simple_interface_counters[i][j];
4473           vat_json_array_add_uint (counter_array, packets);
4474         }
4475     }
4476   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4477     {
4478       msg = vat_json_array_add (msg_array);
4479       vat_json_init_object (msg);
4480       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4481                                        (u8 *) counter_type_to_str (i, 1));
4482       vat_json_object_add_int (msg, "is_combined", 1);
4483       counter_array = vat_json_object_add (msg, "data");
4484       vat_json_init_array (counter_array);
4485       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4486         {
4487           c = vam->combined_interface_counters[i][j];
4488           counter = vat_json_array_add (counter_array);
4489           vat_json_init_object (counter);
4490           vat_json_object_add_uint (counter, "packets", c.packets);
4491           vat_json_object_add_uint (counter, "bytes", c.bytes);
4492         }
4493     }
4494
4495   /* ip4 fib counters */
4496   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4497   vat_json_init_array (msg_array);
4498   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4499     {
4500       msg = vat_json_array_add (msg_array);
4501       vat_json_init_object (msg);
4502       vat_json_object_add_uint (msg, "vrf_id",
4503                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4504       counter_array = vat_json_object_add (msg, "c");
4505       vat_json_init_array (counter_array);
4506       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4507         {
4508           counter = vat_json_array_add (counter_array);
4509           vat_json_init_object (counter);
4510           c4 = &vam->ip4_fib_counters[i][j];
4511           vat_json_object_add_ip4 (counter, "address", c4->address);
4512           vat_json_object_add_uint (counter, "address_length",
4513                                     c4->address_length);
4514           vat_json_object_add_uint (counter, "packets", c4->packets);
4515           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4516         }
4517     }
4518
4519   /* ip6 fib counters */
4520   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4521   vat_json_init_array (msg_array);
4522   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4523     {
4524       msg = vat_json_array_add (msg_array);
4525       vat_json_init_object (msg);
4526       vat_json_object_add_uint (msg, "vrf_id",
4527                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4528       counter_array = vat_json_object_add (msg, "c");
4529       vat_json_init_array (counter_array);
4530       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4531         {
4532           counter = vat_json_array_add (counter_array);
4533           vat_json_init_object (counter);
4534           c6 = &vam->ip6_fib_counters[i][j];
4535           vat_json_object_add_ip6 (counter, "address", c6->address);
4536           vat_json_object_add_uint (counter, "address_length",
4537                                     c6->address_length);
4538           vat_json_object_add_uint (counter, "packets", c6->packets);
4539           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4540         }
4541     }
4542
4543   /* ip4 nbr counters */
4544   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4545   vat_json_init_array (msg_array);
4546   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4547     {
4548       msg = vat_json_array_add (msg_array);
4549       vat_json_init_object (msg);
4550       vat_json_object_add_uint (msg, "sw_if_index", i);
4551       counter_array = vat_json_object_add (msg, "c");
4552       vat_json_init_array (counter_array);
4553       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4554         {
4555           counter = vat_json_array_add (counter_array);
4556           vat_json_init_object (counter);
4557           n4 = &vam->ip4_nbr_counters[i][j];
4558           vat_json_object_add_ip4 (counter, "address", n4->address);
4559           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4560           vat_json_object_add_uint (counter, "packets", n4->packets);
4561           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4562         }
4563     }
4564
4565   /* ip6 nbr counters */
4566   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4567   vat_json_init_array (msg_array);
4568   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4569     {
4570       msg = vat_json_array_add (msg_array);
4571       vat_json_init_object (msg);
4572       vat_json_object_add_uint (msg, "sw_if_index", i);
4573       counter_array = vat_json_object_add (msg, "c");
4574       vat_json_init_array (counter_array);
4575       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4576         {
4577           counter = vat_json_array_add (counter_array);
4578           vat_json_init_object (counter);
4579           n6 = &vam->ip6_nbr_counters[i][j];
4580           vat_json_object_add_ip6 (counter, "address", n6->address);
4581           vat_json_object_add_uint (counter, "packets", n6->packets);
4582           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4583         }
4584     }
4585
4586   vat_json_print (vam->ofp, &node);
4587   vat_json_free (&node);
4588
4589   return 0;
4590 }
4591
4592 int
4593 exec (vat_main_t * vam)
4594 {
4595   api_main_t *am = &api_main;
4596   vl_api_cli_request_t *mp;
4597   f64 timeout;
4598   void *oldheap;
4599   u8 *cmd = 0;
4600   unformat_input_t *i = vam->input;
4601
4602   if (vec_len (i->buffer) == 0)
4603     return -1;
4604
4605   if (vam->exec_mode == 0 && unformat (i, "mode"))
4606     {
4607       vam->exec_mode = 1;
4608       return 0;
4609     }
4610   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4611     {
4612       vam->exec_mode = 0;
4613       return 0;
4614     }
4615
4616
4617   M (CLI_REQUEST, mp);
4618
4619   /*
4620    * Copy cmd into shared memory.
4621    * In order for the CLI command to work, it
4622    * must be a vector ending in \n, not a C-string ending
4623    * in \n\0.
4624    */
4625   pthread_mutex_lock (&am->vlib_rp->mutex);
4626   oldheap = svm_push_data_heap (am->vlib_rp);
4627
4628   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4629   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4630
4631   svm_pop_heap (oldheap);
4632   pthread_mutex_unlock (&am->vlib_rp->mutex);
4633
4634   mp->cmd_in_shmem = (u64) cmd;
4635   S (mp);
4636   timeout = vat_time_now (vam) + 10.0;
4637
4638   while (vat_time_now (vam) < timeout)
4639     {
4640       if (vam->result_ready == 1)
4641         {
4642           u8 *free_me;
4643           if (vam->shmem_result != NULL)
4644             print (vam->ofp, "%s", vam->shmem_result);
4645           pthread_mutex_lock (&am->vlib_rp->mutex);
4646           oldheap = svm_push_data_heap (am->vlib_rp);
4647
4648           free_me = (u8 *) vam->shmem_result;
4649           vec_free (free_me);
4650
4651           svm_pop_heap (oldheap);
4652           pthread_mutex_unlock (&am->vlib_rp->mutex);
4653           return 0;
4654         }
4655     }
4656   return -99;
4657 }
4658
4659 /*
4660  * Future replacement of exec() that passes CLI buffers directly in
4661  * the API messages instead of an additional shared memory area.
4662  */
4663 static int
4664 exec_inband (vat_main_t * vam)
4665 {
4666   vl_api_cli_inband_t *mp;
4667   unformat_input_t *i = vam->input;
4668   int ret;
4669
4670   if (vec_len (i->buffer) == 0)
4671     return -1;
4672
4673   if (vam->exec_mode == 0 && unformat (i, "mode"))
4674     {
4675       vam->exec_mode = 1;
4676       return 0;
4677     }
4678   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4679     {
4680       vam->exec_mode = 0;
4681       return 0;
4682     }
4683
4684   /*
4685    * In order for the CLI command to work, it
4686    * must be a vector ending in \n, not a C-string ending
4687    * in \n\0.
4688    */
4689   u32 len = vec_len (vam->input->buffer);
4690   M2 (CLI_INBAND, mp, len);
4691   clib_memcpy (mp->cmd, vam->input->buffer, len);
4692   mp->length = htonl (len);
4693
4694   S (mp);
4695   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4696   return ret;
4697 }
4698
4699 static int
4700 api_create_loopback (vat_main_t * vam)
4701 {
4702   unformat_input_t *i = vam->input;
4703   vl_api_create_loopback_t *mp;
4704   u8 mac_address[6];
4705   u8 mac_set = 0;
4706   int ret;
4707
4708   memset (mac_address, 0, sizeof (mac_address));
4709
4710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4711     {
4712       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4713         mac_set = 1;
4714       else
4715         break;
4716     }
4717
4718   /* Construct the API message */
4719   M (CREATE_LOOPBACK, mp);
4720   if (mac_set)
4721     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4722
4723   S (mp);
4724   W (ret);
4725   return ret;
4726 }
4727
4728 static int
4729 api_delete_loopback (vat_main_t * vam)
4730 {
4731   unformat_input_t *i = vam->input;
4732   vl_api_delete_loopback_t *mp;
4733   u32 sw_if_index = ~0;
4734   int ret;
4735
4736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4737     {
4738       if (unformat (i, "sw_if_index %d", &sw_if_index))
4739         ;
4740       else
4741         break;
4742     }
4743
4744   if (sw_if_index == ~0)
4745     {
4746       errmsg ("missing sw_if_index");
4747       return -99;
4748     }
4749
4750   /* Construct the API message */
4751   M (DELETE_LOOPBACK, mp);
4752   mp->sw_if_index = ntohl (sw_if_index);
4753
4754   S (mp);
4755   W (ret);
4756   return ret;
4757 }
4758
4759 static int
4760 api_want_stats (vat_main_t * vam)
4761 {
4762   unformat_input_t *i = vam->input;
4763   vl_api_want_stats_t *mp;
4764   int enable = -1;
4765   int ret;
4766
4767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4768     {
4769       if (unformat (i, "enable"))
4770         enable = 1;
4771       else if (unformat (i, "disable"))
4772         enable = 0;
4773       else
4774         break;
4775     }
4776
4777   if (enable == -1)
4778     {
4779       errmsg ("missing enable|disable");
4780       return -99;
4781     }
4782
4783   M (WANT_STATS, mp);
4784   mp->enable_disable = enable;
4785
4786   S (mp);
4787   W (ret);
4788   return ret;
4789 }
4790
4791 static int
4792 api_want_interface_events (vat_main_t * vam)
4793 {
4794   unformat_input_t *i = vam->input;
4795   vl_api_want_interface_events_t *mp;
4796   int enable = -1;
4797   int ret;
4798
4799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4800     {
4801       if (unformat (i, "enable"))
4802         enable = 1;
4803       else if (unformat (i, "disable"))
4804         enable = 0;
4805       else
4806         break;
4807     }
4808
4809   if (enable == -1)
4810     {
4811       errmsg ("missing enable|disable");
4812       return -99;
4813     }
4814
4815   M (WANT_INTERFACE_EVENTS, mp);
4816   mp->enable_disable = enable;
4817
4818   vam->interface_event_display = enable;
4819
4820   S (mp);
4821   W (ret);
4822   return ret;
4823 }
4824
4825
4826 /* Note: non-static, called once to set up the initial intfc table */
4827 int
4828 api_sw_interface_dump (vat_main_t * vam)
4829 {
4830   vl_api_sw_interface_dump_t *mp;
4831   vl_api_control_ping_t *mp_ping;
4832   hash_pair_t *p;
4833   name_sort_t *nses = 0, *ns;
4834   sw_interface_subif_t *sub = NULL;
4835   int ret;
4836
4837   /* Toss the old name table */
4838   /* *INDENT-OFF* */
4839   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4840   ({
4841     vec_add2 (nses, ns, 1);
4842     ns->name = (u8 *)(p->key);
4843     ns->value = (u32) p->value[0];
4844   }));
4845   /* *INDENT-ON* */
4846
4847   hash_free (vam->sw_if_index_by_interface_name);
4848
4849   vec_foreach (ns, nses) vec_free (ns->name);
4850
4851   vec_free (nses);
4852
4853   vec_foreach (sub, vam->sw_if_subif_table)
4854   {
4855     vec_free (sub->interface_name);
4856   }
4857   vec_free (vam->sw_if_subif_table);
4858
4859   /* recreate the interface name hash table */
4860   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4861
4862   /* Get list of ethernets */
4863   M (SW_INTERFACE_DUMP, mp);
4864   mp->name_filter_valid = 1;
4865   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4866   S (mp);
4867
4868   /* and local / loopback interfaces */
4869   M (SW_INTERFACE_DUMP, mp);
4870   mp->name_filter_valid = 1;
4871   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4872   S (mp);
4873
4874   /* and packet-generator interfaces */
4875   M (SW_INTERFACE_DUMP, mp);
4876   mp->name_filter_valid = 1;
4877   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4878   S (mp);
4879
4880   /* and vxlan-gpe tunnel interfaces */
4881   M (SW_INTERFACE_DUMP, mp);
4882   mp->name_filter_valid = 1;
4883   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4884            sizeof (mp->name_filter) - 1);
4885   S (mp);
4886
4887   /* and vxlan tunnel interfaces */
4888   M (SW_INTERFACE_DUMP, mp);
4889   mp->name_filter_valid = 1;
4890   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4891   S (mp);
4892
4893   /* and host (af_packet) interfaces */
4894   M (SW_INTERFACE_DUMP, mp);
4895   mp->name_filter_valid = 1;
4896   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4897   S (mp);
4898
4899   /* and l2tpv3 tunnel interfaces */
4900   M (SW_INTERFACE_DUMP, mp);
4901   mp->name_filter_valid = 1;
4902   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4903            sizeof (mp->name_filter) - 1);
4904   S (mp);
4905
4906   /* and GRE tunnel interfaces */
4907   M (SW_INTERFACE_DUMP, mp);
4908   mp->name_filter_valid = 1;
4909   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4910   S (mp);
4911
4912   /* and LISP-GPE interfaces */
4913   M (SW_INTERFACE_DUMP, mp);
4914   mp->name_filter_valid = 1;
4915   strncpy ((char *) mp->name_filter, "lisp_gpe",
4916            sizeof (mp->name_filter) - 1);
4917   S (mp);
4918
4919   /* and IPSEC tunnel interfaces */
4920   M (SW_INTERFACE_DUMP, mp);
4921   mp->name_filter_valid = 1;
4922   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4923   S (mp);
4924
4925   /* Use a control ping for synchronization */
4926   M (CONTROL_PING, mp_ping);
4927   S (mp_ping);
4928
4929   W (ret);
4930   return ret;
4931 }
4932
4933 static int
4934 api_sw_interface_set_flags (vat_main_t * vam)
4935 {
4936   unformat_input_t *i = vam->input;
4937   vl_api_sw_interface_set_flags_t *mp;
4938   u32 sw_if_index;
4939   u8 sw_if_index_set = 0;
4940   u8 admin_up = 0, link_up = 0;
4941   int ret;
4942
4943   /* Parse args required to build the message */
4944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4945     {
4946       if (unformat (i, "admin-up"))
4947         admin_up = 1;
4948       else if (unformat (i, "admin-down"))
4949         admin_up = 0;
4950       else if (unformat (i, "link-up"))
4951         link_up = 1;
4952       else if (unformat (i, "link-down"))
4953         link_up = 0;
4954       else
4955         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4956         sw_if_index_set = 1;
4957       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4958         sw_if_index_set = 1;
4959       else
4960         break;
4961     }
4962
4963   if (sw_if_index_set == 0)
4964     {
4965       errmsg ("missing interface name or sw_if_index");
4966       return -99;
4967     }
4968
4969   /* Construct the API message */
4970   M (SW_INTERFACE_SET_FLAGS, mp);
4971   mp->sw_if_index = ntohl (sw_if_index);
4972   mp->admin_up_down = admin_up;
4973   mp->link_up_down = link_up;
4974
4975   /* send it... */
4976   S (mp);
4977
4978   /* Wait for a reply, return the good/bad news... */
4979   W (ret);
4980   return ret;
4981 }
4982
4983 static int
4984 api_sw_interface_clear_stats (vat_main_t * vam)
4985 {
4986   unformat_input_t *i = vam->input;
4987   vl_api_sw_interface_clear_stats_t *mp;
4988   u32 sw_if_index;
4989   u8 sw_if_index_set = 0;
4990   int ret;
4991
4992   /* Parse args required to build the message */
4993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4994     {
4995       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4996         sw_if_index_set = 1;
4997       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4998         sw_if_index_set = 1;
4999       else
5000         break;
5001     }
5002
5003   /* Construct the API message */
5004   M (SW_INTERFACE_CLEAR_STATS, mp);
5005
5006   if (sw_if_index_set == 1)
5007     mp->sw_if_index = ntohl (sw_if_index);
5008   else
5009     mp->sw_if_index = ~0;
5010
5011   /* send it... */
5012   S (mp);
5013
5014   /* Wait for a reply, return the good/bad news... */
5015   W (ret);
5016   return ret;
5017 }
5018
5019 #if DPDK >0
5020 static int
5021 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
5022 {
5023   unformat_input_t *i = vam->input;
5024   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
5025   u32 sw_if_index;
5026   u8 sw_if_index_set = 0;
5027   u32 subport;
5028   u8 subport_set = 0;
5029   u32 pipe;
5030   u8 pipe_set = 0;
5031   u32 profile;
5032   u8 profile_set = 0;
5033   int ret;
5034
5035   /* Parse args required to build the message */
5036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5037     {
5038       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5039         sw_if_index_set = 1;
5040       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5041         sw_if_index_set = 1;
5042       else if (unformat (i, "subport %u", &subport))
5043         subport_set = 1;
5044       else
5045         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5046         sw_if_index_set = 1;
5047       else if (unformat (i, "pipe %u", &pipe))
5048         pipe_set = 1;
5049       else if (unformat (i, "profile %u", &profile))
5050         profile_set = 1;
5051       else
5052         break;
5053     }
5054
5055   if (sw_if_index_set == 0)
5056     {
5057       errmsg ("missing interface name or sw_if_index");
5058       return -99;
5059     }
5060
5061   if (subport_set == 0)
5062     {
5063       errmsg ("missing subport ");
5064       return -99;
5065     }
5066
5067   if (pipe_set == 0)
5068     {
5069       errmsg ("missing pipe");
5070       return -99;
5071     }
5072
5073   if (profile_set == 0)
5074     {
5075       errmsg ("missing profile");
5076       return -99;
5077     }
5078
5079   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, mp);
5080
5081   mp->sw_if_index = ntohl (sw_if_index);
5082   mp->subport = ntohl (subport);
5083   mp->pipe = ntohl (pipe);
5084   mp->profile = ntohl (profile);
5085
5086
5087   S (mp);
5088   W (ret);
5089   return ret;
5090 }
5091
5092 static int
5093 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
5094 {
5095   unformat_input_t *i = vam->input;
5096   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
5097   u32 sw_if_index;
5098   u8 sw_if_index_set = 0;
5099   u32 subport;
5100   u8 subport_set = 0;
5101   u32 tb_rate = 1250000000;     /* 10GbE */
5102   u32 tb_size = 1000000;
5103   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
5104   u32 tc_period = 10;
5105   int ret;
5106
5107   /* Parse args required to build the message */
5108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5109     {
5110       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5111         sw_if_index_set = 1;
5112       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5113         sw_if_index_set = 1;
5114       else if (unformat (i, "subport %u", &subport))
5115         subport_set = 1;
5116       else
5117         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5118         sw_if_index_set = 1;
5119       else if (unformat (i, "rate %u", &tb_rate))
5120         {
5121           u32 tc_id;
5122
5123           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
5124                tc_id++)
5125             tc_rate[tc_id] = tb_rate;
5126         }
5127       else if (unformat (i, "bktsize %u", &tb_size))
5128         ;
5129       else if (unformat (i, "tc0 %u", &tc_rate[0]))
5130         ;
5131       else if (unformat (i, "tc1 %u", &tc_rate[1]))
5132         ;
5133       else if (unformat (i, "tc2 %u", &tc_rate[2]))
5134         ;
5135       else if (unformat (i, "tc3 %u", &tc_rate[3]))
5136         ;
5137       else if (unformat (i, "period %u", &tc_period))
5138         ;
5139       else
5140         break;
5141     }
5142
5143   if (sw_if_index_set == 0)
5144     {
5145       errmsg ("missing interface name or sw_if_index");
5146       return -99;
5147     }
5148
5149   if (subport_set == 0)
5150     {
5151       errmsg ("missing subport ");
5152       return -99;
5153     }
5154
5155   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, mp);
5156
5157   mp->sw_if_index = ntohl (sw_if_index);
5158   mp->subport = ntohl (subport);
5159   mp->tb_rate = ntohl (tb_rate);
5160   mp->tb_size = ntohl (tb_size);
5161   mp->tc_rate[0] = ntohl (tc_rate[0]);
5162   mp->tc_rate[1] = ntohl (tc_rate[1]);
5163   mp->tc_rate[2] = ntohl (tc_rate[2]);
5164   mp->tc_rate[3] = ntohl (tc_rate[3]);
5165   mp->tc_period = ntohl (tc_period);
5166
5167   S (mp);
5168   W (ret);
5169   return ret;
5170 }
5171
5172 static int
5173 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
5174 {
5175   unformat_input_t *i = vam->input;
5176   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
5177   u32 sw_if_index;
5178   u8 sw_if_index_set = 0;
5179   u8 entry_set = 0;
5180   u8 tc_set = 0;
5181   u8 queue_set = 0;
5182   u32 entry, tc, queue;
5183   int ret;
5184
5185   /* Parse args required to build the message */
5186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5187     {
5188       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
5189         sw_if_index_set = 1;
5190       else if (unformat (i, "sw_if_index %u", &sw_if_index))
5191         sw_if_index_set = 1;
5192       else if (unformat (i, "entry %d", &entry))
5193         entry_set = 1;
5194       else if (unformat (i, "tc %d", &tc))
5195         tc_set = 1;
5196       else if (unformat (i, "queue %d", &queue))
5197         queue_set = 1;
5198       else
5199         break;
5200     }
5201
5202   if (sw_if_index_set == 0)
5203     {
5204       errmsg ("missing interface name or sw_if_index");
5205       return -99;
5206     }
5207
5208   if (entry_set == 0)
5209     {
5210       errmsg ("missing entry ");
5211       return -99;
5212     }
5213
5214   if (tc_set == 0)
5215     {
5216       errmsg ("missing traffic class ");
5217       return -99;
5218     }
5219
5220   if (queue_set == 0)
5221     {
5222       errmsg ("missing queue ");
5223       return -99;
5224     }
5225
5226   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, mp);
5227
5228   mp->sw_if_index = ntohl (sw_if_index);
5229   mp->entry = ntohl (entry);
5230   mp->tc = ntohl (tc);
5231   mp->queue = ntohl (queue);
5232
5233   S (mp);
5234   W (ret);
5235   return ret;
5236 }
5237 #endif
5238
5239 static int
5240 api_sw_interface_add_del_address (vat_main_t * vam)
5241 {
5242   unformat_input_t *i = vam->input;
5243   vl_api_sw_interface_add_del_address_t *mp;
5244   u32 sw_if_index;
5245   u8 sw_if_index_set = 0;
5246   u8 is_add = 1, del_all = 0;
5247   u32 address_length = 0;
5248   u8 v4_address_set = 0;
5249   u8 v6_address_set = 0;
5250   ip4_address_t v4address;
5251   ip6_address_t v6address;
5252   int ret;
5253
5254   /* Parse args required to build the message */
5255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5256     {
5257       if (unformat (i, "del-all"))
5258         del_all = 1;
5259       else if (unformat (i, "del"))
5260         is_add = 0;
5261       else
5262         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5263         sw_if_index_set = 1;
5264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5265         sw_if_index_set = 1;
5266       else if (unformat (i, "%U/%d",
5267                          unformat_ip4_address, &v4address, &address_length))
5268         v4_address_set = 1;
5269       else if (unformat (i, "%U/%d",
5270                          unformat_ip6_address, &v6address, &address_length))
5271         v6_address_set = 1;
5272       else
5273         break;
5274     }
5275
5276   if (sw_if_index_set == 0)
5277     {
5278       errmsg ("missing interface name or sw_if_index");
5279       return -99;
5280     }
5281   if (v4_address_set && v6_address_set)
5282     {
5283       errmsg ("both v4 and v6 addresses set");
5284       return -99;
5285     }
5286   if (!v4_address_set && !v6_address_set && !del_all)
5287     {
5288       errmsg ("no addresses set");
5289       return -99;
5290     }
5291
5292   /* Construct the API message */
5293   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5294
5295   mp->sw_if_index = ntohl (sw_if_index);
5296   mp->is_add = is_add;
5297   mp->del_all = del_all;
5298   if (v6_address_set)
5299     {
5300       mp->is_ipv6 = 1;
5301       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5302     }
5303   else
5304     {
5305       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5306     }
5307   mp->address_length = address_length;
5308
5309   /* send it... */
5310   S (mp);
5311
5312   /* Wait for a reply, return good/bad news  */
5313   W (ret);
5314   return ret;
5315 }
5316
5317 static int
5318 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5319 {
5320   unformat_input_t *i = vam->input;
5321   vl_api_sw_interface_set_mpls_enable_t *mp;
5322   u32 sw_if_index;
5323   u8 sw_if_index_set = 0;
5324   u8 enable = 1;
5325   int ret;
5326
5327   /* Parse args required to build the message */
5328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5329     {
5330       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5331         sw_if_index_set = 1;
5332       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5333         sw_if_index_set = 1;
5334       else if (unformat (i, "disable"))
5335         enable = 0;
5336       else if (unformat (i, "dis"))
5337         enable = 0;
5338       else
5339         break;
5340     }
5341
5342   if (sw_if_index_set == 0)
5343     {
5344       errmsg ("missing interface name or sw_if_index");
5345       return -99;
5346     }
5347
5348   /* Construct the API message */
5349   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5350
5351   mp->sw_if_index = ntohl (sw_if_index);
5352   mp->enable = enable;
5353
5354   /* send it... */
5355   S (mp);
5356
5357   /* Wait for a reply... */
5358   W (ret);
5359   return ret;
5360 }
5361
5362 static int
5363 api_sw_interface_set_table (vat_main_t * vam)
5364 {
5365   unformat_input_t *i = vam->input;
5366   vl_api_sw_interface_set_table_t *mp;
5367   u32 sw_if_index, vrf_id = 0;
5368   u8 sw_if_index_set = 0;
5369   u8 is_ipv6 = 0;
5370   int ret;
5371
5372   /* Parse args required to build the message */
5373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5374     {
5375       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5376         sw_if_index_set = 1;
5377       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5378         sw_if_index_set = 1;
5379       else if (unformat (i, "vrf %d", &vrf_id))
5380         ;
5381       else if (unformat (i, "ipv6"))
5382         is_ipv6 = 1;
5383       else
5384         break;
5385     }
5386
5387   if (sw_if_index_set == 0)
5388     {
5389       errmsg ("missing interface name or sw_if_index");
5390       return -99;
5391     }
5392
5393   /* Construct the API message */
5394   M (SW_INTERFACE_SET_TABLE, mp);
5395
5396   mp->sw_if_index = ntohl (sw_if_index);
5397   mp->is_ipv6 = is_ipv6;
5398   mp->vrf_id = ntohl (vrf_id);
5399
5400   /* send it... */
5401   S (mp);
5402
5403   /* Wait for a reply... */
5404   W (ret);
5405   return ret;
5406 }
5407
5408 static void vl_api_sw_interface_get_table_reply_t_handler
5409   (vl_api_sw_interface_get_table_reply_t * mp)
5410 {
5411   vat_main_t *vam = &vat_main;
5412
5413   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5414
5415   vam->retval = ntohl (mp->retval);
5416   vam->result_ready = 1;
5417
5418 }
5419
5420 static void vl_api_sw_interface_get_table_reply_t_handler_json
5421   (vl_api_sw_interface_get_table_reply_t * mp)
5422 {
5423   vat_main_t *vam = &vat_main;
5424   vat_json_node_t node;
5425
5426   vat_json_init_object (&node);
5427   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5428   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5429
5430   vat_json_print (vam->ofp, &node);
5431   vat_json_free (&node);
5432
5433   vam->retval = ntohl (mp->retval);
5434   vam->result_ready = 1;
5435 }
5436
5437 static int
5438 api_sw_interface_get_table (vat_main_t * vam)
5439 {
5440   unformat_input_t *i = vam->input;
5441   vl_api_sw_interface_get_table_t *mp;
5442   u32 sw_if_index;
5443   u8 sw_if_index_set = 0;
5444   u8 is_ipv6 = 0;
5445   int ret;
5446
5447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5448     {
5449       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5450         sw_if_index_set = 1;
5451       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5452         sw_if_index_set = 1;
5453       else if (unformat (i, "ipv6"))
5454         is_ipv6 = 1;
5455       else
5456         break;
5457     }
5458
5459   if (sw_if_index_set == 0)
5460     {
5461       errmsg ("missing interface name or sw_if_index");
5462       return -99;
5463     }
5464
5465   M (SW_INTERFACE_GET_TABLE, mp);
5466   mp->sw_if_index = htonl (sw_if_index);
5467   mp->is_ipv6 = is_ipv6;
5468
5469   S (mp);
5470   W (ret);
5471   return ret;
5472 }
5473
5474 static int
5475 api_sw_interface_set_vpath (vat_main_t * vam)
5476 {
5477   unformat_input_t *i = vam->input;
5478   vl_api_sw_interface_set_vpath_t *mp;
5479   u32 sw_if_index = 0;
5480   u8 sw_if_index_set = 0;
5481   u8 is_enable = 0;
5482   int ret;
5483
5484   /* Parse args required to build the message */
5485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5486     {
5487       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5488         sw_if_index_set = 1;
5489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5490         sw_if_index_set = 1;
5491       else if (unformat (i, "enable"))
5492         is_enable = 1;
5493       else if (unformat (i, "disable"))
5494         is_enable = 0;
5495       else
5496         break;
5497     }
5498
5499   if (sw_if_index_set == 0)
5500     {
5501       errmsg ("missing interface name or sw_if_index");
5502       return -99;
5503     }
5504
5505   /* Construct the API message */
5506   M (SW_INTERFACE_SET_VPATH, mp);
5507
5508   mp->sw_if_index = ntohl (sw_if_index);
5509   mp->enable = is_enable;
5510
5511   /* send it... */
5512   S (mp);
5513
5514   /* Wait for a reply... */
5515   W (ret);
5516   return ret;
5517 }
5518
5519 static int
5520 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5521 {
5522   unformat_input_t *i = vam->input;
5523   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5524   u32 sw_if_index = 0;
5525   u8 sw_if_index_set = 0;
5526   u8 is_enable = 1;
5527   u8 is_ipv6 = 0;
5528   int ret;
5529
5530   /* Parse args required to build the message */
5531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5532     {
5533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5534         sw_if_index_set = 1;
5535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5536         sw_if_index_set = 1;
5537       else if (unformat (i, "enable"))
5538         is_enable = 1;
5539       else if (unformat (i, "disable"))
5540         is_enable = 0;
5541       else if (unformat (i, "ip4"))
5542         is_ipv6 = 0;
5543       else if (unformat (i, "ip6"))
5544         is_ipv6 = 1;
5545       else
5546         break;
5547     }
5548
5549   if (sw_if_index_set == 0)
5550     {
5551       errmsg ("missing interface name or sw_if_index");
5552       return -99;
5553     }
5554
5555   /* Construct the API message */
5556   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5557
5558   mp->sw_if_index = ntohl (sw_if_index);
5559   mp->enable = is_enable;
5560   mp->is_ipv6 = is_ipv6;
5561
5562   /* send it... */
5563   S (mp);
5564
5565   /* Wait for a reply... */
5566   W (ret);
5567   return ret;
5568 }
5569
5570 static int
5571 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5572 {
5573   unformat_input_t *i = vam->input;
5574   vl_api_sw_interface_set_l2_xconnect_t *mp;
5575   u32 rx_sw_if_index;
5576   u8 rx_sw_if_index_set = 0;
5577   u32 tx_sw_if_index;
5578   u8 tx_sw_if_index_set = 0;
5579   u8 enable = 1;
5580   int ret;
5581
5582   /* Parse args required to build the message */
5583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5584     {
5585       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5586         rx_sw_if_index_set = 1;
5587       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5588         tx_sw_if_index_set = 1;
5589       else if (unformat (i, "rx"))
5590         {
5591           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5592             {
5593               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5594                             &rx_sw_if_index))
5595                 rx_sw_if_index_set = 1;
5596             }
5597           else
5598             break;
5599         }
5600       else if (unformat (i, "tx"))
5601         {
5602           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5603             {
5604               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5605                             &tx_sw_if_index))
5606                 tx_sw_if_index_set = 1;
5607             }
5608           else
5609             break;
5610         }
5611       else if (unformat (i, "enable"))
5612         enable = 1;
5613       else if (unformat (i, "disable"))
5614         enable = 0;
5615       else
5616         break;
5617     }
5618
5619   if (rx_sw_if_index_set == 0)
5620     {
5621       errmsg ("missing rx interface name or rx_sw_if_index");
5622       return -99;
5623     }
5624
5625   if (enable && (tx_sw_if_index_set == 0))
5626     {
5627       errmsg ("missing tx interface name or tx_sw_if_index");
5628       return -99;
5629     }
5630
5631   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5632
5633   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5634   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5635   mp->enable = enable;
5636
5637   S (mp);
5638   W (ret);
5639   return ret;
5640 }
5641
5642 static int
5643 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5644 {
5645   unformat_input_t *i = vam->input;
5646   vl_api_sw_interface_set_l2_bridge_t *mp;
5647   u32 rx_sw_if_index;
5648   u8 rx_sw_if_index_set = 0;
5649   u32 bd_id;
5650   u8 bd_id_set = 0;
5651   u8 bvi = 0;
5652   u32 shg = 0;
5653   u8 enable = 1;
5654   int ret;
5655
5656   /* Parse args required to build the message */
5657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5658     {
5659       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5660         rx_sw_if_index_set = 1;
5661       else if (unformat (i, "bd_id %d", &bd_id))
5662         bd_id_set = 1;
5663       else
5664         if (unformat
5665             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5666         rx_sw_if_index_set = 1;
5667       else if (unformat (i, "shg %d", &shg))
5668         ;
5669       else if (unformat (i, "bvi"))
5670         bvi = 1;
5671       else if (unformat (i, "enable"))
5672         enable = 1;
5673       else if (unformat (i, "disable"))
5674         enable = 0;
5675       else
5676         break;
5677     }
5678
5679   if (rx_sw_if_index_set == 0)
5680     {
5681       errmsg ("missing rx interface name or sw_if_index");
5682       return -99;
5683     }
5684
5685   if (enable && (bd_id_set == 0))
5686     {
5687       errmsg ("missing bridge domain");
5688       return -99;
5689     }
5690
5691   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5692
5693   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5694   mp->bd_id = ntohl (bd_id);
5695   mp->shg = (u8) shg;
5696   mp->bvi = bvi;
5697   mp->enable = enable;
5698
5699   S (mp);
5700   W (ret);
5701   return ret;
5702 }
5703
5704 static int
5705 api_bridge_domain_dump (vat_main_t * vam)
5706 {
5707   unformat_input_t *i = vam->input;
5708   vl_api_bridge_domain_dump_t *mp;
5709   vl_api_control_ping_t *mp_ping;
5710   u32 bd_id = ~0;
5711   int ret;
5712
5713   /* Parse args required to build the message */
5714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5715     {
5716       if (unformat (i, "bd_id %d", &bd_id))
5717         ;
5718       else
5719         break;
5720     }
5721
5722   M (BRIDGE_DOMAIN_DUMP, mp);
5723   mp->bd_id = ntohl (bd_id);
5724   S (mp);
5725
5726   /* Use a control ping for synchronization */
5727   M (CONTROL_PING, mp_ping);
5728   S (mp_ping);
5729
5730   W (ret);
5731   return ret;
5732 }
5733
5734 static int
5735 api_bridge_domain_add_del (vat_main_t * vam)
5736 {
5737   unformat_input_t *i = vam->input;
5738   vl_api_bridge_domain_add_del_t *mp;
5739   u32 bd_id = ~0;
5740   u8 is_add = 1;
5741   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5742   u32 mac_age = 0;
5743   int ret;
5744
5745   /* Parse args required to build the message */
5746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5747     {
5748       if (unformat (i, "bd_id %d", &bd_id))
5749         ;
5750       else if (unformat (i, "flood %d", &flood))
5751         ;
5752       else if (unformat (i, "uu-flood %d", &uu_flood))
5753         ;
5754       else if (unformat (i, "forward %d", &forward))
5755         ;
5756       else if (unformat (i, "learn %d", &learn))
5757         ;
5758       else if (unformat (i, "arp-term %d", &arp_term))
5759         ;
5760       else if (unformat (i, "mac-age %d", &mac_age))
5761         ;
5762       else if (unformat (i, "del"))
5763         {
5764           is_add = 0;
5765           flood = uu_flood = forward = learn = 0;
5766         }
5767       else
5768         break;
5769     }
5770
5771   if (bd_id == ~0)
5772     {
5773       errmsg ("missing bridge domain");
5774       return -99;
5775     }
5776
5777   if (mac_age > 255)
5778     {
5779       errmsg ("mac age must be less than 256 ");
5780       return -99;
5781     }
5782
5783   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5784
5785   mp->bd_id = ntohl (bd_id);
5786   mp->flood = flood;
5787   mp->uu_flood = uu_flood;
5788   mp->forward = forward;
5789   mp->learn = learn;
5790   mp->arp_term = arp_term;
5791   mp->is_add = is_add;
5792   mp->mac_age = (u8) mac_age;
5793
5794   S (mp);
5795   W (ret);
5796   return ret;
5797 }
5798
5799 static int
5800 api_l2fib_add_del (vat_main_t * vam)
5801 {
5802   unformat_input_t *i = vam->input;
5803   vl_api_l2fib_add_del_t *mp;
5804   f64 timeout;
5805   u64 mac = 0;
5806   u8 mac_set = 0;
5807   u32 bd_id;
5808   u8 bd_id_set = 0;
5809   u32 sw_if_index = ~0;
5810   u8 sw_if_index_set = 0;
5811   u8 is_add = 1;
5812   u8 static_mac = 0;
5813   u8 filter_mac = 0;
5814   u8 bvi_mac = 0;
5815   int count = 1;
5816   f64 before = 0;
5817   int j;
5818
5819   /* Parse args required to build the message */
5820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5821     {
5822       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5823         mac_set = 1;
5824       else if (unformat (i, "bd_id %d", &bd_id))
5825         bd_id_set = 1;
5826       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5827         sw_if_index_set = 1;
5828       else if (unformat (i, "sw_if"))
5829         {
5830           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5831             {
5832               if (unformat
5833                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5834                 sw_if_index_set = 1;
5835             }
5836           else
5837             break;
5838         }
5839       else if (unformat (i, "static"))
5840         static_mac = 1;
5841       else if (unformat (i, "filter"))
5842         {
5843           filter_mac = 1;
5844           static_mac = 1;
5845         }
5846       else if (unformat (i, "bvi"))
5847         {
5848           bvi_mac = 1;
5849           static_mac = 1;
5850         }
5851       else if (unformat (i, "del"))
5852         is_add = 0;
5853       else if (unformat (i, "count %d", &count))
5854         ;
5855       else
5856         break;
5857     }
5858
5859   if (mac_set == 0)
5860     {
5861       errmsg ("missing mac address");
5862       return -99;
5863     }
5864
5865   if (bd_id_set == 0)
5866     {
5867       errmsg ("missing bridge domain");
5868       return -99;
5869     }
5870
5871   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5872     {
5873       errmsg ("missing interface name or sw_if_index");
5874       return -99;
5875     }
5876
5877   if (count > 1)
5878     {
5879       /* Turn on async mode */
5880       vam->async_mode = 1;
5881       vam->async_errors = 0;
5882       before = vat_time_now (vam);
5883     }
5884
5885   for (j = 0; j < count; j++)
5886     {
5887       M (L2FIB_ADD_DEL, mp);
5888
5889       mp->mac = mac;
5890       mp->bd_id = ntohl (bd_id);
5891       mp->is_add = is_add;
5892
5893       if (is_add)
5894         {
5895           mp->sw_if_index = ntohl (sw_if_index);
5896           mp->static_mac = static_mac;
5897           mp->filter_mac = filter_mac;
5898           mp->bvi_mac = bvi_mac;
5899         }
5900       increment_mac_address (&mac);
5901       /* send it... */
5902       S (mp);
5903     }
5904
5905   if (count > 1)
5906     {
5907       vl_api_control_ping_t *mp_ping;
5908       f64 after;
5909
5910       /* Shut off async mode */
5911       vam->async_mode = 0;
5912
5913       M (CONTROL_PING, mp_ping);
5914       S (mp_ping);
5915
5916       timeout = vat_time_now (vam) + 1.0;
5917       while (vat_time_now (vam) < timeout)
5918         if (vam->result_ready == 1)
5919           goto out;
5920       vam->retval = -99;
5921
5922     out:
5923       if (vam->retval == -99)
5924         errmsg ("timeout");
5925
5926       if (vam->async_errors > 0)
5927         {
5928           errmsg ("%d asynchronous errors", vam->async_errors);
5929           vam->retval = -98;
5930         }
5931       vam->async_errors = 0;
5932       after = vat_time_now (vam);
5933
5934       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5935              count, after - before, count / (after - before));
5936     }
5937   else
5938     {
5939       int ret;
5940
5941       /* Wait for a reply... */
5942       W (ret);
5943       return ret;
5944     }
5945   /* Return the good/bad news */
5946   return (vam->retval);
5947 }
5948
5949 static int
5950 api_l2_flags (vat_main_t * vam)
5951 {
5952   unformat_input_t *i = vam->input;
5953   vl_api_l2_flags_t *mp;
5954   u32 sw_if_index;
5955   u32 feature_bitmap = 0;
5956   u8 sw_if_index_set = 0;
5957   int ret;
5958
5959   /* Parse args required to build the message */
5960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5961     {
5962       if (unformat (i, "sw_if_index %d", &sw_if_index))
5963         sw_if_index_set = 1;
5964       else if (unformat (i, "sw_if"))
5965         {
5966           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5967             {
5968               if (unformat
5969                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5970                 sw_if_index_set = 1;
5971             }
5972           else
5973             break;
5974         }
5975       else if (unformat (i, "learn"))
5976         feature_bitmap |= L2INPUT_FEAT_LEARN;
5977       else if (unformat (i, "forward"))
5978         feature_bitmap |= L2INPUT_FEAT_FWD;
5979       else if (unformat (i, "flood"))
5980         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5981       else if (unformat (i, "uu-flood"))
5982         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5983       else
5984         break;
5985     }
5986
5987   if (sw_if_index_set == 0)
5988     {
5989       errmsg ("missing interface name or sw_if_index");
5990       return -99;
5991     }
5992
5993   M (L2_FLAGS, mp);
5994
5995   mp->sw_if_index = ntohl (sw_if_index);
5996   mp->feature_bitmap = ntohl (feature_bitmap);
5997
5998   S (mp);
5999   W (ret);
6000   return ret;
6001 }
6002
6003 static int
6004 api_bridge_flags (vat_main_t * vam)
6005 {
6006   unformat_input_t *i = vam->input;
6007   vl_api_bridge_flags_t *mp;
6008   u32 bd_id;
6009   u8 bd_id_set = 0;
6010   u8 is_set = 1;
6011   u32 flags = 0;
6012   int ret;
6013
6014   /* Parse args required to build the message */
6015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6016     {
6017       if (unformat (i, "bd_id %d", &bd_id))
6018         bd_id_set = 1;
6019       else if (unformat (i, "learn"))
6020         flags |= L2_LEARN;
6021       else if (unformat (i, "forward"))
6022         flags |= L2_FWD;
6023       else if (unformat (i, "flood"))
6024         flags |= L2_FLOOD;
6025       else if (unformat (i, "uu-flood"))
6026         flags |= L2_UU_FLOOD;
6027       else if (unformat (i, "arp-term"))
6028         flags |= L2_ARP_TERM;
6029       else if (unformat (i, "off"))
6030         is_set = 0;
6031       else if (unformat (i, "disable"))
6032         is_set = 0;
6033       else
6034         break;
6035     }
6036
6037   if (bd_id_set == 0)
6038     {
6039       errmsg ("missing bridge domain");
6040       return -99;
6041     }
6042
6043   M (BRIDGE_FLAGS, mp);
6044
6045   mp->bd_id = ntohl (bd_id);
6046   mp->feature_bitmap = ntohl (flags);
6047   mp->is_set = is_set;
6048
6049   S (mp);
6050   W (ret);
6051   return ret;
6052 }
6053
6054 static int
6055 api_bd_ip_mac_add_del (vat_main_t * vam)
6056 {
6057   unformat_input_t *i = vam->input;
6058   vl_api_bd_ip_mac_add_del_t *mp;
6059   u32 bd_id;
6060   u8 is_ipv6 = 0;
6061   u8 is_add = 1;
6062   u8 bd_id_set = 0;
6063   u8 ip_set = 0;
6064   u8 mac_set = 0;
6065   ip4_address_t v4addr;
6066   ip6_address_t v6addr;
6067   u8 macaddr[6];
6068   int ret;
6069
6070
6071   /* Parse args required to build the message */
6072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6073     {
6074       if (unformat (i, "bd_id %d", &bd_id))
6075         {
6076           bd_id_set++;
6077         }
6078       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6079         {
6080           ip_set++;
6081         }
6082       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6083         {
6084           ip_set++;
6085           is_ipv6++;
6086         }
6087       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6088         {
6089           mac_set++;
6090         }
6091       else if (unformat (i, "del"))
6092         is_add = 0;
6093       else
6094         break;
6095     }
6096
6097   if (bd_id_set == 0)
6098     {
6099       errmsg ("missing bridge domain");
6100       return -99;
6101     }
6102   else if (ip_set == 0)
6103     {
6104       errmsg ("missing IP address");
6105       return -99;
6106     }
6107   else if (mac_set == 0)
6108     {
6109       errmsg ("missing MAC address");
6110       return -99;
6111     }
6112
6113   M (BD_IP_MAC_ADD_DEL, mp);
6114
6115   mp->bd_id = ntohl (bd_id);
6116   mp->is_ipv6 = is_ipv6;
6117   mp->is_add = is_add;
6118   if (is_ipv6)
6119     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6120   else
6121     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6122   clib_memcpy (mp->mac_address, macaddr, 6);
6123   S (mp);
6124   W (ret);
6125   return ret;
6126 }
6127
6128 static int
6129 api_tap_connect (vat_main_t * vam)
6130 {
6131   unformat_input_t *i = vam->input;
6132   vl_api_tap_connect_t *mp;
6133   u8 mac_address[6];
6134   u8 random_mac = 1;
6135   u8 name_set = 0;
6136   u8 *tap_name;
6137   u8 *tag = 0;
6138   ip4_address_t ip4_address;
6139   u32 ip4_mask_width;
6140   int ip4_address_set = 0;
6141   ip6_address_t ip6_address;
6142   u32 ip6_mask_width;
6143   int ip6_address_set = 0;
6144   int ret;
6145
6146   memset (mac_address, 0, sizeof (mac_address));
6147
6148   /* Parse args required to build the message */
6149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6150     {
6151       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6152         {
6153           random_mac = 0;
6154         }
6155       else if (unformat (i, "random-mac"))
6156         random_mac = 1;
6157       else if (unformat (i, "tapname %s", &tap_name))
6158         name_set = 1;
6159       else if (unformat (i, "tag %s", &tag))
6160         ;
6161       else if (unformat (i, "address %U/%d",
6162                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6163         ip4_address_set = 1;
6164       else if (unformat (i, "address %U/%d",
6165                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6166         ip6_address_set = 1;
6167       else
6168         break;
6169     }
6170
6171   if (name_set == 0)
6172     {
6173       errmsg ("missing tap name");
6174       return -99;
6175     }
6176   if (vec_len (tap_name) > 63)
6177     {
6178       errmsg ("tap name too long");
6179       return -99;
6180     }
6181   vec_add1 (tap_name, 0);
6182
6183   if (vec_len (tag) > 63)
6184     {
6185       errmsg ("tag too long");
6186       return -99;
6187     }
6188
6189   /* Construct the API message */
6190   M (TAP_CONNECT, mp);
6191
6192   mp->use_random_mac = random_mac;
6193   clib_memcpy (mp->mac_address, mac_address, 6);
6194   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6195   if (tag)
6196     clib_memcpy (mp->tag, tag, vec_len (tag));
6197
6198   if (ip4_address_set)
6199     {
6200       mp->ip4_address_set = 1;
6201       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6202       mp->ip4_mask_width = ip4_mask_width;
6203     }
6204   if (ip6_address_set)
6205     {
6206       mp->ip6_address_set = 1;
6207       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6208       mp->ip6_mask_width = ip6_mask_width;
6209     }
6210
6211   vec_free (tap_name);
6212   vec_free (tag);
6213
6214   /* send it... */
6215   S (mp);
6216
6217   /* Wait for a reply... */
6218   W (ret);
6219   return ret;
6220 }
6221
6222 static int
6223 api_tap_modify (vat_main_t * vam)
6224 {
6225   unformat_input_t *i = vam->input;
6226   vl_api_tap_modify_t *mp;
6227   u8 mac_address[6];
6228   u8 random_mac = 1;
6229   u8 name_set = 0;
6230   u8 *tap_name;
6231   u32 sw_if_index = ~0;
6232   u8 sw_if_index_set = 0;
6233   int ret;
6234
6235   memset (mac_address, 0, sizeof (mac_address));
6236
6237   /* Parse args required to build the message */
6238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6239     {
6240       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6241         sw_if_index_set = 1;
6242       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6243         sw_if_index_set = 1;
6244       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6245         {
6246           random_mac = 0;
6247         }
6248       else if (unformat (i, "random-mac"))
6249         random_mac = 1;
6250       else if (unformat (i, "tapname %s", &tap_name))
6251         name_set = 1;
6252       else
6253         break;
6254     }
6255
6256   if (sw_if_index_set == 0)
6257     {
6258       errmsg ("missing vpp interface name");
6259       return -99;
6260     }
6261   if (name_set == 0)
6262     {
6263       errmsg ("missing tap name");
6264       return -99;
6265     }
6266   if (vec_len (tap_name) > 63)
6267     {
6268       errmsg ("tap name too long");
6269     }
6270   vec_add1 (tap_name, 0);
6271
6272   /* Construct the API message */
6273   M (TAP_MODIFY, mp);
6274
6275   mp->use_random_mac = random_mac;
6276   mp->sw_if_index = ntohl (sw_if_index);
6277   clib_memcpy (mp->mac_address, mac_address, 6);
6278   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6279   vec_free (tap_name);
6280
6281   /* send it... */
6282   S (mp);
6283
6284   /* Wait for a reply... */
6285   W (ret);
6286   return ret;
6287 }
6288
6289 static int
6290 api_tap_delete (vat_main_t * vam)
6291 {
6292   unformat_input_t *i = vam->input;
6293   vl_api_tap_delete_t *mp;
6294   u32 sw_if_index = ~0;
6295   u8 sw_if_index_set = 0;
6296   int ret;
6297
6298   /* Parse args required to build the message */
6299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6300     {
6301       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6302         sw_if_index_set = 1;
6303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6304         sw_if_index_set = 1;
6305       else
6306         break;
6307     }
6308
6309   if (sw_if_index_set == 0)
6310     {
6311       errmsg ("missing vpp interface name");
6312       return -99;
6313     }
6314
6315   /* Construct the API message */
6316   M (TAP_DELETE, mp);
6317
6318   mp->sw_if_index = ntohl (sw_if_index);
6319
6320   /* send it... */
6321   S (mp);
6322
6323   /* Wait for a reply... */
6324   W (ret);
6325   return ret;
6326 }
6327
6328 static int
6329 api_ip_add_del_route (vat_main_t * vam)
6330 {
6331   unformat_input_t *i = vam->input;
6332   vl_api_ip_add_del_route_t *mp;
6333   u32 sw_if_index = ~0, vrf_id = 0;
6334   u8 is_ipv6 = 0;
6335   u8 is_local = 0, is_drop = 0;
6336   u8 is_unreach = 0, is_prohibit = 0;
6337   u8 create_vrf_if_needed = 0;
6338   u8 is_add = 1;
6339   u32 next_hop_weight = 1;
6340   u8 not_last = 0;
6341   u8 is_multipath = 0;
6342   u8 address_set = 0;
6343   u8 address_length_set = 0;
6344   u32 next_hop_table_id = 0;
6345   u32 resolve_attempts = 0;
6346   u32 dst_address_length = 0;
6347   u8 next_hop_set = 0;
6348   ip4_address_t v4_dst_address, v4_next_hop_address;
6349   ip6_address_t v6_dst_address, v6_next_hop_address;
6350   int count = 1;
6351   int j;
6352   f64 before = 0;
6353   u32 random_add_del = 0;
6354   u32 *random_vector = 0;
6355   uword *random_hash;
6356   u32 random_seed = 0xdeaddabe;
6357   u32 classify_table_index = ~0;
6358   u8 is_classify = 0;
6359   u8 resolve_host = 0, resolve_attached = 0;
6360   mpls_label_t *next_hop_out_label_stack = NULL;
6361   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6362   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6363
6364   /* Parse args required to build the message */
6365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6366     {
6367       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6368         ;
6369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6370         ;
6371       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6372         {
6373           address_set = 1;
6374           is_ipv6 = 0;
6375         }
6376       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6377         {
6378           address_set = 1;
6379           is_ipv6 = 1;
6380         }
6381       else if (unformat (i, "/%d", &dst_address_length))
6382         {
6383           address_length_set = 1;
6384         }
6385
6386       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6387                                          &v4_next_hop_address))
6388         {
6389           next_hop_set = 1;
6390         }
6391       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6392                                          &v6_next_hop_address))
6393         {
6394           next_hop_set = 1;
6395         }
6396       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6397         ;
6398       else if (unformat (i, "weight %d", &next_hop_weight))
6399         ;
6400       else if (unformat (i, "drop"))
6401         {
6402           is_drop = 1;
6403         }
6404       else if (unformat (i, "null-send-unreach"))
6405         {
6406           is_unreach = 1;
6407         }
6408       else if (unformat (i, "null-send-prohibit"))
6409         {
6410           is_prohibit = 1;
6411         }
6412       else if (unformat (i, "local"))
6413         {
6414           is_local = 1;
6415         }
6416       else if (unformat (i, "classify %d", &classify_table_index))
6417         {
6418           is_classify = 1;
6419         }
6420       else if (unformat (i, "del"))
6421         is_add = 0;
6422       else if (unformat (i, "add"))
6423         is_add = 1;
6424       else if (unformat (i, "not-last"))
6425         not_last = 1;
6426       else if (unformat (i, "resolve-via-host"))
6427         resolve_host = 1;
6428       else if (unformat (i, "resolve-via-attached"))
6429         resolve_attached = 1;
6430       else if (unformat (i, "multipath"))
6431         is_multipath = 1;
6432       else if (unformat (i, "vrf %d", &vrf_id))
6433         ;
6434       else if (unformat (i, "create-vrf"))
6435         create_vrf_if_needed = 1;
6436       else if (unformat (i, "count %d", &count))
6437         ;
6438       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6439         ;
6440       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6441         ;
6442       else if (unformat (i, "out-label %d", &next_hop_out_label))
6443         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6444       else if (unformat (i, "via-label %d", &next_hop_via_label))
6445         ;
6446       else if (unformat (i, "random"))
6447         random_add_del = 1;
6448       else if (unformat (i, "seed %d", &random_seed))
6449         ;
6450       else
6451         {
6452           clib_warning ("parse error '%U'", format_unformat_error, i);
6453           return -99;
6454         }
6455     }
6456
6457   if (!next_hop_set && !is_drop && !is_local &&
6458       !is_classify && !is_unreach && !is_prohibit &&
6459       MPLS_LABEL_INVALID == next_hop_via_label)
6460     {
6461       errmsg
6462         ("next hop / local / drop / unreach / prohibit / classify not set");
6463       return -99;
6464     }
6465
6466   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6467     {
6468       errmsg ("next hop and next-hop via label set");
6469       return -99;
6470     }
6471   if (address_set == 0)
6472     {
6473       errmsg ("missing addresses");
6474       return -99;
6475     }
6476
6477   if (address_length_set == 0)
6478     {
6479       errmsg ("missing address length");
6480       return -99;
6481     }
6482
6483   /* Generate a pile of unique, random routes */
6484   if (random_add_del)
6485     {
6486       u32 this_random_address;
6487       random_hash = hash_create (count, sizeof (uword));
6488
6489       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6490       for (j = 0; j <= count; j++)
6491         {
6492           do
6493             {
6494               this_random_address = random_u32 (&random_seed);
6495               this_random_address =
6496                 clib_host_to_net_u32 (this_random_address);
6497             }
6498           while (hash_get (random_hash, this_random_address));
6499           vec_add1 (random_vector, this_random_address);
6500           hash_set (random_hash, this_random_address, 1);
6501         }
6502       hash_free (random_hash);
6503       v4_dst_address.as_u32 = random_vector[0];
6504     }
6505
6506   if (count > 1)
6507     {
6508       /* Turn on async mode */
6509       vam->async_mode = 1;
6510       vam->async_errors = 0;
6511       before = vat_time_now (vam);
6512     }
6513
6514   for (j = 0; j < count; j++)
6515     {
6516       /* Construct the API message */
6517       M2 (IP_ADD_DEL_ROUTE, mp,
6518           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6519
6520       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6521       mp->table_id = ntohl (vrf_id);
6522       mp->create_vrf_if_needed = create_vrf_if_needed;
6523
6524       mp->is_add = is_add;
6525       mp->is_drop = is_drop;
6526       mp->is_unreach = is_unreach;
6527       mp->is_prohibit = is_prohibit;
6528       mp->is_ipv6 = is_ipv6;
6529       mp->is_local = is_local;
6530       mp->is_classify = is_classify;
6531       mp->is_multipath = is_multipath;
6532       mp->is_resolve_host = resolve_host;
6533       mp->is_resolve_attached = resolve_attached;
6534       mp->not_last = not_last;
6535       mp->next_hop_weight = next_hop_weight;
6536       mp->dst_address_length = dst_address_length;
6537       mp->next_hop_table_id = ntohl (next_hop_table_id);
6538       mp->classify_table_index = ntohl (classify_table_index);
6539       mp->next_hop_via_label = ntohl (next_hop_via_label);
6540       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6541       if (0 != mp->next_hop_n_out_labels)
6542         {
6543           memcpy (mp->next_hop_out_label_stack,
6544                   next_hop_out_label_stack,
6545                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6546           vec_free (next_hop_out_label_stack);
6547         }
6548
6549       if (is_ipv6)
6550         {
6551           clib_memcpy (mp->dst_address, &v6_dst_address,
6552                        sizeof (v6_dst_address));
6553           if (next_hop_set)
6554             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6555                          sizeof (v6_next_hop_address));
6556           increment_v6_address (&v6_dst_address);
6557         }
6558       else
6559         {
6560           clib_memcpy (mp->dst_address, &v4_dst_address,
6561                        sizeof (v4_dst_address));
6562           if (next_hop_set)
6563             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6564                          sizeof (v4_next_hop_address));
6565           if (random_add_del)
6566             v4_dst_address.as_u32 = random_vector[j + 1];
6567           else
6568             increment_v4_address (&v4_dst_address);
6569         }
6570       /* send it... */
6571       S (mp);
6572       /* If we receive SIGTERM, stop now... */
6573       if (vam->do_exit)
6574         break;
6575     }
6576
6577   /* When testing multiple add/del ops, use a control-ping to sync */
6578   if (count > 1)
6579     {
6580       vl_api_control_ping_t *mp_ping;
6581       f64 after;
6582       f64 timeout;
6583
6584       /* Shut off async mode */
6585       vam->async_mode = 0;
6586
6587       M (CONTROL_PING, mp_ping);
6588       S (mp_ping);
6589
6590       timeout = vat_time_now (vam) + 1.0;
6591       while (vat_time_now (vam) < timeout)
6592         if (vam->result_ready == 1)
6593           goto out;
6594       vam->retval = -99;
6595
6596     out:
6597       if (vam->retval == -99)
6598         errmsg ("timeout");
6599
6600       if (vam->async_errors > 0)
6601         {
6602           errmsg ("%d asynchronous errors", vam->async_errors);
6603           vam->retval = -98;
6604         }
6605       vam->async_errors = 0;
6606       after = vat_time_now (vam);
6607
6608       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6609       if (j > 0)
6610         count = j;
6611
6612       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6613              count, after - before, count / (after - before));
6614     }
6615   else
6616     {
6617       int ret;
6618
6619       /* Wait for a reply... */
6620       W (ret);
6621       return ret;
6622     }
6623
6624   /* Return the good/bad news */
6625   return (vam->retval);
6626 }
6627
6628 static int
6629 api_ip_mroute_add_del (vat_main_t * vam)
6630 {
6631   unformat_input_t *i = vam->input;
6632   vl_api_ip_mroute_add_del_t *mp;
6633   u32 sw_if_index = ~0, vrf_id = 0;
6634   u8 is_ipv6 = 0;
6635   u8 is_local = 0;
6636   u8 create_vrf_if_needed = 0;
6637   u8 is_add = 1;
6638   u8 address_set = 0;
6639   u32 grp_address_length = 0;
6640   ip4_address_t v4_grp_address, v4_src_address;
6641   ip6_address_t v6_grp_address, v6_src_address;
6642   mfib_itf_flags_t iflags = 0;
6643   mfib_entry_flags_t eflags = 0;
6644   int ret;
6645
6646   /* Parse args required to build the message */
6647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6648     {
6649       if (unformat (i, "sw_if_index %d", &sw_if_index))
6650         ;
6651       else if (unformat (i, "%U %U",
6652                          unformat_ip4_address, &v4_src_address,
6653                          unformat_ip4_address, &v4_grp_address))
6654         {
6655           grp_address_length = 64;
6656           address_set = 1;
6657           is_ipv6 = 0;
6658         }
6659       else if (unformat (i, "%U %U",
6660                          unformat_ip6_address, &v6_src_address,
6661                          unformat_ip6_address, &v6_grp_address))
6662         {
6663           grp_address_length = 256;
6664           address_set = 1;
6665           is_ipv6 = 1;
6666         }
6667       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6668         {
6669           memset (&v4_src_address, 0, sizeof (v4_src_address));
6670           grp_address_length = 32;
6671           address_set = 1;
6672           is_ipv6 = 0;
6673         }
6674       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6675         {
6676           memset (&v6_src_address, 0, sizeof (v6_src_address));
6677           grp_address_length = 128;
6678           address_set = 1;
6679           is_ipv6 = 1;
6680         }
6681       else if (unformat (i, "/%d", &grp_address_length))
6682         ;
6683       else if (unformat (i, "local"))
6684         {
6685           is_local = 1;
6686         }
6687       else if (unformat (i, "del"))
6688         is_add = 0;
6689       else if (unformat (i, "add"))
6690         is_add = 1;
6691       else if (unformat (i, "vrf %d", &vrf_id))
6692         ;
6693       else if (unformat (i, "create-vrf"))
6694         create_vrf_if_needed = 1;
6695       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6696         ;
6697       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6698         ;
6699       else
6700         {
6701           clib_warning ("parse error '%U'", format_unformat_error, i);
6702           return -99;
6703         }
6704     }
6705
6706   if (address_set == 0)
6707     {
6708       errmsg ("missing addresses\n");
6709       return -99;
6710     }
6711
6712   /* Construct the API message */
6713   M (IP_MROUTE_ADD_DEL, mp);
6714
6715   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6716   mp->table_id = ntohl (vrf_id);
6717   mp->create_vrf_if_needed = create_vrf_if_needed;
6718
6719   mp->is_add = is_add;
6720   mp->is_ipv6 = is_ipv6;
6721   mp->is_local = is_local;
6722   mp->itf_flags = ntohl (iflags);
6723   mp->entry_flags = ntohl (eflags);
6724   mp->grp_address_length = grp_address_length;
6725   mp->grp_address_length = ntohs (mp->grp_address_length);
6726
6727   if (is_ipv6)
6728     {
6729       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6730       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6731     }
6732   else
6733     {
6734       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6735       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6736
6737     }
6738
6739   /* send it... */
6740   S (mp);
6741   /* Wait for a reply... */
6742   W (ret);
6743   return ret;
6744 }
6745
6746 static int
6747 api_mpls_route_add_del (vat_main_t * vam)
6748 {
6749   unformat_input_t *i = vam->input;
6750   vl_api_mpls_route_add_del_t *mp;
6751   u32 sw_if_index = ~0, table_id = 0;
6752   u8 create_table_if_needed = 0;
6753   u8 is_add = 1;
6754   u32 next_hop_weight = 1;
6755   u8 is_multipath = 0;
6756   u32 next_hop_table_id = 0;
6757   u8 next_hop_set = 0;
6758   ip4_address_t v4_next_hop_address = {
6759     .as_u32 = 0,
6760   };
6761   ip6_address_t v6_next_hop_address = { {0} };
6762   int count = 1;
6763   int j;
6764   f64 before = 0;
6765   u32 classify_table_index = ~0;
6766   u8 is_classify = 0;
6767   u8 resolve_host = 0, resolve_attached = 0;
6768   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6769   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6770   mpls_label_t *next_hop_out_label_stack = NULL;
6771   mpls_label_t local_label = MPLS_LABEL_INVALID;
6772   u8 is_eos = 0;
6773   u8 next_hop_proto_is_ip4 = 1;
6774
6775   /* Parse args required to build the message */
6776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6777     {
6778       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6779         ;
6780       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6781         ;
6782       else if (unformat (i, "%d", &local_label))
6783         ;
6784       else if (unformat (i, "eos"))
6785         is_eos = 1;
6786       else if (unformat (i, "non-eos"))
6787         is_eos = 0;
6788       else if (unformat (i, "via %U", unformat_ip4_address,
6789                          &v4_next_hop_address))
6790         {
6791           next_hop_set = 1;
6792           next_hop_proto_is_ip4 = 1;
6793         }
6794       else if (unformat (i, "via %U", unformat_ip6_address,
6795                          &v6_next_hop_address))
6796         {
6797           next_hop_set = 1;
6798           next_hop_proto_is_ip4 = 0;
6799         }
6800       else if (unformat (i, "weight %d", &next_hop_weight))
6801         ;
6802       else if (unformat (i, "create-table"))
6803         create_table_if_needed = 1;
6804       else if (unformat (i, "classify %d", &classify_table_index))
6805         {
6806           is_classify = 1;
6807         }
6808       else if (unformat (i, "del"))
6809         is_add = 0;
6810       else if (unformat (i, "add"))
6811         is_add = 1;
6812       else if (unformat (i, "resolve-via-host"))
6813         resolve_host = 1;
6814       else if (unformat (i, "resolve-via-attached"))
6815         resolve_attached = 1;
6816       else if (unformat (i, "multipath"))
6817         is_multipath = 1;
6818       else if (unformat (i, "count %d", &count))
6819         ;
6820       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6821         {
6822           next_hop_set = 1;
6823           next_hop_proto_is_ip4 = 1;
6824         }
6825       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6826         {
6827           next_hop_set = 1;
6828           next_hop_proto_is_ip4 = 0;
6829         }
6830       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6831         ;
6832       else if (unformat (i, "via-label %d", &next_hop_via_label))
6833         ;
6834       else if (unformat (i, "out-label %d", &next_hop_out_label))
6835         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6836       else
6837         {
6838           clib_warning ("parse error '%U'", format_unformat_error, i);
6839           return -99;
6840         }
6841     }
6842
6843   if (!next_hop_set && !is_classify)
6844     {
6845       errmsg ("next hop / classify not set");
6846       return -99;
6847     }
6848
6849   if (MPLS_LABEL_INVALID == local_label)
6850     {
6851       errmsg ("missing label");
6852       return -99;
6853     }
6854
6855   if (count > 1)
6856     {
6857       /* Turn on async mode */
6858       vam->async_mode = 1;
6859       vam->async_errors = 0;
6860       before = vat_time_now (vam);
6861     }
6862
6863   for (j = 0; j < count; j++)
6864     {
6865       /* Construct the API message */
6866       M2 (MPLS_ROUTE_ADD_DEL, mp,
6867           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6868
6869       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6870       mp->mr_table_id = ntohl (table_id);
6871       mp->mr_create_table_if_needed = create_table_if_needed;
6872
6873       mp->mr_is_add = is_add;
6874       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6875       mp->mr_is_classify = is_classify;
6876       mp->mr_is_multipath = is_multipath;
6877       mp->mr_is_resolve_host = resolve_host;
6878       mp->mr_is_resolve_attached = resolve_attached;
6879       mp->mr_next_hop_weight = next_hop_weight;
6880       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6881       mp->mr_classify_table_index = ntohl (classify_table_index);
6882       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6883       mp->mr_label = ntohl (local_label);
6884       mp->mr_eos = is_eos;
6885
6886       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6887       if (0 != mp->mr_next_hop_n_out_labels)
6888         {
6889           memcpy (mp->mr_next_hop_out_label_stack,
6890                   next_hop_out_label_stack,
6891                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6892           vec_free (next_hop_out_label_stack);
6893         }
6894
6895       if (next_hop_set)
6896         {
6897           if (next_hop_proto_is_ip4)
6898             {
6899               clib_memcpy (mp->mr_next_hop,
6900                            &v4_next_hop_address,
6901                            sizeof (v4_next_hop_address));
6902             }
6903           else
6904             {
6905               clib_memcpy (mp->mr_next_hop,
6906                            &v6_next_hop_address,
6907                            sizeof (v6_next_hop_address));
6908             }
6909         }
6910       local_label++;
6911
6912       /* send it... */
6913       S (mp);
6914       /* If we receive SIGTERM, stop now... */
6915       if (vam->do_exit)
6916         break;
6917     }
6918
6919   /* When testing multiple add/del ops, use a control-ping to sync */
6920   if (count > 1)
6921     {
6922       vl_api_control_ping_t *mp_ping;
6923       f64 after;
6924       f64 timeout;
6925
6926       /* Shut off async mode */
6927       vam->async_mode = 0;
6928
6929       M (CONTROL_PING, mp_ping);
6930       S (mp_ping);
6931
6932       timeout = vat_time_now (vam) + 1.0;
6933       while (vat_time_now (vam) < timeout)
6934         if (vam->result_ready == 1)
6935           goto out;
6936       vam->retval = -99;
6937
6938     out:
6939       if (vam->retval == -99)
6940         errmsg ("timeout");
6941
6942       if (vam->async_errors > 0)
6943         {
6944           errmsg ("%d asynchronous errors", vam->async_errors);
6945           vam->retval = -98;
6946         }
6947       vam->async_errors = 0;
6948       after = vat_time_now (vam);
6949
6950       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6951       if (j > 0)
6952         count = j;
6953
6954       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6955              count, after - before, count / (after - before));
6956     }
6957   else
6958     {
6959       int ret;
6960
6961       /* Wait for a reply... */
6962       W (ret);
6963       return ret;
6964     }
6965
6966   /* Return the good/bad news */
6967   return (vam->retval);
6968 }
6969
6970 static int
6971 api_mpls_ip_bind_unbind (vat_main_t * vam)
6972 {
6973   unformat_input_t *i = vam->input;
6974   vl_api_mpls_ip_bind_unbind_t *mp;
6975   u32 ip_table_id = 0;
6976   u8 create_table_if_needed = 0;
6977   u8 is_bind = 1;
6978   u8 is_ip4 = 1;
6979   ip4_address_t v4_address;
6980   ip6_address_t v6_address;
6981   u32 address_length;
6982   u8 address_set = 0;
6983   mpls_label_t local_label = MPLS_LABEL_INVALID;
6984   int ret;
6985
6986   /* Parse args required to build the message */
6987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6988     {
6989       if (unformat (i, "%U/%d", unformat_ip4_address,
6990                     &v4_address, &address_length))
6991         {
6992           is_ip4 = 1;
6993           address_set = 1;
6994         }
6995       else if (unformat (i, "%U/%d", unformat_ip6_address,
6996                          &v6_address, &address_length))
6997         {
6998           is_ip4 = 0;
6999           address_set = 1;
7000         }
7001       else if (unformat (i, "%d", &local_label))
7002         ;
7003       else if (unformat (i, "create-table"))
7004         create_table_if_needed = 1;
7005       else if (unformat (i, "table-id %d", &ip_table_id))
7006         ;
7007       else if (unformat (i, "unbind"))
7008         is_bind = 0;
7009       else if (unformat (i, "bind"))
7010         is_bind = 1;
7011       else
7012         {
7013           clib_warning ("parse error '%U'", format_unformat_error, i);
7014           return -99;
7015         }
7016     }
7017
7018   if (!address_set)
7019     {
7020       errmsg ("IP addres not set");
7021       return -99;
7022     }
7023
7024   if (MPLS_LABEL_INVALID == local_label)
7025     {
7026       errmsg ("missing label");
7027       return -99;
7028     }
7029
7030   /* Construct the API message */
7031   M (MPLS_IP_BIND_UNBIND, mp);
7032
7033   mp->mb_create_table_if_needed = create_table_if_needed;
7034   mp->mb_is_bind = is_bind;
7035   mp->mb_is_ip4 = is_ip4;
7036   mp->mb_ip_table_id = ntohl (ip_table_id);
7037   mp->mb_mpls_table_id = 0;
7038   mp->mb_label = ntohl (local_label);
7039   mp->mb_address_length = address_length;
7040
7041   if (is_ip4)
7042     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7043   else
7044     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7045
7046   /* send it... */
7047   S (mp);
7048
7049   /* Wait for a reply... */
7050   W (ret);
7051   return ret;
7052 }
7053
7054 static int
7055 api_proxy_arp_add_del (vat_main_t * vam)
7056 {
7057   unformat_input_t *i = vam->input;
7058   vl_api_proxy_arp_add_del_t *mp;
7059   u32 vrf_id = 0;
7060   u8 is_add = 1;
7061   ip4_address_t lo, hi;
7062   u8 range_set = 0;
7063   int ret;
7064
7065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7066     {
7067       if (unformat (i, "vrf %d", &vrf_id))
7068         ;
7069       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7070                          unformat_ip4_address, &hi))
7071         range_set = 1;
7072       else if (unformat (i, "del"))
7073         is_add = 0;
7074       else
7075         {
7076           clib_warning ("parse error '%U'", format_unformat_error, i);
7077           return -99;
7078         }
7079     }
7080
7081   if (range_set == 0)
7082     {
7083       errmsg ("address range not set");
7084       return -99;
7085     }
7086
7087   M (PROXY_ARP_ADD_DEL, mp);
7088
7089   mp->vrf_id = ntohl (vrf_id);
7090   mp->is_add = is_add;
7091   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7092   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7093
7094   S (mp);
7095   W (ret);
7096   return ret;
7097 }
7098
7099 static int
7100 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7101 {
7102   unformat_input_t *i = vam->input;
7103   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7104   u32 sw_if_index;
7105   u8 enable = 1;
7106   u8 sw_if_index_set = 0;
7107   int ret;
7108
7109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7110     {
7111       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7112         sw_if_index_set = 1;
7113       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7114         sw_if_index_set = 1;
7115       else if (unformat (i, "enable"))
7116         enable = 1;
7117       else if (unformat (i, "disable"))
7118         enable = 0;
7119       else
7120         {
7121           clib_warning ("parse error '%U'", format_unformat_error, i);
7122           return -99;
7123         }
7124     }
7125
7126   if (sw_if_index_set == 0)
7127     {
7128       errmsg ("missing interface name or sw_if_index");
7129       return -99;
7130     }
7131
7132   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7133
7134   mp->sw_if_index = ntohl (sw_if_index);
7135   mp->enable_disable = enable;
7136
7137   S (mp);
7138   W (ret);
7139   return ret;
7140 }
7141
7142 static int
7143 api_mpls_tunnel_add_del (vat_main_t * vam)
7144 {
7145   unformat_input_t *i = vam->input;
7146   vl_api_mpls_tunnel_add_del_t *mp;
7147
7148   u8 is_add = 1;
7149   u8 l2_only = 0;
7150   u32 sw_if_index = ~0;
7151   u32 next_hop_sw_if_index = ~0;
7152   u32 next_hop_proto_is_ip4 = 1;
7153
7154   u32 next_hop_table_id = 0;
7155   ip4_address_t v4_next_hop_address = {
7156     .as_u32 = 0,
7157   };
7158   ip6_address_t v6_next_hop_address = { {0} };
7159   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7160   int ret;
7161
7162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7163     {
7164       if (unformat (i, "add"))
7165         is_add = 1;
7166       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7167         is_add = 0;
7168       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7169         ;
7170       else if (unformat (i, "via %U",
7171                          unformat_ip4_address, &v4_next_hop_address))
7172         {
7173           next_hop_proto_is_ip4 = 1;
7174         }
7175       else if (unformat (i, "via %U",
7176                          unformat_ip6_address, &v6_next_hop_address))
7177         {
7178           next_hop_proto_is_ip4 = 0;
7179         }
7180       else if (unformat (i, "l2-only"))
7181         l2_only = 1;
7182       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7183         ;
7184       else if (unformat (i, "out-label %d", &next_hop_out_label))
7185         vec_add1 (labels, ntohl (next_hop_out_label));
7186       else
7187         {
7188           clib_warning ("parse error '%U'", format_unformat_error, i);
7189           return -99;
7190         }
7191     }
7192
7193   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7194
7195   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7196   mp->mt_sw_if_index = ntohl (sw_if_index);
7197   mp->mt_is_add = is_add;
7198   mp->mt_l2_only = l2_only;
7199   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7200   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7201
7202   mp->mt_next_hop_n_out_labels = vec_len (labels);
7203
7204   if (0 != mp->mt_next_hop_n_out_labels)
7205     {
7206       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7207                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7208       vec_free (labels);
7209     }
7210
7211   if (next_hop_proto_is_ip4)
7212     {
7213       clib_memcpy (mp->mt_next_hop,
7214                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7215     }
7216   else
7217     {
7218       clib_memcpy (mp->mt_next_hop,
7219                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7220     }
7221
7222   S (mp);
7223   W (ret);
7224   return ret;
7225 }
7226
7227 static int
7228 api_sw_interface_set_unnumbered (vat_main_t * vam)
7229 {
7230   unformat_input_t *i = vam->input;
7231   vl_api_sw_interface_set_unnumbered_t *mp;
7232   u32 sw_if_index;
7233   u32 unnum_sw_index = ~0;
7234   u8 is_add = 1;
7235   u8 sw_if_index_set = 0;
7236   int ret;
7237
7238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7239     {
7240       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7241         sw_if_index_set = 1;
7242       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7243         sw_if_index_set = 1;
7244       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7245         ;
7246       else if (unformat (i, "del"))
7247         is_add = 0;
7248       else
7249         {
7250           clib_warning ("parse error '%U'", format_unformat_error, i);
7251           return -99;
7252         }
7253     }
7254
7255   if (sw_if_index_set == 0)
7256     {
7257       errmsg ("missing interface name or sw_if_index");
7258       return -99;
7259     }
7260
7261   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7262
7263   mp->sw_if_index = ntohl (sw_if_index);
7264   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7265   mp->is_add = is_add;
7266
7267   S (mp);
7268   W (ret);
7269   return ret;
7270 }
7271
7272 static int
7273 api_ip_neighbor_add_del (vat_main_t * vam)
7274 {
7275   unformat_input_t *i = vam->input;
7276   vl_api_ip_neighbor_add_del_t *mp;
7277   u32 sw_if_index;
7278   u8 sw_if_index_set = 0;
7279   u32 vrf_id = 0;
7280   u8 is_add = 1;
7281   u8 is_static = 0;
7282   u8 mac_address[6];
7283   u8 mac_set = 0;
7284   u8 v4_address_set = 0;
7285   u8 v6_address_set = 0;
7286   ip4_address_t v4address;
7287   ip6_address_t v6address;
7288   int ret;
7289
7290   memset (mac_address, 0, sizeof (mac_address));
7291
7292   /* Parse args required to build the message */
7293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7294     {
7295       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7296         {
7297           mac_set = 1;
7298         }
7299       else if (unformat (i, "del"))
7300         is_add = 0;
7301       else
7302         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7303         sw_if_index_set = 1;
7304       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7305         sw_if_index_set = 1;
7306       else if (unformat (i, "is_static"))
7307         is_static = 1;
7308       else if (unformat (i, "vrf %d", &vrf_id))
7309         ;
7310       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7311         v4_address_set = 1;
7312       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7313         v6_address_set = 1;
7314       else
7315         {
7316           clib_warning ("parse error '%U'", format_unformat_error, i);
7317           return -99;
7318         }
7319     }
7320
7321   if (sw_if_index_set == 0)
7322     {
7323       errmsg ("missing interface name or sw_if_index");
7324       return -99;
7325     }
7326   if (v4_address_set && v6_address_set)
7327     {
7328       errmsg ("both v4 and v6 addresses set");
7329       return -99;
7330     }
7331   if (!v4_address_set && !v6_address_set)
7332     {
7333       errmsg ("no address set");
7334       return -99;
7335     }
7336
7337   /* Construct the API message */
7338   M (IP_NEIGHBOR_ADD_DEL, mp);
7339
7340   mp->sw_if_index = ntohl (sw_if_index);
7341   mp->is_add = is_add;
7342   mp->vrf_id = ntohl (vrf_id);
7343   mp->is_static = is_static;
7344   if (mac_set)
7345     clib_memcpy (mp->mac_address, mac_address, 6);
7346   if (v6_address_set)
7347     {
7348       mp->is_ipv6 = 1;
7349       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7350     }
7351   else
7352     {
7353       /* mp->is_ipv6 = 0; via memset in M macro above */
7354       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7355     }
7356
7357   /* send it... */
7358   S (mp);
7359
7360   /* Wait for a reply, return good/bad news  */
7361   W (ret);
7362   return ret;
7363 }
7364
7365 static int
7366 api_reset_vrf (vat_main_t * vam)
7367 {
7368   unformat_input_t *i = vam->input;
7369   vl_api_reset_vrf_t *mp;
7370   u32 vrf_id = 0;
7371   u8 is_ipv6 = 0;
7372   u8 vrf_id_set = 0;
7373   int ret;
7374
7375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7376     {
7377       if (unformat (i, "vrf %d", &vrf_id))
7378         vrf_id_set = 1;
7379       else if (unformat (i, "ipv6"))
7380         is_ipv6 = 1;
7381       else
7382         {
7383           clib_warning ("parse error '%U'", format_unformat_error, i);
7384           return -99;
7385         }
7386     }
7387
7388   if (vrf_id_set == 0)
7389     {
7390       errmsg ("missing vrf id");
7391       return -99;
7392     }
7393
7394   M (RESET_VRF, mp);
7395
7396   mp->vrf_id = ntohl (vrf_id);
7397   mp->is_ipv6 = is_ipv6;
7398
7399   S (mp);
7400   W (ret);
7401   return ret;
7402 }
7403
7404 static int
7405 api_create_vlan_subif (vat_main_t * vam)
7406 {
7407   unformat_input_t *i = vam->input;
7408   vl_api_create_vlan_subif_t *mp;
7409   u32 sw_if_index;
7410   u8 sw_if_index_set = 0;
7411   u32 vlan_id;
7412   u8 vlan_id_set = 0;
7413   int ret;
7414
7415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7416     {
7417       if (unformat (i, "sw_if_index %d", &sw_if_index))
7418         sw_if_index_set = 1;
7419       else
7420         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7421         sw_if_index_set = 1;
7422       else if (unformat (i, "vlan %d", &vlan_id))
7423         vlan_id_set = 1;
7424       else
7425         {
7426           clib_warning ("parse error '%U'", format_unformat_error, i);
7427           return -99;
7428         }
7429     }
7430
7431   if (sw_if_index_set == 0)
7432     {
7433       errmsg ("missing interface name or sw_if_index");
7434       return -99;
7435     }
7436
7437   if (vlan_id_set == 0)
7438     {
7439       errmsg ("missing vlan_id");
7440       return -99;
7441     }
7442   M (CREATE_VLAN_SUBIF, mp);
7443
7444   mp->sw_if_index = ntohl (sw_if_index);
7445   mp->vlan_id = ntohl (vlan_id);
7446
7447   S (mp);
7448   W (ret);
7449   return ret;
7450 }
7451
7452 #define foreach_create_subif_bit                \
7453 _(no_tags)                                      \
7454 _(one_tag)                                      \
7455 _(two_tags)                                     \
7456 _(dot1ad)                                       \
7457 _(exact_match)                                  \
7458 _(default_sub)                                  \
7459 _(outer_vlan_id_any)                            \
7460 _(inner_vlan_id_any)
7461
7462 static int
7463 api_create_subif (vat_main_t * vam)
7464 {
7465   unformat_input_t *i = vam->input;
7466   vl_api_create_subif_t *mp;
7467   u32 sw_if_index;
7468   u8 sw_if_index_set = 0;
7469   u32 sub_id;
7470   u8 sub_id_set = 0;
7471   u32 no_tags = 0;
7472   u32 one_tag = 0;
7473   u32 two_tags = 0;
7474   u32 dot1ad = 0;
7475   u32 exact_match = 0;
7476   u32 default_sub = 0;
7477   u32 outer_vlan_id_any = 0;
7478   u32 inner_vlan_id_any = 0;
7479   u32 tmp;
7480   u16 outer_vlan_id = 0;
7481   u16 inner_vlan_id = 0;
7482   int ret;
7483
7484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7485     {
7486       if (unformat (i, "sw_if_index %d", &sw_if_index))
7487         sw_if_index_set = 1;
7488       else
7489         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7490         sw_if_index_set = 1;
7491       else if (unformat (i, "sub_id %d", &sub_id))
7492         sub_id_set = 1;
7493       else if (unformat (i, "outer_vlan_id %d", &tmp))
7494         outer_vlan_id = tmp;
7495       else if (unformat (i, "inner_vlan_id %d", &tmp))
7496         inner_vlan_id = tmp;
7497
7498 #define _(a) else if (unformat (i, #a)) a = 1 ;
7499       foreach_create_subif_bit
7500 #undef _
7501         else
7502         {
7503           clib_warning ("parse error '%U'", format_unformat_error, i);
7504           return -99;
7505         }
7506     }
7507
7508   if (sw_if_index_set == 0)
7509     {
7510       errmsg ("missing interface name or sw_if_index");
7511       return -99;
7512     }
7513
7514   if (sub_id_set == 0)
7515     {
7516       errmsg ("missing sub_id");
7517       return -99;
7518     }
7519   M (CREATE_SUBIF, mp);
7520
7521   mp->sw_if_index = ntohl (sw_if_index);
7522   mp->sub_id = ntohl (sub_id);
7523
7524 #define _(a) mp->a = a;
7525   foreach_create_subif_bit;
7526 #undef _
7527
7528   mp->outer_vlan_id = ntohs (outer_vlan_id);
7529   mp->inner_vlan_id = ntohs (inner_vlan_id);
7530
7531   S (mp);
7532   W (ret);
7533   return ret;
7534 }
7535
7536 static int
7537 api_oam_add_del (vat_main_t * vam)
7538 {
7539   unformat_input_t *i = vam->input;
7540   vl_api_oam_add_del_t *mp;
7541   u32 vrf_id = 0;
7542   u8 is_add = 1;
7543   ip4_address_t src, dst;
7544   u8 src_set = 0;
7545   u8 dst_set = 0;
7546   int ret;
7547
7548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7549     {
7550       if (unformat (i, "vrf %d", &vrf_id))
7551         ;
7552       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7553         src_set = 1;
7554       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7555         dst_set = 1;
7556       else if (unformat (i, "del"))
7557         is_add = 0;
7558       else
7559         {
7560           clib_warning ("parse error '%U'", format_unformat_error, i);
7561           return -99;
7562         }
7563     }
7564
7565   if (src_set == 0)
7566     {
7567       errmsg ("missing src addr");
7568       return -99;
7569     }
7570
7571   if (dst_set == 0)
7572     {
7573       errmsg ("missing dst addr");
7574       return -99;
7575     }
7576
7577   M (OAM_ADD_DEL, mp);
7578
7579   mp->vrf_id = ntohl (vrf_id);
7580   mp->is_add = is_add;
7581   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7582   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7583
7584   S (mp);
7585   W (ret);
7586   return ret;
7587 }
7588
7589 static int
7590 api_reset_fib (vat_main_t * vam)
7591 {
7592   unformat_input_t *i = vam->input;
7593   vl_api_reset_fib_t *mp;
7594   u32 vrf_id = 0;
7595   u8 is_ipv6 = 0;
7596   u8 vrf_id_set = 0;
7597
7598   int ret;
7599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7600     {
7601       if (unformat (i, "vrf %d", &vrf_id))
7602         vrf_id_set = 1;
7603       else if (unformat (i, "ipv6"))
7604         is_ipv6 = 1;
7605       else
7606         {
7607           clib_warning ("parse error '%U'", format_unformat_error, i);
7608           return -99;
7609         }
7610     }
7611
7612   if (vrf_id_set == 0)
7613     {
7614       errmsg ("missing vrf id");
7615       return -99;
7616     }
7617
7618   M (RESET_FIB, mp);
7619
7620   mp->vrf_id = ntohl (vrf_id);
7621   mp->is_ipv6 = is_ipv6;
7622
7623   S (mp);
7624   W (ret);
7625   return ret;
7626 }
7627
7628 static int
7629 api_dhcp_proxy_config (vat_main_t * vam)
7630 {
7631   unformat_input_t *i = vam->input;
7632   vl_api_dhcp_proxy_config_t *mp;
7633   u32 rx_vrf_id = 0;
7634   u32 server_vrf_id = 0;
7635   u8 is_add = 1;
7636   u8 v4_address_set = 0;
7637   u8 v6_address_set = 0;
7638   ip4_address_t v4address;
7639   ip6_address_t v6address;
7640   u8 v4_src_address_set = 0;
7641   u8 v6_src_address_set = 0;
7642   ip4_address_t v4srcaddress;
7643   ip6_address_t v6srcaddress;
7644   int ret;
7645
7646   /* Parse args required to build the message */
7647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7648     {
7649       if (unformat (i, "del"))
7650         is_add = 0;
7651       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7652         ;
7653       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7654         ;
7655       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7656         v4_address_set = 1;
7657       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7658         v6_address_set = 1;
7659       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7660         v4_src_address_set = 1;
7661       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7662         v6_src_address_set = 1;
7663       else
7664         break;
7665     }
7666
7667   if (v4_address_set && v6_address_set)
7668     {
7669       errmsg ("both v4 and v6 server addresses set");
7670       return -99;
7671     }
7672   if (!v4_address_set && !v6_address_set)
7673     {
7674       errmsg ("no server addresses set");
7675       return -99;
7676     }
7677
7678   if (v4_src_address_set && v6_src_address_set)
7679     {
7680       errmsg ("both v4 and v6  src addresses set");
7681       return -99;
7682     }
7683   if (!v4_src_address_set && !v6_src_address_set)
7684     {
7685       errmsg ("no src addresses set");
7686       return -99;
7687     }
7688
7689   if (!(v4_src_address_set && v4_address_set) &&
7690       !(v6_src_address_set && v6_address_set))
7691     {
7692       errmsg ("no matching server and src addresses set");
7693       return -99;
7694     }
7695
7696   /* Construct the API message */
7697   M (DHCP_PROXY_CONFIG, mp);
7698
7699   mp->is_add = is_add;
7700   mp->rx_vrf_id = ntohl (rx_vrf_id);
7701   mp->server_vrf_id = ntohl (server_vrf_id);
7702   if (v6_address_set)
7703     {
7704       mp->is_ipv6 = 1;
7705       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7706       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7707     }
7708   else
7709     {
7710       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7711       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7712     }
7713
7714   /* send it... */
7715   S (mp);
7716
7717   /* Wait for a reply, return good/bad news  */
7718   W (ret);
7719   return ret;
7720 }
7721
7722 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7723 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7724
7725 static void
7726 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7727 {
7728   vat_main_t *vam = &vat_main;
7729
7730   if (mp->is_ipv6)
7731     print (vam->ofp,
7732            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7733            ntohl (mp->rx_vrf_id),
7734            ntohl (mp->server_vrf_id),
7735            format_ip6_address, mp->dhcp_server,
7736            format_ip6_address, mp->dhcp_src_address,
7737            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7738   else
7739     print (vam->ofp,
7740            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7741            ntohl (mp->rx_vrf_id),
7742            ntohl (mp->server_vrf_id),
7743            format_ip4_address, mp->dhcp_server,
7744            format_ip4_address, mp->dhcp_src_address,
7745            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7746 }
7747
7748 static void vl_api_dhcp_proxy_details_t_handler_json
7749   (vl_api_dhcp_proxy_details_t * mp)
7750 {
7751   vat_main_t *vam = &vat_main;
7752   vat_json_node_t *node = NULL;
7753   struct in_addr ip4;
7754   struct in6_addr ip6;
7755
7756   if (VAT_JSON_ARRAY != vam->json_tree.type)
7757     {
7758       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7759       vat_json_init_array (&vam->json_tree);
7760     }
7761   node = vat_json_array_add (&vam->json_tree);
7762
7763   vat_json_init_object (node);
7764   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7765   vat_json_object_add_uint (node, "server-table-id",
7766                             ntohl (mp->server_vrf_id));
7767   if (mp->is_ipv6)
7768     {
7769       clib_memcpy (&ip6, &mp->dhcp_server, sizeof (ip6));
7770       vat_json_object_add_ip6 (node, "server_address", ip6);
7771       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7772       vat_json_object_add_ip6 (node, "src_address", ip6);
7773     }
7774   else
7775     {
7776       clib_memcpy (&ip4, &mp->dhcp_server, sizeof (ip4));
7777       vat_json_object_add_ip4 (node, "server_address", ip4);
7778       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7779       vat_json_object_add_ip4 (node, "src_address", ip4);
7780     }
7781   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7782   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7783 }
7784
7785 static int
7786 api_dhcp_proxy_dump (vat_main_t * vam)
7787 {
7788   unformat_input_t *i = vam->input;
7789   vl_api_control_ping_t *mp_ping;
7790   vl_api_dhcp_proxy_dump_t *mp;
7791   u8 is_ipv6 = 0;
7792   int ret;
7793
7794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7795     {
7796       if (unformat (i, "ipv6"))
7797         is_ipv6 = 1;
7798       else
7799         {
7800           clib_warning ("parse error '%U'", format_unformat_error, i);
7801           return -99;
7802         }
7803     }
7804
7805   M (DHCP_PROXY_DUMP, mp);
7806
7807   mp->is_ip6 = is_ipv6;
7808   S (mp);
7809
7810   /* Use a control ping for synchronization */
7811   M (CONTROL_PING, mp_ping);
7812   S (mp_ping);
7813
7814   W (ret);
7815   return ret;
7816 }
7817
7818 static int
7819 api_dhcp_proxy_set_vss (vat_main_t * vam)
7820 {
7821   unformat_input_t *i = vam->input;
7822   vl_api_dhcp_proxy_set_vss_t *mp;
7823   u8 is_ipv6 = 0;
7824   u8 is_add = 1;
7825   u32 tbl_id;
7826   u8 tbl_id_set = 0;
7827   u32 oui;
7828   u8 oui_set = 0;
7829   u32 fib_id;
7830   u8 fib_id_set = 0;
7831   int ret;
7832
7833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7834     {
7835       if (unformat (i, "tbl_id %d", &tbl_id))
7836         tbl_id_set = 1;
7837       if (unformat (i, "fib_id %d", &fib_id))
7838         fib_id_set = 1;
7839       if (unformat (i, "oui %d", &oui))
7840         oui_set = 1;
7841       else if (unformat (i, "ipv6"))
7842         is_ipv6 = 1;
7843       else if (unformat (i, "del"))
7844         is_add = 0;
7845       else
7846         {
7847           clib_warning ("parse error '%U'", format_unformat_error, i);
7848           return -99;
7849         }
7850     }
7851
7852   if (tbl_id_set == 0)
7853     {
7854       errmsg ("missing tbl id");
7855       return -99;
7856     }
7857
7858   if (fib_id_set == 0)
7859     {
7860       errmsg ("missing fib id");
7861       return -99;
7862     }
7863   if (oui_set == 0)
7864     {
7865       errmsg ("missing oui");
7866       return -99;
7867     }
7868
7869   M (DHCP_PROXY_SET_VSS, mp);
7870   mp->tbl_id = ntohl (tbl_id);
7871   mp->fib_id = ntohl (fib_id);
7872   mp->oui = ntohl (oui);
7873   mp->is_ipv6 = is_ipv6;
7874   mp->is_add = is_add;
7875
7876   S (mp);
7877   W (ret);
7878   return ret;
7879 }
7880
7881 static int
7882 api_dhcp_client_config (vat_main_t * vam)
7883 {
7884   unformat_input_t *i = vam->input;
7885   vl_api_dhcp_client_config_t *mp;
7886   u32 sw_if_index;
7887   u8 sw_if_index_set = 0;
7888   u8 is_add = 1;
7889   u8 *hostname = 0;
7890   u8 disable_event = 0;
7891   int ret;
7892
7893   /* Parse args required to build the message */
7894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7895     {
7896       if (unformat (i, "del"))
7897         is_add = 0;
7898       else
7899         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7900         sw_if_index_set = 1;
7901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7902         sw_if_index_set = 1;
7903       else if (unformat (i, "hostname %s", &hostname))
7904         ;
7905       else if (unformat (i, "disable_event"))
7906         disable_event = 1;
7907       else
7908         break;
7909     }
7910
7911   if (sw_if_index_set == 0)
7912     {
7913       errmsg ("missing interface name or sw_if_index");
7914       return -99;
7915     }
7916
7917   if (vec_len (hostname) > 63)
7918     {
7919       errmsg ("hostname too long");
7920     }
7921   vec_add1 (hostname, 0);
7922
7923   /* Construct the API message */
7924   M (DHCP_CLIENT_CONFIG, mp);
7925
7926   mp->sw_if_index = ntohl (sw_if_index);
7927   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7928   vec_free (hostname);
7929   mp->is_add = is_add;
7930   mp->want_dhcp_event = disable_event ? 0 : 1;
7931   mp->pid = getpid ();
7932
7933   /* send it... */
7934   S (mp);
7935
7936   /* Wait for a reply, return good/bad news  */
7937   W (ret);
7938   return ret;
7939 }
7940
7941 static int
7942 api_set_ip_flow_hash (vat_main_t * vam)
7943 {
7944   unformat_input_t *i = vam->input;
7945   vl_api_set_ip_flow_hash_t *mp;
7946   u32 vrf_id = 0;
7947   u8 is_ipv6 = 0;
7948   u8 vrf_id_set = 0;
7949   u8 src = 0;
7950   u8 dst = 0;
7951   u8 sport = 0;
7952   u8 dport = 0;
7953   u8 proto = 0;
7954   u8 reverse = 0;
7955   int ret;
7956
7957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7958     {
7959       if (unformat (i, "vrf %d", &vrf_id))
7960         vrf_id_set = 1;
7961       else if (unformat (i, "ipv6"))
7962         is_ipv6 = 1;
7963       else if (unformat (i, "src"))
7964         src = 1;
7965       else if (unformat (i, "dst"))
7966         dst = 1;
7967       else if (unformat (i, "sport"))
7968         sport = 1;
7969       else if (unformat (i, "dport"))
7970         dport = 1;
7971       else if (unformat (i, "proto"))
7972         proto = 1;
7973       else if (unformat (i, "reverse"))
7974         reverse = 1;
7975
7976       else
7977         {
7978           clib_warning ("parse error '%U'", format_unformat_error, i);
7979           return -99;
7980         }
7981     }
7982
7983   if (vrf_id_set == 0)
7984     {
7985       errmsg ("missing vrf id");
7986       return -99;
7987     }
7988
7989   M (SET_IP_FLOW_HASH, mp);
7990   mp->src = src;
7991   mp->dst = dst;
7992   mp->sport = sport;
7993   mp->dport = dport;
7994   mp->proto = proto;
7995   mp->reverse = reverse;
7996   mp->vrf_id = ntohl (vrf_id);
7997   mp->is_ipv6 = is_ipv6;
7998
7999   S (mp);
8000   W (ret);
8001   return ret;
8002 }
8003
8004 static int
8005 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8006 {
8007   unformat_input_t *i = vam->input;
8008   vl_api_sw_interface_ip6_enable_disable_t *mp;
8009   u32 sw_if_index;
8010   u8 sw_if_index_set = 0;
8011   u8 enable = 0;
8012   int ret;
8013
8014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8015     {
8016       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8017         sw_if_index_set = 1;
8018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8019         sw_if_index_set = 1;
8020       else if (unformat (i, "enable"))
8021         enable = 1;
8022       else if (unformat (i, "disable"))
8023         enable = 0;
8024       else
8025         {
8026           clib_warning ("parse error '%U'", format_unformat_error, i);
8027           return -99;
8028         }
8029     }
8030
8031   if (sw_if_index_set == 0)
8032     {
8033       errmsg ("missing interface name or sw_if_index");
8034       return -99;
8035     }
8036
8037   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8038
8039   mp->sw_if_index = ntohl (sw_if_index);
8040   mp->enable = enable;
8041
8042   S (mp);
8043   W (ret);
8044   return ret;
8045 }
8046
8047 static int
8048 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8049 {
8050   unformat_input_t *i = vam->input;
8051   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8052   u32 sw_if_index;
8053   u8 sw_if_index_set = 0;
8054   u8 v6_address_set = 0;
8055   ip6_address_t v6address;
8056   int ret;
8057
8058   /* Parse args required to build the message */
8059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8060     {
8061       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8062         sw_if_index_set = 1;
8063       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8064         sw_if_index_set = 1;
8065       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8066         v6_address_set = 1;
8067       else
8068         break;
8069     }
8070
8071   if (sw_if_index_set == 0)
8072     {
8073       errmsg ("missing interface name or sw_if_index");
8074       return -99;
8075     }
8076   if (!v6_address_set)
8077     {
8078       errmsg ("no address set");
8079       return -99;
8080     }
8081
8082   /* Construct the API message */
8083   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8084
8085   mp->sw_if_index = ntohl (sw_if_index);
8086   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8087
8088   /* send it... */
8089   S (mp);
8090
8091   /* Wait for a reply, return good/bad news  */
8092   W (ret);
8093   return ret;
8094 }
8095
8096
8097 static int
8098 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8099 {
8100   unformat_input_t *i = vam->input;
8101   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8102   u32 sw_if_index;
8103   u8 sw_if_index_set = 0;
8104   u32 address_length = 0;
8105   u8 v6_address_set = 0;
8106   ip6_address_t v6address;
8107   u8 use_default = 0;
8108   u8 no_advertise = 0;
8109   u8 off_link = 0;
8110   u8 no_autoconfig = 0;
8111   u8 no_onlink = 0;
8112   u8 is_no = 0;
8113   u32 val_lifetime = 0;
8114   u32 pref_lifetime = 0;
8115   int ret;
8116
8117   /* Parse args required to build the message */
8118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8119     {
8120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8121         sw_if_index_set = 1;
8122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8123         sw_if_index_set = 1;
8124       else if (unformat (i, "%U/%d",
8125                          unformat_ip6_address, &v6address, &address_length))
8126         v6_address_set = 1;
8127       else if (unformat (i, "val_life %d", &val_lifetime))
8128         ;
8129       else if (unformat (i, "pref_life %d", &pref_lifetime))
8130         ;
8131       else if (unformat (i, "def"))
8132         use_default = 1;
8133       else if (unformat (i, "noadv"))
8134         no_advertise = 1;
8135       else if (unformat (i, "offl"))
8136         off_link = 1;
8137       else if (unformat (i, "noauto"))
8138         no_autoconfig = 1;
8139       else if (unformat (i, "nolink"))
8140         no_onlink = 1;
8141       else if (unformat (i, "isno"))
8142         is_no = 1;
8143       else
8144         {
8145           clib_warning ("parse error '%U'", format_unformat_error, i);
8146           return -99;
8147         }
8148     }
8149
8150   if (sw_if_index_set == 0)
8151     {
8152       errmsg ("missing interface name or sw_if_index");
8153       return -99;
8154     }
8155   if (!v6_address_set)
8156     {
8157       errmsg ("no address set");
8158       return -99;
8159     }
8160
8161   /* Construct the API message */
8162   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8163
8164   mp->sw_if_index = ntohl (sw_if_index);
8165   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8166   mp->address_length = address_length;
8167   mp->use_default = use_default;
8168   mp->no_advertise = no_advertise;
8169   mp->off_link = off_link;
8170   mp->no_autoconfig = no_autoconfig;
8171   mp->no_onlink = no_onlink;
8172   mp->is_no = is_no;
8173   mp->val_lifetime = ntohl (val_lifetime);
8174   mp->pref_lifetime = ntohl (pref_lifetime);
8175
8176   /* send it... */
8177   S (mp);
8178
8179   /* Wait for a reply, return good/bad news  */
8180   W (ret);
8181   return ret;
8182 }
8183
8184 static int
8185 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8186 {
8187   unformat_input_t *i = vam->input;
8188   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8189   u32 sw_if_index;
8190   u8 sw_if_index_set = 0;
8191   u8 suppress = 0;
8192   u8 managed = 0;
8193   u8 other = 0;
8194   u8 ll_option = 0;
8195   u8 send_unicast = 0;
8196   u8 cease = 0;
8197   u8 is_no = 0;
8198   u8 default_router = 0;
8199   u32 max_interval = 0;
8200   u32 min_interval = 0;
8201   u32 lifetime = 0;
8202   u32 initial_count = 0;
8203   u32 initial_interval = 0;
8204   int ret;
8205
8206
8207   /* Parse args required to build the message */
8208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8209     {
8210       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8211         sw_if_index_set = 1;
8212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8213         sw_if_index_set = 1;
8214       else if (unformat (i, "maxint %d", &max_interval))
8215         ;
8216       else if (unformat (i, "minint %d", &min_interval))
8217         ;
8218       else if (unformat (i, "life %d", &lifetime))
8219         ;
8220       else if (unformat (i, "count %d", &initial_count))
8221         ;
8222       else if (unformat (i, "interval %d", &initial_interval))
8223         ;
8224       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8225         suppress = 1;
8226       else if (unformat (i, "managed"))
8227         managed = 1;
8228       else if (unformat (i, "other"))
8229         other = 1;
8230       else if (unformat (i, "ll"))
8231         ll_option = 1;
8232       else if (unformat (i, "send"))
8233         send_unicast = 1;
8234       else if (unformat (i, "cease"))
8235         cease = 1;
8236       else if (unformat (i, "isno"))
8237         is_no = 1;
8238       else if (unformat (i, "def"))
8239         default_router = 1;
8240       else
8241         {
8242           clib_warning ("parse error '%U'", format_unformat_error, i);
8243           return -99;
8244         }
8245     }
8246
8247   if (sw_if_index_set == 0)
8248     {
8249       errmsg ("missing interface name or sw_if_index");
8250       return -99;
8251     }
8252
8253   /* Construct the API message */
8254   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8255
8256   mp->sw_if_index = ntohl (sw_if_index);
8257   mp->max_interval = ntohl (max_interval);
8258   mp->min_interval = ntohl (min_interval);
8259   mp->lifetime = ntohl (lifetime);
8260   mp->initial_count = ntohl (initial_count);
8261   mp->initial_interval = ntohl (initial_interval);
8262   mp->suppress = suppress;
8263   mp->managed = managed;
8264   mp->other = other;
8265   mp->ll_option = ll_option;
8266   mp->send_unicast = send_unicast;
8267   mp->cease = cease;
8268   mp->is_no = is_no;
8269   mp->default_router = default_router;
8270
8271   /* send it... */
8272   S (mp);
8273
8274   /* Wait for a reply, return good/bad news  */
8275   W (ret);
8276   return ret;
8277 }
8278
8279 static int
8280 api_set_arp_neighbor_limit (vat_main_t * vam)
8281 {
8282   unformat_input_t *i = vam->input;
8283   vl_api_set_arp_neighbor_limit_t *mp;
8284   u32 arp_nbr_limit;
8285   u8 limit_set = 0;
8286   u8 is_ipv6 = 0;
8287   int ret;
8288
8289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8290     {
8291       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8292         limit_set = 1;
8293       else if (unformat (i, "ipv6"))
8294         is_ipv6 = 1;
8295       else
8296         {
8297           clib_warning ("parse error '%U'", format_unformat_error, i);
8298           return -99;
8299         }
8300     }
8301
8302   if (limit_set == 0)
8303     {
8304       errmsg ("missing limit value");
8305       return -99;
8306     }
8307
8308   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8309
8310   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8311   mp->is_ipv6 = is_ipv6;
8312
8313   S (mp);
8314   W (ret);
8315   return ret;
8316 }
8317
8318 static int
8319 api_l2_patch_add_del (vat_main_t * vam)
8320 {
8321   unformat_input_t *i = vam->input;
8322   vl_api_l2_patch_add_del_t *mp;
8323   u32 rx_sw_if_index;
8324   u8 rx_sw_if_index_set = 0;
8325   u32 tx_sw_if_index;
8326   u8 tx_sw_if_index_set = 0;
8327   u8 is_add = 1;
8328   int ret;
8329
8330   /* Parse args required to build the message */
8331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8332     {
8333       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8334         rx_sw_if_index_set = 1;
8335       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8336         tx_sw_if_index_set = 1;
8337       else if (unformat (i, "rx"))
8338         {
8339           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8340             {
8341               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8342                             &rx_sw_if_index))
8343                 rx_sw_if_index_set = 1;
8344             }
8345           else
8346             break;
8347         }
8348       else if (unformat (i, "tx"))
8349         {
8350           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8351             {
8352               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8353                             &tx_sw_if_index))
8354                 tx_sw_if_index_set = 1;
8355             }
8356           else
8357             break;
8358         }
8359       else if (unformat (i, "del"))
8360         is_add = 0;
8361       else
8362         break;
8363     }
8364
8365   if (rx_sw_if_index_set == 0)
8366     {
8367       errmsg ("missing rx interface name or rx_sw_if_index");
8368       return -99;
8369     }
8370
8371   if (tx_sw_if_index_set == 0)
8372     {
8373       errmsg ("missing tx interface name or tx_sw_if_index");
8374       return -99;
8375     }
8376
8377   M (L2_PATCH_ADD_DEL, mp);
8378
8379   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8380   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8381   mp->is_add = is_add;
8382
8383   S (mp);
8384   W (ret);
8385   return ret;
8386 }
8387
8388 static int
8389 api_ioam_enable (vat_main_t * vam)
8390 {
8391   unformat_input_t *input = vam->input;
8392   vl_api_ioam_enable_t *mp;
8393   u32 id = 0;
8394   int has_trace_option = 0;
8395   int has_pot_option = 0;
8396   int has_seqno_option = 0;
8397   int has_analyse_option = 0;
8398   int ret;
8399
8400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8401     {
8402       if (unformat (input, "trace"))
8403         has_trace_option = 1;
8404       else if (unformat (input, "pot"))
8405         has_pot_option = 1;
8406       else if (unformat (input, "seqno"))
8407         has_seqno_option = 1;
8408       else if (unformat (input, "analyse"))
8409         has_analyse_option = 1;
8410       else
8411         break;
8412     }
8413   M (IOAM_ENABLE, mp);
8414   mp->id = htons (id);
8415   mp->seqno = has_seqno_option;
8416   mp->analyse = has_analyse_option;
8417   mp->pot_enable = has_pot_option;
8418   mp->trace_enable = has_trace_option;
8419
8420   S (mp);
8421   W (ret);
8422   return ret;
8423 }
8424
8425
8426 static int
8427 api_ioam_disable (vat_main_t * vam)
8428 {
8429   vl_api_ioam_disable_t *mp;
8430   int ret;
8431
8432   M (IOAM_DISABLE, mp);
8433   S (mp);
8434   W (ret);
8435   return ret;
8436 }
8437
8438 static int
8439 api_sr_tunnel_add_del (vat_main_t * vam)
8440 {
8441   unformat_input_t *i = vam->input;
8442   vl_api_sr_tunnel_add_del_t *mp;
8443   int is_del = 0;
8444   int pl_index;
8445   ip6_address_t src_address;
8446   int src_address_set = 0;
8447   ip6_address_t dst_address;
8448   u32 dst_mask_width;
8449   int dst_address_set = 0;
8450   u16 flags = 0;
8451   u32 rx_table_id = 0;
8452   u32 tx_table_id = 0;
8453   ip6_address_t *segments = 0;
8454   ip6_address_t *this_seg;
8455   ip6_address_t *tags = 0;
8456   ip6_address_t *this_tag;
8457   ip6_address_t next_address, tag;
8458   u8 *name = 0;
8459   u8 *policy_name = 0;
8460   int ret;
8461
8462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8463     {
8464       if (unformat (i, "del"))
8465         is_del = 1;
8466       else if (unformat (i, "name %s", &name))
8467         ;
8468       else if (unformat (i, "policy %s", &policy_name))
8469         ;
8470       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8471         ;
8472       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8473         ;
8474       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8475         src_address_set = 1;
8476       else if (unformat (i, "dst %U/%d",
8477                          unformat_ip6_address, &dst_address, &dst_mask_width))
8478         dst_address_set = 1;
8479       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8480         {
8481           vec_add2 (segments, this_seg, 1);
8482           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8483                        sizeof (*this_seg));
8484         }
8485       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8486         {
8487           vec_add2 (tags, this_tag, 1);
8488           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8489         }
8490       else if (unformat (i, "clean"))
8491         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8492       else if (unformat (i, "protected"))
8493         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8494       else if (unformat (i, "InPE %d", &pl_index))
8495         {
8496           if (pl_index <= 0 || pl_index > 4)
8497             {
8498             pl_index_range_error:
8499               errmsg ("pl index %d out of range", pl_index);
8500               return -99;
8501             }
8502           flags |=
8503             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8504         }
8505       else if (unformat (i, "EgPE %d", &pl_index))
8506         {
8507           if (pl_index <= 0 || pl_index > 4)
8508             goto pl_index_range_error;
8509           flags |=
8510             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8511         }
8512       else if (unformat (i, "OrgSrc %d", &pl_index))
8513         {
8514           if (pl_index <= 0 || pl_index > 4)
8515             goto pl_index_range_error;
8516           flags |=
8517             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8518         }
8519       else
8520         break;
8521     }
8522
8523   if (!src_address_set)
8524     {
8525       errmsg ("src address required");
8526       return -99;
8527     }
8528
8529   if (!dst_address_set)
8530     {
8531       errmsg ("dst address required");
8532       return -99;
8533     }
8534
8535   if (!segments)
8536     {
8537       errmsg ("at least one sr segment required");
8538       return -99;
8539     }
8540
8541   M2 (SR_TUNNEL_ADD_DEL, mp,
8542       vec_len (segments) * sizeof (ip6_address_t)
8543       + vec_len (tags) * sizeof (ip6_address_t));
8544
8545   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8546   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8547   mp->dst_mask_width = dst_mask_width;
8548   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8549   mp->n_segments = vec_len (segments);
8550   mp->n_tags = vec_len (tags);
8551   mp->is_add = is_del == 0;
8552   clib_memcpy (mp->segs_and_tags, segments,
8553                vec_len (segments) * sizeof (ip6_address_t));
8554   clib_memcpy (mp->segs_and_tags +
8555                vec_len (segments) * sizeof (ip6_address_t), tags,
8556                vec_len (tags) * sizeof (ip6_address_t));
8557
8558   mp->outer_vrf_id = ntohl (rx_table_id);
8559   mp->inner_vrf_id = ntohl (tx_table_id);
8560   memcpy (mp->name, name, vec_len (name));
8561   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8562
8563   vec_free (segments);
8564   vec_free (tags);
8565
8566   S (mp);
8567   W (ret);
8568   return ret;
8569 }
8570
8571 static int
8572 api_sr_policy_add_del (vat_main_t * vam)
8573 {
8574   unformat_input_t *input = vam->input;
8575   vl_api_sr_policy_add_del_t *mp;
8576   int is_del = 0;
8577   u8 *name = 0;
8578   u8 *tunnel_name = 0;
8579   u8 **tunnel_names = 0;
8580
8581   int name_set = 0;
8582   int tunnel_set = 0;
8583   int j = 0;
8584   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8585   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8586   int ret;
8587
8588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8589     {
8590       if (unformat (input, "del"))
8591         is_del = 1;
8592       else if (unformat (input, "name %s", &name))
8593         name_set = 1;
8594       else if (unformat (input, "tunnel %s", &tunnel_name))
8595         {
8596           if (tunnel_name)
8597             {
8598               vec_add1 (tunnel_names, tunnel_name);
8599               /* For serializer:
8600                  - length = #bytes to store in serial vector
8601                  - +1 = byte to store that length
8602                */
8603               tunnel_names_length += (vec_len (tunnel_name) + 1);
8604               tunnel_set = 1;
8605               tunnel_name = 0;
8606             }
8607         }
8608       else
8609         break;
8610     }
8611
8612   if (!name_set)
8613     {
8614       errmsg ("policy name required");
8615       return -99;
8616     }
8617
8618   if ((!tunnel_set) && (!is_del))
8619     {
8620       errmsg ("tunnel name required");
8621       return -99;
8622     }
8623
8624   M2 (SR_POLICY_ADD_DEL, mp, tunnel_names_length);
8625
8626
8627
8628   mp->is_add = !is_del;
8629
8630   memcpy (mp->name, name, vec_len (name));
8631   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8632   u8 *serial_orig = 0;
8633   vec_validate (serial_orig, tunnel_names_length);
8634   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8635   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8636
8637   for (j = 0; j < vec_len (tunnel_names); j++)
8638     {
8639       tun_name_len = vec_len (tunnel_names[j]);
8640       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8641       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8642       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8643       serial_orig += tun_name_len;      // Advance past the copy
8644     }
8645   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8646
8647   vec_free (tunnel_names);
8648   vec_free (tunnel_name);
8649
8650   S (mp);
8651   W (ret);
8652   return ret;
8653 }
8654
8655 static int
8656 api_sr_multicast_map_add_del (vat_main_t * vam)
8657 {
8658   unformat_input_t *input = vam->input;
8659   vl_api_sr_multicast_map_add_del_t *mp;
8660   int is_del = 0;
8661   ip6_address_t multicast_address;
8662   u8 *policy_name = 0;
8663   int multicast_address_set = 0;
8664   int ret;
8665
8666   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8667     {
8668       if (unformat (input, "del"))
8669         is_del = 1;
8670       else
8671         if (unformat
8672             (input, "address %U", unformat_ip6_address, &multicast_address))
8673         multicast_address_set = 1;
8674       else if (unformat (input, "sr-policy %s", &policy_name))
8675         ;
8676       else
8677         break;
8678     }
8679
8680   if (!is_del && !policy_name)
8681     {
8682       errmsg ("sr-policy name required");
8683       return -99;
8684     }
8685
8686
8687   if (!multicast_address_set)
8688     {
8689       errmsg ("address required");
8690       return -99;
8691     }
8692
8693   M (SR_MULTICAST_MAP_ADD_DEL, mp);
8694
8695   mp->is_add = !is_del;
8696   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8697   clib_memcpy (mp->multicast_address, &multicast_address,
8698                sizeof (mp->multicast_address));
8699
8700
8701   vec_free (policy_name);
8702
8703   S (mp);
8704   W (ret);
8705   return ret;
8706 }
8707
8708
8709 #define foreach_tcp_proto_field                 \
8710 _(src_port)                                     \
8711 _(dst_port)
8712
8713 #define foreach_udp_proto_field                 \
8714 _(src_port)                                     \
8715 _(dst_port)
8716
8717 #define foreach_ip4_proto_field                 \
8718 _(src_address)                                  \
8719 _(dst_address)                                  \
8720 _(tos)                                          \
8721 _(length)                                       \
8722 _(fragment_id)                                  \
8723 _(ttl)                                          \
8724 _(protocol)                                     \
8725 _(checksum)
8726
8727 uword
8728 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8729 {
8730   u8 **maskp = va_arg (*args, u8 **);
8731   u8 *mask = 0;
8732   u8 found_something = 0;
8733   tcp_header_t *tcp;
8734
8735 #define _(a) u8 a=0;
8736   foreach_tcp_proto_field;
8737 #undef _
8738
8739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8740     {
8741       if (0);
8742 #define _(a) else if (unformat (input, #a)) a=1;
8743       foreach_tcp_proto_field
8744 #undef _
8745         else
8746         break;
8747     }
8748
8749 #define _(a) found_something += a;
8750   foreach_tcp_proto_field;
8751 #undef _
8752
8753   if (found_something == 0)
8754     return 0;
8755
8756   vec_validate (mask, sizeof (*tcp) - 1);
8757
8758   tcp = (tcp_header_t *) mask;
8759
8760 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8761   foreach_tcp_proto_field;
8762 #undef _
8763
8764   *maskp = mask;
8765   return 1;
8766 }
8767
8768 uword
8769 unformat_udp_mask (unformat_input_t * input, va_list * args)
8770 {
8771   u8 **maskp = va_arg (*args, u8 **);
8772   u8 *mask = 0;
8773   u8 found_something = 0;
8774   udp_header_t *udp;
8775
8776 #define _(a) u8 a=0;
8777   foreach_udp_proto_field;
8778 #undef _
8779
8780   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8781     {
8782       if (0);
8783 #define _(a) else if (unformat (input, #a)) a=1;
8784       foreach_udp_proto_field
8785 #undef _
8786         else
8787         break;
8788     }
8789
8790 #define _(a) found_something += a;
8791   foreach_udp_proto_field;
8792 #undef _
8793
8794   if (found_something == 0)
8795     return 0;
8796
8797   vec_validate (mask, sizeof (*udp) - 1);
8798
8799   udp = (udp_header_t *) mask;
8800
8801 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8802   foreach_udp_proto_field;
8803 #undef _
8804
8805   *maskp = mask;
8806   return 1;
8807 }
8808
8809 typedef struct
8810 {
8811   u16 src_port, dst_port;
8812 } tcpudp_header_t;
8813
8814 uword
8815 unformat_l4_mask (unformat_input_t * input, va_list * args)
8816 {
8817   u8 **maskp = va_arg (*args, u8 **);
8818   u16 src_port = 0, dst_port = 0;
8819   tcpudp_header_t *tcpudp;
8820
8821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8822     {
8823       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8824         return 1;
8825       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8826         return 1;
8827       else if (unformat (input, "src_port"))
8828         src_port = 0xFFFF;
8829       else if (unformat (input, "dst_port"))
8830         dst_port = 0xFFFF;
8831       else
8832         return 0;
8833     }
8834
8835   if (!src_port && !dst_port)
8836     return 0;
8837
8838   u8 *mask = 0;
8839   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8840
8841   tcpudp = (tcpudp_header_t *) mask;
8842   tcpudp->src_port = src_port;
8843   tcpudp->dst_port = dst_port;
8844
8845   *maskp = mask;
8846
8847   return 1;
8848 }
8849
8850 uword
8851 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8852 {
8853   u8 **maskp = va_arg (*args, u8 **);
8854   u8 *mask = 0;
8855   u8 found_something = 0;
8856   ip4_header_t *ip;
8857
8858 #define _(a) u8 a=0;
8859   foreach_ip4_proto_field;
8860 #undef _
8861   u8 version = 0;
8862   u8 hdr_length = 0;
8863
8864
8865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8866     {
8867       if (unformat (input, "version"))
8868         version = 1;
8869       else if (unformat (input, "hdr_length"))
8870         hdr_length = 1;
8871       else if (unformat (input, "src"))
8872         src_address = 1;
8873       else if (unformat (input, "dst"))
8874         dst_address = 1;
8875       else if (unformat (input, "proto"))
8876         protocol = 1;
8877
8878 #define _(a) else if (unformat (input, #a)) a=1;
8879       foreach_ip4_proto_field
8880 #undef _
8881         else
8882         break;
8883     }
8884
8885 #define _(a) found_something += a;
8886   foreach_ip4_proto_field;
8887 #undef _
8888
8889   if (found_something == 0)
8890     return 0;
8891
8892   vec_validate (mask, sizeof (*ip) - 1);
8893
8894   ip = (ip4_header_t *) mask;
8895
8896 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8897   foreach_ip4_proto_field;
8898 #undef _
8899
8900   ip->ip_version_and_header_length = 0;
8901
8902   if (version)
8903     ip->ip_version_and_header_length |= 0xF0;
8904
8905   if (hdr_length)
8906     ip->ip_version_and_header_length |= 0x0F;
8907
8908   *maskp = mask;
8909   return 1;
8910 }
8911
8912 #define foreach_ip6_proto_field                 \
8913 _(src_address)                                  \
8914 _(dst_address)                                  \
8915 _(payload_length)                               \
8916 _(hop_limit)                                    \
8917 _(protocol)
8918
8919 uword
8920 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8921 {
8922   u8 **maskp = va_arg (*args, u8 **);
8923   u8 *mask = 0;
8924   u8 found_something = 0;
8925   ip6_header_t *ip;
8926   u32 ip_version_traffic_class_and_flow_label;
8927
8928 #define _(a) u8 a=0;
8929   foreach_ip6_proto_field;
8930 #undef _
8931   u8 version = 0;
8932   u8 traffic_class = 0;
8933   u8 flow_label = 0;
8934
8935   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8936     {
8937       if (unformat (input, "version"))
8938         version = 1;
8939       else if (unformat (input, "traffic-class"))
8940         traffic_class = 1;
8941       else if (unformat (input, "flow-label"))
8942         flow_label = 1;
8943       else if (unformat (input, "src"))
8944         src_address = 1;
8945       else if (unformat (input, "dst"))
8946         dst_address = 1;
8947       else if (unformat (input, "proto"))
8948         protocol = 1;
8949
8950 #define _(a) else if (unformat (input, #a)) a=1;
8951       foreach_ip6_proto_field
8952 #undef _
8953         else
8954         break;
8955     }
8956
8957 #define _(a) found_something += a;
8958   foreach_ip6_proto_field;
8959 #undef _
8960
8961   if (found_something == 0)
8962     return 0;
8963
8964   vec_validate (mask, sizeof (*ip) - 1);
8965
8966   ip = (ip6_header_t *) mask;
8967
8968 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8969   foreach_ip6_proto_field;
8970 #undef _
8971
8972   ip_version_traffic_class_and_flow_label = 0;
8973
8974   if (version)
8975     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8976
8977   if (traffic_class)
8978     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8979
8980   if (flow_label)
8981     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8982
8983   ip->ip_version_traffic_class_and_flow_label =
8984     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8985
8986   *maskp = mask;
8987   return 1;
8988 }
8989
8990 uword
8991 unformat_l3_mask (unformat_input_t * input, va_list * args)
8992 {
8993   u8 **maskp = va_arg (*args, u8 **);
8994
8995   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8996     {
8997       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8998         return 1;
8999       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9000         return 1;
9001       else
9002         break;
9003     }
9004   return 0;
9005 }
9006
9007 uword
9008 unformat_l2_mask (unformat_input_t * input, va_list * args)
9009 {
9010   u8 **maskp = va_arg (*args, u8 **);
9011   u8 *mask = 0;
9012   u8 src = 0;
9013   u8 dst = 0;
9014   u8 proto = 0;
9015   u8 tag1 = 0;
9016   u8 tag2 = 0;
9017   u8 ignore_tag1 = 0;
9018   u8 ignore_tag2 = 0;
9019   u8 cos1 = 0;
9020   u8 cos2 = 0;
9021   u8 dot1q = 0;
9022   u8 dot1ad = 0;
9023   int len = 14;
9024
9025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9026     {
9027       if (unformat (input, "src"))
9028         src = 1;
9029       else if (unformat (input, "dst"))
9030         dst = 1;
9031       else if (unformat (input, "proto"))
9032         proto = 1;
9033       else if (unformat (input, "tag1"))
9034         tag1 = 1;
9035       else if (unformat (input, "tag2"))
9036         tag2 = 1;
9037       else if (unformat (input, "ignore-tag1"))
9038         ignore_tag1 = 1;
9039       else if (unformat (input, "ignore-tag2"))
9040         ignore_tag2 = 1;
9041       else if (unformat (input, "cos1"))
9042         cos1 = 1;
9043       else if (unformat (input, "cos2"))
9044         cos2 = 1;
9045       else if (unformat (input, "dot1q"))
9046         dot1q = 1;
9047       else if (unformat (input, "dot1ad"))
9048         dot1ad = 1;
9049       else
9050         break;
9051     }
9052   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9053        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9054     return 0;
9055
9056   if (tag1 || ignore_tag1 || cos1 || dot1q)
9057     len = 18;
9058   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9059     len = 22;
9060
9061   vec_validate (mask, len - 1);
9062
9063   if (dst)
9064     memset (mask, 0xff, 6);
9065
9066   if (src)
9067     memset (mask + 6, 0xff, 6);
9068
9069   if (tag2 || dot1ad)
9070     {
9071       /* inner vlan tag */
9072       if (tag2)
9073         {
9074           mask[19] = 0xff;
9075           mask[18] = 0x0f;
9076         }
9077       if (cos2)
9078         mask[18] |= 0xe0;
9079       if (proto)
9080         mask[21] = mask[20] = 0xff;
9081       if (tag1)
9082         {
9083           mask[15] = 0xff;
9084           mask[14] = 0x0f;
9085         }
9086       if (cos1)
9087         mask[14] |= 0xe0;
9088       *maskp = mask;
9089       return 1;
9090     }
9091   if (tag1 | dot1q)
9092     {
9093       if (tag1)
9094         {
9095           mask[15] = 0xff;
9096           mask[14] = 0x0f;
9097         }
9098       if (cos1)
9099         mask[14] |= 0xe0;
9100       if (proto)
9101         mask[16] = mask[17] = 0xff;
9102
9103       *maskp = mask;
9104       return 1;
9105     }
9106   if (cos2)
9107     mask[18] |= 0xe0;
9108   if (cos1)
9109     mask[14] |= 0xe0;
9110   if (proto)
9111     mask[12] = mask[13] = 0xff;
9112
9113   *maskp = mask;
9114   return 1;
9115 }
9116
9117 uword
9118 unformat_classify_mask (unformat_input_t * input, va_list * args)
9119 {
9120   u8 **maskp = va_arg (*args, u8 **);
9121   u32 *skipp = va_arg (*args, u32 *);
9122   u32 *matchp = va_arg (*args, u32 *);
9123   u32 match;
9124   u8 *mask = 0;
9125   u8 *l2 = 0;
9126   u8 *l3 = 0;
9127   u8 *l4 = 0;
9128   int i;
9129
9130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9131     {
9132       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9133         ;
9134       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9135         ;
9136       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9137         ;
9138       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9139         ;
9140       else
9141         break;
9142     }
9143
9144   if (l4 && !l3)
9145     {
9146       vec_free (mask);
9147       vec_free (l2);
9148       vec_free (l4);
9149       return 0;
9150     }
9151
9152   if (mask || l2 || l3 || l4)
9153     {
9154       if (l2 || l3 || l4)
9155         {
9156           /* "With a free Ethernet header in every package" */
9157           if (l2 == 0)
9158             vec_validate (l2, 13);
9159           mask = l2;
9160           if (vec_len (l3))
9161             {
9162               vec_append (mask, l3);
9163               vec_free (l3);
9164             }
9165           if (vec_len (l4))
9166             {
9167               vec_append (mask, l4);
9168               vec_free (l4);
9169             }
9170         }
9171
9172       /* Scan forward looking for the first significant mask octet */
9173       for (i = 0; i < vec_len (mask); i++)
9174         if (mask[i])
9175           break;
9176
9177       /* compute (skip, match) params */
9178       *skipp = i / sizeof (u32x4);
9179       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9180
9181       /* Pad mask to an even multiple of the vector size */
9182       while (vec_len (mask) % sizeof (u32x4))
9183         vec_add1 (mask, 0);
9184
9185       match = vec_len (mask) / sizeof (u32x4);
9186
9187       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9188         {
9189           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9190           if (*tmp || *(tmp + 1))
9191             break;
9192           match--;
9193         }
9194       if (match == 0)
9195         clib_warning ("BUG: match 0");
9196
9197       _vec_len (mask) = match * sizeof (u32x4);
9198
9199       *matchp = match;
9200       *maskp = mask;
9201
9202       return 1;
9203     }
9204
9205   return 0;
9206 }
9207
9208 #define foreach_l2_next                         \
9209 _(drop, DROP)                                   \
9210 _(ethernet, ETHERNET_INPUT)                     \
9211 _(ip4, IP4_INPUT)                               \
9212 _(ip6, IP6_INPUT)
9213
9214 uword
9215 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9216 {
9217   u32 *miss_next_indexp = va_arg (*args, u32 *);
9218   u32 next_index = 0;
9219   u32 tmp;
9220
9221 #define _(n,N) \
9222   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9223   foreach_l2_next;
9224 #undef _
9225
9226   if (unformat (input, "%d", &tmp))
9227     {
9228       next_index = tmp;
9229       goto out;
9230     }
9231
9232   return 0;
9233
9234 out:
9235   *miss_next_indexp = next_index;
9236   return 1;
9237 }
9238
9239 #define foreach_ip_next                         \
9240 _(drop, DROP)                                   \
9241 _(local, LOCAL)                                 \
9242 _(rewrite, REWRITE)
9243
9244 uword
9245 unformat_ip_next_index (unformat_input_t * input, va_list * args)
9246 {
9247   u32 *miss_next_indexp = va_arg (*args, u32 *);
9248   u32 next_index = 0;
9249   u32 tmp;
9250
9251 #define _(n,N) \
9252   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9253   foreach_ip_next;
9254 #undef _
9255
9256   if (unformat (input, "%d", &tmp))
9257     {
9258       next_index = tmp;
9259       goto out;
9260     }
9261
9262   return 0;
9263
9264 out:
9265   *miss_next_indexp = next_index;
9266   return 1;
9267 }
9268
9269 #define foreach_acl_next                        \
9270 _(deny, DENY)
9271
9272 uword
9273 unformat_acl_next_index (unformat_input_t * input, va_list * args)
9274 {
9275   u32 *miss_next_indexp = va_arg (*args, u32 *);
9276   u32 next_index = 0;
9277   u32 tmp;
9278
9279 #define _(n,N) \
9280   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9281   foreach_acl_next;
9282 #undef _
9283
9284   if (unformat (input, "permit"))
9285     {
9286       next_index = ~0;
9287       goto out;
9288     }
9289   else if (unformat (input, "%d", &tmp))
9290     {
9291       next_index = tmp;
9292       goto out;
9293     }
9294
9295   return 0;
9296
9297 out:
9298   *miss_next_indexp = next_index;
9299   return 1;
9300 }
9301
9302 uword
9303 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9304 {
9305   u32 *r = va_arg (*args, u32 *);
9306
9307   if (unformat (input, "conform-color"))
9308     *r = POLICE_CONFORM;
9309   else if (unformat (input, "exceed-color"))
9310     *r = POLICE_EXCEED;
9311   else
9312     return 0;
9313
9314   return 1;
9315 }
9316
9317 static int
9318 api_classify_add_del_table (vat_main_t * vam)
9319 {
9320   unformat_input_t *i = vam->input;
9321   vl_api_classify_add_del_table_t *mp;
9322
9323   u32 nbuckets = 2;
9324   u32 skip = ~0;
9325   u32 match = ~0;
9326   int is_add = 1;
9327   int del_chain = 0;
9328   u32 table_index = ~0;
9329   u32 next_table_index = ~0;
9330   u32 miss_next_index = ~0;
9331   u32 memory_size = 32 << 20;
9332   u8 *mask = 0;
9333   u32 current_data_flag = 0;
9334   int current_data_offset = 0;
9335   int ret;
9336
9337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9338     {
9339       if (unformat (i, "del"))
9340         is_add = 0;
9341       else if (unformat (i, "del-chain"))
9342         {
9343           is_add = 0;
9344           del_chain = 1;
9345         }
9346       else if (unformat (i, "buckets %d", &nbuckets))
9347         ;
9348       else if (unformat (i, "memory_size %d", &memory_size))
9349         ;
9350       else if (unformat (i, "skip %d", &skip))
9351         ;
9352       else if (unformat (i, "match %d", &match))
9353         ;
9354       else if (unformat (i, "table %d", &table_index))
9355         ;
9356       else if (unformat (i, "mask %U", unformat_classify_mask,
9357                          &mask, &skip, &match))
9358         ;
9359       else if (unformat (i, "next-table %d", &next_table_index))
9360         ;
9361       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
9362                          &miss_next_index))
9363         ;
9364       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9365                          &miss_next_index))
9366         ;
9367       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9368                          &miss_next_index))
9369         ;
9370       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9371         ;
9372       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9373         ;
9374       else
9375         break;
9376     }
9377
9378   if (is_add && mask == 0)
9379     {
9380       errmsg ("Mask required");
9381       return -99;
9382     }
9383
9384   if (is_add && skip == ~0)
9385     {
9386       errmsg ("skip count required");
9387       return -99;
9388     }
9389
9390   if (is_add && match == ~0)
9391     {
9392       errmsg ("match count required");
9393       return -99;
9394     }
9395
9396   if (!is_add && table_index == ~0)
9397     {
9398       errmsg ("table index required for delete");
9399       return -99;
9400     }
9401
9402   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9403
9404   mp->is_add = is_add;
9405   mp->del_chain = del_chain;
9406   mp->table_index = ntohl (table_index);
9407   mp->nbuckets = ntohl (nbuckets);
9408   mp->memory_size = ntohl (memory_size);
9409   mp->skip_n_vectors = ntohl (skip);
9410   mp->match_n_vectors = ntohl (match);
9411   mp->next_table_index = ntohl (next_table_index);
9412   mp->miss_next_index = ntohl (miss_next_index);
9413   mp->current_data_flag = ntohl (current_data_flag);
9414   mp->current_data_offset = ntohl (current_data_offset);
9415   clib_memcpy (mp->mask, mask, vec_len (mask));
9416
9417   vec_free (mask);
9418
9419   S (mp);
9420   W (ret);
9421   return ret;
9422 }
9423
9424 uword
9425 unformat_l4_match (unformat_input_t * input, va_list * args)
9426 {
9427   u8 **matchp = va_arg (*args, u8 **);
9428
9429   u8 *proto_header = 0;
9430   int src_port = 0;
9431   int dst_port = 0;
9432
9433   tcpudp_header_t h;
9434
9435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9436     {
9437       if (unformat (input, "src_port %d", &src_port))
9438         ;
9439       else if (unformat (input, "dst_port %d", &dst_port))
9440         ;
9441       else
9442         return 0;
9443     }
9444
9445   h.src_port = clib_host_to_net_u16 (src_port);
9446   h.dst_port = clib_host_to_net_u16 (dst_port);
9447   vec_validate (proto_header, sizeof (h) - 1);
9448   memcpy (proto_header, &h, sizeof (h));
9449
9450   *matchp = proto_header;
9451
9452   return 1;
9453 }
9454
9455 uword
9456 unformat_ip4_match (unformat_input_t * input, va_list * args)
9457 {
9458   u8 **matchp = va_arg (*args, u8 **);
9459   u8 *match = 0;
9460   ip4_header_t *ip;
9461   int version = 0;
9462   u32 version_val;
9463   int hdr_length = 0;
9464   u32 hdr_length_val;
9465   int src = 0, dst = 0;
9466   ip4_address_t src_val, dst_val;
9467   int proto = 0;
9468   u32 proto_val;
9469   int tos = 0;
9470   u32 tos_val;
9471   int length = 0;
9472   u32 length_val;
9473   int fragment_id = 0;
9474   u32 fragment_id_val;
9475   int ttl = 0;
9476   int ttl_val;
9477   int checksum = 0;
9478   u32 checksum_val;
9479
9480   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9481     {
9482       if (unformat (input, "version %d", &version_val))
9483         version = 1;
9484       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9485         hdr_length = 1;
9486       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9487         src = 1;
9488       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9489         dst = 1;
9490       else if (unformat (input, "proto %d", &proto_val))
9491         proto = 1;
9492       else if (unformat (input, "tos %d", &tos_val))
9493         tos = 1;
9494       else if (unformat (input, "length %d", &length_val))
9495         length = 1;
9496       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9497         fragment_id = 1;
9498       else if (unformat (input, "ttl %d", &ttl_val))
9499         ttl = 1;
9500       else if (unformat (input, "checksum %d", &checksum_val))
9501         checksum = 1;
9502       else
9503         break;
9504     }
9505
9506   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9507       + ttl + checksum == 0)
9508     return 0;
9509
9510   /*
9511    * Aligned because we use the real comparison functions
9512    */
9513   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9514
9515   ip = (ip4_header_t *) match;
9516
9517   /* These are realistically matched in practice */
9518   if (src)
9519     ip->src_address.as_u32 = src_val.as_u32;
9520
9521   if (dst)
9522     ip->dst_address.as_u32 = dst_val.as_u32;
9523
9524   if (proto)
9525     ip->protocol = proto_val;
9526
9527
9528   /* These are not, but they're included for completeness */
9529   if (version)
9530     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9531
9532   if (hdr_length)
9533     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9534
9535   if (tos)
9536     ip->tos = tos_val;
9537
9538   if (length)
9539     ip->length = clib_host_to_net_u16 (length_val);
9540
9541   if (ttl)
9542     ip->ttl = ttl_val;
9543
9544   if (checksum)
9545     ip->checksum = clib_host_to_net_u16 (checksum_val);
9546
9547   *matchp = match;
9548   return 1;
9549 }
9550
9551 uword
9552 unformat_ip6_match (unformat_input_t * input, va_list * args)
9553 {
9554   u8 **matchp = va_arg (*args, u8 **);
9555   u8 *match = 0;
9556   ip6_header_t *ip;
9557   int version = 0;
9558   u32 version_val;
9559   u8 traffic_class = 0;
9560   u32 traffic_class_val = 0;
9561   u8 flow_label = 0;
9562   u8 flow_label_val;
9563   int src = 0, dst = 0;
9564   ip6_address_t src_val, dst_val;
9565   int proto = 0;
9566   u32 proto_val;
9567   int payload_length = 0;
9568   u32 payload_length_val;
9569   int hop_limit = 0;
9570   int hop_limit_val;
9571   u32 ip_version_traffic_class_and_flow_label;
9572
9573   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9574     {
9575       if (unformat (input, "version %d", &version_val))
9576         version = 1;
9577       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9578         traffic_class = 1;
9579       else if (unformat (input, "flow_label %d", &flow_label_val))
9580         flow_label = 1;
9581       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9582         src = 1;
9583       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9584         dst = 1;
9585       else if (unformat (input, "proto %d", &proto_val))
9586         proto = 1;
9587       else if (unformat (input, "payload_length %d", &payload_length_val))
9588         payload_length = 1;
9589       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9590         hop_limit = 1;
9591       else
9592         break;
9593     }
9594
9595   if (version + traffic_class + flow_label + src + dst + proto +
9596       payload_length + hop_limit == 0)
9597     return 0;
9598
9599   /*
9600    * Aligned because we use the real comparison functions
9601    */
9602   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9603
9604   ip = (ip6_header_t *) match;
9605
9606   if (src)
9607     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9608
9609   if (dst)
9610     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9611
9612   if (proto)
9613     ip->protocol = proto_val;
9614
9615   ip_version_traffic_class_and_flow_label = 0;
9616
9617   if (version)
9618     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9619
9620   if (traffic_class)
9621     ip_version_traffic_class_and_flow_label |=
9622       (traffic_class_val & 0xFF) << 20;
9623
9624   if (flow_label)
9625     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9626
9627   ip->ip_version_traffic_class_and_flow_label =
9628     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9629
9630   if (payload_length)
9631     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9632
9633   if (hop_limit)
9634     ip->hop_limit = hop_limit_val;
9635
9636   *matchp = match;
9637   return 1;
9638 }
9639
9640 uword
9641 unformat_l3_match (unformat_input_t * input, va_list * args)
9642 {
9643   u8 **matchp = va_arg (*args, u8 **);
9644
9645   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9646     {
9647       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9648         return 1;
9649       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9650         return 1;
9651       else
9652         break;
9653     }
9654   return 0;
9655 }
9656
9657 uword
9658 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9659 {
9660   u8 *tagp = va_arg (*args, u8 *);
9661   u32 tag;
9662
9663   if (unformat (input, "%d", &tag))
9664     {
9665       tagp[0] = (tag >> 8) & 0x0F;
9666       tagp[1] = tag & 0xFF;
9667       return 1;
9668     }
9669
9670   return 0;
9671 }
9672
9673 uword
9674 unformat_l2_match (unformat_input_t * input, va_list * args)
9675 {
9676   u8 **matchp = va_arg (*args, u8 **);
9677   u8 *match = 0;
9678   u8 src = 0;
9679   u8 src_val[6];
9680   u8 dst = 0;
9681   u8 dst_val[6];
9682   u8 proto = 0;
9683   u16 proto_val;
9684   u8 tag1 = 0;
9685   u8 tag1_val[2];
9686   u8 tag2 = 0;
9687   u8 tag2_val[2];
9688   int len = 14;
9689   u8 ignore_tag1 = 0;
9690   u8 ignore_tag2 = 0;
9691   u8 cos1 = 0;
9692   u8 cos2 = 0;
9693   u32 cos1_val = 0;
9694   u32 cos2_val = 0;
9695
9696   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9697     {
9698       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9699         src = 1;
9700       else
9701         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9702         dst = 1;
9703       else if (unformat (input, "proto %U",
9704                          unformat_ethernet_type_host_byte_order, &proto_val))
9705         proto = 1;
9706       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9707         tag1 = 1;
9708       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9709         tag2 = 1;
9710       else if (unformat (input, "ignore-tag1"))
9711         ignore_tag1 = 1;
9712       else if (unformat (input, "ignore-tag2"))
9713         ignore_tag2 = 1;
9714       else if (unformat (input, "cos1 %d", &cos1_val))
9715         cos1 = 1;
9716       else if (unformat (input, "cos2 %d", &cos2_val))
9717         cos2 = 1;
9718       else
9719         break;
9720     }
9721   if ((src + dst + proto + tag1 + tag2 +
9722        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9723     return 0;
9724
9725   if (tag1 || ignore_tag1 || cos1)
9726     len = 18;
9727   if (tag2 || ignore_tag2 || cos2)
9728     len = 22;
9729
9730   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9731
9732   if (dst)
9733     clib_memcpy (match, dst_val, 6);
9734
9735   if (src)
9736     clib_memcpy (match + 6, src_val, 6);
9737
9738   if (tag2)
9739     {
9740       /* inner vlan tag */
9741       match[19] = tag2_val[1];
9742       match[18] = tag2_val[0];
9743       if (cos2)
9744         match[18] |= (cos2_val & 0x7) << 5;
9745       if (proto)
9746         {
9747           match[21] = proto_val & 0xff;
9748           match[20] = proto_val >> 8;
9749         }
9750       if (tag1)
9751         {
9752           match[15] = tag1_val[1];
9753           match[14] = tag1_val[0];
9754         }
9755       if (cos1)
9756         match[14] |= (cos1_val & 0x7) << 5;
9757       *matchp = match;
9758       return 1;
9759     }
9760   if (tag1)
9761     {
9762       match[15] = tag1_val[1];
9763       match[14] = tag1_val[0];
9764       if (proto)
9765         {
9766           match[17] = proto_val & 0xff;
9767           match[16] = proto_val >> 8;
9768         }
9769       if (cos1)
9770         match[14] |= (cos1_val & 0x7) << 5;
9771
9772       *matchp = match;
9773       return 1;
9774     }
9775   if (cos2)
9776     match[18] |= (cos2_val & 0x7) << 5;
9777   if (cos1)
9778     match[14] |= (cos1_val & 0x7) << 5;
9779   if (proto)
9780     {
9781       match[13] = proto_val & 0xff;
9782       match[12] = proto_val >> 8;
9783     }
9784
9785   *matchp = match;
9786   return 1;
9787 }
9788
9789
9790 uword
9791 unformat_classify_match (unformat_input_t * input, va_list * args)
9792 {
9793   u8 **matchp = va_arg (*args, u8 **);
9794   u32 skip_n_vectors = va_arg (*args, u32);
9795   u32 match_n_vectors = va_arg (*args, u32);
9796
9797   u8 *match = 0;
9798   u8 *l2 = 0;
9799   u8 *l3 = 0;
9800   u8 *l4 = 0;
9801
9802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9803     {
9804       if (unformat (input, "hex %U", unformat_hex_string, &match))
9805         ;
9806       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9807         ;
9808       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9809         ;
9810       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9811         ;
9812       else
9813         break;
9814     }
9815
9816   if (l4 && !l3)
9817     {
9818       vec_free (match);
9819       vec_free (l2);
9820       vec_free (l4);
9821       return 0;
9822     }
9823
9824   if (match || l2 || l3 || l4)
9825     {
9826       if (l2 || l3 || l4)
9827         {
9828           /* "Win a free Ethernet header in every packet" */
9829           if (l2 == 0)
9830             vec_validate_aligned (l2, 13, sizeof (u32x4));
9831           match = l2;
9832           if (vec_len (l3))
9833             {
9834               vec_append_aligned (match, l3, sizeof (u32x4));
9835               vec_free (l3);
9836             }
9837           if (vec_len (l4))
9838             {
9839               vec_append_aligned (match, l4, sizeof (u32x4));
9840               vec_free (l4);
9841             }
9842         }
9843
9844       /* Make sure the vector is big enough even if key is all 0's */
9845       vec_validate_aligned
9846         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9847          sizeof (u32x4));
9848
9849       /* Set size, include skipped vectors */
9850       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9851
9852       *matchp = match;
9853
9854       return 1;
9855     }
9856
9857   return 0;
9858 }
9859
9860 static int
9861 api_classify_add_del_session (vat_main_t * vam)
9862 {
9863   unformat_input_t *i = vam->input;
9864   vl_api_classify_add_del_session_t *mp;
9865   int is_add = 1;
9866   u32 table_index = ~0;
9867   u32 hit_next_index = ~0;
9868   u32 opaque_index = ~0;
9869   u8 *match = 0;
9870   i32 advance = 0;
9871   u32 skip_n_vectors = 0;
9872   u32 match_n_vectors = 0;
9873   u32 action = 0;
9874   u32 metadata = 0;
9875   int ret;
9876
9877   /*
9878    * Warning: you have to supply skip_n and match_n
9879    * because the API client cant simply look at the classify
9880    * table object.
9881    */
9882
9883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9884     {
9885       if (unformat (i, "del"))
9886         is_add = 0;
9887       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9888                          &hit_next_index))
9889         ;
9890       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9891                          &hit_next_index))
9892         ;
9893       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9894                          &hit_next_index))
9895         ;
9896       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9897         ;
9898       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9899         ;
9900       else if (unformat (i, "opaque-index %d", &opaque_index))
9901         ;
9902       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9903         ;
9904       else if (unformat (i, "match_n %d", &match_n_vectors))
9905         ;
9906       else if (unformat (i, "match %U", unformat_classify_match,
9907                          &match, skip_n_vectors, match_n_vectors))
9908         ;
9909       else if (unformat (i, "advance %d", &advance))
9910         ;
9911       else if (unformat (i, "table-index %d", &table_index))
9912         ;
9913       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9914         action = 1;
9915       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9916         action = 2;
9917       else if (unformat (i, "action %d", &action))
9918         ;
9919       else if (unformat (i, "metadata %d", &metadata))
9920         ;
9921       else
9922         break;
9923     }
9924
9925   if (table_index == ~0)
9926     {
9927       errmsg ("Table index required");
9928       return -99;
9929     }
9930
9931   if (is_add && match == 0)
9932     {
9933       errmsg ("Match value required");
9934       return -99;
9935     }
9936
9937   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9938
9939   mp->is_add = is_add;
9940   mp->table_index = ntohl (table_index);
9941   mp->hit_next_index = ntohl (hit_next_index);
9942   mp->opaque_index = ntohl (opaque_index);
9943   mp->advance = ntohl (advance);
9944   mp->action = action;
9945   mp->metadata = ntohl (metadata);
9946   clib_memcpy (mp->match, match, vec_len (match));
9947   vec_free (match);
9948
9949   S (mp);
9950   W (ret);
9951   return ret;
9952 }
9953
9954 static int
9955 api_classify_set_interface_ip_table (vat_main_t * vam)
9956 {
9957   unformat_input_t *i = vam->input;
9958   vl_api_classify_set_interface_ip_table_t *mp;
9959   u32 sw_if_index;
9960   int sw_if_index_set;
9961   u32 table_index = ~0;
9962   u8 is_ipv6 = 0;
9963   int ret;
9964
9965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9966     {
9967       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9968         sw_if_index_set = 1;
9969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9970         sw_if_index_set = 1;
9971       else if (unformat (i, "table %d", &table_index))
9972         ;
9973       else
9974         {
9975           clib_warning ("parse error '%U'", format_unformat_error, i);
9976           return -99;
9977         }
9978     }
9979
9980   if (sw_if_index_set == 0)
9981     {
9982       errmsg ("missing interface name or sw_if_index");
9983       return -99;
9984     }
9985
9986
9987   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9988
9989   mp->sw_if_index = ntohl (sw_if_index);
9990   mp->table_index = ntohl (table_index);
9991   mp->is_ipv6 = is_ipv6;
9992
9993   S (mp);
9994   W (ret);
9995   return ret;
9996 }
9997
9998 static int
9999 api_classify_set_interface_l2_tables (vat_main_t * vam)
10000 {
10001   unformat_input_t *i = vam->input;
10002   vl_api_classify_set_interface_l2_tables_t *mp;
10003   u32 sw_if_index;
10004   int sw_if_index_set;
10005   u32 ip4_table_index = ~0;
10006   u32 ip6_table_index = ~0;
10007   u32 other_table_index = ~0;
10008   u32 is_input = 1;
10009   int ret;
10010
10011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10012     {
10013       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10014         sw_if_index_set = 1;
10015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10016         sw_if_index_set = 1;
10017       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10018         ;
10019       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10020         ;
10021       else if (unformat (i, "other-table %d", &other_table_index))
10022         ;
10023       else if (unformat (i, "is-input %d", &is_input))
10024         ;
10025       else
10026         {
10027           clib_warning ("parse error '%U'", format_unformat_error, i);
10028           return -99;
10029         }
10030     }
10031
10032   if (sw_if_index_set == 0)
10033     {
10034       errmsg ("missing interface name or sw_if_index");
10035       return -99;
10036     }
10037
10038
10039   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10040
10041   mp->sw_if_index = ntohl (sw_if_index);
10042   mp->ip4_table_index = ntohl (ip4_table_index);
10043   mp->ip6_table_index = ntohl (ip6_table_index);
10044   mp->other_table_index = ntohl (other_table_index);
10045   mp->is_input = (u8) is_input;
10046
10047   S (mp);
10048   W (ret);
10049   return ret;
10050 }
10051
10052 static int
10053 api_set_ipfix_exporter (vat_main_t * vam)
10054 {
10055   unformat_input_t *i = vam->input;
10056   vl_api_set_ipfix_exporter_t *mp;
10057   ip4_address_t collector_address;
10058   u8 collector_address_set = 0;
10059   u32 collector_port = ~0;
10060   ip4_address_t src_address;
10061   u8 src_address_set = 0;
10062   u32 vrf_id = ~0;
10063   u32 path_mtu = ~0;
10064   u32 template_interval = ~0;
10065   u8 udp_checksum = 0;
10066   int ret;
10067
10068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10069     {
10070       if (unformat (i, "collector_address %U", unformat_ip4_address,
10071                     &collector_address))
10072         collector_address_set = 1;
10073       else if (unformat (i, "collector_port %d", &collector_port))
10074         ;
10075       else if (unformat (i, "src_address %U", unformat_ip4_address,
10076                          &src_address))
10077         src_address_set = 1;
10078       else if (unformat (i, "vrf_id %d", &vrf_id))
10079         ;
10080       else if (unformat (i, "path_mtu %d", &path_mtu))
10081         ;
10082       else if (unformat (i, "template_interval %d", &template_interval))
10083         ;
10084       else if (unformat (i, "udp_checksum"))
10085         udp_checksum = 1;
10086       else
10087         break;
10088     }
10089
10090   if (collector_address_set == 0)
10091     {
10092       errmsg ("collector_address required");
10093       return -99;
10094     }
10095
10096   if (src_address_set == 0)
10097     {
10098       errmsg ("src_address required");
10099       return -99;
10100     }
10101
10102   M (SET_IPFIX_EXPORTER, mp);
10103
10104   memcpy (mp->collector_address, collector_address.data,
10105           sizeof (collector_address.data));
10106   mp->collector_port = htons ((u16) collector_port);
10107   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10108   mp->vrf_id = htonl (vrf_id);
10109   mp->path_mtu = htonl (path_mtu);
10110   mp->template_interval = htonl (template_interval);
10111   mp->udp_checksum = udp_checksum;
10112
10113   S (mp);
10114   W (ret);
10115   return ret;
10116 }
10117
10118 static int
10119 api_set_ipfix_classify_stream (vat_main_t * vam)
10120 {
10121   unformat_input_t *i = vam->input;
10122   vl_api_set_ipfix_classify_stream_t *mp;
10123   u32 domain_id = 0;
10124   u32 src_port = UDP_DST_PORT_ipfix;
10125   int ret;
10126
10127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10128     {
10129       if (unformat (i, "domain %d", &domain_id))
10130         ;
10131       else if (unformat (i, "src_port %d", &src_port))
10132         ;
10133       else
10134         {
10135           errmsg ("unknown input `%U'", format_unformat_error, i);
10136           return -99;
10137         }
10138     }
10139
10140   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10141
10142   mp->domain_id = htonl (domain_id);
10143   mp->src_port = htons ((u16) src_port);
10144
10145   S (mp);
10146   W (ret);
10147   return ret;
10148 }
10149
10150 static int
10151 api_ipfix_classify_table_add_del (vat_main_t * vam)
10152 {
10153   unformat_input_t *i = vam->input;
10154   vl_api_ipfix_classify_table_add_del_t *mp;
10155   int is_add = -1;
10156   u32 classify_table_index = ~0;
10157   u8 ip_version = 0;
10158   u8 transport_protocol = 255;
10159   int ret;
10160
10161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10162     {
10163       if (unformat (i, "add"))
10164         is_add = 1;
10165       else if (unformat (i, "del"))
10166         is_add = 0;
10167       else if (unformat (i, "table %d", &classify_table_index))
10168         ;
10169       else if (unformat (i, "ip4"))
10170         ip_version = 4;
10171       else if (unformat (i, "ip6"))
10172         ip_version = 6;
10173       else if (unformat (i, "tcp"))
10174         transport_protocol = 6;
10175       else if (unformat (i, "udp"))
10176         transport_protocol = 17;
10177       else
10178         {
10179           errmsg ("unknown input `%U'", format_unformat_error, i);
10180           return -99;
10181         }
10182     }
10183
10184   if (is_add == -1)
10185     {
10186       errmsg ("expecting: add|del");
10187       return -99;
10188     }
10189   if (classify_table_index == ~0)
10190     {
10191       errmsg ("classifier table not specified");
10192       return -99;
10193     }
10194   if (ip_version == 0)
10195     {
10196       errmsg ("IP version not specified");
10197       return -99;
10198     }
10199
10200   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10201
10202   mp->is_add = is_add;
10203   mp->table_id = htonl (classify_table_index);
10204   mp->ip_version = ip_version;
10205   mp->transport_protocol = transport_protocol;
10206
10207   S (mp);
10208   W (ret);
10209   return ret;
10210 }
10211
10212 static int
10213 api_get_node_index (vat_main_t * vam)
10214 {
10215   unformat_input_t *i = vam->input;
10216   vl_api_get_node_index_t *mp;
10217   u8 *name = 0;
10218   int ret;
10219
10220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10221     {
10222       if (unformat (i, "node %s", &name))
10223         ;
10224       else
10225         break;
10226     }
10227   if (name == 0)
10228     {
10229       errmsg ("node name required");
10230       return -99;
10231     }
10232   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10233     {
10234       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10235       return -99;
10236     }
10237
10238   M (GET_NODE_INDEX, mp);
10239   clib_memcpy (mp->node_name, name, vec_len (name));
10240   vec_free (name);
10241
10242   S (mp);
10243   W (ret);
10244   return ret;
10245 }
10246
10247 static int
10248 api_get_next_index (vat_main_t * vam)
10249 {
10250   unformat_input_t *i = vam->input;
10251   vl_api_get_next_index_t *mp;
10252   u8 *node_name = 0, *next_node_name = 0;
10253   int ret;
10254
10255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10256     {
10257       if (unformat (i, "node-name %s", &node_name))
10258         ;
10259       else if (unformat (i, "next-node-name %s", &next_node_name))
10260         break;
10261     }
10262
10263   if (node_name == 0)
10264     {
10265       errmsg ("node name required");
10266       return -99;
10267     }
10268   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10269     {
10270       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10271       return -99;
10272     }
10273
10274   if (next_node_name == 0)
10275     {
10276       errmsg ("next node name required");
10277       return -99;
10278     }
10279   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10280     {
10281       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10282       return -99;
10283     }
10284
10285   M (GET_NEXT_INDEX, mp);
10286   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10287   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10288   vec_free (node_name);
10289   vec_free (next_node_name);
10290
10291   S (mp);
10292   W (ret);
10293   return ret;
10294 }
10295
10296 static int
10297 api_add_node_next (vat_main_t * vam)
10298 {
10299   unformat_input_t *i = vam->input;
10300   vl_api_add_node_next_t *mp;
10301   u8 *name = 0;
10302   u8 *next = 0;
10303   int ret;
10304
10305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10306     {
10307       if (unformat (i, "node %s", &name))
10308         ;
10309       else if (unformat (i, "next %s", &next))
10310         ;
10311       else
10312         break;
10313     }
10314   if (name == 0)
10315     {
10316       errmsg ("node name required");
10317       return -99;
10318     }
10319   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10320     {
10321       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10322       return -99;
10323     }
10324   if (next == 0)
10325     {
10326       errmsg ("next node required");
10327       return -99;
10328     }
10329   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10330     {
10331       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10332       return -99;
10333     }
10334
10335   M (ADD_NODE_NEXT, mp);
10336   clib_memcpy (mp->node_name, name, vec_len (name));
10337   clib_memcpy (mp->next_name, next, vec_len (next));
10338   vec_free (name);
10339   vec_free (next);
10340
10341   S (mp);
10342   W (ret);
10343   return ret;
10344 }
10345
10346 static int
10347 api_l2tpv3_create_tunnel (vat_main_t * vam)
10348 {
10349   unformat_input_t *i = vam->input;
10350   ip6_address_t client_address, our_address;
10351   int client_address_set = 0;
10352   int our_address_set = 0;
10353   u32 local_session_id = 0;
10354   u32 remote_session_id = 0;
10355   u64 local_cookie = 0;
10356   u64 remote_cookie = 0;
10357   u8 l2_sublayer_present = 0;
10358   vl_api_l2tpv3_create_tunnel_t *mp;
10359   int ret;
10360
10361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10362     {
10363       if (unformat (i, "client_address %U", unformat_ip6_address,
10364                     &client_address))
10365         client_address_set = 1;
10366       else if (unformat (i, "our_address %U", unformat_ip6_address,
10367                          &our_address))
10368         our_address_set = 1;
10369       else if (unformat (i, "local_session_id %d", &local_session_id))
10370         ;
10371       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10372         ;
10373       else if (unformat (i, "local_cookie %lld", &local_cookie))
10374         ;
10375       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10376         ;
10377       else if (unformat (i, "l2-sublayer-present"))
10378         l2_sublayer_present = 1;
10379       else
10380         break;
10381     }
10382
10383   if (client_address_set == 0)
10384     {
10385       errmsg ("client_address required");
10386       return -99;
10387     }
10388
10389   if (our_address_set == 0)
10390     {
10391       errmsg ("our_address required");
10392       return -99;
10393     }
10394
10395   M (L2TPV3_CREATE_TUNNEL, mp);
10396
10397   clib_memcpy (mp->client_address, client_address.as_u8,
10398                sizeof (mp->client_address));
10399
10400   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10401
10402   mp->local_session_id = ntohl (local_session_id);
10403   mp->remote_session_id = ntohl (remote_session_id);
10404   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10405   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10406   mp->l2_sublayer_present = l2_sublayer_present;
10407   mp->is_ipv6 = 1;
10408
10409   S (mp);
10410   W (ret);
10411   return ret;
10412 }
10413
10414 static int
10415 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10416 {
10417   unformat_input_t *i = vam->input;
10418   u32 sw_if_index;
10419   u8 sw_if_index_set = 0;
10420   u64 new_local_cookie = 0;
10421   u64 new_remote_cookie = 0;
10422   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10423   int ret;
10424
10425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10426     {
10427       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10428         sw_if_index_set = 1;
10429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10430         sw_if_index_set = 1;
10431       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10432         ;
10433       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10434         ;
10435       else
10436         break;
10437     }
10438
10439   if (sw_if_index_set == 0)
10440     {
10441       errmsg ("missing interface name or sw_if_index");
10442       return -99;
10443     }
10444
10445   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10446
10447   mp->sw_if_index = ntohl (sw_if_index);
10448   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10449   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10450
10451   S (mp);
10452   W (ret);
10453   return ret;
10454 }
10455
10456 static int
10457 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10458 {
10459   unformat_input_t *i = vam->input;
10460   vl_api_l2tpv3_interface_enable_disable_t *mp;
10461   u32 sw_if_index;
10462   u8 sw_if_index_set = 0;
10463   u8 enable_disable = 1;
10464   int ret;
10465
10466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10467     {
10468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10469         sw_if_index_set = 1;
10470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10471         sw_if_index_set = 1;
10472       else if (unformat (i, "enable"))
10473         enable_disable = 1;
10474       else if (unformat (i, "disable"))
10475         enable_disable = 0;
10476       else
10477         break;
10478     }
10479
10480   if (sw_if_index_set == 0)
10481     {
10482       errmsg ("missing interface name or sw_if_index");
10483       return -99;
10484     }
10485
10486   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10487
10488   mp->sw_if_index = ntohl (sw_if_index);
10489   mp->enable_disable = enable_disable;
10490
10491   S (mp);
10492   W (ret);
10493   return ret;
10494 }
10495
10496 static int
10497 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10498 {
10499   unformat_input_t *i = vam->input;
10500   vl_api_l2tpv3_set_lookup_key_t *mp;
10501   u8 key = ~0;
10502   int ret;
10503
10504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10505     {
10506       if (unformat (i, "lookup_v6_src"))
10507         key = L2T_LOOKUP_SRC_ADDRESS;
10508       else if (unformat (i, "lookup_v6_dst"))
10509         key = L2T_LOOKUP_DST_ADDRESS;
10510       else if (unformat (i, "lookup_session_id"))
10511         key = L2T_LOOKUP_SESSION_ID;
10512       else
10513         break;
10514     }
10515
10516   if (key == (u8) ~ 0)
10517     {
10518       errmsg ("l2tp session lookup key unset");
10519       return -99;
10520     }
10521
10522   M (L2TPV3_SET_LOOKUP_KEY, mp);
10523
10524   mp->key = key;
10525
10526   S (mp);
10527   W (ret);
10528   return ret;
10529 }
10530
10531 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10532   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10533 {
10534   vat_main_t *vam = &vat_main;
10535
10536   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10537          format_ip6_address, mp->our_address,
10538          format_ip6_address, mp->client_address,
10539          clib_net_to_host_u32 (mp->sw_if_index));
10540
10541   print (vam->ofp,
10542          "   local cookies %016llx %016llx remote cookie %016llx",
10543          clib_net_to_host_u64 (mp->local_cookie[0]),
10544          clib_net_to_host_u64 (mp->local_cookie[1]),
10545          clib_net_to_host_u64 (mp->remote_cookie));
10546
10547   print (vam->ofp, "   local session-id %d remote session-id %d",
10548          clib_net_to_host_u32 (mp->local_session_id),
10549          clib_net_to_host_u32 (mp->remote_session_id));
10550
10551   print (vam->ofp, "   l2 specific sublayer %s\n",
10552          mp->l2_sublayer_present ? "preset" : "absent");
10553
10554 }
10555
10556 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10557   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10558 {
10559   vat_main_t *vam = &vat_main;
10560   vat_json_node_t *node = NULL;
10561   struct in6_addr addr;
10562
10563   if (VAT_JSON_ARRAY != vam->json_tree.type)
10564     {
10565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10566       vat_json_init_array (&vam->json_tree);
10567     }
10568   node = vat_json_array_add (&vam->json_tree);
10569
10570   vat_json_init_object (node);
10571
10572   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10573   vat_json_object_add_ip6 (node, "our_address", addr);
10574   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10575   vat_json_object_add_ip6 (node, "client_address", addr);
10576
10577   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10578   vat_json_init_array (lc);
10579   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10580   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10581   vat_json_object_add_uint (node, "remote_cookie",
10582                             clib_net_to_host_u64 (mp->remote_cookie));
10583
10584   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10585   vat_json_object_add_uint (node, "local_session_id",
10586                             clib_net_to_host_u32 (mp->local_session_id));
10587   vat_json_object_add_uint (node, "remote_session_id",
10588                             clib_net_to_host_u32 (mp->remote_session_id));
10589   vat_json_object_add_string_copy (node, "l2_sublayer",
10590                                    mp->l2_sublayer_present ? (u8 *) "present"
10591                                    : (u8 *) "absent");
10592 }
10593
10594 static int
10595 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10596 {
10597   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10598   vl_api_control_ping_t *mp_ping;
10599   int ret;
10600
10601   /* Get list of l2tpv3-tunnel interfaces */
10602   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10603   S (mp);
10604
10605   /* Use a control ping for synchronization */
10606   M (CONTROL_PING, mp_ping);
10607   S (mp_ping);
10608
10609   W (ret);
10610   return ret;
10611 }
10612
10613
10614 static void vl_api_sw_interface_tap_details_t_handler
10615   (vl_api_sw_interface_tap_details_t * mp)
10616 {
10617   vat_main_t *vam = &vat_main;
10618
10619   print (vam->ofp, "%-16s %d",
10620          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10621 }
10622
10623 static void vl_api_sw_interface_tap_details_t_handler_json
10624   (vl_api_sw_interface_tap_details_t * mp)
10625 {
10626   vat_main_t *vam = &vat_main;
10627   vat_json_node_t *node = NULL;
10628
10629   if (VAT_JSON_ARRAY != vam->json_tree.type)
10630     {
10631       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10632       vat_json_init_array (&vam->json_tree);
10633     }
10634   node = vat_json_array_add (&vam->json_tree);
10635
10636   vat_json_init_object (node);
10637   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10638   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10639 }
10640
10641 static int
10642 api_sw_interface_tap_dump (vat_main_t * vam)
10643 {
10644   vl_api_sw_interface_tap_dump_t *mp;
10645   vl_api_control_ping_t *mp_ping;
10646   int ret;
10647
10648   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10649   /* Get list of tap interfaces */
10650   M (SW_INTERFACE_TAP_DUMP, mp);
10651   S (mp);
10652
10653   /* Use a control ping for synchronization */
10654   M (CONTROL_PING, mp_ping);
10655   S (mp_ping);
10656
10657   W (ret);
10658   return ret;
10659 }
10660
10661 static uword unformat_vxlan_decap_next
10662   (unformat_input_t * input, va_list * args)
10663 {
10664   u32 *result = va_arg (*args, u32 *);
10665   u32 tmp;
10666
10667   if (unformat (input, "l2"))
10668     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10669   else if (unformat (input, "%d", &tmp))
10670     *result = tmp;
10671   else
10672     return 0;
10673   return 1;
10674 }
10675
10676 static int
10677 api_vxlan_add_del_tunnel (vat_main_t * vam)
10678 {
10679   unformat_input_t *line_input = vam->input;
10680   vl_api_vxlan_add_del_tunnel_t *mp;
10681   ip46_address_t src, dst;
10682   u8 is_add = 1;
10683   u8 ipv4_set = 0, ipv6_set = 0;
10684   u8 src_set = 0;
10685   u8 dst_set = 0;
10686   u8 grp_set = 0;
10687   u32 mcast_sw_if_index = ~0;
10688   u32 encap_vrf_id = 0;
10689   u32 decap_next_index = ~0;
10690   u32 vni = 0;
10691   int ret;
10692
10693   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10694   memset (&src, 0, sizeof src);
10695   memset (&dst, 0, sizeof dst);
10696
10697   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10698     {
10699       if (unformat (line_input, "del"))
10700         is_add = 0;
10701       else
10702         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10703         {
10704           ipv4_set = 1;
10705           src_set = 1;
10706         }
10707       else
10708         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10709         {
10710           ipv4_set = 1;
10711           dst_set = 1;
10712         }
10713       else
10714         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10715         {
10716           ipv6_set = 1;
10717           src_set = 1;
10718         }
10719       else
10720         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10721         {
10722           ipv6_set = 1;
10723           dst_set = 1;
10724         }
10725       else if (unformat (line_input, "group %U %U",
10726                          unformat_ip4_address, &dst.ip4,
10727                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10728         {
10729           grp_set = dst_set = 1;
10730           ipv4_set = 1;
10731         }
10732       else if (unformat (line_input, "group %U",
10733                          unformat_ip4_address, &dst.ip4))
10734         {
10735           grp_set = dst_set = 1;
10736           ipv4_set = 1;
10737         }
10738       else if (unformat (line_input, "group %U %U",
10739                          unformat_ip6_address, &dst.ip6,
10740                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10741         {
10742           grp_set = dst_set = 1;
10743           ipv6_set = 1;
10744         }
10745       else if (unformat (line_input, "group %U",
10746                          unformat_ip6_address, &dst.ip6))
10747         {
10748           grp_set = dst_set = 1;
10749           ipv6_set = 1;
10750         }
10751       else
10752         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10753         ;
10754       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10755         ;
10756       else if (unformat (line_input, "decap-next %U",
10757                          unformat_vxlan_decap_next, &decap_next_index))
10758         ;
10759       else if (unformat (line_input, "vni %d", &vni))
10760         ;
10761       else
10762         {
10763           errmsg ("parse error '%U'", format_unformat_error, line_input);
10764           return -99;
10765         }
10766     }
10767
10768   if (src_set == 0)
10769     {
10770       errmsg ("tunnel src address not specified");
10771       return -99;
10772     }
10773   if (dst_set == 0)
10774     {
10775       errmsg ("tunnel dst address not specified");
10776       return -99;
10777     }
10778
10779   if (grp_set && !ip46_address_is_multicast (&dst))
10780     {
10781       errmsg ("tunnel group address not multicast");
10782       return -99;
10783     }
10784   if (grp_set && mcast_sw_if_index == ~0)
10785     {
10786       errmsg ("tunnel nonexistent multicast device");
10787       return -99;
10788     }
10789   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10790     {
10791       errmsg ("tunnel dst address must be unicast");
10792       return -99;
10793     }
10794
10795
10796   if (ipv4_set && ipv6_set)
10797     {
10798       errmsg ("both IPv4 and IPv6 addresses specified");
10799       return -99;
10800     }
10801
10802   if ((vni == 0) || (vni >> 24))
10803     {
10804       errmsg ("vni not specified or out of range");
10805       return -99;
10806     }
10807
10808   M (VXLAN_ADD_DEL_TUNNEL, mp);
10809
10810   if (ipv6_set)
10811     {
10812       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10813       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10814     }
10815   else
10816     {
10817       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10818       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10819     }
10820   mp->encap_vrf_id = ntohl (encap_vrf_id);
10821   mp->decap_next_index = ntohl (decap_next_index);
10822   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10823   mp->vni = ntohl (vni);
10824   mp->is_add = is_add;
10825   mp->is_ipv6 = ipv6_set;
10826
10827   S (mp);
10828   W (ret);
10829   return ret;
10830 }
10831
10832 static void vl_api_vxlan_tunnel_details_t_handler
10833   (vl_api_vxlan_tunnel_details_t * mp)
10834 {
10835   vat_main_t *vam = &vat_main;
10836   ip46_address_t src, dst;
10837
10838   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10839   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10840
10841   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10842          ntohl (mp->sw_if_index),
10843          format_ip46_address, &src, IP46_TYPE_ANY,
10844          format_ip46_address, &dst, IP46_TYPE_ANY,
10845          ntohl (mp->encap_vrf_id),
10846          ntohl (mp->decap_next_index), ntohl (mp->vni),
10847          ntohl (mp->mcast_sw_if_index));
10848 }
10849
10850 static void vl_api_vxlan_tunnel_details_t_handler_json
10851   (vl_api_vxlan_tunnel_details_t * mp)
10852 {
10853   vat_main_t *vam = &vat_main;
10854   vat_json_node_t *node = NULL;
10855
10856   if (VAT_JSON_ARRAY != vam->json_tree.type)
10857     {
10858       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10859       vat_json_init_array (&vam->json_tree);
10860     }
10861   node = vat_json_array_add (&vam->json_tree);
10862
10863   vat_json_init_object (node);
10864   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10865   if (mp->is_ipv6)
10866     {
10867       struct in6_addr ip6;
10868
10869       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10870       vat_json_object_add_ip6 (node, "src_address", ip6);
10871       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10872       vat_json_object_add_ip6 (node, "dst_address", ip6);
10873     }
10874   else
10875     {
10876       struct in_addr ip4;
10877
10878       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10879       vat_json_object_add_ip4 (node, "src_address", ip4);
10880       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10881       vat_json_object_add_ip4 (node, "dst_address", ip4);
10882     }
10883   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10884   vat_json_object_add_uint (node, "decap_next_index",
10885                             ntohl (mp->decap_next_index));
10886   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10887   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10888   vat_json_object_add_uint (node, "mcast_sw_if_index",
10889                             ntohl (mp->mcast_sw_if_index));
10890 }
10891
10892 static int
10893 api_vxlan_tunnel_dump (vat_main_t * vam)
10894 {
10895   unformat_input_t *i = vam->input;
10896   vl_api_vxlan_tunnel_dump_t *mp;
10897   vl_api_control_ping_t *mp_ping;
10898   u32 sw_if_index;
10899   u8 sw_if_index_set = 0;
10900   int ret;
10901
10902   /* Parse args required to build the message */
10903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10904     {
10905       if (unformat (i, "sw_if_index %d", &sw_if_index))
10906         sw_if_index_set = 1;
10907       else
10908         break;
10909     }
10910
10911   if (sw_if_index_set == 0)
10912     {
10913       sw_if_index = ~0;
10914     }
10915
10916   if (!vam->json_output)
10917     {
10918       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10919              "sw_if_index", "src_address", "dst_address",
10920              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10921     }
10922
10923   /* Get list of vxlan-tunnel interfaces */
10924   M (VXLAN_TUNNEL_DUMP, mp);
10925
10926   mp->sw_if_index = htonl (sw_if_index);
10927
10928   S (mp);
10929
10930   /* Use a control ping for synchronization */
10931   M (CONTROL_PING, mp_ping);
10932   S (mp_ping);
10933
10934   W (ret);
10935   return ret;
10936 }
10937
10938 static int
10939 api_gre_add_del_tunnel (vat_main_t * vam)
10940 {
10941   unformat_input_t *line_input = vam->input;
10942   vl_api_gre_add_del_tunnel_t *mp;
10943   ip4_address_t src4, dst4;
10944   u8 is_add = 1;
10945   u8 teb = 0;
10946   u8 src_set = 0;
10947   u8 dst_set = 0;
10948   u32 outer_fib_id = 0;
10949   int ret;
10950
10951   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10952     {
10953       if (unformat (line_input, "del"))
10954         is_add = 0;
10955       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10956         src_set = 1;
10957       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10958         dst_set = 1;
10959       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10960         ;
10961       else if (unformat (line_input, "teb"))
10962         teb = 1;
10963       else
10964         {
10965           errmsg ("parse error '%U'", format_unformat_error, line_input);
10966           return -99;
10967         }
10968     }
10969
10970   if (src_set == 0)
10971     {
10972       errmsg ("tunnel src address not specified");
10973       return -99;
10974     }
10975   if (dst_set == 0)
10976     {
10977       errmsg ("tunnel dst address not specified");
10978       return -99;
10979     }
10980
10981
10982   M (GRE_ADD_DEL_TUNNEL, mp);
10983
10984   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10985   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10986   mp->outer_fib_id = ntohl (outer_fib_id);
10987   mp->is_add = is_add;
10988   mp->teb = teb;
10989
10990   S (mp);
10991   W (ret);
10992   return ret;
10993 }
10994
10995 static void vl_api_gre_tunnel_details_t_handler
10996   (vl_api_gre_tunnel_details_t * mp)
10997 {
10998   vat_main_t *vam = &vat_main;
10999
11000   print (vam->ofp, "%11d%15U%15U%6d%14d",
11001          ntohl (mp->sw_if_index),
11002          format_ip4_address, &mp->src_address,
11003          format_ip4_address, &mp->dst_address,
11004          mp->teb, ntohl (mp->outer_fib_id));
11005 }
11006
11007 static void vl_api_gre_tunnel_details_t_handler_json
11008   (vl_api_gre_tunnel_details_t * mp)
11009 {
11010   vat_main_t *vam = &vat_main;
11011   vat_json_node_t *node = NULL;
11012   struct in_addr ip4;
11013
11014   if (VAT_JSON_ARRAY != vam->json_tree.type)
11015     {
11016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11017       vat_json_init_array (&vam->json_tree);
11018     }
11019   node = vat_json_array_add (&vam->json_tree);
11020
11021   vat_json_init_object (node);
11022   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11023   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11024   vat_json_object_add_ip4 (node, "src_address", ip4);
11025   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11026   vat_json_object_add_ip4 (node, "dst_address", ip4);
11027   vat_json_object_add_uint (node, "teb", mp->teb);
11028   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11029 }
11030
11031 static int
11032 api_gre_tunnel_dump (vat_main_t * vam)
11033 {
11034   unformat_input_t *i = vam->input;
11035   vl_api_gre_tunnel_dump_t *mp;
11036   vl_api_control_ping_t *mp_ping;
11037   u32 sw_if_index;
11038   u8 sw_if_index_set = 0;
11039   int ret;
11040
11041   /* Parse args required to build the message */
11042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11043     {
11044       if (unformat (i, "sw_if_index %d", &sw_if_index))
11045         sw_if_index_set = 1;
11046       else
11047         break;
11048     }
11049
11050   if (sw_if_index_set == 0)
11051     {
11052       sw_if_index = ~0;
11053     }
11054
11055   if (!vam->json_output)
11056     {
11057       print (vam->ofp, "%11s%15s%15s%6s%14s",
11058              "sw_if_index", "src_address", "dst_address", "teb",
11059              "outer_fib_id");
11060     }
11061
11062   /* Get list of gre-tunnel interfaces */
11063   M (GRE_TUNNEL_DUMP, mp);
11064
11065   mp->sw_if_index = htonl (sw_if_index);
11066
11067   S (mp);
11068
11069   /* Use a control ping for synchronization */
11070   M (CONTROL_PING, mp_ping);
11071   S (mp_ping);
11072
11073   W (ret);
11074   return ret;
11075 }
11076
11077 static int
11078 api_l2_fib_clear_table (vat_main_t * vam)
11079 {
11080 //  unformat_input_t * i = vam->input;
11081   vl_api_l2_fib_clear_table_t *mp;
11082   int ret;
11083
11084   M (L2_FIB_CLEAR_TABLE, mp);
11085
11086   S (mp);
11087   W (ret);
11088   return ret;
11089 }
11090
11091 static int
11092 api_l2_interface_efp_filter (vat_main_t * vam)
11093 {
11094   unformat_input_t *i = vam->input;
11095   vl_api_l2_interface_efp_filter_t *mp;
11096   u32 sw_if_index;
11097   u8 enable = 1;
11098   u8 sw_if_index_set = 0;
11099   int ret;
11100
11101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11102     {
11103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11104         sw_if_index_set = 1;
11105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11106         sw_if_index_set = 1;
11107       else if (unformat (i, "enable"))
11108         enable = 1;
11109       else if (unformat (i, "disable"))
11110         enable = 0;
11111       else
11112         {
11113           clib_warning ("parse error '%U'", format_unformat_error, i);
11114           return -99;
11115         }
11116     }
11117
11118   if (sw_if_index_set == 0)
11119     {
11120       errmsg ("missing sw_if_index");
11121       return -99;
11122     }
11123
11124   M (L2_INTERFACE_EFP_FILTER, mp);
11125
11126   mp->sw_if_index = ntohl (sw_if_index);
11127   mp->enable_disable = enable;
11128
11129   S (mp);
11130   W (ret);
11131   return ret;
11132 }
11133
11134 #define foreach_vtr_op                          \
11135 _("disable",  L2_VTR_DISABLED)                  \
11136 _("push-1",  L2_VTR_PUSH_1)                     \
11137 _("push-2",  L2_VTR_PUSH_2)                     \
11138 _("pop-1",  L2_VTR_POP_1)                       \
11139 _("pop-2",  L2_VTR_POP_2)                       \
11140 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11141 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11142 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11143 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11144
11145 static int
11146 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11147 {
11148   unformat_input_t *i = vam->input;
11149   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11150   u32 sw_if_index;
11151   u8 sw_if_index_set = 0;
11152   u8 vtr_op_set = 0;
11153   u32 vtr_op = 0;
11154   u32 push_dot1q = 1;
11155   u32 tag1 = ~0;
11156   u32 tag2 = ~0;
11157   int ret;
11158
11159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11160     {
11161       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11162         sw_if_index_set = 1;
11163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11164         sw_if_index_set = 1;
11165       else if (unformat (i, "vtr_op %d", &vtr_op))
11166         vtr_op_set = 1;
11167 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11168       foreach_vtr_op
11169 #undef _
11170         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11171         ;
11172       else if (unformat (i, "tag1 %d", &tag1))
11173         ;
11174       else if (unformat (i, "tag2 %d", &tag2))
11175         ;
11176       else
11177         {
11178           clib_warning ("parse error '%U'", format_unformat_error, i);
11179           return -99;
11180         }
11181     }
11182
11183   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11184     {
11185       errmsg ("missing vtr operation or sw_if_index");
11186       return -99;
11187     }
11188
11189   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11190   mp->sw_if_index = ntohl (sw_if_index);
11191   mp->vtr_op = ntohl (vtr_op);
11192   mp->push_dot1q = ntohl (push_dot1q);
11193   mp->tag1 = ntohl (tag1);
11194   mp->tag2 = ntohl (tag2);
11195
11196   S (mp);
11197   W (ret);
11198   return ret;
11199 }
11200
11201 static int
11202 api_create_vhost_user_if (vat_main_t * vam)
11203 {
11204   unformat_input_t *i = vam->input;
11205   vl_api_create_vhost_user_if_t *mp;
11206   u8 *file_name;
11207   u8 is_server = 0;
11208   u8 file_name_set = 0;
11209   u32 custom_dev_instance = ~0;
11210   u8 hwaddr[6];
11211   u8 use_custom_mac = 0;
11212   u8 *tag = 0;
11213   int ret;
11214
11215   /* Shut up coverity */
11216   memset (hwaddr, 0, sizeof (hwaddr));
11217
11218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11219     {
11220       if (unformat (i, "socket %s", &file_name))
11221         {
11222           file_name_set = 1;
11223         }
11224       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11225         ;
11226       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11227         use_custom_mac = 1;
11228       else if (unformat (i, "server"))
11229         is_server = 1;
11230       else if (unformat (i, "tag %s", &tag))
11231         ;
11232       else
11233         break;
11234     }
11235
11236   if (file_name_set == 0)
11237     {
11238       errmsg ("missing socket file name");
11239       return -99;
11240     }
11241
11242   if (vec_len (file_name) > 255)
11243     {
11244       errmsg ("socket file name too long");
11245       return -99;
11246     }
11247   vec_add1 (file_name, 0);
11248
11249   M (CREATE_VHOST_USER_IF, mp);
11250
11251   mp->is_server = is_server;
11252   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11253   vec_free (file_name);
11254   if (custom_dev_instance != ~0)
11255     {
11256       mp->renumber = 1;
11257       mp->custom_dev_instance = ntohl (custom_dev_instance);
11258     }
11259   mp->use_custom_mac = use_custom_mac;
11260   clib_memcpy (mp->mac_address, hwaddr, 6);
11261   if (tag)
11262     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11263   vec_free (tag);
11264
11265   S (mp);
11266   W (ret);
11267   return ret;
11268 }
11269
11270 static int
11271 api_modify_vhost_user_if (vat_main_t * vam)
11272 {
11273   unformat_input_t *i = vam->input;
11274   vl_api_modify_vhost_user_if_t *mp;
11275   u8 *file_name;
11276   u8 is_server = 0;
11277   u8 file_name_set = 0;
11278   u32 custom_dev_instance = ~0;
11279   u8 sw_if_index_set = 0;
11280   u32 sw_if_index = (u32) ~ 0;
11281   int ret;
11282
11283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11284     {
11285       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11286         sw_if_index_set = 1;
11287       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11288         sw_if_index_set = 1;
11289       else if (unformat (i, "socket %s", &file_name))
11290         {
11291           file_name_set = 1;
11292         }
11293       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11294         ;
11295       else if (unformat (i, "server"))
11296         is_server = 1;
11297       else
11298         break;
11299     }
11300
11301   if (sw_if_index_set == 0)
11302     {
11303       errmsg ("missing sw_if_index or interface name");
11304       return -99;
11305     }
11306
11307   if (file_name_set == 0)
11308     {
11309       errmsg ("missing socket file name");
11310       return -99;
11311     }
11312
11313   if (vec_len (file_name) > 255)
11314     {
11315       errmsg ("socket file name too long");
11316       return -99;
11317     }
11318   vec_add1 (file_name, 0);
11319
11320   M (MODIFY_VHOST_USER_IF, mp);
11321
11322   mp->sw_if_index = ntohl (sw_if_index);
11323   mp->is_server = is_server;
11324   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11325   vec_free (file_name);
11326   if (custom_dev_instance != ~0)
11327     {
11328       mp->renumber = 1;
11329       mp->custom_dev_instance = ntohl (custom_dev_instance);
11330     }
11331
11332   S (mp);
11333   W (ret);
11334   return ret;
11335 }
11336
11337 static int
11338 api_delete_vhost_user_if (vat_main_t * vam)
11339 {
11340   unformat_input_t *i = vam->input;
11341   vl_api_delete_vhost_user_if_t *mp;
11342   u32 sw_if_index = ~0;
11343   u8 sw_if_index_set = 0;
11344   int ret;
11345
11346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11347     {
11348       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11349         sw_if_index_set = 1;
11350       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11351         sw_if_index_set = 1;
11352       else
11353         break;
11354     }
11355
11356   if (sw_if_index_set == 0)
11357     {
11358       errmsg ("missing sw_if_index or interface name");
11359       return -99;
11360     }
11361
11362
11363   M (DELETE_VHOST_USER_IF, mp);
11364
11365   mp->sw_if_index = ntohl (sw_if_index);
11366
11367   S (mp);
11368   W (ret);
11369   return ret;
11370 }
11371
11372 static void vl_api_sw_interface_vhost_user_details_t_handler
11373   (vl_api_sw_interface_vhost_user_details_t * mp)
11374 {
11375   vat_main_t *vam = &vat_main;
11376
11377   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11378          (char *) mp->interface_name,
11379          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11380          clib_net_to_host_u64 (mp->features), mp->is_server,
11381          ntohl (mp->num_regions), (char *) mp->sock_filename);
11382   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11383 }
11384
11385 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11386   (vl_api_sw_interface_vhost_user_details_t * mp)
11387 {
11388   vat_main_t *vam = &vat_main;
11389   vat_json_node_t *node = NULL;
11390
11391   if (VAT_JSON_ARRAY != vam->json_tree.type)
11392     {
11393       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11394       vat_json_init_array (&vam->json_tree);
11395     }
11396   node = vat_json_array_add (&vam->json_tree);
11397
11398   vat_json_init_object (node);
11399   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11400   vat_json_object_add_string_copy (node, "interface_name",
11401                                    mp->interface_name);
11402   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11403                             ntohl (mp->virtio_net_hdr_sz));
11404   vat_json_object_add_uint (node, "features",
11405                             clib_net_to_host_u64 (mp->features));
11406   vat_json_object_add_uint (node, "is_server", mp->is_server);
11407   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11408   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11409   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11410 }
11411
11412 static int
11413 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11414 {
11415   vl_api_sw_interface_vhost_user_dump_t *mp;
11416   vl_api_control_ping_t *mp_ping;
11417   int ret;
11418   print (vam->ofp,
11419          "Interface name           idx hdr_sz features server regions filename");
11420
11421   /* Get list of vhost-user interfaces */
11422   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11423   S (mp);
11424
11425   /* Use a control ping for synchronization */
11426   M (CONTROL_PING, mp_ping);
11427   S (mp_ping);
11428
11429   W (ret);
11430   return ret;
11431 }
11432
11433 static int
11434 api_show_version (vat_main_t * vam)
11435 {
11436   vl_api_show_version_t *mp;
11437   int ret;
11438
11439   M (SHOW_VERSION, mp);
11440
11441   S (mp);
11442   W (ret);
11443   return ret;
11444 }
11445
11446
11447 static int
11448 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11449 {
11450   unformat_input_t *line_input = vam->input;
11451   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11452   ip4_address_t local4, remote4;
11453   ip6_address_t local6, remote6;
11454   u8 is_add = 1;
11455   u8 ipv4_set = 0, ipv6_set = 0;
11456   u8 local_set = 0;
11457   u8 remote_set = 0;
11458   u32 encap_vrf_id = 0;
11459   u32 decap_vrf_id = 0;
11460   u8 protocol = ~0;
11461   u32 vni;
11462   u8 vni_set = 0;
11463   int ret;
11464
11465   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11466     {
11467       if (unformat (line_input, "del"))
11468         is_add = 0;
11469       else if (unformat (line_input, "local %U",
11470                          unformat_ip4_address, &local4))
11471         {
11472           local_set = 1;
11473           ipv4_set = 1;
11474         }
11475       else if (unformat (line_input, "remote %U",
11476                          unformat_ip4_address, &remote4))
11477         {
11478           remote_set = 1;
11479           ipv4_set = 1;
11480         }
11481       else if (unformat (line_input, "local %U",
11482                          unformat_ip6_address, &local6))
11483         {
11484           local_set = 1;
11485           ipv6_set = 1;
11486         }
11487       else if (unformat (line_input, "remote %U",
11488                          unformat_ip6_address, &remote6))
11489         {
11490           remote_set = 1;
11491           ipv6_set = 1;
11492         }
11493       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11494         ;
11495       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11496         ;
11497       else if (unformat (line_input, "vni %d", &vni))
11498         vni_set = 1;
11499       else if (unformat (line_input, "next-ip4"))
11500         protocol = 1;
11501       else if (unformat (line_input, "next-ip6"))
11502         protocol = 2;
11503       else if (unformat (line_input, "next-ethernet"))
11504         protocol = 3;
11505       else if (unformat (line_input, "next-nsh"))
11506         protocol = 4;
11507       else
11508         {
11509           errmsg ("parse error '%U'", format_unformat_error, line_input);
11510           return -99;
11511         }
11512     }
11513
11514   if (local_set == 0)
11515     {
11516       errmsg ("tunnel local address not specified");
11517       return -99;
11518     }
11519   if (remote_set == 0)
11520     {
11521       errmsg ("tunnel remote address not specified");
11522       return -99;
11523     }
11524   if (ipv4_set && ipv6_set)
11525     {
11526       errmsg ("both IPv4 and IPv6 addresses specified");
11527       return -99;
11528     }
11529
11530   if (vni_set == 0)
11531     {
11532       errmsg ("vni not specified");
11533       return -99;
11534     }
11535
11536   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11537
11538
11539   if (ipv6_set)
11540     {
11541       clib_memcpy (&mp->local, &local6, sizeof (local6));
11542       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11543     }
11544   else
11545     {
11546       clib_memcpy (&mp->local, &local4, sizeof (local4));
11547       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11548     }
11549
11550   mp->encap_vrf_id = ntohl (encap_vrf_id);
11551   mp->decap_vrf_id = ntohl (decap_vrf_id);
11552   mp->protocol = protocol;
11553   mp->vni = ntohl (vni);
11554   mp->is_add = is_add;
11555   mp->is_ipv6 = ipv6_set;
11556
11557   S (mp);
11558   W (ret);
11559   return ret;
11560 }
11561
11562 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11563   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11564 {
11565   vat_main_t *vam = &vat_main;
11566
11567   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11568          ntohl (mp->sw_if_index),
11569          format_ip46_address, &(mp->local[0]),
11570          format_ip46_address, &(mp->remote[0]),
11571          ntohl (mp->vni),
11572          ntohl (mp->protocol),
11573          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11574 }
11575
11576 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11577   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11578 {
11579   vat_main_t *vam = &vat_main;
11580   vat_json_node_t *node = NULL;
11581   struct in_addr ip4;
11582   struct in6_addr ip6;
11583
11584   if (VAT_JSON_ARRAY != vam->json_tree.type)
11585     {
11586       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11587       vat_json_init_array (&vam->json_tree);
11588     }
11589   node = vat_json_array_add (&vam->json_tree);
11590
11591   vat_json_init_object (node);
11592   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11593   if (mp->is_ipv6)
11594     {
11595       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11596       vat_json_object_add_ip6 (node, "local", ip6);
11597       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11598       vat_json_object_add_ip6 (node, "remote", ip6);
11599     }
11600   else
11601     {
11602       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11603       vat_json_object_add_ip4 (node, "local", ip4);
11604       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11605       vat_json_object_add_ip4 (node, "remote", ip4);
11606     }
11607   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11608   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11609   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11610   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11611   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11612 }
11613
11614 static int
11615 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11616 {
11617   unformat_input_t *i = vam->input;
11618   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11619   vl_api_control_ping_t *mp_ping;
11620   u32 sw_if_index;
11621   u8 sw_if_index_set = 0;
11622   int ret;
11623
11624   /* Parse args required to build the message */
11625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11626     {
11627       if (unformat (i, "sw_if_index %d", &sw_if_index))
11628         sw_if_index_set = 1;
11629       else
11630         break;
11631     }
11632
11633   if (sw_if_index_set == 0)
11634     {
11635       sw_if_index = ~0;
11636     }
11637
11638   if (!vam->json_output)
11639     {
11640       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11641              "sw_if_index", "local", "remote", "vni",
11642              "protocol", "encap_vrf_id", "decap_vrf_id");
11643     }
11644
11645   /* Get list of vxlan-tunnel interfaces */
11646   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11647
11648   mp->sw_if_index = htonl (sw_if_index);
11649
11650   S (mp);
11651
11652   /* Use a control ping for synchronization */
11653   M (CONTROL_PING, mp_ping);
11654   S (mp_ping);
11655
11656   W (ret);
11657   return ret;
11658 }
11659
11660 u8 *
11661 format_l2_fib_mac_address (u8 * s, va_list * args)
11662 {
11663   u8 *a = va_arg (*args, u8 *);
11664
11665   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11666                  a[2], a[3], a[4], a[5], a[6], a[7]);
11667 }
11668
11669 static void vl_api_l2_fib_table_entry_t_handler
11670   (vl_api_l2_fib_table_entry_t * mp)
11671 {
11672   vat_main_t *vam = &vat_main;
11673
11674   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11675          "       %d       %d     %d",
11676          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11677          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11678          mp->bvi_mac);
11679 }
11680
11681 static void vl_api_l2_fib_table_entry_t_handler_json
11682   (vl_api_l2_fib_table_entry_t * mp)
11683 {
11684   vat_main_t *vam = &vat_main;
11685   vat_json_node_t *node = NULL;
11686
11687   if (VAT_JSON_ARRAY != vam->json_tree.type)
11688     {
11689       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11690       vat_json_init_array (&vam->json_tree);
11691     }
11692   node = vat_json_array_add (&vam->json_tree);
11693
11694   vat_json_init_object (node);
11695   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11696   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11697   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11698   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11699   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11700   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11701 }
11702
11703 static int
11704 api_l2_fib_table_dump (vat_main_t * vam)
11705 {
11706   unformat_input_t *i = vam->input;
11707   vl_api_l2_fib_table_dump_t *mp;
11708   vl_api_control_ping_t *mp_ping;
11709   u32 bd_id;
11710   u8 bd_id_set = 0;
11711   int ret;
11712
11713   /* Parse args required to build the message */
11714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11715     {
11716       if (unformat (i, "bd_id %d", &bd_id))
11717         bd_id_set = 1;
11718       else
11719         break;
11720     }
11721
11722   if (bd_id_set == 0)
11723     {
11724       errmsg ("missing bridge domain");
11725       return -99;
11726     }
11727
11728   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11729
11730   /* Get list of l2 fib entries */
11731   M (L2_FIB_TABLE_DUMP, mp);
11732
11733   mp->bd_id = ntohl (bd_id);
11734   S (mp);
11735
11736   /* Use a control ping for synchronization */
11737   M (CONTROL_PING, mp_ping);
11738   S (mp_ping);
11739
11740   W (ret);
11741   return ret;
11742 }
11743
11744
11745 static int
11746 api_interface_name_renumber (vat_main_t * vam)
11747 {
11748   unformat_input_t *line_input = vam->input;
11749   vl_api_interface_name_renumber_t *mp;
11750   u32 sw_if_index = ~0;
11751   u32 new_show_dev_instance = ~0;
11752   int ret;
11753
11754   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11755     {
11756       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11757                     &sw_if_index))
11758         ;
11759       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11760         ;
11761       else if (unformat (line_input, "new_show_dev_instance %d",
11762                          &new_show_dev_instance))
11763         ;
11764       else
11765         break;
11766     }
11767
11768   if (sw_if_index == ~0)
11769     {
11770       errmsg ("missing interface name or sw_if_index");
11771       return -99;
11772     }
11773
11774   if (new_show_dev_instance == ~0)
11775     {
11776       errmsg ("missing new_show_dev_instance");
11777       return -99;
11778     }
11779
11780   M (INTERFACE_NAME_RENUMBER, mp);
11781
11782   mp->sw_if_index = ntohl (sw_if_index);
11783   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11784
11785   S (mp);
11786   W (ret);
11787   return ret;
11788 }
11789
11790 static int
11791 api_want_ip4_arp_events (vat_main_t * vam)
11792 {
11793   unformat_input_t *line_input = vam->input;
11794   vl_api_want_ip4_arp_events_t *mp;
11795   ip4_address_t address;
11796   int address_set = 0;
11797   u32 enable_disable = 1;
11798   int ret;
11799
11800   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11801     {
11802       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11803         address_set = 1;
11804       else if (unformat (line_input, "del"))
11805         enable_disable = 0;
11806       else
11807         break;
11808     }
11809
11810   if (address_set == 0)
11811     {
11812       errmsg ("missing addresses");
11813       return -99;
11814     }
11815
11816   M (WANT_IP4_ARP_EVENTS, mp);
11817   mp->enable_disable = enable_disable;
11818   mp->pid = getpid ();
11819   mp->address = address.as_u32;
11820
11821   S (mp);
11822   W (ret);
11823   return ret;
11824 }
11825
11826 static int
11827 api_want_ip6_nd_events (vat_main_t * vam)
11828 {
11829   unformat_input_t *line_input = vam->input;
11830   vl_api_want_ip6_nd_events_t *mp;
11831   ip6_address_t address;
11832   int address_set = 0;
11833   u32 enable_disable = 1;
11834   int ret;
11835
11836   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11837     {
11838       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11839         address_set = 1;
11840       else if (unformat (line_input, "del"))
11841         enable_disable = 0;
11842       else
11843         break;
11844     }
11845
11846   if (address_set == 0)
11847     {
11848       errmsg ("missing addresses");
11849       return -99;
11850     }
11851
11852   M (WANT_IP6_ND_EVENTS, mp);
11853   mp->enable_disable = enable_disable;
11854   mp->pid = getpid ();
11855   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11856
11857   S (mp);
11858   W (ret);
11859   return ret;
11860 }
11861
11862 static int
11863 api_input_acl_set_interface (vat_main_t * vam)
11864 {
11865   unformat_input_t *i = vam->input;
11866   vl_api_input_acl_set_interface_t *mp;
11867   u32 sw_if_index;
11868   int sw_if_index_set;
11869   u32 ip4_table_index = ~0;
11870   u32 ip6_table_index = ~0;
11871   u32 l2_table_index = ~0;
11872   u8 is_add = 1;
11873   int ret;
11874
11875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11876     {
11877       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11878         sw_if_index_set = 1;
11879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11880         sw_if_index_set = 1;
11881       else if (unformat (i, "del"))
11882         is_add = 0;
11883       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11884         ;
11885       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11886         ;
11887       else if (unformat (i, "l2-table %d", &l2_table_index))
11888         ;
11889       else
11890         {
11891           clib_warning ("parse error '%U'", format_unformat_error, i);
11892           return -99;
11893         }
11894     }
11895
11896   if (sw_if_index_set == 0)
11897     {
11898       errmsg ("missing interface name or sw_if_index");
11899       return -99;
11900     }
11901
11902   M (INPUT_ACL_SET_INTERFACE, mp);
11903
11904   mp->sw_if_index = ntohl (sw_if_index);
11905   mp->ip4_table_index = ntohl (ip4_table_index);
11906   mp->ip6_table_index = ntohl (ip6_table_index);
11907   mp->l2_table_index = ntohl (l2_table_index);
11908   mp->is_add = is_add;
11909
11910   S (mp);
11911   W (ret);
11912   return ret;
11913 }
11914
11915 static int
11916 api_ip_address_dump (vat_main_t * vam)
11917 {
11918   unformat_input_t *i = vam->input;
11919   vl_api_ip_address_dump_t *mp;
11920   vl_api_control_ping_t *mp_ping;
11921   u32 sw_if_index = ~0;
11922   u8 sw_if_index_set = 0;
11923   u8 ipv4_set = 0;
11924   u8 ipv6_set = 0;
11925   int ret;
11926
11927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11928     {
11929       if (unformat (i, "sw_if_index %d", &sw_if_index))
11930         sw_if_index_set = 1;
11931       else
11932         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11933         sw_if_index_set = 1;
11934       else if (unformat (i, "ipv4"))
11935         ipv4_set = 1;
11936       else if (unformat (i, "ipv6"))
11937         ipv6_set = 1;
11938       else
11939         break;
11940     }
11941
11942   if (ipv4_set && ipv6_set)
11943     {
11944       errmsg ("ipv4 and ipv6 flags cannot be both set");
11945       return -99;
11946     }
11947
11948   if ((!ipv4_set) && (!ipv6_set))
11949     {
11950       errmsg ("no ipv4 nor ipv6 flag set");
11951       return -99;
11952     }
11953
11954   if (sw_if_index_set == 0)
11955     {
11956       errmsg ("missing interface name or sw_if_index");
11957       return -99;
11958     }
11959
11960   vam->current_sw_if_index = sw_if_index;
11961   vam->is_ipv6 = ipv6_set;
11962
11963   M (IP_ADDRESS_DUMP, mp);
11964   mp->sw_if_index = ntohl (sw_if_index);
11965   mp->is_ipv6 = ipv6_set;
11966   S (mp);
11967
11968   /* Use a control ping for synchronization */
11969   M (CONTROL_PING, mp_ping);
11970   S (mp_ping);
11971
11972   W (ret);
11973   return ret;
11974 }
11975
11976 static int
11977 api_ip_dump (vat_main_t * vam)
11978 {
11979   vl_api_ip_dump_t *mp;
11980   vl_api_control_ping_t *mp_ping;
11981   unformat_input_t *in = vam->input;
11982   int ipv4_set = 0;
11983   int ipv6_set = 0;
11984   int is_ipv6;
11985   int i;
11986   int ret;
11987
11988   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11989     {
11990       if (unformat (in, "ipv4"))
11991         ipv4_set = 1;
11992       else if (unformat (in, "ipv6"))
11993         ipv6_set = 1;
11994       else
11995         break;
11996     }
11997
11998   if (ipv4_set && ipv6_set)
11999     {
12000       errmsg ("ipv4 and ipv6 flags cannot be both set");
12001       return -99;
12002     }
12003
12004   if ((!ipv4_set) && (!ipv6_set))
12005     {
12006       errmsg ("no ipv4 nor ipv6 flag set");
12007       return -99;
12008     }
12009
12010   is_ipv6 = ipv6_set;
12011   vam->is_ipv6 = is_ipv6;
12012
12013   /* free old data */
12014   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12015     {
12016       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12017     }
12018   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12019
12020   M (IP_DUMP, mp);
12021   mp->is_ipv6 = ipv6_set;
12022   S (mp);
12023
12024   /* Use a control ping for synchronization */
12025   M (CONTROL_PING, mp_ping);
12026   S (mp_ping);
12027
12028   W (ret);
12029   return ret;
12030 }
12031
12032 static int
12033 api_ipsec_spd_add_del (vat_main_t * vam)
12034 {
12035   unformat_input_t *i = vam->input;
12036   vl_api_ipsec_spd_add_del_t *mp;
12037   u32 spd_id = ~0;
12038   u8 is_add = 1;
12039   int ret;
12040
12041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12042     {
12043       if (unformat (i, "spd_id %d", &spd_id))
12044         ;
12045       else if (unformat (i, "del"))
12046         is_add = 0;
12047       else
12048         {
12049           clib_warning ("parse error '%U'", format_unformat_error, i);
12050           return -99;
12051         }
12052     }
12053   if (spd_id == ~0)
12054     {
12055       errmsg ("spd_id must be set");
12056       return -99;
12057     }
12058
12059   M (IPSEC_SPD_ADD_DEL, mp);
12060
12061   mp->spd_id = ntohl (spd_id);
12062   mp->is_add = is_add;
12063
12064   S (mp);
12065   W (ret);
12066   return ret;
12067 }
12068
12069 static int
12070 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12071 {
12072   unformat_input_t *i = vam->input;
12073   vl_api_ipsec_interface_add_del_spd_t *mp;
12074   u32 sw_if_index;
12075   u8 sw_if_index_set = 0;
12076   u32 spd_id = (u32) ~ 0;
12077   u8 is_add = 1;
12078   int ret;
12079
12080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12081     {
12082       if (unformat (i, "del"))
12083         is_add = 0;
12084       else if (unformat (i, "spd_id %d", &spd_id))
12085         ;
12086       else
12087         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12088         sw_if_index_set = 1;
12089       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12090         sw_if_index_set = 1;
12091       else
12092         {
12093           clib_warning ("parse error '%U'", format_unformat_error, i);
12094           return -99;
12095         }
12096
12097     }
12098
12099   if (spd_id == (u32) ~ 0)
12100     {
12101       errmsg ("spd_id must be set");
12102       return -99;
12103     }
12104
12105   if (sw_if_index_set == 0)
12106     {
12107       errmsg ("missing interface name or sw_if_index");
12108       return -99;
12109     }
12110
12111   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12112
12113   mp->spd_id = ntohl (spd_id);
12114   mp->sw_if_index = ntohl (sw_if_index);
12115   mp->is_add = is_add;
12116
12117   S (mp);
12118   W (ret);
12119   return ret;
12120 }
12121
12122 static int
12123 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12124 {
12125   unformat_input_t *i = vam->input;
12126   vl_api_ipsec_spd_add_del_entry_t *mp;
12127   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12128   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12129   i32 priority = 0;
12130   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12131   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12132   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12133   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12134   int ret;
12135
12136   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12137   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12138   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12139   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12140   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12141   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12142
12143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12144     {
12145       if (unformat (i, "del"))
12146         is_add = 0;
12147       if (unformat (i, "outbound"))
12148         is_outbound = 1;
12149       if (unformat (i, "inbound"))
12150         is_outbound = 0;
12151       else if (unformat (i, "spd_id %d", &spd_id))
12152         ;
12153       else if (unformat (i, "sa_id %d", &sa_id))
12154         ;
12155       else if (unformat (i, "priority %d", &priority))
12156         ;
12157       else if (unformat (i, "protocol %d", &protocol))
12158         ;
12159       else if (unformat (i, "lport_start %d", &lport_start))
12160         ;
12161       else if (unformat (i, "lport_stop %d", &lport_stop))
12162         ;
12163       else if (unformat (i, "rport_start %d", &rport_start))
12164         ;
12165       else if (unformat (i, "rport_stop %d", &rport_stop))
12166         ;
12167       else
12168         if (unformat
12169             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12170         {
12171           is_ipv6 = 0;
12172           is_ip_any = 0;
12173         }
12174       else
12175         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12176         {
12177           is_ipv6 = 0;
12178           is_ip_any = 0;
12179         }
12180       else
12181         if (unformat
12182             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12183         {
12184           is_ipv6 = 0;
12185           is_ip_any = 0;
12186         }
12187       else
12188         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12189         {
12190           is_ipv6 = 0;
12191           is_ip_any = 0;
12192         }
12193       else
12194         if (unformat
12195             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12196         {
12197           is_ipv6 = 1;
12198           is_ip_any = 0;
12199         }
12200       else
12201         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12202         {
12203           is_ipv6 = 1;
12204           is_ip_any = 0;
12205         }
12206       else
12207         if (unformat
12208             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12209         {
12210           is_ipv6 = 1;
12211           is_ip_any = 0;
12212         }
12213       else
12214         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12215         {
12216           is_ipv6 = 1;
12217           is_ip_any = 0;
12218         }
12219       else
12220         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12221         {
12222           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12223             {
12224               clib_warning ("unsupported action: 'resolve'");
12225               return -99;
12226             }
12227         }
12228       else
12229         {
12230           clib_warning ("parse error '%U'", format_unformat_error, i);
12231           return -99;
12232         }
12233
12234     }
12235
12236   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12237
12238   mp->spd_id = ntohl (spd_id);
12239   mp->priority = ntohl (priority);
12240   mp->is_outbound = is_outbound;
12241
12242   mp->is_ipv6 = is_ipv6;
12243   if (is_ipv6 || is_ip_any)
12244     {
12245       clib_memcpy (mp->remote_address_start, &raddr6_start,
12246                    sizeof (ip6_address_t));
12247       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12248                    sizeof (ip6_address_t));
12249       clib_memcpy (mp->local_address_start, &laddr6_start,
12250                    sizeof (ip6_address_t));
12251       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12252                    sizeof (ip6_address_t));
12253     }
12254   else
12255     {
12256       clib_memcpy (mp->remote_address_start, &raddr4_start,
12257                    sizeof (ip4_address_t));
12258       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12259                    sizeof (ip4_address_t));
12260       clib_memcpy (mp->local_address_start, &laddr4_start,
12261                    sizeof (ip4_address_t));
12262       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12263                    sizeof (ip4_address_t));
12264     }
12265   mp->protocol = (u8) protocol;
12266   mp->local_port_start = ntohs ((u16) lport_start);
12267   mp->local_port_stop = ntohs ((u16) lport_stop);
12268   mp->remote_port_start = ntohs ((u16) rport_start);
12269   mp->remote_port_stop = ntohs ((u16) rport_stop);
12270   mp->policy = (u8) policy;
12271   mp->sa_id = ntohl (sa_id);
12272   mp->is_add = is_add;
12273   mp->is_ip_any = is_ip_any;
12274   S (mp);
12275   W (ret);
12276   return ret;
12277 }
12278
12279 static int
12280 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12281 {
12282   unformat_input_t *i = vam->input;
12283   vl_api_ipsec_sad_add_del_entry_t *mp;
12284   u32 sad_id = 0, spi = 0;
12285   u8 *ck = 0, *ik = 0;
12286   u8 is_add = 1;
12287
12288   u8 protocol = IPSEC_PROTOCOL_AH;
12289   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12290   u32 crypto_alg = 0, integ_alg = 0;
12291   ip4_address_t tun_src4;
12292   ip4_address_t tun_dst4;
12293   ip6_address_t tun_src6;
12294   ip6_address_t tun_dst6;
12295   int ret;
12296
12297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12298     {
12299       if (unformat (i, "del"))
12300         is_add = 0;
12301       else if (unformat (i, "sad_id %d", &sad_id))
12302         ;
12303       else if (unformat (i, "spi %d", &spi))
12304         ;
12305       else if (unformat (i, "esp"))
12306         protocol = IPSEC_PROTOCOL_ESP;
12307       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12308         {
12309           is_tunnel = 1;
12310           is_tunnel_ipv6 = 0;
12311         }
12312       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12313         {
12314           is_tunnel = 1;
12315           is_tunnel_ipv6 = 0;
12316         }
12317       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12318         {
12319           is_tunnel = 1;
12320           is_tunnel_ipv6 = 1;
12321         }
12322       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12323         {
12324           is_tunnel = 1;
12325           is_tunnel_ipv6 = 1;
12326         }
12327       else
12328         if (unformat
12329             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12330         {
12331           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12332               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12333             {
12334               clib_warning ("unsupported crypto-alg: '%U'",
12335                             format_ipsec_crypto_alg, crypto_alg);
12336               return -99;
12337             }
12338         }
12339       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12340         ;
12341       else
12342         if (unformat
12343             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12344         {
12345           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12346               integ_alg >= IPSEC_INTEG_N_ALG)
12347             {
12348               clib_warning ("unsupported integ-alg: '%U'",
12349                             format_ipsec_integ_alg, integ_alg);
12350               return -99;
12351             }
12352         }
12353       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12354         ;
12355       else
12356         {
12357           clib_warning ("parse error '%U'", format_unformat_error, i);
12358           return -99;
12359         }
12360
12361     }
12362
12363   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12364
12365   mp->sad_id = ntohl (sad_id);
12366   mp->is_add = is_add;
12367   mp->protocol = protocol;
12368   mp->spi = ntohl (spi);
12369   mp->is_tunnel = is_tunnel;
12370   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12371   mp->crypto_algorithm = crypto_alg;
12372   mp->integrity_algorithm = integ_alg;
12373   mp->crypto_key_length = vec_len (ck);
12374   mp->integrity_key_length = vec_len (ik);
12375
12376   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12377     mp->crypto_key_length = sizeof (mp->crypto_key);
12378
12379   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12380     mp->integrity_key_length = sizeof (mp->integrity_key);
12381
12382   if (ck)
12383     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12384   if (ik)
12385     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12386
12387   if (is_tunnel)
12388     {
12389       if (is_tunnel_ipv6)
12390         {
12391           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12392                        sizeof (ip6_address_t));
12393           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12394                        sizeof (ip6_address_t));
12395         }
12396       else
12397         {
12398           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12399                        sizeof (ip4_address_t));
12400           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12401                        sizeof (ip4_address_t));
12402         }
12403     }
12404
12405   S (mp);
12406   W (ret);
12407   return ret;
12408 }
12409
12410 static int
12411 api_ipsec_sa_set_key (vat_main_t * vam)
12412 {
12413   unformat_input_t *i = vam->input;
12414   vl_api_ipsec_sa_set_key_t *mp;
12415   u32 sa_id;
12416   u8 *ck = 0, *ik = 0;
12417   int ret;
12418
12419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12420     {
12421       if (unformat (i, "sa_id %d", &sa_id))
12422         ;
12423       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12424         ;
12425       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12426         ;
12427       else
12428         {
12429           clib_warning ("parse error '%U'", format_unformat_error, i);
12430           return -99;
12431         }
12432     }
12433
12434   M (IPSEC_SA_SET_KEY, mp);
12435
12436   mp->sa_id = ntohl (sa_id);
12437   mp->crypto_key_length = vec_len (ck);
12438   mp->integrity_key_length = vec_len (ik);
12439
12440   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12441     mp->crypto_key_length = sizeof (mp->crypto_key);
12442
12443   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12444     mp->integrity_key_length = sizeof (mp->integrity_key);
12445
12446   if (ck)
12447     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12448   if (ik)
12449     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12450
12451   S (mp);
12452   W (ret);
12453   return ret;
12454 }
12455
12456 static int
12457 api_ikev2_profile_add_del (vat_main_t * vam)
12458 {
12459   unformat_input_t *i = vam->input;
12460   vl_api_ikev2_profile_add_del_t *mp;
12461   u8 is_add = 1;
12462   u8 *name = 0;
12463   int ret;
12464
12465   const char *valid_chars = "a-zA-Z0-9_";
12466
12467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12468     {
12469       if (unformat (i, "del"))
12470         is_add = 0;
12471       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12472         vec_add1 (name, 0);
12473       else
12474         {
12475           errmsg ("parse error '%U'", format_unformat_error, i);
12476           return -99;
12477         }
12478     }
12479
12480   if (!vec_len (name))
12481     {
12482       errmsg ("profile name must be specified");
12483       return -99;
12484     }
12485
12486   if (vec_len (name) > 64)
12487     {
12488       errmsg ("profile name too long");
12489       return -99;
12490     }
12491
12492   M (IKEV2_PROFILE_ADD_DEL, mp);
12493
12494   clib_memcpy (mp->name, name, vec_len (name));
12495   mp->is_add = is_add;
12496   vec_free (name);
12497
12498   S (mp);
12499   W (ret);
12500   return ret;
12501 }
12502
12503 static int
12504 api_ikev2_profile_set_auth (vat_main_t * vam)
12505 {
12506   unformat_input_t *i = vam->input;
12507   vl_api_ikev2_profile_set_auth_t *mp;
12508   u8 *name = 0;
12509   u8 *data = 0;
12510   u32 auth_method = 0;
12511   u8 is_hex = 0;
12512   int ret;
12513
12514   const char *valid_chars = "a-zA-Z0-9_";
12515
12516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12517     {
12518       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12519         vec_add1 (name, 0);
12520       else if (unformat (i, "auth_method %U",
12521                          unformat_ikev2_auth_method, &auth_method))
12522         ;
12523       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12524         is_hex = 1;
12525       else if (unformat (i, "auth_data %v", &data))
12526         ;
12527       else
12528         {
12529           errmsg ("parse error '%U'", format_unformat_error, i);
12530           return -99;
12531         }
12532     }
12533
12534   if (!vec_len (name))
12535     {
12536       errmsg ("profile name must be specified");
12537       return -99;
12538     }
12539
12540   if (vec_len (name) > 64)
12541     {
12542       errmsg ("profile name too long");
12543       return -99;
12544     }
12545
12546   if (!vec_len (data))
12547     {
12548       errmsg ("auth_data must be specified");
12549       return -99;
12550     }
12551
12552   if (!auth_method)
12553     {
12554       errmsg ("auth_method must be specified");
12555       return -99;
12556     }
12557
12558   M (IKEV2_PROFILE_SET_AUTH, mp);
12559
12560   mp->is_hex = is_hex;
12561   mp->auth_method = (u8) auth_method;
12562   mp->data_len = vec_len (data);
12563   clib_memcpy (mp->name, name, vec_len (name));
12564   clib_memcpy (mp->data, data, vec_len (data));
12565   vec_free (name);
12566   vec_free (data);
12567
12568   S (mp);
12569   W (ret);
12570   return ret;
12571 }
12572
12573 static int
12574 api_ikev2_profile_set_id (vat_main_t * vam)
12575 {
12576   unformat_input_t *i = vam->input;
12577   vl_api_ikev2_profile_set_id_t *mp;
12578   u8 *name = 0;
12579   u8 *data = 0;
12580   u8 is_local = 0;
12581   u32 id_type = 0;
12582   ip4_address_t ip4;
12583   int ret;
12584
12585   const char *valid_chars = "a-zA-Z0-9_";
12586
12587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12588     {
12589       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12590         vec_add1 (name, 0);
12591       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12592         ;
12593       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12594         {
12595           data = vec_new (u8, 4);
12596           clib_memcpy (data, ip4.as_u8, 4);
12597         }
12598       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12599         ;
12600       else if (unformat (i, "id_data %v", &data))
12601         ;
12602       else if (unformat (i, "local"))
12603         is_local = 1;
12604       else if (unformat (i, "remote"))
12605         is_local = 0;
12606       else
12607         {
12608           errmsg ("parse error '%U'", format_unformat_error, i);
12609           return -99;
12610         }
12611     }
12612
12613   if (!vec_len (name))
12614     {
12615       errmsg ("profile name must be specified");
12616       return -99;
12617     }
12618
12619   if (vec_len (name) > 64)
12620     {
12621       errmsg ("profile name too long");
12622       return -99;
12623     }
12624
12625   if (!vec_len (data))
12626     {
12627       errmsg ("id_data must be specified");
12628       return -99;
12629     }
12630
12631   if (!id_type)
12632     {
12633       errmsg ("id_type must be specified");
12634       return -99;
12635     }
12636
12637   M (IKEV2_PROFILE_SET_ID, mp);
12638
12639   mp->is_local = is_local;
12640   mp->id_type = (u8) id_type;
12641   mp->data_len = vec_len (data);
12642   clib_memcpy (mp->name, name, vec_len (name));
12643   clib_memcpy (mp->data, data, vec_len (data));
12644   vec_free (name);
12645   vec_free (data);
12646
12647   S (mp);
12648   W (ret);
12649   return ret;
12650 }
12651
12652 static int
12653 api_ikev2_profile_set_ts (vat_main_t * vam)
12654 {
12655   unformat_input_t *i = vam->input;
12656   vl_api_ikev2_profile_set_ts_t *mp;
12657   u8 *name = 0;
12658   u8 is_local = 0;
12659   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12660   ip4_address_t start_addr, end_addr;
12661
12662   const char *valid_chars = "a-zA-Z0-9_";
12663   int ret;
12664
12665   start_addr.as_u32 = 0;
12666   end_addr.as_u32 = (u32) ~ 0;
12667
12668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12669     {
12670       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12671         vec_add1 (name, 0);
12672       else if (unformat (i, "protocol %d", &proto))
12673         ;
12674       else if (unformat (i, "start_port %d", &start_port))
12675         ;
12676       else if (unformat (i, "end_port %d", &end_port))
12677         ;
12678       else
12679         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12680         ;
12681       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12682         ;
12683       else if (unformat (i, "local"))
12684         is_local = 1;
12685       else if (unformat (i, "remote"))
12686         is_local = 0;
12687       else
12688         {
12689           errmsg ("parse error '%U'", format_unformat_error, i);
12690           return -99;
12691         }
12692     }
12693
12694   if (!vec_len (name))
12695     {
12696       errmsg ("profile name must be specified");
12697       return -99;
12698     }
12699
12700   if (vec_len (name) > 64)
12701     {
12702       errmsg ("profile name too long");
12703       return -99;
12704     }
12705
12706   M (IKEV2_PROFILE_SET_TS, mp);
12707
12708   mp->is_local = is_local;
12709   mp->proto = (u8) proto;
12710   mp->start_port = (u16) start_port;
12711   mp->end_port = (u16) end_port;
12712   mp->start_addr = start_addr.as_u32;
12713   mp->end_addr = end_addr.as_u32;
12714   clib_memcpy (mp->name, name, vec_len (name));
12715   vec_free (name);
12716
12717   S (mp);
12718   W (ret);
12719   return ret;
12720 }
12721
12722 static int
12723 api_ikev2_set_local_key (vat_main_t * vam)
12724 {
12725   unformat_input_t *i = vam->input;
12726   vl_api_ikev2_set_local_key_t *mp;
12727   u8 *file = 0;
12728   int ret;
12729
12730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12731     {
12732       if (unformat (i, "file %v", &file))
12733         vec_add1 (file, 0);
12734       else
12735         {
12736           errmsg ("parse error '%U'", format_unformat_error, i);
12737           return -99;
12738         }
12739     }
12740
12741   if (!vec_len (file))
12742     {
12743       errmsg ("RSA key file must be specified");
12744       return -99;
12745     }
12746
12747   if (vec_len (file) > 256)
12748     {
12749       errmsg ("file name too long");
12750       return -99;
12751     }
12752
12753   M (IKEV2_SET_LOCAL_KEY, mp);
12754
12755   clib_memcpy (mp->key_file, file, vec_len (file));
12756   vec_free (file);
12757
12758   S (mp);
12759   W (ret);
12760   return ret;
12761 }
12762
12763 static int
12764 api_ikev2_set_responder (vat_main_t * vam)
12765 {
12766   unformat_input_t *i = vam->input;
12767   vl_api_ikev2_set_responder_t *mp;
12768   int ret;
12769   u8 *name = 0;
12770   u32 sw_if_index = ~0;
12771   ip4_address_t address;
12772
12773   const char *valid_chars = "a-zA-Z0-9_";
12774
12775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12776     {
12777       if (unformat
12778           (i, "%U interface %d address %U", unformat_token, valid_chars,
12779            &name, &sw_if_index, unformat_ip4_address, &address))
12780         vec_add1 (name, 0);
12781       else
12782         {
12783           errmsg ("parse error '%U'", format_unformat_error, i);
12784           return -99;
12785         }
12786     }
12787
12788   if (!vec_len (name))
12789     {
12790       errmsg ("profile name must be specified");
12791       return -99;
12792     }
12793
12794   if (vec_len (name) > 64)
12795     {
12796       errmsg ("profile name too long");
12797       return -99;
12798     }
12799
12800   M (IKEV2_SET_RESPONDER, mp);
12801
12802   clib_memcpy (mp->name, name, vec_len (name));
12803   vec_free (name);
12804
12805   mp->sw_if_index = sw_if_index;
12806   clib_memcpy (mp->address, &address, sizeof (address));
12807
12808   S (mp);
12809   W (ret);
12810   return ret;
12811 }
12812
12813 static int
12814 api_ikev2_set_ike_transforms (vat_main_t * vam)
12815 {
12816   unformat_input_t *i = vam->input;
12817   vl_api_ikev2_set_ike_transforms_t *mp;
12818   int ret;
12819   u8 *name = 0;
12820   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12821
12822   const char *valid_chars = "a-zA-Z0-9_";
12823
12824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12825     {
12826       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12827                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12828         vec_add1 (name, 0);
12829       else
12830         {
12831           errmsg ("parse error '%U'", format_unformat_error, i);
12832           return -99;
12833         }
12834     }
12835
12836   if (!vec_len (name))
12837     {
12838       errmsg ("profile name must be specified");
12839       return -99;
12840     }
12841
12842   if (vec_len (name) > 64)
12843     {
12844       errmsg ("profile name too long");
12845       return -99;
12846     }
12847
12848   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12849
12850   clib_memcpy (mp->name, name, vec_len (name));
12851   vec_free (name);
12852   mp->crypto_alg = crypto_alg;
12853   mp->crypto_key_size = crypto_key_size;
12854   mp->integ_alg = integ_alg;
12855   mp->dh_group = dh_group;
12856
12857   S (mp);
12858   W (ret);
12859   return ret;
12860 }
12861
12862
12863 static int
12864 api_ikev2_set_esp_transforms (vat_main_t * vam)
12865 {
12866   unformat_input_t *i = vam->input;
12867   vl_api_ikev2_set_esp_transforms_t *mp;
12868   int ret;
12869   u8 *name = 0;
12870   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12871
12872   const char *valid_chars = "a-zA-Z0-9_";
12873
12874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12875     {
12876       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12877                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12878         vec_add1 (name, 0);
12879       else
12880         {
12881           errmsg ("parse error '%U'", format_unformat_error, i);
12882           return -99;
12883         }
12884     }
12885
12886   if (!vec_len (name))
12887     {
12888       errmsg ("profile name must be specified");
12889       return -99;
12890     }
12891
12892   if (vec_len (name) > 64)
12893     {
12894       errmsg ("profile name too long");
12895       return -99;
12896     }
12897
12898   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12899
12900   clib_memcpy (mp->name, name, vec_len (name));
12901   vec_free (name);
12902   mp->crypto_alg = crypto_alg;
12903   mp->crypto_key_size = crypto_key_size;
12904   mp->integ_alg = integ_alg;
12905   mp->dh_group = dh_group;
12906
12907   S (mp);
12908   W (ret);
12909   return ret;
12910 }
12911
12912 static int
12913 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12914 {
12915   unformat_input_t *i = vam->input;
12916   vl_api_ikev2_set_sa_lifetime_t *mp;
12917   int ret;
12918   u8 *name = 0;
12919   u64 lifetime, lifetime_maxdata;
12920   u32 lifetime_jitter, handover;
12921
12922   const char *valid_chars = "a-zA-Z0-9_";
12923
12924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12925     {
12926       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12927                     &lifetime, &lifetime_jitter, &handover,
12928                     &lifetime_maxdata))
12929         vec_add1 (name, 0);
12930       else
12931         {
12932           errmsg ("parse error '%U'", format_unformat_error, i);
12933           return -99;
12934         }
12935     }
12936
12937   if (!vec_len (name))
12938     {
12939       errmsg ("profile name must be specified");
12940       return -99;
12941     }
12942
12943   if (vec_len (name) > 64)
12944     {
12945       errmsg ("profile name too long");
12946       return -99;
12947     }
12948
12949   M (IKEV2_SET_SA_LIFETIME, mp);
12950
12951   clib_memcpy (mp->name, name, vec_len (name));
12952   vec_free (name);
12953   mp->lifetime = lifetime;
12954   mp->lifetime_jitter = lifetime_jitter;
12955   mp->handover = handover;
12956   mp->lifetime_maxdata = lifetime_maxdata;
12957
12958   S (mp);
12959   W (ret);
12960   return ret;
12961 }
12962
12963 static int
12964 api_ikev2_initiate_sa_init (vat_main_t * vam)
12965 {
12966   unformat_input_t *i = vam->input;
12967   vl_api_ikev2_initiate_sa_init_t *mp;
12968   int ret;
12969   u8 *name = 0;
12970
12971   const char *valid_chars = "a-zA-Z0-9_";
12972
12973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12974     {
12975       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12976         vec_add1 (name, 0);
12977       else
12978         {
12979           errmsg ("parse error '%U'", format_unformat_error, i);
12980           return -99;
12981         }
12982     }
12983
12984   if (!vec_len (name))
12985     {
12986       errmsg ("profile name must be specified");
12987       return -99;
12988     }
12989
12990   if (vec_len (name) > 64)
12991     {
12992       errmsg ("profile name too long");
12993       return -99;
12994     }
12995
12996   M (IKEV2_INITIATE_SA_INIT, mp);
12997
12998   clib_memcpy (mp->name, name, vec_len (name));
12999   vec_free (name);
13000
13001   S (mp);
13002   W (ret);
13003   return ret;
13004 }
13005
13006 static int
13007 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13008 {
13009   unformat_input_t *i = vam->input;
13010   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13011   int ret;
13012   u64 ispi;
13013
13014
13015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13016     {
13017       if (unformat (i, "%lx", &ispi))
13018         ;
13019       else
13020         {
13021           errmsg ("parse error '%U'", format_unformat_error, i);
13022           return -99;
13023         }
13024     }
13025
13026   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13027
13028   mp->ispi = ispi;
13029
13030   S (mp);
13031   W (ret);
13032   return ret;
13033 }
13034
13035 static int
13036 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13037 {
13038   unformat_input_t *i = vam->input;
13039   vl_api_ikev2_initiate_del_child_sa_t *mp;
13040   int ret;
13041   u32 ispi;
13042
13043
13044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13045     {
13046       if (unformat (i, "%x", &ispi))
13047         ;
13048       else
13049         {
13050           errmsg ("parse error '%U'", format_unformat_error, i);
13051           return -99;
13052         }
13053     }
13054
13055   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13056
13057   mp->ispi = ispi;
13058
13059   S (mp);
13060   W (ret);
13061   return ret;
13062 }
13063
13064 static int
13065 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13066 {
13067   unformat_input_t *i = vam->input;
13068   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13069   int ret;
13070   u32 ispi;
13071
13072
13073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13074     {
13075       if (unformat (i, "%x", &ispi))
13076         ;
13077       else
13078         {
13079           errmsg ("parse error '%U'", format_unformat_error, i);
13080           return -99;
13081         }
13082     }
13083
13084   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13085
13086   mp->ispi = ispi;
13087
13088   S (mp);
13089   W (ret);
13090   return ret;
13091 }
13092
13093 /*
13094  * MAP
13095  */
13096 static int
13097 api_map_add_domain (vat_main_t * vam)
13098 {
13099   unformat_input_t *i = vam->input;
13100   vl_api_map_add_domain_t *mp;
13101
13102   ip4_address_t ip4_prefix;
13103   ip6_address_t ip6_prefix;
13104   ip6_address_t ip6_src;
13105   u32 num_m_args = 0;
13106   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13107     0, psid_length = 0;
13108   u8 is_translation = 0;
13109   u32 mtu = 0;
13110   u32 ip6_src_len = 128;
13111   int ret;
13112
13113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13114     {
13115       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13116                     &ip4_prefix, &ip4_prefix_len))
13117         num_m_args++;
13118       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13119                          &ip6_prefix, &ip6_prefix_len))
13120         num_m_args++;
13121       else
13122         if (unformat
13123             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13124              &ip6_src_len))
13125         num_m_args++;
13126       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13127         num_m_args++;
13128       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13129         num_m_args++;
13130       else if (unformat (i, "psid-offset %d", &psid_offset))
13131         num_m_args++;
13132       else if (unformat (i, "psid-len %d", &psid_length))
13133         num_m_args++;
13134       else if (unformat (i, "mtu %d", &mtu))
13135         num_m_args++;
13136       else if (unformat (i, "map-t"))
13137         is_translation = 1;
13138       else
13139         {
13140           clib_warning ("parse error '%U'", format_unformat_error, i);
13141           return -99;
13142         }
13143     }
13144
13145   if (num_m_args < 3)
13146     {
13147       errmsg ("mandatory argument(s) missing");
13148       return -99;
13149     }
13150
13151   /* Construct the API message */
13152   M (MAP_ADD_DOMAIN, mp);
13153
13154   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13155   mp->ip4_prefix_len = ip4_prefix_len;
13156
13157   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13158   mp->ip6_prefix_len = ip6_prefix_len;
13159
13160   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13161   mp->ip6_src_prefix_len = ip6_src_len;
13162
13163   mp->ea_bits_len = ea_bits_len;
13164   mp->psid_offset = psid_offset;
13165   mp->psid_length = psid_length;
13166   mp->is_translation = is_translation;
13167   mp->mtu = htons (mtu);
13168
13169   /* send it... */
13170   S (mp);
13171
13172   /* Wait for a reply, return good/bad news  */
13173   W (ret);
13174   return ret;
13175 }
13176
13177 static int
13178 api_map_del_domain (vat_main_t * vam)
13179 {
13180   unformat_input_t *i = vam->input;
13181   vl_api_map_del_domain_t *mp;
13182
13183   u32 num_m_args = 0;
13184   u32 index;
13185   int ret;
13186
13187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13188     {
13189       if (unformat (i, "index %d", &index))
13190         num_m_args++;
13191       else
13192         {
13193           clib_warning ("parse error '%U'", format_unformat_error, i);
13194           return -99;
13195         }
13196     }
13197
13198   if (num_m_args != 1)
13199     {
13200       errmsg ("mandatory argument(s) missing");
13201       return -99;
13202     }
13203
13204   /* Construct the API message */
13205   M (MAP_DEL_DOMAIN, mp);
13206
13207   mp->index = ntohl (index);
13208
13209   /* send it... */
13210   S (mp);
13211
13212   /* Wait for a reply, return good/bad news  */
13213   W (ret);
13214   return ret;
13215 }
13216
13217 static int
13218 api_map_add_del_rule (vat_main_t * vam)
13219 {
13220   unformat_input_t *i = vam->input;
13221   vl_api_map_add_del_rule_t *mp;
13222   u8 is_add = 1;
13223   ip6_address_t ip6_dst;
13224   u32 num_m_args = 0, index, psid = 0;
13225   int ret;
13226
13227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13228     {
13229       if (unformat (i, "index %d", &index))
13230         num_m_args++;
13231       else if (unformat (i, "psid %d", &psid))
13232         num_m_args++;
13233       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13234         num_m_args++;
13235       else if (unformat (i, "del"))
13236         {
13237           is_add = 0;
13238         }
13239       else
13240         {
13241           clib_warning ("parse error '%U'", format_unformat_error, i);
13242           return -99;
13243         }
13244     }
13245
13246   /* Construct the API message */
13247   M (MAP_ADD_DEL_RULE, mp);
13248
13249   mp->index = ntohl (index);
13250   mp->is_add = is_add;
13251   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13252   mp->psid = ntohs (psid);
13253
13254   /* send it... */
13255   S (mp);
13256
13257   /* Wait for a reply, return good/bad news  */
13258   W (ret);
13259   return ret;
13260 }
13261
13262 static int
13263 api_map_domain_dump (vat_main_t * vam)
13264 {
13265   vl_api_map_domain_dump_t *mp;
13266   vl_api_control_ping_t *mp_ping;
13267   int ret;
13268
13269   /* Construct the API message */
13270   M (MAP_DOMAIN_DUMP, mp);
13271
13272   /* send it... */
13273   S (mp);
13274
13275   /* Use a control ping for synchronization */
13276   M (CONTROL_PING, mp_ping);
13277   S (mp_ping);
13278
13279   W (ret);
13280   return ret;
13281 }
13282
13283 static int
13284 api_map_rule_dump (vat_main_t * vam)
13285 {
13286   unformat_input_t *i = vam->input;
13287   vl_api_map_rule_dump_t *mp;
13288   vl_api_control_ping_t *mp_ping;
13289   u32 domain_index = ~0;
13290   int ret;
13291
13292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13293     {
13294       if (unformat (i, "index %u", &domain_index))
13295         ;
13296       else
13297         break;
13298     }
13299
13300   if (domain_index == ~0)
13301     {
13302       clib_warning ("parse error: domain index expected");
13303       return -99;
13304     }
13305
13306   /* Construct the API message */
13307   M (MAP_RULE_DUMP, mp);
13308
13309   mp->domain_index = htonl (domain_index);
13310
13311   /* send it... */
13312   S (mp);
13313
13314   /* Use a control ping for synchronization */
13315   M (CONTROL_PING, mp_ping);
13316   S (mp_ping);
13317
13318   W (ret);
13319   return ret;
13320 }
13321
13322 static void vl_api_map_add_domain_reply_t_handler
13323   (vl_api_map_add_domain_reply_t * mp)
13324 {
13325   vat_main_t *vam = &vat_main;
13326   i32 retval = ntohl (mp->retval);
13327
13328   if (vam->async_mode)
13329     {
13330       vam->async_errors += (retval < 0);
13331     }
13332   else
13333     {
13334       vam->retval = retval;
13335       vam->result_ready = 1;
13336     }
13337 }
13338
13339 static void vl_api_map_add_domain_reply_t_handler_json
13340   (vl_api_map_add_domain_reply_t * mp)
13341 {
13342   vat_main_t *vam = &vat_main;
13343   vat_json_node_t node;
13344
13345   vat_json_init_object (&node);
13346   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13347   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13348
13349   vat_json_print (vam->ofp, &node);
13350   vat_json_free (&node);
13351
13352   vam->retval = ntohl (mp->retval);
13353   vam->result_ready = 1;
13354 }
13355
13356 static int
13357 api_get_first_msg_id (vat_main_t * vam)
13358 {
13359   vl_api_get_first_msg_id_t *mp;
13360   unformat_input_t *i = vam->input;
13361   u8 *name;
13362   u8 name_set = 0;
13363   int ret;
13364
13365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13366     {
13367       if (unformat (i, "client %s", &name))
13368         name_set = 1;
13369       else
13370         break;
13371     }
13372
13373   if (name_set == 0)
13374     {
13375       errmsg ("missing client name");
13376       return -99;
13377     }
13378   vec_add1 (name, 0);
13379
13380   if (vec_len (name) > 63)
13381     {
13382       errmsg ("client name too long");
13383       return -99;
13384     }
13385
13386   M (GET_FIRST_MSG_ID, mp);
13387   clib_memcpy (mp->name, name, vec_len (name));
13388   S (mp);
13389   W (ret);
13390   return ret;
13391 }
13392
13393 static int
13394 api_cop_interface_enable_disable (vat_main_t * vam)
13395 {
13396   unformat_input_t *line_input = vam->input;
13397   vl_api_cop_interface_enable_disable_t *mp;
13398   u32 sw_if_index = ~0;
13399   u8 enable_disable = 1;
13400   int ret;
13401
13402   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13403     {
13404       if (unformat (line_input, "disable"))
13405         enable_disable = 0;
13406       if (unformat (line_input, "enable"))
13407         enable_disable = 1;
13408       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13409                          vam, &sw_if_index))
13410         ;
13411       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13412         ;
13413       else
13414         break;
13415     }
13416
13417   if (sw_if_index == ~0)
13418     {
13419       errmsg ("missing interface name or sw_if_index");
13420       return -99;
13421     }
13422
13423   /* Construct the API message */
13424   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13425   mp->sw_if_index = ntohl (sw_if_index);
13426   mp->enable_disable = enable_disable;
13427
13428   /* send it... */
13429   S (mp);
13430   /* Wait for the reply */
13431   W (ret);
13432   return ret;
13433 }
13434
13435 static int
13436 api_cop_whitelist_enable_disable (vat_main_t * vam)
13437 {
13438   unformat_input_t *line_input = vam->input;
13439   vl_api_cop_whitelist_enable_disable_t *mp;
13440   u32 sw_if_index = ~0;
13441   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13442   u32 fib_id = 0;
13443   int ret;
13444
13445   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13446     {
13447       if (unformat (line_input, "ip4"))
13448         ip4 = 1;
13449       else if (unformat (line_input, "ip6"))
13450         ip6 = 1;
13451       else if (unformat (line_input, "default"))
13452         default_cop = 1;
13453       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13454                          vam, &sw_if_index))
13455         ;
13456       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13457         ;
13458       else if (unformat (line_input, "fib-id %d", &fib_id))
13459         ;
13460       else
13461         break;
13462     }
13463
13464   if (sw_if_index == ~0)
13465     {
13466       errmsg ("missing interface name or sw_if_index");
13467       return -99;
13468     }
13469
13470   /* Construct the API message */
13471   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13472   mp->sw_if_index = ntohl (sw_if_index);
13473   mp->fib_id = ntohl (fib_id);
13474   mp->ip4 = ip4;
13475   mp->ip6 = ip6;
13476   mp->default_cop = default_cop;
13477
13478   /* send it... */
13479   S (mp);
13480   /* Wait for the reply */
13481   W (ret);
13482   return ret;
13483 }
13484
13485 static int
13486 api_get_node_graph (vat_main_t * vam)
13487 {
13488   vl_api_get_node_graph_t *mp;
13489   int ret;
13490
13491   M (GET_NODE_GRAPH, mp);
13492
13493   /* send it... */
13494   S (mp);
13495   /* Wait for the reply */
13496   W (ret);
13497   return ret;
13498 }
13499
13500 /* *INDENT-OFF* */
13501 /** Used for parsing LISP eids */
13502 typedef CLIB_PACKED(struct{
13503   u8 addr[16];   /**< eid address */
13504   u32 len;       /**< prefix length if IP */
13505   u8 type;      /**< type of eid */
13506 }) lisp_eid_vat_t;
13507 /* *INDENT-ON* */
13508
13509 static uword
13510 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13511 {
13512   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13513
13514   memset (a, 0, sizeof (a[0]));
13515
13516   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13517     {
13518       a->type = 0;              /* ipv4 type */
13519     }
13520   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13521     {
13522       a->type = 1;              /* ipv6 type */
13523     }
13524   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13525     {
13526       a->type = 2;              /* mac type */
13527     }
13528   else
13529     {
13530       return 0;
13531     }
13532
13533   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13534     {
13535       return 0;
13536     }
13537
13538   return 1;
13539 }
13540
13541 static int
13542 lisp_eid_size_vat (u8 type)
13543 {
13544   switch (type)
13545     {
13546     case 0:
13547       return 4;
13548     case 1:
13549       return 16;
13550     case 2:
13551       return 6;
13552     }
13553   return 0;
13554 }
13555
13556 static void
13557 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13558 {
13559   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13560 }
13561
13562 static int
13563 api_one_add_del_locator_set (vat_main_t * vam)
13564 {
13565   unformat_input_t *input = vam->input;
13566   vl_api_one_add_del_locator_set_t *mp;
13567   u8 is_add = 1;
13568   u8 *locator_set_name = NULL;
13569   u8 locator_set_name_set = 0;
13570   vl_api_local_locator_t locator, *locators = 0;
13571   u32 sw_if_index, priority, weight;
13572   u32 data_len = 0;
13573
13574   int ret;
13575   /* Parse args required to build the message */
13576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13577     {
13578       if (unformat (input, "del"))
13579         {
13580           is_add = 0;
13581         }
13582       else if (unformat (input, "locator-set %s", &locator_set_name))
13583         {
13584           locator_set_name_set = 1;
13585         }
13586       else if (unformat (input, "sw_if_index %u p %u w %u",
13587                          &sw_if_index, &priority, &weight))
13588         {
13589           locator.sw_if_index = htonl (sw_if_index);
13590           locator.priority = priority;
13591           locator.weight = weight;
13592           vec_add1 (locators, locator);
13593         }
13594       else
13595         if (unformat
13596             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13597              &sw_if_index, &priority, &weight))
13598         {
13599           locator.sw_if_index = htonl (sw_if_index);
13600           locator.priority = priority;
13601           locator.weight = weight;
13602           vec_add1 (locators, locator);
13603         }
13604       else
13605         break;
13606     }
13607
13608   if (locator_set_name_set == 0)
13609     {
13610       errmsg ("missing locator-set name");
13611       vec_free (locators);
13612       return -99;
13613     }
13614
13615   if (vec_len (locator_set_name) > 64)
13616     {
13617       errmsg ("locator-set name too long");
13618       vec_free (locator_set_name);
13619       vec_free (locators);
13620       return -99;
13621     }
13622   vec_add1 (locator_set_name, 0);
13623
13624   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13625
13626   /* Construct the API message */
13627   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13628
13629   mp->is_add = is_add;
13630   clib_memcpy (mp->locator_set_name, locator_set_name,
13631                vec_len (locator_set_name));
13632   vec_free (locator_set_name);
13633
13634   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13635   if (locators)
13636     clib_memcpy (mp->locators, locators, data_len);
13637   vec_free (locators);
13638
13639   /* send it... */
13640   S (mp);
13641
13642   /* Wait for a reply... */
13643   W (ret);
13644   return ret;
13645 }
13646
13647 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13648
13649 static int
13650 api_one_add_del_locator (vat_main_t * vam)
13651 {
13652   unformat_input_t *input = vam->input;
13653   vl_api_one_add_del_locator_t *mp;
13654   u32 tmp_if_index = ~0;
13655   u32 sw_if_index = ~0;
13656   u8 sw_if_index_set = 0;
13657   u8 sw_if_index_if_name_set = 0;
13658   u32 priority = ~0;
13659   u8 priority_set = 0;
13660   u32 weight = ~0;
13661   u8 weight_set = 0;
13662   u8 is_add = 1;
13663   u8 *locator_set_name = NULL;
13664   u8 locator_set_name_set = 0;
13665   int ret;
13666
13667   /* Parse args required to build the message */
13668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13669     {
13670       if (unformat (input, "del"))
13671         {
13672           is_add = 0;
13673         }
13674       else if (unformat (input, "locator-set %s", &locator_set_name))
13675         {
13676           locator_set_name_set = 1;
13677         }
13678       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13679                          &tmp_if_index))
13680         {
13681           sw_if_index_if_name_set = 1;
13682           sw_if_index = tmp_if_index;
13683         }
13684       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13685         {
13686           sw_if_index_set = 1;
13687           sw_if_index = tmp_if_index;
13688         }
13689       else if (unformat (input, "p %d", &priority))
13690         {
13691           priority_set = 1;
13692         }
13693       else if (unformat (input, "w %d", &weight))
13694         {
13695           weight_set = 1;
13696         }
13697       else
13698         break;
13699     }
13700
13701   if (locator_set_name_set == 0)
13702     {
13703       errmsg ("missing locator-set name");
13704       return -99;
13705     }
13706
13707   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13708     {
13709       errmsg ("missing sw_if_index");
13710       vec_free (locator_set_name);
13711       return -99;
13712     }
13713
13714   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13715     {
13716       errmsg ("cannot use both params interface name and sw_if_index");
13717       vec_free (locator_set_name);
13718       return -99;
13719     }
13720
13721   if (priority_set == 0)
13722     {
13723       errmsg ("missing locator-set priority");
13724       vec_free (locator_set_name);
13725       return -99;
13726     }
13727
13728   if (weight_set == 0)
13729     {
13730       errmsg ("missing locator-set weight");
13731       vec_free (locator_set_name);
13732       return -99;
13733     }
13734
13735   if (vec_len (locator_set_name) > 64)
13736     {
13737       errmsg ("locator-set name too long");
13738       vec_free (locator_set_name);
13739       return -99;
13740     }
13741   vec_add1 (locator_set_name, 0);
13742
13743   /* Construct the API message */
13744   M (ONE_ADD_DEL_LOCATOR, mp);
13745
13746   mp->is_add = is_add;
13747   mp->sw_if_index = ntohl (sw_if_index);
13748   mp->priority = priority;
13749   mp->weight = weight;
13750   clib_memcpy (mp->locator_set_name, locator_set_name,
13751                vec_len (locator_set_name));
13752   vec_free (locator_set_name);
13753
13754   /* send it... */
13755   S (mp);
13756
13757   /* Wait for a reply... */
13758   W (ret);
13759   return ret;
13760 }
13761
13762 #define api_lisp_add_del_locator api_one_add_del_locator
13763
13764 uword
13765 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13766 {
13767   u32 *key_id = va_arg (*args, u32 *);
13768   u8 *s = 0;
13769
13770   if (unformat (input, "%s", &s))
13771     {
13772       if (!strcmp ((char *) s, "sha1"))
13773         key_id[0] = HMAC_SHA_1_96;
13774       else if (!strcmp ((char *) s, "sha256"))
13775         key_id[0] = HMAC_SHA_256_128;
13776       else
13777         {
13778           clib_warning ("invalid key_id: '%s'", s);
13779           key_id[0] = HMAC_NO_KEY;
13780         }
13781     }
13782   else
13783     return 0;
13784
13785   vec_free (s);
13786   return 1;
13787 }
13788
13789 static int
13790 api_one_add_del_local_eid (vat_main_t * vam)
13791 {
13792   unformat_input_t *input = vam->input;
13793   vl_api_one_add_del_local_eid_t *mp;
13794   u8 is_add = 1;
13795   u8 eid_set = 0;
13796   lisp_eid_vat_t _eid, *eid = &_eid;
13797   u8 *locator_set_name = 0;
13798   u8 locator_set_name_set = 0;
13799   u32 vni = 0;
13800   u16 key_id = 0;
13801   u8 *key = 0;
13802   int ret;
13803
13804   /* Parse args required to build the message */
13805   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13806     {
13807       if (unformat (input, "del"))
13808         {
13809           is_add = 0;
13810         }
13811       else if (unformat (input, "vni %d", &vni))
13812         {
13813           ;
13814         }
13815       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13816         {
13817           eid_set = 1;
13818         }
13819       else if (unformat (input, "locator-set %s", &locator_set_name))
13820         {
13821           locator_set_name_set = 1;
13822         }
13823       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13824         ;
13825       else if (unformat (input, "secret-key %_%v%_", &key))
13826         ;
13827       else
13828         break;
13829     }
13830
13831   if (locator_set_name_set == 0)
13832     {
13833       errmsg ("missing locator-set name");
13834       return -99;
13835     }
13836
13837   if (0 == eid_set)
13838     {
13839       errmsg ("EID address not set!");
13840       vec_free (locator_set_name);
13841       return -99;
13842     }
13843
13844   if (key && (0 == key_id))
13845     {
13846       errmsg ("invalid key_id!");
13847       return -99;
13848     }
13849
13850   if (vec_len (key) > 64)
13851     {
13852       errmsg ("key too long");
13853       vec_free (key);
13854       return -99;
13855     }
13856
13857   if (vec_len (locator_set_name) > 64)
13858     {
13859       errmsg ("locator-set name too long");
13860       vec_free (locator_set_name);
13861       return -99;
13862     }
13863   vec_add1 (locator_set_name, 0);
13864
13865   /* Construct the API message */
13866   M (ONE_ADD_DEL_LOCAL_EID, mp);
13867
13868   mp->is_add = is_add;
13869   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13870   mp->eid_type = eid->type;
13871   mp->prefix_len = eid->len;
13872   mp->vni = clib_host_to_net_u32 (vni);
13873   mp->key_id = clib_host_to_net_u16 (key_id);
13874   clib_memcpy (mp->locator_set_name, locator_set_name,
13875                vec_len (locator_set_name));
13876   clib_memcpy (mp->key, key, vec_len (key));
13877
13878   vec_free (locator_set_name);
13879   vec_free (key);
13880
13881   /* send it... */
13882   S (mp);
13883
13884   /* Wait for a reply... */
13885   W (ret);
13886   return ret;
13887 }
13888
13889 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13890
13891 static int
13892 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13893 {
13894   u32 dp_table = 0, vni = 0;;
13895   unformat_input_t *input = vam->input;
13896   vl_api_gpe_add_del_fwd_entry_t *mp;
13897   u8 is_add = 1;
13898   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13899   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13900   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13901   u32 action = ~0, w;
13902   ip4_address_t rmt_rloc4, lcl_rloc4;
13903   ip6_address_t rmt_rloc6, lcl_rloc6;
13904   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 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 (GPE_ADD_DEL_FWD_ENTRY, mp,
13997       sizeof (vl_api_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_gpe_locator_t) * vec_len (lcl_locs)));
14014
14015       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14016       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14017                    (sizeof (vl_api_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_one_add_del_map_server (vat_main_t * vam)
14032 {
14033   unformat_input_t *input = vam->input;
14034   vl_api_one_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 (ONE_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 #define api_lisp_add_del_map_server api_one_add_del_map_server
14097
14098 static int
14099 api_one_add_del_map_resolver (vat_main_t * vam)
14100 {
14101   unformat_input_t *input = vam->input;
14102   vl_api_one_add_del_map_resolver_t *mp;
14103   u8 is_add = 1;
14104   u8 ipv4_set = 0;
14105   u8 ipv6_set = 0;
14106   ip4_address_t ipv4;
14107   ip6_address_t ipv6;
14108   int ret;
14109
14110   /* Parse args required to build the message */
14111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14112     {
14113       if (unformat (input, "del"))
14114         {
14115           is_add = 0;
14116         }
14117       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14118         {
14119           ipv4_set = 1;
14120         }
14121       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14122         {
14123           ipv6_set = 1;
14124         }
14125       else
14126         break;
14127     }
14128
14129   if (ipv4_set && ipv6_set)
14130     {
14131       errmsg ("both eid v4 and v6 addresses set");
14132       return -99;
14133     }
14134
14135   if (!ipv4_set && !ipv6_set)
14136     {
14137       errmsg ("eid addresses not set");
14138       return -99;
14139     }
14140
14141   /* Construct the API message */
14142   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14143
14144   mp->is_add = is_add;
14145   if (ipv6_set)
14146     {
14147       mp->is_ipv6 = 1;
14148       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14149     }
14150   else
14151     {
14152       mp->is_ipv6 = 0;
14153       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14154     }
14155
14156   /* send it... */
14157   S (mp);
14158
14159   /* Wait for a reply... */
14160   W (ret);
14161   return ret;
14162 }
14163
14164 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14165
14166 static int
14167 api_lisp_gpe_enable_disable (vat_main_t * vam)
14168 {
14169   unformat_input_t *input = vam->input;
14170   vl_api_gpe_enable_disable_t *mp;
14171   u8 is_set = 0;
14172   u8 is_en = 1;
14173   int ret;
14174
14175   /* Parse args required to build the message */
14176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14177     {
14178       if (unformat (input, "enable"))
14179         {
14180           is_set = 1;
14181           is_en = 1;
14182         }
14183       else if (unformat (input, "disable"))
14184         {
14185           is_set = 1;
14186           is_en = 0;
14187         }
14188       else
14189         break;
14190     }
14191
14192   if (is_set == 0)
14193     {
14194       errmsg ("Value not set");
14195       return -99;
14196     }
14197
14198   /* Construct the API message */
14199   M (GPE_ENABLE_DISABLE, mp);
14200
14201   mp->is_en = is_en;
14202
14203   /* send it... */
14204   S (mp);
14205
14206   /* Wait for a reply... */
14207   W (ret);
14208   return ret;
14209 }
14210
14211 static int
14212 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14213 {
14214   unformat_input_t *input = vam->input;
14215   vl_api_one_rloc_probe_enable_disable_t *mp;
14216   u8 is_set = 0;
14217   u8 is_en = 0;
14218   int ret;
14219
14220   /* Parse args required to build the message */
14221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14222     {
14223       if (unformat (input, "enable"))
14224         {
14225           is_set = 1;
14226           is_en = 1;
14227         }
14228       else if (unformat (input, "disable"))
14229         is_set = 1;
14230       else
14231         break;
14232     }
14233
14234   if (!is_set)
14235     {
14236       errmsg ("Value not set");
14237       return -99;
14238     }
14239
14240   /* Construct the API message */
14241   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14242
14243   mp->is_enabled = is_en;
14244
14245   /* send it... */
14246   S (mp);
14247
14248   /* Wait for a reply... */
14249   W (ret);
14250   return ret;
14251 }
14252
14253 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14254
14255 static int
14256 api_one_map_register_enable_disable (vat_main_t * vam)
14257 {
14258   unformat_input_t *input = vam->input;
14259   vl_api_one_map_register_enable_disable_t *mp;
14260   u8 is_set = 0;
14261   u8 is_en = 0;
14262   int ret;
14263
14264   /* Parse args required to build the message */
14265   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14266     {
14267       if (unformat (input, "enable"))
14268         {
14269           is_set = 1;
14270           is_en = 1;
14271         }
14272       else if (unformat (input, "disable"))
14273         is_set = 1;
14274       else
14275         break;
14276     }
14277
14278   if (!is_set)
14279     {
14280       errmsg ("Value not set");
14281       return -99;
14282     }
14283
14284   /* Construct the API message */
14285   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14286
14287   mp->is_enabled = is_en;
14288
14289   /* send it... */
14290   S (mp);
14291
14292   /* Wait for a reply... */
14293   W (ret);
14294   return ret;
14295 }
14296
14297 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14298
14299 static int
14300 api_one_enable_disable (vat_main_t * vam)
14301 {
14302   unformat_input_t *input = vam->input;
14303   vl_api_one_enable_disable_t *mp;
14304   u8 is_set = 0;
14305   u8 is_en = 0;
14306   int ret;
14307
14308   /* Parse args required to build the message */
14309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14310     {
14311       if (unformat (input, "enable"))
14312         {
14313           is_set = 1;
14314           is_en = 1;
14315         }
14316       else if (unformat (input, "disable"))
14317         {
14318           is_set = 1;
14319         }
14320       else
14321         break;
14322     }
14323
14324   if (!is_set)
14325     {
14326       errmsg ("Value not set");
14327       return -99;
14328     }
14329
14330   /* Construct the API message */
14331   M (ONE_ENABLE_DISABLE, mp);
14332
14333   mp->is_en = is_en;
14334
14335   /* send it... */
14336   S (mp);
14337
14338   /* Wait for a reply... */
14339   W (ret);
14340   return ret;
14341 }
14342
14343 #define api_lisp_enable_disable api_one_enable_disable
14344
14345 static int
14346 api_show_one_map_register_state (vat_main_t * vam)
14347 {
14348   vl_api_show_one_map_register_state_t *mp;
14349   int ret;
14350
14351   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14352
14353   /* send */
14354   S (mp);
14355
14356   /* wait for reply */
14357   W (ret);
14358   return ret;
14359 }
14360
14361 #define api_show_lisp_map_register_state api_show_one_map_register_state
14362
14363 static int
14364 api_show_one_rloc_probe_state (vat_main_t * vam)
14365 {
14366   vl_api_show_one_rloc_probe_state_t *mp;
14367   int ret;
14368
14369   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14370
14371   /* send */
14372   S (mp);
14373
14374   /* wait for reply */
14375   W (ret);
14376   return ret;
14377 }
14378
14379 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14380
14381 static int
14382 api_show_one_map_request_mode (vat_main_t * vam)
14383 {
14384   vl_api_show_one_map_request_mode_t *mp;
14385   int ret;
14386
14387   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14388
14389   /* send */
14390   S (mp);
14391
14392   /* wait for reply */
14393   W (ret);
14394   return ret;
14395 }
14396
14397 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14398
14399 static int
14400 api_one_map_request_mode (vat_main_t * vam)
14401 {
14402   unformat_input_t *input = vam->input;
14403   vl_api_one_map_request_mode_t *mp;
14404   u8 mode = 0;
14405   int ret;
14406
14407   /* Parse args required to build the message */
14408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14409     {
14410       if (unformat (input, "dst-only"))
14411         mode = 0;
14412       else if (unformat (input, "src-dst"))
14413         mode = 1;
14414       else
14415         {
14416           errmsg ("parse error '%U'", format_unformat_error, input);
14417           return -99;
14418         }
14419     }
14420
14421   M (ONE_MAP_REQUEST_MODE, mp);
14422
14423   mp->mode = mode;
14424
14425   /* send */
14426   S (mp);
14427
14428   /* wait for reply */
14429   W (ret);
14430   return ret;
14431 }
14432
14433 #define api_lisp_map_request_mode api_one_map_request_mode
14434
14435 /**
14436  * Enable/disable ONE proxy ITR.
14437  *
14438  * @param vam vpp API test context
14439  * @return return code
14440  */
14441 static int
14442 api_one_pitr_set_locator_set (vat_main_t * vam)
14443 {
14444   u8 ls_name_set = 0;
14445   unformat_input_t *input = vam->input;
14446   vl_api_one_pitr_set_locator_set_t *mp;
14447   u8 is_add = 1;
14448   u8 *ls_name = 0;
14449   int ret;
14450
14451   /* Parse args required to build the message */
14452   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14453     {
14454       if (unformat (input, "del"))
14455         is_add = 0;
14456       else if (unformat (input, "locator-set %s", &ls_name))
14457         ls_name_set = 1;
14458       else
14459         {
14460           errmsg ("parse error '%U'", format_unformat_error, input);
14461           return -99;
14462         }
14463     }
14464
14465   if (!ls_name_set)
14466     {
14467       errmsg ("locator-set name not set!");
14468       return -99;
14469     }
14470
14471   M (ONE_PITR_SET_LOCATOR_SET, mp);
14472
14473   mp->is_add = is_add;
14474   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14475   vec_free (ls_name);
14476
14477   /* send */
14478   S (mp);
14479
14480   /* wait for reply */
14481   W (ret);
14482   return ret;
14483 }
14484
14485 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14486
14487 static int
14488 api_show_one_pitr (vat_main_t * vam)
14489 {
14490   vl_api_show_one_pitr_t *mp;
14491   int ret;
14492
14493   if (!vam->json_output)
14494     {
14495       print (vam->ofp, "%=20s", "lisp status:");
14496     }
14497
14498   M (SHOW_ONE_PITR, mp);
14499   /* send it... */
14500   S (mp);
14501
14502   /* Wait for a reply... */
14503   W (ret);
14504   return ret;
14505 }
14506
14507 #define api_show_lisp_pitr api_show_one_pitr
14508
14509 /**
14510  * Add/delete mapping between vni and vrf
14511  */
14512 static int
14513 api_one_eid_table_add_del_map (vat_main_t * vam)
14514 {
14515   unformat_input_t *input = vam->input;
14516   vl_api_one_eid_table_add_del_map_t *mp;
14517   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14518   u32 vni, vrf, bd_index;
14519   int ret;
14520
14521   /* Parse args required to build the message */
14522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14523     {
14524       if (unformat (input, "del"))
14525         is_add = 0;
14526       else if (unformat (input, "vrf %d", &vrf))
14527         vrf_set = 1;
14528       else if (unformat (input, "bd_index %d", &bd_index))
14529         bd_index_set = 1;
14530       else if (unformat (input, "vni %d", &vni))
14531         vni_set = 1;
14532       else
14533         break;
14534     }
14535
14536   if (!vni_set || (!vrf_set && !bd_index_set))
14537     {
14538       errmsg ("missing arguments!");
14539       return -99;
14540     }
14541
14542   if (vrf_set && bd_index_set)
14543     {
14544       errmsg ("error: both vrf and bd entered!");
14545       return -99;
14546     }
14547
14548   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14549
14550   mp->is_add = is_add;
14551   mp->vni = htonl (vni);
14552   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14553   mp->is_l2 = bd_index_set;
14554
14555   /* send */
14556   S (mp);
14557
14558   /* wait for reply */
14559   W (ret);
14560   return ret;
14561 }
14562
14563 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14564
14565 uword
14566 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14567 {
14568   u32 *action = va_arg (*args, u32 *);
14569   u8 *s = 0;
14570
14571   if (unformat (input, "%s", &s))
14572     {
14573       if (!strcmp ((char *) s, "no-action"))
14574         action[0] = 0;
14575       else if (!strcmp ((char *) s, "natively-forward"))
14576         action[0] = 1;
14577       else if (!strcmp ((char *) s, "send-map-request"))
14578         action[0] = 2;
14579       else if (!strcmp ((char *) s, "drop"))
14580         action[0] = 3;
14581       else
14582         {
14583           clib_warning ("invalid action: '%s'", s);
14584           action[0] = 3;
14585         }
14586     }
14587   else
14588     return 0;
14589
14590   vec_free (s);
14591   return 1;
14592 }
14593
14594 /**
14595  * Add/del remote mapping to/from ONE control plane
14596  *
14597  * @param vam vpp API test context
14598  * @return return code
14599  */
14600 static int
14601 api_one_add_del_remote_mapping (vat_main_t * vam)
14602 {
14603   unformat_input_t *input = vam->input;
14604   vl_api_one_add_del_remote_mapping_t *mp;
14605   u32 vni = 0;
14606   lisp_eid_vat_t _eid, *eid = &_eid;
14607   lisp_eid_vat_t _seid, *seid = &_seid;
14608   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14609   u32 action = ~0, p, w, data_len;
14610   ip4_address_t rloc4;
14611   ip6_address_t rloc6;
14612   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14613   int ret;
14614
14615   memset (&rloc, 0, sizeof (rloc));
14616
14617   /* Parse args required to build the message */
14618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14619     {
14620       if (unformat (input, "del-all"))
14621         {
14622           del_all = 1;
14623         }
14624       else if (unformat (input, "del"))
14625         {
14626           is_add = 0;
14627         }
14628       else if (unformat (input, "add"))
14629         {
14630           is_add = 1;
14631         }
14632       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14633         {
14634           eid_set = 1;
14635         }
14636       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14637         {
14638           seid_set = 1;
14639         }
14640       else if (unformat (input, "vni %d", &vni))
14641         {
14642           ;
14643         }
14644       else if (unformat (input, "p %d w %d", &p, &w))
14645         {
14646           if (!curr_rloc)
14647             {
14648               errmsg ("No RLOC configured for setting priority/weight!");
14649               return -99;
14650             }
14651           curr_rloc->priority = p;
14652           curr_rloc->weight = w;
14653         }
14654       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14655         {
14656           rloc.is_ip4 = 1;
14657           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14658           vec_add1 (rlocs, rloc);
14659           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14660         }
14661       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14662         {
14663           rloc.is_ip4 = 0;
14664           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14665           vec_add1 (rlocs, rloc);
14666           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14667         }
14668       else if (unformat (input, "action %U",
14669                          unformat_negative_mapping_action, &action))
14670         {
14671           ;
14672         }
14673       else
14674         {
14675           clib_warning ("parse error '%U'", format_unformat_error, input);
14676           return -99;
14677         }
14678     }
14679
14680   if (0 == eid_set)
14681     {
14682       errmsg ("missing params!");
14683       return -99;
14684     }
14685
14686   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14687     {
14688       errmsg ("no action set for negative map-reply!");
14689       return -99;
14690     }
14691
14692   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14693
14694   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14695   mp->is_add = is_add;
14696   mp->vni = htonl (vni);
14697   mp->action = (u8) action;
14698   mp->is_src_dst = seid_set;
14699   mp->eid_len = eid->len;
14700   mp->seid_len = seid->len;
14701   mp->del_all = del_all;
14702   mp->eid_type = eid->type;
14703   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14704   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14705
14706   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14707   clib_memcpy (mp->rlocs, rlocs, data_len);
14708   vec_free (rlocs);
14709
14710   /* send it... */
14711   S (mp);
14712
14713   /* Wait for a reply... */
14714   W (ret);
14715   return ret;
14716 }
14717
14718 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14719
14720 /**
14721  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14722  * forwarding entries in data-plane accordingly.
14723  *
14724  * @param vam vpp API test context
14725  * @return return code
14726  */
14727 static int
14728 api_one_add_del_adjacency (vat_main_t * vam)
14729 {
14730   unformat_input_t *input = vam->input;
14731   vl_api_one_add_del_adjacency_t *mp;
14732   u32 vni = 0;
14733   ip4_address_t leid4, reid4;
14734   ip6_address_t leid6, reid6;
14735   u8 reid_mac[6] = { 0 };
14736   u8 leid_mac[6] = { 0 };
14737   u8 reid_type, leid_type;
14738   u32 leid_len = 0, reid_len = 0, len;
14739   u8 is_add = 1;
14740   int ret;
14741
14742   leid_type = reid_type = (u8) ~ 0;
14743
14744   /* Parse args required to build the message */
14745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14746     {
14747       if (unformat (input, "del"))
14748         {
14749           is_add = 0;
14750         }
14751       else if (unformat (input, "add"))
14752         {
14753           is_add = 1;
14754         }
14755       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14756                          &reid4, &len))
14757         {
14758           reid_type = 0;        /* ipv4 */
14759           reid_len = len;
14760         }
14761       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14762                          &reid6, &len))
14763         {
14764           reid_type = 1;        /* ipv6 */
14765           reid_len = len;
14766         }
14767       else if (unformat (input, "reid %U", unformat_ethernet_address,
14768                          reid_mac))
14769         {
14770           reid_type = 2;        /* mac */
14771         }
14772       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14773                          &leid4, &len))
14774         {
14775           leid_type = 0;        /* ipv4 */
14776           leid_len = len;
14777         }
14778       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14779                          &leid6, &len))
14780         {
14781           leid_type = 1;        /* ipv6 */
14782           leid_len = len;
14783         }
14784       else if (unformat (input, "leid %U", unformat_ethernet_address,
14785                          leid_mac))
14786         {
14787           leid_type = 2;        /* mac */
14788         }
14789       else if (unformat (input, "vni %d", &vni))
14790         {
14791           ;
14792         }
14793       else
14794         {
14795           errmsg ("parse error '%U'", format_unformat_error, input);
14796           return -99;
14797         }
14798     }
14799
14800   if ((u8) ~ 0 == reid_type)
14801     {
14802       errmsg ("missing params!");
14803       return -99;
14804     }
14805
14806   if (leid_type != reid_type)
14807     {
14808       errmsg ("remote and local EIDs are of different types!");
14809       return -99;
14810     }
14811
14812   M (ONE_ADD_DEL_ADJACENCY, mp);
14813   mp->is_add = is_add;
14814   mp->vni = htonl (vni);
14815   mp->leid_len = leid_len;
14816   mp->reid_len = reid_len;
14817   mp->eid_type = reid_type;
14818
14819   switch (mp->eid_type)
14820     {
14821     case 0:
14822       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14823       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14824       break;
14825     case 1:
14826       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14827       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14828       break;
14829     case 2:
14830       clib_memcpy (mp->leid, leid_mac, 6);
14831       clib_memcpy (mp->reid, reid_mac, 6);
14832       break;
14833     default:
14834       errmsg ("unknown EID type %d!", mp->eid_type);
14835       return 0;
14836     }
14837
14838   /* send it... */
14839   S (mp);
14840
14841   /* Wait for a reply... */
14842   W (ret);
14843   return ret;
14844 }
14845
14846 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14847
14848 static int
14849 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14850 {
14851   unformat_input_t *input = vam->input;
14852   vl_api_gpe_add_del_iface_t *mp;
14853   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14854   u32 dp_table = 0, vni = 0;
14855   int ret;
14856
14857   /* Parse args required to build the message */
14858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14859     {
14860       if (unformat (input, "up"))
14861         {
14862           action_set = 1;
14863           is_add = 1;
14864         }
14865       else if (unformat (input, "down"))
14866         {
14867           action_set = 1;
14868           is_add = 0;
14869         }
14870       else if (unformat (input, "table_id %d", &dp_table))
14871         {
14872           dp_table_set = 1;
14873         }
14874       else if (unformat (input, "bd_id %d", &dp_table))
14875         {
14876           dp_table_set = 1;
14877           is_l2 = 1;
14878         }
14879       else if (unformat (input, "vni %d", &vni))
14880         {
14881           vni_set = 1;
14882         }
14883       else
14884         break;
14885     }
14886
14887   if (action_set == 0)
14888     {
14889       errmsg ("Action not set");
14890       return -99;
14891     }
14892   if (dp_table_set == 0 || vni_set == 0)
14893     {
14894       errmsg ("vni and dp_table must be set");
14895       return -99;
14896     }
14897
14898   /* Construct the API message */
14899   M (GPE_ADD_DEL_IFACE, mp);
14900
14901   mp->is_add = is_add;
14902   mp->dp_table = dp_table;
14903   mp->is_l2 = is_l2;
14904   mp->vni = vni;
14905
14906   /* send it... */
14907   S (mp);
14908
14909   /* Wait for a reply... */
14910   W (ret);
14911   return ret;
14912 }
14913
14914 /**
14915  * Add/del map request itr rlocs from ONE control plane and updates
14916  *
14917  * @param vam vpp API test context
14918  * @return return code
14919  */
14920 static int
14921 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14922 {
14923   unformat_input_t *input = vam->input;
14924   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14925   u8 *locator_set_name = 0;
14926   u8 locator_set_name_set = 0;
14927   u8 is_add = 1;
14928   int ret;
14929
14930   /* Parse args required to build the message */
14931   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14932     {
14933       if (unformat (input, "del"))
14934         {
14935           is_add = 0;
14936         }
14937       else if (unformat (input, "%_%v%_", &locator_set_name))
14938         {
14939           locator_set_name_set = 1;
14940         }
14941       else
14942         {
14943           clib_warning ("parse error '%U'", format_unformat_error, input);
14944           return -99;
14945         }
14946     }
14947
14948   if (is_add && !locator_set_name_set)
14949     {
14950       errmsg ("itr-rloc is not set!");
14951       return -99;
14952     }
14953
14954   if (is_add && vec_len (locator_set_name) > 64)
14955     {
14956       errmsg ("itr-rloc locator-set name too long");
14957       vec_free (locator_set_name);
14958       return -99;
14959     }
14960
14961   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14962   mp->is_add = is_add;
14963   if (is_add)
14964     {
14965       clib_memcpy (mp->locator_set_name, locator_set_name,
14966                    vec_len (locator_set_name));
14967     }
14968   else
14969     {
14970       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14971     }
14972   vec_free (locator_set_name);
14973
14974   /* send it... */
14975   S (mp);
14976
14977   /* Wait for a reply... */
14978   W (ret);
14979   return ret;
14980 }
14981
14982 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
14983
14984 static int
14985 api_one_locator_dump (vat_main_t * vam)
14986 {
14987   unformat_input_t *input = vam->input;
14988   vl_api_one_locator_dump_t *mp;
14989   vl_api_control_ping_t *mp_ping;
14990   u8 is_index_set = 0, is_name_set = 0;
14991   u8 *ls_name = 0;
14992   u32 ls_index = ~0;
14993   int ret;
14994
14995   /* Parse args required to build the message */
14996   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14997     {
14998       if (unformat (input, "ls_name %_%v%_", &ls_name))
14999         {
15000           is_name_set = 1;
15001         }
15002       else if (unformat (input, "ls_index %d", &ls_index))
15003         {
15004           is_index_set = 1;
15005         }
15006       else
15007         {
15008           errmsg ("parse error '%U'", format_unformat_error, input);
15009           return -99;
15010         }
15011     }
15012
15013   if (!is_index_set && !is_name_set)
15014     {
15015       errmsg ("error: expected one of index or name!");
15016       return -99;
15017     }
15018
15019   if (is_index_set && is_name_set)
15020     {
15021       errmsg ("error: only one param expected!");
15022       return -99;
15023     }
15024
15025   if (vec_len (ls_name) > 62)
15026     {
15027       errmsg ("error: locator set name too long!");
15028       return -99;
15029     }
15030
15031   if (!vam->json_output)
15032     {
15033       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15034     }
15035
15036   M (ONE_LOCATOR_DUMP, mp);
15037   mp->is_index_set = is_index_set;
15038
15039   if (is_index_set)
15040     mp->ls_index = clib_host_to_net_u32 (ls_index);
15041   else
15042     {
15043       vec_add1 (ls_name, 0);
15044       strncpy ((char *) mp->ls_name, (char *) ls_name,
15045                sizeof (mp->ls_name) - 1);
15046     }
15047
15048   /* send it... */
15049   S (mp);
15050
15051   /* Use a control ping for synchronization */
15052   M (CONTROL_PING, mp_ping);
15053   S (mp_ping);
15054
15055   /* Wait for a reply... */
15056   W (ret);
15057   return ret;
15058 }
15059
15060 #define api_lisp_locator_dump api_one_locator_dump
15061
15062 static int
15063 api_one_locator_set_dump (vat_main_t * vam)
15064 {
15065   vl_api_one_locator_set_dump_t *mp;
15066   vl_api_control_ping_t *mp_ping;
15067   unformat_input_t *input = vam->input;
15068   u8 filter = 0;
15069   int ret;
15070
15071   /* Parse args required to build the message */
15072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15073     {
15074       if (unformat (input, "local"))
15075         {
15076           filter = 1;
15077         }
15078       else if (unformat (input, "remote"))
15079         {
15080           filter = 2;
15081         }
15082       else
15083         {
15084           errmsg ("parse error '%U'", format_unformat_error, input);
15085           return -99;
15086         }
15087     }
15088
15089   if (!vam->json_output)
15090     {
15091       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15092     }
15093
15094   M (ONE_LOCATOR_SET_DUMP, mp);
15095
15096   mp->filter = filter;
15097
15098   /* send it... */
15099   S (mp);
15100
15101   /* Use a control ping for synchronization */
15102   M (CONTROL_PING, mp_ping);
15103   S (mp_ping);
15104
15105   /* Wait for a reply... */
15106   W (ret);
15107   return ret;
15108 }
15109
15110 #define api_lisp_locator_set_dump api_one_locator_set_dump
15111
15112 static int
15113 api_one_eid_table_map_dump (vat_main_t * vam)
15114 {
15115   u8 is_l2 = 0;
15116   u8 mode_set = 0;
15117   unformat_input_t *input = vam->input;
15118   vl_api_one_eid_table_map_dump_t *mp;
15119   vl_api_control_ping_t *mp_ping;
15120   int ret;
15121
15122   /* Parse args required to build the message */
15123   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15124     {
15125       if (unformat (input, "l2"))
15126         {
15127           is_l2 = 1;
15128           mode_set = 1;
15129         }
15130       else if (unformat (input, "l3"))
15131         {
15132           is_l2 = 0;
15133           mode_set = 1;
15134         }
15135       else
15136         {
15137           errmsg ("parse error '%U'", format_unformat_error, input);
15138           return -99;
15139         }
15140     }
15141
15142   if (!mode_set)
15143     {
15144       errmsg ("expected one of 'l2' or 'l3' parameter!");
15145       return -99;
15146     }
15147
15148   if (!vam->json_output)
15149     {
15150       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15151     }
15152
15153   M (ONE_EID_TABLE_MAP_DUMP, mp);
15154   mp->is_l2 = is_l2;
15155
15156   /* send it... */
15157   S (mp);
15158
15159   /* Use a control ping for synchronization */
15160   M (CONTROL_PING, mp_ping);
15161   S (mp_ping);
15162
15163   /* Wait for a reply... */
15164   W (ret);
15165   return ret;
15166 }
15167
15168 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15169
15170 static int
15171 api_one_eid_table_vni_dump (vat_main_t * vam)
15172 {
15173   vl_api_one_eid_table_vni_dump_t *mp;
15174   vl_api_control_ping_t *mp_ping;
15175   int ret;
15176
15177   if (!vam->json_output)
15178     {
15179       print (vam->ofp, "VNI");
15180     }
15181
15182   M (ONE_EID_TABLE_VNI_DUMP, mp);
15183
15184   /* send it... */
15185   S (mp);
15186
15187   /* Use a control ping for synchronization */
15188   M (CONTROL_PING, mp_ping);
15189   S (mp_ping);
15190
15191   /* Wait for a reply... */
15192   W (ret);
15193   return ret;
15194 }
15195
15196 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15197
15198 static int
15199 api_one_eid_table_dump (vat_main_t * vam)
15200 {
15201   unformat_input_t *i = vam->input;
15202   vl_api_one_eid_table_dump_t *mp;
15203   vl_api_control_ping_t *mp_ping;
15204   struct in_addr ip4;
15205   struct in6_addr ip6;
15206   u8 mac[6];
15207   u8 eid_type = ~0, eid_set = 0;
15208   u32 prefix_length = ~0, t, vni = 0;
15209   u8 filter = 0;
15210   int ret;
15211
15212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15213     {
15214       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15215         {
15216           eid_set = 1;
15217           eid_type = 0;
15218           prefix_length = t;
15219         }
15220       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15221         {
15222           eid_set = 1;
15223           eid_type = 1;
15224           prefix_length = t;
15225         }
15226       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15227         {
15228           eid_set = 1;
15229           eid_type = 2;
15230         }
15231       else if (unformat (i, "vni %d", &t))
15232         {
15233           vni = t;
15234         }
15235       else if (unformat (i, "local"))
15236         {
15237           filter = 1;
15238         }
15239       else if (unformat (i, "remote"))
15240         {
15241           filter = 2;
15242         }
15243       else
15244         {
15245           errmsg ("parse error '%U'", format_unformat_error, i);
15246           return -99;
15247         }
15248     }
15249
15250   if (!vam->json_output)
15251     {
15252       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15253              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15254     }
15255
15256   M (ONE_EID_TABLE_DUMP, mp);
15257
15258   mp->filter = filter;
15259   if (eid_set)
15260     {
15261       mp->eid_set = 1;
15262       mp->vni = htonl (vni);
15263       mp->eid_type = eid_type;
15264       switch (eid_type)
15265         {
15266         case 0:
15267           mp->prefix_length = prefix_length;
15268           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15269           break;
15270         case 1:
15271           mp->prefix_length = prefix_length;
15272           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15273           break;
15274         case 2:
15275           clib_memcpy (mp->eid, mac, sizeof (mac));
15276           break;
15277         default:
15278           errmsg ("unknown EID type %d!", eid_type);
15279           return -99;
15280         }
15281     }
15282
15283   /* send it... */
15284   S (mp);
15285
15286   /* Use a control ping for synchronization */
15287   M (CONTROL_PING, mp_ping);
15288   S (mp_ping);
15289
15290   /* Wait for a reply... */
15291   W (ret);
15292   return ret;
15293 }
15294
15295 #define api_lisp_eid_table_dump api_one_eid_table_dump
15296
15297 static int
15298 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15299 {
15300   unformat_input_t *i = vam->input;
15301   vl_api_gpe_fwd_entries_get_t *mp;
15302   u8 vni_set = 0;
15303   u32 vni = ~0;
15304   int ret;
15305
15306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15307     {
15308       if (unformat (i, "vni %d", &vni))
15309         {
15310           vni_set = 1;
15311         }
15312       else
15313         {
15314           errmsg ("parse error '%U'", format_unformat_error, i);
15315           return -99;
15316         }
15317     }
15318
15319   if (!vni_set)
15320     {
15321       errmsg ("vni not set!");
15322       return -99;
15323     }
15324
15325   if (!vam->json_output)
15326     {
15327       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15328              "leid", "reid");
15329     }
15330
15331   M (GPE_FWD_ENTRIES_GET, mp);
15332   mp->vni = clib_host_to_net_u32 (vni);
15333
15334   /* send it... */
15335   S (mp);
15336
15337   /* Wait for a reply... */
15338   W (ret);
15339   return ret;
15340 }
15341
15342 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15343 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15344 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15345 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15346
15347 static int
15348 api_one_adjacencies_get (vat_main_t * vam)
15349 {
15350   unformat_input_t *i = vam->input;
15351   vl_api_one_adjacencies_get_t *mp;
15352   u8 vni_set = 0;
15353   u32 vni = ~0;
15354   int ret;
15355
15356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15357     {
15358       if (unformat (i, "vni %d", &vni))
15359         {
15360           vni_set = 1;
15361         }
15362       else
15363         {
15364           errmsg ("parse error '%U'", format_unformat_error, i);
15365           return -99;
15366         }
15367     }
15368
15369   if (!vni_set)
15370     {
15371       errmsg ("vni not set!");
15372       return -99;
15373     }
15374
15375   if (!vam->json_output)
15376     {
15377       print (vam->ofp, "%s %40s", "leid", "reid");
15378     }
15379
15380   M (ONE_ADJACENCIES_GET, mp);
15381   mp->vni = clib_host_to_net_u32 (vni);
15382
15383   /* send it... */
15384   S (mp);
15385
15386   /* Wait for a reply... */
15387   W (ret);
15388   return ret;
15389 }
15390
15391 #define api_lisp_adjacencies_get api_one_adjacencies_get
15392
15393 static int
15394 api_one_map_server_dump (vat_main_t * vam)
15395 {
15396   vl_api_one_map_server_dump_t *mp;
15397   vl_api_control_ping_t *mp_ping;
15398   int ret;
15399
15400   if (!vam->json_output)
15401     {
15402       print (vam->ofp, "%=20s", "Map server");
15403     }
15404
15405   M (ONE_MAP_SERVER_DUMP, mp);
15406   /* send it... */
15407   S (mp);
15408
15409   /* Use a control ping for synchronization */
15410   M (CONTROL_PING, mp_ping);
15411   S (mp_ping);
15412
15413   /* Wait for a reply... */
15414   W (ret);
15415   return ret;
15416 }
15417
15418 #define api_lisp_map_server_dump api_one_map_server_dump
15419
15420 static int
15421 api_one_map_resolver_dump (vat_main_t * vam)
15422 {
15423   vl_api_one_map_resolver_dump_t *mp;
15424   vl_api_control_ping_t *mp_ping;
15425   int ret;
15426
15427   if (!vam->json_output)
15428     {
15429       print (vam->ofp, "%=20s", "Map resolver");
15430     }
15431
15432   M (ONE_MAP_RESOLVER_DUMP, mp);
15433   /* send it... */
15434   S (mp);
15435
15436   /* Use a control ping for synchronization */
15437   M (CONTROL_PING, mp_ping);
15438   S (mp_ping);
15439
15440   /* Wait for a reply... */
15441   W (ret);
15442   return ret;
15443 }
15444
15445 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15446
15447 static int
15448 api_show_one_status (vat_main_t * vam)
15449 {
15450   vl_api_show_one_status_t *mp;
15451   int ret;
15452
15453   if (!vam->json_output)
15454     {
15455       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15456     }
15457
15458   M (SHOW_ONE_STATUS, mp);
15459   /* send it... */
15460   S (mp);
15461   /* Wait for a reply... */
15462   W (ret);
15463   return ret;
15464 }
15465
15466 #define api_show_lisp_status api_show_one_status
15467
15468 static int
15469 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15470 {
15471   vl_api_gpe_fwd_entry_path_dump_t *mp;
15472   vl_api_control_ping_t *mp_ping;
15473   unformat_input_t *i = vam->input;
15474   u32 fwd_entry_index = ~0;
15475   int ret;
15476
15477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15478     {
15479       if (unformat (i, "index %d", &fwd_entry_index))
15480         ;
15481       else
15482         break;
15483     }
15484
15485   if (~0 == fwd_entry_index)
15486     {
15487       errmsg ("no index specified!");
15488       return -99;
15489     }
15490
15491   if (!vam->json_output)
15492     {
15493       print (vam->ofp, "first line");
15494     }
15495
15496   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15497
15498   /* send it... */
15499   S (mp);
15500   /* Use a control ping for synchronization */
15501   M (CONTROL_PING, mp_ping);
15502   S (mp_ping);
15503
15504   /* Wait for a reply... */
15505   W (ret);
15506   return ret;
15507 }
15508
15509 static int
15510 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15511 {
15512   vl_api_one_get_map_request_itr_rlocs_t *mp;
15513   int ret;
15514
15515   if (!vam->json_output)
15516     {
15517       print (vam->ofp, "%=20s", "itr-rlocs:");
15518     }
15519
15520   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15521   /* send it... */
15522   S (mp);
15523   /* Wait for a reply... */
15524   W (ret);
15525   return ret;
15526 }
15527
15528 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15529
15530 static int
15531 api_af_packet_create (vat_main_t * vam)
15532 {
15533   unformat_input_t *i = vam->input;
15534   vl_api_af_packet_create_t *mp;
15535   u8 *host_if_name = 0;
15536   u8 hw_addr[6];
15537   u8 random_hw_addr = 1;
15538   int ret;
15539
15540   memset (hw_addr, 0, sizeof (hw_addr));
15541
15542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15543     {
15544       if (unformat (i, "name %s", &host_if_name))
15545         vec_add1 (host_if_name, 0);
15546       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15547         random_hw_addr = 0;
15548       else
15549         break;
15550     }
15551
15552   if (!vec_len (host_if_name))
15553     {
15554       errmsg ("host-interface name must be specified");
15555       return -99;
15556     }
15557
15558   if (vec_len (host_if_name) > 64)
15559     {
15560       errmsg ("host-interface name too long");
15561       return -99;
15562     }
15563
15564   M (AF_PACKET_CREATE, mp);
15565
15566   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15567   clib_memcpy (mp->hw_addr, hw_addr, 6);
15568   mp->use_random_hw_addr = random_hw_addr;
15569   vec_free (host_if_name);
15570
15571   S (mp);
15572   W2 (ret, fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
15573   return ret;
15574 }
15575
15576 static int
15577 api_af_packet_delete (vat_main_t * vam)
15578 {
15579   unformat_input_t *i = vam->input;
15580   vl_api_af_packet_delete_t *mp;
15581   u8 *host_if_name = 0;
15582   int ret;
15583
15584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15585     {
15586       if (unformat (i, "name %s", &host_if_name))
15587         vec_add1 (host_if_name, 0);
15588       else
15589         break;
15590     }
15591
15592   if (!vec_len (host_if_name))
15593     {
15594       errmsg ("host-interface name must be specified");
15595       return -99;
15596     }
15597
15598   if (vec_len (host_if_name) > 64)
15599     {
15600       errmsg ("host-interface name too long");
15601       return -99;
15602     }
15603
15604   M (AF_PACKET_DELETE, mp);
15605
15606   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15607   vec_free (host_if_name);
15608
15609   S (mp);
15610   W (ret);
15611   return ret;
15612 }
15613
15614 static int
15615 api_policer_add_del (vat_main_t * vam)
15616 {
15617   unformat_input_t *i = vam->input;
15618   vl_api_policer_add_del_t *mp;
15619   u8 is_add = 1;
15620   u8 *name = 0;
15621   u32 cir = 0;
15622   u32 eir = 0;
15623   u64 cb = 0;
15624   u64 eb = 0;
15625   u8 rate_type = 0;
15626   u8 round_type = 0;
15627   u8 type = 0;
15628   u8 color_aware = 0;
15629   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15630   int ret;
15631
15632   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15633   conform_action.dscp = 0;
15634   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15635   exceed_action.dscp = 0;
15636   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15637   violate_action.dscp = 0;
15638
15639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15640     {
15641       if (unformat (i, "del"))
15642         is_add = 0;
15643       else if (unformat (i, "name %s", &name))
15644         vec_add1 (name, 0);
15645       else if (unformat (i, "cir %u", &cir))
15646         ;
15647       else if (unformat (i, "eir %u", &eir))
15648         ;
15649       else if (unformat (i, "cb %u", &cb))
15650         ;
15651       else if (unformat (i, "eb %u", &eb))
15652         ;
15653       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15654                          &rate_type))
15655         ;
15656       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15657                          &round_type))
15658         ;
15659       else if (unformat (i, "type %U", unformat_policer_type, &type))
15660         ;
15661       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15662                          &conform_action))
15663         ;
15664       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15665                          &exceed_action))
15666         ;
15667       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15668                          &violate_action))
15669         ;
15670       else if (unformat (i, "color-aware"))
15671         color_aware = 1;
15672       else
15673         break;
15674     }
15675
15676   if (!vec_len (name))
15677     {
15678       errmsg ("policer name must be specified");
15679       return -99;
15680     }
15681
15682   if (vec_len (name) > 64)
15683     {
15684       errmsg ("policer name too long");
15685       return -99;
15686     }
15687
15688   M (POLICER_ADD_DEL, mp);
15689
15690   clib_memcpy (mp->name, name, vec_len (name));
15691   vec_free (name);
15692   mp->is_add = is_add;
15693   mp->cir = cir;
15694   mp->eir = eir;
15695   mp->cb = cb;
15696   mp->eb = eb;
15697   mp->rate_type = rate_type;
15698   mp->round_type = round_type;
15699   mp->type = type;
15700   mp->conform_action_type = conform_action.action_type;
15701   mp->conform_dscp = conform_action.dscp;
15702   mp->exceed_action_type = exceed_action.action_type;
15703   mp->exceed_dscp = exceed_action.dscp;
15704   mp->violate_action_type = violate_action.action_type;
15705   mp->violate_dscp = violate_action.dscp;
15706   mp->color_aware = color_aware;
15707
15708   S (mp);
15709   W (ret);
15710   return ret;
15711 }
15712
15713 static int
15714 api_policer_dump (vat_main_t * vam)
15715 {
15716   unformat_input_t *i = vam->input;
15717   vl_api_policer_dump_t *mp;
15718   vl_api_control_ping_t *mp_ping;
15719   u8 *match_name = 0;
15720   u8 match_name_valid = 0;
15721   int ret;
15722
15723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15724     {
15725       if (unformat (i, "name %s", &match_name))
15726         {
15727           vec_add1 (match_name, 0);
15728           match_name_valid = 1;
15729         }
15730       else
15731         break;
15732     }
15733
15734   M (POLICER_DUMP, mp);
15735   mp->match_name_valid = match_name_valid;
15736   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15737   vec_free (match_name);
15738   /* send it... */
15739   S (mp);
15740
15741   /* Use a control ping for synchronization */
15742   M (CONTROL_PING, mp_ping);
15743   S (mp_ping);
15744
15745   /* Wait for a reply... */
15746   W (ret);
15747   return ret;
15748 }
15749
15750 static int
15751 api_policer_classify_set_interface (vat_main_t * vam)
15752 {
15753   unformat_input_t *i = vam->input;
15754   vl_api_policer_classify_set_interface_t *mp;
15755   u32 sw_if_index;
15756   int sw_if_index_set;
15757   u32 ip4_table_index = ~0;
15758   u32 ip6_table_index = ~0;
15759   u32 l2_table_index = ~0;
15760   u8 is_add = 1;
15761   int ret;
15762
15763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15764     {
15765       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15766         sw_if_index_set = 1;
15767       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15768         sw_if_index_set = 1;
15769       else if (unformat (i, "del"))
15770         is_add = 0;
15771       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15772         ;
15773       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15774         ;
15775       else if (unformat (i, "l2-table %d", &l2_table_index))
15776         ;
15777       else
15778         {
15779           clib_warning ("parse error '%U'", format_unformat_error, i);
15780           return -99;
15781         }
15782     }
15783
15784   if (sw_if_index_set == 0)
15785     {
15786       errmsg ("missing interface name or sw_if_index");
15787       return -99;
15788     }
15789
15790   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15791
15792   mp->sw_if_index = ntohl (sw_if_index);
15793   mp->ip4_table_index = ntohl (ip4_table_index);
15794   mp->ip6_table_index = ntohl (ip6_table_index);
15795   mp->l2_table_index = ntohl (l2_table_index);
15796   mp->is_add = is_add;
15797
15798   S (mp);
15799   W (ret);
15800   return ret;
15801 }
15802
15803 static int
15804 api_policer_classify_dump (vat_main_t * vam)
15805 {
15806   unformat_input_t *i = vam->input;
15807   vl_api_policer_classify_dump_t *mp;
15808   vl_api_control_ping_t *mp_ping;
15809   u8 type = POLICER_CLASSIFY_N_TABLES;
15810   int ret;
15811
15812   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15813     ;
15814   else
15815     {
15816       errmsg ("classify table type must be specified");
15817       return -99;
15818     }
15819
15820   if (!vam->json_output)
15821     {
15822       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15823     }
15824
15825   M (POLICER_CLASSIFY_DUMP, mp);
15826   mp->type = type;
15827   /* send it... */
15828   S (mp);
15829
15830   /* Use a control ping for synchronization */
15831   M (CONTROL_PING, mp_ping);
15832   S (mp_ping);
15833
15834   /* Wait for a reply... */
15835   W (ret);
15836   return ret;
15837 }
15838
15839 static int
15840 api_netmap_create (vat_main_t * vam)
15841 {
15842   unformat_input_t *i = vam->input;
15843   vl_api_netmap_create_t *mp;
15844   u8 *if_name = 0;
15845   u8 hw_addr[6];
15846   u8 random_hw_addr = 1;
15847   u8 is_pipe = 0;
15848   u8 is_master = 0;
15849   int ret;
15850
15851   memset (hw_addr, 0, sizeof (hw_addr));
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 if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15858         random_hw_addr = 0;
15859       else if (unformat (i, "pipe"))
15860         is_pipe = 1;
15861       else if (unformat (i, "master"))
15862         is_master = 1;
15863       else if (unformat (i, "slave"))
15864         is_master = 0;
15865       else
15866         break;
15867     }
15868
15869   if (!vec_len (if_name))
15870     {
15871       errmsg ("interface name must be specified");
15872       return -99;
15873     }
15874
15875   if (vec_len (if_name) > 64)
15876     {
15877       errmsg ("interface name too long");
15878       return -99;
15879     }
15880
15881   M (NETMAP_CREATE, mp);
15882
15883   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15884   clib_memcpy (mp->hw_addr, hw_addr, 6);
15885   mp->use_random_hw_addr = random_hw_addr;
15886   mp->is_pipe = is_pipe;
15887   mp->is_master = is_master;
15888   vec_free (if_name);
15889
15890   S (mp);
15891   W (ret);
15892   return ret;
15893 }
15894
15895 static int
15896 api_netmap_delete (vat_main_t * vam)
15897 {
15898   unformat_input_t *i = vam->input;
15899   vl_api_netmap_delete_t *mp;
15900   u8 *if_name = 0;
15901   int ret;
15902
15903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15904     {
15905       if (unformat (i, "name %s", &if_name))
15906         vec_add1 (if_name, 0);
15907       else
15908         break;
15909     }
15910
15911   if (!vec_len (if_name))
15912     {
15913       errmsg ("interface name must be specified");
15914       return -99;
15915     }
15916
15917   if (vec_len (if_name) > 64)
15918     {
15919       errmsg ("interface name too long");
15920       return -99;
15921     }
15922
15923   M (NETMAP_DELETE, mp);
15924
15925   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15926   vec_free (if_name);
15927
15928   S (mp);
15929   W (ret);
15930   return ret;
15931 }
15932
15933 static void vl_api_mpls_tunnel_details_t_handler
15934   (vl_api_mpls_tunnel_details_t * mp)
15935 {
15936   vat_main_t *vam = &vat_main;
15937   i32 len = mp->mt_next_hop_n_labels;
15938   i32 i;
15939
15940   print (vam->ofp, "[%d]: via %U %d labels ",
15941          mp->tunnel_index,
15942          format_ip4_address, mp->mt_next_hop,
15943          ntohl (mp->mt_next_hop_sw_if_index));
15944   for (i = 0; i < len; i++)
15945     {
15946       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15947     }
15948   print (vam->ofp, "");
15949 }
15950
15951 static void vl_api_mpls_tunnel_details_t_handler_json
15952   (vl_api_mpls_tunnel_details_t * mp)
15953 {
15954   vat_main_t *vam = &vat_main;
15955   vat_json_node_t *node = NULL;
15956   struct in_addr ip4;
15957   i32 i;
15958   i32 len = mp->mt_next_hop_n_labels;
15959
15960   if (VAT_JSON_ARRAY != vam->json_tree.type)
15961     {
15962       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15963       vat_json_init_array (&vam->json_tree);
15964     }
15965   node = vat_json_array_add (&vam->json_tree);
15966
15967   vat_json_init_object (node);
15968   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15969   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15970   vat_json_object_add_ip4 (node, "next_hop", ip4);
15971   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15972                             ntohl (mp->mt_next_hop_sw_if_index));
15973   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15974   vat_json_object_add_uint (node, "label_count", len);
15975   for (i = 0; i < len; i++)
15976     {
15977       vat_json_object_add_uint (node, "label",
15978                                 ntohl (mp->mt_next_hop_out_labels[i]));
15979     }
15980 }
15981
15982 static int
15983 api_mpls_tunnel_dump (vat_main_t * vam)
15984 {
15985   vl_api_mpls_tunnel_dump_t *mp;
15986   vl_api_control_ping_t *mp_ping;
15987   i32 index = -1;
15988   int ret;
15989
15990   /* Parse args required to build the message */
15991   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15992     {
15993       if (!unformat (vam->input, "tunnel_index %d", &index))
15994         {
15995           index = -1;
15996           break;
15997         }
15998     }
15999
16000   print (vam->ofp, "  tunnel_index %d", index);
16001
16002   M (MPLS_TUNNEL_DUMP, mp);
16003   mp->tunnel_index = htonl (index);
16004   S (mp);
16005
16006   /* Use a control ping for synchronization */
16007   M (CONTROL_PING, mp_ping);
16008   S (mp_ping);
16009
16010   W (ret);
16011   return ret;
16012 }
16013
16014 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16015 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16016
16017 static void
16018 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16019 {
16020   vat_main_t *vam = &vat_main;
16021   int count = ntohl (mp->count);
16022   vl_api_fib_path2_t *fp;
16023   int i;
16024
16025   print (vam->ofp,
16026          "table-id %d, label %u, ess_bit %u",
16027          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16028   fp = mp->path;
16029   for (i = 0; i < count; i++)
16030     {
16031       if (fp->afi == IP46_TYPE_IP6)
16032         print (vam->ofp,
16033                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16034                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16035                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16036                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16037                format_ip6_address, fp->next_hop);
16038       else if (fp->afi == IP46_TYPE_IP4)
16039         print (vam->ofp,
16040                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16041                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16042                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16043                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16044                format_ip4_address, fp->next_hop);
16045       fp++;
16046     }
16047 }
16048
16049 static void vl_api_mpls_fib_details_t_handler_json
16050   (vl_api_mpls_fib_details_t * mp)
16051 {
16052   vat_main_t *vam = &vat_main;
16053   int count = ntohl (mp->count);
16054   vat_json_node_t *node = NULL;
16055   struct in_addr ip4;
16056   struct in6_addr ip6;
16057   vl_api_fib_path2_t *fp;
16058   int i;
16059
16060   if (VAT_JSON_ARRAY != vam->json_tree.type)
16061     {
16062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16063       vat_json_init_array (&vam->json_tree);
16064     }
16065   node = vat_json_array_add (&vam->json_tree);
16066
16067   vat_json_init_object (node);
16068   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16069   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16070   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16071   vat_json_object_add_uint (node, "path_count", count);
16072   fp = mp->path;
16073   for (i = 0; i < count; i++)
16074     {
16075       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16076       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16077       vat_json_object_add_uint (node, "is_local", fp->is_local);
16078       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16079       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16080       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16081       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16082       if (fp->afi == IP46_TYPE_IP4)
16083         {
16084           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16085           vat_json_object_add_ip4 (node, "next_hop", ip4);
16086         }
16087       else if (fp->afi == IP46_TYPE_IP6)
16088         {
16089           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16090           vat_json_object_add_ip6 (node, "next_hop", ip6);
16091         }
16092     }
16093 }
16094
16095 static int
16096 api_mpls_fib_dump (vat_main_t * vam)
16097 {
16098   vl_api_mpls_fib_dump_t *mp;
16099   vl_api_control_ping_t *mp_ping;
16100   int ret;
16101
16102   M (MPLS_FIB_DUMP, mp);
16103   S (mp);
16104
16105   /* Use a control ping for synchronization */
16106   M (CONTROL_PING, mp_ping);
16107   S (mp_ping);
16108
16109   W (ret);
16110   return ret;
16111 }
16112
16113 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16114 #define vl_api_ip_fib_details_t_print vl_noop_handler
16115
16116 static void
16117 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16118 {
16119   vat_main_t *vam = &vat_main;
16120   int count = ntohl (mp->count);
16121   vl_api_fib_path_t *fp;
16122   int i;
16123
16124   print (vam->ofp,
16125          "table-id %d, prefix %U/%d",
16126          ntohl (mp->table_id), format_ip4_address, mp->address,
16127          mp->address_length);
16128   fp = mp->path;
16129   for (i = 0; i < count; i++)
16130     {
16131       if (fp->afi == IP46_TYPE_IP6)
16132         print (vam->ofp,
16133                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16134                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16135                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16136                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16137                format_ip6_address, fp->next_hop);
16138       else if (fp->afi == IP46_TYPE_IP4)
16139         print (vam->ofp,
16140                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16141                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16142                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16143                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16144                format_ip4_address, fp->next_hop);
16145       fp++;
16146     }
16147 }
16148
16149 static void vl_api_ip_fib_details_t_handler_json
16150   (vl_api_ip_fib_details_t * mp)
16151 {
16152   vat_main_t *vam = &vat_main;
16153   int count = ntohl (mp->count);
16154   vat_json_node_t *node = NULL;
16155   struct in_addr ip4;
16156   struct in6_addr ip6;
16157   vl_api_fib_path_t *fp;
16158   int i;
16159
16160   if (VAT_JSON_ARRAY != vam->json_tree.type)
16161     {
16162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16163       vat_json_init_array (&vam->json_tree);
16164     }
16165   node = vat_json_array_add (&vam->json_tree);
16166
16167   vat_json_init_object (node);
16168   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16169   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16170   vat_json_object_add_ip4 (node, "prefix", ip4);
16171   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16172   vat_json_object_add_uint (node, "path_count", count);
16173   fp = mp->path;
16174   for (i = 0; i < count; i++)
16175     {
16176       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16177       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16178       vat_json_object_add_uint (node, "is_local", fp->is_local);
16179       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16180       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16181       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16182       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16183       if (fp->afi == IP46_TYPE_IP4)
16184         {
16185           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16186           vat_json_object_add_ip4 (node, "next_hop", ip4);
16187         }
16188       else if (fp->afi == IP46_TYPE_IP6)
16189         {
16190           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16191           vat_json_object_add_ip6 (node, "next_hop", ip6);
16192         }
16193     }
16194 }
16195
16196 static int
16197 api_ip_fib_dump (vat_main_t * vam)
16198 {
16199   vl_api_ip_fib_dump_t *mp;
16200   vl_api_control_ping_t *mp_ping;
16201   int ret;
16202
16203   M (IP_FIB_DUMP, mp);
16204   S (mp);
16205
16206   /* Use a control ping for synchronization */
16207   M (CONTROL_PING, mp_ping);
16208   S (mp_ping);
16209
16210   W (ret);
16211   return ret;
16212 }
16213
16214 static int
16215 api_ip_mfib_dump (vat_main_t * vam)
16216 {
16217   vl_api_ip_mfib_dump_t *mp;
16218   vl_api_control_ping_t *mp_ping;
16219   int ret;
16220
16221   M (IP_MFIB_DUMP, mp);
16222   S (mp);
16223
16224   /* Use a control ping for synchronization */
16225   M (CONTROL_PING, mp_ping);
16226   S (mp_ping);
16227
16228   W (ret);
16229   return ret;
16230 }
16231
16232 static void vl_api_ip_neighbor_details_t_handler
16233   (vl_api_ip_neighbor_details_t * mp)
16234 {
16235   vat_main_t *vam = &vat_main;
16236
16237   print (vam->ofp, "%c %U %U",
16238          (mp->is_static) ? 'S' : 'D',
16239          format_ethernet_address, &mp->mac_address,
16240          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16241          &mp->ip_address);
16242 }
16243
16244 static void vl_api_ip_neighbor_details_t_handler_json
16245   (vl_api_ip_neighbor_details_t * mp)
16246 {
16247
16248   vat_main_t *vam = &vat_main;
16249   vat_json_node_t *node;
16250   struct in_addr ip4;
16251   struct in6_addr ip6;
16252
16253   if (VAT_JSON_ARRAY != vam->json_tree.type)
16254     {
16255       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16256       vat_json_init_array (&vam->json_tree);
16257     }
16258   node = vat_json_array_add (&vam->json_tree);
16259
16260   vat_json_init_object (node);
16261   vat_json_object_add_string_copy (node, "flag",
16262                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16263                                    "dynamic");
16264
16265   vat_json_object_add_string_copy (node, "link_layer",
16266                                    format (0, "%U", format_ethernet_address,
16267                                            &mp->mac_address));
16268
16269   if (mp->is_ipv6)
16270     {
16271       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16272       vat_json_object_add_ip6 (node, "ip_address", ip6);
16273     }
16274   else
16275     {
16276       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16277       vat_json_object_add_ip4 (node, "ip_address", ip4);
16278     }
16279 }
16280
16281 static int
16282 api_ip_neighbor_dump (vat_main_t * vam)
16283 {
16284   unformat_input_t *i = vam->input;
16285   vl_api_ip_neighbor_dump_t *mp;
16286   vl_api_control_ping_t *mp_ping;
16287   u8 is_ipv6 = 0;
16288   u32 sw_if_index = ~0;
16289   int ret;
16290
16291   /* Parse args required to build the message */
16292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16293     {
16294       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16295         ;
16296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16297         ;
16298       else if (unformat (i, "ip6"))
16299         is_ipv6 = 1;
16300       else
16301         break;
16302     }
16303
16304   if (sw_if_index == ~0)
16305     {
16306       errmsg ("missing interface name or sw_if_index");
16307       return -99;
16308     }
16309
16310   M (IP_NEIGHBOR_DUMP, mp);
16311   mp->is_ipv6 = (u8) is_ipv6;
16312   mp->sw_if_index = ntohl (sw_if_index);
16313   S (mp);
16314
16315   /* Use a control ping for synchronization */
16316   M (CONTROL_PING, mp_ping);
16317   S (mp_ping);
16318
16319   W (ret);
16320   return ret;
16321 }
16322
16323 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16324 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16325
16326 static void
16327 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16328 {
16329   vat_main_t *vam = &vat_main;
16330   int count = ntohl (mp->count);
16331   vl_api_fib_path_t *fp;
16332   int i;
16333
16334   print (vam->ofp,
16335          "table-id %d, prefix %U/%d",
16336          ntohl (mp->table_id), format_ip6_address, mp->address,
16337          mp->address_length);
16338   fp = mp->path;
16339   for (i = 0; i < count; i++)
16340     {
16341       if (fp->afi == IP46_TYPE_IP6)
16342         print (vam->ofp,
16343                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16344                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16345                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16346                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16347                format_ip6_address, fp->next_hop);
16348       else if (fp->afi == IP46_TYPE_IP4)
16349         print (vam->ofp,
16350                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16351                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16352                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16353                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16354                format_ip4_address, fp->next_hop);
16355       fp++;
16356     }
16357 }
16358
16359 static void vl_api_ip6_fib_details_t_handler_json
16360   (vl_api_ip6_fib_details_t * mp)
16361 {
16362   vat_main_t *vam = &vat_main;
16363   int count = ntohl (mp->count);
16364   vat_json_node_t *node = NULL;
16365   struct in_addr ip4;
16366   struct in6_addr ip6;
16367   vl_api_fib_path_t *fp;
16368   int i;
16369
16370   if (VAT_JSON_ARRAY != vam->json_tree.type)
16371     {
16372       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16373       vat_json_init_array (&vam->json_tree);
16374     }
16375   node = vat_json_array_add (&vam->json_tree);
16376
16377   vat_json_init_object (node);
16378   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16379   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16380   vat_json_object_add_ip6 (node, "prefix", ip6);
16381   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16382   vat_json_object_add_uint (node, "path_count", count);
16383   fp = mp->path;
16384   for (i = 0; i < count; i++)
16385     {
16386       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16387       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16388       vat_json_object_add_uint (node, "is_local", fp->is_local);
16389       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16390       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16391       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16392       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16393       if (fp->afi == IP46_TYPE_IP4)
16394         {
16395           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16396           vat_json_object_add_ip4 (node, "next_hop", ip4);
16397         }
16398       else if (fp->afi == IP46_TYPE_IP6)
16399         {
16400           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16401           vat_json_object_add_ip6 (node, "next_hop", ip6);
16402         }
16403     }
16404 }
16405
16406 static int
16407 api_ip6_fib_dump (vat_main_t * vam)
16408 {
16409   vl_api_ip6_fib_dump_t *mp;
16410   vl_api_control_ping_t *mp_ping;
16411   int ret;
16412
16413   M (IP6_FIB_DUMP, mp);
16414   S (mp);
16415
16416   /* Use a control ping for synchronization */
16417   M (CONTROL_PING, mp_ping);
16418   S (mp_ping);
16419
16420   W (ret);
16421   return ret;
16422 }
16423
16424 static int
16425 api_ip6_mfib_dump (vat_main_t * vam)
16426 {
16427   vl_api_ip6_mfib_dump_t *mp;
16428   vl_api_control_ping_t *mp_ping;
16429   int ret;
16430
16431   M (IP6_MFIB_DUMP, mp);
16432   S (mp);
16433
16434   /* Use a control ping for synchronization */
16435   M (CONTROL_PING, mp_ping);
16436   S (mp_ping);
16437
16438   W (ret);
16439   return ret;
16440 }
16441
16442 int
16443 api_classify_table_ids (vat_main_t * vam)
16444 {
16445   vl_api_classify_table_ids_t *mp;
16446   int ret;
16447
16448   /* Construct the API message */
16449   M (CLASSIFY_TABLE_IDS, mp);
16450   mp->context = 0;
16451
16452   S (mp);
16453   W (ret);
16454   return ret;
16455 }
16456
16457 int
16458 api_classify_table_by_interface (vat_main_t * vam)
16459 {
16460   unformat_input_t *input = vam->input;
16461   vl_api_classify_table_by_interface_t *mp;
16462
16463   u32 sw_if_index = ~0;
16464   int ret;
16465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16466     {
16467       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16468         ;
16469       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16470         ;
16471       else
16472         break;
16473     }
16474   if (sw_if_index == ~0)
16475     {
16476       errmsg ("missing interface name or sw_if_index");
16477       return -99;
16478     }
16479
16480   /* Construct the API message */
16481   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16482   mp->context = 0;
16483   mp->sw_if_index = ntohl (sw_if_index);
16484
16485   S (mp);
16486   W (ret);
16487   return ret;
16488 }
16489
16490 int
16491 api_classify_table_info (vat_main_t * vam)
16492 {
16493   unformat_input_t *input = vam->input;
16494   vl_api_classify_table_info_t *mp;
16495
16496   u32 table_id = ~0;
16497   int ret;
16498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16499     {
16500       if (unformat (input, "table_id %d", &table_id))
16501         ;
16502       else
16503         break;
16504     }
16505   if (table_id == ~0)
16506     {
16507       errmsg ("missing table id");
16508       return -99;
16509     }
16510
16511   /* Construct the API message */
16512   M (CLASSIFY_TABLE_INFO, mp);
16513   mp->context = 0;
16514   mp->table_id = ntohl (table_id);
16515
16516   S (mp);
16517   W (ret);
16518   return ret;
16519 }
16520
16521 int
16522 api_classify_session_dump (vat_main_t * vam)
16523 {
16524   unformat_input_t *input = vam->input;
16525   vl_api_classify_session_dump_t *mp;
16526   vl_api_control_ping_t *mp_ping;
16527
16528   u32 table_id = ~0;
16529   int ret;
16530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16531     {
16532       if (unformat (input, "table_id %d", &table_id))
16533         ;
16534       else
16535         break;
16536     }
16537   if (table_id == ~0)
16538     {
16539       errmsg ("missing table id");
16540       return -99;
16541     }
16542
16543   /* Construct the API message */
16544   M (CLASSIFY_SESSION_DUMP, mp);
16545   mp->context = 0;
16546   mp->table_id = ntohl (table_id);
16547   S (mp);
16548
16549   /* Use a control ping for synchronization */
16550   M (CONTROL_PING, mp_ping);
16551   S (mp_ping);
16552
16553   W (ret);
16554   return ret;
16555 }
16556
16557 static void
16558 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16559 {
16560   vat_main_t *vam = &vat_main;
16561
16562   print (vam->ofp, "collector_address %U, collector_port %d, "
16563          "src_address %U, vrf_id %d, path_mtu %u, "
16564          "template_interval %u, udp_checksum %d",
16565          format_ip4_address, mp->collector_address,
16566          ntohs (mp->collector_port),
16567          format_ip4_address, mp->src_address,
16568          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16569          ntohl (mp->template_interval), mp->udp_checksum);
16570
16571   vam->retval = 0;
16572   vam->result_ready = 1;
16573 }
16574
16575 static void
16576   vl_api_ipfix_exporter_details_t_handler_json
16577   (vl_api_ipfix_exporter_details_t * mp)
16578 {
16579   vat_main_t *vam = &vat_main;
16580   vat_json_node_t node;
16581   struct in_addr collector_address;
16582   struct in_addr src_address;
16583
16584   vat_json_init_object (&node);
16585   clib_memcpy (&collector_address, &mp->collector_address,
16586                sizeof (collector_address));
16587   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16588   vat_json_object_add_uint (&node, "collector_port",
16589                             ntohs (mp->collector_port));
16590   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16591   vat_json_object_add_ip4 (&node, "src_address", src_address);
16592   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16593   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16594   vat_json_object_add_uint (&node, "template_interval",
16595                             ntohl (mp->template_interval));
16596   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16597
16598   vat_json_print (vam->ofp, &node);
16599   vat_json_free (&node);
16600   vam->retval = 0;
16601   vam->result_ready = 1;
16602 }
16603
16604 int
16605 api_ipfix_exporter_dump (vat_main_t * vam)
16606 {
16607   vl_api_ipfix_exporter_dump_t *mp;
16608   int ret;
16609
16610   /* Construct the API message */
16611   M (IPFIX_EXPORTER_DUMP, mp);
16612   mp->context = 0;
16613
16614   S (mp);
16615   W (ret);
16616   return ret;
16617 }
16618
16619 static int
16620 api_ipfix_classify_stream_dump (vat_main_t * vam)
16621 {
16622   vl_api_ipfix_classify_stream_dump_t *mp;
16623   int ret;
16624
16625   /* Construct the API message */
16626   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16627   mp->context = 0;
16628
16629   S (mp);
16630   W (ret);
16631   return ret;
16632   /* NOTREACHED */
16633   return 0;
16634 }
16635
16636 static void
16637   vl_api_ipfix_classify_stream_details_t_handler
16638   (vl_api_ipfix_classify_stream_details_t * mp)
16639 {
16640   vat_main_t *vam = &vat_main;
16641   print (vam->ofp, "domain_id %d, src_port %d",
16642          ntohl (mp->domain_id), ntohs (mp->src_port));
16643   vam->retval = 0;
16644   vam->result_ready = 1;
16645 }
16646
16647 static void
16648   vl_api_ipfix_classify_stream_details_t_handler_json
16649   (vl_api_ipfix_classify_stream_details_t * mp)
16650 {
16651   vat_main_t *vam = &vat_main;
16652   vat_json_node_t node;
16653
16654   vat_json_init_object (&node);
16655   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16656   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16657
16658   vat_json_print (vam->ofp, &node);
16659   vat_json_free (&node);
16660   vam->retval = 0;
16661   vam->result_ready = 1;
16662 }
16663
16664 static int
16665 api_ipfix_classify_table_dump (vat_main_t * vam)
16666 {
16667   vl_api_ipfix_classify_table_dump_t *mp;
16668   vl_api_control_ping_t *mp_ping;
16669   int ret;
16670
16671   if (!vam->json_output)
16672     {
16673       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16674              "transport_protocol");
16675     }
16676
16677   /* Construct the API message */
16678   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16679
16680   /* send it... */
16681   S (mp);
16682
16683   /* Use a control ping for synchronization */
16684   M (CONTROL_PING, mp_ping);
16685   S (mp_ping);
16686
16687   W (ret);
16688   return ret;
16689 }
16690
16691 static void
16692   vl_api_ipfix_classify_table_details_t_handler
16693   (vl_api_ipfix_classify_table_details_t * mp)
16694 {
16695   vat_main_t *vam = &vat_main;
16696   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16697          mp->transport_protocol);
16698 }
16699
16700 static void
16701   vl_api_ipfix_classify_table_details_t_handler_json
16702   (vl_api_ipfix_classify_table_details_t * mp)
16703 {
16704   vat_json_node_t *node = NULL;
16705   vat_main_t *vam = &vat_main;
16706
16707   if (VAT_JSON_ARRAY != vam->json_tree.type)
16708     {
16709       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16710       vat_json_init_array (&vam->json_tree);
16711     }
16712
16713   node = vat_json_array_add (&vam->json_tree);
16714   vat_json_init_object (node);
16715
16716   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16717   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16718   vat_json_object_add_uint (node, "transport_protocol",
16719                             mp->transport_protocol);
16720 }
16721
16722 static int
16723 api_sw_interface_span_enable_disable (vat_main_t * vam)
16724 {
16725   unformat_input_t *i = vam->input;
16726   vl_api_sw_interface_span_enable_disable_t *mp;
16727   u32 src_sw_if_index = ~0;
16728   u32 dst_sw_if_index = ~0;
16729   u8 state = 3;
16730   int ret;
16731
16732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16733     {
16734       if (unformat
16735           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16736         ;
16737       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16738         ;
16739       else
16740         if (unformat
16741             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16742         ;
16743       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16744         ;
16745       else if (unformat (i, "disable"))
16746         state = 0;
16747       else if (unformat (i, "rx"))
16748         state = 1;
16749       else if (unformat (i, "tx"))
16750         state = 2;
16751       else if (unformat (i, "both"))
16752         state = 3;
16753       else
16754         break;
16755     }
16756
16757   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16758
16759   mp->sw_if_index_from = htonl (src_sw_if_index);
16760   mp->sw_if_index_to = htonl (dst_sw_if_index);
16761   mp->state = state;
16762
16763   S (mp);
16764   W (ret);
16765   return ret;
16766 }
16767
16768 static void
16769 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16770                                             * mp)
16771 {
16772   vat_main_t *vam = &vat_main;
16773   u8 *sw_if_from_name = 0;
16774   u8 *sw_if_to_name = 0;
16775   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16776   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16777   char *states[] = { "none", "rx", "tx", "both" };
16778   hash_pair_t *p;
16779
16780   /* *INDENT-OFF* */
16781   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16782   ({
16783     if ((u32) p->value[0] == sw_if_index_from)
16784       {
16785         sw_if_from_name = (u8 *)(p->key);
16786         if (sw_if_to_name)
16787           break;
16788       }
16789     if ((u32) p->value[0] == sw_if_index_to)
16790       {
16791         sw_if_to_name = (u8 *)(p->key);
16792         if (sw_if_from_name)
16793           break;
16794       }
16795   }));
16796   /* *INDENT-ON* */
16797   print (vam->ofp, "%20s => %20s (%s)",
16798          sw_if_from_name, sw_if_to_name, states[mp->state]);
16799 }
16800
16801 static void
16802   vl_api_sw_interface_span_details_t_handler_json
16803   (vl_api_sw_interface_span_details_t * mp)
16804 {
16805   vat_main_t *vam = &vat_main;
16806   vat_json_node_t *node = NULL;
16807   u8 *sw_if_from_name = 0;
16808   u8 *sw_if_to_name = 0;
16809   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16810   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16811   hash_pair_t *p;
16812
16813   /* *INDENT-OFF* */
16814   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16815   ({
16816     if ((u32) p->value[0] == sw_if_index_from)
16817       {
16818         sw_if_from_name = (u8 *)(p->key);
16819         if (sw_if_to_name)
16820           break;
16821       }
16822     if ((u32) p->value[0] == sw_if_index_to)
16823       {
16824         sw_if_to_name = (u8 *)(p->key);
16825         if (sw_if_from_name)
16826           break;
16827       }
16828   }));
16829   /* *INDENT-ON* */
16830
16831   if (VAT_JSON_ARRAY != vam->json_tree.type)
16832     {
16833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16834       vat_json_init_array (&vam->json_tree);
16835     }
16836   node = vat_json_array_add (&vam->json_tree);
16837
16838   vat_json_init_object (node);
16839   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16840   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16841   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16842   if (0 != sw_if_to_name)
16843     {
16844       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16845     }
16846   vat_json_object_add_uint (node, "state", mp->state);
16847 }
16848
16849 static int
16850 api_sw_interface_span_dump (vat_main_t * vam)
16851 {
16852   vl_api_sw_interface_span_dump_t *mp;
16853   vl_api_control_ping_t *mp_ping;
16854   int ret;
16855
16856   M (SW_INTERFACE_SPAN_DUMP, mp);
16857   S (mp);
16858
16859   /* Use a control ping for synchronization */
16860   M (CONTROL_PING, mp_ping);
16861   S (mp_ping);
16862
16863   W (ret);
16864   return ret;
16865 }
16866
16867 int
16868 api_pg_create_interface (vat_main_t * vam)
16869 {
16870   unformat_input_t *input = vam->input;
16871   vl_api_pg_create_interface_t *mp;
16872
16873   u32 if_id = ~0;
16874   int ret;
16875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16876     {
16877       if (unformat (input, "if_id %d", &if_id))
16878         ;
16879       else
16880         break;
16881     }
16882   if (if_id == ~0)
16883     {
16884       errmsg ("missing pg interface index");
16885       return -99;
16886     }
16887
16888   /* Construct the API message */
16889   M (PG_CREATE_INTERFACE, mp);
16890   mp->context = 0;
16891   mp->interface_id = ntohl (if_id);
16892
16893   S (mp);
16894   W (ret);
16895   return ret;
16896 }
16897
16898 int
16899 api_pg_capture (vat_main_t * vam)
16900 {
16901   unformat_input_t *input = vam->input;
16902   vl_api_pg_capture_t *mp;
16903
16904   u32 if_id = ~0;
16905   u8 enable = 1;
16906   u32 count = 1;
16907   u8 pcap_file_set = 0;
16908   u8 *pcap_file = 0;
16909   int ret;
16910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16911     {
16912       if (unformat (input, "if_id %d", &if_id))
16913         ;
16914       else if (unformat (input, "pcap %s", &pcap_file))
16915         pcap_file_set = 1;
16916       else if (unformat (input, "count %d", &count))
16917         ;
16918       else if (unformat (input, "disable"))
16919         enable = 0;
16920       else
16921         break;
16922     }
16923   if (if_id == ~0)
16924     {
16925       errmsg ("missing pg interface index");
16926       return -99;
16927     }
16928   if (pcap_file_set > 0)
16929     {
16930       if (vec_len (pcap_file) > 255)
16931         {
16932           errmsg ("pcap file name is too long");
16933           return -99;
16934         }
16935     }
16936
16937   u32 name_len = vec_len (pcap_file);
16938   /* Construct the API message */
16939   M (PG_CAPTURE, mp);
16940   mp->context = 0;
16941   mp->interface_id = ntohl (if_id);
16942   mp->is_enabled = enable;
16943   mp->count = ntohl (count);
16944   mp->pcap_name_length = ntohl (name_len);
16945   if (pcap_file_set != 0)
16946     {
16947       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16948     }
16949   vec_free (pcap_file);
16950
16951   S (mp);
16952   W (ret);
16953   return ret;
16954 }
16955
16956 int
16957 api_pg_enable_disable (vat_main_t * vam)
16958 {
16959   unformat_input_t *input = vam->input;
16960   vl_api_pg_enable_disable_t *mp;
16961
16962   u8 enable = 1;
16963   u8 stream_name_set = 0;
16964   u8 *stream_name = 0;
16965   int ret;
16966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16967     {
16968       if (unformat (input, "stream %s", &stream_name))
16969         stream_name_set = 1;
16970       else if (unformat (input, "disable"))
16971         enable = 0;
16972       else
16973         break;
16974     }
16975
16976   if (stream_name_set > 0)
16977     {
16978       if (vec_len (stream_name) > 255)
16979         {
16980           errmsg ("stream name too long");
16981           return -99;
16982         }
16983     }
16984
16985   u32 name_len = vec_len (stream_name);
16986   /* Construct the API message */
16987   M (PG_ENABLE_DISABLE, mp);
16988   mp->context = 0;
16989   mp->is_enabled = enable;
16990   if (stream_name_set != 0)
16991     {
16992       mp->stream_name_length = ntohl (name_len);
16993       clib_memcpy (mp->stream_name, stream_name, name_len);
16994     }
16995   vec_free (stream_name);
16996
16997   S (mp);
16998   W (ret);
16999   return ret;
17000 }
17001
17002 int
17003 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17004 {
17005   unformat_input_t *input = vam->input;
17006   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17007
17008   u16 *low_ports = 0;
17009   u16 *high_ports = 0;
17010   u16 this_low;
17011   u16 this_hi;
17012   ip4_address_t ip4_addr;
17013   ip6_address_t ip6_addr;
17014   u32 length;
17015   u32 tmp, tmp2;
17016   u8 prefix_set = 0;
17017   u32 vrf_id = ~0;
17018   u8 is_add = 1;
17019   u8 is_ipv6 = 0;
17020   int ret;
17021
17022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17023     {
17024       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17025         {
17026           prefix_set = 1;
17027         }
17028       else
17029         if (unformat
17030             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17031         {
17032           prefix_set = 1;
17033           is_ipv6 = 1;
17034         }
17035       else if (unformat (input, "vrf %d", &vrf_id))
17036         ;
17037       else if (unformat (input, "del"))
17038         is_add = 0;
17039       else if (unformat (input, "port %d", &tmp))
17040         {
17041           if (tmp == 0 || tmp > 65535)
17042             {
17043               errmsg ("port %d out of range", tmp);
17044               return -99;
17045             }
17046           this_low = tmp;
17047           this_hi = this_low + 1;
17048           vec_add1 (low_ports, this_low);
17049           vec_add1 (high_ports, this_hi);
17050         }
17051       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17052         {
17053           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17054             {
17055               errmsg ("incorrect range parameters");
17056               return -99;
17057             }
17058           this_low = tmp;
17059           /* Note: in debug CLI +1 is added to high before
17060              passing to real fn that does "the work"
17061              (ip_source_and_port_range_check_add_del).
17062              This fn is a wrapper around the binary API fn a
17063              control plane will call, which expects this increment
17064              to have occurred. Hence letting the binary API control
17065              plane fn do the increment for consistency between VAT
17066              and other control planes.
17067            */
17068           this_hi = tmp2;
17069           vec_add1 (low_ports, this_low);
17070           vec_add1 (high_ports, this_hi);
17071         }
17072       else
17073         break;
17074     }
17075
17076   if (prefix_set == 0)
17077     {
17078       errmsg ("<address>/<mask> not specified");
17079       return -99;
17080     }
17081
17082   if (vrf_id == ~0)
17083     {
17084       errmsg ("VRF ID required, not specified");
17085       return -99;
17086     }
17087
17088   if (vrf_id == 0)
17089     {
17090       errmsg
17091         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17092       return -99;
17093     }
17094
17095   if (vec_len (low_ports) == 0)
17096     {
17097       errmsg ("At least one port or port range required");
17098       return -99;
17099     }
17100
17101   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17102
17103   mp->is_add = is_add;
17104
17105   if (is_ipv6)
17106     {
17107       mp->is_ipv6 = 1;
17108       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17109     }
17110   else
17111     {
17112       mp->is_ipv6 = 0;
17113       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17114     }
17115
17116   mp->mask_length = length;
17117   mp->number_of_ranges = vec_len (low_ports);
17118
17119   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17120   vec_free (low_ports);
17121
17122   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17123   vec_free (high_ports);
17124
17125   mp->vrf_id = ntohl (vrf_id);
17126
17127   S (mp);
17128   W (ret);
17129   return ret;
17130 }
17131
17132 int
17133 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17134 {
17135   unformat_input_t *input = vam->input;
17136   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17137   u32 sw_if_index = ~0;
17138   int vrf_set = 0;
17139   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17140   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17141   u8 is_add = 1;
17142   int ret;
17143
17144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17145     {
17146       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17147         ;
17148       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17149         ;
17150       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17151         vrf_set = 1;
17152       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17153         vrf_set = 1;
17154       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17155         vrf_set = 1;
17156       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17157         vrf_set = 1;
17158       else if (unformat (input, "del"))
17159         is_add = 0;
17160       else
17161         break;
17162     }
17163
17164   if (sw_if_index == ~0)
17165     {
17166       errmsg ("Interface required but not specified");
17167       return -99;
17168     }
17169
17170   if (vrf_set == 0)
17171     {
17172       errmsg ("VRF ID required but not specified");
17173       return -99;
17174     }
17175
17176   if (tcp_out_vrf_id == 0
17177       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17178     {
17179       errmsg
17180         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17181       return -99;
17182     }
17183
17184   /* Construct the API message */
17185   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17186
17187   mp->sw_if_index = ntohl (sw_if_index);
17188   mp->is_add = is_add;
17189   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17190   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17191   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17192   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17193
17194   /* send it... */
17195   S (mp);
17196
17197   /* Wait for a reply... */
17198   W (ret);
17199   return ret;
17200 }
17201
17202 static int
17203 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17204 {
17205   unformat_input_t *i = vam->input;
17206   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17207   u32 local_sa_id = 0;
17208   u32 remote_sa_id = 0;
17209   ip4_address_t src_address;
17210   ip4_address_t dst_address;
17211   u8 is_add = 1;
17212   int ret;
17213
17214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17215     {
17216       if (unformat (i, "local_sa %d", &local_sa_id))
17217         ;
17218       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17219         ;
17220       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17221         ;
17222       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17223         ;
17224       else if (unformat (i, "del"))
17225         is_add = 0;
17226       else
17227         {
17228           clib_warning ("parse error '%U'", format_unformat_error, i);
17229           return -99;
17230         }
17231     }
17232
17233   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17234
17235   mp->local_sa_id = ntohl (local_sa_id);
17236   mp->remote_sa_id = ntohl (remote_sa_id);
17237   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17238   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17239   mp->is_add = is_add;
17240
17241   S (mp);
17242   W (ret);
17243   return ret;
17244 }
17245
17246 static int
17247 api_punt (vat_main_t * vam)
17248 {
17249   unformat_input_t *i = vam->input;
17250   vl_api_punt_t *mp;
17251   u32 ipv = ~0;
17252   u32 protocol = ~0;
17253   u32 port = ~0;
17254   int is_add = 1;
17255   int ret;
17256
17257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17258     {
17259       if (unformat (i, "ip %d", &ipv))
17260         ;
17261       else if (unformat (i, "protocol %d", &protocol))
17262         ;
17263       else if (unformat (i, "port %d", &port))
17264         ;
17265       else if (unformat (i, "del"))
17266         is_add = 0;
17267       else
17268         {
17269           clib_warning ("parse error '%U'", format_unformat_error, i);
17270           return -99;
17271         }
17272     }
17273
17274   M (PUNT, mp);
17275
17276   mp->is_add = (u8) is_add;
17277   mp->ipv = (u8) ipv;
17278   mp->l4_protocol = (u8) protocol;
17279   mp->l4_port = htons ((u16) port);
17280
17281   S (mp);
17282   W (ret);
17283   return ret;
17284 }
17285
17286 static void vl_api_ipsec_gre_tunnel_details_t_handler
17287   (vl_api_ipsec_gre_tunnel_details_t * mp)
17288 {
17289   vat_main_t *vam = &vat_main;
17290
17291   print (vam->ofp, "%11d%15U%15U%14d%14d",
17292          ntohl (mp->sw_if_index),
17293          format_ip4_address, &mp->src_address,
17294          format_ip4_address, &mp->dst_address,
17295          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17296 }
17297
17298 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17299   (vl_api_ipsec_gre_tunnel_details_t * mp)
17300 {
17301   vat_main_t *vam = &vat_main;
17302   vat_json_node_t *node = NULL;
17303   struct in_addr ip4;
17304
17305   if (VAT_JSON_ARRAY != vam->json_tree.type)
17306     {
17307       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17308       vat_json_init_array (&vam->json_tree);
17309     }
17310   node = vat_json_array_add (&vam->json_tree);
17311
17312   vat_json_init_object (node);
17313   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17314   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17315   vat_json_object_add_ip4 (node, "src_address", ip4);
17316   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17317   vat_json_object_add_ip4 (node, "dst_address", ip4);
17318   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17319   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17320 }
17321
17322 static int
17323 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17324 {
17325   unformat_input_t *i = vam->input;
17326   vl_api_ipsec_gre_tunnel_dump_t *mp;
17327   vl_api_control_ping_t *mp_ping;
17328   u32 sw_if_index;
17329   u8 sw_if_index_set = 0;
17330   int ret;
17331
17332   /* Parse args required to build the message */
17333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17334     {
17335       if (unformat (i, "sw_if_index %d", &sw_if_index))
17336         sw_if_index_set = 1;
17337       else
17338         break;
17339     }
17340
17341   if (sw_if_index_set == 0)
17342     {
17343       sw_if_index = ~0;
17344     }
17345
17346   if (!vam->json_output)
17347     {
17348       print (vam->ofp, "%11s%15s%15s%14s%14s",
17349              "sw_if_index", "src_address", "dst_address",
17350              "local_sa_id", "remote_sa_id");
17351     }
17352
17353   /* Get list of gre-tunnel interfaces */
17354   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17355
17356   mp->sw_if_index = htonl (sw_if_index);
17357
17358   S (mp);
17359
17360   /* Use a control ping for synchronization */
17361   M (CONTROL_PING, mp_ping);
17362   S (mp_ping);
17363
17364   W (ret);
17365   return ret;
17366 }
17367
17368 static int
17369 api_delete_subif (vat_main_t * vam)
17370 {
17371   unformat_input_t *i = vam->input;
17372   vl_api_delete_subif_t *mp;
17373   u32 sw_if_index = ~0;
17374   int ret;
17375
17376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17377     {
17378       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17379         ;
17380       if (unformat (i, "sw_if_index %d", &sw_if_index))
17381         ;
17382       else
17383         break;
17384     }
17385
17386   if (sw_if_index == ~0)
17387     {
17388       errmsg ("missing sw_if_index");
17389       return -99;
17390     }
17391
17392   /* Construct the API message */
17393   M (DELETE_SUBIF, mp);
17394   mp->sw_if_index = ntohl (sw_if_index);
17395
17396   S (mp);
17397   W (ret);
17398   return ret;
17399 }
17400
17401 #define foreach_pbb_vtr_op      \
17402 _("disable",  L2_VTR_DISABLED)  \
17403 _("pop",  L2_VTR_POP_2)         \
17404 _("push",  L2_VTR_PUSH_2)
17405
17406 static int
17407 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17408 {
17409   unformat_input_t *i = vam->input;
17410   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17411   u32 sw_if_index = ~0, vtr_op = ~0;
17412   u16 outer_tag = ~0;
17413   u8 dmac[6], smac[6];
17414   u8 dmac_set = 0, smac_set = 0;
17415   u16 vlanid = 0;
17416   u32 sid = ~0;
17417   u32 tmp;
17418   int ret;
17419
17420   /* Shut up coverity */
17421   memset (dmac, 0, sizeof (dmac));
17422   memset (smac, 0, sizeof (smac));
17423
17424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17425     {
17426       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17427         ;
17428       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17429         ;
17430       else if (unformat (i, "vtr_op %d", &vtr_op))
17431         ;
17432 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17433       foreach_pbb_vtr_op
17434 #undef _
17435         else if (unformat (i, "translate_pbb_stag"))
17436         {
17437           if (unformat (i, "%d", &tmp))
17438             {
17439               vtr_op = L2_VTR_TRANSLATE_2_1;
17440               outer_tag = tmp;
17441             }
17442           else
17443             {
17444               errmsg
17445                 ("translate_pbb_stag operation requires outer tag definition");
17446               return -99;
17447             }
17448         }
17449       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17450         dmac_set++;
17451       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17452         smac_set++;
17453       else if (unformat (i, "sid %d", &sid))
17454         ;
17455       else if (unformat (i, "vlanid %d", &tmp))
17456         vlanid = tmp;
17457       else
17458         {
17459           clib_warning ("parse error '%U'", format_unformat_error, i);
17460           return -99;
17461         }
17462     }
17463
17464   if ((sw_if_index == ~0) || (vtr_op == ~0))
17465     {
17466       errmsg ("missing sw_if_index or vtr operation");
17467       return -99;
17468     }
17469   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17470       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17471     {
17472       errmsg
17473         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17474       return -99;
17475     }
17476
17477   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17478   mp->sw_if_index = ntohl (sw_if_index);
17479   mp->vtr_op = ntohl (vtr_op);
17480   mp->outer_tag = ntohs (outer_tag);
17481   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17482   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17483   mp->b_vlanid = ntohs (vlanid);
17484   mp->i_sid = ntohl (sid);
17485
17486   S (mp);
17487   W (ret);
17488   return ret;
17489 }
17490
17491 static int
17492 api_flow_classify_set_interface (vat_main_t * vam)
17493 {
17494   unformat_input_t *i = vam->input;
17495   vl_api_flow_classify_set_interface_t *mp;
17496   u32 sw_if_index;
17497   int sw_if_index_set;
17498   u32 ip4_table_index = ~0;
17499   u32 ip6_table_index = ~0;
17500   u8 is_add = 1;
17501   int ret;
17502
17503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17504     {
17505       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17506         sw_if_index_set = 1;
17507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17508         sw_if_index_set = 1;
17509       else if (unformat (i, "del"))
17510         is_add = 0;
17511       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17512         ;
17513       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17514         ;
17515       else
17516         {
17517           clib_warning ("parse error '%U'", format_unformat_error, i);
17518           return -99;
17519         }
17520     }
17521
17522   if (sw_if_index_set == 0)
17523     {
17524       errmsg ("missing interface name or sw_if_index");
17525       return -99;
17526     }
17527
17528   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17529
17530   mp->sw_if_index = ntohl (sw_if_index);
17531   mp->ip4_table_index = ntohl (ip4_table_index);
17532   mp->ip6_table_index = ntohl (ip6_table_index);
17533   mp->is_add = is_add;
17534
17535   S (mp);
17536   W (ret);
17537   return ret;
17538 }
17539
17540 static int
17541 api_flow_classify_dump (vat_main_t * vam)
17542 {
17543   unformat_input_t *i = vam->input;
17544   vl_api_flow_classify_dump_t *mp;
17545   vl_api_control_ping_t *mp_ping;
17546   u8 type = FLOW_CLASSIFY_N_TABLES;
17547   int ret;
17548
17549   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17550     ;
17551   else
17552     {
17553       errmsg ("classify table type must be specified");
17554       return -99;
17555     }
17556
17557   if (!vam->json_output)
17558     {
17559       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17560     }
17561
17562   M (FLOW_CLASSIFY_DUMP, mp);
17563   mp->type = type;
17564   /* send it... */
17565   S (mp);
17566
17567   /* Use a control ping for synchronization */
17568   M (CONTROL_PING, mp_ping);
17569   S (mp_ping);
17570
17571   /* Wait for a reply... */
17572   W (ret);
17573   return ret;
17574 }
17575
17576 static int
17577 api_feature_enable_disable (vat_main_t * vam)
17578 {
17579   unformat_input_t *i = vam->input;
17580   vl_api_feature_enable_disable_t *mp;
17581   u8 *arc_name = 0;
17582   u8 *feature_name = 0;
17583   u32 sw_if_index = ~0;
17584   u8 enable = 1;
17585   int ret;
17586
17587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17588     {
17589       if (unformat (i, "arc_name %s", &arc_name))
17590         ;
17591       else if (unformat (i, "feature_name %s", &feature_name))
17592         ;
17593       else
17594         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17595         ;
17596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17597         ;
17598       else if (unformat (i, "disable"))
17599         enable = 0;
17600       else
17601         break;
17602     }
17603
17604   if (arc_name == 0)
17605     {
17606       errmsg ("missing arc name");
17607       return -99;
17608     }
17609   if (vec_len (arc_name) > 63)
17610     {
17611       errmsg ("arc name too long");
17612     }
17613
17614   if (feature_name == 0)
17615     {
17616       errmsg ("missing feature name");
17617       return -99;
17618     }
17619   if (vec_len (feature_name) > 63)
17620     {
17621       errmsg ("feature name too long");
17622     }
17623
17624   if (sw_if_index == ~0)
17625     {
17626       errmsg ("missing interface name or sw_if_index");
17627       return -99;
17628     }
17629
17630   /* Construct the API message */
17631   M (FEATURE_ENABLE_DISABLE, mp);
17632   mp->sw_if_index = ntohl (sw_if_index);
17633   mp->enable = enable;
17634   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17635   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17636   vec_free (arc_name);
17637   vec_free (feature_name);
17638
17639   S (mp);
17640   W (ret);
17641   return ret;
17642 }
17643
17644 static int
17645 api_sw_interface_tag_add_del (vat_main_t * vam)
17646 {
17647   unformat_input_t *i = vam->input;
17648   vl_api_sw_interface_tag_add_del_t *mp;
17649   u32 sw_if_index = ~0;
17650   u8 *tag = 0;
17651   u8 enable = 1;
17652   int ret;
17653
17654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17655     {
17656       if (unformat (i, "tag %s", &tag))
17657         ;
17658       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17659         ;
17660       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17661         ;
17662       else if (unformat (i, "del"))
17663         enable = 0;
17664       else
17665         break;
17666     }
17667
17668   if (sw_if_index == ~0)
17669     {
17670       errmsg ("missing interface name or sw_if_index");
17671       return -99;
17672     }
17673
17674   if (enable && (tag == 0))
17675     {
17676       errmsg ("no tag specified");
17677       return -99;
17678     }
17679
17680   /* Construct the API message */
17681   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17682   mp->sw_if_index = ntohl (sw_if_index);
17683   mp->is_add = enable;
17684   if (enable)
17685     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17686   vec_free (tag);
17687
17688   S (mp);
17689   W (ret);
17690   return ret;
17691 }
17692
17693 static void vl_api_l2_xconnect_details_t_handler
17694   (vl_api_l2_xconnect_details_t * mp)
17695 {
17696   vat_main_t *vam = &vat_main;
17697
17698   print (vam->ofp, "%15d%15d",
17699          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17700 }
17701
17702 static void vl_api_l2_xconnect_details_t_handler_json
17703   (vl_api_l2_xconnect_details_t * mp)
17704 {
17705   vat_main_t *vam = &vat_main;
17706   vat_json_node_t *node = NULL;
17707
17708   if (VAT_JSON_ARRAY != vam->json_tree.type)
17709     {
17710       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17711       vat_json_init_array (&vam->json_tree);
17712     }
17713   node = vat_json_array_add (&vam->json_tree);
17714
17715   vat_json_init_object (node);
17716   vat_json_object_add_uint (node, "rx_sw_if_index",
17717                             ntohl (mp->rx_sw_if_index));
17718   vat_json_object_add_uint (node, "tx_sw_if_index",
17719                             ntohl (mp->tx_sw_if_index));
17720 }
17721
17722 static int
17723 api_l2_xconnect_dump (vat_main_t * vam)
17724 {
17725   vl_api_l2_xconnect_dump_t *mp;
17726   vl_api_control_ping_t *mp_ping;
17727   int ret;
17728
17729   if (!vam->json_output)
17730     {
17731       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17732     }
17733
17734   M (L2_XCONNECT_DUMP, mp);
17735
17736   S (mp);
17737
17738   /* Use a control ping for synchronization */
17739   M (CONTROL_PING, mp_ping);
17740   S (mp_ping);
17741
17742   W (ret);
17743   return ret;
17744 }
17745
17746 static int
17747 api_sw_interface_set_mtu (vat_main_t * vam)
17748 {
17749   unformat_input_t *i = vam->input;
17750   vl_api_sw_interface_set_mtu_t *mp;
17751   u32 sw_if_index = ~0;
17752   u32 mtu = 0;
17753   int ret;
17754
17755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17756     {
17757       if (unformat (i, "mtu %d", &mtu))
17758         ;
17759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17760         ;
17761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17762         ;
17763       else
17764         break;
17765     }
17766
17767   if (sw_if_index == ~0)
17768     {
17769       errmsg ("missing interface name or sw_if_index");
17770       return -99;
17771     }
17772
17773   if (mtu == 0)
17774     {
17775       errmsg ("no mtu specified");
17776       return -99;
17777     }
17778
17779   /* Construct the API message */
17780   M (SW_INTERFACE_SET_MTU, mp);
17781   mp->sw_if_index = ntohl (sw_if_index);
17782   mp->mtu = ntohs ((u16) mtu);
17783
17784   S (mp);
17785   W (ret);
17786   return ret;
17787 }
17788
17789
17790 static int
17791 q_or_quit (vat_main_t * vam)
17792 {
17793   longjmp (vam->jump_buf, 1);
17794   return 0;                     /* not so much */
17795 }
17796
17797 static int
17798 q (vat_main_t * vam)
17799 {
17800   return q_or_quit (vam);
17801 }
17802
17803 static int
17804 quit (vat_main_t * vam)
17805 {
17806   return q_or_quit (vam);
17807 }
17808
17809 static int
17810 comment (vat_main_t * vam)
17811 {
17812   return 0;
17813 }
17814
17815 static int
17816 cmd_cmp (void *a1, void *a2)
17817 {
17818   u8 **c1 = a1;
17819   u8 **c2 = a2;
17820
17821   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17822 }
17823
17824 static int
17825 help (vat_main_t * vam)
17826 {
17827   u8 **cmds = 0;
17828   u8 *name = 0;
17829   hash_pair_t *p;
17830   unformat_input_t *i = vam->input;
17831   int j;
17832
17833   if (unformat (i, "%s", &name))
17834     {
17835       uword *hs;
17836
17837       vec_add1 (name, 0);
17838
17839       hs = hash_get_mem (vam->help_by_name, name);
17840       if (hs)
17841         print (vam->ofp, "usage: %s %s", name, hs[0]);
17842       else
17843         print (vam->ofp, "No such msg / command '%s'", name);
17844       vec_free (name);
17845       return 0;
17846     }
17847
17848   print (vam->ofp, "Help is available for the following:");
17849
17850     /* *INDENT-OFF* */
17851     hash_foreach_pair (p, vam->function_by_name,
17852     ({
17853       vec_add1 (cmds, (u8 *)(p->key));
17854     }));
17855     /* *INDENT-ON* */
17856
17857   vec_sort_with_function (cmds, cmd_cmp);
17858
17859   for (j = 0; j < vec_len (cmds); j++)
17860     print (vam->ofp, "%s", cmds[j]);
17861
17862   vec_free (cmds);
17863   return 0;
17864 }
17865
17866 static int
17867 set (vat_main_t * vam)
17868 {
17869   u8 *name = 0, *value = 0;
17870   unformat_input_t *i = vam->input;
17871
17872   if (unformat (i, "%s", &name))
17873     {
17874       /* The input buffer is a vector, not a string. */
17875       value = vec_dup (i->buffer);
17876       vec_delete (value, i->index, 0);
17877       /* Almost certainly has a trailing newline */
17878       if (value[vec_len (value) - 1] == '\n')
17879         value[vec_len (value) - 1] = 0;
17880       /* Make sure it's a proper string, one way or the other */
17881       vec_add1 (value, 0);
17882       (void) clib_macro_set_value (&vam->macro_main,
17883                                    (char *) name, (char *) value);
17884     }
17885   else
17886     errmsg ("usage: set <name> <value>");
17887
17888   vec_free (name);
17889   vec_free (value);
17890   return 0;
17891 }
17892
17893 static int
17894 unset (vat_main_t * vam)
17895 {
17896   u8 *name = 0;
17897
17898   if (unformat (vam->input, "%s", &name))
17899     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17900       errmsg ("unset: %s wasn't set", name);
17901   vec_free (name);
17902   return 0;
17903 }
17904
17905 typedef struct
17906 {
17907   u8 *name;
17908   u8 *value;
17909 } macro_sort_t;
17910
17911
17912 static int
17913 macro_sort_cmp (void *a1, void *a2)
17914 {
17915   macro_sort_t *s1 = a1;
17916   macro_sort_t *s2 = a2;
17917
17918   return strcmp ((char *) (s1->name), (char *) (s2->name));
17919 }
17920
17921 static int
17922 dump_macro_table (vat_main_t * vam)
17923 {
17924   macro_sort_t *sort_me = 0, *sm;
17925   int i;
17926   hash_pair_t *p;
17927
17928     /* *INDENT-OFF* */
17929     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17930     ({
17931       vec_add2 (sort_me, sm, 1);
17932       sm->name = (u8 *)(p->key);
17933       sm->value = (u8 *) (p->value[0]);
17934     }));
17935     /* *INDENT-ON* */
17936
17937   vec_sort_with_function (sort_me, macro_sort_cmp);
17938
17939   if (vec_len (sort_me))
17940     print (vam->ofp, "%-15s%s", "Name", "Value");
17941   else
17942     print (vam->ofp, "The macro table is empty...");
17943
17944   for (i = 0; i < vec_len (sort_me); i++)
17945     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17946   return 0;
17947 }
17948
17949 static int
17950 dump_node_table (vat_main_t * vam)
17951 {
17952   int i, j;
17953   vlib_node_t *node, *next_node;
17954
17955   if (vec_len (vam->graph_nodes) == 0)
17956     {
17957       print (vam->ofp, "Node table empty, issue get_node_graph...");
17958       return 0;
17959     }
17960
17961   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17962     {
17963       node = vam->graph_nodes[i];
17964       print (vam->ofp, "[%d] %s", i, node->name);
17965       for (j = 0; j < vec_len (node->next_nodes); j++)
17966         {
17967           if (node->next_nodes[j] != ~0)
17968             {
17969               next_node = vam->graph_nodes[node->next_nodes[j]];
17970               print (vam->ofp, "  [%d] %s", j, next_node->name);
17971             }
17972         }
17973     }
17974   return 0;
17975 }
17976
17977 static int
17978 value_sort_cmp (void *a1, void *a2)
17979 {
17980   name_sort_t *n1 = a1;
17981   name_sort_t *n2 = a2;
17982
17983   if (n1->value < n2->value)
17984     return -1;
17985   if (n1->value > n2->value)
17986     return 1;
17987   return 0;
17988 }
17989
17990
17991 static int
17992 dump_msg_api_table (vat_main_t * vam)
17993 {
17994   api_main_t *am = &api_main;
17995   name_sort_t *nses = 0, *ns;
17996   hash_pair_t *hp;
17997   int i;
17998
17999   /* *INDENT-OFF* */
18000   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18001   ({
18002     vec_add2 (nses, ns, 1);
18003     ns->name = (u8 *)(hp->key);
18004     ns->value = (u32) hp->value[0];
18005   }));
18006   /* *INDENT-ON* */
18007
18008   vec_sort_with_function (nses, value_sort_cmp);
18009
18010   for (i = 0; i < vec_len (nses); i++)
18011     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18012   vec_free (nses);
18013   return 0;
18014 }
18015
18016 static int
18017 get_msg_id (vat_main_t * vam)
18018 {
18019   u8 *name_and_crc;
18020   u32 message_index;
18021
18022   if (unformat (vam->input, "%s", &name_and_crc))
18023     {
18024       message_index = vl_api_get_msg_index (name_and_crc);
18025       if (message_index == ~0)
18026         {
18027           print (vam->ofp, " '%s' not found", name_and_crc);
18028           return 0;
18029         }
18030       print (vam->ofp, " '%s' has message index %d",
18031              name_and_crc, message_index);
18032       return 0;
18033     }
18034   errmsg ("name_and_crc required...");
18035   return 0;
18036 }
18037
18038 static int
18039 search_node_table (vat_main_t * vam)
18040 {
18041   unformat_input_t *line_input = vam->input;
18042   u8 *node_to_find;
18043   int j;
18044   vlib_node_t *node, *next_node;
18045   uword *p;
18046
18047   if (vam->graph_node_index_by_name == 0)
18048     {
18049       print (vam->ofp, "Node table empty, issue get_node_graph...");
18050       return 0;
18051     }
18052
18053   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18054     {
18055       if (unformat (line_input, "%s", &node_to_find))
18056         {
18057           vec_add1 (node_to_find, 0);
18058           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18059           if (p == 0)
18060             {
18061               print (vam->ofp, "%s not found...", node_to_find);
18062               goto out;
18063             }
18064           node = vam->graph_nodes[p[0]];
18065           print (vam->ofp, "[%d] %s", p[0], node->name);
18066           for (j = 0; j < vec_len (node->next_nodes); j++)
18067             {
18068               if (node->next_nodes[j] != ~0)
18069                 {
18070                   next_node = vam->graph_nodes[node->next_nodes[j]];
18071                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18072                 }
18073             }
18074         }
18075
18076       else
18077         {
18078           clib_warning ("parse error '%U'", format_unformat_error,
18079                         line_input);
18080           return -99;
18081         }
18082
18083     out:
18084       vec_free (node_to_find);
18085
18086     }
18087
18088   return 0;
18089 }
18090
18091
18092 static int
18093 script (vat_main_t * vam)
18094 {
18095 #if (VPP_API_TEST_BUILTIN==0)
18096   u8 *s = 0;
18097   char *save_current_file;
18098   unformat_input_t save_input;
18099   jmp_buf save_jump_buf;
18100   u32 save_line_number;
18101
18102   FILE *new_fp, *save_ifp;
18103
18104   if (unformat (vam->input, "%s", &s))
18105     {
18106       new_fp = fopen ((char *) s, "r");
18107       if (new_fp == 0)
18108         {
18109           errmsg ("Couldn't open script file %s", s);
18110           vec_free (s);
18111           return -99;
18112         }
18113     }
18114   else
18115     {
18116       errmsg ("Missing script name");
18117       return -99;
18118     }
18119
18120   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18121   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18122   save_ifp = vam->ifp;
18123   save_line_number = vam->input_line_number;
18124   save_current_file = (char *) vam->current_file;
18125
18126   vam->input_line_number = 0;
18127   vam->ifp = new_fp;
18128   vam->current_file = s;
18129   do_one_file (vam);
18130
18131   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18132   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18133   vam->ifp = save_ifp;
18134   vam->input_line_number = save_line_number;
18135   vam->current_file = (u8 *) save_current_file;
18136   vec_free (s);
18137
18138   return 0;
18139 #else
18140   clib_warning ("use the exec command...");
18141   return -99;
18142 #endif
18143 }
18144
18145 static int
18146 echo (vat_main_t * vam)
18147 {
18148   print (vam->ofp, "%v", vam->input->buffer);
18149   return 0;
18150 }
18151
18152 /* List of API message constructors, CLI names map to api_xxx */
18153 #define foreach_vpe_api_msg                                             \
18154 _(create_loopback,"[mac <mac-addr>]")                                   \
18155 _(sw_interface_dump,"")                                                 \
18156 _(sw_interface_set_flags,                                               \
18157   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18158 _(sw_interface_add_del_address,                                         \
18159   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18160 _(sw_interface_set_table,                                               \
18161   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18162 _(sw_interface_set_mpls_enable,                                         \
18163   "<intfc> | sw_if_index [disable | dis]")                              \
18164 _(sw_interface_set_vpath,                                               \
18165   "<intfc> | sw_if_index <id> enable | disable")                        \
18166 _(sw_interface_set_vxlan_bypass,                                        \
18167   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18168 _(sw_interface_set_l2_xconnect,                                         \
18169   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18170   "enable | disable")                                                   \
18171 _(sw_interface_set_l2_bridge,                                           \
18172   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18173   "[shg <split-horizon-group>] [bvi]\n"                                 \
18174   "enable | disable")                                                   \
18175 _(bridge_domain_add_del,                                                \
18176   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18177 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18178 _(l2fib_add_del,                                                        \
18179   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18180 _(l2_flags,                                                             \
18181   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18182 _(bridge_flags,                                                         \
18183   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18184 _(tap_connect,                                                          \
18185   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18186 _(tap_modify,                                                           \
18187   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18188 _(tap_delete,                                                           \
18189   "<vpp-if-name> | sw_if_index <id>")                                   \
18190 _(sw_interface_tap_dump, "")                                            \
18191 _(ip_add_del_route,                                                     \
18192   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18193   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18194   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18195   "[multipath] [count <n>]")                                            \
18196 _(ip_mroute_add_del,                                                    \
18197   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18198   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18199 _(mpls_route_add_del,                                                   \
18200   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18201   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18202   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18203   "[multipath] [count <n>]")                                            \
18204 _(mpls_ip_bind_unbind,                                                  \
18205   "<label> <addr/len>")                                                 \
18206 _(mpls_tunnel_add_del,                                                  \
18207   " via <addr> [table-id <n>]\n"                                        \
18208   "sw_if_index <id>] [l2]  [del]")                                      \
18209 _(proxy_arp_add_del,                                                    \
18210   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18211 _(proxy_arp_intfc_enable_disable,                                       \
18212   "<intfc> | sw_if_index <id> enable | disable")                        \
18213 _(sw_interface_set_unnumbered,                                          \
18214   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18215 _(ip_neighbor_add_del,                                                  \
18216   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18217   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18218 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18219 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18220 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18221   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18222   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18223   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18224 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18225 _(reset_fib, "vrf <n> [ipv6]")                                          \
18226 _(dhcp_proxy_config,                                                    \
18227   "svr <v46-address> src <v46-address>\n"                               \
18228    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18229 _(dhcp_proxy_set_vss,                                                   \
18230   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18231 _(dhcp_proxy_dump, "ip6")                                               \
18232 _(dhcp_client_config,                                                   \
18233   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18234 _(set_ip_flow_hash,                                                     \
18235   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18236 _(sw_interface_ip6_enable_disable,                                      \
18237   "<intfc> | sw_if_index <id> enable | disable")                        \
18238 _(sw_interface_ip6_set_link_local_address,                              \
18239   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18240 _(sw_interface_ip6nd_ra_prefix,                                         \
18241   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18242   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18243   "[nolink] [isno]")                                                    \
18244 _(sw_interface_ip6nd_ra_config,                                         \
18245   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18246   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18247   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18248 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18249 _(l2_patch_add_del,                                                     \
18250   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18251   "enable | disable")                                                   \
18252 _(sr_tunnel_add_del,                                                    \
18253   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
18254   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
18255   "[policy <policy_name>]")                                             \
18256 _(sr_policy_add_del,                                                    \
18257   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
18258 _(sr_multicast_map_add_del,                                             \
18259   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
18260 _(classify_add_del_table,                                               \
18261   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18262   " [del] [del-chain] mask <mask-value>\n"                              \
18263   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18264   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18265 _(classify_add_del_session,                                             \
18266   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18267   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18268   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18269   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18270 _(classify_set_interface_ip_table,                                      \
18271   "<intfc> | sw_if_index <nn> table <nn>")                              \
18272 _(classify_set_interface_l2_tables,                                     \
18273   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18274   "  [other-table <nn>]")                                               \
18275 _(get_node_index, "node <node-name")                                    \
18276 _(add_node_next, "node <node-name> next <next-node-name>")              \
18277 _(l2tpv3_create_tunnel,                                                 \
18278   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18279   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18280   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18281 _(l2tpv3_set_tunnel_cookies,                                            \
18282   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18283   "[new_remote_cookie <nn>]\n")                                         \
18284 _(l2tpv3_interface_enable_disable,                                      \
18285   "<intfc> | sw_if_index <nn> enable | disable")                        \
18286 _(l2tpv3_set_lookup_key,                                                \
18287   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18288 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18289 _(vxlan_add_del_tunnel,                                                 \
18290   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18291   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18292   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18293 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18294 _(gre_add_del_tunnel,                                                   \
18295   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18296 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18297 _(l2_fib_clear_table, "")                                               \
18298 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18299 _(l2_interface_vlan_tag_rewrite,                                        \
18300   "<intfc> | sw_if_index <nn> \n"                                       \
18301   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18302   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18303 _(create_vhost_user_if,                                                 \
18304         "socket <filename> [server] [renumber <dev_instance>] "         \
18305         "[mac <mac_address>]")                                          \
18306 _(modify_vhost_user_if,                                                 \
18307         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18308         "[server] [renumber <dev_instance>]")                           \
18309 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18310 _(sw_interface_vhost_user_dump, "")                                     \
18311 _(show_version, "")                                                     \
18312 _(vxlan_gpe_add_del_tunnel,                                             \
18313   "local <addr> remote <addr> vni <nn>\n"                               \
18314     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18315   "[next-ethernet] [next-nsh]\n")                                       \
18316 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18317 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18318 _(interface_name_renumber,                                              \
18319   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18320 _(input_acl_set_interface,                                              \
18321   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18322   "  [l2-table <nn>] [del]")                                            \
18323 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18324 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18325 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18326 _(ip_dump, "ipv4 | ipv6")                                               \
18327 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18328 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18329   "  spid_id <n> ")                                                     \
18330 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18331   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18332   "  integ_alg <alg> integ_key <hex>")                                  \
18333 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18334   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18335   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18336   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18337 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18338 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18339 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18340   "(auth_data 0x<data> | auth_data <data>)")                            \
18341 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18342   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18343 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18344   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18345   "(local|remote)")                                                     \
18346 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18347 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18348 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18349 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18350 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18351 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18352 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18353 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18354 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18355 _(delete_loopback,"sw_if_index <nn>")                                   \
18356 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18357 _(map_add_domain,                                                       \
18358   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18359   "ip6-src <ip6addr> "                                                  \
18360   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18361 _(map_del_domain, "index <n>")                                          \
18362 _(map_add_del_rule,                                                     \
18363   "index <n> psid <n> dst <ip6addr> [del]")                             \
18364 _(map_domain_dump, "")                                                  \
18365 _(map_rule_dump, "index <map-domain>")                                  \
18366 _(want_interface_events,  "enable|disable")                             \
18367 _(want_stats,"enable|disable")                                          \
18368 _(get_first_msg_id, "client <name>")                                    \
18369 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18370 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18371   "fib-id <nn> [ip4][ip6][default]")                                    \
18372 _(get_node_graph, " ")                                                  \
18373 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18374 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18375 _(ioam_disable, "")                                                     \
18376 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18377                             " sw_if_index <sw_if_index> p <priority> "  \
18378                             "w <weight>] [del]")                        \
18379 _(one_add_del_locator, "locator-set <locator_name> "                    \
18380                         "iface <intf> | sw_if_index <sw_if_index> "     \
18381                         "p <priority> w <weight> [del]")                \
18382 _(one_add_del_local_eid,"vni <vni> eid "                                \
18383                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18384                          "locator-set <locator_name> [del]"             \
18385                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18386 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18387 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18388 _(one_enable_disable, "enable|disable")                                 \
18389 _(one_map_register_enable_disable, "enable|disable")                    \
18390 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18391 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18392                                "[seid <seid>] "                         \
18393                                "rloc <locator> p <prio> "               \
18394                                "w <weight> [rloc <loc> ... ] "          \
18395                                "action <action> [del-all]")             \
18396 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18397                           "<local-eid>")                                \
18398 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18399 _(one_map_request_mode, "src-dst|dst-only")                             \
18400 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18401 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18402 _(one_locator_set_dump, "[local | remote]")                             \
18403 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18404 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18405                        "[local] | [remote]")                            \
18406 _(one_eid_table_vni_dump, "")                                           \
18407 _(one_eid_table_map_dump, "l2|l3")                                      \
18408 _(one_map_resolver_dump, "")                                            \
18409 _(one_map_server_dump, "")                                              \
18410 _(one_adjacencies_get, "vni <vni>")                                     \
18411 _(show_one_rloc_probe_state, "")                                        \
18412 _(show_one_map_register_state, "")                                      \
18413 _(show_one_status, "")                                                  \
18414 _(one_get_map_request_itr_rlocs, "")                                    \
18415 _(show_one_pitr, "")                                                    \
18416 _(show_one_map_request_mode, "")                                        \
18417 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18418                             " sw_if_index <sw_if_index> p <priority> "  \
18419                             "w <weight>] [del]")                        \
18420 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18421                         "iface <intf> | sw_if_index <sw_if_index> "     \
18422                         "p <priority> w <weight> [del]")                \
18423 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18424                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18425                          "locator-set <locator_name> [del]"             \
18426                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18427 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18428 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18429 _(lisp_enable_disable, "enable|disable")                                \
18430 _(lisp_map_register_enable_disable, "enable|disable")                   \
18431 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18432 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18433                                "[seid <seid>] "                         \
18434                                "rloc <locator> p <prio> "               \
18435                                "w <weight> [rloc <loc> ... ] "          \
18436                                "action <action> [del-all]")             \
18437 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18438                           "<local-eid>")                                \
18439 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18440 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18441 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18442 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18443 _(lisp_locator_set_dump, "[local | remote]")                            \
18444 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18445 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18446                        "[local] | [remote]")                            \
18447 _(lisp_eid_table_vni_dump, "")                                          \
18448 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18449 _(lisp_map_resolver_dump, "")                                           \
18450 _(lisp_map_server_dump, "")                                             \
18451 _(lisp_adjacencies_get, "vni <vni>")                                    \
18452 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18453 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18454 _(lisp_gpe_add_del_iface, "up|down")                                    \
18455 _(lisp_gpe_enable_disable, "enable|disable")                            \
18456 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18457   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18458 _(show_lisp_rloc_probe_state, "")                                       \
18459 _(show_lisp_map_register_state, "")                                     \
18460 _(show_lisp_status, "")                                                 \
18461 _(lisp_get_map_request_itr_rlocs, "")                                   \
18462 _(show_lisp_pitr, "")                                                   \
18463 _(show_lisp_map_request_mode, "")                                       \
18464 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18465 _(af_packet_delete, "name <host interface name>")                       \
18466 _(policer_add_del, "name <policer name> <params> [del]")                \
18467 _(policer_dump, "[name <policer name>]")                                \
18468 _(policer_classify_set_interface,                                       \
18469   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18470   "  [l2-table <nn>] [del]")                                            \
18471 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18472 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18473     "[master|slave]")                                                   \
18474 _(netmap_delete, "name <interface name>")                               \
18475 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18476 _(mpls_fib_dump, "")                                                    \
18477 _(classify_table_ids, "")                                               \
18478 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18479 _(classify_table_info, "table_id <nn>")                                 \
18480 _(classify_session_dump, "table_id <nn>")                               \
18481 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18482     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18483     "[template_interval <nn>] [udp_checksum]")                          \
18484 _(ipfix_exporter_dump, "")                                              \
18485 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18486 _(ipfix_classify_stream_dump, "")                                       \
18487 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18488 _(ipfix_classify_table_dump, "")                                        \
18489 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18490 _(sw_interface_span_dump, "")                                           \
18491 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18492 _(pg_create_interface, "if_id <nn>")                                    \
18493 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18494 _(pg_enable_disable, "[stream <id>] disable")                           \
18495 _(ip_source_and_port_range_check_add_del,                               \
18496   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18497 _(ip_source_and_port_range_check_interface_add_del,                     \
18498   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18499   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18500 _(ipsec_gre_add_del_tunnel,                                             \
18501   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18502 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18503 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18504 _(l2_interface_pbb_tag_rewrite,                                         \
18505   "<intfc> | sw_if_index <nn> \n"                                       \
18506   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18507   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18508 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18509 _(flow_classify_set_interface,                                          \
18510   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18511 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18512 _(ip_fib_dump, "")                                                      \
18513 _(ip_mfib_dump, "")                                                     \
18514 _(ip6_fib_dump, "")                                                     \
18515 _(ip6_mfib_dump, "")                                                    \
18516 _(feature_enable_disable, "arc_name <arc_name> "                        \
18517   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18518 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18519 "[disable]")                                                            \
18520 _(l2_xconnect_dump, "")                                                 \
18521 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18522 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18523 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18524
18525 #if DPDK > 0
18526 #define foreach_vpe_dpdk_api_msg                                        \
18527 _(sw_interface_set_dpdk_hqos_pipe,                                      \
18528   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
18529   "profile <profile-id>\n")                                             \
18530 _(sw_interface_set_dpdk_hqos_subport,                                   \
18531   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
18532   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
18533 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
18534   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
18535 #endif
18536
18537 /* List of command functions, CLI names map directly to functions */
18538 #define foreach_cli_function                                    \
18539 _(comment, "usage: comment <ignore-rest-of-line>")              \
18540 _(dump_interface_table, "usage: dump_interface_table")          \
18541 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18542 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18543 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18544 _(dump_stats_table, "usage: dump_stats_table")                  \
18545 _(dump_macro_table, "usage: dump_macro_table ")                 \
18546 _(dump_node_table, "usage: dump_node_table")                    \
18547 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18548 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18549 _(echo, "usage: echo <message>")                                \
18550 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18551 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18552 _(help, "usage: help")                                          \
18553 _(q, "usage: quit")                                             \
18554 _(quit, "usage: quit")                                          \
18555 _(search_node_table, "usage: search_node_table <name>...")      \
18556 _(set, "usage: set <variable-name> <value>")                    \
18557 _(script, "usage: script <file-name>")                          \
18558 _(unset, "usage: unset <variable-name>")
18559
18560 #define _(N,n)                                  \
18561     static void vl_api_##n##_t_handler_uni      \
18562     (vl_api_##n##_t * mp)                       \
18563     {                                           \
18564         vat_main_t * vam = &vat_main;           \
18565         if (vam->json_output) {                 \
18566             vl_api_##n##_t_handler_json(mp);    \
18567         } else {                                \
18568             vl_api_##n##_t_handler(mp);         \
18569         }                                       \
18570     }
18571 foreach_vpe_api_reply_msg;
18572 #undef _
18573
18574 #if DPDK > 0
18575 #define _(N,n)                                  \
18576     static void vl_api_##n##_t_handler_uni      \
18577     (vl_api_##n##_t * mp)                       \
18578     {                                           \
18579         vat_main_t * vam = &vat_main;           \
18580         if (vam->json_output) {                 \
18581             vl_api_##n##_t_handler_json(mp);    \
18582         } else {                                \
18583             vl_api_##n##_t_handler(mp);         \
18584         }                                       \
18585     }
18586 foreach_vpe_dpdk_api_reply_msg;
18587 #undef _
18588 #endif
18589
18590 void
18591 vat_api_hookup (vat_main_t * vam)
18592 {
18593 #define _(N,n)                                                  \
18594     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18595                            vl_api_##n##_t_handler_uni,          \
18596                            vl_noop_handler,                     \
18597                            vl_api_##n##_t_endian,               \
18598                            vl_api_##n##_t_print,                \
18599                            sizeof(vl_api_##n##_t), 1);
18600   foreach_vpe_api_reply_msg;
18601 #undef _
18602
18603 #if DPDK > 0
18604 #define _(N,n)                                                  \
18605     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18606                            vl_api_##n##_t_handler_uni,          \
18607                            vl_noop_handler,                     \
18608                            vl_api_##n##_t_endian,               \
18609                            vl_api_##n##_t_print,                \
18610                            sizeof(vl_api_##n##_t), 1);
18611   foreach_vpe_dpdk_api_reply_msg;
18612 #undef _
18613 #endif
18614
18615 #if (VPP_API_TEST_BUILTIN==0)
18616   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18617 #endif
18618
18619   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18620
18621   vam->function_by_name = hash_create_string (0, sizeof (uword));
18622
18623   vam->help_by_name = hash_create_string (0, sizeof (uword));
18624
18625   /* API messages we can send */
18626 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18627   foreach_vpe_api_msg;
18628 #undef _
18629 #if DPDK >0
18630 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18631   foreach_vpe_dpdk_api_msg;
18632 #undef _
18633 #endif
18634
18635   /* Help strings */
18636 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18637   foreach_vpe_api_msg;
18638 #undef _
18639 #if DPDK >0
18640 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18641   foreach_vpe_dpdk_api_msg;
18642 #undef _
18643 #endif
18644
18645   /* CLI functions */
18646 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18647   foreach_cli_function;
18648 #undef _
18649
18650   /* Help strings */
18651 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18652   foreach_cli_function;
18653 #undef _
18654 }
18655
18656 /*
18657  * fd.io coding-style-patch-verification: ON
18658  *
18659  * Local Variables:
18660  * eval: (c-set-style "gnu")
18661  * End:
18662  */