svm: refactor memfd and remove ssvm_eth
[vpp.git] / src / vpp / api / 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 <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/geneve/geneve.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 #include <vnet/dhcp/dhcp_proxy.h>
53
54 #include "vat/json_format.h"
55
56 #include <inttypes.h>
57 #include <sys/stat.h>
58
59 #define vl_typedefs             /* define message structures */
60 #include <vpp/api/vpe_all_api_h.h>
61 #undef vl_typedefs
62
63 /* declare message handlers for each api */
64
65 #define vl_endianfun            /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_endianfun
68
69 /* instantiate all the print functions we know about */
70 #define vl_print(handle, ...)
71 #define vl_printfun
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_printfun
74
75 #define __plugin_msg_base 0
76 #include <vlibapi/vat_helper_macros.h>
77
78 #if VPP_API_TEST_BUILTIN == 0
79 #include <netdb.h>
80
81 u32
82 vl (void *p)
83 {
84   return vec_len (p);
85 }
86
87 int
88 vat_socket_connect (vat_main_t * vam)
89 {
90   vam->socket_client_main = &socket_client_main;
91   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
92                                    0 /* default socket rx, tx buffer */ );
93 }
94 #else /* vpp built-in case, we don't do sockets... */
95 int
96 vat_socket_connect (vat_main_t * vam)
97 {
98   return 0;
99 }
100
101 int
102 vl_socket_client_read (int wait)
103 {
104   return -1;
105 };
106
107 int
108 vl_socket_client_write ()
109 {
110   return -1;
111 };
112
113 void *
114 vl_socket_client_msg_alloc (int nbytes)
115 {
116   return 0;
117 }
118 #endif
119
120
121 f64
122 vat_time_now (vat_main_t * vam)
123 {
124 #if VPP_API_TEST_BUILTIN
125   return vlib_time_now (vam->vlib_main);
126 #else
127   return clib_time_now (&vam->clib_time);
128 #endif
129 }
130
131 void
132 errmsg (char *fmt, ...)
133 {
134   vat_main_t *vam = &vat_main;
135   va_list va;
136   u8 *s;
137
138   va_start (va, fmt);
139   s = va_format (0, fmt, &va);
140   va_end (va);
141
142   vec_add1 (s, 0);
143
144 #if VPP_API_TEST_BUILTIN
145   vlib_cli_output (vam->vlib_main, (char *) s);
146 #else
147   {
148     if (vam->ifp != stdin)
149       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
150                vam->input_line_number);
151     fformat (vam->ofp, (char *) s);
152     fflush (vam->ofp);
153   }
154 #endif
155
156   vec_free (s);
157 }
158
159 #if VPP_API_TEST_BUILTIN == 0
160 static uword
161 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
162 {
163   vat_main_t *vam = va_arg (*args, vat_main_t *);
164   u32 *result = va_arg (*args, u32 *);
165   u8 *if_name;
166   uword *p;
167
168   if (!unformat (input, "%s", &if_name))
169     return 0;
170
171   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
172   if (p == 0)
173     return 0;
174   *result = p[0];
175   return 1;
176 }
177
178 /* Parse an IP4 address %d.%d.%d.%d. */
179 uword
180 unformat_ip4_address (unformat_input_t * input, va_list * args)
181 {
182   u8 *result = va_arg (*args, u8 *);
183   unsigned a[4];
184
185   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
186     return 0;
187
188   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
189     return 0;
190
191   result[0] = a[0];
192   result[1] = a[1];
193   result[2] = a[2];
194   result[3] = a[3];
195
196   return 1;
197 }
198
199 uword
200 unformat_ethernet_address (unformat_input_t * input, va_list * args)
201 {
202   u8 *result = va_arg (*args, u8 *);
203   u32 i, a[6];
204
205   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
206                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
207     return 0;
208
209   /* Check range. */
210   for (i = 0; i < 6; i++)
211     if (a[i] >= (1 << 8))
212       return 0;
213
214   for (i = 0; i < 6; i++)
215     result[i] = a[i];
216
217   return 1;
218 }
219
220 /* Returns ethernet type as an int in host byte order. */
221 uword
222 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
223                                         va_list * args)
224 {
225   u16 *result = va_arg (*args, u16 *);
226   int type;
227
228   /* Numeric type. */
229   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
230     {
231       if (type >= (1 << 16))
232         return 0;
233       *result = type;
234       return 1;
235     }
236   return 0;
237 }
238
239 /* Parse an IP6 address. */
240 uword
241 unformat_ip6_address (unformat_input_t * input, va_list * args)
242 {
243   ip6_address_t *result = va_arg (*args, ip6_address_t *);
244   u16 hex_quads[8];
245   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
246   uword c, n_colon, double_colon_index;
247
248   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
249   double_colon_index = ARRAY_LEN (hex_quads);
250   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
251     {
252       hex_digit = 16;
253       if (c >= '0' && c <= '9')
254         hex_digit = c - '0';
255       else if (c >= 'a' && c <= 'f')
256         hex_digit = c + 10 - 'a';
257       else if (c >= 'A' && c <= 'F')
258         hex_digit = c + 10 - 'A';
259       else if (c == ':' && n_colon < 2)
260         n_colon++;
261       else
262         {
263           unformat_put_input (input);
264           break;
265         }
266
267       /* Too many hex quads. */
268       if (n_hex_quads >= ARRAY_LEN (hex_quads))
269         return 0;
270
271       if (hex_digit < 16)
272         {
273           hex_quad = (hex_quad << 4) | hex_digit;
274
275           /* Hex quad must fit in 16 bits. */
276           if (n_hex_digits >= 4)
277             return 0;
278
279           n_colon = 0;
280           n_hex_digits++;
281         }
282
283       /* Save position of :: */
284       if (n_colon == 2)
285         {
286           /* More than one :: ? */
287           if (double_colon_index < ARRAY_LEN (hex_quads))
288             return 0;
289           double_colon_index = n_hex_quads;
290         }
291
292       if (n_colon > 0 && n_hex_digits > 0)
293         {
294           hex_quads[n_hex_quads++] = hex_quad;
295           hex_quad = 0;
296           n_hex_digits = 0;
297         }
298     }
299
300   if (n_hex_digits > 0)
301     hex_quads[n_hex_quads++] = hex_quad;
302
303   {
304     word i;
305
306     /* Expand :: to appropriate number of zero hex quads. */
307     if (double_colon_index < ARRAY_LEN (hex_quads))
308       {
309         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
310
311         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
312           hex_quads[n_zero + i] = hex_quads[i];
313
314         for (i = 0; i < n_zero; i++)
315           hex_quads[double_colon_index + i] = 0;
316
317         n_hex_quads = ARRAY_LEN (hex_quads);
318       }
319
320     /* Too few hex quads given. */
321     if (n_hex_quads < ARRAY_LEN (hex_quads))
322       return 0;
323
324     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
325       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
326
327     return 1;
328   }
329 }
330
331 uword
332 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
338   foreach_ipsec_policy_action
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 uword
346 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
347 {
348   u32 *r = va_arg (*args, u32 *);
349
350   if (0);
351 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
352   foreach_ipsec_crypto_alg
353 #undef _
354     else
355     return 0;
356   return 1;
357 }
358
359 u8 *
360 format_ipsec_crypto_alg (u8 * s, va_list * args)
361 {
362   u32 i = va_arg (*args, u32);
363   u8 *t = 0;
364
365   switch (i)
366     {
367 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
368       foreach_ipsec_crypto_alg
369 #undef _
370     default:
371       return format (s, "unknown");
372     }
373   return format (s, "%s", t);
374 }
375
376 uword
377 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
383   foreach_ipsec_integ_alg
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389
390 u8 *
391 format_ipsec_integ_alg (u8 * s, va_list * args)
392 {
393   u32 i = va_arg (*args, u32);
394   u8 *t = 0;
395
396   switch (i)
397     {
398 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
399       foreach_ipsec_integ_alg
400 #undef _
401     default:
402       return format (s, "unknown");
403     }
404   return format (s, "%s", t);
405 }
406
407 uword
408 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
409 {
410   u32 *r = va_arg (*args, u32 *);
411
412   if (0);
413 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
414   foreach_ikev2_auth_method
415 #undef _
416     else
417     return 0;
418   return 1;
419 }
420
421 uword
422 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
423 {
424   u32 *r = va_arg (*args, u32 *);
425
426   if (0);
427 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
428   foreach_ikev2_id_type
429 #undef _
430     else
431     return 0;
432   return 1;
433 }
434 #else /* VPP_API_TEST_BUILTIN == 1 */
435 static uword
436 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
437 {
438   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
439   vnet_main_t *vnm = vnet_get_main ();
440   u32 *result = va_arg (*args, u32 *);
441   u32 sw_if_index;
442
443   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
444     return 0;
445
446   *result = sw_if_index;
447   return 1;
448 }
449 #endif /* VPP_API_TEST_BUILTIN */
450
451 static uword
452 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
453 {
454   u8 *r = va_arg (*args, u8 *);
455
456   if (unformat (input, "kbps"))
457     *r = SSE2_QOS_RATE_KBPS;
458   else if (unformat (input, "pps"))
459     *r = SSE2_QOS_RATE_PPS;
460   else
461     return 0;
462   return 1;
463 }
464
465 static uword
466 unformat_policer_round_type (unformat_input_t * input, va_list * args)
467 {
468   u8 *r = va_arg (*args, u8 *);
469
470   if (unformat (input, "closest"))
471     *r = SSE2_QOS_ROUND_TO_CLOSEST;
472   else if (unformat (input, "up"))
473     *r = SSE2_QOS_ROUND_TO_UP;
474   else if (unformat (input, "down"))
475     *r = SSE2_QOS_ROUND_TO_DOWN;
476   else
477     return 0;
478   return 1;
479 }
480
481 static uword
482 unformat_policer_type (unformat_input_t * input, va_list * args)
483 {
484   u8 *r = va_arg (*args, u8 *);
485
486   if (unformat (input, "1r2c"))
487     *r = SSE2_QOS_POLICER_TYPE_1R2C;
488   else if (unformat (input, "1r3c"))
489     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
490   else if (unformat (input, "2r3c-2698"))
491     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
492   else if (unformat (input, "2r3c-4115"))
493     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
494   else if (unformat (input, "2r3c-mef5cf1"))
495     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
496   else
497     return 0;
498   return 1;
499 }
500
501 static uword
502 unformat_dscp (unformat_input_t * input, va_list * va)
503 {
504   u8 *r = va_arg (*va, u8 *);
505
506   if (0);
507 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
508   foreach_vnet_dscp
509 #undef _
510     else
511     return 0;
512   return 1;
513 }
514
515 static uword
516 unformat_policer_action_type (unformat_input_t * input, va_list * va)
517 {
518   sse2_qos_pol_action_params_st *a
519     = va_arg (*va, sse2_qos_pol_action_params_st *);
520
521   if (unformat (input, "drop"))
522     a->action_type = SSE2_QOS_ACTION_DROP;
523   else if (unformat (input, "transmit"))
524     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
525   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
526     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
527   else
528     return 0;
529   return 1;
530 }
531
532 static uword
533 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
534 {
535   u32 *r = va_arg (*va, u32 *);
536   u32 tid;
537
538   if (unformat (input, "ip4"))
539     tid = POLICER_CLASSIFY_TABLE_IP4;
540   else if (unformat (input, "ip6"))
541     tid = POLICER_CLASSIFY_TABLE_IP6;
542   else if (unformat (input, "l2"))
543     tid = POLICER_CLASSIFY_TABLE_L2;
544   else
545     return 0;
546
547   *r = tid;
548   return 1;
549 }
550
551 static uword
552 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
553 {
554   u32 *r = va_arg (*va, u32 *);
555   u32 tid;
556
557   if (unformat (input, "ip4"))
558     tid = FLOW_CLASSIFY_TABLE_IP4;
559   else if (unformat (input, "ip6"))
560     tid = FLOW_CLASSIFY_TABLE_IP6;
561   else
562     return 0;
563
564   *r = tid;
565   return 1;
566 }
567
568 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
569 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
570 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
571 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
572
573 #if (VPP_API_TEST_BUILTIN==0)
574 uword
575 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
576 {
577   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
578   mfib_itf_attribute_t attr;
579
580   old = *iflags;
581   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
582   {
583     if (unformat (input, mfib_itf_flag_long_names[attr]))
584       *iflags |= (1 << attr);
585   }
586   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
587   {
588     if (unformat (input, mfib_itf_flag_names[attr]))
589       *iflags |= (1 << attr);
590   }
591
592   return (old == *iflags ? 0 : 1);
593 }
594
595 uword
596 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
597 {
598   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
599   mfib_entry_attribute_t attr;
600
601   old = *eflags;
602   FOR_EACH_MFIB_ATTRIBUTE (attr)
603   {
604     if (unformat (input, mfib_flag_long_names[attr]))
605       *eflags |= (1 << attr);
606   }
607   FOR_EACH_MFIB_ATTRIBUTE (attr)
608   {
609     if (unformat (input, mfib_flag_names[attr]))
610       *eflags |= (1 << attr);
611   }
612
613   return (old == *eflags ? 0 : 1);
614 }
615
616 u8 *
617 format_ip4_address (u8 * s, va_list * args)
618 {
619   u8 *a = va_arg (*args, u8 *);
620   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
621 }
622
623 u8 *
624 format_ip6_address (u8 * s, va_list * args)
625 {
626   ip6_address_t *a = va_arg (*args, ip6_address_t *);
627   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
628
629   i_max_n_zero = ARRAY_LEN (a->as_u16);
630   max_n_zeros = 0;
631   i_first_zero = i_max_n_zero;
632   n_zeros = 0;
633   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
634     {
635       u32 is_zero = a->as_u16[i] == 0;
636       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
637         {
638           i_first_zero = i;
639           n_zeros = 0;
640         }
641       n_zeros += is_zero;
642       if ((!is_zero && n_zeros > max_n_zeros)
643           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
644         {
645           i_max_n_zero = i_first_zero;
646           max_n_zeros = n_zeros;
647           i_first_zero = ARRAY_LEN (a->as_u16);
648           n_zeros = 0;
649         }
650     }
651
652   last_double_colon = 0;
653   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
654     {
655       if (i == i_max_n_zero && max_n_zeros > 1)
656         {
657           s = format (s, "::");
658           i += max_n_zeros - 1;
659           last_double_colon = 1;
660         }
661       else
662         {
663           s = format (s, "%s%x",
664                       (last_double_colon || i == 0) ? "" : ":",
665                       clib_net_to_host_u16 (a->as_u16[i]));
666           last_double_colon = 0;
667         }
668     }
669
670   return s;
671 }
672
673 /* Format an IP46 address. */
674 u8 *
675 format_ip46_address (u8 * s, va_list * args)
676 {
677   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
678   ip46_type_t type = va_arg (*args, ip46_type_t);
679   int is_ip4 = 1;
680
681   switch (type)
682     {
683     case IP46_TYPE_ANY:
684       is_ip4 = ip46_address_is_ip4 (ip46);
685       break;
686     case IP46_TYPE_IP4:
687       is_ip4 = 1;
688       break;
689     case IP46_TYPE_IP6:
690       is_ip4 = 0;
691       break;
692     }
693
694   return is_ip4 ?
695     format (s, "%U", format_ip4_address, &ip46->ip4) :
696     format (s, "%U", format_ip6_address, &ip46->ip6);
697 }
698
699 u8 *
700 format_ethernet_address (u8 * s, va_list * args)
701 {
702   u8 *a = va_arg (*args, u8 *);
703
704   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
705                  a[0], a[1], a[2], a[3], a[4], a[5]);
706 }
707 #endif
708
709 static void
710 increment_v4_address (ip4_address_t * a)
711 {
712   u32 v;
713
714   v = ntohl (a->as_u32) + 1;
715   a->as_u32 = ntohl (v);
716 }
717
718 static void
719 increment_v6_address (ip6_address_t * a)
720 {
721   u64 v0, v1;
722
723   v0 = clib_net_to_host_u64 (a->as_u64[0]);
724   v1 = clib_net_to_host_u64 (a->as_u64[1]);
725
726   v1 += 1;
727   if (v1 == 0)
728     v0 += 1;
729   a->as_u64[0] = clib_net_to_host_u64 (v0);
730   a->as_u64[1] = clib_net_to_host_u64 (v1);
731 }
732
733 static void
734 increment_mac_address (u8 * mac)
735 {
736   u64 tmp = *((u64 *) mac);
737   tmp = clib_net_to_host_u64 (tmp);
738   tmp += 1 << 16;               /* skip unused (least significant) octets */
739   tmp = clib_host_to_net_u64 (tmp);
740
741   clib_memcpy (mac, &tmp, 6);
742 }
743
744 static void vl_api_create_loopback_reply_t_handler
745   (vl_api_create_loopback_reply_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   i32 retval = ntohl (mp->retval);
749
750   vam->retval = retval;
751   vam->regenerate_interface_table = 1;
752   vam->sw_if_index = ntohl (mp->sw_if_index);
753   vam->result_ready = 1;
754 }
755
756 static void vl_api_create_loopback_reply_t_handler_json
757   (vl_api_create_loopback_reply_t * mp)
758 {
759   vat_main_t *vam = &vat_main;
760   vat_json_node_t node;
761
762   vat_json_init_object (&node);
763   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
764   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
765
766   vat_json_print (vam->ofp, &node);
767   vat_json_free (&node);
768   vam->retval = ntohl (mp->retval);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_instance_reply_t_handler
773   (vl_api_create_loopback_instance_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   i32 retval = ntohl (mp->retval);
777
778   vam->retval = retval;
779   vam->regenerate_interface_table = 1;
780   vam->sw_if_index = ntohl (mp->sw_if_index);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_loopback_instance_reply_t_handler_json
785   (vl_api_create_loopback_instance_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   vat_json_node_t node;
789
790   vat_json_init_object (&node);
791   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
792   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
793
794   vat_json_print (vam->ofp, &node);
795   vat_json_free (&node);
796   vam->retval = ntohl (mp->retval);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_af_packet_create_reply_t_handler
801   (vl_api_af_packet_create_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->sw_if_index = ntohl (mp->sw_if_index);
809   vam->result_ready = 1;
810 }
811
812 static void vl_api_af_packet_create_reply_t_handler_json
813   (vl_api_af_packet_create_reply_t * mp)
814 {
815   vat_main_t *vam = &vat_main;
816   vat_json_node_t node;
817
818   vat_json_init_object (&node);
819   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
820   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
821
822   vat_json_print (vam->ofp, &node);
823   vat_json_free (&node);
824
825   vam->retval = ntohl (mp->retval);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_vlan_subif_reply_t_handler
830   (vl_api_create_vlan_subif_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   i32 retval = ntohl (mp->retval);
834
835   vam->retval = retval;
836   vam->regenerate_interface_table = 1;
837   vam->sw_if_index = ntohl (mp->sw_if_index);
838   vam->result_ready = 1;
839 }
840
841 static void vl_api_create_vlan_subif_reply_t_handler_json
842   (vl_api_create_vlan_subif_reply_t * mp)
843 {
844   vat_main_t *vam = &vat_main;
845   vat_json_node_t node;
846
847   vat_json_init_object (&node);
848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
849   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
850
851   vat_json_print (vam->ofp, &node);
852   vat_json_free (&node);
853
854   vam->retval = ntohl (mp->retval);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_subif_reply_t_handler
859   (vl_api_create_subif_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   i32 retval = ntohl (mp->retval);
863
864   vam->retval = retval;
865   vam->regenerate_interface_table = 1;
866   vam->sw_if_index = ntohl (mp->sw_if_index);
867   vam->result_ready = 1;
868 }
869
870 static void vl_api_create_subif_reply_t_handler_json
871   (vl_api_create_subif_reply_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t node;
875
876   vat_json_init_object (&node);
877   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
878   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
879
880   vat_json_print (vam->ofp, &node);
881   vat_json_free (&node);
882
883   vam->retval = ntohl (mp->retval);
884   vam->result_ready = 1;
885 }
886
887 static void vl_api_interface_name_renumber_reply_t_handler
888   (vl_api_interface_name_renumber_reply_t * mp)
889 {
890   vat_main_t *vam = &vat_main;
891   i32 retval = ntohl (mp->retval);
892
893   vam->retval = retval;
894   vam->regenerate_interface_table = 1;
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_interface_name_renumber_reply_t_handler_json
899   (vl_api_interface_name_renumber_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 /*
915  * Special-case: build the interface table, maintain
916  * the next loopback sw_if_index vbl.
917  */
918 static void vl_api_sw_interface_details_t_handler
919   (vl_api_sw_interface_details_t * mp)
920 {
921   vat_main_t *vam = &vat_main;
922   u8 *s = format (0, "%s%c", mp->interface_name, 0);
923
924   hash_set_mem (vam->sw_if_index_by_interface_name, s,
925                 ntohl (mp->sw_if_index));
926
927   /* In sub interface case, fill the sub interface table entry */
928   if (mp->sw_if_index != mp->sup_sw_if_index)
929     {
930       sw_interface_subif_t *sub = NULL;
931
932       vec_add2 (vam->sw_if_subif_table, sub, 1);
933
934       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
935       strncpy ((char *) sub->interface_name, (char *) s,
936                vec_len (sub->interface_name));
937       sub->sw_if_index = ntohl (mp->sw_if_index);
938       sub->sub_id = ntohl (mp->sub_id);
939
940       sub->sub_dot1ad = mp->sub_dot1ad;
941       sub->sub_number_of_tags = mp->sub_number_of_tags;
942       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
943       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
944       sub->sub_exact_match = mp->sub_exact_match;
945       sub->sub_default = mp->sub_default;
946       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
947       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
948
949       /* vlan tag rewrite */
950       sub->vtr_op = ntohl (mp->vtr_op);
951       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
952       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
953       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
954     }
955 }
956
957 static void vl_api_sw_interface_details_t_handler_json
958   (vl_api_sw_interface_details_t * mp)
959 {
960   vat_main_t *vam = &vat_main;
961   vat_json_node_t *node = NULL;
962
963   if (VAT_JSON_ARRAY != vam->json_tree.type)
964     {
965       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
966       vat_json_init_array (&vam->json_tree);
967     }
968   node = vat_json_array_add (&vam->json_tree);
969
970   vat_json_init_object (node);
971   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
972   vat_json_object_add_uint (node, "sup_sw_if_index",
973                             ntohl (mp->sup_sw_if_index));
974   vat_json_object_add_uint (node, "l2_address_length",
975                             ntohl (mp->l2_address_length));
976   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
977                              sizeof (mp->l2_address));
978   vat_json_object_add_string_copy (node, "interface_name",
979                                    mp->interface_name);
980   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
981   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
982   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
983   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
984   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
985   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
986   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
987   vat_json_object_add_uint (node, "sub_number_of_tags",
988                             mp->sub_number_of_tags);
989   vat_json_object_add_uint (node, "sub_outer_vlan_id",
990                             ntohs (mp->sub_outer_vlan_id));
991   vat_json_object_add_uint (node, "sub_inner_vlan_id",
992                             ntohs (mp->sub_inner_vlan_id));
993   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
994   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
995   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
996                             mp->sub_outer_vlan_id_any);
997   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
998                             mp->sub_inner_vlan_id_any);
999   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1000   vat_json_object_add_uint (node, "vtr_push_dot1q",
1001                             ntohl (mp->vtr_push_dot1q));
1002   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1003   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1004   if (mp->sub_dot1ah)
1005     {
1006       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1007                                        format (0, "%U",
1008                                                format_ethernet_address,
1009                                                &mp->b_dmac));
1010       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1011                                        format (0, "%U",
1012                                                format_ethernet_address,
1013                                                &mp->b_smac));
1014       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1015       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1016     }
1017 }
1018
1019 #if VPP_API_TEST_BUILTIN == 0
1020 static void vl_api_sw_interface_event_t_handler
1021   (vl_api_sw_interface_event_t * mp)
1022 {
1023   vat_main_t *vam = &vat_main;
1024   if (vam->interface_event_display)
1025     errmsg ("interface flags: sw_if_index %d %s %s",
1026             ntohl (mp->sw_if_index),
1027             mp->admin_up_down ? "admin-up" : "admin-down",
1028             mp->link_up_down ? "link-up" : "link-down");
1029 }
1030 #endif
1031
1032 static void vl_api_sw_interface_event_t_handler_json
1033   (vl_api_sw_interface_event_t * mp)
1034 {
1035   /* JSON output not supported */
1036 }
1037
1038 static void
1039 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1040 {
1041   vat_main_t *vam = &vat_main;
1042   i32 retval = ntohl (mp->retval);
1043
1044   vam->retval = retval;
1045   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1046   vam->result_ready = 1;
1047 }
1048
1049 static void
1050 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1051 {
1052   vat_main_t *vam = &vat_main;
1053   vat_json_node_t node;
1054   api_main_t *am = &api_main;
1055   void *oldheap;
1056   u8 *reply;
1057
1058   vat_json_init_object (&node);
1059   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1060   vat_json_object_add_uint (&node, "reply_in_shmem",
1061                             ntohl (mp->reply_in_shmem));
1062   /* Toss the shared-memory original... */
1063   pthread_mutex_lock (&am->vlib_rp->mutex);
1064   oldheap = svm_push_data_heap (am->vlib_rp);
1065
1066   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1067   vec_free (reply);
1068
1069   svm_pop_heap (oldheap);
1070   pthread_mutex_unlock (&am->vlib_rp->mutex);
1071
1072   vat_json_print (vam->ofp, &node);
1073   vat_json_free (&node);
1074
1075   vam->retval = ntohl (mp->retval);
1076   vam->result_ready = 1;
1077 }
1078
1079 static void
1080 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   i32 retval = ntohl (mp->retval);
1084   u32 length = ntohl (mp->length);
1085
1086   vec_reset_length (vam->cmd_reply);
1087
1088   vam->retval = retval;
1089   if (retval == 0)
1090     {
1091       vec_validate (vam->cmd_reply, length);
1092       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1093       vam->cmd_reply[length] = 0;
1094     }
1095   vam->result_ready = 1;
1096 }
1097
1098 static void
1099 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   vat_json_node_t node;
1103
1104   vec_reset_length (vam->cmd_reply);
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1109
1110   vat_json_print (vam->ofp, &node);
1111   vat_json_free (&node);
1112
1113   vam->retval = ntohl (mp->retval);
1114   vam->result_ready = 1;
1115 }
1116
1117 static void vl_api_classify_add_del_table_reply_t_handler
1118   (vl_api_classify_add_del_table_reply_t * mp)
1119 {
1120   vat_main_t *vam = &vat_main;
1121   i32 retval = ntohl (mp->retval);
1122   if (vam->async_mode)
1123     {
1124       vam->async_errors += (retval < 0);
1125     }
1126   else
1127     {
1128       vam->retval = retval;
1129       if (retval == 0 &&
1130           ((mp->new_table_index != 0xFFFFFFFF) ||
1131            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1132            (mp->match_n_vectors != 0xFFFFFFFF)))
1133         /*
1134          * Note: this is just barely thread-safe, depends on
1135          * the main thread spinning waiting for an answer...
1136          */
1137         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1138                 ntohl (mp->new_table_index),
1139                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1140       vam->result_ready = 1;
1141     }
1142 }
1143
1144 static void vl_api_classify_add_del_table_reply_t_handler_json
1145   (vl_api_classify_add_del_table_reply_t * mp)
1146 {
1147   vat_main_t *vam = &vat_main;
1148   vat_json_node_t node;
1149
1150   vat_json_init_object (&node);
1151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1152   vat_json_object_add_uint (&node, "new_table_index",
1153                             ntohl (mp->new_table_index));
1154   vat_json_object_add_uint (&node, "skip_n_vectors",
1155                             ntohl (mp->skip_n_vectors));
1156   vat_json_object_add_uint (&node, "match_n_vectors",
1157                             ntohl (mp->match_n_vectors));
1158
1159   vat_json_print (vam->ofp, &node);
1160   vat_json_free (&node);
1161
1162   vam->retval = ntohl (mp->retval);
1163   vam->result_ready = 1;
1164 }
1165
1166 static void vl_api_get_node_index_reply_t_handler
1167   (vl_api_get_node_index_reply_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   i32 retval = ntohl (mp->retval);
1171   if (vam->async_mode)
1172     {
1173       vam->async_errors += (retval < 0);
1174     }
1175   else
1176     {
1177       vam->retval = retval;
1178       if (retval == 0)
1179         errmsg ("node index %d", ntohl (mp->node_index));
1180       vam->result_ready = 1;
1181     }
1182 }
1183
1184 static void vl_api_get_node_index_reply_t_handler_json
1185   (vl_api_get_node_index_reply_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   vat_json_node_t node;
1189
1190   vat_json_init_object (&node);
1191   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1192   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1193
1194   vat_json_print (vam->ofp, &node);
1195   vat_json_free (&node);
1196
1197   vam->retval = ntohl (mp->retval);
1198   vam->result_ready = 1;
1199 }
1200
1201 static void vl_api_get_next_index_reply_t_handler
1202   (vl_api_get_next_index_reply_t * mp)
1203 {
1204   vat_main_t *vam = &vat_main;
1205   i32 retval = ntohl (mp->retval);
1206   if (vam->async_mode)
1207     {
1208       vam->async_errors += (retval < 0);
1209     }
1210   else
1211     {
1212       vam->retval = retval;
1213       if (retval == 0)
1214         errmsg ("next node index %d", ntohl (mp->next_index));
1215       vam->result_ready = 1;
1216     }
1217 }
1218
1219 static void vl_api_get_next_index_reply_t_handler_json
1220   (vl_api_get_next_index_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   vat_json_node_t node;
1224
1225   vat_json_init_object (&node);
1226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1227   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1228
1229   vat_json_print (vam->ofp, &node);
1230   vat_json_free (&node);
1231
1232   vam->retval = ntohl (mp->retval);
1233   vam->result_ready = 1;
1234 }
1235
1236 static void vl_api_add_node_next_reply_t_handler
1237   (vl_api_add_node_next_reply_t * mp)
1238 {
1239   vat_main_t *vam = &vat_main;
1240   i32 retval = ntohl (mp->retval);
1241   if (vam->async_mode)
1242     {
1243       vam->async_errors += (retval < 0);
1244     }
1245   else
1246     {
1247       vam->retval = retval;
1248       if (retval == 0)
1249         errmsg ("next index %d", ntohl (mp->next_index));
1250       vam->result_ready = 1;
1251     }
1252 }
1253
1254 static void vl_api_add_node_next_reply_t_handler_json
1255   (vl_api_add_node_next_reply_t * mp)
1256 {
1257   vat_main_t *vam = &vat_main;
1258   vat_json_node_t node;
1259
1260   vat_json_init_object (&node);
1261   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1262   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1263
1264   vat_json_print (vam->ofp, &node);
1265   vat_json_free (&node);
1266
1267   vam->retval = ntohl (mp->retval);
1268   vam->result_ready = 1;
1269 }
1270
1271 static void vl_api_show_version_reply_t_handler
1272   (vl_api_show_version_reply_t * mp)
1273 {
1274   vat_main_t *vam = &vat_main;
1275   i32 retval = ntohl (mp->retval);
1276
1277   if (retval >= 0)
1278     {
1279       errmsg ("        program: %s", mp->program);
1280       errmsg ("        version: %s", mp->version);
1281       errmsg ("     build date: %s", mp->build_date);
1282       errmsg ("build directory: %s", mp->build_directory);
1283     }
1284   vam->retval = retval;
1285   vam->result_ready = 1;
1286 }
1287
1288 static void vl_api_show_version_reply_t_handler_json
1289   (vl_api_show_version_reply_t * mp)
1290 {
1291   vat_main_t *vam = &vat_main;
1292   vat_json_node_t node;
1293
1294   vat_json_init_object (&node);
1295   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1296   vat_json_object_add_string_copy (&node, "program", mp->program);
1297   vat_json_object_add_string_copy (&node, "version", mp->version);
1298   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1299   vat_json_object_add_string_copy (&node, "build_directory",
1300                                    mp->build_directory);
1301
1302   vat_json_print (vam->ofp, &node);
1303   vat_json_free (&node);
1304
1305   vam->retval = ntohl (mp->retval);
1306   vam->result_ready = 1;
1307 }
1308
1309 static void
1310 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1311 {
1312   u32 sw_if_index = ntohl (mp->sw_if_index);
1313   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1314           mp->mac_ip ? "mac/ip binding" : "address resolution",
1315           ntohl (mp->pid), format_ip4_address, &mp->address,
1316           format_ethernet_address, mp->new_mac, sw_if_index);
1317 }
1318
1319 static void
1320 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1321 {
1322   /* JSON output not supported */
1323 }
1324
1325 static void
1326 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1327 {
1328   u32 sw_if_index = ntohl (mp->sw_if_index);
1329   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1330           mp->mac_ip ? "mac/ip binding" : "address resolution",
1331           ntohl (mp->pid), format_ip6_address, mp->address,
1332           format_ethernet_address, mp->new_mac, sw_if_index);
1333 }
1334
1335 static void
1336 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1337 {
1338   /* JSON output not supported */
1339 }
1340
1341 static void
1342 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1343 {
1344   u32 n_macs = ntohl (mp->n_macs);
1345   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1346           ntohl (mp->pid), mp->client_index, n_macs);
1347   int i;
1348   for (i = 0; i < n_macs; i++)
1349     {
1350       vl_api_mac_entry_t *mac = &mp->mac[i];
1351       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1352               i + 1, ntohl (mac->sw_if_index),
1353               format_ethernet_address, mac->mac_addr, mac->is_del);
1354       if (i == 1000)
1355         break;
1356     }
1357 }
1358
1359 static void
1360 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1361 {
1362   /* JSON output not supported */
1363 }
1364
1365 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1366 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1367
1368 /*
1369  * Special-case: build the bridge domain table, maintain
1370  * the next bd id vbl.
1371  */
1372 static void vl_api_bridge_domain_details_t_handler
1373   (vl_api_bridge_domain_details_t * mp)
1374 {
1375   vat_main_t *vam = &vat_main;
1376   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1377   int i;
1378
1379   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1380          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1381
1382   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1383          ntohl (mp->bd_id), mp->learn, mp->forward,
1384          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1385
1386   if (n_sw_ifs)
1387     {
1388       vl_api_bridge_domain_sw_if_t *sw_ifs;
1389       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1390              "Interface Name");
1391
1392       sw_ifs = mp->sw_if_details;
1393       for (i = 0; i < n_sw_ifs; i++)
1394         {
1395           u8 *sw_if_name = 0;
1396           u32 sw_if_index;
1397           hash_pair_t *p;
1398
1399           sw_if_index = ntohl (sw_ifs->sw_if_index);
1400
1401           /* *INDENT-OFF* */
1402           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1403                              ({
1404                                if ((u32) p->value[0] == sw_if_index)
1405                                  {
1406                                    sw_if_name = (u8 *)(p->key);
1407                                    break;
1408                                  }
1409                              }));
1410           /* *INDENT-ON* */
1411           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1412                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1413                  "sw_if_index not found!");
1414
1415           sw_ifs++;
1416         }
1417     }
1418 }
1419
1420 static void vl_api_bridge_domain_details_t_handler_json
1421   (vl_api_bridge_domain_details_t * mp)
1422 {
1423   vat_main_t *vam = &vat_main;
1424   vat_json_node_t *node, *array = NULL;
1425   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1426
1427   if (VAT_JSON_ARRAY != vam->json_tree.type)
1428     {
1429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1430       vat_json_init_array (&vam->json_tree);
1431     }
1432   node = vat_json_array_add (&vam->json_tree);
1433
1434   vat_json_init_object (node);
1435   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1436   vat_json_object_add_uint (node, "flood", mp->flood);
1437   vat_json_object_add_uint (node, "forward", mp->forward);
1438   vat_json_object_add_uint (node, "learn", mp->learn);
1439   vat_json_object_add_uint (node, "bvi_sw_if_index",
1440                             ntohl (mp->bvi_sw_if_index));
1441   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1442   array = vat_json_object_add (node, "sw_if");
1443   vat_json_init_array (array);
1444
1445
1446
1447   if (n_sw_ifs)
1448     {
1449       vl_api_bridge_domain_sw_if_t *sw_ifs;
1450       int i;
1451
1452       sw_ifs = mp->sw_if_details;
1453       for (i = 0; i < n_sw_ifs; i++)
1454         {
1455           node = vat_json_array_add (array);
1456           vat_json_init_object (node);
1457           vat_json_object_add_uint (node, "sw_if_index",
1458                                     ntohl (sw_ifs->sw_if_index));
1459           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1460           sw_ifs++;
1461         }
1462     }
1463 }
1464
1465 static void vl_api_control_ping_reply_t_handler
1466   (vl_api_control_ping_reply_t * mp)
1467 {
1468   vat_main_t *vam = &vat_main;
1469   i32 retval = ntohl (mp->retval);
1470   if (vam->async_mode)
1471     {
1472       vam->async_errors += (retval < 0);
1473     }
1474   else
1475     {
1476       vam->retval = retval;
1477       vam->result_ready = 1;
1478     }
1479   if (vam->socket_client_main)
1480     vam->socket_client_main->control_pings_outstanding--;
1481 }
1482
1483 static void vl_api_control_ping_reply_t_handler_json
1484   (vl_api_control_ping_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488
1489   if (VAT_JSON_NONE != vam->json_tree.type)
1490     {
1491       vat_json_print (vam->ofp, &vam->json_tree);
1492       vat_json_free (&vam->json_tree);
1493       vam->json_tree.type = VAT_JSON_NONE;
1494     }
1495   else
1496     {
1497       /* just print [] */
1498       vat_json_init_array (&vam->json_tree);
1499       vat_json_print (vam->ofp, &vam->json_tree);
1500       vam->json_tree.type = VAT_JSON_NONE;
1501     }
1502
1503   vam->retval = retval;
1504   vam->result_ready = 1;
1505 }
1506
1507 static void
1508   vl_api_bridge_domain_set_mac_age_reply_t_handler
1509   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1510 {
1511   vat_main_t *vam = &vat_main;
1512   i32 retval = ntohl (mp->retval);
1513   if (vam->async_mode)
1514     {
1515       vam->async_errors += (retval < 0);
1516     }
1517   else
1518     {
1519       vam->retval = retval;
1520       vam->result_ready = 1;
1521     }
1522 }
1523
1524 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1525   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   vat_json_node_t node;
1529
1530   vat_json_init_object (&node);
1531   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540 static void
1541 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   i32 retval = ntohl (mp->retval);
1545   if (vam->async_mode)
1546     {
1547       vam->async_errors += (retval < 0);
1548     }
1549   else
1550     {
1551       vam->retval = retval;
1552       vam->result_ready = 1;
1553     }
1554 }
1555
1556 static void vl_api_l2_flags_reply_t_handler_json
1557   (vl_api_l2_flags_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   vat_json_node_t node;
1561
1562   vat_json_init_object (&node);
1563   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1564   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1565                             ntohl (mp->resulting_feature_bitmap));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574 static void vl_api_bridge_flags_reply_t_handler
1575   (vl_api_bridge_flags_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->result_ready = 1;
1587     }
1588 }
1589
1590 static void vl_api_bridge_flags_reply_t_handler_json
1591   (vl_api_bridge_flags_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   vat_json_node_t node;
1595
1596   vat_json_init_object (&node);
1597   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1598   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1599                             ntohl (mp->resulting_feature_bitmap));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_tap_connect_reply_t_handler
1609   (vl_api_tap_connect_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623
1624 }
1625
1626 static void vl_api_tap_connect_reply_t_handler_json
1627   (vl_api_tap_connect_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   vat_json_node_t node;
1631
1632   vat_json_init_object (&node);
1633   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1634   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1635
1636   vat_json_print (vam->ofp, &node);
1637   vat_json_free (&node);
1638
1639   vam->retval = ntohl (mp->retval);
1640   vam->result_ready = 1;
1641
1642 }
1643
1644 static void
1645 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   i32 retval = ntohl (mp->retval);
1649   if (vam->async_mode)
1650     {
1651       vam->async_errors += (retval < 0);
1652     }
1653   else
1654     {
1655       vam->retval = retval;
1656       vam->sw_if_index = ntohl (mp->sw_if_index);
1657       vam->result_ready = 1;
1658     }
1659 }
1660
1661 static void vl_api_tap_modify_reply_t_handler_json
1662   (vl_api_tap_modify_reply_t * mp)
1663 {
1664   vat_main_t *vam = &vat_main;
1665   vat_json_node_t node;
1666
1667   vat_json_init_object (&node);
1668   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1669   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1670
1671   vat_json_print (vam->ofp, &node);
1672   vat_json_free (&node);
1673
1674   vam->retval = ntohl (mp->retval);
1675   vam->result_ready = 1;
1676 }
1677
1678 static void
1679 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1680 {
1681   vat_main_t *vam = &vat_main;
1682   i32 retval = ntohl (mp->retval);
1683   if (vam->async_mode)
1684     {
1685       vam->async_errors += (retval < 0);
1686     }
1687   else
1688     {
1689       vam->retval = retval;
1690       vam->result_ready = 1;
1691     }
1692 }
1693
1694 static void vl_api_tap_delete_reply_t_handler_json
1695   (vl_api_tap_delete_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   vat_json_node_t node;
1699
1700   vat_json_init_object (&node);
1701   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1702
1703   vat_json_print (vam->ofp, &node);
1704   vat_json_free (&node);
1705
1706   vam->retval = ntohl (mp->retval);
1707   vam->result_ready = 1;
1708 }
1709
1710 static void
1711 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   i32 retval = ntohl (mp->retval);
1715   if (vam->async_mode)
1716     {
1717       vam->async_errors += (retval < 0);
1718     }
1719   else
1720     {
1721       vam->retval = retval;
1722       vam->sw_if_index = ntohl (mp->sw_if_index);
1723       vam->result_ready = 1;
1724     }
1725
1726 }
1727
1728 static void vl_api_tap_create_v2_reply_t_handler_json
1729   (vl_api_tap_create_v2_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   vat_json_node_t node;
1733
1734   vat_json_init_object (&node);
1735   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1736   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1737
1738   vat_json_print (vam->ofp, &node);
1739   vat_json_free (&node);
1740
1741   vam->retval = ntohl (mp->retval);
1742   vam->result_ready = 1;
1743
1744 }
1745
1746 static void
1747 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   i32 retval = ntohl (mp->retval);
1751   if (vam->async_mode)
1752     {
1753       vam->async_errors += (retval < 0);
1754     }
1755   else
1756     {
1757       vam->retval = retval;
1758       vam->result_ready = 1;
1759     }
1760 }
1761
1762 static void vl_api_tap_delete_v2_reply_t_handler_json
1763   (vl_api_tap_delete_v2_reply_t * mp)
1764 {
1765   vat_main_t *vam = &vat_main;
1766   vat_json_node_t node;
1767
1768   vat_json_init_object (&node);
1769   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1770
1771   vat_json_print (vam->ofp, &node);
1772   vat_json_free (&node);
1773
1774   vam->retval = ntohl (mp->retval);
1775   vam->result_ready = 1;
1776 }
1777
1778 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1779   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   i32 retval = ntohl (mp->retval);
1783   if (vam->async_mode)
1784     {
1785       vam->async_errors += (retval < 0);
1786     }
1787   else
1788     {
1789       vam->retval = retval;
1790       vam->result_ready = 1;
1791     }
1792 }
1793
1794 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1795   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1796 {
1797   vat_main_t *vam = &vat_main;
1798   vat_json_node_t node;
1799
1800   vat_json_init_object (&node);
1801   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1802   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1803                             ntohl (mp->sw_if_index));
1804
1805   vat_json_print (vam->ofp, &node);
1806   vat_json_free (&node);
1807
1808   vam->retval = ntohl (mp->retval);
1809   vam->result_ready = 1;
1810 }
1811
1812 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1813   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1814 {
1815   vat_main_t *vam = &vat_main;
1816   i32 retval = ntohl (mp->retval);
1817   if (vam->async_mode)
1818     {
1819       vam->async_errors += (retval < 0);
1820     }
1821   else
1822     {
1823       vam->retval = retval;
1824       vam->sw_if_index = ntohl (mp->sw_if_index);
1825       vam->result_ready = 1;
1826     }
1827 }
1828
1829 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1830   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1831 {
1832   vat_main_t *vam = &vat_main;
1833   vat_json_node_t node;
1834
1835   vat_json_init_object (&node);
1836   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1837   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1838
1839   vat_json_print (vam->ofp, &node);
1840   vat_json_free (&node);
1841
1842   vam->retval = ntohl (mp->retval);
1843   vam->result_ready = 1;
1844 }
1845
1846 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1847   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   i32 retval = ntohl (mp->retval);
1851   if (vam->async_mode)
1852     {
1853       vam->async_errors += (retval < 0);
1854     }
1855   else
1856     {
1857       vam->retval = retval;
1858       vam->result_ready = 1;
1859     }
1860 }
1861
1862 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1863   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1864 {
1865   vat_main_t *vam = &vat_main;
1866   vat_json_node_t node;
1867
1868   vat_json_init_object (&node);
1869   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1870   vat_json_object_add_uint (&node, "fwd_entry_index",
1871                             clib_net_to_host_u32 (mp->fwd_entry_index));
1872
1873   vat_json_print (vam->ofp, &node);
1874   vat_json_free (&node);
1875
1876   vam->retval = ntohl (mp->retval);
1877   vam->result_ready = 1;
1878 }
1879
1880 u8 *
1881 format_lisp_transport_protocol (u8 * s, va_list * args)
1882 {
1883   u32 proto = va_arg (*args, u32);
1884
1885   switch (proto)
1886     {
1887     case 1:
1888       return format (s, "udp");
1889     case 2:
1890       return format (s, "api");
1891     default:
1892       return 0;
1893     }
1894   return 0;
1895 }
1896
1897 static void vl_api_one_get_transport_protocol_reply_t_handler
1898   (vl_api_one_get_transport_protocol_reply_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   i32 retval = ntohl (mp->retval);
1902   if (vam->async_mode)
1903     {
1904       vam->async_errors += (retval < 0);
1905     }
1906   else
1907     {
1908       u32 proto = mp->protocol;
1909       print (vam->ofp, "Transport protocol: %U",
1910              format_lisp_transport_protocol, proto);
1911       vam->retval = retval;
1912       vam->result_ready = 1;
1913     }
1914 }
1915
1916 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1917   (vl_api_one_get_transport_protocol_reply_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   vat_json_node_t node;
1921   u8 *s;
1922
1923   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1924   vec_add1 (s, 0);
1925
1926   vat_json_init_object (&node);
1927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1928   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1929
1930   vec_free (s);
1931   vat_json_print (vam->ofp, &node);
1932   vat_json_free (&node);
1933
1934   vam->retval = ntohl (mp->retval);
1935   vam->result_ready = 1;
1936 }
1937
1938 static void vl_api_one_add_del_locator_set_reply_t_handler
1939   (vl_api_one_add_del_locator_set_reply_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   i32 retval = ntohl (mp->retval);
1943   if (vam->async_mode)
1944     {
1945       vam->async_errors += (retval < 0);
1946     }
1947   else
1948     {
1949       vam->retval = retval;
1950       vam->result_ready = 1;
1951     }
1952 }
1953
1954 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1955   (vl_api_one_add_del_locator_set_reply_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958   vat_json_node_t node;
1959
1960   vat_json_init_object (&node);
1961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1962   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1963
1964   vat_json_print (vam->ofp, &node);
1965   vat_json_free (&node);
1966
1967   vam->retval = ntohl (mp->retval);
1968   vam->result_ready = 1;
1969 }
1970
1971 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1972   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1973 {
1974   vat_main_t *vam = &vat_main;
1975   i32 retval = ntohl (mp->retval);
1976   if (vam->async_mode)
1977     {
1978       vam->async_errors += (retval < 0);
1979     }
1980   else
1981     {
1982       vam->retval = retval;
1983       vam->sw_if_index = ntohl (mp->sw_if_index);
1984       vam->result_ready = 1;
1985     }
1986 }
1987
1988 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1989   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1990 {
1991   vat_main_t *vam = &vat_main;
1992   vat_json_node_t node;
1993
1994   vat_json_init_object (&node);
1995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1996   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1997
1998   vat_json_print (vam->ofp, &node);
1999   vat_json_free (&node);
2000
2001   vam->retval = ntohl (mp->retval);
2002   vam->result_ready = 1;
2003 }
2004
2005 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2006   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2007 {
2008   vat_main_t *vam = &vat_main;
2009   i32 retval = ntohl (mp->retval);
2010   if (vam->async_mode)
2011     {
2012       vam->async_errors += (retval < 0);
2013     }
2014   else
2015     {
2016       vam->retval = retval;
2017       vam->sw_if_index = ntohl (mp->sw_if_index);
2018       vam->result_ready = 1;
2019     }
2020 }
2021
2022 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2023   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2024 {
2025   vat_main_t *vam = &vat_main;
2026   vat_json_node_t node;
2027
2028   vat_json_init_object (&node);
2029   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2030   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2031
2032   vat_json_print (vam->ofp, &node);
2033   vat_json_free (&node);
2034
2035   vam->retval = ntohl (mp->retval);
2036   vam->result_ready = 1;
2037 }
2038
2039 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2040   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2041 {
2042   vat_main_t *vam = &vat_main;
2043   i32 retval = ntohl (mp->retval);
2044   if (vam->async_mode)
2045     {
2046       vam->async_errors += (retval < 0);
2047     }
2048   else
2049     {
2050       vam->retval = retval;
2051       vam->sw_if_index = ntohl (mp->sw_if_index);
2052       vam->result_ready = 1;
2053     }
2054 }
2055
2056 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2057   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2058 {
2059   vat_main_t *vam = &vat_main;
2060   vat_json_node_t node;
2061
2062   vat_json_init_object (&node);
2063   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2064   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2065
2066   vat_json_print (vam->ofp, &node);
2067   vat_json_free (&node);
2068
2069   vam->retval = ntohl (mp->retval);
2070   vam->result_ready = 1;
2071 }
2072
2073 static void vl_api_gre_add_del_tunnel_reply_t_handler
2074   (vl_api_gre_add_del_tunnel_reply_t * mp)
2075 {
2076   vat_main_t *vam = &vat_main;
2077   i32 retval = ntohl (mp->retval);
2078   if (vam->async_mode)
2079     {
2080       vam->async_errors += (retval < 0);
2081     }
2082   else
2083     {
2084       vam->retval = retval;
2085       vam->sw_if_index = ntohl (mp->sw_if_index);
2086       vam->result_ready = 1;
2087     }
2088 }
2089
2090 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2091   (vl_api_gre_add_del_tunnel_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   vat_json_node_t node;
2095
2096   vat_json_init_object (&node);
2097   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2098   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2099
2100   vat_json_print (vam->ofp, &node);
2101   vat_json_free (&node);
2102
2103   vam->retval = ntohl (mp->retval);
2104   vam->result_ready = 1;
2105 }
2106
2107 static void vl_api_create_vhost_user_if_reply_t_handler
2108   (vl_api_create_vhost_user_if_reply_t * mp)
2109 {
2110   vat_main_t *vam = &vat_main;
2111   i32 retval = ntohl (mp->retval);
2112   if (vam->async_mode)
2113     {
2114       vam->async_errors += (retval < 0);
2115     }
2116   else
2117     {
2118       vam->retval = retval;
2119       vam->sw_if_index = ntohl (mp->sw_if_index);
2120       vam->result_ready = 1;
2121     }
2122 }
2123
2124 static void vl_api_create_vhost_user_if_reply_t_handler_json
2125   (vl_api_create_vhost_user_if_reply_t * mp)
2126 {
2127   vat_main_t *vam = &vat_main;
2128   vat_json_node_t node;
2129
2130   vat_json_init_object (&node);
2131   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2132   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2133
2134   vat_json_print (vam->ofp, &node);
2135   vat_json_free (&node);
2136
2137   vam->retval = ntohl (mp->retval);
2138   vam->result_ready = 1;
2139 }
2140
2141 static clib_error_t *
2142 receive_fd_msg (int socket_fd, int *my_fd)
2143 {
2144   char msgbuf[16];
2145   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2146   struct msghdr mh = { 0 };
2147   struct iovec iov[1];
2148   ssize_t size;
2149   struct ucred *cr = 0;
2150   struct cmsghdr *cmsg;
2151   pid_t pid __attribute__ ((unused));
2152   uid_t uid __attribute__ ((unused));
2153   gid_t gid __attribute__ ((unused));
2154
2155   iov[0].iov_base = msgbuf;
2156   iov[0].iov_len = 5;
2157   mh.msg_iov = iov;
2158   mh.msg_iovlen = 1;
2159   mh.msg_control = ctl;
2160   mh.msg_controllen = sizeof (ctl);
2161
2162   memset (ctl, 0, sizeof (ctl));
2163
2164   /* receive the incoming message */
2165   size = recvmsg (socket_fd, &mh, 0);
2166   if (size != 5)
2167     {
2168       return (size == 0) ? clib_error_return (0, "disconnected") :
2169         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2170                                 socket_fd);
2171     }
2172
2173   cmsg = CMSG_FIRSTHDR (&mh);
2174   while (cmsg)
2175     {
2176       if (cmsg->cmsg_level == SOL_SOCKET)
2177         {
2178           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2179             {
2180               cr = (struct ucred *) CMSG_DATA (cmsg);
2181               uid = cr->uid;
2182               gid = cr->gid;
2183               pid = cr->pid;
2184             }
2185           else if (cmsg->cmsg_type == SCM_RIGHTS)
2186             {
2187               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2188             }
2189         }
2190       cmsg = CMSG_NXTHDR (&mh, cmsg);
2191     }
2192   return 0;
2193 }
2194
2195 static void vl_api_memfd_segment_create_reply_t_handler
2196   (vl_api_memfd_segment_create_reply_t * mp)
2197 {
2198   /* Dont bother in the builtin version */
2199 #if VPP_API_TEST_BUILTIN == 0
2200   vat_main_t *vam = &vat_main;
2201   api_main_t *am = &api_main;
2202   socket_client_main_t *scm = vam->socket_client_main;
2203   int my_fd = -1;
2204   clib_error_t *error;
2205   ssvm_private_t memfd;
2206   i32 retval = ntohl (mp->retval);
2207
2208   if (retval == 0)
2209     {
2210       error = receive_fd_msg (scm->socket_fd, &my_fd);
2211       if (error)
2212         {
2213           retval = -99;
2214           goto out;
2215         }
2216
2217       memset (&memfd, 0, sizeof (memfd));
2218       memfd.fd = my_fd;
2219
2220       vam->client_index_invalid = 1;
2221
2222       /* Note: this closes memfd.fd */
2223       retval = ssvm_slave_init_memfd (&memfd);
2224       if (retval)
2225         clib_warning ("WARNING: segment map returned %d", retval);
2226
2227       /* Pivot to the memory client segment that vpp just created */
2228
2229       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2230
2231       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2232
2233       vl_client_install_client_message_handlers ();
2234
2235       vl_client_connect_to_vlib_no_map ("pvt",
2236                                         "vpp_api_test(p)",
2237                                         32 /* input_queue_length */ );
2238       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2239
2240       vl_socket_client_enable_disable (0 /* disable socket */ );
2241     }
2242
2243 out:
2244   if (vam->async_mode)
2245     {
2246       vam->async_errors += (retval < 0);
2247     }
2248   else
2249     {
2250       vam->retval = retval;
2251       vam->result_ready = 1;
2252     }
2253 #endif
2254 }
2255
2256 static void vl_api_memfd_segment_create_reply_t_handler_json
2257   (vl_api_memfd_segment_create_reply_t * mp)
2258 {
2259   clib_warning ("no");
2260 }
2261
2262 static void vl_api_dns_resolve_name_reply_t_handler
2263   (vl_api_dns_resolve_name_reply_t * mp)
2264 {
2265   vat_main_t *vam = &vat_main;
2266   i32 retval = ntohl (mp->retval);
2267   if (vam->async_mode)
2268     {
2269       vam->async_errors += (retval < 0);
2270     }
2271   else
2272     {
2273       vam->retval = retval;
2274       vam->result_ready = 1;
2275
2276       if (retval == 0)
2277         {
2278           if (mp->ip4_set)
2279             clib_warning ("ip4 address %U", format_ip4_address,
2280                           (ip4_address_t *) mp->ip4_address);
2281           if (mp->ip6_set)
2282             clib_warning ("ip6 address %U", format_ip6_address,
2283                           (ip6_address_t *) mp->ip6_address);
2284         }
2285       else
2286         clib_warning ("retval %d", retval);
2287     }
2288 }
2289
2290 static void vl_api_dns_resolve_name_reply_t_handler_json
2291   (vl_api_dns_resolve_name_reply_t * mp)
2292 {
2293   clib_warning ("not implemented");
2294 }
2295
2296 static void vl_api_dns_resolve_ip_reply_t_handler
2297   (vl_api_dns_resolve_ip_reply_t * mp)
2298 {
2299   vat_main_t *vam = &vat_main;
2300   i32 retval = ntohl (mp->retval);
2301   if (vam->async_mode)
2302     {
2303       vam->async_errors += (retval < 0);
2304     }
2305   else
2306     {
2307       vam->retval = retval;
2308       vam->result_ready = 1;
2309
2310       if (retval == 0)
2311         {
2312           clib_warning ("canonical name %s", mp->name);
2313         }
2314       else
2315         clib_warning ("retval %d", retval);
2316     }
2317 }
2318
2319 static void vl_api_dns_resolve_ip_reply_t_handler_json
2320   (vl_api_dns_resolve_ip_reply_t * mp)
2321 {
2322   clib_warning ("not implemented");
2323 }
2324
2325
2326 static void vl_api_ip_address_details_t_handler
2327   (vl_api_ip_address_details_t * mp)
2328 {
2329   vat_main_t *vam = &vat_main;
2330   static ip_address_details_t empty_ip_address_details = { {0} };
2331   ip_address_details_t *address = NULL;
2332   ip_details_t *current_ip_details = NULL;
2333   ip_details_t *details = NULL;
2334
2335   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2336
2337   if (!details || vam->current_sw_if_index >= vec_len (details)
2338       || !details[vam->current_sw_if_index].present)
2339     {
2340       errmsg ("ip address details arrived but not stored");
2341       errmsg ("ip_dump should be called first");
2342       return;
2343     }
2344
2345   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2346
2347 #define addresses (current_ip_details->addr)
2348
2349   vec_validate_init_empty (addresses, vec_len (addresses),
2350                            empty_ip_address_details);
2351
2352   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2353
2354   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2355   address->prefix_length = mp->prefix_length;
2356 #undef addresses
2357 }
2358
2359 static void vl_api_ip_address_details_t_handler_json
2360   (vl_api_ip_address_details_t * mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   vat_json_node_t *node = NULL;
2364   struct in6_addr ip6;
2365   struct in_addr ip4;
2366
2367   if (VAT_JSON_ARRAY != vam->json_tree.type)
2368     {
2369       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2370       vat_json_init_array (&vam->json_tree);
2371     }
2372   node = vat_json_array_add (&vam->json_tree);
2373
2374   vat_json_init_object (node);
2375   if (vam->is_ipv6)
2376     {
2377       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2378       vat_json_object_add_ip6 (node, "ip", ip6);
2379     }
2380   else
2381     {
2382       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2383       vat_json_object_add_ip4 (node, "ip", ip4);
2384     }
2385   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2386 }
2387
2388 static void
2389 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2390 {
2391   vat_main_t *vam = &vat_main;
2392   static ip_details_t empty_ip_details = { 0 };
2393   ip_details_t *ip = NULL;
2394   u32 sw_if_index = ~0;
2395
2396   sw_if_index = ntohl (mp->sw_if_index);
2397
2398   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2399                            sw_if_index, empty_ip_details);
2400
2401   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2402                          sw_if_index);
2403
2404   ip->present = 1;
2405 }
2406
2407 static void
2408 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411
2412   if (VAT_JSON_ARRAY != vam->json_tree.type)
2413     {
2414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2415       vat_json_init_array (&vam->json_tree);
2416     }
2417   vat_json_array_add_uint (&vam->json_tree,
2418                            clib_net_to_host_u32 (mp->sw_if_index));
2419 }
2420
2421 static void vl_api_map_domain_details_t_handler_json
2422   (vl_api_map_domain_details_t * mp)
2423 {
2424   vat_json_node_t *node = NULL;
2425   vat_main_t *vam = &vat_main;
2426   struct in6_addr ip6;
2427   struct in_addr ip4;
2428
2429   if (VAT_JSON_ARRAY != vam->json_tree.type)
2430     {
2431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2432       vat_json_init_array (&vam->json_tree);
2433     }
2434
2435   node = vat_json_array_add (&vam->json_tree);
2436   vat_json_init_object (node);
2437
2438   vat_json_object_add_uint (node, "domain_index",
2439                             clib_net_to_host_u32 (mp->domain_index));
2440   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2441   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2442   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2443   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2444   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2445   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2446   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2447   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2448   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2449   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2450   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2451   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2452   vat_json_object_add_uint (node, "flags", mp->flags);
2453   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2454   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2455 }
2456
2457 static void vl_api_map_domain_details_t_handler
2458   (vl_api_map_domain_details_t * mp)
2459 {
2460   vat_main_t *vam = &vat_main;
2461
2462   if (mp->is_translation)
2463     {
2464       print (vam->ofp,
2465              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2466              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2467              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2468              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2469              clib_net_to_host_u32 (mp->domain_index));
2470     }
2471   else
2472     {
2473       print (vam->ofp,
2474              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2475              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2476              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2477              format_ip6_address, mp->ip6_src,
2478              clib_net_to_host_u32 (mp->domain_index));
2479     }
2480   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2481          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2482          mp->is_translation ? "map-t" : "");
2483 }
2484
2485 static void vl_api_map_rule_details_t_handler_json
2486   (vl_api_map_rule_details_t * mp)
2487 {
2488   struct in6_addr ip6;
2489   vat_json_node_t *node = NULL;
2490   vat_main_t *vam = &vat_main;
2491
2492   if (VAT_JSON_ARRAY != vam->json_tree.type)
2493     {
2494       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2495       vat_json_init_array (&vam->json_tree);
2496     }
2497
2498   node = vat_json_array_add (&vam->json_tree);
2499   vat_json_init_object (node);
2500
2501   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2502   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2503   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2504 }
2505
2506 static void
2507 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2508 {
2509   vat_main_t *vam = &vat_main;
2510   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2511          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2512 }
2513
2514 static void
2515 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2516 {
2517   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2518           "router_addr %U host_mac %U",
2519           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2520           format_ip4_address, &mp->host_address,
2521           format_ip4_address, &mp->router_address,
2522           format_ethernet_address, mp->host_mac);
2523 }
2524
2525 static void vl_api_dhcp_compl_event_t_handler_json
2526   (vl_api_dhcp_compl_event_t * mp)
2527 {
2528   /* JSON output not supported */
2529 }
2530
2531 static void
2532 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2533                               u32 counter)
2534 {
2535   vat_main_t *vam = &vat_main;
2536   static u64 default_counter = 0;
2537
2538   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2539                            NULL);
2540   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2541                            sw_if_index, default_counter);
2542   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2543 }
2544
2545 static void
2546 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2547                                 interface_counter_t counter)
2548 {
2549   vat_main_t *vam = &vat_main;
2550   static interface_counter_t default_counter = { 0, };
2551
2552   vec_validate_init_empty (vam->combined_interface_counters,
2553                            vnet_counter_type, NULL);
2554   vec_validate_init_empty (vam->combined_interface_counters
2555                            [vnet_counter_type], sw_if_index, default_counter);
2556   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2557 }
2558
2559 static void vl_api_vnet_interface_simple_counters_t_handler
2560   (vl_api_vnet_interface_simple_counters_t * mp)
2561 {
2562   /* not supported */
2563 }
2564
2565 static void vl_api_vnet_interface_combined_counters_t_handler
2566   (vl_api_vnet_interface_combined_counters_t * mp)
2567 {
2568   /* not supported */
2569 }
2570
2571 static void vl_api_vnet_interface_simple_counters_t_handler_json
2572   (vl_api_vnet_interface_simple_counters_t * mp)
2573 {
2574   u64 *v_packets;
2575   u64 packets;
2576   u32 count;
2577   u32 first_sw_if_index;
2578   int i;
2579
2580   count = ntohl (mp->count);
2581   first_sw_if_index = ntohl (mp->first_sw_if_index);
2582
2583   v_packets = (u64 *) & mp->data;
2584   for (i = 0; i < count; i++)
2585     {
2586       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2587       set_simple_interface_counter (mp->vnet_counter_type,
2588                                     first_sw_if_index + i, packets);
2589       v_packets++;
2590     }
2591 }
2592
2593 static void vl_api_vnet_interface_combined_counters_t_handler_json
2594   (vl_api_vnet_interface_combined_counters_t * mp)
2595 {
2596   interface_counter_t counter;
2597   vlib_counter_t *v;
2598   u32 first_sw_if_index;
2599   int i;
2600   u32 count;
2601
2602   count = ntohl (mp->count);
2603   first_sw_if_index = ntohl (mp->first_sw_if_index);
2604
2605   v = (vlib_counter_t *) & mp->data;
2606   for (i = 0; i < count; i++)
2607     {
2608       counter.packets =
2609         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2610       counter.bytes =
2611         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2612       set_combined_interface_counter (mp->vnet_counter_type,
2613                                       first_sw_if_index + i, counter);
2614       v++;
2615     }
2616 }
2617
2618 static u32
2619 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2620 {
2621   vat_main_t *vam = &vat_main;
2622   u32 i;
2623
2624   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2625     {
2626       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2627         {
2628           return i;
2629         }
2630     }
2631   return ~0;
2632 }
2633
2634 static u32
2635 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2636 {
2637   vat_main_t *vam = &vat_main;
2638   u32 i;
2639
2640   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2641     {
2642       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2643         {
2644           return i;
2645         }
2646     }
2647   return ~0;
2648 }
2649
2650 static void vl_api_vnet_ip4_fib_counters_t_handler
2651   (vl_api_vnet_ip4_fib_counters_t * mp)
2652 {
2653   /* not supported */
2654 }
2655
2656 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2657   (vl_api_vnet_ip4_fib_counters_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vl_api_ip4_fib_counter_t *v;
2661   ip4_fib_counter_t *counter;
2662   struct in_addr ip4;
2663   u32 vrf_id;
2664   u32 vrf_index;
2665   u32 count;
2666   int i;
2667
2668   vrf_id = ntohl (mp->vrf_id);
2669   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2670   if (~0 == vrf_index)
2671     {
2672       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2673       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2674       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2675       vec_validate (vam->ip4_fib_counters, vrf_index);
2676       vam->ip4_fib_counters[vrf_index] = NULL;
2677     }
2678
2679   vec_free (vam->ip4_fib_counters[vrf_index]);
2680   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2681   count = ntohl (mp->count);
2682   for (i = 0; i < count; i++)
2683     {
2684       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2685       counter = &vam->ip4_fib_counters[vrf_index][i];
2686       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2687       counter->address = ip4;
2688       counter->address_length = v->address_length;
2689       counter->packets = clib_net_to_host_u64 (v->packets);
2690       counter->bytes = clib_net_to_host_u64 (v->bytes);
2691       v++;
2692     }
2693 }
2694
2695 static void vl_api_vnet_ip4_nbr_counters_t_handler
2696   (vl_api_vnet_ip4_nbr_counters_t * mp)
2697 {
2698   /* not supported */
2699 }
2700
2701 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2702   (vl_api_vnet_ip4_nbr_counters_t * mp)
2703 {
2704   vat_main_t *vam = &vat_main;
2705   vl_api_ip4_nbr_counter_t *v;
2706   ip4_nbr_counter_t *counter;
2707   u32 sw_if_index;
2708   u32 count;
2709   int i;
2710
2711   sw_if_index = ntohl (mp->sw_if_index);
2712   count = ntohl (mp->count);
2713   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2714
2715   if (mp->begin)
2716     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2717
2718   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2719   for (i = 0; i < count; i++)
2720     {
2721       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2722       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2723       counter->address.s_addr = v->address;
2724       counter->packets = clib_net_to_host_u64 (v->packets);
2725       counter->bytes = clib_net_to_host_u64 (v->bytes);
2726       counter->linkt = v->link_type;
2727       v++;
2728     }
2729 }
2730
2731 static void vl_api_vnet_ip6_fib_counters_t_handler
2732   (vl_api_vnet_ip6_fib_counters_t * mp)
2733 {
2734   /* not supported */
2735 }
2736
2737 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2738   (vl_api_vnet_ip6_fib_counters_t * mp)
2739 {
2740   vat_main_t *vam = &vat_main;
2741   vl_api_ip6_fib_counter_t *v;
2742   ip6_fib_counter_t *counter;
2743   struct in6_addr ip6;
2744   u32 vrf_id;
2745   u32 vrf_index;
2746   u32 count;
2747   int i;
2748
2749   vrf_id = ntohl (mp->vrf_id);
2750   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2751   if (~0 == vrf_index)
2752     {
2753       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2754       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2755       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2756       vec_validate (vam->ip6_fib_counters, vrf_index);
2757       vam->ip6_fib_counters[vrf_index] = NULL;
2758     }
2759
2760   vec_free (vam->ip6_fib_counters[vrf_index]);
2761   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2762   count = ntohl (mp->count);
2763   for (i = 0; i < count; i++)
2764     {
2765       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2766       counter = &vam->ip6_fib_counters[vrf_index][i];
2767       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2768       counter->address = ip6;
2769       counter->address_length = v->address_length;
2770       counter->packets = clib_net_to_host_u64 (v->packets);
2771       counter->bytes = clib_net_to_host_u64 (v->bytes);
2772       v++;
2773     }
2774 }
2775
2776 static void vl_api_vnet_ip6_nbr_counters_t_handler
2777   (vl_api_vnet_ip6_nbr_counters_t * mp)
2778 {
2779   /* not supported */
2780 }
2781
2782 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2783   (vl_api_vnet_ip6_nbr_counters_t * mp)
2784 {
2785   vat_main_t *vam = &vat_main;
2786   vl_api_ip6_nbr_counter_t *v;
2787   ip6_nbr_counter_t *counter;
2788   struct in6_addr ip6;
2789   u32 sw_if_index;
2790   u32 count;
2791   int i;
2792
2793   sw_if_index = ntohl (mp->sw_if_index);
2794   count = ntohl (mp->count);
2795   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2796
2797   if (mp->begin)
2798     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2799
2800   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2801   for (i = 0; i < count; i++)
2802     {
2803       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2804       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2805       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2806       counter->address = ip6;
2807       counter->packets = clib_net_to_host_u64 (v->packets);
2808       counter->bytes = clib_net_to_host_u64 (v->bytes);
2809       v++;
2810     }
2811 }
2812
2813 static void vl_api_get_first_msg_id_reply_t_handler
2814   (vl_api_get_first_msg_id_reply_t * mp)
2815 {
2816   vat_main_t *vam = &vat_main;
2817   i32 retval = ntohl (mp->retval);
2818
2819   if (vam->async_mode)
2820     {
2821       vam->async_errors += (retval < 0);
2822     }
2823   else
2824     {
2825       vam->retval = retval;
2826       vam->result_ready = 1;
2827     }
2828   if (retval >= 0)
2829     {
2830       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2831     }
2832 }
2833
2834 static void vl_api_get_first_msg_id_reply_t_handler_json
2835   (vl_api_get_first_msg_id_reply_t * mp)
2836 {
2837   vat_main_t *vam = &vat_main;
2838   vat_json_node_t node;
2839
2840   vat_json_init_object (&node);
2841   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2842   vat_json_object_add_uint (&node, "first_msg_id",
2843                             (uint) ntohs (mp->first_msg_id));
2844
2845   vat_json_print (vam->ofp, &node);
2846   vat_json_free (&node);
2847
2848   vam->retval = ntohl (mp->retval);
2849   vam->result_ready = 1;
2850 }
2851
2852 static void vl_api_get_node_graph_reply_t_handler
2853   (vl_api_get_node_graph_reply_t * mp)
2854 {
2855   vat_main_t *vam = &vat_main;
2856   api_main_t *am = &api_main;
2857   i32 retval = ntohl (mp->retval);
2858   u8 *pvt_copy, *reply;
2859   void *oldheap;
2860   vlib_node_t *node;
2861   int i;
2862
2863   if (vam->async_mode)
2864     {
2865       vam->async_errors += (retval < 0);
2866     }
2867   else
2868     {
2869       vam->retval = retval;
2870       vam->result_ready = 1;
2871     }
2872
2873   /* "Should never happen..." */
2874   if (retval != 0)
2875     return;
2876
2877   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2878   pvt_copy = vec_dup (reply);
2879
2880   /* Toss the shared-memory original... */
2881   pthread_mutex_lock (&am->vlib_rp->mutex);
2882   oldheap = svm_push_data_heap (am->vlib_rp);
2883
2884   vec_free (reply);
2885
2886   svm_pop_heap (oldheap);
2887   pthread_mutex_unlock (&am->vlib_rp->mutex);
2888
2889   if (vam->graph_nodes)
2890     {
2891       hash_free (vam->graph_node_index_by_name);
2892
2893       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2894         {
2895           node = vam->graph_nodes[i];
2896           vec_free (node->name);
2897           vec_free (node->next_nodes);
2898           vec_free (node);
2899         }
2900       vec_free (vam->graph_nodes);
2901     }
2902
2903   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2904   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2905   vec_free (pvt_copy);
2906
2907   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2908     {
2909       node = vam->graph_nodes[i];
2910       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2911     }
2912 }
2913
2914 static void vl_api_get_node_graph_reply_t_handler_json
2915   (vl_api_get_node_graph_reply_t * mp)
2916 {
2917   vat_main_t *vam = &vat_main;
2918   api_main_t *am = &api_main;
2919   void *oldheap;
2920   vat_json_node_t node;
2921   u8 *reply;
2922
2923   /* $$$$ make this real? */
2924   vat_json_init_object (&node);
2925   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2926   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2927
2928   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2929
2930   /* Toss the shared-memory original... */
2931   pthread_mutex_lock (&am->vlib_rp->mutex);
2932   oldheap = svm_push_data_heap (am->vlib_rp);
2933
2934   vec_free (reply);
2935
2936   svm_pop_heap (oldheap);
2937   pthread_mutex_unlock (&am->vlib_rp->mutex);
2938
2939   vat_json_print (vam->ofp, &node);
2940   vat_json_free (&node);
2941
2942   vam->retval = ntohl (mp->retval);
2943   vam->result_ready = 1;
2944 }
2945
2946 static void
2947 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2948 {
2949   vat_main_t *vam = &vat_main;
2950   u8 *s = 0;
2951
2952   if (mp->local)
2953     {
2954       s = format (s, "%=16d%=16d%=16d",
2955                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2956     }
2957   else
2958     {
2959       s = format (s, "%=16U%=16d%=16d",
2960                   mp->is_ipv6 ? format_ip6_address :
2961                   format_ip4_address,
2962                   mp->ip_address, mp->priority, mp->weight);
2963     }
2964
2965   print (vam->ofp, "%v", s);
2966   vec_free (s);
2967 }
2968
2969 static void
2970 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2971 {
2972   vat_main_t *vam = &vat_main;
2973   vat_json_node_t *node = NULL;
2974   struct in6_addr ip6;
2975   struct in_addr ip4;
2976
2977   if (VAT_JSON_ARRAY != vam->json_tree.type)
2978     {
2979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2980       vat_json_init_array (&vam->json_tree);
2981     }
2982   node = vat_json_array_add (&vam->json_tree);
2983   vat_json_init_object (node);
2984
2985   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2986   vat_json_object_add_uint (node, "priority", mp->priority);
2987   vat_json_object_add_uint (node, "weight", mp->weight);
2988
2989   if (mp->local)
2990     vat_json_object_add_uint (node, "sw_if_index",
2991                               clib_net_to_host_u32 (mp->sw_if_index));
2992   else
2993     {
2994       if (mp->is_ipv6)
2995         {
2996           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2997           vat_json_object_add_ip6 (node, "address", ip6);
2998         }
2999       else
3000         {
3001           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3002           vat_json_object_add_ip4 (node, "address", ip4);
3003         }
3004     }
3005 }
3006
3007 static void
3008 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3009                                           mp)
3010 {
3011   vat_main_t *vam = &vat_main;
3012   u8 *ls_name = 0;
3013
3014   ls_name = format (0, "%s", mp->ls_name);
3015
3016   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3017          ls_name);
3018   vec_free (ls_name);
3019 }
3020
3021 static void
3022   vl_api_one_locator_set_details_t_handler_json
3023   (vl_api_one_locator_set_details_t * mp)
3024 {
3025   vat_main_t *vam = &vat_main;
3026   vat_json_node_t *node = 0;
3027   u8 *ls_name = 0;
3028
3029   ls_name = format (0, "%s", mp->ls_name);
3030   vec_add1 (ls_name, 0);
3031
3032   if (VAT_JSON_ARRAY != vam->json_tree.type)
3033     {
3034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3035       vat_json_init_array (&vam->json_tree);
3036     }
3037   node = vat_json_array_add (&vam->json_tree);
3038
3039   vat_json_init_object (node);
3040   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3041   vat_json_object_add_uint (node, "ls_index",
3042                             clib_net_to_host_u32 (mp->ls_index));
3043   vec_free (ls_name);
3044 }
3045
3046 typedef struct
3047 {
3048   u32 spi;
3049   u8 si;
3050 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3051
3052 uword
3053 unformat_nsh_address (unformat_input_t * input, va_list * args)
3054 {
3055   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3056   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3057 }
3058
3059 u8 *
3060 format_nsh_address_vat (u8 * s, va_list * args)
3061 {
3062   nsh_t *a = va_arg (*args, nsh_t *);
3063   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3064 }
3065
3066 static u8 *
3067 format_lisp_flat_eid (u8 * s, va_list * args)
3068 {
3069   u32 type = va_arg (*args, u32);
3070   u8 *eid = va_arg (*args, u8 *);
3071   u32 eid_len = va_arg (*args, u32);
3072
3073   switch (type)
3074     {
3075     case 0:
3076       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3077     case 1:
3078       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3079     case 2:
3080       return format (s, "%U", format_ethernet_address, eid);
3081     case 3:
3082       return format (s, "%U", format_nsh_address_vat, eid);
3083     }
3084   return 0;
3085 }
3086
3087 static u8 *
3088 format_lisp_eid_vat (u8 * s, va_list * args)
3089 {
3090   u32 type = va_arg (*args, u32);
3091   u8 *eid = va_arg (*args, u8 *);
3092   u32 eid_len = va_arg (*args, u32);
3093   u8 *seid = va_arg (*args, u8 *);
3094   u32 seid_len = va_arg (*args, u32);
3095   u32 is_src_dst = va_arg (*args, u32);
3096
3097   if (is_src_dst)
3098     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3099
3100   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3101
3102   return s;
3103 }
3104
3105 static void
3106 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3107 {
3108   vat_main_t *vam = &vat_main;
3109   u8 *s = 0, *eid = 0;
3110
3111   if (~0 == mp->locator_set_index)
3112     s = format (0, "action: %d", mp->action);
3113   else
3114     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3115
3116   eid = format (0, "%U", format_lisp_eid_vat,
3117                 mp->eid_type,
3118                 mp->eid,
3119                 mp->eid_prefix_len,
3120                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3121   vec_add1 (eid, 0);
3122
3123   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3124          clib_net_to_host_u32 (mp->vni),
3125          eid,
3126          mp->is_local ? "local" : "remote",
3127          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3128          clib_net_to_host_u16 (mp->key_id), mp->key);
3129
3130   vec_free (s);
3131   vec_free (eid);
3132 }
3133
3134 static void
3135 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3136                                              * mp)
3137 {
3138   vat_main_t *vam = &vat_main;
3139   vat_json_node_t *node = 0;
3140   u8 *eid = 0;
3141
3142   if (VAT_JSON_ARRAY != vam->json_tree.type)
3143     {
3144       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3145       vat_json_init_array (&vam->json_tree);
3146     }
3147   node = vat_json_array_add (&vam->json_tree);
3148
3149   vat_json_init_object (node);
3150   if (~0 == mp->locator_set_index)
3151     vat_json_object_add_uint (node, "action", mp->action);
3152   else
3153     vat_json_object_add_uint (node, "locator_set_index",
3154                               clib_net_to_host_u32 (mp->locator_set_index));
3155
3156   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3157   if (mp->eid_type == 3)
3158     {
3159       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3160       vat_json_init_object (nsh_json);
3161       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3162       vat_json_object_add_uint (nsh_json, "spi",
3163                                 clib_net_to_host_u32 (nsh->spi));
3164       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3165     }
3166   else
3167     {
3168       eid = format (0, "%U", format_lisp_eid_vat,
3169                     mp->eid_type,
3170                     mp->eid,
3171                     mp->eid_prefix_len,
3172                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3173       vec_add1 (eid, 0);
3174       vat_json_object_add_string_copy (node, "eid", eid);
3175       vec_free (eid);
3176     }
3177   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3178   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3179   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3180
3181   if (mp->key_id)
3182     {
3183       vat_json_object_add_uint (node, "key_id",
3184                                 clib_net_to_host_u16 (mp->key_id));
3185       vat_json_object_add_string_copy (node, "key", mp->key);
3186     }
3187 }
3188
3189 static void
3190 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3191 {
3192   vat_main_t *vam = &vat_main;
3193   u8 *seid = 0, *deid = 0;
3194   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3195
3196   deid = format (0, "%U", format_lisp_eid_vat,
3197                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3198
3199   seid = format (0, "%U", format_lisp_eid_vat,
3200                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3201
3202   vec_add1 (deid, 0);
3203   vec_add1 (seid, 0);
3204
3205   if (mp->is_ip4)
3206     format_ip_address_fcn = format_ip4_address;
3207   else
3208     format_ip_address_fcn = format_ip6_address;
3209
3210
3211   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3212          clib_net_to_host_u32 (mp->vni),
3213          seid, deid,
3214          format_ip_address_fcn, mp->lloc,
3215          format_ip_address_fcn, mp->rloc,
3216          clib_net_to_host_u32 (mp->pkt_count),
3217          clib_net_to_host_u32 (mp->bytes));
3218
3219   vec_free (deid);
3220   vec_free (seid);
3221 }
3222
3223 static void
3224 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3225 {
3226   struct in6_addr ip6;
3227   struct in_addr ip4;
3228   vat_main_t *vam = &vat_main;
3229   vat_json_node_t *node = 0;
3230   u8 *deid = 0, *seid = 0;
3231
3232   if (VAT_JSON_ARRAY != vam->json_tree.type)
3233     {
3234       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3235       vat_json_init_array (&vam->json_tree);
3236     }
3237   node = vat_json_array_add (&vam->json_tree);
3238
3239   vat_json_init_object (node);
3240   deid = format (0, "%U", format_lisp_eid_vat,
3241                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3242
3243   seid = format (0, "%U", format_lisp_eid_vat,
3244                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3245
3246   vec_add1 (deid, 0);
3247   vec_add1 (seid, 0);
3248
3249   vat_json_object_add_string_copy (node, "seid", seid);
3250   vat_json_object_add_string_copy (node, "deid", deid);
3251   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3252
3253   if (mp->is_ip4)
3254     {
3255       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3256       vat_json_object_add_ip4 (node, "lloc", ip4);
3257       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3258       vat_json_object_add_ip4 (node, "rloc", ip4);
3259     }
3260   else
3261     {
3262       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3263       vat_json_object_add_ip6 (node, "lloc", ip6);
3264       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3265       vat_json_object_add_ip6 (node, "rloc", ip6);
3266     }
3267   vat_json_object_add_uint (node, "pkt_count",
3268                             clib_net_to_host_u32 (mp->pkt_count));
3269   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3270
3271   vec_free (deid);
3272   vec_free (seid);
3273 }
3274
3275 static void
3276   vl_api_one_eid_table_map_details_t_handler
3277   (vl_api_one_eid_table_map_details_t * mp)
3278 {
3279   vat_main_t *vam = &vat_main;
3280
3281   u8 *line = format (0, "%=10d%=10d",
3282                      clib_net_to_host_u32 (mp->vni),
3283                      clib_net_to_host_u32 (mp->dp_table));
3284   print (vam->ofp, "%v", line);
3285   vec_free (line);
3286 }
3287
3288 static void
3289   vl_api_one_eid_table_map_details_t_handler_json
3290   (vl_api_one_eid_table_map_details_t * mp)
3291 {
3292   vat_main_t *vam = &vat_main;
3293   vat_json_node_t *node = NULL;
3294
3295   if (VAT_JSON_ARRAY != vam->json_tree.type)
3296     {
3297       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3298       vat_json_init_array (&vam->json_tree);
3299     }
3300   node = vat_json_array_add (&vam->json_tree);
3301   vat_json_init_object (node);
3302   vat_json_object_add_uint (node, "dp_table",
3303                             clib_net_to_host_u32 (mp->dp_table));
3304   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3305 }
3306
3307 static void
3308   vl_api_one_eid_table_vni_details_t_handler
3309   (vl_api_one_eid_table_vni_details_t * mp)
3310 {
3311   vat_main_t *vam = &vat_main;
3312
3313   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3314   print (vam->ofp, "%v", line);
3315   vec_free (line);
3316 }
3317
3318 static void
3319   vl_api_one_eid_table_vni_details_t_handler_json
3320   (vl_api_one_eid_table_vni_details_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t *node = NULL;
3324
3325   if (VAT_JSON_ARRAY != vam->json_tree.type)
3326     {
3327       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3328       vat_json_init_array (&vam->json_tree);
3329     }
3330   node = vat_json_array_add (&vam->json_tree);
3331   vat_json_init_object (node);
3332   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3333 }
3334
3335 static void
3336   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3337   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3338 {
3339   vat_main_t *vam = &vat_main;
3340   int retval = clib_net_to_host_u32 (mp->retval);
3341
3342   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3343   print (vam->ofp, "fallback threshold value: %d", mp->value);
3344
3345   vam->retval = retval;
3346   vam->result_ready = 1;
3347 }
3348
3349 static void
3350   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3351   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3352 {
3353   vat_main_t *vam = &vat_main;
3354   vat_json_node_t _node, *node = &_node;
3355   int retval = clib_net_to_host_u32 (mp->retval);
3356
3357   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3358   vat_json_init_object (node);
3359   vat_json_object_add_uint (node, "value", mp->value);
3360
3361   vat_json_print (vam->ofp, node);
3362   vat_json_free (node);
3363
3364   vam->retval = retval;
3365   vam->result_ready = 1;
3366 }
3367
3368 static void
3369   vl_api_show_one_map_register_state_reply_t_handler
3370   (vl_api_show_one_map_register_state_reply_t * mp)
3371 {
3372   vat_main_t *vam = &vat_main;
3373   int retval = clib_net_to_host_u32 (mp->retval);
3374
3375   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3376
3377   vam->retval = retval;
3378   vam->result_ready = 1;
3379 }
3380
3381 static void
3382   vl_api_show_one_map_register_state_reply_t_handler_json
3383   (vl_api_show_one_map_register_state_reply_t * mp)
3384 {
3385   vat_main_t *vam = &vat_main;
3386   vat_json_node_t _node, *node = &_node;
3387   int retval = clib_net_to_host_u32 (mp->retval);
3388
3389   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3390
3391   vat_json_init_object (node);
3392   vat_json_object_add_string_copy (node, "state", s);
3393
3394   vat_json_print (vam->ofp, node);
3395   vat_json_free (node);
3396
3397   vam->retval = retval;
3398   vam->result_ready = 1;
3399   vec_free (s);
3400 }
3401
3402 static void
3403   vl_api_show_one_rloc_probe_state_reply_t_handler
3404   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3405 {
3406   vat_main_t *vam = &vat_main;
3407   int retval = clib_net_to_host_u32 (mp->retval);
3408
3409   if (retval)
3410     goto end;
3411
3412   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3413 end:
3414   vam->retval = retval;
3415   vam->result_ready = 1;
3416 }
3417
3418 static void
3419   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3420   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3421 {
3422   vat_main_t *vam = &vat_main;
3423   vat_json_node_t _node, *node = &_node;
3424   int retval = clib_net_to_host_u32 (mp->retval);
3425
3426   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3427   vat_json_init_object (node);
3428   vat_json_object_add_string_copy (node, "state", s);
3429
3430   vat_json_print (vam->ofp, node);
3431   vat_json_free (node);
3432
3433   vam->retval = retval;
3434   vam->result_ready = 1;
3435   vec_free (s);
3436 }
3437
3438 static void
3439   vl_api_show_one_stats_enable_disable_reply_t_handler
3440   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3441 {
3442   vat_main_t *vam = &vat_main;
3443   int retval = clib_net_to_host_u32 (mp->retval);
3444
3445   if (retval)
3446     goto end;
3447
3448   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3449 end:
3450   vam->retval = retval;
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3456   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   vat_json_node_t _node, *node = &_node;
3460   int retval = clib_net_to_host_u32 (mp->retval);
3461
3462   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3463   vat_json_init_object (node);
3464   vat_json_object_add_string_copy (node, "state", s);
3465
3466   vat_json_print (vam->ofp, node);
3467   vat_json_free (node);
3468
3469   vam->retval = retval;
3470   vam->result_ready = 1;
3471   vec_free (s);
3472 }
3473
3474 static void
3475 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3476 {
3477   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3478   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3479   e->vni = clib_net_to_host_u32 (e->vni);
3480 }
3481
3482 static void
3483   gpe_fwd_entries_get_reply_t_net_to_host
3484   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3485 {
3486   u32 i;
3487
3488   mp->count = clib_net_to_host_u32 (mp->count);
3489   for (i = 0; i < mp->count; i++)
3490     {
3491       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3492     }
3493 }
3494
3495 static u8 *
3496 format_gpe_encap_mode (u8 * s, va_list * args)
3497 {
3498   u32 mode = va_arg (*args, u32);
3499
3500   switch (mode)
3501     {
3502     case 0:
3503       return format (s, "lisp");
3504     case 1:
3505       return format (s, "vxlan");
3506     }
3507   return 0;
3508 }
3509
3510 static void
3511   vl_api_gpe_get_encap_mode_reply_t_handler
3512   (vl_api_gpe_get_encap_mode_reply_t * mp)
3513 {
3514   vat_main_t *vam = &vat_main;
3515
3516   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3517   vam->retval = ntohl (mp->retval);
3518   vam->result_ready = 1;
3519 }
3520
3521 static void
3522   vl_api_gpe_get_encap_mode_reply_t_handler_json
3523   (vl_api_gpe_get_encap_mode_reply_t * mp)
3524 {
3525   vat_main_t *vam = &vat_main;
3526   vat_json_node_t node;
3527
3528   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3529   vec_add1 (encap_mode, 0);
3530
3531   vat_json_init_object (&node);
3532   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3533
3534   vec_free (encap_mode);
3535   vat_json_print (vam->ofp, &node);
3536   vat_json_free (&node);
3537
3538   vam->retval = ntohl (mp->retval);
3539   vam->result_ready = 1;
3540 }
3541
3542 static void
3543   vl_api_gpe_fwd_entry_path_details_t_handler
3544   (vl_api_gpe_fwd_entry_path_details_t * mp)
3545 {
3546   vat_main_t *vam = &vat_main;
3547   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3548
3549   if (mp->lcl_loc.is_ip4)
3550     format_ip_address_fcn = format_ip4_address;
3551   else
3552     format_ip_address_fcn = format_ip6_address;
3553
3554   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3555          format_ip_address_fcn, &mp->lcl_loc,
3556          format_ip_address_fcn, &mp->rmt_loc);
3557 }
3558
3559 static void
3560 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3561 {
3562   struct in6_addr ip6;
3563   struct in_addr ip4;
3564
3565   if (loc->is_ip4)
3566     {
3567       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3568       vat_json_object_add_ip4 (n, "address", ip4);
3569     }
3570   else
3571     {
3572       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3573       vat_json_object_add_ip6 (n, "address", ip6);
3574     }
3575   vat_json_object_add_uint (n, "weight", loc->weight);
3576 }
3577
3578 static void
3579   vl_api_gpe_fwd_entry_path_details_t_handler_json
3580   (vl_api_gpe_fwd_entry_path_details_t * mp)
3581 {
3582   vat_main_t *vam = &vat_main;
3583   vat_json_node_t *node = NULL;
3584   vat_json_node_t *loc_node;
3585
3586   if (VAT_JSON_ARRAY != vam->json_tree.type)
3587     {
3588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3589       vat_json_init_array (&vam->json_tree);
3590     }
3591   node = vat_json_array_add (&vam->json_tree);
3592   vat_json_init_object (node);
3593
3594   loc_node = vat_json_object_add (node, "local_locator");
3595   vat_json_init_object (loc_node);
3596   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3597
3598   loc_node = vat_json_object_add (node, "remote_locator");
3599   vat_json_init_object (loc_node);
3600   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3601 }
3602
3603 static void
3604   vl_api_gpe_fwd_entries_get_reply_t_handler
3605   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3606 {
3607   vat_main_t *vam = &vat_main;
3608   u32 i;
3609   int retval = clib_net_to_host_u32 (mp->retval);
3610   vl_api_gpe_fwd_entry_t *e;
3611
3612   if (retval)
3613     goto end;
3614
3615   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3616
3617   for (i = 0; i < mp->count; i++)
3618     {
3619       e = &mp->entries[i];
3620       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3621              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3622              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3623     }
3624
3625 end:
3626   vam->retval = retval;
3627   vam->result_ready = 1;
3628 }
3629
3630 static void
3631   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3632   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3633 {
3634   u8 *s = 0;
3635   vat_main_t *vam = &vat_main;
3636   vat_json_node_t *e = 0, root;
3637   u32 i;
3638   int retval = clib_net_to_host_u32 (mp->retval);
3639   vl_api_gpe_fwd_entry_t *fwd;
3640
3641   if (retval)
3642     goto end;
3643
3644   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3645   vat_json_init_array (&root);
3646
3647   for (i = 0; i < mp->count; i++)
3648     {
3649       e = vat_json_array_add (&root);
3650       fwd = &mp->entries[i];
3651
3652       vat_json_init_object (e);
3653       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3654       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3655       vat_json_object_add_int (e, "vni", fwd->vni);
3656       vat_json_object_add_int (e, "action", fwd->action);
3657
3658       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3659                   fwd->leid_prefix_len);
3660       vec_add1 (s, 0);
3661       vat_json_object_add_string_copy (e, "leid", s);
3662       vec_free (s);
3663
3664       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3665                   fwd->reid_prefix_len);
3666       vec_add1 (s, 0);
3667       vat_json_object_add_string_copy (e, "reid", s);
3668       vec_free (s);
3669     }
3670
3671   vat_json_print (vam->ofp, &root);
3672   vat_json_free (&root);
3673
3674 end:
3675   vam->retval = retval;
3676   vam->result_ready = 1;
3677 }
3678
3679 static void
3680   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3681   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3682 {
3683   vat_main_t *vam = &vat_main;
3684   u32 i, n;
3685   int retval = clib_net_to_host_u32 (mp->retval);
3686   vl_api_gpe_native_fwd_rpath_t *r;
3687
3688   if (retval)
3689     goto end;
3690
3691   n = clib_net_to_host_u32 (mp->count);
3692
3693   for (i = 0; i < n; i++)
3694     {
3695       r = &mp->entries[i];
3696       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3697              clib_net_to_host_u32 (r->fib_index),
3698              clib_net_to_host_u32 (r->nh_sw_if_index),
3699              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3700     }
3701
3702 end:
3703   vam->retval = retval;
3704   vam->result_ready = 1;
3705 }
3706
3707 static void
3708   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3709   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3710 {
3711   vat_main_t *vam = &vat_main;
3712   vat_json_node_t root, *e;
3713   u32 i, n;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715   vl_api_gpe_native_fwd_rpath_t *r;
3716   u8 *s;
3717
3718   if (retval)
3719     goto end;
3720
3721   n = clib_net_to_host_u32 (mp->count);
3722   vat_json_init_array (&root);
3723
3724   for (i = 0; i < n; i++)
3725     {
3726       e = vat_json_array_add (&root);
3727       vat_json_init_object (e);
3728       r = &mp->entries[i];
3729       s =
3730         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3731                 r->nh_addr);
3732       vec_add1 (s, 0);
3733       vat_json_object_add_string_copy (e, "ip4", s);
3734       vec_free (s);
3735
3736       vat_json_object_add_uint (e, "fib_index",
3737                                 clib_net_to_host_u32 (r->fib_index));
3738       vat_json_object_add_uint (e, "nh_sw_if_index",
3739                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3740     }
3741
3742   vat_json_print (vam->ofp, &root);
3743   vat_json_free (&root);
3744
3745 end:
3746   vam->retval = retval;
3747   vam->result_ready = 1;
3748 }
3749
3750 static void
3751   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3752   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3753 {
3754   vat_main_t *vam = &vat_main;
3755   u32 i, n;
3756   int retval = clib_net_to_host_u32 (mp->retval);
3757
3758   if (retval)
3759     goto end;
3760
3761   n = clib_net_to_host_u32 (mp->count);
3762
3763   for (i = 0; i < n; i++)
3764     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3765
3766 end:
3767   vam->retval = retval;
3768   vam->result_ready = 1;
3769 }
3770
3771 static void
3772   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3773   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3774 {
3775   vat_main_t *vam = &vat_main;
3776   vat_json_node_t root;
3777   u32 i, n;
3778   int retval = clib_net_to_host_u32 (mp->retval);
3779
3780   if (retval)
3781     goto end;
3782
3783   n = clib_net_to_host_u32 (mp->count);
3784   vat_json_init_array (&root);
3785
3786   for (i = 0; i < n; i++)
3787     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3788
3789   vat_json_print (vam->ofp, &root);
3790   vat_json_free (&root);
3791
3792 end:
3793   vam->retval = retval;
3794   vam->result_ready = 1;
3795 }
3796
3797 static void
3798   vl_api_one_ndp_entries_get_reply_t_handler
3799   (vl_api_one_ndp_entries_get_reply_t * mp)
3800 {
3801   vat_main_t *vam = &vat_main;
3802   u32 i, n;
3803   int retval = clib_net_to_host_u32 (mp->retval);
3804
3805   if (retval)
3806     goto end;
3807
3808   n = clib_net_to_host_u32 (mp->count);
3809
3810   for (i = 0; i < n; i++)
3811     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3812            format_ethernet_address, mp->entries[i].mac);
3813
3814 end:
3815   vam->retval = retval;
3816   vam->result_ready = 1;
3817 }
3818
3819 static void
3820   vl_api_one_ndp_entries_get_reply_t_handler_json
3821   (vl_api_one_ndp_entries_get_reply_t * mp)
3822 {
3823   u8 *s = 0;
3824   vat_main_t *vam = &vat_main;
3825   vat_json_node_t *e = 0, root;
3826   u32 i, n;
3827   int retval = clib_net_to_host_u32 (mp->retval);
3828   vl_api_one_ndp_entry_t *arp_entry;
3829
3830   if (retval)
3831     goto end;
3832
3833   n = clib_net_to_host_u32 (mp->count);
3834   vat_json_init_array (&root);
3835
3836   for (i = 0; i < n; i++)
3837     {
3838       e = vat_json_array_add (&root);
3839       arp_entry = &mp->entries[i];
3840
3841       vat_json_init_object (e);
3842       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3843       vec_add1 (s, 0);
3844
3845       vat_json_object_add_string_copy (e, "mac", s);
3846       vec_free (s);
3847
3848       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3849       vec_add1 (s, 0);
3850       vat_json_object_add_string_copy (e, "ip6", s);
3851       vec_free (s);
3852     }
3853
3854   vat_json_print (vam->ofp, &root);
3855   vat_json_free (&root);
3856
3857 end:
3858   vam->retval = retval;
3859   vam->result_ready = 1;
3860 }
3861
3862 static void
3863   vl_api_one_l2_arp_entries_get_reply_t_handler
3864   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3865 {
3866   vat_main_t *vam = &vat_main;
3867   u32 i, n;
3868   int retval = clib_net_to_host_u32 (mp->retval);
3869
3870   if (retval)
3871     goto end;
3872
3873   n = clib_net_to_host_u32 (mp->count);
3874
3875   for (i = 0; i < n; i++)
3876     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3877            format_ethernet_address, mp->entries[i].mac);
3878
3879 end:
3880   vam->retval = retval;
3881   vam->result_ready = 1;
3882 }
3883
3884 static void
3885   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3886   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3887 {
3888   u8 *s = 0;
3889   vat_main_t *vam = &vat_main;
3890   vat_json_node_t *e = 0, root;
3891   u32 i, n;
3892   int retval = clib_net_to_host_u32 (mp->retval);
3893   vl_api_one_l2_arp_entry_t *arp_entry;
3894
3895   if (retval)
3896     goto end;
3897
3898   n = clib_net_to_host_u32 (mp->count);
3899   vat_json_init_array (&root);
3900
3901   for (i = 0; i < n; i++)
3902     {
3903       e = vat_json_array_add (&root);
3904       arp_entry = &mp->entries[i];
3905
3906       vat_json_init_object (e);
3907       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3908       vec_add1 (s, 0);
3909
3910       vat_json_object_add_string_copy (e, "mac", s);
3911       vec_free (s);
3912
3913       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3914       vec_add1 (s, 0);
3915       vat_json_object_add_string_copy (e, "ip4", s);
3916       vec_free (s);
3917     }
3918
3919   vat_json_print (vam->ofp, &root);
3920   vat_json_free (&root);
3921
3922 end:
3923   vam->retval = retval;
3924   vam->result_ready = 1;
3925 }
3926
3927 static void
3928 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3929 {
3930   vat_main_t *vam = &vat_main;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933
3934   if (retval)
3935     goto end;
3936
3937   n = clib_net_to_host_u32 (mp->count);
3938
3939   for (i = 0; i < n; i++)
3940     {
3941       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3942     }
3943
3944 end:
3945   vam->retval = retval;
3946   vam->result_ready = 1;
3947 }
3948
3949 static void
3950   vl_api_one_ndp_bd_get_reply_t_handler_json
3951   (vl_api_one_ndp_bd_get_reply_t * mp)
3952 {
3953   vat_main_t *vam = &vat_main;
3954   vat_json_node_t root;
3955   u32 i, n;
3956   int retval = clib_net_to_host_u32 (mp->retval);
3957
3958   if (retval)
3959     goto end;
3960
3961   n = clib_net_to_host_u32 (mp->count);
3962   vat_json_init_array (&root);
3963
3964   for (i = 0; i < n; i++)
3965     {
3966       vat_json_array_add_uint (&root,
3967                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3968     }
3969
3970   vat_json_print (vam->ofp, &root);
3971   vat_json_free (&root);
3972
3973 end:
3974   vam->retval = retval;
3975   vam->result_ready = 1;
3976 }
3977
3978 static void
3979   vl_api_one_l2_arp_bd_get_reply_t_handler
3980   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3981 {
3982   vat_main_t *vam = &vat_main;
3983   u32 i, n;
3984   int retval = clib_net_to_host_u32 (mp->retval);
3985
3986   if (retval)
3987     goto end;
3988
3989   n = clib_net_to_host_u32 (mp->count);
3990
3991   for (i = 0; i < n; i++)
3992     {
3993       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3994     }
3995
3996 end:
3997   vam->retval = retval;
3998   vam->result_ready = 1;
3999 }
4000
4001 static void
4002   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4003   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4004 {
4005   vat_main_t *vam = &vat_main;
4006   vat_json_node_t root;
4007   u32 i, n;
4008   int retval = clib_net_to_host_u32 (mp->retval);
4009
4010   if (retval)
4011     goto end;
4012
4013   n = clib_net_to_host_u32 (mp->count);
4014   vat_json_init_array (&root);
4015
4016   for (i = 0; i < n; i++)
4017     {
4018       vat_json_array_add_uint (&root,
4019                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4020     }
4021
4022   vat_json_print (vam->ofp, &root);
4023   vat_json_free (&root);
4024
4025 end:
4026   vam->retval = retval;
4027   vam->result_ready = 1;
4028 }
4029
4030 static void
4031   vl_api_one_adjacencies_get_reply_t_handler
4032   (vl_api_one_adjacencies_get_reply_t * mp)
4033 {
4034   vat_main_t *vam = &vat_main;
4035   u32 i, n;
4036   int retval = clib_net_to_host_u32 (mp->retval);
4037   vl_api_one_adjacency_t *a;
4038
4039   if (retval)
4040     goto end;
4041
4042   n = clib_net_to_host_u32 (mp->count);
4043
4044   for (i = 0; i < n; i++)
4045     {
4046       a = &mp->adjacencies[i];
4047       print (vam->ofp, "%U %40U",
4048              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4049              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4050     }
4051
4052 end:
4053   vam->retval = retval;
4054   vam->result_ready = 1;
4055 }
4056
4057 static void
4058   vl_api_one_adjacencies_get_reply_t_handler_json
4059   (vl_api_one_adjacencies_get_reply_t * mp)
4060 {
4061   u8 *s = 0;
4062   vat_main_t *vam = &vat_main;
4063   vat_json_node_t *e = 0, root;
4064   u32 i, n;
4065   int retval = clib_net_to_host_u32 (mp->retval);
4066   vl_api_one_adjacency_t *a;
4067
4068   if (retval)
4069     goto end;
4070
4071   n = clib_net_to_host_u32 (mp->count);
4072   vat_json_init_array (&root);
4073
4074   for (i = 0; i < n; i++)
4075     {
4076       e = vat_json_array_add (&root);
4077       a = &mp->adjacencies[i];
4078
4079       vat_json_init_object (e);
4080       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4081                   a->leid_prefix_len);
4082       vec_add1 (s, 0);
4083       vat_json_object_add_string_copy (e, "leid", s);
4084       vec_free (s);
4085
4086       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4087                   a->reid_prefix_len);
4088       vec_add1 (s, 0);
4089       vat_json_object_add_string_copy (e, "reid", s);
4090       vec_free (s);
4091     }
4092
4093   vat_json_print (vam->ofp, &root);
4094   vat_json_free (&root);
4095
4096 end:
4097   vam->retval = retval;
4098   vam->result_ready = 1;
4099 }
4100
4101 static void
4102 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4103 {
4104   vat_main_t *vam = &vat_main;
4105
4106   print (vam->ofp, "%=20U",
4107          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4108          mp->ip_address);
4109 }
4110
4111 static void
4112   vl_api_one_map_server_details_t_handler_json
4113   (vl_api_one_map_server_details_t * mp)
4114 {
4115   vat_main_t *vam = &vat_main;
4116   vat_json_node_t *node = NULL;
4117   struct in6_addr ip6;
4118   struct in_addr ip4;
4119
4120   if (VAT_JSON_ARRAY != vam->json_tree.type)
4121     {
4122       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4123       vat_json_init_array (&vam->json_tree);
4124     }
4125   node = vat_json_array_add (&vam->json_tree);
4126
4127   vat_json_init_object (node);
4128   if (mp->is_ipv6)
4129     {
4130       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4131       vat_json_object_add_ip6 (node, "map-server", ip6);
4132     }
4133   else
4134     {
4135       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4136       vat_json_object_add_ip4 (node, "map-server", ip4);
4137     }
4138 }
4139
4140 static void
4141 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4142                                            * mp)
4143 {
4144   vat_main_t *vam = &vat_main;
4145
4146   print (vam->ofp, "%=20U",
4147          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4148          mp->ip_address);
4149 }
4150
4151 static void
4152   vl_api_one_map_resolver_details_t_handler_json
4153   (vl_api_one_map_resolver_details_t * mp)
4154 {
4155   vat_main_t *vam = &vat_main;
4156   vat_json_node_t *node = NULL;
4157   struct in6_addr ip6;
4158   struct in_addr ip4;
4159
4160   if (VAT_JSON_ARRAY != vam->json_tree.type)
4161     {
4162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4163       vat_json_init_array (&vam->json_tree);
4164     }
4165   node = vat_json_array_add (&vam->json_tree);
4166
4167   vat_json_init_object (node);
4168   if (mp->is_ipv6)
4169     {
4170       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4171       vat_json_object_add_ip6 (node, "map resolver", ip6);
4172     }
4173   else
4174     {
4175       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4176       vat_json_object_add_ip4 (node, "map resolver", ip4);
4177     }
4178 }
4179
4180 static void
4181 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4182 {
4183   vat_main_t *vam = &vat_main;
4184   i32 retval = ntohl (mp->retval);
4185
4186   if (0 <= retval)
4187     {
4188       print (vam->ofp, "feature: %s\ngpe: %s",
4189              mp->feature_status ? "enabled" : "disabled",
4190              mp->gpe_status ? "enabled" : "disabled");
4191     }
4192
4193   vam->retval = retval;
4194   vam->result_ready = 1;
4195 }
4196
4197 static void
4198   vl_api_show_one_status_reply_t_handler_json
4199   (vl_api_show_one_status_reply_t * mp)
4200 {
4201   vat_main_t *vam = &vat_main;
4202   vat_json_node_t node;
4203   u8 *gpe_status = NULL;
4204   u8 *feature_status = NULL;
4205
4206   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4207   feature_status = format (0, "%s",
4208                            mp->feature_status ? "enabled" : "disabled");
4209   vec_add1 (gpe_status, 0);
4210   vec_add1 (feature_status, 0);
4211
4212   vat_json_init_object (&node);
4213   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4214   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4215
4216   vec_free (gpe_status);
4217   vec_free (feature_status);
4218
4219   vat_json_print (vam->ofp, &node);
4220   vat_json_free (&node);
4221
4222   vam->retval = ntohl (mp->retval);
4223   vam->result_ready = 1;
4224 }
4225
4226 static void
4227   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4228   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4229 {
4230   vat_main_t *vam = &vat_main;
4231   i32 retval = ntohl (mp->retval);
4232
4233   if (retval >= 0)
4234     {
4235       print (vam->ofp, "%=20s", mp->locator_set_name);
4236     }
4237
4238   vam->retval = retval;
4239   vam->result_ready = 1;
4240 }
4241
4242 static void
4243   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4244   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4245 {
4246   vat_main_t *vam = &vat_main;
4247   vat_json_node_t *node = NULL;
4248
4249   if (VAT_JSON_ARRAY != vam->json_tree.type)
4250     {
4251       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4252       vat_json_init_array (&vam->json_tree);
4253     }
4254   node = vat_json_array_add (&vam->json_tree);
4255
4256   vat_json_init_object (node);
4257   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4258
4259   vat_json_print (vam->ofp, node);
4260   vat_json_free (node);
4261
4262   vam->retval = ntohl (mp->retval);
4263   vam->result_ready = 1;
4264 }
4265
4266 static u8 *
4267 format_lisp_map_request_mode (u8 * s, va_list * args)
4268 {
4269   u32 mode = va_arg (*args, u32);
4270
4271   switch (mode)
4272     {
4273     case 0:
4274       return format (0, "dst-only");
4275     case 1:
4276       return format (0, "src-dst");
4277     }
4278   return 0;
4279 }
4280
4281 static void
4282   vl_api_show_one_map_request_mode_reply_t_handler
4283   (vl_api_show_one_map_request_mode_reply_t * mp)
4284 {
4285   vat_main_t *vam = &vat_main;
4286   i32 retval = ntohl (mp->retval);
4287
4288   if (0 <= retval)
4289     {
4290       u32 mode = mp->mode;
4291       print (vam->ofp, "map_request_mode: %U",
4292              format_lisp_map_request_mode, mode);
4293     }
4294
4295   vam->retval = retval;
4296   vam->result_ready = 1;
4297 }
4298
4299 static void
4300   vl_api_show_one_map_request_mode_reply_t_handler_json
4301   (vl_api_show_one_map_request_mode_reply_t * mp)
4302 {
4303   vat_main_t *vam = &vat_main;
4304   vat_json_node_t node;
4305   u8 *s = 0;
4306   u32 mode;
4307
4308   mode = mp->mode;
4309   s = format (0, "%U", format_lisp_map_request_mode, mode);
4310   vec_add1 (s, 0);
4311
4312   vat_json_init_object (&node);
4313   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4314   vat_json_print (vam->ofp, &node);
4315   vat_json_free (&node);
4316
4317   vec_free (s);
4318   vam->retval = ntohl (mp->retval);
4319   vam->result_ready = 1;
4320 }
4321
4322 static void
4323   vl_api_one_show_xtr_mode_reply_t_handler
4324   (vl_api_one_show_xtr_mode_reply_t * mp)
4325 {
4326   vat_main_t *vam = &vat_main;
4327   i32 retval = ntohl (mp->retval);
4328
4329   if (0 <= retval)
4330     {
4331       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4332     }
4333
4334   vam->retval = retval;
4335   vam->result_ready = 1;
4336 }
4337
4338 static void
4339   vl_api_one_show_xtr_mode_reply_t_handler_json
4340   (vl_api_one_show_xtr_mode_reply_t * mp)
4341 {
4342   vat_main_t *vam = &vat_main;
4343   vat_json_node_t node;
4344   u8 *status = 0;
4345
4346   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4347   vec_add1 (status, 0);
4348
4349   vat_json_init_object (&node);
4350   vat_json_object_add_string_copy (&node, "status", status);
4351
4352   vec_free (status);
4353
4354   vat_json_print (vam->ofp, &node);
4355   vat_json_free (&node);
4356
4357   vam->retval = ntohl (mp->retval);
4358   vam->result_ready = 1;
4359 }
4360
4361 static void
4362   vl_api_one_show_pitr_mode_reply_t_handler
4363   (vl_api_one_show_pitr_mode_reply_t * mp)
4364 {
4365   vat_main_t *vam = &vat_main;
4366   i32 retval = ntohl (mp->retval);
4367
4368   if (0 <= retval)
4369     {
4370       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4371     }
4372
4373   vam->retval = retval;
4374   vam->result_ready = 1;
4375 }
4376
4377 static void
4378   vl_api_one_show_pitr_mode_reply_t_handler_json
4379   (vl_api_one_show_pitr_mode_reply_t * mp)
4380 {
4381   vat_main_t *vam = &vat_main;
4382   vat_json_node_t node;
4383   u8 *status = 0;
4384
4385   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4386   vec_add1 (status, 0);
4387
4388   vat_json_init_object (&node);
4389   vat_json_object_add_string_copy (&node, "status", status);
4390
4391   vec_free (status);
4392
4393   vat_json_print (vam->ofp, &node);
4394   vat_json_free (&node);
4395
4396   vam->retval = ntohl (mp->retval);
4397   vam->result_ready = 1;
4398 }
4399
4400 static void
4401   vl_api_one_show_petr_mode_reply_t_handler
4402   (vl_api_one_show_petr_mode_reply_t * mp)
4403 {
4404   vat_main_t *vam = &vat_main;
4405   i32 retval = ntohl (mp->retval);
4406
4407   if (0 <= retval)
4408     {
4409       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4410     }
4411
4412   vam->retval = retval;
4413   vam->result_ready = 1;
4414 }
4415
4416 static void
4417   vl_api_one_show_petr_mode_reply_t_handler_json
4418   (vl_api_one_show_petr_mode_reply_t * mp)
4419 {
4420   vat_main_t *vam = &vat_main;
4421   vat_json_node_t node;
4422   u8 *status = 0;
4423
4424   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4425   vec_add1 (status, 0);
4426
4427   vat_json_init_object (&node);
4428   vat_json_object_add_string_copy (&node, "status", status);
4429
4430   vec_free (status);
4431
4432   vat_json_print (vam->ofp, &node);
4433   vat_json_free (&node);
4434
4435   vam->retval = ntohl (mp->retval);
4436   vam->result_ready = 1;
4437 }
4438
4439 static void
4440   vl_api_show_one_use_petr_reply_t_handler
4441   (vl_api_show_one_use_petr_reply_t * mp)
4442 {
4443   vat_main_t *vam = &vat_main;
4444   i32 retval = ntohl (mp->retval);
4445
4446   if (0 <= retval)
4447     {
4448       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4449       if (mp->status)
4450         {
4451           print (vam->ofp, "Proxy-ETR address; %U",
4452                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4453                  mp->address);
4454         }
4455     }
4456
4457   vam->retval = retval;
4458   vam->result_ready = 1;
4459 }
4460
4461 static void
4462   vl_api_show_one_use_petr_reply_t_handler_json
4463   (vl_api_show_one_use_petr_reply_t * mp)
4464 {
4465   vat_main_t *vam = &vat_main;
4466   vat_json_node_t node;
4467   u8 *status = 0;
4468   struct in_addr ip4;
4469   struct in6_addr ip6;
4470
4471   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4472   vec_add1 (status, 0);
4473
4474   vat_json_init_object (&node);
4475   vat_json_object_add_string_copy (&node, "status", status);
4476   if (mp->status)
4477     {
4478       if (mp->is_ip4)
4479         {
4480           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4481           vat_json_object_add_ip6 (&node, "address", ip6);
4482         }
4483       else
4484         {
4485           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4486           vat_json_object_add_ip4 (&node, "address", ip4);
4487         }
4488     }
4489
4490   vec_free (status);
4491
4492   vat_json_print (vam->ofp, &node);
4493   vat_json_free (&node);
4494
4495   vam->retval = ntohl (mp->retval);
4496   vam->result_ready = 1;
4497 }
4498
4499 static void
4500   vl_api_show_one_nsh_mapping_reply_t_handler
4501   (vl_api_show_one_nsh_mapping_reply_t * mp)
4502 {
4503   vat_main_t *vam = &vat_main;
4504   i32 retval = ntohl (mp->retval);
4505
4506   if (0 <= retval)
4507     {
4508       print (vam->ofp, "%-20s%-16s",
4509              mp->is_set ? "set" : "not-set",
4510              mp->is_set ? (char *) mp->locator_set_name : "");
4511     }
4512
4513   vam->retval = retval;
4514   vam->result_ready = 1;
4515 }
4516
4517 static void
4518   vl_api_show_one_nsh_mapping_reply_t_handler_json
4519   (vl_api_show_one_nsh_mapping_reply_t * mp)
4520 {
4521   vat_main_t *vam = &vat_main;
4522   vat_json_node_t node;
4523   u8 *status = 0;
4524
4525   status = format (0, "%s", mp->is_set ? "yes" : "no");
4526   vec_add1 (status, 0);
4527
4528   vat_json_init_object (&node);
4529   vat_json_object_add_string_copy (&node, "is_set", status);
4530   if (mp->is_set)
4531     {
4532       vat_json_object_add_string_copy (&node, "locator_set",
4533                                        mp->locator_set_name);
4534     }
4535
4536   vec_free (status);
4537
4538   vat_json_print (vam->ofp, &node);
4539   vat_json_free (&node);
4540
4541   vam->retval = ntohl (mp->retval);
4542   vam->result_ready = 1;
4543 }
4544
4545 static void
4546   vl_api_show_one_map_register_ttl_reply_t_handler
4547   (vl_api_show_one_map_register_ttl_reply_t * mp)
4548 {
4549   vat_main_t *vam = &vat_main;
4550   i32 retval = ntohl (mp->retval);
4551
4552   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4553
4554   if (0 <= retval)
4555     {
4556       print (vam->ofp, "ttl: %u", mp->ttl);
4557     }
4558
4559   vam->retval = retval;
4560   vam->result_ready = 1;
4561 }
4562
4563 static void
4564   vl_api_show_one_map_register_ttl_reply_t_handler_json
4565   (vl_api_show_one_map_register_ttl_reply_t * mp)
4566 {
4567   vat_main_t *vam = &vat_main;
4568   vat_json_node_t node;
4569
4570   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4571   vat_json_init_object (&node);
4572   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4573
4574   vat_json_print (vam->ofp, &node);
4575   vat_json_free (&node);
4576
4577   vam->retval = ntohl (mp->retval);
4578   vam->result_ready = 1;
4579 }
4580
4581 static void
4582 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4583 {
4584   vat_main_t *vam = &vat_main;
4585   i32 retval = ntohl (mp->retval);
4586
4587   if (0 <= retval)
4588     {
4589       print (vam->ofp, "%-20s%-16s",
4590              mp->status ? "enabled" : "disabled",
4591              mp->status ? (char *) mp->locator_set_name : "");
4592     }
4593
4594   vam->retval = retval;
4595   vam->result_ready = 1;
4596 }
4597
4598 static void
4599 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4600 {
4601   vat_main_t *vam = &vat_main;
4602   vat_json_node_t node;
4603   u8 *status = 0;
4604
4605   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4606   vec_add1 (status, 0);
4607
4608   vat_json_init_object (&node);
4609   vat_json_object_add_string_copy (&node, "status", status);
4610   if (mp->status)
4611     {
4612       vat_json_object_add_string_copy (&node, "locator_set",
4613                                        mp->locator_set_name);
4614     }
4615
4616   vec_free (status);
4617
4618   vat_json_print (vam->ofp, &node);
4619   vat_json_free (&node);
4620
4621   vam->retval = ntohl (mp->retval);
4622   vam->result_ready = 1;
4623 }
4624
4625 static u8 *
4626 format_policer_type (u8 * s, va_list * va)
4627 {
4628   u32 i = va_arg (*va, u32);
4629
4630   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4631     s = format (s, "1r2c");
4632   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4633     s = format (s, "1r3c");
4634   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4635     s = format (s, "2r3c-2698");
4636   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4637     s = format (s, "2r3c-4115");
4638   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4639     s = format (s, "2r3c-mef5cf1");
4640   else
4641     s = format (s, "ILLEGAL");
4642   return s;
4643 }
4644
4645 static u8 *
4646 format_policer_rate_type (u8 * s, va_list * va)
4647 {
4648   u32 i = va_arg (*va, u32);
4649
4650   if (i == SSE2_QOS_RATE_KBPS)
4651     s = format (s, "kbps");
4652   else if (i == SSE2_QOS_RATE_PPS)
4653     s = format (s, "pps");
4654   else
4655     s = format (s, "ILLEGAL");
4656   return s;
4657 }
4658
4659 static u8 *
4660 format_policer_round_type (u8 * s, va_list * va)
4661 {
4662   u32 i = va_arg (*va, u32);
4663
4664   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4665     s = format (s, "closest");
4666   else if (i == SSE2_QOS_ROUND_TO_UP)
4667     s = format (s, "up");
4668   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4669     s = format (s, "down");
4670   else
4671     s = format (s, "ILLEGAL");
4672   return s;
4673 }
4674
4675 static u8 *
4676 format_policer_action_type (u8 * s, va_list * va)
4677 {
4678   u32 i = va_arg (*va, u32);
4679
4680   if (i == SSE2_QOS_ACTION_DROP)
4681     s = format (s, "drop");
4682   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4683     s = format (s, "transmit");
4684   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4685     s = format (s, "mark-and-transmit");
4686   else
4687     s = format (s, "ILLEGAL");
4688   return s;
4689 }
4690
4691 static u8 *
4692 format_dscp (u8 * s, va_list * va)
4693 {
4694   u32 i = va_arg (*va, u32);
4695   char *t = 0;
4696
4697   switch (i)
4698     {
4699 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4700       foreach_vnet_dscp
4701 #undef _
4702     default:
4703       return format (s, "ILLEGAL");
4704     }
4705   s = format (s, "%s", t);
4706   return s;
4707 }
4708
4709 static void
4710 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4711 {
4712   vat_main_t *vam = &vat_main;
4713   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4714
4715   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4716     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4717   else
4718     conform_dscp_str = format (0, "");
4719
4720   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4721     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4722   else
4723     exceed_dscp_str = format (0, "");
4724
4725   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4726     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4727   else
4728     violate_dscp_str = format (0, "");
4729
4730   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4731          "rate type %U, round type %U, %s rate, %s color-aware, "
4732          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4733          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4734          "conform action %U%s, exceed action %U%s, violate action %U%s",
4735          mp->name,
4736          format_policer_type, mp->type,
4737          ntohl (mp->cir),
4738          ntohl (mp->eir),
4739          clib_net_to_host_u64 (mp->cb),
4740          clib_net_to_host_u64 (mp->eb),
4741          format_policer_rate_type, mp->rate_type,
4742          format_policer_round_type, mp->round_type,
4743          mp->single_rate ? "single" : "dual",
4744          mp->color_aware ? "is" : "not",
4745          ntohl (mp->cir_tokens_per_period),
4746          ntohl (mp->pir_tokens_per_period),
4747          ntohl (mp->scale),
4748          ntohl (mp->current_limit),
4749          ntohl (mp->current_bucket),
4750          ntohl (mp->extended_limit),
4751          ntohl (mp->extended_bucket),
4752          clib_net_to_host_u64 (mp->last_update_time),
4753          format_policer_action_type, mp->conform_action_type,
4754          conform_dscp_str,
4755          format_policer_action_type, mp->exceed_action_type,
4756          exceed_dscp_str,
4757          format_policer_action_type, mp->violate_action_type,
4758          violate_dscp_str);
4759
4760   vec_free (conform_dscp_str);
4761   vec_free (exceed_dscp_str);
4762   vec_free (violate_dscp_str);
4763 }
4764
4765 static void vl_api_policer_details_t_handler_json
4766   (vl_api_policer_details_t * mp)
4767 {
4768   vat_main_t *vam = &vat_main;
4769   vat_json_node_t *node;
4770   u8 *rate_type_str, *round_type_str, *type_str;
4771   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4772
4773   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4774   round_type_str =
4775     format (0, "%U", format_policer_round_type, mp->round_type);
4776   type_str = format (0, "%U", format_policer_type, mp->type);
4777   conform_action_str = format (0, "%U", format_policer_action_type,
4778                                mp->conform_action_type);
4779   exceed_action_str = format (0, "%U", format_policer_action_type,
4780                               mp->exceed_action_type);
4781   violate_action_str = format (0, "%U", format_policer_action_type,
4782                                mp->violate_action_type);
4783
4784   if (VAT_JSON_ARRAY != vam->json_tree.type)
4785     {
4786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4787       vat_json_init_array (&vam->json_tree);
4788     }
4789   node = vat_json_array_add (&vam->json_tree);
4790
4791   vat_json_init_object (node);
4792   vat_json_object_add_string_copy (node, "name", mp->name);
4793   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4794   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4795   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4796   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4797   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4798   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4799   vat_json_object_add_string_copy (node, "type", type_str);
4800   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4801   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4802   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4803   vat_json_object_add_uint (node, "cir_tokens_per_period",
4804                             ntohl (mp->cir_tokens_per_period));
4805   vat_json_object_add_uint (node, "eir_tokens_per_period",
4806                             ntohl (mp->pir_tokens_per_period));
4807   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4808   vat_json_object_add_uint (node, "current_bucket",
4809                             ntohl (mp->current_bucket));
4810   vat_json_object_add_uint (node, "extended_limit",
4811                             ntohl (mp->extended_limit));
4812   vat_json_object_add_uint (node, "extended_bucket",
4813                             ntohl (mp->extended_bucket));
4814   vat_json_object_add_uint (node, "last_update_time",
4815                             ntohl (mp->last_update_time));
4816   vat_json_object_add_string_copy (node, "conform_action",
4817                                    conform_action_str);
4818   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4819     {
4820       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4821       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4822       vec_free (dscp_str);
4823     }
4824   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4825   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4826     {
4827       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4828       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4829       vec_free (dscp_str);
4830     }
4831   vat_json_object_add_string_copy (node, "violate_action",
4832                                    violate_action_str);
4833   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4834     {
4835       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4836       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4837       vec_free (dscp_str);
4838     }
4839
4840   vec_free (rate_type_str);
4841   vec_free (round_type_str);
4842   vec_free (type_str);
4843   vec_free (conform_action_str);
4844   vec_free (exceed_action_str);
4845   vec_free (violate_action_str);
4846 }
4847
4848 static void
4849 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4850                                            mp)
4851 {
4852   vat_main_t *vam = &vat_main;
4853   int i, count = ntohl (mp->count);
4854
4855   if (count > 0)
4856     print (vam->ofp, "classify table ids (%d) : ", count);
4857   for (i = 0; i < count; i++)
4858     {
4859       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4860       print (vam->ofp, (i < count - 1) ? "," : "");
4861     }
4862   vam->retval = ntohl (mp->retval);
4863   vam->result_ready = 1;
4864 }
4865
4866 static void
4867   vl_api_classify_table_ids_reply_t_handler_json
4868   (vl_api_classify_table_ids_reply_t * mp)
4869 {
4870   vat_main_t *vam = &vat_main;
4871   int i, count = ntohl (mp->count);
4872
4873   if (count > 0)
4874     {
4875       vat_json_node_t node;
4876
4877       vat_json_init_object (&node);
4878       for (i = 0; i < count; i++)
4879         {
4880           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4881         }
4882       vat_json_print (vam->ofp, &node);
4883       vat_json_free (&node);
4884     }
4885   vam->retval = ntohl (mp->retval);
4886   vam->result_ready = 1;
4887 }
4888
4889 static void
4890   vl_api_classify_table_by_interface_reply_t_handler
4891   (vl_api_classify_table_by_interface_reply_t * mp)
4892 {
4893   vat_main_t *vam = &vat_main;
4894   u32 table_id;
4895
4896   table_id = ntohl (mp->l2_table_id);
4897   if (table_id != ~0)
4898     print (vam->ofp, "l2 table id : %d", table_id);
4899   else
4900     print (vam->ofp, "l2 table id : No input ACL tables configured");
4901   table_id = ntohl (mp->ip4_table_id);
4902   if (table_id != ~0)
4903     print (vam->ofp, "ip4 table id : %d", table_id);
4904   else
4905     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4906   table_id = ntohl (mp->ip6_table_id);
4907   if (table_id != ~0)
4908     print (vam->ofp, "ip6 table id : %d", table_id);
4909   else
4910     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4911   vam->retval = ntohl (mp->retval);
4912   vam->result_ready = 1;
4913 }
4914
4915 static void
4916   vl_api_classify_table_by_interface_reply_t_handler_json
4917   (vl_api_classify_table_by_interface_reply_t * mp)
4918 {
4919   vat_main_t *vam = &vat_main;
4920   vat_json_node_t node;
4921
4922   vat_json_init_object (&node);
4923
4924   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4925   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4926   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4927
4928   vat_json_print (vam->ofp, &node);
4929   vat_json_free (&node);
4930
4931   vam->retval = ntohl (mp->retval);
4932   vam->result_ready = 1;
4933 }
4934
4935 static void vl_api_policer_add_del_reply_t_handler
4936   (vl_api_policer_add_del_reply_t * mp)
4937 {
4938   vat_main_t *vam = &vat_main;
4939   i32 retval = ntohl (mp->retval);
4940   if (vam->async_mode)
4941     {
4942       vam->async_errors += (retval < 0);
4943     }
4944   else
4945     {
4946       vam->retval = retval;
4947       vam->result_ready = 1;
4948       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4949         /*
4950          * Note: this is just barely thread-safe, depends on
4951          * the main thread spinning waiting for an answer...
4952          */
4953         errmsg ("policer index %d", ntohl (mp->policer_index));
4954     }
4955 }
4956
4957 static void vl_api_policer_add_del_reply_t_handler_json
4958   (vl_api_policer_add_del_reply_t * mp)
4959 {
4960   vat_main_t *vam = &vat_main;
4961   vat_json_node_t node;
4962
4963   vat_json_init_object (&node);
4964   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4965   vat_json_object_add_uint (&node, "policer_index",
4966                             ntohl (mp->policer_index));
4967
4968   vat_json_print (vam->ofp, &node);
4969   vat_json_free (&node);
4970
4971   vam->retval = ntohl (mp->retval);
4972   vam->result_ready = 1;
4973 }
4974
4975 /* Format hex dump. */
4976 u8 *
4977 format_hex_bytes (u8 * s, va_list * va)
4978 {
4979   u8 *bytes = va_arg (*va, u8 *);
4980   int n_bytes = va_arg (*va, int);
4981   uword i;
4982
4983   /* Print short or long form depending on byte count. */
4984   uword short_form = n_bytes <= 32;
4985   u32 indent = format_get_indent (s);
4986
4987   if (n_bytes == 0)
4988     return s;
4989
4990   for (i = 0; i < n_bytes; i++)
4991     {
4992       if (!short_form && (i % 32) == 0)
4993         s = format (s, "%08x: ", i);
4994       s = format (s, "%02x", bytes[i]);
4995       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4996         s = format (s, "\n%U", format_white_space, indent);
4997     }
4998
4999   return s;
5000 }
5001
5002 static void
5003 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5004                                             * mp)
5005 {
5006   vat_main_t *vam = &vat_main;
5007   i32 retval = ntohl (mp->retval);
5008   if (retval == 0)
5009     {
5010       print (vam->ofp, "classify table info :");
5011       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5012              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5013              ntohl (mp->miss_next_index));
5014       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5015              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5016              ntohl (mp->match_n_vectors));
5017       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5018              ntohl (mp->mask_length));
5019     }
5020   vam->retval = retval;
5021   vam->result_ready = 1;
5022 }
5023
5024 static void
5025   vl_api_classify_table_info_reply_t_handler_json
5026   (vl_api_classify_table_info_reply_t * mp)
5027 {
5028   vat_main_t *vam = &vat_main;
5029   vat_json_node_t node;
5030
5031   i32 retval = ntohl (mp->retval);
5032   if (retval == 0)
5033     {
5034       vat_json_init_object (&node);
5035
5036       vat_json_object_add_int (&node, "sessions",
5037                                ntohl (mp->active_sessions));
5038       vat_json_object_add_int (&node, "nexttbl",
5039                                ntohl (mp->next_table_index));
5040       vat_json_object_add_int (&node, "nextnode",
5041                                ntohl (mp->miss_next_index));
5042       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5043       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5044       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5045       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5046                       ntohl (mp->mask_length), 0);
5047       vat_json_object_add_string_copy (&node, "mask", s);
5048
5049       vat_json_print (vam->ofp, &node);
5050       vat_json_free (&node);
5051     }
5052   vam->retval = ntohl (mp->retval);
5053   vam->result_ready = 1;
5054 }
5055
5056 static void
5057 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5058                                            mp)
5059 {
5060   vat_main_t *vam = &vat_main;
5061
5062   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5063          ntohl (mp->hit_next_index), ntohl (mp->advance),
5064          ntohl (mp->opaque_index));
5065   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5066          ntohl (mp->match_length));
5067 }
5068
5069 static void
5070   vl_api_classify_session_details_t_handler_json
5071   (vl_api_classify_session_details_t * mp)
5072 {
5073   vat_main_t *vam = &vat_main;
5074   vat_json_node_t *node = NULL;
5075
5076   if (VAT_JSON_ARRAY != vam->json_tree.type)
5077     {
5078       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5079       vat_json_init_array (&vam->json_tree);
5080     }
5081   node = vat_json_array_add (&vam->json_tree);
5082
5083   vat_json_init_object (node);
5084   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5085   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5086   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5087   u8 *s =
5088     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5089             0);
5090   vat_json_object_add_string_copy (node, "match", s);
5091 }
5092
5093 static void vl_api_pg_create_interface_reply_t_handler
5094   (vl_api_pg_create_interface_reply_t * mp)
5095 {
5096   vat_main_t *vam = &vat_main;
5097
5098   vam->retval = ntohl (mp->retval);
5099   vam->result_ready = 1;
5100 }
5101
5102 static void vl_api_pg_create_interface_reply_t_handler_json
5103   (vl_api_pg_create_interface_reply_t * mp)
5104 {
5105   vat_main_t *vam = &vat_main;
5106   vat_json_node_t node;
5107
5108   i32 retval = ntohl (mp->retval);
5109   if (retval == 0)
5110     {
5111       vat_json_init_object (&node);
5112
5113       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5114
5115       vat_json_print (vam->ofp, &node);
5116       vat_json_free (&node);
5117     }
5118   vam->retval = ntohl (mp->retval);
5119   vam->result_ready = 1;
5120 }
5121
5122 static void vl_api_policer_classify_details_t_handler
5123   (vl_api_policer_classify_details_t * mp)
5124 {
5125   vat_main_t *vam = &vat_main;
5126
5127   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5128          ntohl (mp->table_index));
5129 }
5130
5131 static void vl_api_policer_classify_details_t_handler_json
5132   (vl_api_policer_classify_details_t * mp)
5133 {
5134   vat_main_t *vam = &vat_main;
5135   vat_json_node_t *node;
5136
5137   if (VAT_JSON_ARRAY != vam->json_tree.type)
5138     {
5139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5140       vat_json_init_array (&vam->json_tree);
5141     }
5142   node = vat_json_array_add (&vam->json_tree);
5143
5144   vat_json_init_object (node);
5145   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5146   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5147 }
5148
5149 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5150   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5151 {
5152   vat_main_t *vam = &vat_main;
5153   i32 retval = ntohl (mp->retval);
5154   if (vam->async_mode)
5155     {
5156       vam->async_errors += (retval < 0);
5157     }
5158   else
5159     {
5160       vam->retval = retval;
5161       vam->sw_if_index = ntohl (mp->sw_if_index);
5162       vam->result_ready = 1;
5163     }
5164 }
5165
5166 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5167   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5168 {
5169   vat_main_t *vam = &vat_main;
5170   vat_json_node_t node;
5171
5172   vat_json_init_object (&node);
5173   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5174   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5175
5176   vat_json_print (vam->ofp, &node);
5177   vat_json_free (&node);
5178
5179   vam->retval = ntohl (mp->retval);
5180   vam->result_ready = 1;
5181 }
5182
5183 static void vl_api_flow_classify_details_t_handler
5184   (vl_api_flow_classify_details_t * mp)
5185 {
5186   vat_main_t *vam = &vat_main;
5187
5188   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5189          ntohl (mp->table_index));
5190 }
5191
5192 static void vl_api_flow_classify_details_t_handler_json
5193   (vl_api_flow_classify_details_t * mp)
5194 {
5195   vat_main_t *vam = &vat_main;
5196   vat_json_node_t *node;
5197
5198   if (VAT_JSON_ARRAY != vam->json_tree.type)
5199     {
5200       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5201       vat_json_init_array (&vam->json_tree);
5202     }
5203   node = vat_json_array_add (&vam->json_tree);
5204
5205   vat_json_init_object (node);
5206   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5207   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5208 }
5209
5210 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5211 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5212 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5213 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5214 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5215 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5216 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5217 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5218 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5219 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5220 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5221 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5222 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5223 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5224 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5225 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5226 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5227 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5228 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5229 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5230 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5231 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5232
5233 /*
5234  * Generate boilerplate reply handlers, which
5235  * dig the return value out of the xxx_reply_t API message,
5236  * stick it into vam->retval, and set vam->result_ready
5237  *
5238  * Could also do this by pointing N message decode slots at
5239  * a single function, but that could break in subtle ways.
5240  */
5241
5242 #define foreach_standard_reply_retval_handler           \
5243 _(sw_interface_set_flags_reply)                         \
5244 _(sw_interface_add_del_address_reply)                   \
5245 _(sw_interface_set_rx_mode_reply)                       \
5246 _(sw_interface_set_table_reply)                         \
5247 _(sw_interface_set_mpls_enable_reply)                   \
5248 _(sw_interface_set_vpath_reply)                         \
5249 _(sw_interface_set_vxlan_bypass_reply)                  \
5250 _(sw_interface_set_geneve_bypass_reply)                 \
5251 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5252 _(sw_interface_set_l2_bridge_reply)                     \
5253 _(bridge_domain_add_del_reply)                          \
5254 _(sw_interface_set_l2_xconnect_reply)                   \
5255 _(l2fib_add_del_reply)                                  \
5256 _(l2fib_flush_int_reply)                                \
5257 _(l2fib_flush_bd_reply)                                 \
5258 _(ip_add_del_route_reply)                               \
5259 _(ip_table_add_del_reply)                               \
5260 _(ip_mroute_add_del_reply)                              \
5261 _(mpls_route_add_del_reply)                             \
5262 _(mpls_table_add_del_reply)                             \
5263 _(mpls_ip_bind_unbind_reply)                            \
5264 _(bier_route_add_del_reply)                             \
5265 _(bier_table_add_del_reply)                             \
5266 _(proxy_arp_add_del_reply)                              \
5267 _(proxy_arp_intfc_enable_disable_reply)                 \
5268 _(sw_interface_set_unnumbered_reply)                    \
5269 _(ip_neighbor_add_del_reply)                            \
5270 _(oam_add_del_reply)                                    \
5271 _(reset_fib_reply)                                      \
5272 _(dhcp_proxy_config_reply)                              \
5273 _(dhcp_proxy_set_vss_reply)                             \
5274 _(dhcp_client_config_reply)                             \
5275 _(set_ip_flow_hash_reply)                               \
5276 _(sw_interface_ip6_enable_disable_reply)                \
5277 _(sw_interface_ip6_set_link_local_address_reply)        \
5278 _(ip6nd_proxy_add_del_reply)                            \
5279 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5280 _(sw_interface_ip6nd_ra_config_reply)                   \
5281 _(set_arp_neighbor_limit_reply)                         \
5282 _(l2_patch_add_del_reply)                               \
5283 _(sr_policy_add_reply)                                  \
5284 _(sr_policy_mod_reply)                                  \
5285 _(sr_policy_del_reply)                                  \
5286 _(sr_localsid_add_del_reply)                            \
5287 _(sr_steering_add_del_reply)                            \
5288 _(classify_add_del_session_reply)                       \
5289 _(classify_set_interface_ip_table_reply)                \
5290 _(classify_set_interface_l2_tables_reply)               \
5291 _(l2tpv3_set_tunnel_cookies_reply)                      \
5292 _(l2tpv3_interface_enable_disable_reply)                \
5293 _(l2tpv3_set_lookup_key_reply)                          \
5294 _(l2_fib_clear_table_reply)                             \
5295 _(l2_interface_efp_filter_reply)                        \
5296 _(l2_interface_vlan_tag_rewrite_reply)                  \
5297 _(modify_vhost_user_if_reply)                           \
5298 _(delete_vhost_user_if_reply)                           \
5299 _(want_ip4_arp_events_reply)                            \
5300 _(want_ip6_nd_events_reply)                             \
5301 _(want_l2_macs_events_reply)                            \
5302 _(input_acl_set_interface_reply)                        \
5303 _(ipsec_spd_add_del_reply)                              \
5304 _(ipsec_interface_add_del_spd_reply)                    \
5305 _(ipsec_spd_add_del_entry_reply)                        \
5306 _(ipsec_sad_add_del_entry_reply)                        \
5307 _(ipsec_sa_set_key_reply)                               \
5308 _(ipsec_tunnel_if_add_del_reply)                        \
5309 _(ipsec_tunnel_if_set_key_reply)                        \
5310 _(ipsec_tunnel_if_set_sa_reply)                         \
5311 _(ikev2_profile_add_del_reply)                          \
5312 _(ikev2_profile_set_auth_reply)                         \
5313 _(ikev2_profile_set_id_reply)                           \
5314 _(ikev2_profile_set_ts_reply)                           \
5315 _(ikev2_set_local_key_reply)                            \
5316 _(ikev2_set_responder_reply)                            \
5317 _(ikev2_set_ike_transforms_reply)                       \
5318 _(ikev2_set_esp_transforms_reply)                       \
5319 _(ikev2_set_sa_lifetime_reply)                          \
5320 _(ikev2_initiate_sa_init_reply)                         \
5321 _(ikev2_initiate_del_ike_sa_reply)                      \
5322 _(ikev2_initiate_del_child_sa_reply)                    \
5323 _(ikev2_initiate_rekey_child_sa_reply)                  \
5324 _(delete_loopback_reply)                                \
5325 _(bd_ip_mac_add_del_reply)                              \
5326 _(map_del_domain_reply)                                 \
5327 _(map_add_del_rule_reply)                               \
5328 _(want_interface_events_reply)                          \
5329 _(want_stats_reply)                                     \
5330 _(cop_interface_enable_disable_reply)                   \
5331 _(cop_whitelist_enable_disable_reply)                   \
5332 _(sw_interface_clear_stats_reply)                       \
5333 _(ioam_enable_reply)                                    \
5334 _(ioam_disable_reply)                                   \
5335 _(one_add_del_locator_reply)                            \
5336 _(one_add_del_local_eid_reply)                          \
5337 _(one_add_del_remote_mapping_reply)                     \
5338 _(one_add_del_adjacency_reply)                          \
5339 _(one_add_del_map_resolver_reply)                       \
5340 _(one_add_del_map_server_reply)                         \
5341 _(one_enable_disable_reply)                             \
5342 _(one_rloc_probe_enable_disable_reply)                  \
5343 _(one_map_register_enable_disable_reply)                \
5344 _(one_map_register_set_ttl_reply)                       \
5345 _(one_set_transport_protocol_reply)                     \
5346 _(one_map_register_fallback_threshold_reply)            \
5347 _(one_pitr_set_locator_set_reply)                       \
5348 _(one_map_request_mode_reply)                           \
5349 _(one_add_del_map_request_itr_rlocs_reply)              \
5350 _(one_eid_table_add_del_map_reply)                      \
5351 _(one_use_petr_reply)                                   \
5352 _(one_stats_enable_disable_reply)                       \
5353 _(one_add_del_l2_arp_entry_reply)                       \
5354 _(one_add_del_ndp_entry_reply)                          \
5355 _(one_stats_flush_reply)                                \
5356 _(one_enable_disable_xtr_mode_reply)                    \
5357 _(one_enable_disable_pitr_mode_reply)                   \
5358 _(one_enable_disable_petr_mode_reply)                   \
5359 _(gpe_enable_disable_reply)                             \
5360 _(gpe_set_encap_mode_reply)                             \
5361 _(gpe_add_del_iface_reply)                              \
5362 _(gpe_add_del_native_fwd_rpath_reply)                   \
5363 _(af_packet_delete_reply)                               \
5364 _(policer_classify_set_interface_reply)                 \
5365 _(netmap_create_reply)                                  \
5366 _(netmap_delete_reply)                                  \
5367 _(set_ipfix_exporter_reply)                             \
5368 _(set_ipfix_classify_stream_reply)                      \
5369 _(ipfix_classify_table_add_del_reply)                   \
5370 _(flow_classify_set_interface_reply)                    \
5371 _(sw_interface_span_enable_disable_reply)               \
5372 _(pg_capture_reply)                                     \
5373 _(pg_enable_disable_reply)                              \
5374 _(ip_source_and_port_range_check_add_del_reply)         \
5375 _(ip_source_and_port_range_check_interface_add_del_reply)\
5376 _(delete_subif_reply)                                   \
5377 _(l2_interface_pbb_tag_rewrite_reply)                   \
5378 _(punt_reply)                                           \
5379 _(feature_enable_disable_reply)                         \
5380 _(sw_interface_tag_add_del_reply)                       \
5381 _(sw_interface_set_mtu_reply)                           \
5382 _(p2p_ethernet_add_reply)                               \
5383 _(p2p_ethernet_del_reply)                               \
5384 _(lldp_config_reply)                                    \
5385 _(sw_interface_set_lldp_reply)                          \
5386 _(tcp_configure_src_addresses_reply)                    \
5387 _(dns_enable_disable_reply)                             \
5388 _(dns_name_server_add_del_reply)                        \
5389 _(session_rule_add_del_reply)                           \
5390 _(ip_container_proxy_add_del_reply)
5391
5392 #define _(n)                                    \
5393     static void vl_api_##n##_t_handler          \
5394     (vl_api_##n##_t * mp)                       \
5395     {                                           \
5396         vat_main_t * vam = &vat_main;           \
5397         i32 retval = ntohl(mp->retval);         \
5398         if (vam->async_mode) {                  \
5399             vam->async_errors += (retval < 0);  \
5400         } else {                                \
5401             vam->retval = retval;               \
5402             vam->result_ready = 1;              \
5403         }                                       \
5404     }
5405 foreach_standard_reply_retval_handler;
5406 #undef _
5407
5408 #define _(n)                                    \
5409     static void vl_api_##n##_t_handler_json     \
5410     (vl_api_##n##_t * mp)                       \
5411     {                                           \
5412         vat_main_t * vam = &vat_main;           \
5413         vat_json_node_t node;                   \
5414         vat_json_init_object(&node);            \
5415         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5416         vat_json_print(vam->ofp, &node);        \
5417         vam->retval = ntohl(mp->retval);        \
5418         vam->result_ready = 1;                  \
5419     }
5420 foreach_standard_reply_retval_handler;
5421 #undef _
5422
5423 /*
5424  * Table of message reply handlers, must include boilerplate handlers
5425  * we just generated
5426  */
5427
5428 #define foreach_vpe_api_reply_msg                                       \
5429 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5430 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5431 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5432 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5433 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5434 _(CLI_REPLY, cli_reply)                                                 \
5435 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5436 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5437   sw_interface_add_del_address_reply)                                   \
5438 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5439 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5440 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5441 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5442 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5443 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5444 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5445 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5446   sw_interface_set_l2_xconnect_reply)                                   \
5447 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5448   sw_interface_set_l2_bridge_reply)                                     \
5449 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5450 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5451 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5452 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5453 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5454 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5455 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5456 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5457 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5458 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5459 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5460 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5461 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5462 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5463 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5464 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5465 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5466 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5467 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5468 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5469 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5470 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5471 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5472 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5473 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5474   proxy_arp_intfc_enable_disable_reply)                                 \
5475 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5476 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5477   sw_interface_set_unnumbered_reply)                                    \
5478 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5479 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5480 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5481 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5482 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5483 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5484 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5485 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5486 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5487 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5488 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5489   sw_interface_ip6_enable_disable_reply)                                \
5490 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5491   sw_interface_ip6_set_link_local_address_reply)                        \
5492 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5493 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5494 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5495   sw_interface_ip6nd_ra_prefix_reply)                                   \
5496 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5497   sw_interface_ip6nd_ra_config_reply)                                   \
5498 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5499 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5500 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5501 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5502 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5503 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5504 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5505 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5506 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5507 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5508 classify_set_interface_ip_table_reply)                                  \
5509 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5510   classify_set_interface_l2_tables_reply)                               \
5511 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5512 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5513 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5514 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5515 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5516   l2tpv3_interface_enable_disable_reply)                                \
5517 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5518 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5519 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5520 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5521 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5522 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5523 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5524 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5525 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5526 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5527 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5528 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5529 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5530 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5531 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5532 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5533 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5534 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5535 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5536 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5537 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5538 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5539 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5540 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5541 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5542 _(L2_MACS_EVENT, l2_macs_event)                                         \
5543 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5544 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5545 _(IP_DETAILS, ip_details)                                               \
5546 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5547 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5548 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5549 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5550 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5551 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5552 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5553 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5554 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5555 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5556 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5557 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5558 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5559 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5560 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5561 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5562 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5563 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5564 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5565 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5566 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5567 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5568 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5569 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5570 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5571 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5572 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5573 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5574 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5575 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5576 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5577 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5578 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5579 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5580 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5581 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5582 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5583 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5584 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5585 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5586 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5587 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5588 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5589 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5590 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5591 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5592 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5593 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5594   one_map_register_enable_disable_reply)                                \
5595 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5596 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5597 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5598 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5599   one_map_register_fallback_threshold_reply)                            \
5600 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5601   one_rloc_probe_enable_disable_reply)                                  \
5602 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5603 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5604 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5605 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5606 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5607 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5608 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5609 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5610 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5611 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5612 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5613 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5614 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5615 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5616 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5617 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5618   show_one_stats_enable_disable_reply)                                  \
5619 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5620 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5621 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5622 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5623 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5624 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5625 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5626 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5627   one_enable_disable_pitr_mode_reply)                                   \
5628 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5629   one_enable_disable_petr_mode_reply)                                   \
5630 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5631 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5632 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5633 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5634 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5635 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5636 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5637 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5638 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5639 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5640 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5641 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5642   gpe_add_del_native_fwd_rpath_reply)                                   \
5643 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5644   gpe_fwd_entry_path_details)                                           \
5645 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5646 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5647   one_add_del_map_request_itr_rlocs_reply)                              \
5648 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5649   one_get_map_request_itr_rlocs_reply)                                  \
5650 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5651 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5652 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5653 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5654 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5655 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5656   show_one_map_register_state_reply)                                    \
5657 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5658 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5659   show_one_map_register_fallback_threshold_reply)                       \
5660 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5661 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5662 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5663 _(POLICER_DETAILS, policer_details)                                     \
5664 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5665 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5666 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5667 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5668 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5669 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5670 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5671 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5672 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5673 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5674 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5675 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5676 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5677 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5678 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5679 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5680 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5681 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5682 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5683 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5684 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5685 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5686 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5687 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5688 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5689  ip_source_and_port_range_check_add_del_reply)                          \
5690 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5691  ip_source_and_port_range_check_interface_add_del_reply)                \
5692 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5693 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5694 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5695 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5696 _(PUNT_REPLY, punt_reply)                                               \
5697 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5698 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5699 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5700 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5701 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5702 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5703 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5704 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5705 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5706 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5707 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5708 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5709 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5710 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5711 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5712 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5713 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5714 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5715 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5716 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5717 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5718
5719 #define foreach_standalone_reply_msg                                    \
5720 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5721 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5722 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5723 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5724 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5725 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5726 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5727 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5728
5729 typedef struct
5730 {
5731   u8 *name;
5732   u32 value;
5733 } name_sort_t;
5734
5735
5736 #define STR_VTR_OP_CASE(op)     \
5737     case L2_VTR_ ## op:         \
5738         return "" # op;
5739
5740 static const char *
5741 str_vtr_op (u32 vtr_op)
5742 {
5743   switch (vtr_op)
5744     {
5745       STR_VTR_OP_CASE (DISABLED);
5746       STR_VTR_OP_CASE (PUSH_1);
5747       STR_VTR_OP_CASE (PUSH_2);
5748       STR_VTR_OP_CASE (POP_1);
5749       STR_VTR_OP_CASE (POP_2);
5750       STR_VTR_OP_CASE (TRANSLATE_1_1);
5751       STR_VTR_OP_CASE (TRANSLATE_1_2);
5752       STR_VTR_OP_CASE (TRANSLATE_2_1);
5753       STR_VTR_OP_CASE (TRANSLATE_2_2);
5754     }
5755
5756   return "UNKNOWN";
5757 }
5758
5759 static int
5760 dump_sub_interface_table (vat_main_t * vam)
5761 {
5762   const sw_interface_subif_t *sub = NULL;
5763
5764   if (vam->json_output)
5765     {
5766       clib_warning
5767         ("JSON output supported only for VPE API calls and dump_stats_table");
5768       return -99;
5769     }
5770
5771   print (vam->ofp,
5772          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5773          "Interface", "sw_if_index",
5774          "sub id", "dot1ad", "tags", "outer id",
5775          "inner id", "exact", "default", "outer any", "inner any");
5776
5777   vec_foreach (sub, vam->sw_if_subif_table)
5778   {
5779     print (vam->ofp,
5780            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5781            sub->interface_name,
5782            sub->sw_if_index,
5783            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5784            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5785            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5786            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5787     if (sub->vtr_op != L2_VTR_DISABLED)
5788       {
5789         print (vam->ofp,
5790                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5791                "tag1: %d tag2: %d ]",
5792                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5793                sub->vtr_tag1, sub->vtr_tag2);
5794       }
5795   }
5796
5797   return 0;
5798 }
5799
5800 static int
5801 name_sort_cmp (void *a1, void *a2)
5802 {
5803   name_sort_t *n1 = a1;
5804   name_sort_t *n2 = a2;
5805
5806   return strcmp ((char *) n1->name, (char *) n2->name);
5807 }
5808
5809 static int
5810 dump_interface_table (vat_main_t * vam)
5811 {
5812   hash_pair_t *p;
5813   name_sort_t *nses = 0, *ns;
5814
5815   if (vam->json_output)
5816     {
5817       clib_warning
5818         ("JSON output supported only for VPE API calls and dump_stats_table");
5819       return -99;
5820     }
5821
5822   /* *INDENT-OFF* */
5823   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5824   ({
5825     vec_add2 (nses, ns, 1);
5826     ns->name = (u8 *)(p->key);
5827     ns->value = (u32) p->value[0];
5828   }));
5829   /* *INDENT-ON* */
5830
5831   vec_sort_with_function (nses, name_sort_cmp);
5832
5833   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5834   vec_foreach (ns, nses)
5835   {
5836     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5837   }
5838   vec_free (nses);
5839   return 0;
5840 }
5841
5842 static int
5843 dump_ip_table (vat_main_t * vam, int is_ipv6)
5844 {
5845   const ip_details_t *det = NULL;
5846   const ip_address_details_t *address = NULL;
5847   u32 i = ~0;
5848
5849   print (vam->ofp, "%-12s", "sw_if_index");
5850
5851   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5852   {
5853     i++;
5854     if (!det->present)
5855       {
5856         continue;
5857       }
5858     print (vam->ofp, "%-12d", i);
5859     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5860     if (!det->addr)
5861       {
5862         continue;
5863       }
5864     vec_foreach (address, det->addr)
5865     {
5866       print (vam->ofp,
5867              "            %-30U%-13d",
5868              is_ipv6 ? format_ip6_address : format_ip4_address,
5869              address->ip, address->prefix_length);
5870     }
5871   }
5872
5873   return 0;
5874 }
5875
5876 static int
5877 dump_ipv4_table (vat_main_t * vam)
5878 {
5879   if (vam->json_output)
5880     {
5881       clib_warning
5882         ("JSON output supported only for VPE API calls and dump_stats_table");
5883       return -99;
5884     }
5885
5886   return dump_ip_table (vam, 0);
5887 }
5888
5889 static int
5890 dump_ipv6_table (vat_main_t * vam)
5891 {
5892   if (vam->json_output)
5893     {
5894       clib_warning
5895         ("JSON output supported only for VPE API calls and dump_stats_table");
5896       return -99;
5897     }
5898
5899   return dump_ip_table (vam, 1);
5900 }
5901
5902 static char *
5903 counter_type_to_str (u8 counter_type, u8 is_combined)
5904 {
5905   if (!is_combined)
5906     {
5907       switch (counter_type)
5908         {
5909         case VNET_INTERFACE_COUNTER_DROP:
5910           return "drop";
5911         case VNET_INTERFACE_COUNTER_PUNT:
5912           return "punt";
5913         case VNET_INTERFACE_COUNTER_IP4:
5914           return "ip4";
5915         case VNET_INTERFACE_COUNTER_IP6:
5916           return "ip6";
5917         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5918           return "rx-no-buf";
5919         case VNET_INTERFACE_COUNTER_RX_MISS:
5920           return "rx-miss";
5921         case VNET_INTERFACE_COUNTER_RX_ERROR:
5922           return "rx-error";
5923         case VNET_INTERFACE_COUNTER_TX_ERROR:
5924           return "tx-error";
5925         default:
5926           return "INVALID-COUNTER-TYPE";
5927         }
5928     }
5929   else
5930     {
5931       switch (counter_type)
5932         {
5933         case VNET_INTERFACE_COUNTER_RX:
5934           return "rx";
5935         case VNET_INTERFACE_COUNTER_TX:
5936           return "tx";
5937         default:
5938           return "INVALID-COUNTER-TYPE";
5939         }
5940     }
5941 }
5942
5943 static int
5944 dump_stats_table (vat_main_t * vam)
5945 {
5946   vat_json_node_t node;
5947   vat_json_node_t *msg_array;
5948   vat_json_node_t *msg;
5949   vat_json_node_t *counter_array;
5950   vat_json_node_t *counter;
5951   interface_counter_t c;
5952   u64 packets;
5953   ip4_fib_counter_t *c4;
5954   ip6_fib_counter_t *c6;
5955   ip4_nbr_counter_t *n4;
5956   ip6_nbr_counter_t *n6;
5957   int i, j;
5958
5959   if (!vam->json_output)
5960     {
5961       clib_warning ("dump_stats_table supported only in JSON format");
5962       return -99;
5963     }
5964
5965   vat_json_init_object (&node);
5966
5967   /* interface counters */
5968   msg_array = vat_json_object_add (&node, "interface_counters");
5969   vat_json_init_array (msg_array);
5970   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5971     {
5972       msg = vat_json_array_add (msg_array);
5973       vat_json_init_object (msg);
5974       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5975                                        (u8 *) counter_type_to_str (i, 0));
5976       vat_json_object_add_int (msg, "is_combined", 0);
5977       counter_array = vat_json_object_add (msg, "data");
5978       vat_json_init_array (counter_array);
5979       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5980         {
5981           packets = vam->simple_interface_counters[i][j];
5982           vat_json_array_add_uint (counter_array, packets);
5983         }
5984     }
5985   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5986     {
5987       msg = vat_json_array_add (msg_array);
5988       vat_json_init_object (msg);
5989       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5990                                        (u8 *) counter_type_to_str (i, 1));
5991       vat_json_object_add_int (msg, "is_combined", 1);
5992       counter_array = vat_json_object_add (msg, "data");
5993       vat_json_init_array (counter_array);
5994       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5995         {
5996           c = vam->combined_interface_counters[i][j];
5997           counter = vat_json_array_add (counter_array);
5998           vat_json_init_object (counter);
5999           vat_json_object_add_uint (counter, "packets", c.packets);
6000           vat_json_object_add_uint (counter, "bytes", c.bytes);
6001         }
6002     }
6003
6004   /* ip4 fib counters */
6005   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6006   vat_json_init_array (msg_array);
6007   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6008     {
6009       msg = vat_json_array_add (msg_array);
6010       vat_json_init_object (msg);
6011       vat_json_object_add_uint (msg, "vrf_id",
6012                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6013       counter_array = vat_json_object_add (msg, "c");
6014       vat_json_init_array (counter_array);
6015       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6016         {
6017           counter = vat_json_array_add (counter_array);
6018           vat_json_init_object (counter);
6019           c4 = &vam->ip4_fib_counters[i][j];
6020           vat_json_object_add_ip4 (counter, "address", c4->address);
6021           vat_json_object_add_uint (counter, "address_length",
6022                                     c4->address_length);
6023           vat_json_object_add_uint (counter, "packets", c4->packets);
6024           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6025         }
6026     }
6027
6028   /* ip6 fib counters */
6029   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6030   vat_json_init_array (msg_array);
6031   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6032     {
6033       msg = vat_json_array_add (msg_array);
6034       vat_json_init_object (msg);
6035       vat_json_object_add_uint (msg, "vrf_id",
6036                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6037       counter_array = vat_json_object_add (msg, "c");
6038       vat_json_init_array (counter_array);
6039       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6040         {
6041           counter = vat_json_array_add (counter_array);
6042           vat_json_init_object (counter);
6043           c6 = &vam->ip6_fib_counters[i][j];
6044           vat_json_object_add_ip6 (counter, "address", c6->address);
6045           vat_json_object_add_uint (counter, "address_length",
6046                                     c6->address_length);
6047           vat_json_object_add_uint (counter, "packets", c6->packets);
6048           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6049         }
6050     }
6051
6052   /* ip4 nbr counters */
6053   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6054   vat_json_init_array (msg_array);
6055   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6056     {
6057       msg = vat_json_array_add (msg_array);
6058       vat_json_init_object (msg);
6059       vat_json_object_add_uint (msg, "sw_if_index", i);
6060       counter_array = vat_json_object_add (msg, "c");
6061       vat_json_init_array (counter_array);
6062       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6063         {
6064           counter = vat_json_array_add (counter_array);
6065           vat_json_init_object (counter);
6066           n4 = &vam->ip4_nbr_counters[i][j];
6067           vat_json_object_add_ip4 (counter, "address", n4->address);
6068           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6069           vat_json_object_add_uint (counter, "packets", n4->packets);
6070           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6071         }
6072     }
6073
6074   /* ip6 nbr counters */
6075   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6076   vat_json_init_array (msg_array);
6077   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6078     {
6079       msg = vat_json_array_add (msg_array);
6080       vat_json_init_object (msg);
6081       vat_json_object_add_uint (msg, "sw_if_index", i);
6082       counter_array = vat_json_object_add (msg, "c");
6083       vat_json_init_array (counter_array);
6084       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6085         {
6086           counter = vat_json_array_add (counter_array);
6087           vat_json_init_object (counter);
6088           n6 = &vam->ip6_nbr_counters[i][j];
6089           vat_json_object_add_ip6 (counter, "address", n6->address);
6090           vat_json_object_add_uint (counter, "packets", n6->packets);
6091           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6092         }
6093     }
6094
6095   vat_json_print (vam->ofp, &node);
6096   vat_json_free (&node);
6097
6098   return 0;
6099 }
6100
6101 /*
6102  * Pass CLI buffers directly in the CLI_INBAND API message,
6103  * instead of an additional shared memory area.
6104  */
6105 static int
6106 exec_inband (vat_main_t * vam)
6107 {
6108   vl_api_cli_inband_t *mp;
6109   unformat_input_t *i = vam->input;
6110   int ret;
6111
6112   if (vec_len (i->buffer) == 0)
6113     return -1;
6114
6115   if (vam->exec_mode == 0 && unformat (i, "mode"))
6116     {
6117       vam->exec_mode = 1;
6118       return 0;
6119     }
6120   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6121     {
6122       vam->exec_mode = 0;
6123       return 0;
6124     }
6125
6126   /*
6127    * In order for the CLI command to work, it
6128    * must be a vector ending in \n, not a C-string ending
6129    * in \n\0.
6130    */
6131   u32 len = vec_len (vam->input->buffer);
6132   M2 (CLI_INBAND, mp, len);
6133   clib_memcpy (mp->cmd, vam->input->buffer, len);
6134   mp->length = htonl (len);
6135
6136   S (mp);
6137   W (ret);
6138   /* json responses may or may not include a useful reply... */
6139   if (vec_len (vam->cmd_reply))
6140     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6141   return ret;
6142 }
6143
6144 int
6145 exec (vat_main_t * vam)
6146 {
6147   return exec_inband (vam);
6148 }
6149
6150 static int
6151 api_create_loopback (vat_main_t * vam)
6152 {
6153   unformat_input_t *i = vam->input;
6154   vl_api_create_loopback_t *mp;
6155   vl_api_create_loopback_instance_t *mp_lbi;
6156   u8 mac_address[6];
6157   u8 mac_set = 0;
6158   u8 is_specified = 0;
6159   u32 user_instance = 0;
6160   int ret;
6161
6162   memset (mac_address, 0, sizeof (mac_address));
6163
6164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6165     {
6166       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6167         mac_set = 1;
6168       if (unformat (i, "instance %d", &user_instance))
6169         is_specified = 1;
6170       else
6171         break;
6172     }
6173
6174   if (is_specified)
6175     {
6176       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6177       mp_lbi->is_specified = is_specified;
6178       if (is_specified)
6179         mp_lbi->user_instance = htonl (user_instance);
6180       if (mac_set)
6181         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6182       S (mp_lbi);
6183     }
6184   else
6185     {
6186       /* Construct the API message */
6187       M (CREATE_LOOPBACK, mp);
6188       if (mac_set)
6189         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6190       S (mp);
6191     }
6192
6193   W (ret);
6194   return ret;
6195 }
6196
6197 static int
6198 api_delete_loopback (vat_main_t * vam)
6199 {
6200   unformat_input_t *i = vam->input;
6201   vl_api_delete_loopback_t *mp;
6202   u32 sw_if_index = ~0;
6203   int ret;
6204
6205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6206     {
6207       if (unformat (i, "sw_if_index %d", &sw_if_index))
6208         ;
6209       else
6210         break;
6211     }
6212
6213   if (sw_if_index == ~0)
6214     {
6215       errmsg ("missing sw_if_index");
6216       return -99;
6217     }
6218
6219   /* Construct the API message */
6220   M (DELETE_LOOPBACK, mp);
6221   mp->sw_if_index = ntohl (sw_if_index);
6222
6223   S (mp);
6224   W (ret);
6225   return ret;
6226 }
6227
6228 static int
6229 api_want_stats (vat_main_t * vam)
6230 {
6231   unformat_input_t *i = vam->input;
6232   vl_api_want_stats_t *mp;
6233   int enable = -1;
6234   int ret;
6235
6236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6237     {
6238       if (unformat (i, "enable"))
6239         enable = 1;
6240       else if (unformat (i, "disable"))
6241         enable = 0;
6242       else
6243         break;
6244     }
6245
6246   if (enable == -1)
6247     {
6248       errmsg ("missing enable|disable");
6249       return -99;
6250     }
6251
6252   M (WANT_STATS, mp);
6253   mp->enable_disable = enable;
6254
6255   S (mp);
6256   W (ret);
6257   return ret;
6258 }
6259
6260 static int
6261 api_want_interface_events (vat_main_t * vam)
6262 {
6263   unformat_input_t *i = vam->input;
6264   vl_api_want_interface_events_t *mp;
6265   int enable = -1;
6266   int ret;
6267
6268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6269     {
6270       if (unformat (i, "enable"))
6271         enable = 1;
6272       else if (unformat (i, "disable"))
6273         enable = 0;
6274       else
6275         break;
6276     }
6277
6278   if (enable == -1)
6279     {
6280       errmsg ("missing enable|disable");
6281       return -99;
6282     }
6283
6284   M (WANT_INTERFACE_EVENTS, mp);
6285   mp->enable_disable = enable;
6286
6287   vam->interface_event_display = enable;
6288
6289   S (mp);
6290   W (ret);
6291   return ret;
6292 }
6293
6294
6295 /* Note: non-static, called once to set up the initial intfc table */
6296 int
6297 api_sw_interface_dump (vat_main_t * vam)
6298 {
6299   vl_api_sw_interface_dump_t *mp;
6300   vl_api_control_ping_t *mp_ping;
6301   hash_pair_t *p;
6302   name_sort_t *nses = 0, *ns;
6303   sw_interface_subif_t *sub = NULL;
6304   int ret;
6305
6306   /* Toss the old name table */
6307   /* *INDENT-OFF* */
6308   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6309   ({
6310     vec_add2 (nses, ns, 1);
6311     ns->name = (u8 *)(p->key);
6312     ns->value = (u32) p->value[0];
6313   }));
6314   /* *INDENT-ON* */
6315
6316   hash_free (vam->sw_if_index_by_interface_name);
6317
6318   vec_foreach (ns, nses) vec_free (ns->name);
6319
6320   vec_free (nses);
6321
6322   vec_foreach (sub, vam->sw_if_subif_table)
6323   {
6324     vec_free (sub->interface_name);
6325   }
6326   vec_free (vam->sw_if_subif_table);
6327
6328   /* recreate the interface name hash table */
6329   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6330
6331   /* Get list of ethernets */
6332   M (SW_INTERFACE_DUMP, mp);
6333   mp->name_filter_valid = 1;
6334   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6335   S (mp);
6336
6337   /* and local / loopback interfaces */
6338   M (SW_INTERFACE_DUMP, mp);
6339   mp->name_filter_valid = 1;
6340   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6341   S (mp);
6342
6343   /* and packet-generator interfaces */
6344   M (SW_INTERFACE_DUMP, mp);
6345   mp->name_filter_valid = 1;
6346   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6347   S (mp);
6348
6349   /* and vxlan-gpe tunnel interfaces */
6350   M (SW_INTERFACE_DUMP, mp);
6351   mp->name_filter_valid = 1;
6352   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6353            sizeof (mp->name_filter) - 1);
6354   S (mp);
6355
6356   /* and vxlan tunnel interfaces */
6357   M (SW_INTERFACE_DUMP, mp);
6358   mp->name_filter_valid = 1;
6359   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6360   S (mp);
6361
6362   /* and geneve tunnel interfaces */
6363   M (SW_INTERFACE_DUMP, mp);
6364   mp->name_filter_valid = 1;
6365   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6366   S (mp);
6367
6368   /* and host (af_packet) interfaces */
6369   M (SW_INTERFACE_DUMP, mp);
6370   mp->name_filter_valid = 1;
6371   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6372   S (mp);
6373
6374   /* and l2tpv3 tunnel interfaces */
6375   M (SW_INTERFACE_DUMP, mp);
6376   mp->name_filter_valid = 1;
6377   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6378            sizeof (mp->name_filter) - 1);
6379   S (mp);
6380
6381   /* and GRE tunnel interfaces */
6382   M (SW_INTERFACE_DUMP, mp);
6383   mp->name_filter_valid = 1;
6384   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6385   S (mp);
6386
6387   /* and LISP-GPE interfaces */
6388   M (SW_INTERFACE_DUMP, mp);
6389   mp->name_filter_valid = 1;
6390   strncpy ((char *) mp->name_filter, "lisp_gpe",
6391            sizeof (mp->name_filter) - 1);
6392   S (mp);
6393
6394   /* and IPSEC tunnel interfaces */
6395   M (SW_INTERFACE_DUMP, mp);
6396   mp->name_filter_valid = 1;
6397   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6398   S (mp);
6399
6400   /* Use a control ping for synchronization */
6401   MPING (CONTROL_PING, mp_ping);
6402   S (mp_ping);
6403
6404   W (ret);
6405   return ret;
6406 }
6407
6408 static int
6409 api_sw_interface_set_flags (vat_main_t * vam)
6410 {
6411   unformat_input_t *i = vam->input;
6412   vl_api_sw_interface_set_flags_t *mp;
6413   u32 sw_if_index;
6414   u8 sw_if_index_set = 0;
6415   u8 admin_up = 0;
6416   int ret;
6417
6418   /* Parse args required to build the message */
6419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6420     {
6421       if (unformat (i, "admin-up"))
6422         admin_up = 1;
6423       else if (unformat (i, "admin-down"))
6424         admin_up = 0;
6425       else
6426         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6427         sw_if_index_set = 1;
6428       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6429         sw_if_index_set = 1;
6430       else
6431         break;
6432     }
6433
6434   if (sw_if_index_set == 0)
6435     {
6436       errmsg ("missing interface name or sw_if_index");
6437       return -99;
6438     }
6439
6440   /* Construct the API message */
6441   M (SW_INTERFACE_SET_FLAGS, mp);
6442   mp->sw_if_index = ntohl (sw_if_index);
6443   mp->admin_up_down = admin_up;
6444
6445   /* send it... */
6446   S (mp);
6447
6448   /* Wait for a reply, return the good/bad news... */
6449   W (ret);
6450   return ret;
6451 }
6452
6453 static int
6454 api_sw_interface_set_rx_mode (vat_main_t * vam)
6455 {
6456   unformat_input_t *i = vam->input;
6457   vl_api_sw_interface_set_rx_mode_t *mp;
6458   u32 sw_if_index;
6459   u8 sw_if_index_set = 0;
6460   int ret;
6461   u8 queue_id_valid = 0;
6462   u32 queue_id;
6463   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6464
6465   /* Parse args required to build the message */
6466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6467     {
6468       if (unformat (i, "queue %d", &queue_id))
6469         queue_id_valid = 1;
6470       else if (unformat (i, "polling"))
6471         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6472       else if (unformat (i, "interrupt"))
6473         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6474       else if (unformat (i, "adaptive"))
6475         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6476       else
6477         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6478         sw_if_index_set = 1;
6479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6480         sw_if_index_set = 1;
6481       else
6482         break;
6483     }
6484
6485   if (sw_if_index_set == 0)
6486     {
6487       errmsg ("missing interface name or sw_if_index");
6488       return -99;
6489     }
6490   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6491     {
6492       errmsg ("missing rx-mode");
6493       return -99;
6494     }
6495
6496   /* Construct the API message */
6497   M (SW_INTERFACE_SET_RX_MODE, mp);
6498   mp->sw_if_index = ntohl (sw_if_index);
6499   mp->mode = mode;
6500   mp->queue_id_valid = queue_id_valid;
6501   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6502
6503   /* send it... */
6504   S (mp);
6505
6506   /* Wait for a reply, return the good/bad news... */
6507   W (ret);
6508   return ret;
6509 }
6510
6511 static int
6512 api_sw_interface_clear_stats (vat_main_t * vam)
6513 {
6514   unformat_input_t *i = vam->input;
6515   vl_api_sw_interface_clear_stats_t *mp;
6516   u32 sw_if_index;
6517   u8 sw_if_index_set = 0;
6518   int ret;
6519
6520   /* Parse args required to build the message */
6521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6522     {
6523       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6524         sw_if_index_set = 1;
6525       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6526         sw_if_index_set = 1;
6527       else
6528         break;
6529     }
6530
6531   /* Construct the API message */
6532   M (SW_INTERFACE_CLEAR_STATS, mp);
6533
6534   if (sw_if_index_set == 1)
6535     mp->sw_if_index = ntohl (sw_if_index);
6536   else
6537     mp->sw_if_index = ~0;
6538
6539   /* send it... */
6540   S (mp);
6541
6542   /* Wait for a reply, return the good/bad news... */
6543   W (ret);
6544   return ret;
6545 }
6546
6547 static int
6548 api_sw_interface_add_del_address (vat_main_t * vam)
6549 {
6550   unformat_input_t *i = vam->input;
6551   vl_api_sw_interface_add_del_address_t *mp;
6552   u32 sw_if_index;
6553   u8 sw_if_index_set = 0;
6554   u8 is_add = 1, del_all = 0;
6555   u32 address_length = 0;
6556   u8 v4_address_set = 0;
6557   u8 v6_address_set = 0;
6558   ip4_address_t v4address;
6559   ip6_address_t v6address;
6560   int ret;
6561
6562   /* Parse args required to build the message */
6563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6564     {
6565       if (unformat (i, "del-all"))
6566         del_all = 1;
6567       else if (unformat (i, "del"))
6568         is_add = 0;
6569       else
6570         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6571         sw_if_index_set = 1;
6572       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6573         sw_if_index_set = 1;
6574       else if (unformat (i, "%U/%d",
6575                          unformat_ip4_address, &v4address, &address_length))
6576         v4_address_set = 1;
6577       else if (unformat (i, "%U/%d",
6578                          unformat_ip6_address, &v6address, &address_length))
6579         v6_address_set = 1;
6580       else
6581         break;
6582     }
6583
6584   if (sw_if_index_set == 0)
6585     {
6586       errmsg ("missing interface name or sw_if_index");
6587       return -99;
6588     }
6589   if (v4_address_set && v6_address_set)
6590     {
6591       errmsg ("both v4 and v6 addresses set");
6592       return -99;
6593     }
6594   if (!v4_address_set && !v6_address_set && !del_all)
6595     {
6596       errmsg ("no addresses set");
6597       return -99;
6598     }
6599
6600   /* Construct the API message */
6601   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6602
6603   mp->sw_if_index = ntohl (sw_if_index);
6604   mp->is_add = is_add;
6605   mp->del_all = del_all;
6606   if (v6_address_set)
6607     {
6608       mp->is_ipv6 = 1;
6609       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6610     }
6611   else
6612     {
6613       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6614     }
6615   mp->address_length = address_length;
6616
6617   /* send it... */
6618   S (mp);
6619
6620   /* Wait for a reply, return good/bad news  */
6621   W (ret);
6622   return ret;
6623 }
6624
6625 static int
6626 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6627 {
6628   unformat_input_t *i = vam->input;
6629   vl_api_sw_interface_set_mpls_enable_t *mp;
6630   u32 sw_if_index;
6631   u8 sw_if_index_set = 0;
6632   u8 enable = 1;
6633   int ret;
6634
6635   /* Parse args required to build the message */
6636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6637     {
6638       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6639         sw_if_index_set = 1;
6640       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6641         sw_if_index_set = 1;
6642       else if (unformat (i, "disable"))
6643         enable = 0;
6644       else if (unformat (i, "dis"))
6645         enable = 0;
6646       else
6647         break;
6648     }
6649
6650   if (sw_if_index_set == 0)
6651     {
6652       errmsg ("missing interface name or sw_if_index");
6653       return -99;
6654     }
6655
6656   /* Construct the API message */
6657   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6658
6659   mp->sw_if_index = ntohl (sw_if_index);
6660   mp->enable = enable;
6661
6662   /* send it... */
6663   S (mp);
6664
6665   /* Wait for a reply... */
6666   W (ret);
6667   return ret;
6668 }
6669
6670 static int
6671 api_sw_interface_set_table (vat_main_t * vam)
6672 {
6673   unformat_input_t *i = vam->input;
6674   vl_api_sw_interface_set_table_t *mp;
6675   u32 sw_if_index, vrf_id = 0;
6676   u8 sw_if_index_set = 0;
6677   u8 is_ipv6 = 0;
6678   int ret;
6679
6680   /* Parse args required to build the message */
6681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6682     {
6683       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6684         sw_if_index_set = 1;
6685       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6686         sw_if_index_set = 1;
6687       else if (unformat (i, "vrf %d", &vrf_id))
6688         ;
6689       else if (unformat (i, "ipv6"))
6690         is_ipv6 = 1;
6691       else
6692         break;
6693     }
6694
6695   if (sw_if_index_set == 0)
6696     {
6697       errmsg ("missing interface name or sw_if_index");
6698       return -99;
6699     }
6700
6701   /* Construct the API message */
6702   M (SW_INTERFACE_SET_TABLE, mp);
6703
6704   mp->sw_if_index = ntohl (sw_if_index);
6705   mp->is_ipv6 = is_ipv6;
6706   mp->vrf_id = ntohl (vrf_id);
6707
6708   /* send it... */
6709   S (mp);
6710
6711   /* Wait for a reply... */
6712   W (ret);
6713   return ret;
6714 }
6715
6716 static void vl_api_sw_interface_get_table_reply_t_handler
6717   (vl_api_sw_interface_get_table_reply_t * mp)
6718 {
6719   vat_main_t *vam = &vat_main;
6720
6721   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6722
6723   vam->retval = ntohl (mp->retval);
6724   vam->result_ready = 1;
6725
6726 }
6727
6728 static void vl_api_sw_interface_get_table_reply_t_handler_json
6729   (vl_api_sw_interface_get_table_reply_t * mp)
6730 {
6731   vat_main_t *vam = &vat_main;
6732   vat_json_node_t node;
6733
6734   vat_json_init_object (&node);
6735   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6736   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6737
6738   vat_json_print (vam->ofp, &node);
6739   vat_json_free (&node);
6740
6741   vam->retval = ntohl (mp->retval);
6742   vam->result_ready = 1;
6743 }
6744
6745 static int
6746 api_sw_interface_get_table (vat_main_t * vam)
6747 {
6748   unformat_input_t *i = vam->input;
6749   vl_api_sw_interface_get_table_t *mp;
6750   u32 sw_if_index;
6751   u8 sw_if_index_set = 0;
6752   u8 is_ipv6 = 0;
6753   int ret;
6754
6755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6756     {
6757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6758         sw_if_index_set = 1;
6759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6760         sw_if_index_set = 1;
6761       else if (unformat (i, "ipv6"))
6762         is_ipv6 = 1;
6763       else
6764         break;
6765     }
6766
6767   if (sw_if_index_set == 0)
6768     {
6769       errmsg ("missing interface name or sw_if_index");
6770       return -99;
6771     }
6772
6773   M (SW_INTERFACE_GET_TABLE, mp);
6774   mp->sw_if_index = htonl (sw_if_index);
6775   mp->is_ipv6 = is_ipv6;
6776
6777   S (mp);
6778   W (ret);
6779   return ret;
6780 }
6781
6782 static int
6783 api_sw_interface_set_vpath (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_sw_interface_set_vpath_t *mp;
6787   u32 sw_if_index = 0;
6788   u8 sw_if_index_set = 0;
6789   u8 is_enable = 0;
6790   int ret;
6791
6792   /* Parse args required to build the message */
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6796         sw_if_index_set = 1;
6797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6798         sw_if_index_set = 1;
6799       else if (unformat (i, "enable"))
6800         is_enable = 1;
6801       else if (unformat (i, "disable"))
6802         is_enable = 0;
6803       else
6804         break;
6805     }
6806
6807   if (sw_if_index_set == 0)
6808     {
6809       errmsg ("missing interface name or sw_if_index");
6810       return -99;
6811     }
6812
6813   /* Construct the API message */
6814   M (SW_INTERFACE_SET_VPATH, mp);
6815
6816   mp->sw_if_index = ntohl (sw_if_index);
6817   mp->enable = is_enable;
6818
6819   /* send it... */
6820   S (mp);
6821
6822   /* Wait for a reply... */
6823   W (ret);
6824   return ret;
6825 }
6826
6827 static int
6828 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6829 {
6830   unformat_input_t *i = vam->input;
6831   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6832   u32 sw_if_index = 0;
6833   u8 sw_if_index_set = 0;
6834   u8 is_enable = 1;
6835   u8 is_ipv6 = 0;
6836   int ret;
6837
6838   /* Parse args required to build the message */
6839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6840     {
6841       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6842         sw_if_index_set = 1;
6843       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6844         sw_if_index_set = 1;
6845       else if (unformat (i, "enable"))
6846         is_enable = 1;
6847       else if (unformat (i, "disable"))
6848         is_enable = 0;
6849       else if (unformat (i, "ip4"))
6850         is_ipv6 = 0;
6851       else if (unformat (i, "ip6"))
6852         is_ipv6 = 1;
6853       else
6854         break;
6855     }
6856
6857   if (sw_if_index_set == 0)
6858     {
6859       errmsg ("missing interface name or sw_if_index");
6860       return -99;
6861     }
6862
6863   /* Construct the API message */
6864   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6865
6866   mp->sw_if_index = ntohl (sw_if_index);
6867   mp->enable = is_enable;
6868   mp->is_ipv6 = is_ipv6;
6869
6870   /* send it... */
6871   S (mp);
6872
6873   /* Wait for a reply... */
6874   W (ret);
6875   return ret;
6876 }
6877
6878 static int
6879 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6880 {
6881   unformat_input_t *i = vam->input;
6882   vl_api_sw_interface_set_geneve_bypass_t *mp;
6883   u32 sw_if_index = 0;
6884   u8 sw_if_index_set = 0;
6885   u8 is_enable = 1;
6886   u8 is_ipv6 = 0;
6887   int ret;
6888
6889   /* Parse args required to build the message */
6890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6891     {
6892       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6893         sw_if_index_set = 1;
6894       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6895         sw_if_index_set = 1;
6896       else if (unformat (i, "enable"))
6897         is_enable = 1;
6898       else if (unformat (i, "disable"))
6899         is_enable = 0;
6900       else if (unformat (i, "ip4"))
6901         is_ipv6 = 0;
6902       else if (unformat (i, "ip6"))
6903         is_ipv6 = 1;
6904       else
6905         break;
6906     }
6907
6908   if (sw_if_index_set == 0)
6909     {
6910       errmsg ("missing interface name or sw_if_index");
6911       return -99;
6912     }
6913
6914   /* Construct the API message */
6915   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6916
6917   mp->sw_if_index = ntohl (sw_if_index);
6918   mp->enable = is_enable;
6919   mp->is_ipv6 = is_ipv6;
6920
6921   /* send it... */
6922   S (mp);
6923
6924   /* Wait for a reply... */
6925   W (ret);
6926   return ret;
6927 }
6928
6929 static int
6930 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6931 {
6932   unformat_input_t *i = vam->input;
6933   vl_api_sw_interface_set_l2_xconnect_t *mp;
6934   u32 rx_sw_if_index;
6935   u8 rx_sw_if_index_set = 0;
6936   u32 tx_sw_if_index;
6937   u8 tx_sw_if_index_set = 0;
6938   u8 enable = 1;
6939   int ret;
6940
6941   /* Parse args required to build the message */
6942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6943     {
6944       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6945         rx_sw_if_index_set = 1;
6946       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6947         tx_sw_if_index_set = 1;
6948       else if (unformat (i, "rx"))
6949         {
6950           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6951             {
6952               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6953                             &rx_sw_if_index))
6954                 rx_sw_if_index_set = 1;
6955             }
6956           else
6957             break;
6958         }
6959       else if (unformat (i, "tx"))
6960         {
6961           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6962             {
6963               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6964                             &tx_sw_if_index))
6965                 tx_sw_if_index_set = 1;
6966             }
6967           else
6968             break;
6969         }
6970       else if (unformat (i, "enable"))
6971         enable = 1;
6972       else if (unformat (i, "disable"))
6973         enable = 0;
6974       else
6975         break;
6976     }
6977
6978   if (rx_sw_if_index_set == 0)
6979     {
6980       errmsg ("missing rx interface name or rx_sw_if_index");
6981       return -99;
6982     }
6983
6984   if (enable && (tx_sw_if_index_set == 0))
6985     {
6986       errmsg ("missing tx interface name or tx_sw_if_index");
6987       return -99;
6988     }
6989
6990   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6991
6992   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6993   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6994   mp->enable = enable;
6995
6996   S (mp);
6997   W (ret);
6998   return ret;
6999 }
7000
7001 static int
7002 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7003 {
7004   unformat_input_t *i = vam->input;
7005   vl_api_sw_interface_set_l2_bridge_t *mp;
7006   u32 rx_sw_if_index;
7007   u8 rx_sw_if_index_set = 0;
7008   u32 bd_id;
7009   u8 bd_id_set = 0;
7010   u8 bvi = 0;
7011   u32 shg = 0;
7012   u8 enable = 1;
7013   int ret;
7014
7015   /* Parse args required to build the message */
7016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017     {
7018       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7019         rx_sw_if_index_set = 1;
7020       else if (unformat (i, "bd_id %d", &bd_id))
7021         bd_id_set = 1;
7022       else
7023         if (unformat
7024             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7025         rx_sw_if_index_set = 1;
7026       else if (unformat (i, "shg %d", &shg))
7027         ;
7028       else if (unformat (i, "bvi"))
7029         bvi = 1;
7030       else if (unformat (i, "enable"))
7031         enable = 1;
7032       else if (unformat (i, "disable"))
7033         enable = 0;
7034       else
7035         break;
7036     }
7037
7038   if (rx_sw_if_index_set == 0)
7039     {
7040       errmsg ("missing rx interface name or sw_if_index");
7041       return -99;
7042     }
7043
7044   if (enable && (bd_id_set == 0))
7045     {
7046       errmsg ("missing bridge domain");
7047       return -99;
7048     }
7049
7050   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7051
7052   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7053   mp->bd_id = ntohl (bd_id);
7054   mp->shg = (u8) shg;
7055   mp->bvi = bvi;
7056   mp->enable = enable;
7057
7058   S (mp);
7059   W (ret);
7060   return ret;
7061 }
7062
7063 static int
7064 api_bridge_domain_dump (vat_main_t * vam)
7065 {
7066   unformat_input_t *i = vam->input;
7067   vl_api_bridge_domain_dump_t *mp;
7068   vl_api_control_ping_t *mp_ping;
7069   u32 bd_id = ~0;
7070   int ret;
7071
7072   /* Parse args required to build the message */
7073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7074     {
7075       if (unformat (i, "bd_id %d", &bd_id))
7076         ;
7077       else
7078         break;
7079     }
7080
7081   M (BRIDGE_DOMAIN_DUMP, mp);
7082   mp->bd_id = ntohl (bd_id);
7083   S (mp);
7084
7085   /* Use a control ping for synchronization */
7086   MPING (CONTROL_PING, mp_ping);
7087   S (mp_ping);
7088
7089   W (ret);
7090   return ret;
7091 }
7092
7093 static int
7094 api_bridge_domain_add_del (vat_main_t * vam)
7095 {
7096   unformat_input_t *i = vam->input;
7097   vl_api_bridge_domain_add_del_t *mp;
7098   u32 bd_id = ~0;
7099   u8 is_add = 1;
7100   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7101   u8 *bd_tag = NULL;
7102   u32 mac_age = 0;
7103   int ret;
7104
7105   /* Parse args required to build the message */
7106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7107     {
7108       if (unformat (i, "bd_id %d", &bd_id))
7109         ;
7110       else if (unformat (i, "flood %d", &flood))
7111         ;
7112       else if (unformat (i, "uu-flood %d", &uu_flood))
7113         ;
7114       else if (unformat (i, "forward %d", &forward))
7115         ;
7116       else if (unformat (i, "learn %d", &learn))
7117         ;
7118       else if (unformat (i, "arp-term %d", &arp_term))
7119         ;
7120       else if (unformat (i, "mac-age %d", &mac_age))
7121         ;
7122       else if (unformat (i, "bd-tag %s", &bd_tag))
7123         ;
7124       else if (unformat (i, "del"))
7125         {
7126           is_add = 0;
7127           flood = uu_flood = forward = learn = 0;
7128         }
7129       else
7130         break;
7131     }
7132
7133   if (bd_id == ~0)
7134     {
7135       errmsg ("missing bridge domain");
7136       ret = -99;
7137       goto done;
7138     }
7139
7140   if (mac_age > 255)
7141     {
7142       errmsg ("mac age must be less than 256 ");
7143       ret = -99;
7144       goto done;
7145     }
7146
7147   if ((bd_tag) && (vec_len (bd_tag) > 63))
7148     {
7149       errmsg ("bd-tag cannot be longer than 63");
7150       ret = -99;
7151       goto done;
7152     }
7153
7154   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7155
7156   mp->bd_id = ntohl (bd_id);
7157   mp->flood = flood;
7158   mp->uu_flood = uu_flood;
7159   mp->forward = forward;
7160   mp->learn = learn;
7161   mp->arp_term = arp_term;
7162   mp->is_add = is_add;
7163   mp->mac_age = (u8) mac_age;
7164   if (bd_tag)
7165     {
7166       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7167       mp->bd_tag[vec_len (bd_tag)] = 0;
7168     }
7169   S (mp);
7170   W (ret);
7171
7172 done:
7173   vec_free (bd_tag);
7174   return ret;
7175 }
7176
7177 static int
7178 api_l2fib_flush_bd (vat_main_t * vam)
7179 {
7180   unformat_input_t *i = vam->input;
7181   vl_api_l2fib_flush_bd_t *mp;
7182   u32 bd_id = ~0;
7183   int ret;
7184
7185   /* Parse args required to build the message */
7186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7187     {
7188       if (unformat (i, "bd_id %d", &bd_id));
7189       else
7190         break;
7191     }
7192
7193   if (bd_id == ~0)
7194     {
7195       errmsg ("missing bridge domain");
7196       return -99;
7197     }
7198
7199   M (L2FIB_FLUSH_BD, mp);
7200
7201   mp->bd_id = htonl (bd_id);
7202
7203   S (mp);
7204   W (ret);
7205   return ret;
7206 }
7207
7208 static int
7209 api_l2fib_flush_int (vat_main_t * vam)
7210 {
7211   unformat_input_t *i = vam->input;
7212   vl_api_l2fib_flush_int_t *mp;
7213   u32 sw_if_index = ~0;
7214   int ret;
7215
7216   /* Parse args required to build the message */
7217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218     {
7219       if (unformat (i, "sw_if_index %d", &sw_if_index));
7220       else
7221         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7222       else
7223         break;
7224     }
7225
7226   if (sw_if_index == ~0)
7227     {
7228       errmsg ("missing interface name or sw_if_index");
7229       return -99;
7230     }
7231
7232   M (L2FIB_FLUSH_INT, mp);
7233
7234   mp->sw_if_index = ntohl (sw_if_index);
7235
7236   S (mp);
7237   W (ret);
7238   return ret;
7239 }
7240
7241 static int
7242 api_l2fib_add_del (vat_main_t * vam)
7243 {
7244   unformat_input_t *i = vam->input;
7245   vl_api_l2fib_add_del_t *mp;
7246   f64 timeout;
7247   u8 mac[6] = { 0 };
7248   u8 mac_set = 0;
7249   u32 bd_id;
7250   u8 bd_id_set = 0;
7251   u32 sw_if_index = ~0;
7252   u8 sw_if_index_set = 0;
7253   u8 is_add = 1;
7254   u8 static_mac = 0;
7255   u8 filter_mac = 0;
7256   u8 bvi_mac = 0;
7257   int count = 1;
7258   f64 before = 0;
7259   int j;
7260
7261   /* Parse args required to build the message */
7262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7263     {
7264       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7265         mac_set = 1;
7266       else if (unformat (i, "bd_id %d", &bd_id))
7267         bd_id_set = 1;
7268       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7269         sw_if_index_set = 1;
7270       else if (unformat (i, "sw_if"))
7271         {
7272           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7273             {
7274               if (unformat
7275                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7276                 sw_if_index_set = 1;
7277             }
7278           else
7279             break;
7280         }
7281       else if (unformat (i, "static"))
7282         static_mac = 1;
7283       else if (unformat (i, "filter"))
7284         {
7285           filter_mac = 1;
7286           static_mac = 1;
7287         }
7288       else if (unformat (i, "bvi"))
7289         {
7290           bvi_mac = 1;
7291           static_mac = 1;
7292         }
7293       else if (unformat (i, "del"))
7294         is_add = 0;
7295       else if (unformat (i, "count %d", &count))
7296         ;
7297       else
7298         break;
7299     }
7300
7301   if (mac_set == 0)
7302     {
7303       errmsg ("missing mac address");
7304       return -99;
7305     }
7306
7307   if (bd_id_set == 0)
7308     {
7309       errmsg ("missing bridge domain");
7310       return -99;
7311     }
7312
7313   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7314     {
7315       errmsg ("missing interface name or sw_if_index");
7316       return -99;
7317     }
7318
7319   if (count > 1)
7320     {
7321       /* Turn on async mode */
7322       vam->async_mode = 1;
7323       vam->async_errors = 0;
7324       before = vat_time_now (vam);
7325     }
7326
7327   for (j = 0; j < count; j++)
7328     {
7329       M (L2FIB_ADD_DEL, mp);
7330
7331       clib_memcpy (mp->mac, mac, 6);
7332       mp->bd_id = ntohl (bd_id);
7333       mp->is_add = is_add;
7334
7335       if (is_add)
7336         {
7337           mp->sw_if_index = ntohl (sw_if_index);
7338           mp->static_mac = static_mac;
7339           mp->filter_mac = filter_mac;
7340           mp->bvi_mac = bvi_mac;
7341         }
7342       increment_mac_address (mac);
7343       /* send it... */
7344       S (mp);
7345     }
7346
7347   if (count > 1)
7348     {
7349       vl_api_control_ping_t *mp_ping;
7350       f64 after;
7351
7352       /* Shut off async mode */
7353       vam->async_mode = 0;
7354
7355       MPING (CONTROL_PING, mp_ping);
7356       S (mp_ping);
7357
7358       timeout = vat_time_now (vam) + 1.0;
7359       while (vat_time_now (vam) < timeout)
7360         if (vam->result_ready == 1)
7361           goto out;
7362       vam->retval = -99;
7363
7364     out:
7365       if (vam->retval == -99)
7366         errmsg ("timeout");
7367
7368       if (vam->async_errors > 0)
7369         {
7370           errmsg ("%d asynchronous errors", vam->async_errors);
7371           vam->retval = -98;
7372         }
7373       vam->async_errors = 0;
7374       after = vat_time_now (vam);
7375
7376       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7377              count, after - before, count / (after - before));
7378     }
7379   else
7380     {
7381       int ret;
7382
7383       /* Wait for a reply... */
7384       W (ret);
7385       return ret;
7386     }
7387   /* Return the good/bad news */
7388   return (vam->retval);
7389 }
7390
7391 static int
7392 api_bridge_domain_set_mac_age (vat_main_t * vam)
7393 {
7394   unformat_input_t *i = vam->input;
7395   vl_api_bridge_domain_set_mac_age_t *mp;
7396   u32 bd_id = ~0;
7397   u32 mac_age = 0;
7398   int ret;
7399
7400   /* Parse args required to build the message */
7401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7402     {
7403       if (unformat (i, "bd_id %d", &bd_id));
7404       else if (unformat (i, "mac-age %d", &mac_age));
7405       else
7406         break;
7407     }
7408
7409   if (bd_id == ~0)
7410     {
7411       errmsg ("missing bridge domain");
7412       return -99;
7413     }
7414
7415   if (mac_age > 255)
7416     {
7417       errmsg ("mac age must be less than 256 ");
7418       return -99;
7419     }
7420
7421   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7422
7423   mp->bd_id = htonl (bd_id);
7424   mp->mac_age = (u8) mac_age;
7425
7426   S (mp);
7427   W (ret);
7428   return ret;
7429 }
7430
7431 static int
7432 api_l2_flags (vat_main_t * vam)
7433 {
7434   unformat_input_t *i = vam->input;
7435   vl_api_l2_flags_t *mp;
7436   u32 sw_if_index;
7437   u32 flags = 0;
7438   u8 sw_if_index_set = 0;
7439   u8 is_set = 0;
7440   int ret;
7441
7442   /* Parse args required to build the message */
7443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7444     {
7445       if (unformat (i, "sw_if_index %d", &sw_if_index))
7446         sw_if_index_set = 1;
7447       else if (unformat (i, "sw_if"))
7448         {
7449           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7450             {
7451               if (unformat
7452                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7453                 sw_if_index_set = 1;
7454             }
7455           else
7456             break;
7457         }
7458       else if (unformat (i, "learn"))
7459         flags |= L2_LEARN;
7460       else if (unformat (i, "forward"))
7461         flags |= L2_FWD;
7462       else if (unformat (i, "flood"))
7463         flags |= L2_FLOOD;
7464       else if (unformat (i, "uu-flood"))
7465         flags |= L2_UU_FLOOD;
7466       else if (unformat (i, "arp-term"))
7467         flags |= L2_ARP_TERM;
7468       else if (unformat (i, "off"))
7469         is_set = 0;
7470       else if (unformat (i, "disable"))
7471         is_set = 0;
7472       else
7473         break;
7474     }
7475
7476   if (sw_if_index_set == 0)
7477     {
7478       errmsg ("missing interface name or sw_if_index");
7479       return -99;
7480     }
7481
7482   M (L2_FLAGS, mp);
7483
7484   mp->sw_if_index = ntohl (sw_if_index);
7485   mp->feature_bitmap = ntohl (flags);
7486   mp->is_set = is_set;
7487
7488   S (mp);
7489   W (ret);
7490   return ret;
7491 }
7492
7493 static int
7494 api_bridge_flags (vat_main_t * vam)
7495 {
7496   unformat_input_t *i = vam->input;
7497   vl_api_bridge_flags_t *mp;
7498   u32 bd_id;
7499   u8 bd_id_set = 0;
7500   u8 is_set = 1;
7501   u32 flags = 0;
7502   int ret;
7503
7504   /* Parse args required to build the message */
7505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7506     {
7507       if (unformat (i, "bd_id %d", &bd_id))
7508         bd_id_set = 1;
7509       else if (unformat (i, "learn"))
7510         flags |= L2_LEARN;
7511       else if (unformat (i, "forward"))
7512         flags |= L2_FWD;
7513       else if (unformat (i, "flood"))
7514         flags |= L2_FLOOD;
7515       else if (unformat (i, "uu-flood"))
7516         flags |= L2_UU_FLOOD;
7517       else if (unformat (i, "arp-term"))
7518         flags |= L2_ARP_TERM;
7519       else if (unformat (i, "off"))
7520         is_set = 0;
7521       else if (unformat (i, "disable"))
7522         is_set = 0;
7523       else
7524         break;
7525     }
7526
7527   if (bd_id_set == 0)
7528     {
7529       errmsg ("missing bridge domain");
7530       return -99;
7531     }
7532
7533   M (BRIDGE_FLAGS, mp);
7534
7535   mp->bd_id = ntohl (bd_id);
7536   mp->feature_bitmap = ntohl (flags);
7537   mp->is_set = is_set;
7538
7539   S (mp);
7540   W (ret);
7541   return ret;
7542 }
7543
7544 static int
7545 api_bd_ip_mac_add_del (vat_main_t * vam)
7546 {
7547   unformat_input_t *i = vam->input;
7548   vl_api_bd_ip_mac_add_del_t *mp;
7549   u32 bd_id;
7550   u8 is_ipv6 = 0;
7551   u8 is_add = 1;
7552   u8 bd_id_set = 0;
7553   u8 ip_set = 0;
7554   u8 mac_set = 0;
7555   ip4_address_t v4addr;
7556   ip6_address_t v6addr;
7557   u8 macaddr[6];
7558   int ret;
7559
7560
7561   /* Parse args required to build the message */
7562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7563     {
7564       if (unformat (i, "bd_id %d", &bd_id))
7565         {
7566           bd_id_set++;
7567         }
7568       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7569         {
7570           ip_set++;
7571         }
7572       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7573         {
7574           ip_set++;
7575           is_ipv6++;
7576         }
7577       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7578         {
7579           mac_set++;
7580         }
7581       else if (unformat (i, "del"))
7582         is_add = 0;
7583       else
7584         break;
7585     }
7586
7587   if (bd_id_set == 0)
7588     {
7589       errmsg ("missing bridge domain");
7590       return -99;
7591     }
7592   else if (ip_set == 0)
7593     {
7594       errmsg ("missing IP address");
7595       return -99;
7596     }
7597   else if (mac_set == 0)
7598     {
7599       errmsg ("missing MAC address");
7600       return -99;
7601     }
7602
7603   M (BD_IP_MAC_ADD_DEL, mp);
7604
7605   mp->bd_id = ntohl (bd_id);
7606   mp->is_ipv6 = is_ipv6;
7607   mp->is_add = is_add;
7608   if (is_ipv6)
7609     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7610   else
7611     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7612   clib_memcpy (mp->mac_address, macaddr, 6);
7613   S (mp);
7614   W (ret);
7615   return ret;
7616 }
7617
7618 static int
7619 api_tap_connect (vat_main_t * vam)
7620 {
7621   unformat_input_t *i = vam->input;
7622   vl_api_tap_connect_t *mp;
7623   u8 mac_address[6];
7624   u8 random_mac = 1;
7625   u8 name_set = 0;
7626   u8 *tap_name;
7627   u8 *tag = 0;
7628   ip4_address_t ip4_address;
7629   u32 ip4_mask_width;
7630   int ip4_address_set = 0;
7631   ip6_address_t ip6_address;
7632   u32 ip6_mask_width;
7633   int ip6_address_set = 0;
7634   int ret;
7635
7636   memset (mac_address, 0, sizeof (mac_address));
7637
7638   /* Parse args required to build the message */
7639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7640     {
7641       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7642         {
7643           random_mac = 0;
7644         }
7645       else if (unformat (i, "random-mac"))
7646         random_mac = 1;
7647       else if (unformat (i, "tapname %s", &tap_name))
7648         name_set = 1;
7649       else if (unformat (i, "tag %s", &tag))
7650         ;
7651       else if (unformat (i, "address %U/%d",
7652                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7653         ip4_address_set = 1;
7654       else if (unformat (i, "address %U/%d",
7655                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7656         ip6_address_set = 1;
7657       else
7658         break;
7659     }
7660
7661   if (name_set == 0)
7662     {
7663       errmsg ("missing tap name");
7664       return -99;
7665     }
7666   if (vec_len (tap_name) > 63)
7667     {
7668       errmsg ("tap name too long");
7669       return -99;
7670     }
7671   vec_add1 (tap_name, 0);
7672
7673   if (vec_len (tag) > 63)
7674     {
7675       errmsg ("tag too long");
7676       return -99;
7677     }
7678
7679   /* Construct the API message */
7680   M (TAP_CONNECT, mp);
7681
7682   mp->use_random_mac = random_mac;
7683   clib_memcpy (mp->mac_address, mac_address, 6);
7684   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7685   if (tag)
7686     clib_memcpy (mp->tag, tag, vec_len (tag));
7687
7688   if (ip4_address_set)
7689     {
7690       mp->ip4_address_set = 1;
7691       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7692       mp->ip4_mask_width = ip4_mask_width;
7693     }
7694   if (ip6_address_set)
7695     {
7696       mp->ip6_address_set = 1;
7697       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7698       mp->ip6_mask_width = ip6_mask_width;
7699     }
7700
7701   vec_free (tap_name);
7702   vec_free (tag);
7703
7704   /* send it... */
7705   S (mp);
7706
7707   /* Wait for a reply... */
7708   W (ret);
7709   return ret;
7710 }
7711
7712 static int
7713 api_tap_modify (vat_main_t * vam)
7714 {
7715   unformat_input_t *i = vam->input;
7716   vl_api_tap_modify_t *mp;
7717   u8 mac_address[6];
7718   u8 random_mac = 1;
7719   u8 name_set = 0;
7720   u8 *tap_name;
7721   u32 sw_if_index = ~0;
7722   u8 sw_if_index_set = 0;
7723   int ret;
7724
7725   memset (mac_address, 0, sizeof (mac_address));
7726
7727   /* Parse args required to build the message */
7728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7729     {
7730       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7731         sw_if_index_set = 1;
7732       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7733         sw_if_index_set = 1;
7734       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7735         {
7736           random_mac = 0;
7737         }
7738       else if (unformat (i, "random-mac"))
7739         random_mac = 1;
7740       else if (unformat (i, "tapname %s", &tap_name))
7741         name_set = 1;
7742       else
7743         break;
7744     }
7745
7746   if (sw_if_index_set == 0)
7747     {
7748       errmsg ("missing vpp interface name");
7749       return -99;
7750     }
7751   if (name_set == 0)
7752     {
7753       errmsg ("missing tap name");
7754       return -99;
7755     }
7756   if (vec_len (tap_name) > 63)
7757     {
7758       errmsg ("tap name too long");
7759     }
7760   vec_add1 (tap_name, 0);
7761
7762   /* Construct the API message */
7763   M (TAP_MODIFY, mp);
7764
7765   mp->use_random_mac = random_mac;
7766   mp->sw_if_index = ntohl (sw_if_index);
7767   clib_memcpy (mp->mac_address, mac_address, 6);
7768   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7769   vec_free (tap_name);
7770
7771   /* send it... */
7772   S (mp);
7773
7774   /* Wait for a reply... */
7775   W (ret);
7776   return ret;
7777 }
7778
7779 static int
7780 api_tap_delete (vat_main_t * vam)
7781 {
7782   unformat_input_t *i = vam->input;
7783   vl_api_tap_delete_t *mp;
7784   u32 sw_if_index = ~0;
7785   u8 sw_if_index_set = 0;
7786   int ret;
7787
7788   /* Parse args required to build the message */
7789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7790     {
7791       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7792         sw_if_index_set = 1;
7793       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7794         sw_if_index_set = 1;
7795       else
7796         break;
7797     }
7798
7799   if (sw_if_index_set == 0)
7800     {
7801       errmsg ("missing vpp interface name");
7802       return -99;
7803     }
7804
7805   /* Construct the API message */
7806   M (TAP_DELETE, mp);
7807
7808   mp->sw_if_index = ntohl (sw_if_index);
7809
7810   /* send it... */
7811   S (mp);
7812
7813   /* Wait for a reply... */
7814   W (ret);
7815   return ret;
7816 }
7817
7818 static int
7819 api_tap_create_v2 (vat_main_t * vam)
7820 {
7821   unformat_input_t *i = vam->input;
7822   vl_api_tap_create_v2_t *mp;
7823   u8 mac_address[6];
7824   u8 random_mac = 1;
7825   u32 id = ~0;
7826   u8 *host_if_name = 0;
7827   u8 *host_ns = 0;
7828   u8 host_mac_addr[6];
7829   u8 host_mac_addr_set = 0;
7830   u8 *host_bridge = 0;
7831   ip4_address_t host_ip4_addr;
7832   u32 host_ip4_prefix_len = 0;
7833   ip6_address_t host_ip6_addr;
7834   u32 host_ip6_prefix_len = 0;
7835   int ret;
7836   int rx_ring_sz = 0, tx_ring_sz = 0;
7837
7838   memset (mac_address, 0, sizeof (mac_address));
7839
7840   /* Parse args required to build the message */
7841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7842     {
7843       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7844         {
7845           random_mac = 0;
7846         }
7847       else if (unformat (i, "id %s", &id))
7848         ;
7849       else if (unformat (i, "host-if-name %s", &host_if_name))
7850         ;
7851       else if (unformat (i, "host-ns %s", &host_ns))
7852         ;
7853       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7854                          host_mac_addr))
7855         host_mac_addr_set = 1;
7856       else if (unformat (i, "host-bridge %s", &host_bridge))
7857         ;
7858       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7859                          &host_ip4_addr, &host_ip4_prefix_len))
7860         ;
7861       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7862                          &host_ip6_addr, &host_ip6_prefix_len))
7863         ;
7864       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7865         ;
7866       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7867         ;
7868       else
7869         break;
7870     }
7871
7872   if (vec_len (host_if_name) > 63)
7873     {
7874       errmsg ("tap name too long. ");
7875       return -99;
7876     }
7877   if (vec_len (host_ns) > 63)
7878     {
7879       errmsg ("host name space too long. ");
7880       return -99;
7881     }
7882   if (vec_len (host_bridge) > 63)
7883     {
7884       errmsg ("host bridge name too long. ");
7885       return -99;
7886     }
7887   if (host_ip4_prefix_len > 32)
7888     {
7889       errmsg ("host ip4 prefix length not valid. ");
7890       return -99;
7891     }
7892   if (host_ip6_prefix_len > 128)
7893     {
7894       errmsg ("host ip6 prefix length not valid. ");
7895       return -99;
7896     }
7897   if (!is_pow2 (rx_ring_sz))
7898     {
7899       errmsg ("rx ring size must be power of 2. ");
7900       return -99;
7901     }
7902   if (rx_ring_sz > 32768)
7903     {
7904       errmsg ("rx ring size must be 32768 or lower. ");
7905       return -99;
7906     }
7907   if (!is_pow2 (tx_ring_sz))
7908     {
7909       errmsg ("tx ring size must be power of 2. ");
7910       return -99;
7911     }
7912   if (tx_ring_sz > 32768)
7913     {
7914       errmsg ("tx ring size must be 32768 or lower. ");
7915       return -99;
7916     }
7917
7918   /* Construct the API message */
7919   M (TAP_CREATE_V2, mp);
7920
7921   mp->use_random_mac = random_mac;
7922
7923   mp->id = id;
7924   mp->host_namespace_set = host_ns != 0;
7925   mp->host_bridge_set = host_bridge != 0;
7926   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7927   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7928   mp->rx_ring_sz = rx_ring_sz;
7929   mp->tx_ring_sz = tx_ring_sz;
7930
7931   if (random_mac)
7932     clib_memcpy (mp->mac_address, mac_address, 6);
7933   if (host_mac_addr_set)
7934     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7935   if (host_if_name)
7936     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7937   if (host_ns)
7938     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7939   if (host_bridge)
7940     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7941   if (host_ip4_prefix_len)
7942     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7943   if (host_ip4_prefix_len)
7944     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7945
7946
7947   vec_free (host_ns);
7948   vec_free (host_if_name);
7949   vec_free (host_bridge);
7950
7951   /* send it... */
7952   S (mp);
7953
7954   /* Wait for a reply... */
7955   W (ret);
7956   return ret;
7957 }
7958
7959 static int
7960 api_tap_delete_v2 (vat_main_t * vam)
7961 {
7962   unformat_input_t *i = vam->input;
7963   vl_api_tap_delete_v2_t *mp;
7964   u32 sw_if_index = ~0;
7965   u8 sw_if_index_set = 0;
7966   int ret;
7967
7968   /* Parse args required to build the message */
7969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7970     {
7971       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7972         sw_if_index_set = 1;
7973       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7974         sw_if_index_set = 1;
7975       else
7976         break;
7977     }
7978
7979   if (sw_if_index_set == 0)
7980     {
7981       errmsg ("missing vpp interface name. ");
7982       return -99;
7983     }
7984
7985   /* Construct the API message */
7986   M (TAP_DELETE_V2, mp);
7987
7988   mp->sw_if_index = ntohl (sw_if_index);
7989
7990   /* send it... */
7991   S (mp);
7992
7993   /* Wait for a reply... */
7994   W (ret);
7995   return ret;
7996 }
7997
7998 static int
7999 api_ip_table_add_del (vat_main_t * vam)
8000 {
8001   unformat_input_t *i = vam->input;
8002   vl_api_ip_table_add_del_t *mp;
8003   u32 table_id = ~0;
8004   u8 is_ipv6 = 0;
8005   u8 is_add = 1;
8006   int ret = 0;
8007
8008   /* Parse args required to build the message */
8009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8010     {
8011       if (unformat (i, "ipv6"))
8012         is_ipv6 = 1;
8013       else if (unformat (i, "del"))
8014         is_add = 0;
8015       else if (unformat (i, "add"))
8016         is_add = 1;
8017       else if (unformat (i, "table %d", &table_id))
8018         ;
8019       else
8020         {
8021           clib_warning ("parse error '%U'", format_unformat_error, i);
8022           return -99;
8023         }
8024     }
8025
8026   if (~0 == table_id)
8027     {
8028       errmsg ("missing table-ID");
8029       return -99;
8030     }
8031
8032   /* Construct the API message */
8033   M (IP_TABLE_ADD_DEL, mp);
8034
8035   mp->table_id = ntohl (table_id);
8036   mp->is_ipv6 = is_ipv6;
8037   mp->is_add = is_add;
8038
8039   /* send it... */
8040   S (mp);
8041
8042   /* Wait for a reply... */
8043   W (ret);
8044
8045   return ret;
8046 }
8047
8048 static int
8049 api_ip_add_del_route (vat_main_t * vam)
8050 {
8051   unformat_input_t *i = vam->input;
8052   vl_api_ip_add_del_route_t *mp;
8053   u32 sw_if_index = ~0, vrf_id = 0;
8054   u8 is_ipv6 = 0;
8055   u8 is_local = 0, is_drop = 0;
8056   u8 is_unreach = 0, is_prohibit = 0;
8057   u8 is_add = 1;
8058   u32 next_hop_weight = 1;
8059   u8 is_multipath = 0;
8060   u8 address_set = 0;
8061   u8 address_length_set = 0;
8062   u32 next_hop_table_id = 0;
8063   u32 resolve_attempts = 0;
8064   u32 dst_address_length = 0;
8065   u8 next_hop_set = 0;
8066   ip4_address_t v4_dst_address, v4_next_hop_address;
8067   ip6_address_t v6_dst_address, v6_next_hop_address;
8068   int count = 1;
8069   int j;
8070   f64 before = 0;
8071   u32 random_add_del = 0;
8072   u32 *random_vector = 0;
8073   uword *random_hash;
8074   u32 random_seed = 0xdeaddabe;
8075   u32 classify_table_index = ~0;
8076   u8 is_classify = 0;
8077   u8 resolve_host = 0, resolve_attached = 0;
8078   mpls_label_t *next_hop_out_label_stack = NULL;
8079   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8080   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8081
8082   /* Parse args required to build the message */
8083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8084     {
8085       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8086         ;
8087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8088         ;
8089       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8090         {
8091           address_set = 1;
8092           is_ipv6 = 0;
8093         }
8094       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8095         {
8096           address_set = 1;
8097           is_ipv6 = 1;
8098         }
8099       else if (unformat (i, "/%d", &dst_address_length))
8100         {
8101           address_length_set = 1;
8102         }
8103
8104       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8105                                          &v4_next_hop_address))
8106         {
8107           next_hop_set = 1;
8108         }
8109       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8110                                          &v6_next_hop_address))
8111         {
8112           next_hop_set = 1;
8113         }
8114       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8115         ;
8116       else if (unformat (i, "weight %d", &next_hop_weight))
8117         ;
8118       else if (unformat (i, "drop"))
8119         {
8120           is_drop = 1;
8121         }
8122       else if (unformat (i, "null-send-unreach"))
8123         {
8124           is_unreach = 1;
8125         }
8126       else if (unformat (i, "null-send-prohibit"))
8127         {
8128           is_prohibit = 1;
8129         }
8130       else if (unformat (i, "local"))
8131         {
8132           is_local = 1;
8133         }
8134       else if (unformat (i, "classify %d", &classify_table_index))
8135         {
8136           is_classify = 1;
8137         }
8138       else if (unformat (i, "del"))
8139         is_add = 0;
8140       else if (unformat (i, "add"))
8141         is_add = 1;
8142       else if (unformat (i, "resolve-via-host"))
8143         resolve_host = 1;
8144       else if (unformat (i, "resolve-via-attached"))
8145         resolve_attached = 1;
8146       else if (unformat (i, "multipath"))
8147         is_multipath = 1;
8148       else if (unformat (i, "vrf %d", &vrf_id))
8149         ;
8150       else if (unformat (i, "count %d", &count))
8151         ;
8152       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8153         ;
8154       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8155         ;
8156       else if (unformat (i, "out-label %d", &next_hop_out_label))
8157         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8158       else if (unformat (i, "via-label %d", &next_hop_via_label))
8159         ;
8160       else if (unformat (i, "random"))
8161         random_add_del = 1;
8162       else if (unformat (i, "seed %d", &random_seed))
8163         ;
8164       else
8165         {
8166           clib_warning ("parse error '%U'", format_unformat_error, i);
8167           return -99;
8168         }
8169     }
8170
8171   if (!next_hop_set && !is_drop && !is_local &&
8172       !is_classify && !is_unreach && !is_prohibit &&
8173       MPLS_LABEL_INVALID == next_hop_via_label)
8174     {
8175       errmsg
8176         ("next hop / local / drop / unreach / prohibit / classify not set");
8177       return -99;
8178     }
8179
8180   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8181     {
8182       errmsg ("next hop and next-hop via label set");
8183       return -99;
8184     }
8185   if (address_set == 0)
8186     {
8187       errmsg ("missing addresses");
8188       return -99;
8189     }
8190
8191   if (address_length_set == 0)
8192     {
8193       errmsg ("missing address length");
8194       return -99;
8195     }
8196
8197   /* Generate a pile of unique, random routes */
8198   if (random_add_del)
8199     {
8200       u32 this_random_address;
8201       random_hash = hash_create (count, sizeof (uword));
8202
8203       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8204       for (j = 0; j <= count; j++)
8205         {
8206           do
8207             {
8208               this_random_address = random_u32 (&random_seed);
8209               this_random_address =
8210                 clib_host_to_net_u32 (this_random_address);
8211             }
8212           while (hash_get (random_hash, this_random_address));
8213           vec_add1 (random_vector, this_random_address);
8214           hash_set (random_hash, this_random_address, 1);
8215         }
8216       hash_free (random_hash);
8217       v4_dst_address.as_u32 = random_vector[0];
8218     }
8219
8220   if (count > 1)
8221     {
8222       /* Turn on async mode */
8223       vam->async_mode = 1;
8224       vam->async_errors = 0;
8225       before = vat_time_now (vam);
8226     }
8227
8228   for (j = 0; j < count; j++)
8229     {
8230       /* Construct the API message */
8231       M2 (IP_ADD_DEL_ROUTE, mp,
8232           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8233
8234       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8235       mp->table_id = ntohl (vrf_id);
8236
8237       mp->is_add = is_add;
8238       mp->is_drop = is_drop;
8239       mp->is_unreach = is_unreach;
8240       mp->is_prohibit = is_prohibit;
8241       mp->is_ipv6 = is_ipv6;
8242       mp->is_local = is_local;
8243       mp->is_classify = is_classify;
8244       mp->is_multipath = is_multipath;
8245       mp->is_resolve_host = resolve_host;
8246       mp->is_resolve_attached = resolve_attached;
8247       mp->next_hop_weight = next_hop_weight;
8248       mp->dst_address_length = dst_address_length;
8249       mp->next_hop_table_id = ntohl (next_hop_table_id);
8250       mp->classify_table_index = ntohl (classify_table_index);
8251       mp->next_hop_via_label = ntohl (next_hop_via_label);
8252       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8253       if (0 != mp->next_hop_n_out_labels)
8254         {
8255           memcpy (mp->next_hop_out_label_stack,
8256                   next_hop_out_label_stack,
8257                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8258           vec_free (next_hop_out_label_stack);
8259         }
8260
8261       if (is_ipv6)
8262         {
8263           clib_memcpy (mp->dst_address, &v6_dst_address,
8264                        sizeof (v6_dst_address));
8265           if (next_hop_set)
8266             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8267                          sizeof (v6_next_hop_address));
8268           increment_v6_address (&v6_dst_address);
8269         }
8270       else
8271         {
8272           clib_memcpy (mp->dst_address, &v4_dst_address,
8273                        sizeof (v4_dst_address));
8274           if (next_hop_set)
8275             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8276                          sizeof (v4_next_hop_address));
8277           if (random_add_del)
8278             v4_dst_address.as_u32 = random_vector[j + 1];
8279           else
8280             increment_v4_address (&v4_dst_address);
8281         }
8282       /* send it... */
8283       S (mp);
8284       /* If we receive SIGTERM, stop now... */
8285       if (vam->do_exit)
8286         break;
8287     }
8288
8289   /* When testing multiple add/del ops, use a control-ping to sync */
8290   if (count > 1)
8291     {
8292       vl_api_control_ping_t *mp_ping;
8293       f64 after;
8294       f64 timeout;
8295
8296       /* Shut off async mode */
8297       vam->async_mode = 0;
8298
8299       MPING (CONTROL_PING, mp_ping);
8300       S (mp_ping);
8301
8302       timeout = vat_time_now (vam) + 1.0;
8303       while (vat_time_now (vam) < timeout)
8304         if (vam->result_ready == 1)
8305           goto out;
8306       vam->retval = -99;
8307
8308     out:
8309       if (vam->retval == -99)
8310         errmsg ("timeout");
8311
8312       if (vam->async_errors > 0)
8313         {
8314           errmsg ("%d asynchronous errors", vam->async_errors);
8315           vam->retval = -98;
8316         }
8317       vam->async_errors = 0;
8318       after = vat_time_now (vam);
8319
8320       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8321       if (j > 0)
8322         count = j;
8323
8324       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8325              count, after - before, count / (after - before));
8326     }
8327   else
8328     {
8329       int ret;
8330
8331       /* Wait for a reply... */
8332       W (ret);
8333       return ret;
8334     }
8335
8336   /* Return the good/bad news */
8337   return (vam->retval);
8338 }
8339
8340 static int
8341 api_ip_mroute_add_del (vat_main_t * vam)
8342 {
8343   unformat_input_t *i = vam->input;
8344   vl_api_ip_mroute_add_del_t *mp;
8345   u32 sw_if_index = ~0, vrf_id = 0;
8346   u8 is_ipv6 = 0;
8347   u8 is_local = 0;
8348   u8 is_add = 1;
8349   u8 address_set = 0;
8350   u32 grp_address_length = 0;
8351   ip4_address_t v4_grp_address, v4_src_address;
8352   ip6_address_t v6_grp_address, v6_src_address;
8353   mfib_itf_flags_t iflags = 0;
8354   mfib_entry_flags_t eflags = 0;
8355   int ret;
8356
8357   /* Parse args required to build the message */
8358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8359     {
8360       if (unformat (i, "sw_if_index %d", &sw_if_index))
8361         ;
8362       else if (unformat (i, "%U %U",
8363                          unformat_ip4_address, &v4_src_address,
8364                          unformat_ip4_address, &v4_grp_address))
8365         {
8366           grp_address_length = 64;
8367           address_set = 1;
8368           is_ipv6 = 0;
8369         }
8370       else if (unformat (i, "%U %U",
8371                          unformat_ip6_address, &v6_src_address,
8372                          unformat_ip6_address, &v6_grp_address))
8373         {
8374           grp_address_length = 256;
8375           address_set = 1;
8376           is_ipv6 = 1;
8377         }
8378       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8379         {
8380           memset (&v4_src_address, 0, sizeof (v4_src_address));
8381           grp_address_length = 32;
8382           address_set = 1;
8383           is_ipv6 = 0;
8384         }
8385       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8386         {
8387           memset (&v6_src_address, 0, sizeof (v6_src_address));
8388           grp_address_length = 128;
8389           address_set = 1;
8390           is_ipv6 = 1;
8391         }
8392       else if (unformat (i, "/%d", &grp_address_length))
8393         ;
8394       else if (unformat (i, "local"))
8395         {
8396           is_local = 1;
8397         }
8398       else if (unformat (i, "del"))
8399         is_add = 0;
8400       else if (unformat (i, "add"))
8401         is_add = 1;
8402       else if (unformat (i, "vrf %d", &vrf_id))
8403         ;
8404       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8405         ;
8406       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8407         ;
8408       else
8409         {
8410           clib_warning ("parse error '%U'", format_unformat_error, i);
8411           return -99;
8412         }
8413     }
8414
8415   if (address_set == 0)
8416     {
8417       errmsg ("missing addresses\n");
8418       return -99;
8419     }
8420
8421   /* Construct the API message */
8422   M (IP_MROUTE_ADD_DEL, mp);
8423
8424   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8425   mp->table_id = ntohl (vrf_id);
8426
8427   mp->is_add = is_add;
8428   mp->is_ipv6 = is_ipv6;
8429   mp->is_local = is_local;
8430   mp->itf_flags = ntohl (iflags);
8431   mp->entry_flags = ntohl (eflags);
8432   mp->grp_address_length = grp_address_length;
8433   mp->grp_address_length = ntohs (mp->grp_address_length);
8434
8435   if (is_ipv6)
8436     {
8437       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8438       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8439     }
8440   else
8441     {
8442       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8443       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8444
8445     }
8446
8447   /* send it... */
8448   S (mp);
8449   /* Wait for a reply... */
8450   W (ret);
8451   return ret;
8452 }
8453
8454 static int
8455 api_mpls_table_add_del (vat_main_t * vam)
8456 {
8457   unformat_input_t *i = vam->input;
8458   vl_api_mpls_table_add_del_t *mp;
8459   u32 table_id = ~0;
8460   u8 is_add = 1;
8461   int ret = 0;
8462
8463   /* Parse args required to build the message */
8464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8465     {
8466       if (unformat (i, "table %d", &table_id))
8467         ;
8468       else if (unformat (i, "del"))
8469         is_add = 0;
8470       else if (unformat (i, "add"))
8471         is_add = 1;
8472       else
8473         {
8474           clib_warning ("parse error '%U'", format_unformat_error, i);
8475           return -99;
8476         }
8477     }
8478
8479   if (~0 == table_id)
8480     {
8481       errmsg ("missing table-ID");
8482       return -99;
8483     }
8484
8485   /* Construct the API message */
8486   M (MPLS_TABLE_ADD_DEL, mp);
8487
8488   mp->mt_table_id = ntohl (table_id);
8489   mp->mt_is_add = is_add;
8490
8491   /* send it... */
8492   S (mp);
8493
8494   /* Wait for a reply... */
8495   W (ret);
8496
8497   return ret;
8498 }
8499
8500 static int
8501 api_mpls_route_add_del (vat_main_t * vam)
8502 {
8503   unformat_input_t *i = vam->input;
8504   vl_api_mpls_route_add_del_t *mp;
8505   u32 sw_if_index = ~0, table_id = 0;
8506   u8 is_add = 1;
8507   u32 next_hop_weight = 1;
8508   u8 is_multipath = 0;
8509   u32 next_hop_table_id = 0;
8510   u8 next_hop_set = 0;
8511   ip4_address_t v4_next_hop_address = {
8512     .as_u32 = 0,
8513   };
8514   ip6_address_t v6_next_hop_address = { {0} };
8515   int count = 1;
8516   int j;
8517   f64 before = 0;
8518   u32 classify_table_index = ~0;
8519   u8 is_classify = 0;
8520   u8 resolve_host = 0, resolve_attached = 0;
8521   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8522   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8523   mpls_label_t *next_hop_out_label_stack = NULL;
8524   mpls_label_t local_label = MPLS_LABEL_INVALID;
8525   u8 is_eos = 0;
8526   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8527
8528   /* Parse args required to build the message */
8529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8530     {
8531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8532         ;
8533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8534         ;
8535       else if (unformat (i, "%d", &local_label))
8536         ;
8537       else if (unformat (i, "eos"))
8538         is_eos = 1;
8539       else if (unformat (i, "non-eos"))
8540         is_eos = 0;
8541       else if (unformat (i, "via %U", unformat_ip4_address,
8542                          &v4_next_hop_address))
8543         {
8544           next_hop_set = 1;
8545           next_hop_proto = DPO_PROTO_IP4;
8546         }
8547       else if (unformat (i, "via %U", unformat_ip6_address,
8548                          &v6_next_hop_address))
8549         {
8550           next_hop_set = 1;
8551           next_hop_proto = DPO_PROTO_IP6;
8552         }
8553       else if (unformat (i, "weight %d", &next_hop_weight))
8554         ;
8555       else if (unformat (i, "classify %d", &classify_table_index))
8556         {
8557           is_classify = 1;
8558         }
8559       else if (unformat (i, "del"))
8560         is_add = 0;
8561       else if (unformat (i, "add"))
8562         is_add = 1;
8563       else if (unformat (i, "resolve-via-host"))
8564         resolve_host = 1;
8565       else if (unformat (i, "resolve-via-attached"))
8566         resolve_attached = 1;
8567       else if (unformat (i, "multipath"))
8568         is_multipath = 1;
8569       else if (unformat (i, "count %d", &count))
8570         ;
8571       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8572         {
8573           next_hop_set = 1;
8574           next_hop_proto = DPO_PROTO_IP4;
8575         }
8576       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8577         {
8578           next_hop_set = 1;
8579           next_hop_proto = DPO_PROTO_IP6;
8580         }
8581       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8582         ;
8583       else if (unformat (i, "via-label %d", &next_hop_via_label))
8584         ;
8585       else if (unformat (i, "out-label %d", &next_hop_out_label))
8586         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8587       else
8588         {
8589           clib_warning ("parse error '%U'", format_unformat_error, i);
8590           return -99;
8591         }
8592     }
8593
8594   if (!next_hop_set && !is_classify)
8595     {
8596       errmsg ("next hop / classify not set");
8597       return -99;
8598     }
8599
8600   if (MPLS_LABEL_INVALID == local_label)
8601     {
8602       errmsg ("missing label");
8603       return -99;
8604     }
8605
8606   if (count > 1)
8607     {
8608       /* Turn on async mode */
8609       vam->async_mode = 1;
8610       vam->async_errors = 0;
8611       before = vat_time_now (vam);
8612     }
8613
8614   for (j = 0; j < count; j++)
8615     {
8616       /* Construct the API message */
8617       M2 (MPLS_ROUTE_ADD_DEL, mp,
8618           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8619
8620       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8621       mp->mr_table_id = ntohl (table_id);
8622
8623       mp->mr_is_add = is_add;
8624       mp->mr_next_hop_proto = next_hop_proto;
8625       mp->mr_is_classify = is_classify;
8626       mp->mr_is_multipath = is_multipath;
8627       mp->mr_is_resolve_host = resolve_host;
8628       mp->mr_is_resolve_attached = resolve_attached;
8629       mp->mr_next_hop_weight = next_hop_weight;
8630       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8631       mp->mr_classify_table_index = ntohl (classify_table_index);
8632       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8633       mp->mr_label = ntohl (local_label);
8634       mp->mr_eos = is_eos;
8635
8636       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8637       if (0 != mp->mr_next_hop_n_out_labels)
8638         {
8639           memcpy (mp->mr_next_hop_out_label_stack,
8640                   next_hop_out_label_stack,
8641                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8642           vec_free (next_hop_out_label_stack);
8643         }
8644
8645       if (next_hop_set)
8646         {
8647           if (DPO_PROTO_IP4 == next_hop_proto)
8648             {
8649               clib_memcpy (mp->mr_next_hop,
8650                            &v4_next_hop_address,
8651                            sizeof (v4_next_hop_address));
8652             }
8653           else if (DPO_PROTO_IP6 == next_hop_proto)
8654
8655             {
8656               clib_memcpy (mp->mr_next_hop,
8657                            &v6_next_hop_address,
8658                            sizeof (v6_next_hop_address));
8659             }
8660         }
8661       local_label++;
8662
8663       /* send it... */
8664       S (mp);
8665       /* If we receive SIGTERM, stop now... */
8666       if (vam->do_exit)
8667         break;
8668     }
8669
8670   /* When testing multiple add/del ops, use a control-ping to sync */
8671   if (count > 1)
8672     {
8673       vl_api_control_ping_t *mp_ping;
8674       f64 after;
8675       f64 timeout;
8676
8677       /* Shut off async mode */
8678       vam->async_mode = 0;
8679
8680       MPING (CONTROL_PING, mp_ping);
8681       S (mp_ping);
8682
8683       timeout = vat_time_now (vam) + 1.0;
8684       while (vat_time_now (vam) < timeout)
8685         if (vam->result_ready == 1)
8686           goto out;
8687       vam->retval = -99;
8688
8689     out:
8690       if (vam->retval == -99)
8691         errmsg ("timeout");
8692
8693       if (vam->async_errors > 0)
8694         {
8695           errmsg ("%d asynchronous errors", vam->async_errors);
8696           vam->retval = -98;
8697         }
8698       vam->async_errors = 0;
8699       after = vat_time_now (vam);
8700
8701       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8702       if (j > 0)
8703         count = j;
8704
8705       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8706              count, after - before, count / (after - before));
8707     }
8708   else
8709     {
8710       int ret;
8711
8712       /* Wait for a reply... */
8713       W (ret);
8714       return ret;
8715     }
8716
8717   /* Return the good/bad news */
8718   return (vam->retval);
8719 }
8720
8721 static int
8722 api_mpls_ip_bind_unbind (vat_main_t * vam)
8723 {
8724   unformat_input_t *i = vam->input;
8725   vl_api_mpls_ip_bind_unbind_t *mp;
8726   u32 ip_table_id = 0;
8727   u8 is_bind = 1;
8728   u8 is_ip4 = 1;
8729   ip4_address_t v4_address;
8730   ip6_address_t v6_address;
8731   u32 address_length;
8732   u8 address_set = 0;
8733   mpls_label_t local_label = MPLS_LABEL_INVALID;
8734   int ret;
8735
8736   /* Parse args required to build the message */
8737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8738     {
8739       if (unformat (i, "%U/%d", unformat_ip4_address,
8740                     &v4_address, &address_length))
8741         {
8742           is_ip4 = 1;
8743           address_set = 1;
8744         }
8745       else if (unformat (i, "%U/%d", unformat_ip6_address,
8746                          &v6_address, &address_length))
8747         {
8748           is_ip4 = 0;
8749           address_set = 1;
8750         }
8751       else if (unformat (i, "%d", &local_label))
8752         ;
8753       else if (unformat (i, "table-id %d", &ip_table_id))
8754         ;
8755       else if (unformat (i, "unbind"))
8756         is_bind = 0;
8757       else if (unformat (i, "bind"))
8758         is_bind = 1;
8759       else
8760         {
8761           clib_warning ("parse error '%U'", format_unformat_error, i);
8762           return -99;
8763         }
8764     }
8765
8766   if (!address_set)
8767     {
8768       errmsg ("IP addres not set");
8769       return -99;
8770     }
8771
8772   if (MPLS_LABEL_INVALID == local_label)
8773     {
8774       errmsg ("missing label");
8775       return -99;
8776     }
8777
8778   /* Construct the API message */
8779   M (MPLS_IP_BIND_UNBIND, mp);
8780
8781   mp->mb_is_bind = is_bind;
8782   mp->mb_is_ip4 = is_ip4;
8783   mp->mb_ip_table_id = ntohl (ip_table_id);
8784   mp->mb_mpls_table_id = 0;
8785   mp->mb_label = ntohl (local_label);
8786   mp->mb_address_length = address_length;
8787
8788   if (is_ip4)
8789     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8790   else
8791     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8792
8793   /* send it... */
8794   S (mp);
8795
8796   /* Wait for a reply... */
8797   W (ret);
8798   return ret;
8799 }
8800
8801 static int
8802 api_bier_table_add_del (vat_main_t * vam)
8803 {
8804   unformat_input_t *i = vam->input;
8805   vl_api_bier_table_add_del_t *mp;
8806   u8 is_add = 1;
8807   u32 set = 0, sub_domain = 0, hdr_len = 3;
8808   mpls_label_t local_label = MPLS_LABEL_INVALID;
8809   int ret;
8810
8811   /* Parse args required to build the message */
8812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8813     {
8814       if (unformat (i, "sub-domain %d", &sub_domain))
8815         ;
8816       else if (unformat (i, "set %d", &set))
8817         ;
8818       else if (unformat (i, "label %d", &local_label))
8819         ;
8820       else if (unformat (i, "hdr-len %d", &hdr_len))
8821         ;
8822       else if (unformat (i, "add"))
8823         is_add = 1;
8824       else if (unformat (i, "del"))
8825         is_add = 0;
8826       else
8827         {
8828           clib_warning ("parse error '%U'", format_unformat_error, i);
8829           return -99;
8830         }
8831     }
8832
8833   if (MPLS_LABEL_INVALID == local_label)
8834     {
8835       errmsg ("missing label\n");
8836       return -99;
8837     }
8838
8839   /* Construct the API message */
8840   M (BIER_TABLE_ADD_DEL, mp);
8841
8842   mp->bt_is_add = is_add;
8843   mp->bt_label = ntohl (local_label);
8844   mp->bt_tbl_id.bt_set = set;
8845   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8846   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8847
8848   /* send it... */
8849   S (mp);
8850
8851   /* Wait for a reply... */
8852   W (ret);
8853
8854   return (ret);
8855 }
8856
8857 static int
8858 api_bier_route_add_del (vat_main_t * vam)
8859 {
8860   unformat_input_t *i = vam->input;
8861   vl_api_bier_route_add_del_t *mp;
8862   u8 is_add = 1;
8863   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8864   ip4_address_t v4_next_hop_address;
8865   ip6_address_t v6_next_hop_address;
8866   u8 next_hop_set = 0;
8867   u8 next_hop_proto_is_ip4 = 1;
8868   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8869   int ret;
8870
8871   /* Parse args required to build the message */
8872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8873     {
8874       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8875         {
8876           next_hop_proto_is_ip4 = 1;
8877           next_hop_set = 1;
8878         }
8879       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8880         {
8881           next_hop_proto_is_ip4 = 0;
8882           next_hop_set = 1;
8883         }
8884       if (unformat (i, "sub-domain %d", &sub_domain))
8885         ;
8886       else if (unformat (i, "set %d", &set))
8887         ;
8888       else if (unformat (i, "hdr-len %d", &hdr_len))
8889         ;
8890       else if (unformat (i, "bp %d", &bp))
8891         ;
8892       else if (unformat (i, "add"))
8893         is_add = 1;
8894       else if (unformat (i, "del"))
8895         is_add = 0;
8896       else if (unformat (i, "out-label %d", &next_hop_out_label))
8897         ;
8898       else
8899         {
8900           clib_warning ("parse error '%U'", format_unformat_error, i);
8901           return -99;
8902         }
8903     }
8904
8905   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8906     {
8907       errmsg ("next hop / label set\n");
8908       return -99;
8909     }
8910   if (0 == bp)
8911     {
8912       errmsg ("bit=position not set\n");
8913       return -99;
8914     }
8915
8916   /* Construct the API message */
8917   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8918
8919   mp->br_is_add = is_add;
8920   mp->br_tbl_id.bt_set = set;
8921   mp->br_tbl_id.bt_sub_domain = sub_domain;
8922   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8923   mp->br_bp = ntohs (bp);
8924   mp->br_n_paths = 1;
8925   mp->br_paths[0].n_labels = 1;
8926   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8927   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8928
8929   if (next_hop_proto_is_ip4)
8930     {
8931       clib_memcpy (mp->br_paths[0].next_hop,
8932                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8933     }
8934   else
8935     {
8936       clib_memcpy (mp->br_paths[0].next_hop,
8937                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8938     }
8939
8940   /* send it... */
8941   S (mp);
8942
8943   /* Wait for a reply... */
8944   W (ret);
8945
8946   return (ret);
8947 }
8948
8949 static int
8950 api_proxy_arp_add_del (vat_main_t * vam)
8951 {
8952   unformat_input_t *i = vam->input;
8953   vl_api_proxy_arp_add_del_t *mp;
8954   u32 vrf_id = 0;
8955   u8 is_add = 1;
8956   ip4_address_t lo, hi;
8957   u8 range_set = 0;
8958   int ret;
8959
8960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8961     {
8962       if (unformat (i, "vrf %d", &vrf_id))
8963         ;
8964       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8965                          unformat_ip4_address, &hi))
8966         range_set = 1;
8967       else if (unformat (i, "del"))
8968         is_add = 0;
8969       else
8970         {
8971           clib_warning ("parse error '%U'", format_unformat_error, i);
8972           return -99;
8973         }
8974     }
8975
8976   if (range_set == 0)
8977     {
8978       errmsg ("address range not set");
8979       return -99;
8980     }
8981
8982   M (PROXY_ARP_ADD_DEL, mp);
8983
8984   mp->vrf_id = ntohl (vrf_id);
8985   mp->is_add = is_add;
8986   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8987   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8988
8989   S (mp);
8990   W (ret);
8991   return ret;
8992 }
8993
8994 static int
8995 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8996 {
8997   unformat_input_t *i = vam->input;
8998   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8999   u32 sw_if_index;
9000   u8 enable = 1;
9001   u8 sw_if_index_set = 0;
9002   int ret;
9003
9004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9005     {
9006       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9007         sw_if_index_set = 1;
9008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9009         sw_if_index_set = 1;
9010       else if (unformat (i, "enable"))
9011         enable = 1;
9012       else if (unformat (i, "disable"))
9013         enable = 0;
9014       else
9015         {
9016           clib_warning ("parse error '%U'", format_unformat_error, i);
9017           return -99;
9018         }
9019     }
9020
9021   if (sw_if_index_set == 0)
9022     {
9023       errmsg ("missing interface name or sw_if_index");
9024       return -99;
9025     }
9026
9027   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9028
9029   mp->sw_if_index = ntohl (sw_if_index);
9030   mp->enable_disable = enable;
9031
9032   S (mp);
9033   W (ret);
9034   return ret;
9035 }
9036
9037 static int
9038 api_mpls_tunnel_add_del (vat_main_t * vam)
9039 {
9040   unformat_input_t *i = vam->input;
9041   vl_api_mpls_tunnel_add_del_t *mp;
9042
9043   u8 is_add = 1;
9044   u8 l2_only = 0;
9045   u32 sw_if_index = ~0;
9046   u32 next_hop_sw_if_index = ~0;
9047   u32 next_hop_proto_is_ip4 = 1;
9048
9049   u32 next_hop_table_id = 0;
9050   ip4_address_t v4_next_hop_address = {
9051     .as_u32 = 0,
9052   };
9053   ip6_address_t v6_next_hop_address = { {0} };
9054   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9055   int ret;
9056
9057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9058     {
9059       if (unformat (i, "add"))
9060         is_add = 1;
9061       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9062         is_add = 0;
9063       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9064         ;
9065       else if (unformat (i, "via %U",
9066                          unformat_ip4_address, &v4_next_hop_address))
9067         {
9068           next_hop_proto_is_ip4 = 1;
9069         }
9070       else if (unformat (i, "via %U",
9071                          unformat_ip6_address, &v6_next_hop_address))
9072         {
9073           next_hop_proto_is_ip4 = 0;
9074         }
9075       else if (unformat (i, "l2-only"))
9076         l2_only = 1;
9077       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9078         ;
9079       else if (unformat (i, "out-label %d", &next_hop_out_label))
9080         vec_add1 (labels, ntohl (next_hop_out_label));
9081       else
9082         {
9083           clib_warning ("parse error '%U'", format_unformat_error, i);
9084           return -99;
9085         }
9086     }
9087
9088   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9089
9090   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9091   mp->mt_sw_if_index = ntohl (sw_if_index);
9092   mp->mt_is_add = is_add;
9093   mp->mt_l2_only = l2_only;
9094   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9095   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9096
9097   mp->mt_next_hop_n_out_labels = vec_len (labels);
9098
9099   if (0 != mp->mt_next_hop_n_out_labels)
9100     {
9101       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9102                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9103       vec_free (labels);
9104     }
9105
9106   if (next_hop_proto_is_ip4)
9107     {
9108       clib_memcpy (mp->mt_next_hop,
9109                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9110     }
9111   else
9112     {
9113       clib_memcpy (mp->mt_next_hop,
9114                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9115     }
9116
9117   S (mp);
9118   W (ret);
9119   return ret;
9120 }
9121
9122 static int
9123 api_sw_interface_set_unnumbered (vat_main_t * vam)
9124 {
9125   unformat_input_t *i = vam->input;
9126   vl_api_sw_interface_set_unnumbered_t *mp;
9127   u32 sw_if_index;
9128   u32 unnum_sw_index = ~0;
9129   u8 is_add = 1;
9130   u8 sw_if_index_set = 0;
9131   int ret;
9132
9133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9134     {
9135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9136         sw_if_index_set = 1;
9137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9138         sw_if_index_set = 1;
9139       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9140         ;
9141       else if (unformat (i, "del"))
9142         is_add = 0;
9143       else
9144         {
9145           clib_warning ("parse error '%U'", format_unformat_error, i);
9146           return -99;
9147         }
9148     }
9149
9150   if (sw_if_index_set == 0)
9151     {
9152       errmsg ("missing interface name or sw_if_index");
9153       return -99;
9154     }
9155
9156   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9157
9158   mp->sw_if_index = ntohl (sw_if_index);
9159   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9160   mp->is_add = is_add;
9161
9162   S (mp);
9163   W (ret);
9164   return ret;
9165 }
9166
9167 static int
9168 api_ip_neighbor_add_del (vat_main_t * vam)
9169 {
9170   unformat_input_t *i = vam->input;
9171   vl_api_ip_neighbor_add_del_t *mp;
9172   u32 sw_if_index;
9173   u8 sw_if_index_set = 0;
9174   u8 is_add = 1;
9175   u8 is_static = 0;
9176   u8 is_no_fib_entry = 0;
9177   u8 mac_address[6];
9178   u8 mac_set = 0;
9179   u8 v4_address_set = 0;
9180   u8 v6_address_set = 0;
9181   ip4_address_t v4address;
9182   ip6_address_t v6address;
9183   int ret;
9184
9185   memset (mac_address, 0, sizeof (mac_address));
9186
9187   /* Parse args required to build the message */
9188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9189     {
9190       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9191         {
9192           mac_set = 1;
9193         }
9194       else if (unformat (i, "del"))
9195         is_add = 0;
9196       else
9197         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9198         sw_if_index_set = 1;
9199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9200         sw_if_index_set = 1;
9201       else if (unformat (i, "is_static"))
9202         is_static = 1;
9203       else if (unformat (i, "no-fib-entry"))
9204         is_no_fib_entry = 1;
9205       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9206         v4_address_set = 1;
9207       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9208         v6_address_set = 1;
9209       else
9210         {
9211           clib_warning ("parse error '%U'", format_unformat_error, i);
9212           return -99;
9213         }
9214     }
9215
9216   if (sw_if_index_set == 0)
9217     {
9218       errmsg ("missing interface name or sw_if_index");
9219       return -99;
9220     }
9221   if (v4_address_set && v6_address_set)
9222     {
9223       errmsg ("both v4 and v6 addresses set");
9224       return -99;
9225     }
9226   if (!v4_address_set && !v6_address_set)
9227     {
9228       errmsg ("no address set");
9229       return -99;
9230     }
9231
9232   /* Construct the API message */
9233   M (IP_NEIGHBOR_ADD_DEL, mp);
9234
9235   mp->sw_if_index = ntohl (sw_if_index);
9236   mp->is_add = is_add;
9237   mp->is_static = is_static;
9238   mp->is_no_adj_fib = is_no_fib_entry;
9239   if (mac_set)
9240     clib_memcpy (mp->mac_address, mac_address, 6);
9241   if (v6_address_set)
9242     {
9243       mp->is_ipv6 = 1;
9244       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9245     }
9246   else
9247     {
9248       /* mp->is_ipv6 = 0; via memset in M macro above */
9249       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9250     }
9251
9252   /* send it... */
9253   S (mp);
9254
9255   /* Wait for a reply, return good/bad news  */
9256   W (ret);
9257   return ret;
9258 }
9259
9260 static int
9261 api_create_vlan_subif (vat_main_t * vam)
9262 {
9263   unformat_input_t *i = vam->input;
9264   vl_api_create_vlan_subif_t *mp;
9265   u32 sw_if_index;
9266   u8 sw_if_index_set = 0;
9267   u32 vlan_id;
9268   u8 vlan_id_set = 0;
9269   int ret;
9270
9271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9272     {
9273       if (unformat (i, "sw_if_index %d", &sw_if_index))
9274         sw_if_index_set = 1;
9275       else
9276         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9277         sw_if_index_set = 1;
9278       else if (unformat (i, "vlan %d", &vlan_id))
9279         vlan_id_set = 1;
9280       else
9281         {
9282           clib_warning ("parse error '%U'", format_unformat_error, i);
9283           return -99;
9284         }
9285     }
9286
9287   if (sw_if_index_set == 0)
9288     {
9289       errmsg ("missing interface name or sw_if_index");
9290       return -99;
9291     }
9292
9293   if (vlan_id_set == 0)
9294     {
9295       errmsg ("missing vlan_id");
9296       return -99;
9297     }
9298   M (CREATE_VLAN_SUBIF, mp);
9299
9300   mp->sw_if_index = ntohl (sw_if_index);
9301   mp->vlan_id = ntohl (vlan_id);
9302
9303   S (mp);
9304   W (ret);
9305   return ret;
9306 }
9307
9308 #define foreach_create_subif_bit                \
9309 _(no_tags)                                      \
9310 _(one_tag)                                      \
9311 _(two_tags)                                     \
9312 _(dot1ad)                                       \
9313 _(exact_match)                                  \
9314 _(default_sub)                                  \
9315 _(outer_vlan_id_any)                            \
9316 _(inner_vlan_id_any)
9317
9318 static int
9319 api_create_subif (vat_main_t * vam)
9320 {
9321   unformat_input_t *i = vam->input;
9322   vl_api_create_subif_t *mp;
9323   u32 sw_if_index;
9324   u8 sw_if_index_set = 0;
9325   u32 sub_id;
9326   u8 sub_id_set = 0;
9327   u32 no_tags = 0;
9328   u32 one_tag = 0;
9329   u32 two_tags = 0;
9330   u32 dot1ad = 0;
9331   u32 exact_match = 0;
9332   u32 default_sub = 0;
9333   u32 outer_vlan_id_any = 0;
9334   u32 inner_vlan_id_any = 0;
9335   u32 tmp;
9336   u16 outer_vlan_id = 0;
9337   u16 inner_vlan_id = 0;
9338   int ret;
9339
9340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9341     {
9342       if (unformat (i, "sw_if_index %d", &sw_if_index))
9343         sw_if_index_set = 1;
9344       else
9345         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9346         sw_if_index_set = 1;
9347       else if (unformat (i, "sub_id %d", &sub_id))
9348         sub_id_set = 1;
9349       else if (unformat (i, "outer_vlan_id %d", &tmp))
9350         outer_vlan_id = tmp;
9351       else if (unformat (i, "inner_vlan_id %d", &tmp))
9352         inner_vlan_id = tmp;
9353
9354 #define _(a) else if (unformat (i, #a)) a = 1 ;
9355       foreach_create_subif_bit
9356 #undef _
9357         else
9358         {
9359           clib_warning ("parse error '%U'", format_unformat_error, i);
9360           return -99;
9361         }
9362     }
9363
9364   if (sw_if_index_set == 0)
9365     {
9366       errmsg ("missing interface name or sw_if_index");
9367       return -99;
9368     }
9369
9370   if (sub_id_set == 0)
9371     {
9372       errmsg ("missing sub_id");
9373       return -99;
9374     }
9375   M (CREATE_SUBIF, mp);
9376
9377   mp->sw_if_index = ntohl (sw_if_index);
9378   mp->sub_id = ntohl (sub_id);
9379
9380 #define _(a) mp->a = a;
9381   foreach_create_subif_bit;
9382 #undef _
9383
9384   mp->outer_vlan_id = ntohs (outer_vlan_id);
9385   mp->inner_vlan_id = ntohs (inner_vlan_id);
9386
9387   S (mp);
9388   W (ret);
9389   return ret;
9390 }
9391
9392 static int
9393 api_oam_add_del (vat_main_t * vam)
9394 {
9395   unformat_input_t *i = vam->input;
9396   vl_api_oam_add_del_t *mp;
9397   u32 vrf_id = 0;
9398   u8 is_add = 1;
9399   ip4_address_t src, dst;
9400   u8 src_set = 0;
9401   u8 dst_set = 0;
9402   int ret;
9403
9404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9405     {
9406       if (unformat (i, "vrf %d", &vrf_id))
9407         ;
9408       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9409         src_set = 1;
9410       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9411         dst_set = 1;
9412       else if (unformat (i, "del"))
9413         is_add = 0;
9414       else
9415         {
9416           clib_warning ("parse error '%U'", format_unformat_error, i);
9417           return -99;
9418         }
9419     }
9420
9421   if (src_set == 0)
9422     {
9423       errmsg ("missing src addr");
9424       return -99;
9425     }
9426
9427   if (dst_set == 0)
9428     {
9429       errmsg ("missing dst addr");
9430       return -99;
9431     }
9432
9433   M (OAM_ADD_DEL, mp);
9434
9435   mp->vrf_id = ntohl (vrf_id);
9436   mp->is_add = is_add;
9437   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9438   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9439
9440   S (mp);
9441   W (ret);
9442   return ret;
9443 }
9444
9445 static int
9446 api_reset_fib (vat_main_t * vam)
9447 {
9448   unformat_input_t *i = vam->input;
9449   vl_api_reset_fib_t *mp;
9450   u32 vrf_id = 0;
9451   u8 is_ipv6 = 0;
9452   u8 vrf_id_set = 0;
9453
9454   int ret;
9455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9456     {
9457       if (unformat (i, "vrf %d", &vrf_id))
9458         vrf_id_set = 1;
9459       else if (unformat (i, "ipv6"))
9460         is_ipv6 = 1;
9461       else
9462         {
9463           clib_warning ("parse error '%U'", format_unformat_error, i);
9464           return -99;
9465         }
9466     }
9467
9468   if (vrf_id_set == 0)
9469     {
9470       errmsg ("missing vrf id");
9471       return -99;
9472     }
9473
9474   M (RESET_FIB, mp);
9475
9476   mp->vrf_id = ntohl (vrf_id);
9477   mp->is_ipv6 = is_ipv6;
9478
9479   S (mp);
9480   W (ret);
9481   return ret;
9482 }
9483
9484 static int
9485 api_dhcp_proxy_config (vat_main_t * vam)
9486 {
9487   unformat_input_t *i = vam->input;
9488   vl_api_dhcp_proxy_config_t *mp;
9489   u32 rx_vrf_id = 0;
9490   u32 server_vrf_id = 0;
9491   u8 is_add = 1;
9492   u8 v4_address_set = 0;
9493   u8 v6_address_set = 0;
9494   ip4_address_t v4address;
9495   ip6_address_t v6address;
9496   u8 v4_src_address_set = 0;
9497   u8 v6_src_address_set = 0;
9498   ip4_address_t v4srcaddress;
9499   ip6_address_t v6srcaddress;
9500   int ret;
9501
9502   /* Parse args required to build the message */
9503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9504     {
9505       if (unformat (i, "del"))
9506         is_add = 0;
9507       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9508         ;
9509       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9510         ;
9511       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9512         v4_address_set = 1;
9513       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9514         v6_address_set = 1;
9515       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9516         v4_src_address_set = 1;
9517       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9518         v6_src_address_set = 1;
9519       else
9520         break;
9521     }
9522
9523   if (v4_address_set && v6_address_set)
9524     {
9525       errmsg ("both v4 and v6 server addresses set");
9526       return -99;
9527     }
9528   if (!v4_address_set && !v6_address_set)
9529     {
9530       errmsg ("no server addresses set");
9531       return -99;
9532     }
9533
9534   if (v4_src_address_set && v6_src_address_set)
9535     {
9536       errmsg ("both v4 and v6  src addresses set");
9537       return -99;
9538     }
9539   if (!v4_src_address_set && !v6_src_address_set)
9540     {
9541       errmsg ("no src addresses set");
9542       return -99;
9543     }
9544
9545   if (!(v4_src_address_set && v4_address_set) &&
9546       !(v6_src_address_set && v6_address_set))
9547     {
9548       errmsg ("no matching server and src addresses set");
9549       return -99;
9550     }
9551
9552   /* Construct the API message */
9553   M (DHCP_PROXY_CONFIG, mp);
9554
9555   mp->is_add = is_add;
9556   mp->rx_vrf_id = ntohl (rx_vrf_id);
9557   mp->server_vrf_id = ntohl (server_vrf_id);
9558   if (v6_address_set)
9559     {
9560       mp->is_ipv6 = 1;
9561       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9562       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9563     }
9564   else
9565     {
9566       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9567       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9568     }
9569
9570   /* send it... */
9571   S (mp);
9572
9573   /* Wait for a reply, return good/bad news  */
9574   W (ret);
9575   return ret;
9576 }
9577
9578 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9579 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9580
9581 static void
9582 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9583 {
9584   vat_main_t *vam = &vat_main;
9585   u32 i, count = mp->count;
9586   vl_api_dhcp_server_t *s;
9587
9588   if (mp->is_ipv6)
9589     print (vam->ofp,
9590            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9591            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9592            ntohl (mp->rx_vrf_id),
9593            format_ip6_address, mp->dhcp_src_address,
9594            mp->vss_type, mp->vss_vpn_ascii_id,
9595            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9596   else
9597     print (vam->ofp,
9598            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9599            "VSS VPN-ID '%s', VSS FIB-ID %d, VSS OUI %d",
9600            ntohl (mp->rx_vrf_id),
9601            format_ip4_address, mp->dhcp_src_address,
9602            mp->vss_type, mp->vss_vpn_ascii_id,
9603            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9604
9605   for (i = 0; i < count; i++)
9606     {
9607       s = &mp->servers[i];
9608
9609       if (mp->is_ipv6)
9610         print (vam->ofp,
9611                " Server Table-ID %d, Server Address %U",
9612                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9613       else
9614         print (vam->ofp,
9615                " Server Table-ID %d, Server Address %U",
9616                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9617     }
9618 }
9619
9620 static void vl_api_dhcp_proxy_details_t_handler_json
9621   (vl_api_dhcp_proxy_details_t * mp)
9622 {
9623   vat_main_t *vam = &vat_main;
9624   vat_json_node_t *node = NULL;
9625   u32 i, count = mp->count;
9626   struct in_addr ip4;
9627   struct in6_addr ip6;
9628   vl_api_dhcp_server_t *s;
9629
9630   if (VAT_JSON_ARRAY != vam->json_tree.type)
9631     {
9632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9633       vat_json_init_array (&vam->json_tree);
9634     }
9635   node = vat_json_array_add (&vam->json_tree);
9636
9637   vat_json_init_object (node);
9638   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9639   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9640                              sizeof (mp->vss_type));
9641   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9642                                    mp->vss_vpn_ascii_id);
9643   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9644   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9645
9646   if (mp->is_ipv6)
9647     {
9648       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9649       vat_json_object_add_ip6 (node, "src_address", ip6);
9650     }
9651   else
9652     {
9653       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9654       vat_json_object_add_ip4 (node, "src_address", ip4);
9655     }
9656
9657   for (i = 0; i < count; i++)
9658     {
9659       s = &mp->servers[i];
9660
9661       vat_json_object_add_uint (node, "server-table-id",
9662                                 ntohl (s->server_vrf_id));
9663
9664       if (mp->is_ipv6)
9665         {
9666           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9667           vat_json_object_add_ip4 (node, "src_address", ip4);
9668         }
9669       else
9670         {
9671           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9672           vat_json_object_add_ip6 (node, "server_address", ip6);
9673         }
9674     }
9675 }
9676
9677 static int
9678 api_dhcp_proxy_dump (vat_main_t * vam)
9679 {
9680   unformat_input_t *i = vam->input;
9681   vl_api_control_ping_t *mp_ping;
9682   vl_api_dhcp_proxy_dump_t *mp;
9683   u8 is_ipv6 = 0;
9684   int ret;
9685
9686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9687     {
9688       if (unformat (i, "ipv6"))
9689         is_ipv6 = 1;
9690       else
9691         {
9692           clib_warning ("parse error '%U'", format_unformat_error, i);
9693           return -99;
9694         }
9695     }
9696
9697   M (DHCP_PROXY_DUMP, mp);
9698
9699   mp->is_ip6 = is_ipv6;
9700   S (mp);
9701
9702   /* Use a control ping for synchronization */
9703   MPING (CONTROL_PING, mp_ping);
9704   S (mp_ping);
9705
9706   W (ret);
9707   return ret;
9708 }
9709
9710 static int
9711 api_dhcp_proxy_set_vss (vat_main_t * vam)
9712 {
9713   unformat_input_t *i = vam->input;
9714   vl_api_dhcp_proxy_set_vss_t *mp;
9715   u8 is_ipv6 = 0;
9716   u8 is_add = 1;
9717   u32 tbl_id = ~0;
9718   u8 vss_type = VSS_TYPE_DEFAULT;
9719   u8 *vpn_ascii_id = 0;
9720   u32 oui = 0;
9721   u32 fib_id = 0;
9722   int ret;
9723
9724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9725     {
9726       if (unformat (i, "tbl_id %d", &tbl_id))
9727         ;
9728       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9729         vss_type = VSS_TYPE_ASCII;
9730       else if (unformat (i, "fib_id %d", &fib_id))
9731         vss_type = VSS_TYPE_VPN_ID;
9732       else if (unformat (i, "oui %d", &oui))
9733         vss_type = VSS_TYPE_VPN_ID;
9734       else if (unformat (i, "ipv6"))
9735         is_ipv6 = 1;
9736       else if (unformat (i, "del"))
9737         is_add = 0;
9738       else
9739         break;
9740     }
9741
9742   if (tbl_id == ~0)
9743     {
9744       errmsg ("missing tbl_id ");
9745       vec_free (vpn_ascii_id);
9746       return -99;
9747     }
9748
9749   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9750     {
9751       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9752       vec_free (vpn_ascii_id);
9753       return -99;
9754     }
9755
9756   M (DHCP_PROXY_SET_VSS, mp);
9757   mp->tbl_id = ntohl (tbl_id);
9758   mp->vss_type = vss_type;
9759   if (vpn_ascii_id)
9760     {
9761       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9762       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9763     }
9764   mp->vpn_index = ntohl (fib_id);
9765   mp->oui = ntohl (oui);
9766   mp->is_ipv6 = is_ipv6;
9767   mp->is_add = is_add;
9768
9769   S (mp);
9770   W (ret);
9771
9772   vec_free (vpn_ascii_id);
9773   return ret;
9774 }
9775
9776 static int
9777 api_dhcp_client_config (vat_main_t * vam)
9778 {
9779   unformat_input_t *i = vam->input;
9780   vl_api_dhcp_client_config_t *mp;
9781   u32 sw_if_index;
9782   u8 sw_if_index_set = 0;
9783   u8 is_add = 1;
9784   u8 *hostname = 0;
9785   u8 disable_event = 0;
9786   int ret;
9787
9788   /* Parse args required to build the message */
9789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9790     {
9791       if (unformat (i, "del"))
9792         is_add = 0;
9793       else
9794         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9795         sw_if_index_set = 1;
9796       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9797         sw_if_index_set = 1;
9798       else if (unformat (i, "hostname %s", &hostname))
9799         ;
9800       else if (unformat (i, "disable_event"))
9801         disable_event = 1;
9802       else
9803         break;
9804     }
9805
9806   if (sw_if_index_set == 0)
9807     {
9808       errmsg ("missing interface name or sw_if_index");
9809       return -99;
9810     }
9811
9812   if (vec_len (hostname) > 63)
9813     {
9814       errmsg ("hostname too long");
9815     }
9816   vec_add1 (hostname, 0);
9817
9818   /* Construct the API message */
9819   M (DHCP_CLIENT_CONFIG, mp);
9820
9821   mp->sw_if_index = htonl (sw_if_index);
9822   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9823   vec_free (hostname);
9824   mp->is_add = is_add;
9825   mp->want_dhcp_event = disable_event ? 0 : 1;
9826   mp->pid = htonl (getpid ());
9827
9828   /* send it... */
9829   S (mp);
9830
9831   /* Wait for a reply, return good/bad news  */
9832   W (ret);
9833   return ret;
9834 }
9835
9836 static int
9837 api_set_ip_flow_hash (vat_main_t * vam)
9838 {
9839   unformat_input_t *i = vam->input;
9840   vl_api_set_ip_flow_hash_t *mp;
9841   u32 vrf_id = 0;
9842   u8 is_ipv6 = 0;
9843   u8 vrf_id_set = 0;
9844   u8 src = 0;
9845   u8 dst = 0;
9846   u8 sport = 0;
9847   u8 dport = 0;
9848   u8 proto = 0;
9849   u8 reverse = 0;
9850   int ret;
9851
9852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9853     {
9854       if (unformat (i, "vrf %d", &vrf_id))
9855         vrf_id_set = 1;
9856       else if (unformat (i, "ipv6"))
9857         is_ipv6 = 1;
9858       else if (unformat (i, "src"))
9859         src = 1;
9860       else if (unformat (i, "dst"))
9861         dst = 1;
9862       else if (unformat (i, "sport"))
9863         sport = 1;
9864       else if (unformat (i, "dport"))
9865         dport = 1;
9866       else if (unformat (i, "proto"))
9867         proto = 1;
9868       else if (unformat (i, "reverse"))
9869         reverse = 1;
9870
9871       else
9872         {
9873           clib_warning ("parse error '%U'", format_unformat_error, i);
9874           return -99;
9875         }
9876     }
9877
9878   if (vrf_id_set == 0)
9879     {
9880       errmsg ("missing vrf id");
9881       return -99;
9882     }
9883
9884   M (SET_IP_FLOW_HASH, mp);
9885   mp->src = src;
9886   mp->dst = dst;
9887   mp->sport = sport;
9888   mp->dport = dport;
9889   mp->proto = proto;
9890   mp->reverse = reverse;
9891   mp->vrf_id = ntohl (vrf_id);
9892   mp->is_ipv6 = is_ipv6;
9893
9894   S (mp);
9895   W (ret);
9896   return ret;
9897 }
9898
9899 static int
9900 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9901 {
9902   unformat_input_t *i = vam->input;
9903   vl_api_sw_interface_ip6_enable_disable_t *mp;
9904   u32 sw_if_index;
9905   u8 sw_if_index_set = 0;
9906   u8 enable = 0;
9907   int ret;
9908
9909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9910     {
9911       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9912         sw_if_index_set = 1;
9913       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9914         sw_if_index_set = 1;
9915       else if (unformat (i, "enable"))
9916         enable = 1;
9917       else if (unformat (i, "disable"))
9918         enable = 0;
9919       else
9920         {
9921           clib_warning ("parse error '%U'", format_unformat_error, i);
9922           return -99;
9923         }
9924     }
9925
9926   if (sw_if_index_set == 0)
9927     {
9928       errmsg ("missing interface name or sw_if_index");
9929       return -99;
9930     }
9931
9932   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9933
9934   mp->sw_if_index = ntohl (sw_if_index);
9935   mp->enable = enable;
9936
9937   S (mp);
9938   W (ret);
9939   return ret;
9940 }
9941
9942 static int
9943 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9944 {
9945   unformat_input_t *i = vam->input;
9946   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9947   u32 sw_if_index;
9948   u8 sw_if_index_set = 0;
9949   u8 v6_address_set = 0;
9950   ip6_address_t v6address;
9951   int ret;
9952
9953   /* Parse args required to build the message */
9954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9955     {
9956       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9957         sw_if_index_set = 1;
9958       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9959         sw_if_index_set = 1;
9960       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9961         v6_address_set = 1;
9962       else
9963         break;
9964     }
9965
9966   if (sw_if_index_set == 0)
9967     {
9968       errmsg ("missing interface name or sw_if_index");
9969       return -99;
9970     }
9971   if (!v6_address_set)
9972     {
9973       errmsg ("no address set");
9974       return -99;
9975     }
9976
9977   /* Construct the API message */
9978   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9979
9980   mp->sw_if_index = ntohl (sw_if_index);
9981   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9982
9983   /* send it... */
9984   S (mp);
9985
9986   /* Wait for a reply, return good/bad news  */
9987   W (ret);
9988   return ret;
9989 }
9990
9991 static int
9992 api_ip6nd_proxy_add_del (vat_main_t * vam)
9993 {
9994   unformat_input_t *i = vam->input;
9995   vl_api_ip6nd_proxy_add_del_t *mp;
9996   u32 sw_if_index = ~0;
9997   u8 v6_address_set = 0;
9998   ip6_address_t v6address;
9999   u8 is_del = 0;
10000   int ret;
10001
10002   /* Parse args required to build the message */
10003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10004     {
10005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10006         ;
10007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10008         ;
10009       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10010         v6_address_set = 1;
10011       if (unformat (i, "del"))
10012         is_del = 1;
10013       else
10014         {
10015           clib_warning ("parse error '%U'", format_unformat_error, i);
10016           return -99;
10017         }
10018     }
10019
10020   if (sw_if_index == ~0)
10021     {
10022       errmsg ("missing interface name or sw_if_index");
10023       return -99;
10024     }
10025   if (!v6_address_set)
10026     {
10027       errmsg ("no address set");
10028       return -99;
10029     }
10030
10031   /* Construct the API message */
10032   M (IP6ND_PROXY_ADD_DEL, mp);
10033
10034   mp->is_del = is_del;
10035   mp->sw_if_index = ntohl (sw_if_index);
10036   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10037
10038   /* send it... */
10039   S (mp);
10040
10041   /* Wait for a reply, return good/bad news  */
10042   W (ret);
10043   return ret;
10044 }
10045
10046 static int
10047 api_ip6nd_proxy_dump (vat_main_t * vam)
10048 {
10049   vl_api_ip6nd_proxy_dump_t *mp;
10050   vl_api_control_ping_t *mp_ping;
10051   int ret;
10052
10053   M (IP6ND_PROXY_DUMP, mp);
10054
10055   S (mp);
10056
10057   /* Use a control ping for synchronization */
10058   MPING (CONTROL_PING, mp_ping);
10059   S (mp_ping);
10060
10061   W (ret);
10062   return ret;
10063 }
10064
10065 static void vl_api_ip6nd_proxy_details_t_handler
10066   (vl_api_ip6nd_proxy_details_t * mp)
10067 {
10068   vat_main_t *vam = &vat_main;
10069
10070   print (vam->ofp, "host %U sw_if_index %d",
10071          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10072 }
10073
10074 static void vl_api_ip6nd_proxy_details_t_handler_json
10075   (vl_api_ip6nd_proxy_details_t * mp)
10076 {
10077   vat_main_t *vam = &vat_main;
10078   struct in6_addr ip6;
10079   vat_json_node_t *node = NULL;
10080
10081   if (VAT_JSON_ARRAY != vam->json_tree.type)
10082     {
10083       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10084       vat_json_init_array (&vam->json_tree);
10085     }
10086   node = vat_json_array_add (&vam->json_tree);
10087
10088   vat_json_init_object (node);
10089   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10090
10091   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10092   vat_json_object_add_ip6 (node, "host", ip6);
10093 }
10094
10095 static int
10096 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10097 {
10098   unformat_input_t *i = vam->input;
10099   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10100   u32 sw_if_index;
10101   u8 sw_if_index_set = 0;
10102   u32 address_length = 0;
10103   u8 v6_address_set = 0;
10104   ip6_address_t v6address;
10105   u8 use_default = 0;
10106   u8 no_advertise = 0;
10107   u8 off_link = 0;
10108   u8 no_autoconfig = 0;
10109   u8 no_onlink = 0;
10110   u8 is_no = 0;
10111   u32 val_lifetime = 0;
10112   u32 pref_lifetime = 0;
10113   int ret;
10114
10115   /* Parse args required to build the message */
10116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10117     {
10118       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10119         sw_if_index_set = 1;
10120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10121         sw_if_index_set = 1;
10122       else if (unformat (i, "%U/%d",
10123                          unformat_ip6_address, &v6address, &address_length))
10124         v6_address_set = 1;
10125       else if (unformat (i, "val_life %d", &val_lifetime))
10126         ;
10127       else if (unformat (i, "pref_life %d", &pref_lifetime))
10128         ;
10129       else if (unformat (i, "def"))
10130         use_default = 1;
10131       else if (unformat (i, "noadv"))
10132         no_advertise = 1;
10133       else if (unformat (i, "offl"))
10134         off_link = 1;
10135       else if (unformat (i, "noauto"))
10136         no_autoconfig = 1;
10137       else if (unformat (i, "nolink"))
10138         no_onlink = 1;
10139       else if (unformat (i, "isno"))
10140         is_no = 1;
10141       else
10142         {
10143           clib_warning ("parse error '%U'", format_unformat_error, i);
10144           return -99;
10145         }
10146     }
10147
10148   if (sw_if_index_set == 0)
10149     {
10150       errmsg ("missing interface name or sw_if_index");
10151       return -99;
10152     }
10153   if (!v6_address_set)
10154     {
10155       errmsg ("no address set");
10156       return -99;
10157     }
10158
10159   /* Construct the API message */
10160   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10161
10162   mp->sw_if_index = ntohl (sw_if_index);
10163   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10164   mp->address_length = address_length;
10165   mp->use_default = use_default;
10166   mp->no_advertise = no_advertise;
10167   mp->off_link = off_link;
10168   mp->no_autoconfig = no_autoconfig;
10169   mp->no_onlink = no_onlink;
10170   mp->is_no = is_no;
10171   mp->val_lifetime = ntohl (val_lifetime);
10172   mp->pref_lifetime = ntohl (pref_lifetime);
10173
10174   /* send it... */
10175   S (mp);
10176
10177   /* Wait for a reply, return good/bad news  */
10178   W (ret);
10179   return ret;
10180 }
10181
10182 static int
10183 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10184 {
10185   unformat_input_t *i = vam->input;
10186   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10187   u32 sw_if_index;
10188   u8 sw_if_index_set = 0;
10189   u8 suppress = 0;
10190   u8 managed = 0;
10191   u8 other = 0;
10192   u8 ll_option = 0;
10193   u8 send_unicast = 0;
10194   u8 cease = 0;
10195   u8 is_no = 0;
10196   u8 default_router = 0;
10197   u32 max_interval = 0;
10198   u32 min_interval = 0;
10199   u32 lifetime = 0;
10200   u32 initial_count = 0;
10201   u32 initial_interval = 0;
10202   int ret;
10203
10204
10205   /* Parse args required to build the message */
10206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10207     {
10208       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10209         sw_if_index_set = 1;
10210       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10211         sw_if_index_set = 1;
10212       else if (unformat (i, "maxint %d", &max_interval))
10213         ;
10214       else if (unformat (i, "minint %d", &min_interval))
10215         ;
10216       else if (unformat (i, "life %d", &lifetime))
10217         ;
10218       else if (unformat (i, "count %d", &initial_count))
10219         ;
10220       else if (unformat (i, "interval %d", &initial_interval))
10221         ;
10222       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10223         suppress = 1;
10224       else if (unformat (i, "managed"))
10225         managed = 1;
10226       else if (unformat (i, "other"))
10227         other = 1;
10228       else if (unformat (i, "ll"))
10229         ll_option = 1;
10230       else if (unformat (i, "send"))
10231         send_unicast = 1;
10232       else if (unformat (i, "cease"))
10233         cease = 1;
10234       else if (unformat (i, "isno"))
10235         is_no = 1;
10236       else if (unformat (i, "def"))
10237         default_router = 1;
10238       else
10239         {
10240           clib_warning ("parse error '%U'", format_unformat_error, i);
10241           return -99;
10242         }
10243     }
10244
10245   if (sw_if_index_set == 0)
10246     {
10247       errmsg ("missing interface name or sw_if_index");
10248       return -99;
10249     }
10250
10251   /* Construct the API message */
10252   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10253
10254   mp->sw_if_index = ntohl (sw_if_index);
10255   mp->max_interval = ntohl (max_interval);
10256   mp->min_interval = ntohl (min_interval);
10257   mp->lifetime = ntohl (lifetime);
10258   mp->initial_count = ntohl (initial_count);
10259   mp->initial_interval = ntohl (initial_interval);
10260   mp->suppress = suppress;
10261   mp->managed = managed;
10262   mp->other = other;
10263   mp->ll_option = ll_option;
10264   mp->send_unicast = send_unicast;
10265   mp->cease = cease;
10266   mp->is_no = is_no;
10267   mp->default_router = default_router;
10268
10269   /* send it... */
10270   S (mp);
10271
10272   /* Wait for a reply, return good/bad news  */
10273   W (ret);
10274   return ret;
10275 }
10276
10277 static int
10278 api_set_arp_neighbor_limit (vat_main_t * vam)
10279 {
10280   unformat_input_t *i = vam->input;
10281   vl_api_set_arp_neighbor_limit_t *mp;
10282   u32 arp_nbr_limit;
10283   u8 limit_set = 0;
10284   u8 is_ipv6 = 0;
10285   int ret;
10286
10287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10290         limit_set = 1;
10291       else if (unformat (i, "ipv6"))
10292         is_ipv6 = 1;
10293       else
10294         {
10295           clib_warning ("parse error '%U'", format_unformat_error, i);
10296           return -99;
10297         }
10298     }
10299
10300   if (limit_set == 0)
10301     {
10302       errmsg ("missing limit value");
10303       return -99;
10304     }
10305
10306   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10307
10308   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10309   mp->is_ipv6 = is_ipv6;
10310
10311   S (mp);
10312   W (ret);
10313   return ret;
10314 }
10315
10316 static int
10317 api_l2_patch_add_del (vat_main_t * vam)
10318 {
10319   unformat_input_t *i = vam->input;
10320   vl_api_l2_patch_add_del_t *mp;
10321   u32 rx_sw_if_index;
10322   u8 rx_sw_if_index_set = 0;
10323   u32 tx_sw_if_index;
10324   u8 tx_sw_if_index_set = 0;
10325   u8 is_add = 1;
10326   int ret;
10327
10328   /* Parse args required to build the message */
10329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10330     {
10331       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10332         rx_sw_if_index_set = 1;
10333       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10334         tx_sw_if_index_set = 1;
10335       else if (unformat (i, "rx"))
10336         {
10337           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10338             {
10339               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10340                             &rx_sw_if_index))
10341                 rx_sw_if_index_set = 1;
10342             }
10343           else
10344             break;
10345         }
10346       else if (unformat (i, "tx"))
10347         {
10348           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10349             {
10350               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10351                             &tx_sw_if_index))
10352                 tx_sw_if_index_set = 1;
10353             }
10354           else
10355             break;
10356         }
10357       else if (unformat (i, "del"))
10358         is_add = 0;
10359       else
10360         break;
10361     }
10362
10363   if (rx_sw_if_index_set == 0)
10364     {
10365       errmsg ("missing rx interface name or rx_sw_if_index");
10366       return -99;
10367     }
10368
10369   if (tx_sw_if_index_set == 0)
10370     {
10371       errmsg ("missing tx interface name or tx_sw_if_index");
10372       return -99;
10373     }
10374
10375   M (L2_PATCH_ADD_DEL, mp);
10376
10377   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10378   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10379   mp->is_add = is_add;
10380
10381   S (mp);
10382   W (ret);
10383   return ret;
10384 }
10385
10386 u8 is_del;
10387 u8 localsid_addr[16];
10388 u8 end_psp;
10389 u8 behavior;
10390 u32 sw_if_index;
10391 u32 vlan_index;
10392 u32 fib_table;
10393 u8 nh_addr[16];
10394
10395 static int
10396 api_sr_localsid_add_del (vat_main_t * vam)
10397 {
10398   unformat_input_t *i = vam->input;
10399   vl_api_sr_localsid_add_del_t *mp;
10400
10401   u8 is_del;
10402   ip6_address_t localsid;
10403   u8 end_psp = 0;
10404   u8 behavior = ~0;
10405   u32 sw_if_index;
10406   u32 fib_table = ~(u32) 0;
10407   ip6_address_t next_hop;
10408
10409   bool nexthop_set = 0;
10410
10411   int ret;
10412
10413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10414     {
10415       if (unformat (i, "del"))
10416         is_del = 1;
10417       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10418       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10419         nexthop_set = 1;
10420       else if (unformat (i, "behavior %u", &behavior));
10421       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10422       else if (unformat (i, "fib-table %u", &fib_table));
10423       else if (unformat (i, "end.psp %u", &behavior));
10424       else
10425         break;
10426     }
10427
10428   M (SR_LOCALSID_ADD_DEL, mp);
10429
10430   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10431   if (nexthop_set)
10432     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10433   mp->behavior = behavior;
10434   mp->sw_if_index = ntohl (sw_if_index);
10435   mp->fib_table = ntohl (fib_table);
10436   mp->end_psp = end_psp;
10437   mp->is_del = is_del;
10438
10439   S (mp);
10440   W (ret);
10441   return ret;
10442 }
10443
10444 static int
10445 api_ioam_enable (vat_main_t * vam)
10446 {
10447   unformat_input_t *input = vam->input;
10448   vl_api_ioam_enable_t *mp;
10449   u32 id = 0;
10450   int has_trace_option = 0;
10451   int has_pot_option = 0;
10452   int has_seqno_option = 0;
10453   int has_analyse_option = 0;
10454   int ret;
10455
10456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10457     {
10458       if (unformat (input, "trace"))
10459         has_trace_option = 1;
10460       else if (unformat (input, "pot"))
10461         has_pot_option = 1;
10462       else if (unformat (input, "seqno"))
10463         has_seqno_option = 1;
10464       else if (unformat (input, "analyse"))
10465         has_analyse_option = 1;
10466       else
10467         break;
10468     }
10469   M (IOAM_ENABLE, mp);
10470   mp->id = htons (id);
10471   mp->seqno = has_seqno_option;
10472   mp->analyse = has_analyse_option;
10473   mp->pot_enable = has_pot_option;
10474   mp->trace_enable = has_trace_option;
10475
10476   S (mp);
10477   W (ret);
10478   return ret;
10479 }
10480
10481
10482 static int
10483 api_ioam_disable (vat_main_t * vam)
10484 {
10485   vl_api_ioam_disable_t *mp;
10486   int ret;
10487
10488   M (IOAM_DISABLE, mp);
10489   S (mp);
10490   W (ret);
10491   return ret;
10492 }
10493
10494 #define foreach_tcp_proto_field                 \
10495 _(src_port)                                     \
10496 _(dst_port)
10497
10498 #define foreach_udp_proto_field                 \
10499 _(src_port)                                     \
10500 _(dst_port)
10501
10502 #define foreach_ip4_proto_field                 \
10503 _(src_address)                                  \
10504 _(dst_address)                                  \
10505 _(tos)                                          \
10506 _(length)                                       \
10507 _(fragment_id)                                  \
10508 _(ttl)                                          \
10509 _(protocol)                                     \
10510 _(checksum)
10511
10512 typedef struct
10513 {
10514   u16 src_port, dst_port;
10515 } tcpudp_header_t;
10516
10517 #if VPP_API_TEST_BUILTIN == 0
10518 uword
10519 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10520 {
10521   u8 **maskp = va_arg (*args, u8 **);
10522   u8 *mask = 0;
10523   u8 found_something = 0;
10524   tcp_header_t *tcp;
10525
10526 #define _(a) u8 a=0;
10527   foreach_tcp_proto_field;
10528 #undef _
10529
10530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10531     {
10532       if (0);
10533 #define _(a) else if (unformat (input, #a)) a=1;
10534       foreach_tcp_proto_field
10535 #undef _
10536         else
10537         break;
10538     }
10539
10540 #define _(a) found_something += a;
10541   foreach_tcp_proto_field;
10542 #undef _
10543
10544   if (found_something == 0)
10545     return 0;
10546
10547   vec_validate (mask, sizeof (*tcp) - 1);
10548
10549   tcp = (tcp_header_t *) mask;
10550
10551 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10552   foreach_tcp_proto_field;
10553 #undef _
10554
10555   *maskp = mask;
10556   return 1;
10557 }
10558
10559 uword
10560 unformat_udp_mask (unformat_input_t * input, va_list * args)
10561 {
10562   u8 **maskp = va_arg (*args, u8 **);
10563   u8 *mask = 0;
10564   u8 found_something = 0;
10565   udp_header_t *udp;
10566
10567 #define _(a) u8 a=0;
10568   foreach_udp_proto_field;
10569 #undef _
10570
10571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10572     {
10573       if (0);
10574 #define _(a) else if (unformat (input, #a)) a=1;
10575       foreach_udp_proto_field
10576 #undef _
10577         else
10578         break;
10579     }
10580
10581 #define _(a) found_something += a;
10582   foreach_udp_proto_field;
10583 #undef _
10584
10585   if (found_something == 0)
10586     return 0;
10587
10588   vec_validate (mask, sizeof (*udp) - 1);
10589
10590   udp = (udp_header_t *) mask;
10591
10592 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10593   foreach_udp_proto_field;
10594 #undef _
10595
10596   *maskp = mask;
10597   return 1;
10598 }
10599
10600 uword
10601 unformat_l4_mask (unformat_input_t * input, va_list * args)
10602 {
10603   u8 **maskp = va_arg (*args, u8 **);
10604   u16 src_port = 0, dst_port = 0;
10605   tcpudp_header_t *tcpudp;
10606
10607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10608     {
10609       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10610         return 1;
10611       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10612         return 1;
10613       else if (unformat (input, "src_port"))
10614         src_port = 0xFFFF;
10615       else if (unformat (input, "dst_port"))
10616         dst_port = 0xFFFF;
10617       else
10618         return 0;
10619     }
10620
10621   if (!src_port && !dst_port)
10622     return 0;
10623
10624   u8 *mask = 0;
10625   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10626
10627   tcpudp = (tcpudp_header_t *) mask;
10628   tcpudp->src_port = src_port;
10629   tcpudp->dst_port = dst_port;
10630
10631   *maskp = mask;
10632
10633   return 1;
10634 }
10635
10636 uword
10637 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10638 {
10639   u8 **maskp = va_arg (*args, u8 **);
10640   u8 *mask = 0;
10641   u8 found_something = 0;
10642   ip4_header_t *ip;
10643
10644 #define _(a) u8 a=0;
10645   foreach_ip4_proto_field;
10646 #undef _
10647   u8 version = 0;
10648   u8 hdr_length = 0;
10649
10650
10651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10652     {
10653       if (unformat (input, "version"))
10654         version = 1;
10655       else if (unformat (input, "hdr_length"))
10656         hdr_length = 1;
10657       else if (unformat (input, "src"))
10658         src_address = 1;
10659       else if (unformat (input, "dst"))
10660         dst_address = 1;
10661       else if (unformat (input, "proto"))
10662         protocol = 1;
10663
10664 #define _(a) else if (unformat (input, #a)) a=1;
10665       foreach_ip4_proto_field
10666 #undef _
10667         else
10668         break;
10669     }
10670
10671 #define _(a) found_something += a;
10672   foreach_ip4_proto_field;
10673 #undef _
10674
10675   if (found_something == 0)
10676     return 0;
10677
10678   vec_validate (mask, sizeof (*ip) - 1);
10679
10680   ip = (ip4_header_t *) mask;
10681
10682 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10683   foreach_ip4_proto_field;
10684 #undef _
10685
10686   ip->ip_version_and_header_length = 0;
10687
10688   if (version)
10689     ip->ip_version_and_header_length |= 0xF0;
10690
10691   if (hdr_length)
10692     ip->ip_version_and_header_length |= 0x0F;
10693
10694   *maskp = mask;
10695   return 1;
10696 }
10697
10698 #define foreach_ip6_proto_field                 \
10699 _(src_address)                                  \
10700 _(dst_address)                                  \
10701 _(payload_length)                               \
10702 _(hop_limit)                                    \
10703 _(protocol)
10704
10705 uword
10706 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10707 {
10708   u8 **maskp = va_arg (*args, u8 **);
10709   u8 *mask = 0;
10710   u8 found_something = 0;
10711   ip6_header_t *ip;
10712   u32 ip_version_traffic_class_and_flow_label;
10713
10714 #define _(a) u8 a=0;
10715   foreach_ip6_proto_field;
10716 #undef _
10717   u8 version = 0;
10718   u8 traffic_class = 0;
10719   u8 flow_label = 0;
10720
10721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10722     {
10723       if (unformat (input, "version"))
10724         version = 1;
10725       else if (unformat (input, "traffic-class"))
10726         traffic_class = 1;
10727       else if (unformat (input, "flow-label"))
10728         flow_label = 1;
10729       else if (unformat (input, "src"))
10730         src_address = 1;
10731       else if (unformat (input, "dst"))
10732         dst_address = 1;
10733       else if (unformat (input, "proto"))
10734         protocol = 1;
10735
10736 #define _(a) else if (unformat (input, #a)) a=1;
10737       foreach_ip6_proto_field
10738 #undef _
10739         else
10740         break;
10741     }
10742
10743 #define _(a) found_something += a;
10744   foreach_ip6_proto_field;
10745 #undef _
10746
10747   if (found_something == 0)
10748     return 0;
10749
10750   vec_validate (mask, sizeof (*ip) - 1);
10751
10752   ip = (ip6_header_t *) mask;
10753
10754 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10755   foreach_ip6_proto_field;
10756 #undef _
10757
10758   ip_version_traffic_class_and_flow_label = 0;
10759
10760   if (version)
10761     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10762
10763   if (traffic_class)
10764     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10765
10766   if (flow_label)
10767     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10768
10769   ip->ip_version_traffic_class_and_flow_label =
10770     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10771
10772   *maskp = mask;
10773   return 1;
10774 }
10775
10776 uword
10777 unformat_l3_mask (unformat_input_t * input, va_list * args)
10778 {
10779   u8 **maskp = va_arg (*args, u8 **);
10780
10781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10782     {
10783       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10784         return 1;
10785       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10786         return 1;
10787       else
10788         break;
10789     }
10790   return 0;
10791 }
10792
10793 uword
10794 unformat_l2_mask (unformat_input_t * input, va_list * args)
10795 {
10796   u8 **maskp = va_arg (*args, u8 **);
10797   u8 *mask = 0;
10798   u8 src = 0;
10799   u8 dst = 0;
10800   u8 proto = 0;
10801   u8 tag1 = 0;
10802   u8 tag2 = 0;
10803   u8 ignore_tag1 = 0;
10804   u8 ignore_tag2 = 0;
10805   u8 cos1 = 0;
10806   u8 cos2 = 0;
10807   u8 dot1q = 0;
10808   u8 dot1ad = 0;
10809   int len = 14;
10810
10811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10812     {
10813       if (unformat (input, "src"))
10814         src = 1;
10815       else if (unformat (input, "dst"))
10816         dst = 1;
10817       else if (unformat (input, "proto"))
10818         proto = 1;
10819       else if (unformat (input, "tag1"))
10820         tag1 = 1;
10821       else if (unformat (input, "tag2"))
10822         tag2 = 1;
10823       else if (unformat (input, "ignore-tag1"))
10824         ignore_tag1 = 1;
10825       else if (unformat (input, "ignore-tag2"))
10826         ignore_tag2 = 1;
10827       else if (unformat (input, "cos1"))
10828         cos1 = 1;
10829       else if (unformat (input, "cos2"))
10830         cos2 = 1;
10831       else if (unformat (input, "dot1q"))
10832         dot1q = 1;
10833       else if (unformat (input, "dot1ad"))
10834         dot1ad = 1;
10835       else
10836         break;
10837     }
10838   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10839        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10840     return 0;
10841
10842   if (tag1 || ignore_tag1 || cos1 || dot1q)
10843     len = 18;
10844   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10845     len = 22;
10846
10847   vec_validate (mask, len - 1);
10848
10849   if (dst)
10850     memset (mask, 0xff, 6);
10851
10852   if (src)
10853     memset (mask + 6, 0xff, 6);
10854
10855   if (tag2 || dot1ad)
10856     {
10857       /* inner vlan tag */
10858       if (tag2)
10859         {
10860           mask[19] = 0xff;
10861           mask[18] = 0x0f;
10862         }
10863       if (cos2)
10864         mask[18] |= 0xe0;
10865       if (proto)
10866         mask[21] = mask[20] = 0xff;
10867       if (tag1)
10868         {
10869           mask[15] = 0xff;
10870           mask[14] = 0x0f;
10871         }
10872       if (cos1)
10873         mask[14] |= 0xe0;
10874       *maskp = mask;
10875       return 1;
10876     }
10877   if (tag1 | dot1q)
10878     {
10879       if (tag1)
10880         {
10881           mask[15] = 0xff;
10882           mask[14] = 0x0f;
10883         }
10884       if (cos1)
10885         mask[14] |= 0xe0;
10886       if (proto)
10887         mask[16] = mask[17] = 0xff;
10888
10889       *maskp = mask;
10890       return 1;
10891     }
10892   if (cos2)
10893     mask[18] |= 0xe0;
10894   if (cos1)
10895     mask[14] |= 0xe0;
10896   if (proto)
10897     mask[12] = mask[13] = 0xff;
10898
10899   *maskp = mask;
10900   return 1;
10901 }
10902
10903 uword
10904 unformat_classify_mask (unformat_input_t * input, va_list * args)
10905 {
10906   u8 **maskp = va_arg (*args, u8 **);
10907   u32 *skipp = va_arg (*args, u32 *);
10908   u32 *matchp = va_arg (*args, u32 *);
10909   u32 match;
10910   u8 *mask = 0;
10911   u8 *l2 = 0;
10912   u8 *l3 = 0;
10913   u8 *l4 = 0;
10914   int i;
10915
10916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10917     {
10918       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10919         ;
10920       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10921         ;
10922       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10923         ;
10924       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10925         ;
10926       else
10927         break;
10928     }
10929
10930   if (l4 && !l3)
10931     {
10932       vec_free (mask);
10933       vec_free (l2);
10934       vec_free (l4);
10935       return 0;
10936     }
10937
10938   if (mask || l2 || l3 || l4)
10939     {
10940       if (l2 || l3 || l4)
10941         {
10942           /* "With a free Ethernet header in every package" */
10943           if (l2 == 0)
10944             vec_validate (l2, 13);
10945           mask = l2;
10946           if (vec_len (l3))
10947             {
10948               vec_append (mask, l3);
10949               vec_free (l3);
10950             }
10951           if (vec_len (l4))
10952             {
10953               vec_append (mask, l4);
10954               vec_free (l4);
10955             }
10956         }
10957
10958       /* Scan forward looking for the first significant mask octet */
10959       for (i = 0; i < vec_len (mask); i++)
10960         if (mask[i])
10961           break;
10962
10963       /* compute (skip, match) params */
10964       *skipp = i / sizeof (u32x4);
10965       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10966
10967       /* Pad mask to an even multiple of the vector size */
10968       while (vec_len (mask) % sizeof (u32x4))
10969         vec_add1 (mask, 0);
10970
10971       match = vec_len (mask) / sizeof (u32x4);
10972
10973       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10974         {
10975           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10976           if (*tmp || *(tmp + 1))
10977             break;
10978           match--;
10979         }
10980       if (match == 0)
10981         clib_warning ("BUG: match 0");
10982
10983       _vec_len (mask) = match * sizeof (u32x4);
10984
10985       *matchp = match;
10986       *maskp = mask;
10987
10988       return 1;
10989     }
10990
10991   return 0;
10992 }
10993 #endif /* VPP_API_TEST_BUILTIN */
10994
10995 #define foreach_l2_next                         \
10996 _(drop, DROP)                                   \
10997 _(ethernet, ETHERNET_INPUT)                     \
10998 _(ip4, IP4_INPUT)                               \
10999 _(ip6, IP6_INPUT)
11000
11001 uword
11002 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11003 {
11004   u32 *miss_next_indexp = va_arg (*args, u32 *);
11005   u32 next_index = 0;
11006   u32 tmp;
11007
11008 #define _(n,N) \
11009   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11010   foreach_l2_next;
11011 #undef _
11012
11013   if (unformat (input, "%d", &tmp))
11014     {
11015       next_index = tmp;
11016       goto out;
11017     }
11018
11019   return 0;
11020
11021 out:
11022   *miss_next_indexp = next_index;
11023   return 1;
11024 }
11025
11026 #define foreach_ip_next                         \
11027 _(drop, DROP)                                   \
11028 _(local, LOCAL)                                 \
11029 _(rewrite, REWRITE)
11030
11031 uword
11032 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11033 {
11034   u32 *miss_next_indexp = va_arg (*args, u32 *);
11035   u32 next_index = 0;
11036   u32 tmp;
11037
11038 #define _(n,N) \
11039   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11040   foreach_ip_next;
11041 #undef _
11042
11043   if (unformat (input, "%d", &tmp))
11044     {
11045       next_index = tmp;
11046       goto out;
11047     }
11048
11049   return 0;
11050
11051 out:
11052   *miss_next_indexp = next_index;
11053   return 1;
11054 }
11055
11056 #define foreach_acl_next                        \
11057 _(deny, DENY)
11058
11059 uword
11060 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11061 {
11062   u32 *miss_next_indexp = va_arg (*args, u32 *);
11063   u32 next_index = 0;
11064   u32 tmp;
11065
11066 #define _(n,N) \
11067   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11068   foreach_acl_next;
11069 #undef _
11070
11071   if (unformat (input, "permit"))
11072     {
11073       next_index = ~0;
11074       goto out;
11075     }
11076   else if (unformat (input, "%d", &tmp))
11077     {
11078       next_index = tmp;
11079       goto out;
11080     }
11081
11082   return 0;
11083
11084 out:
11085   *miss_next_indexp = next_index;
11086   return 1;
11087 }
11088
11089 uword
11090 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11091 {
11092   u32 *r = va_arg (*args, u32 *);
11093
11094   if (unformat (input, "conform-color"))
11095     *r = POLICE_CONFORM;
11096   else if (unformat (input, "exceed-color"))
11097     *r = POLICE_EXCEED;
11098   else
11099     return 0;
11100
11101   return 1;
11102 }
11103
11104 static int
11105 api_classify_add_del_table (vat_main_t * vam)
11106 {
11107   unformat_input_t *i = vam->input;
11108   vl_api_classify_add_del_table_t *mp;
11109
11110   u32 nbuckets = 2;
11111   u32 skip = ~0;
11112   u32 match = ~0;
11113   int is_add = 1;
11114   int del_chain = 0;
11115   u32 table_index = ~0;
11116   u32 next_table_index = ~0;
11117   u32 miss_next_index = ~0;
11118   u32 memory_size = 32 << 20;
11119   u8 *mask = 0;
11120   u32 current_data_flag = 0;
11121   int current_data_offset = 0;
11122   int ret;
11123
11124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11125     {
11126       if (unformat (i, "del"))
11127         is_add = 0;
11128       else if (unformat (i, "del-chain"))
11129         {
11130           is_add = 0;
11131           del_chain = 1;
11132         }
11133       else if (unformat (i, "buckets %d", &nbuckets))
11134         ;
11135       else if (unformat (i, "memory_size %d", &memory_size))
11136         ;
11137       else if (unformat (i, "skip %d", &skip))
11138         ;
11139       else if (unformat (i, "match %d", &match))
11140         ;
11141       else if (unformat (i, "table %d", &table_index))
11142         ;
11143       else if (unformat (i, "mask %U", unformat_classify_mask,
11144                          &mask, &skip, &match))
11145         ;
11146       else if (unformat (i, "next-table %d", &next_table_index))
11147         ;
11148       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11149                          &miss_next_index))
11150         ;
11151       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11152                          &miss_next_index))
11153         ;
11154       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11155                          &miss_next_index))
11156         ;
11157       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11158         ;
11159       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11160         ;
11161       else
11162         break;
11163     }
11164
11165   if (is_add && mask == 0)
11166     {
11167       errmsg ("Mask required");
11168       return -99;
11169     }
11170
11171   if (is_add && skip == ~0)
11172     {
11173       errmsg ("skip count required");
11174       return -99;
11175     }
11176
11177   if (is_add && match == ~0)
11178     {
11179       errmsg ("match count required");
11180       return -99;
11181     }
11182
11183   if (!is_add && table_index == ~0)
11184     {
11185       errmsg ("table index required for delete");
11186       return -99;
11187     }
11188
11189   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11190
11191   mp->is_add = is_add;
11192   mp->del_chain = del_chain;
11193   mp->table_index = ntohl (table_index);
11194   mp->nbuckets = ntohl (nbuckets);
11195   mp->memory_size = ntohl (memory_size);
11196   mp->skip_n_vectors = ntohl (skip);
11197   mp->match_n_vectors = ntohl (match);
11198   mp->next_table_index = ntohl (next_table_index);
11199   mp->miss_next_index = ntohl (miss_next_index);
11200   mp->current_data_flag = ntohl (current_data_flag);
11201   mp->current_data_offset = ntohl (current_data_offset);
11202   clib_memcpy (mp->mask, mask, vec_len (mask));
11203
11204   vec_free (mask);
11205
11206   S (mp);
11207   W (ret);
11208   return ret;
11209 }
11210
11211 #if VPP_API_TEST_BUILTIN == 0
11212 uword
11213 unformat_l4_match (unformat_input_t * input, va_list * args)
11214 {
11215   u8 **matchp = va_arg (*args, u8 **);
11216
11217   u8 *proto_header = 0;
11218   int src_port = 0;
11219   int dst_port = 0;
11220
11221   tcpudp_header_t h;
11222
11223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11224     {
11225       if (unformat (input, "src_port %d", &src_port))
11226         ;
11227       else if (unformat (input, "dst_port %d", &dst_port))
11228         ;
11229       else
11230         return 0;
11231     }
11232
11233   h.src_port = clib_host_to_net_u16 (src_port);
11234   h.dst_port = clib_host_to_net_u16 (dst_port);
11235   vec_validate (proto_header, sizeof (h) - 1);
11236   memcpy (proto_header, &h, sizeof (h));
11237
11238   *matchp = proto_header;
11239
11240   return 1;
11241 }
11242
11243 uword
11244 unformat_ip4_match (unformat_input_t * input, va_list * args)
11245 {
11246   u8 **matchp = va_arg (*args, u8 **);
11247   u8 *match = 0;
11248   ip4_header_t *ip;
11249   int version = 0;
11250   u32 version_val;
11251   int hdr_length = 0;
11252   u32 hdr_length_val;
11253   int src = 0, dst = 0;
11254   ip4_address_t src_val, dst_val;
11255   int proto = 0;
11256   u32 proto_val;
11257   int tos = 0;
11258   u32 tos_val;
11259   int length = 0;
11260   u32 length_val;
11261   int fragment_id = 0;
11262   u32 fragment_id_val;
11263   int ttl = 0;
11264   int ttl_val;
11265   int checksum = 0;
11266   u32 checksum_val;
11267
11268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11269     {
11270       if (unformat (input, "version %d", &version_val))
11271         version = 1;
11272       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11273         hdr_length = 1;
11274       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11275         src = 1;
11276       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11277         dst = 1;
11278       else if (unformat (input, "proto %d", &proto_val))
11279         proto = 1;
11280       else if (unformat (input, "tos %d", &tos_val))
11281         tos = 1;
11282       else if (unformat (input, "length %d", &length_val))
11283         length = 1;
11284       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11285         fragment_id = 1;
11286       else if (unformat (input, "ttl %d", &ttl_val))
11287         ttl = 1;
11288       else if (unformat (input, "checksum %d", &checksum_val))
11289         checksum = 1;
11290       else
11291         break;
11292     }
11293
11294   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11295       + ttl + checksum == 0)
11296     return 0;
11297
11298   /*
11299    * Aligned because we use the real comparison functions
11300    */
11301   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11302
11303   ip = (ip4_header_t *) match;
11304
11305   /* These are realistically matched in practice */
11306   if (src)
11307     ip->src_address.as_u32 = src_val.as_u32;
11308
11309   if (dst)
11310     ip->dst_address.as_u32 = dst_val.as_u32;
11311
11312   if (proto)
11313     ip->protocol = proto_val;
11314
11315
11316   /* These are not, but they're included for completeness */
11317   if (version)
11318     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11319
11320   if (hdr_length)
11321     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11322
11323   if (tos)
11324     ip->tos = tos_val;
11325
11326   if (length)
11327     ip->length = clib_host_to_net_u16 (length_val);
11328
11329   if (ttl)
11330     ip->ttl = ttl_val;
11331
11332   if (checksum)
11333     ip->checksum = clib_host_to_net_u16 (checksum_val);
11334
11335   *matchp = match;
11336   return 1;
11337 }
11338
11339 uword
11340 unformat_ip6_match (unformat_input_t * input, va_list * args)
11341 {
11342   u8 **matchp = va_arg (*args, u8 **);
11343   u8 *match = 0;
11344   ip6_header_t *ip;
11345   int version = 0;
11346   u32 version_val;
11347   u8 traffic_class = 0;
11348   u32 traffic_class_val = 0;
11349   u8 flow_label = 0;
11350   u8 flow_label_val;
11351   int src = 0, dst = 0;
11352   ip6_address_t src_val, dst_val;
11353   int proto = 0;
11354   u32 proto_val;
11355   int payload_length = 0;
11356   u32 payload_length_val;
11357   int hop_limit = 0;
11358   int hop_limit_val;
11359   u32 ip_version_traffic_class_and_flow_label;
11360
11361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11362     {
11363       if (unformat (input, "version %d", &version_val))
11364         version = 1;
11365       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11366         traffic_class = 1;
11367       else if (unformat (input, "flow_label %d", &flow_label_val))
11368         flow_label = 1;
11369       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11370         src = 1;
11371       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11372         dst = 1;
11373       else if (unformat (input, "proto %d", &proto_val))
11374         proto = 1;
11375       else if (unformat (input, "payload_length %d", &payload_length_val))
11376         payload_length = 1;
11377       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11378         hop_limit = 1;
11379       else
11380         break;
11381     }
11382
11383   if (version + traffic_class + flow_label + src + dst + proto +
11384       payload_length + hop_limit == 0)
11385     return 0;
11386
11387   /*
11388    * Aligned because we use the real comparison functions
11389    */
11390   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11391
11392   ip = (ip6_header_t *) match;
11393
11394   if (src)
11395     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11396
11397   if (dst)
11398     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11399
11400   if (proto)
11401     ip->protocol = proto_val;
11402
11403   ip_version_traffic_class_and_flow_label = 0;
11404
11405   if (version)
11406     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11407
11408   if (traffic_class)
11409     ip_version_traffic_class_and_flow_label |=
11410       (traffic_class_val & 0xFF) << 20;
11411
11412   if (flow_label)
11413     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11414
11415   ip->ip_version_traffic_class_and_flow_label =
11416     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11417
11418   if (payload_length)
11419     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11420
11421   if (hop_limit)
11422     ip->hop_limit = hop_limit_val;
11423
11424   *matchp = match;
11425   return 1;
11426 }
11427
11428 uword
11429 unformat_l3_match (unformat_input_t * input, va_list * args)
11430 {
11431   u8 **matchp = va_arg (*args, u8 **);
11432
11433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11434     {
11435       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11436         return 1;
11437       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11438         return 1;
11439       else
11440         break;
11441     }
11442   return 0;
11443 }
11444
11445 uword
11446 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11447 {
11448   u8 *tagp = va_arg (*args, u8 *);
11449   u32 tag;
11450
11451   if (unformat (input, "%d", &tag))
11452     {
11453       tagp[0] = (tag >> 8) & 0x0F;
11454       tagp[1] = tag & 0xFF;
11455       return 1;
11456     }
11457
11458   return 0;
11459 }
11460
11461 uword
11462 unformat_l2_match (unformat_input_t * input, va_list * args)
11463 {
11464   u8 **matchp = va_arg (*args, u8 **);
11465   u8 *match = 0;
11466   u8 src = 0;
11467   u8 src_val[6];
11468   u8 dst = 0;
11469   u8 dst_val[6];
11470   u8 proto = 0;
11471   u16 proto_val;
11472   u8 tag1 = 0;
11473   u8 tag1_val[2];
11474   u8 tag2 = 0;
11475   u8 tag2_val[2];
11476   int len = 14;
11477   u8 ignore_tag1 = 0;
11478   u8 ignore_tag2 = 0;
11479   u8 cos1 = 0;
11480   u8 cos2 = 0;
11481   u32 cos1_val = 0;
11482   u32 cos2_val = 0;
11483
11484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11485     {
11486       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11487         src = 1;
11488       else
11489         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11490         dst = 1;
11491       else if (unformat (input, "proto %U",
11492                          unformat_ethernet_type_host_byte_order, &proto_val))
11493         proto = 1;
11494       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11495         tag1 = 1;
11496       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11497         tag2 = 1;
11498       else if (unformat (input, "ignore-tag1"))
11499         ignore_tag1 = 1;
11500       else if (unformat (input, "ignore-tag2"))
11501         ignore_tag2 = 1;
11502       else if (unformat (input, "cos1 %d", &cos1_val))
11503         cos1 = 1;
11504       else if (unformat (input, "cos2 %d", &cos2_val))
11505         cos2 = 1;
11506       else
11507         break;
11508     }
11509   if ((src + dst + proto + tag1 + tag2 +
11510        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11511     return 0;
11512
11513   if (tag1 || ignore_tag1 || cos1)
11514     len = 18;
11515   if (tag2 || ignore_tag2 || cos2)
11516     len = 22;
11517
11518   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11519
11520   if (dst)
11521     clib_memcpy (match, dst_val, 6);
11522
11523   if (src)
11524     clib_memcpy (match + 6, src_val, 6);
11525
11526   if (tag2)
11527     {
11528       /* inner vlan tag */
11529       match[19] = tag2_val[1];
11530       match[18] = tag2_val[0];
11531       if (cos2)
11532         match[18] |= (cos2_val & 0x7) << 5;
11533       if (proto)
11534         {
11535           match[21] = proto_val & 0xff;
11536           match[20] = proto_val >> 8;
11537         }
11538       if (tag1)
11539         {
11540           match[15] = tag1_val[1];
11541           match[14] = tag1_val[0];
11542         }
11543       if (cos1)
11544         match[14] |= (cos1_val & 0x7) << 5;
11545       *matchp = match;
11546       return 1;
11547     }
11548   if (tag1)
11549     {
11550       match[15] = tag1_val[1];
11551       match[14] = tag1_val[0];
11552       if (proto)
11553         {
11554           match[17] = proto_val & 0xff;
11555           match[16] = proto_val >> 8;
11556         }
11557       if (cos1)
11558         match[14] |= (cos1_val & 0x7) << 5;
11559
11560       *matchp = match;
11561       return 1;
11562     }
11563   if (cos2)
11564     match[18] |= (cos2_val & 0x7) << 5;
11565   if (cos1)
11566     match[14] |= (cos1_val & 0x7) << 5;
11567   if (proto)
11568     {
11569       match[13] = proto_val & 0xff;
11570       match[12] = proto_val >> 8;
11571     }
11572
11573   *matchp = match;
11574   return 1;
11575 }
11576 #endif
11577
11578 uword
11579 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11580 {
11581   u8 **matchp = va_arg (*args, u8 **);
11582   u32 skip_n_vectors = va_arg (*args, u32);
11583   u32 match_n_vectors = va_arg (*args, u32);
11584
11585   u8 *match = 0;
11586   u8 *l2 = 0;
11587   u8 *l3 = 0;
11588   u8 *l4 = 0;
11589
11590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11591     {
11592       if (unformat (input, "hex %U", unformat_hex_string, &match))
11593         ;
11594       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11595         ;
11596       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11597         ;
11598       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11599         ;
11600       else
11601         break;
11602     }
11603
11604   if (l4 && !l3)
11605     {
11606       vec_free (match);
11607       vec_free (l2);
11608       vec_free (l4);
11609       return 0;
11610     }
11611
11612   if (match || l2 || l3 || l4)
11613     {
11614       if (l2 || l3 || l4)
11615         {
11616           /* "Win a free Ethernet header in every packet" */
11617           if (l2 == 0)
11618             vec_validate_aligned (l2, 13, sizeof (u32x4));
11619           match = l2;
11620           if (vec_len (l3))
11621             {
11622               vec_append_aligned (match, l3, sizeof (u32x4));
11623               vec_free (l3);
11624             }
11625           if (vec_len (l4))
11626             {
11627               vec_append_aligned (match, l4, sizeof (u32x4));
11628               vec_free (l4);
11629             }
11630         }
11631
11632       /* Make sure the vector is big enough even if key is all 0's */
11633       vec_validate_aligned
11634         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11635          sizeof (u32x4));
11636
11637       /* Set size, include skipped vectors */
11638       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11639
11640       *matchp = match;
11641
11642       return 1;
11643     }
11644
11645   return 0;
11646 }
11647
11648 static int
11649 api_classify_add_del_session (vat_main_t * vam)
11650 {
11651   unformat_input_t *i = vam->input;
11652   vl_api_classify_add_del_session_t *mp;
11653   int is_add = 1;
11654   u32 table_index = ~0;
11655   u32 hit_next_index = ~0;
11656   u32 opaque_index = ~0;
11657   u8 *match = 0;
11658   i32 advance = 0;
11659   u32 skip_n_vectors = 0;
11660   u32 match_n_vectors = 0;
11661   u32 action = 0;
11662   u32 metadata = 0;
11663   int ret;
11664
11665   /*
11666    * Warning: you have to supply skip_n and match_n
11667    * because the API client cant simply look at the classify
11668    * table object.
11669    */
11670
11671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11672     {
11673       if (unformat (i, "del"))
11674         is_add = 0;
11675       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11676                          &hit_next_index))
11677         ;
11678       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11679                          &hit_next_index))
11680         ;
11681       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11682                          &hit_next_index))
11683         ;
11684       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11685         ;
11686       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11687         ;
11688       else if (unformat (i, "opaque-index %d", &opaque_index))
11689         ;
11690       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11691         ;
11692       else if (unformat (i, "match_n %d", &match_n_vectors))
11693         ;
11694       else if (unformat (i, "match %U", api_unformat_classify_match,
11695                          &match, skip_n_vectors, match_n_vectors))
11696         ;
11697       else if (unformat (i, "advance %d", &advance))
11698         ;
11699       else if (unformat (i, "table-index %d", &table_index))
11700         ;
11701       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11702         action = 1;
11703       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11704         action = 2;
11705       else if (unformat (i, "action %d", &action))
11706         ;
11707       else if (unformat (i, "metadata %d", &metadata))
11708         ;
11709       else
11710         break;
11711     }
11712
11713   if (table_index == ~0)
11714     {
11715       errmsg ("Table index required");
11716       return -99;
11717     }
11718
11719   if (is_add && match == 0)
11720     {
11721       errmsg ("Match value required");
11722       return -99;
11723     }
11724
11725   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11726
11727   mp->is_add = is_add;
11728   mp->table_index = ntohl (table_index);
11729   mp->hit_next_index = ntohl (hit_next_index);
11730   mp->opaque_index = ntohl (opaque_index);
11731   mp->advance = ntohl (advance);
11732   mp->action = action;
11733   mp->metadata = ntohl (metadata);
11734   clib_memcpy (mp->match, match, vec_len (match));
11735   vec_free (match);
11736
11737   S (mp);
11738   W (ret);
11739   return ret;
11740 }
11741
11742 static int
11743 api_classify_set_interface_ip_table (vat_main_t * vam)
11744 {
11745   unformat_input_t *i = vam->input;
11746   vl_api_classify_set_interface_ip_table_t *mp;
11747   u32 sw_if_index;
11748   int sw_if_index_set;
11749   u32 table_index = ~0;
11750   u8 is_ipv6 = 0;
11751   int ret;
11752
11753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11754     {
11755       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11756         sw_if_index_set = 1;
11757       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11758         sw_if_index_set = 1;
11759       else if (unformat (i, "table %d", &table_index))
11760         ;
11761       else
11762         {
11763           clib_warning ("parse error '%U'", format_unformat_error, i);
11764           return -99;
11765         }
11766     }
11767
11768   if (sw_if_index_set == 0)
11769     {
11770       errmsg ("missing interface name or sw_if_index");
11771       return -99;
11772     }
11773
11774
11775   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11776
11777   mp->sw_if_index = ntohl (sw_if_index);
11778   mp->table_index = ntohl (table_index);
11779   mp->is_ipv6 = is_ipv6;
11780
11781   S (mp);
11782   W (ret);
11783   return ret;
11784 }
11785
11786 static int
11787 api_classify_set_interface_l2_tables (vat_main_t * vam)
11788 {
11789   unformat_input_t *i = vam->input;
11790   vl_api_classify_set_interface_l2_tables_t *mp;
11791   u32 sw_if_index;
11792   int sw_if_index_set;
11793   u32 ip4_table_index = ~0;
11794   u32 ip6_table_index = ~0;
11795   u32 other_table_index = ~0;
11796   u32 is_input = 1;
11797   int ret;
11798
11799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11800     {
11801       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11802         sw_if_index_set = 1;
11803       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11804         sw_if_index_set = 1;
11805       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11806         ;
11807       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11808         ;
11809       else if (unformat (i, "other-table %d", &other_table_index))
11810         ;
11811       else if (unformat (i, "is-input %d", &is_input))
11812         ;
11813       else
11814         {
11815           clib_warning ("parse error '%U'", format_unformat_error, i);
11816           return -99;
11817         }
11818     }
11819
11820   if (sw_if_index_set == 0)
11821     {
11822       errmsg ("missing interface name or sw_if_index");
11823       return -99;
11824     }
11825
11826
11827   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11828
11829   mp->sw_if_index = ntohl (sw_if_index);
11830   mp->ip4_table_index = ntohl (ip4_table_index);
11831   mp->ip6_table_index = ntohl (ip6_table_index);
11832   mp->other_table_index = ntohl (other_table_index);
11833   mp->is_input = (u8) is_input;
11834
11835   S (mp);
11836   W (ret);
11837   return ret;
11838 }
11839
11840 static int
11841 api_set_ipfix_exporter (vat_main_t * vam)
11842 {
11843   unformat_input_t *i = vam->input;
11844   vl_api_set_ipfix_exporter_t *mp;
11845   ip4_address_t collector_address;
11846   u8 collector_address_set = 0;
11847   u32 collector_port = ~0;
11848   ip4_address_t src_address;
11849   u8 src_address_set = 0;
11850   u32 vrf_id = ~0;
11851   u32 path_mtu = ~0;
11852   u32 template_interval = ~0;
11853   u8 udp_checksum = 0;
11854   int ret;
11855
11856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11857     {
11858       if (unformat (i, "collector_address %U", unformat_ip4_address,
11859                     &collector_address))
11860         collector_address_set = 1;
11861       else if (unformat (i, "collector_port %d", &collector_port))
11862         ;
11863       else if (unformat (i, "src_address %U", unformat_ip4_address,
11864                          &src_address))
11865         src_address_set = 1;
11866       else if (unformat (i, "vrf_id %d", &vrf_id))
11867         ;
11868       else if (unformat (i, "path_mtu %d", &path_mtu))
11869         ;
11870       else if (unformat (i, "template_interval %d", &template_interval))
11871         ;
11872       else if (unformat (i, "udp_checksum"))
11873         udp_checksum = 1;
11874       else
11875         break;
11876     }
11877
11878   if (collector_address_set == 0)
11879     {
11880       errmsg ("collector_address required");
11881       return -99;
11882     }
11883
11884   if (src_address_set == 0)
11885     {
11886       errmsg ("src_address required");
11887       return -99;
11888     }
11889
11890   M (SET_IPFIX_EXPORTER, mp);
11891
11892   memcpy (mp->collector_address, collector_address.data,
11893           sizeof (collector_address.data));
11894   mp->collector_port = htons ((u16) collector_port);
11895   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11896   mp->vrf_id = htonl (vrf_id);
11897   mp->path_mtu = htonl (path_mtu);
11898   mp->template_interval = htonl (template_interval);
11899   mp->udp_checksum = udp_checksum;
11900
11901   S (mp);
11902   W (ret);
11903   return ret;
11904 }
11905
11906 static int
11907 api_set_ipfix_classify_stream (vat_main_t * vam)
11908 {
11909   unformat_input_t *i = vam->input;
11910   vl_api_set_ipfix_classify_stream_t *mp;
11911   u32 domain_id = 0;
11912   u32 src_port = UDP_DST_PORT_ipfix;
11913   int ret;
11914
11915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11916     {
11917       if (unformat (i, "domain %d", &domain_id))
11918         ;
11919       else if (unformat (i, "src_port %d", &src_port))
11920         ;
11921       else
11922         {
11923           errmsg ("unknown input `%U'", format_unformat_error, i);
11924           return -99;
11925         }
11926     }
11927
11928   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11929
11930   mp->domain_id = htonl (domain_id);
11931   mp->src_port = htons ((u16) src_port);
11932
11933   S (mp);
11934   W (ret);
11935   return ret;
11936 }
11937
11938 static int
11939 api_ipfix_classify_table_add_del (vat_main_t * vam)
11940 {
11941   unformat_input_t *i = vam->input;
11942   vl_api_ipfix_classify_table_add_del_t *mp;
11943   int is_add = -1;
11944   u32 classify_table_index = ~0;
11945   u8 ip_version = 0;
11946   u8 transport_protocol = 255;
11947   int ret;
11948
11949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11950     {
11951       if (unformat (i, "add"))
11952         is_add = 1;
11953       else if (unformat (i, "del"))
11954         is_add = 0;
11955       else if (unformat (i, "table %d", &classify_table_index))
11956         ;
11957       else if (unformat (i, "ip4"))
11958         ip_version = 4;
11959       else if (unformat (i, "ip6"))
11960         ip_version = 6;
11961       else if (unformat (i, "tcp"))
11962         transport_protocol = 6;
11963       else if (unformat (i, "udp"))
11964         transport_protocol = 17;
11965       else
11966         {
11967           errmsg ("unknown input `%U'", format_unformat_error, i);
11968           return -99;
11969         }
11970     }
11971
11972   if (is_add == -1)
11973     {
11974       errmsg ("expecting: add|del");
11975       return -99;
11976     }
11977   if (classify_table_index == ~0)
11978     {
11979       errmsg ("classifier table not specified");
11980       return -99;
11981     }
11982   if (ip_version == 0)
11983     {
11984       errmsg ("IP version not specified");
11985       return -99;
11986     }
11987
11988   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11989
11990   mp->is_add = is_add;
11991   mp->table_id = htonl (classify_table_index);
11992   mp->ip_version = ip_version;
11993   mp->transport_protocol = transport_protocol;
11994
11995   S (mp);
11996   W (ret);
11997   return ret;
11998 }
11999
12000 static int
12001 api_get_node_index (vat_main_t * vam)
12002 {
12003   unformat_input_t *i = vam->input;
12004   vl_api_get_node_index_t *mp;
12005   u8 *name = 0;
12006   int ret;
12007
12008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12009     {
12010       if (unformat (i, "node %s", &name))
12011         ;
12012       else
12013         break;
12014     }
12015   if (name == 0)
12016     {
12017       errmsg ("node name required");
12018       return -99;
12019     }
12020   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12021     {
12022       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12023       return -99;
12024     }
12025
12026   M (GET_NODE_INDEX, mp);
12027   clib_memcpy (mp->node_name, name, vec_len (name));
12028   vec_free (name);
12029
12030   S (mp);
12031   W (ret);
12032   return ret;
12033 }
12034
12035 static int
12036 api_get_next_index (vat_main_t * vam)
12037 {
12038   unformat_input_t *i = vam->input;
12039   vl_api_get_next_index_t *mp;
12040   u8 *node_name = 0, *next_node_name = 0;
12041   int ret;
12042
12043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12044     {
12045       if (unformat (i, "node-name %s", &node_name))
12046         ;
12047       else if (unformat (i, "next-node-name %s", &next_node_name))
12048         break;
12049     }
12050
12051   if (node_name == 0)
12052     {
12053       errmsg ("node name required");
12054       return -99;
12055     }
12056   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12057     {
12058       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12059       return -99;
12060     }
12061
12062   if (next_node_name == 0)
12063     {
12064       errmsg ("next node name required");
12065       return -99;
12066     }
12067   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12068     {
12069       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12070       return -99;
12071     }
12072
12073   M (GET_NEXT_INDEX, mp);
12074   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12075   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12076   vec_free (node_name);
12077   vec_free (next_node_name);
12078
12079   S (mp);
12080   W (ret);
12081   return ret;
12082 }
12083
12084 static int
12085 api_add_node_next (vat_main_t * vam)
12086 {
12087   unformat_input_t *i = vam->input;
12088   vl_api_add_node_next_t *mp;
12089   u8 *name = 0;
12090   u8 *next = 0;
12091   int ret;
12092
12093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12094     {
12095       if (unformat (i, "node %s", &name))
12096         ;
12097       else if (unformat (i, "next %s", &next))
12098         ;
12099       else
12100         break;
12101     }
12102   if (name == 0)
12103     {
12104       errmsg ("node name required");
12105       return -99;
12106     }
12107   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12108     {
12109       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12110       return -99;
12111     }
12112   if (next == 0)
12113     {
12114       errmsg ("next node required");
12115       return -99;
12116     }
12117   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12118     {
12119       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12120       return -99;
12121     }
12122
12123   M (ADD_NODE_NEXT, mp);
12124   clib_memcpy (mp->node_name, name, vec_len (name));
12125   clib_memcpy (mp->next_name, next, vec_len (next));
12126   vec_free (name);
12127   vec_free (next);
12128
12129   S (mp);
12130   W (ret);
12131   return ret;
12132 }
12133
12134 static int
12135 api_l2tpv3_create_tunnel (vat_main_t * vam)
12136 {
12137   unformat_input_t *i = vam->input;
12138   ip6_address_t client_address, our_address;
12139   int client_address_set = 0;
12140   int our_address_set = 0;
12141   u32 local_session_id = 0;
12142   u32 remote_session_id = 0;
12143   u64 local_cookie = 0;
12144   u64 remote_cookie = 0;
12145   u8 l2_sublayer_present = 0;
12146   vl_api_l2tpv3_create_tunnel_t *mp;
12147   int ret;
12148
12149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12150     {
12151       if (unformat (i, "client_address %U", unformat_ip6_address,
12152                     &client_address))
12153         client_address_set = 1;
12154       else if (unformat (i, "our_address %U", unformat_ip6_address,
12155                          &our_address))
12156         our_address_set = 1;
12157       else if (unformat (i, "local_session_id %d", &local_session_id))
12158         ;
12159       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12160         ;
12161       else if (unformat (i, "local_cookie %lld", &local_cookie))
12162         ;
12163       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12164         ;
12165       else if (unformat (i, "l2-sublayer-present"))
12166         l2_sublayer_present = 1;
12167       else
12168         break;
12169     }
12170
12171   if (client_address_set == 0)
12172     {
12173       errmsg ("client_address required");
12174       return -99;
12175     }
12176
12177   if (our_address_set == 0)
12178     {
12179       errmsg ("our_address required");
12180       return -99;
12181     }
12182
12183   M (L2TPV3_CREATE_TUNNEL, mp);
12184
12185   clib_memcpy (mp->client_address, client_address.as_u8,
12186                sizeof (mp->client_address));
12187
12188   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12189
12190   mp->local_session_id = ntohl (local_session_id);
12191   mp->remote_session_id = ntohl (remote_session_id);
12192   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12193   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12194   mp->l2_sublayer_present = l2_sublayer_present;
12195   mp->is_ipv6 = 1;
12196
12197   S (mp);
12198   W (ret);
12199   return ret;
12200 }
12201
12202 static int
12203 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12204 {
12205   unformat_input_t *i = vam->input;
12206   u32 sw_if_index;
12207   u8 sw_if_index_set = 0;
12208   u64 new_local_cookie = 0;
12209   u64 new_remote_cookie = 0;
12210   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12211   int ret;
12212
12213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12214     {
12215       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12216         sw_if_index_set = 1;
12217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12218         sw_if_index_set = 1;
12219       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12220         ;
12221       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12222         ;
12223       else
12224         break;
12225     }
12226
12227   if (sw_if_index_set == 0)
12228     {
12229       errmsg ("missing interface name or sw_if_index");
12230       return -99;
12231     }
12232
12233   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12234
12235   mp->sw_if_index = ntohl (sw_if_index);
12236   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12237   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12238
12239   S (mp);
12240   W (ret);
12241   return ret;
12242 }
12243
12244 static int
12245 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12246 {
12247   unformat_input_t *i = vam->input;
12248   vl_api_l2tpv3_interface_enable_disable_t *mp;
12249   u32 sw_if_index;
12250   u8 sw_if_index_set = 0;
12251   u8 enable_disable = 1;
12252   int ret;
12253
12254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12255     {
12256       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12257         sw_if_index_set = 1;
12258       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12259         sw_if_index_set = 1;
12260       else if (unformat (i, "enable"))
12261         enable_disable = 1;
12262       else if (unformat (i, "disable"))
12263         enable_disable = 0;
12264       else
12265         break;
12266     }
12267
12268   if (sw_if_index_set == 0)
12269     {
12270       errmsg ("missing interface name or sw_if_index");
12271       return -99;
12272     }
12273
12274   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12275
12276   mp->sw_if_index = ntohl (sw_if_index);
12277   mp->enable_disable = enable_disable;
12278
12279   S (mp);
12280   W (ret);
12281   return ret;
12282 }
12283
12284 static int
12285 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12286 {
12287   unformat_input_t *i = vam->input;
12288   vl_api_l2tpv3_set_lookup_key_t *mp;
12289   u8 key = ~0;
12290   int ret;
12291
12292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12293     {
12294       if (unformat (i, "lookup_v6_src"))
12295         key = L2T_LOOKUP_SRC_ADDRESS;
12296       else if (unformat (i, "lookup_v6_dst"))
12297         key = L2T_LOOKUP_DST_ADDRESS;
12298       else if (unformat (i, "lookup_session_id"))
12299         key = L2T_LOOKUP_SESSION_ID;
12300       else
12301         break;
12302     }
12303
12304   if (key == (u8) ~ 0)
12305     {
12306       errmsg ("l2tp session lookup key unset");
12307       return -99;
12308     }
12309
12310   M (L2TPV3_SET_LOOKUP_KEY, mp);
12311
12312   mp->key = key;
12313
12314   S (mp);
12315   W (ret);
12316   return ret;
12317 }
12318
12319 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12320   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12321 {
12322   vat_main_t *vam = &vat_main;
12323
12324   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12325          format_ip6_address, mp->our_address,
12326          format_ip6_address, mp->client_address,
12327          clib_net_to_host_u32 (mp->sw_if_index));
12328
12329   print (vam->ofp,
12330          "   local cookies %016llx %016llx remote cookie %016llx",
12331          clib_net_to_host_u64 (mp->local_cookie[0]),
12332          clib_net_to_host_u64 (mp->local_cookie[1]),
12333          clib_net_to_host_u64 (mp->remote_cookie));
12334
12335   print (vam->ofp, "   local session-id %d remote session-id %d",
12336          clib_net_to_host_u32 (mp->local_session_id),
12337          clib_net_to_host_u32 (mp->remote_session_id));
12338
12339   print (vam->ofp, "   l2 specific sublayer %s\n",
12340          mp->l2_sublayer_present ? "preset" : "absent");
12341
12342 }
12343
12344 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12345   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12346 {
12347   vat_main_t *vam = &vat_main;
12348   vat_json_node_t *node = NULL;
12349   struct in6_addr addr;
12350
12351   if (VAT_JSON_ARRAY != vam->json_tree.type)
12352     {
12353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12354       vat_json_init_array (&vam->json_tree);
12355     }
12356   node = vat_json_array_add (&vam->json_tree);
12357
12358   vat_json_init_object (node);
12359
12360   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12361   vat_json_object_add_ip6 (node, "our_address", addr);
12362   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12363   vat_json_object_add_ip6 (node, "client_address", addr);
12364
12365   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12366   vat_json_init_array (lc);
12367   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12368   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12369   vat_json_object_add_uint (node, "remote_cookie",
12370                             clib_net_to_host_u64 (mp->remote_cookie));
12371
12372   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12373   vat_json_object_add_uint (node, "local_session_id",
12374                             clib_net_to_host_u32 (mp->local_session_id));
12375   vat_json_object_add_uint (node, "remote_session_id",
12376                             clib_net_to_host_u32 (mp->remote_session_id));
12377   vat_json_object_add_string_copy (node, "l2_sublayer",
12378                                    mp->l2_sublayer_present ? (u8 *) "present"
12379                                    : (u8 *) "absent");
12380 }
12381
12382 static int
12383 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12384 {
12385   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12386   vl_api_control_ping_t *mp_ping;
12387   int ret;
12388
12389   /* Get list of l2tpv3-tunnel interfaces */
12390   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12391   S (mp);
12392
12393   /* Use a control ping for synchronization */
12394   MPING (CONTROL_PING, mp_ping);
12395   S (mp_ping);
12396
12397   W (ret);
12398   return ret;
12399 }
12400
12401
12402 static void vl_api_sw_interface_tap_details_t_handler
12403   (vl_api_sw_interface_tap_details_t * mp)
12404 {
12405   vat_main_t *vam = &vat_main;
12406
12407   print (vam->ofp, "%-16s %d",
12408          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12409 }
12410
12411 static void vl_api_sw_interface_tap_details_t_handler_json
12412   (vl_api_sw_interface_tap_details_t * mp)
12413 {
12414   vat_main_t *vam = &vat_main;
12415   vat_json_node_t *node = NULL;
12416
12417   if (VAT_JSON_ARRAY != vam->json_tree.type)
12418     {
12419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12420       vat_json_init_array (&vam->json_tree);
12421     }
12422   node = vat_json_array_add (&vam->json_tree);
12423
12424   vat_json_init_object (node);
12425   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12426   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12427 }
12428
12429 static int
12430 api_sw_interface_tap_dump (vat_main_t * vam)
12431 {
12432   vl_api_sw_interface_tap_dump_t *mp;
12433   vl_api_control_ping_t *mp_ping;
12434   int ret;
12435
12436   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12437   /* Get list of tap interfaces */
12438   M (SW_INTERFACE_TAP_DUMP, mp);
12439   S (mp);
12440
12441   /* Use a control ping for synchronization */
12442   MPING (CONTROL_PING, mp_ping);
12443   S (mp_ping);
12444
12445   W (ret);
12446   return ret;
12447 }
12448
12449 static void vl_api_sw_interface_tap_v2_details_t_handler
12450   (vl_api_sw_interface_tap_v2_details_t * mp)
12451 {
12452   vat_main_t *vam = &vat_main;
12453
12454   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12455                     mp->host_ip4_prefix_len);
12456   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12457                     mp->host_ip6_prefix_len);
12458
12459   print (vam->ofp,
12460          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12461          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12462          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12463          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12464          mp->host_bridge, ip4, ip6);
12465
12466   vec_free (ip4);
12467   vec_free (ip6);
12468 }
12469
12470 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12471   (vl_api_sw_interface_tap_v2_details_t * mp)
12472 {
12473   vat_main_t *vam = &vat_main;
12474   vat_json_node_t *node = NULL;
12475
12476   if (VAT_JSON_ARRAY != vam->json_tree.type)
12477     {
12478       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12479       vat_json_init_array (&vam->json_tree);
12480     }
12481   node = vat_json_array_add (&vam->json_tree);
12482
12483   vat_json_init_object (node);
12484   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12485   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12486   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12487   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12488   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12489   vat_json_object_add_string_copy (node, "host_mac_addr",
12490                                    format (0, "%U", format_ethernet_address,
12491                                            &mp->host_mac_addr));
12492   vat_json_object_add_string_copy (node, "host_namespace",
12493                                    mp->host_namespace);
12494   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12495   vat_json_object_add_string_copy (node, "host_ip4_addr",
12496                                    format (0, "%U/%d", format_ip4_address,
12497                                            mp->host_ip4_addr,
12498                                            mp->host_ip4_prefix_len));
12499   vat_json_object_add_string_copy (node, "host_ip6_addr",
12500                                    format (0, "%U/%d", format_ip6_address,
12501                                            mp->host_ip6_addr,
12502                                            mp->host_ip6_prefix_len));
12503
12504 }
12505
12506 static int
12507 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12508 {
12509   vl_api_sw_interface_tap_v2_dump_t *mp;
12510   vl_api_control_ping_t *mp_ping;
12511   int ret;
12512
12513   print (vam->ofp,
12514          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12515          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12516          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12517          "host_ip6_addr");
12518
12519   /* Get list of tap interfaces */
12520   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12521   S (mp);
12522
12523   /* Use a control ping for synchronization */
12524   MPING (CONTROL_PING, mp_ping);
12525   S (mp_ping);
12526
12527   W (ret);
12528   return ret;
12529 }
12530
12531 static uword unformat_vxlan_decap_next
12532   (unformat_input_t * input, va_list * args)
12533 {
12534   u32 *result = va_arg (*args, u32 *);
12535   u32 tmp;
12536
12537   if (unformat (input, "l2"))
12538     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12539   else if (unformat (input, "%d", &tmp))
12540     *result = tmp;
12541   else
12542     return 0;
12543   return 1;
12544 }
12545
12546 static int
12547 api_vxlan_add_del_tunnel (vat_main_t * vam)
12548 {
12549   unformat_input_t *line_input = vam->input;
12550   vl_api_vxlan_add_del_tunnel_t *mp;
12551   ip46_address_t src, dst;
12552   u8 is_add = 1;
12553   u8 ipv4_set = 0, ipv6_set = 0;
12554   u8 src_set = 0;
12555   u8 dst_set = 0;
12556   u8 grp_set = 0;
12557   u32 mcast_sw_if_index = ~0;
12558   u32 encap_vrf_id = 0;
12559   u32 decap_next_index = ~0;
12560   u32 vni = 0;
12561   int ret;
12562
12563   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12564   memset (&src, 0, sizeof src);
12565   memset (&dst, 0, sizeof dst);
12566
12567   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12568     {
12569       if (unformat (line_input, "del"))
12570         is_add = 0;
12571       else
12572         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12573         {
12574           ipv4_set = 1;
12575           src_set = 1;
12576         }
12577       else
12578         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12579         {
12580           ipv4_set = 1;
12581           dst_set = 1;
12582         }
12583       else
12584         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12585         {
12586           ipv6_set = 1;
12587           src_set = 1;
12588         }
12589       else
12590         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12591         {
12592           ipv6_set = 1;
12593           dst_set = 1;
12594         }
12595       else if (unformat (line_input, "group %U %U",
12596                          unformat_ip4_address, &dst.ip4,
12597                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12598         {
12599           grp_set = dst_set = 1;
12600           ipv4_set = 1;
12601         }
12602       else if (unformat (line_input, "group %U",
12603                          unformat_ip4_address, &dst.ip4))
12604         {
12605           grp_set = dst_set = 1;
12606           ipv4_set = 1;
12607         }
12608       else if (unformat (line_input, "group %U %U",
12609                          unformat_ip6_address, &dst.ip6,
12610                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12611         {
12612           grp_set = dst_set = 1;
12613           ipv6_set = 1;
12614         }
12615       else if (unformat (line_input, "group %U",
12616                          unformat_ip6_address, &dst.ip6))
12617         {
12618           grp_set = dst_set = 1;
12619           ipv6_set = 1;
12620         }
12621       else
12622         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12623         ;
12624       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12625         ;
12626       else if (unformat (line_input, "decap-next %U",
12627                          unformat_vxlan_decap_next, &decap_next_index))
12628         ;
12629       else if (unformat (line_input, "vni %d", &vni))
12630         ;
12631       else
12632         {
12633           errmsg ("parse error '%U'", format_unformat_error, line_input);
12634           return -99;
12635         }
12636     }
12637
12638   if (src_set == 0)
12639     {
12640       errmsg ("tunnel src address not specified");
12641       return -99;
12642     }
12643   if (dst_set == 0)
12644     {
12645       errmsg ("tunnel dst address not specified");
12646       return -99;
12647     }
12648
12649   if (grp_set && !ip46_address_is_multicast (&dst))
12650     {
12651       errmsg ("tunnel group address not multicast");
12652       return -99;
12653     }
12654   if (grp_set && mcast_sw_if_index == ~0)
12655     {
12656       errmsg ("tunnel nonexistent multicast device");
12657       return -99;
12658     }
12659   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12660     {
12661       errmsg ("tunnel dst address must be unicast");
12662       return -99;
12663     }
12664
12665
12666   if (ipv4_set && ipv6_set)
12667     {
12668       errmsg ("both IPv4 and IPv6 addresses specified");
12669       return -99;
12670     }
12671
12672   if ((vni == 0) || (vni >> 24))
12673     {
12674       errmsg ("vni not specified or out of range");
12675       return -99;
12676     }
12677
12678   M (VXLAN_ADD_DEL_TUNNEL, mp);
12679
12680   if (ipv6_set)
12681     {
12682       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12683       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12684     }
12685   else
12686     {
12687       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12688       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12689     }
12690   mp->encap_vrf_id = ntohl (encap_vrf_id);
12691   mp->decap_next_index = ntohl (decap_next_index);
12692   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12693   mp->vni = ntohl (vni);
12694   mp->is_add = is_add;
12695   mp->is_ipv6 = ipv6_set;
12696
12697   S (mp);
12698   W (ret);
12699   return ret;
12700 }
12701
12702 static void vl_api_vxlan_tunnel_details_t_handler
12703   (vl_api_vxlan_tunnel_details_t * mp)
12704 {
12705   vat_main_t *vam = &vat_main;
12706   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12707   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12708
12709   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12710          ntohl (mp->sw_if_index),
12711          format_ip46_address, &src, IP46_TYPE_ANY,
12712          format_ip46_address, &dst, IP46_TYPE_ANY,
12713          ntohl (mp->encap_vrf_id),
12714          ntohl (mp->decap_next_index), ntohl (mp->vni),
12715          ntohl (mp->mcast_sw_if_index));
12716 }
12717
12718 static void vl_api_vxlan_tunnel_details_t_handler_json
12719   (vl_api_vxlan_tunnel_details_t * mp)
12720 {
12721   vat_main_t *vam = &vat_main;
12722   vat_json_node_t *node = NULL;
12723
12724   if (VAT_JSON_ARRAY != vam->json_tree.type)
12725     {
12726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12727       vat_json_init_array (&vam->json_tree);
12728     }
12729   node = vat_json_array_add (&vam->json_tree);
12730
12731   vat_json_init_object (node);
12732   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12733   if (mp->is_ipv6)
12734     {
12735       struct in6_addr ip6;
12736
12737       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12738       vat_json_object_add_ip6 (node, "src_address", ip6);
12739       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12740       vat_json_object_add_ip6 (node, "dst_address", ip6);
12741     }
12742   else
12743     {
12744       struct in_addr ip4;
12745
12746       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12747       vat_json_object_add_ip4 (node, "src_address", ip4);
12748       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12749       vat_json_object_add_ip4 (node, "dst_address", ip4);
12750     }
12751   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12752   vat_json_object_add_uint (node, "decap_next_index",
12753                             ntohl (mp->decap_next_index));
12754   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12755   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12756   vat_json_object_add_uint (node, "mcast_sw_if_index",
12757                             ntohl (mp->mcast_sw_if_index));
12758 }
12759
12760 static int
12761 api_vxlan_tunnel_dump (vat_main_t * vam)
12762 {
12763   unformat_input_t *i = vam->input;
12764   vl_api_vxlan_tunnel_dump_t *mp;
12765   vl_api_control_ping_t *mp_ping;
12766   u32 sw_if_index;
12767   u8 sw_if_index_set = 0;
12768   int ret;
12769
12770   /* Parse args required to build the message */
12771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12772     {
12773       if (unformat (i, "sw_if_index %d", &sw_if_index))
12774         sw_if_index_set = 1;
12775       else
12776         break;
12777     }
12778
12779   if (sw_if_index_set == 0)
12780     {
12781       sw_if_index = ~0;
12782     }
12783
12784   if (!vam->json_output)
12785     {
12786       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12787              "sw_if_index", "src_address", "dst_address",
12788              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12789     }
12790
12791   /* Get list of vxlan-tunnel interfaces */
12792   M (VXLAN_TUNNEL_DUMP, mp);
12793
12794   mp->sw_if_index = htonl (sw_if_index);
12795
12796   S (mp);
12797
12798   /* Use a control ping for synchronization */
12799   MPING (CONTROL_PING, mp_ping);
12800   S (mp_ping);
12801
12802   W (ret);
12803   return ret;
12804 }
12805
12806 static uword unformat_geneve_decap_next
12807   (unformat_input_t * input, va_list * args)
12808 {
12809   u32 *result = va_arg (*args, u32 *);
12810   u32 tmp;
12811
12812   if (unformat (input, "l2"))
12813     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12814   else if (unformat (input, "%d", &tmp))
12815     *result = tmp;
12816   else
12817     return 0;
12818   return 1;
12819 }
12820
12821 static int
12822 api_geneve_add_del_tunnel (vat_main_t * vam)
12823 {
12824   unformat_input_t *line_input = vam->input;
12825   vl_api_geneve_add_del_tunnel_t *mp;
12826   ip46_address_t src, dst;
12827   u8 is_add = 1;
12828   u8 ipv4_set = 0, ipv6_set = 0;
12829   u8 src_set = 0;
12830   u8 dst_set = 0;
12831   u8 grp_set = 0;
12832   u32 mcast_sw_if_index = ~0;
12833   u32 encap_vrf_id = 0;
12834   u32 decap_next_index = ~0;
12835   u32 vni = 0;
12836   int ret;
12837
12838   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12839   memset (&src, 0, sizeof src);
12840   memset (&dst, 0, sizeof dst);
12841
12842   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12843     {
12844       if (unformat (line_input, "del"))
12845         is_add = 0;
12846       else
12847         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12848         {
12849           ipv4_set = 1;
12850           src_set = 1;
12851         }
12852       else
12853         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12854         {
12855           ipv4_set = 1;
12856           dst_set = 1;
12857         }
12858       else
12859         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12860         {
12861           ipv6_set = 1;
12862           src_set = 1;
12863         }
12864       else
12865         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12866         {
12867           ipv6_set = 1;
12868           dst_set = 1;
12869         }
12870       else if (unformat (line_input, "group %U %U",
12871                          unformat_ip4_address, &dst.ip4,
12872                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12873         {
12874           grp_set = dst_set = 1;
12875           ipv4_set = 1;
12876         }
12877       else if (unformat (line_input, "group %U",
12878                          unformat_ip4_address, &dst.ip4))
12879         {
12880           grp_set = dst_set = 1;
12881           ipv4_set = 1;
12882         }
12883       else if (unformat (line_input, "group %U %U",
12884                          unformat_ip6_address, &dst.ip6,
12885                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12886         {
12887           grp_set = dst_set = 1;
12888           ipv6_set = 1;
12889         }
12890       else if (unformat (line_input, "group %U",
12891                          unformat_ip6_address, &dst.ip6))
12892         {
12893           grp_set = dst_set = 1;
12894           ipv6_set = 1;
12895         }
12896       else
12897         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12898         ;
12899       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12900         ;
12901       else if (unformat (line_input, "decap-next %U",
12902                          unformat_geneve_decap_next, &decap_next_index))
12903         ;
12904       else if (unformat (line_input, "vni %d", &vni))
12905         ;
12906       else
12907         {
12908           errmsg ("parse error '%U'", format_unformat_error, line_input);
12909           return -99;
12910         }
12911     }
12912
12913   if (src_set == 0)
12914     {
12915       errmsg ("tunnel src address not specified");
12916       return -99;
12917     }
12918   if (dst_set == 0)
12919     {
12920       errmsg ("tunnel dst address not specified");
12921       return -99;
12922     }
12923
12924   if (grp_set && !ip46_address_is_multicast (&dst))
12925     {
12926       errmsg ("tunnel group address not multicast");
12927       return -99;
12928     }
12929   if (grp_set && mcast_sw_if_index == ~0)
12930     {
12931       errmsg ("tunnel nonexistent multicast device");
12932       return -99;
12933     }
12934   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12935     {
12936       errmsg ("tunnel dst address must be unicast");
12937       return -99;
12938     }
12939
12940
12941   if (ipv4_set && ipv6_set)
12942     {
12943       errmsg ("both IPv4 and IPv6 addresses specified");
12944       return -99;
12945     }
12946
12947   if ((vni == 0) || (vni >> 24))
12948     {
12949       errmsg ("vni not specified or out of range");
12950       return -99;
12951     }
12952
12953   M (GENEVE_ADD_DEL_TUNNEL, mp);
12954
12955   if (ipv6_set)
12956     {
12957       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12958       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12959     }
12960   else
12961     {
12962       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12963       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12964     }
12965   mp->encap_vrf_id = ntohl (encap_vrf_id);
12966   mp->decap_next_index = ntohl (decap_next_index);
12967   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12968   mp->vni = ntohl (vni);
12969   mp->is_add = is_add;
12970   mp->is_ipv6 = ipv6_set;
12971
12972   S (mp);
12973   W (ret);
12974   return ret;
12975 }
12976
12977 static void vl_api_geneve_tunnel_details_t_handler
12978   (vl_api_geneve_tunnel_details_t * mp)
12979 {
12980   vat_main_t *vam = &vat_main;
12981   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12982   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12983
12984   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12985          ntohl (mp->sw_if_index),
12986          format_ip46_address, &src, IP46_TYPE_ANY,
12987          format_ip46_address, &dst, IP46_TYPE_ANY,
12988          ntohl (mp->encap_vrf_id),
12989          ntohl (mp->decap_next_index), ntohl (mp->vni),
12990          ntohl (mp->mcast_sw_if_index));
12991 }
12992
12993 static void vl_api_geneve_tunnel_details_t_handler_json
12994   (vl_api_geneve_tunnel_details_t * mp)
12995 {
12996   vat_main_t *vam = &vat_main;
12997   vat_json_node_t *node = NULL;
12998
12999   if (VAT_JSON_ARRAY != vam->json_tree.type)
13000     {
13001       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13002       vat_json_init_array (&vam->json_tree);
13003     }
13004   node = vat_json_array_add (&vam->json_tree);
13005
13006   vat_json_init_object (node);
13007   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13008   if (mp->is_ipv6)
13009     {
13010       struct in6_addr ip6;
13011
13012       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13013       vat_json_object_add_ip6 (node, "src_address", ip6);
13014       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13015       vat_json_object_add_ip6 (node, "dst_address", ip6);
13016     }
13017   else
13018     {
13019       struct in_addr ip4;
13020
13021       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13022       vat_json_object_add_ip4 (node, "src_address", ip4);
13023       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13024       vat_json_object_add_ip4 (node, "dst_address", ip4);
13025     }
13026   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13027   vat_json_object_add_uint (node, "decap_next_index",
13028                             ntohl (mp->decap_next_index));
13029   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13030   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13031   vat_json_object_add_uint (node, "mcast_sw_if_index",
13032                             ntohl (mp->mcast_sw_if_index));
13033 }
13034
13035 static int
13036 api_geneve_tunnel_dump (vat_main_t * vam)
13037 {
13038   unformat_input_t *i = vam->input;
13039   vl_api_geneve_tunnel_dump_t *mp;
13040   vl_api_control_ping_t *mp_ping;
13041   u32 sw_if_index;
13042   u8 sw_if_index_set = 0;
13043   int ret;
13044
13045   /* Parse args required to build the message */
13046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13047     {
13048       if (unformat (i, "sw_if_index %d", &sw_if_index))
13049         sw_if_index_set = 1;
13050       else
13051         break;
13052     }
13053
13054   if (sw_if_index_set == 0)
13055     {
13056       sw_if_index = ~0;
13057     }
13058
13059   if (!vam->json_output)
13060     {
13061       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13062              "sw_if_index", "local_address", "remote_address",
13063              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13064     }
13065
13066   /* Get list of geneve-tunnel interfaces */
13067   M (GENEVE_TUNNEL_DUMP, mp);
13068
13069   mp->sw_if_index = htonl (sw_if_index);
13070
13071   S (mp);
13072
13073   /* Use a control ping for synchronization */
13074   M (CONTROL_PING, mp_ping);
13075   S (mp_ping);
13076
13077   W (ret);
13078   return ret;
13079 }
13080
13081 static int
13082 api_gre_add_del_tunnel (vat_main_t * vam)
13083 {
13084   unformat_input_t *line_input = vam->input;
13085   vl_api_gre_add_del_tunnel_t *mp;
13086   ip4_address_t src4, dst4;
13087   ip6_address_t src6, dst6;
13088   u8 is_add = 1;
13089   u8 ipv4_set = 0;
13090   u8 ipv6_set = 0;
13091   u8 teb = 0;
13092   u8 src_set = 0;
13093   u8 dst_set = 0;
13094   u32 outer_fib_id = 0;
13095   int ret;
13096
13097   memset (&src4, 0, sizeof src4);
13098   memset (&dst4, 0, sizeof dst4);
13099   memset (&src6, 0, sizeof src6);
13100   memset (&dst6, 0, sizeof dst6);
13101
13102   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13103     {
13104       if (unformat (line_input, "del"))
13105         is_add = 0;
13106       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13107         {
13108           src_set = 1;
13109           ipv4_set = 1;
13110         }
13111       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13112         {
13113           dst_set = 1;
13114           ipv4_set = 1;
13115         }
13116       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13117         {
13118           src_set = 1;
13119           ipv6_set = 1;
13120         }
13121       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13122         {
13123           dst_set = 1;
13124           ipv6_set = 1;
13125         }
13126       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13127         ;
13128       else if (unformat (line_input, "teb"))
13129         teb = 1;
13130       else
13131         {
13132           errmsg ("parse error '%U'", format_unformat_error, line_input);
13133           return -99;
13134         }
13135     }
13136
13137   if (src_set == 0)
13138     {
13139       errmsg ("tunnel src address not specified");
13140       return -99;
13141     }
13142   if (dst_set == 0)
13143     {
13144       errmsg ("tunnel dst address not specified");
13145       return -99;
13146     }
13147   if (ipv4_set && ipv6_set)
13148     {
13149       errmsg ("both IPv4 and IPv6 addresses specified");
13150       return -99;
13151     }
13152
13153
13154   M (GRE_ADD_DEL_TUNNEL, mp);
13155
13156   if (ipv4_set)
13157     {
13158       clib_memcpy (&mp->src_address, &src4, 4);
13159       clib_memcpy (&mp->dst_address, &dst4, 4);
13160     }
13161   else
13162     {
13163       clib_memcpy (&mp->src_address, &src6, 16);
13164       clib_memcpy (&mp->dst_address, &dst6, 16);
13165     }
13166   mp->outer_fib_id = ntohl (outer_fib_id);
13167   mp->is_add = is_add;
13168   mp->teb = teb;
13169   mp->is_ipv6 = ipv6_set;
13170
13171   S (mp);
13172   W (ret);
13173   return ret;
13174 }
13175
13176 static void vl_api_gre_tunnel_details_t_handler
13177   (vl_api_gre_tunnel_details_t * mp)
13178 {
13179   vat_main_t *vam = &vat_main;
13180   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13181   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13182
13183   print (vam->ofp, "%11d%24U%24U%6d%14d",
13184          ntohl (mp->sw_if_index),
13185          format_ip46_address, &src, IP46_TYPE_ANY,
13186          format_ip46_address, &dst, IP46_TYPE_ANY,
13187          mp->teb, ntohl (mp->outer_fib_id));
13188 }
13189
13190 static void vl_api_gre_tunnel_details_t_handler_json
13191   (vl_api_gre_tunnel_details_t * mp)
13192 {
13193   vat_main_t *vam = &vat_main;
13194   vat_json_node_t *node = NULL;
13195   struct in_addr ip4;
13196   struct in6_addr ip6;
13197
13198   if (VAT_JSON_ARRAY != vam->json_tree.type)
13199     {
13200       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13201       vat_json_init_array (&vam->json_tree);
13202     }
13203   node = vat_json_array_add (&vam->json_tree);
13204
13205   vat_json_init_object (node);
13206   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13207   if (!mp->is_ipv6)
13208     {
13209       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13210       vat_json_object_add_ip4 (node, "src_address", ip4);
13211       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13212       vat_json_object_add_ip4 (node, "dst_address", ip4);
13213     }
13214   else
13215     {
13216       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13217       vat_json_object_add_ip6 (node, "src_address", ip6);
13218       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13219       vat_json_object_add_ip6 (node, "dst_address", ip6);
13220     }
13221   vat_json_object_add_uint (node, "teb", mp->teb);
13222   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13223   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13224 }
13225
13226 static int
13227 api_gre_tunnel_dump (vat_main_t * vam)
13228 {
13229   unformat_input_t *i = vam->input;
13230   vl_api_gre_tunnel_dump_t *mp;
13231   vl_api_control_ping_t *mp_ping;
13232   u32 sw_if_index;
13233   u8 sw_if_index_set = 0;
13234   int ret;
13235
13236   /* Parse args required to build the message */
13237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13238     {
13239       if (unformat (i, "sw_if_index %d", &sw_if_index))
13240         sw_if_index_set = 1;
13241       else
13242         break;
13243     }
13244
13245   if (sw_if_index_set == 0)
13246     {
13247       sw_if_index = ~0;
13248     }
13249
13250   if (!vam->json_output)
13251     {
13252       print (vam->ofp, "%11s%24s%24s%6s%14s",
13253              "sw_if_index", "src_address", "dst_address", "teb",
13254              "outer_fib_id");
13255     }
13256
13257   /* Get list of gre-tunnel interfaces */
13258   M (GRE_TUNNEL_DUMP, mp);
13259
13260   mp->sw_if_index = htonl (sw_if_index);
13261
13262   S (mp);
13263
13264   /* Use a control ping for synchronization */
13265   MPING (CONTROL_PING, mp_ping);
13266   S (mp_ping);
13267
13268   W (ret);
13269   return ret;
13270 }
13271
13272 static int
13273 api_l2_fib_clear_table (vat_main_t * vam)
13274 {
13275 //  unformat_input_t * i = vam->input;
13276   vl_api_l2_fib_clear_table_t *mp;
13277   int ret;
13278
13279   M (L2_FIB_CLEAR_TABLE, mp);
13280
13281   S (mp);
13282   W (ret);
13283   return ret;
13284 }
13285
13286 static int
13287 api_l2_interface_efp_filter (vat_main_t * vam)
13288 {
13289   unformat_input_t *i = vam->input;
13290   vl_api_l2_interface_efp_filter_t *mp;
13291   u32 sw_if_index;
13292   u8 enable = 1;
13293   u8 sw_if_index_set = 0;
13294   int ret;
13295
13296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13297     {
13298       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13299         sw_if_index_set = 1;
13300       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13301         sw_if_index_set = 1;
13302       else if (unformat (i, "enable"))
13303         enable = 1;
13304       else if (unformat (i, "disable"))
13305         enable = 0;
13306       else
13307         {
13308           clib_warning ("parse error '%U'", format_unformat_error, i);
13309           return -99;
13310         }
13311     }
13312
13313   if (sw_if_index_set == 0)
13314     {
13315       errmsg ("missing sw_if_index");
13316       return -99;
13317     }
13318
13319   M (L2_INTERFACE_EFP_FILTER, mp);
13320
13321   mp->sw_if_index = ntohl (sw_if_index);
13322   mp->enable_disable = enable;
13323
13324   S (mp);
13325   W (ret);
13326   return ret;
13327 }
13328
13329 #define foreach_vtr_op                          \
13330 _("disable",  L2_VTR_DISABLED)                  \
13331 _("push-1",  L2_VTR_PUSH_1)                     \
13332 _("push-2",  L2_VTR_PUSH_2)                     \
13333 _("pop-1",  L2_VTR_POP_1)                       \
13334 _("pop-2",  L2_VTR_POP_2)                       \
13335 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13336 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13337 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13338 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13339
13340 static int
13341 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13342 {
13343   unformat_input_t *i = vam->input;
13344   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13345   u32 sw_if_index;
13346   u8 sw_if_index_set = 0;
13347   u8 vtr_op_set = 0;
13348   u32 vtr_op = 0;
13349   u32 push_dot1q = 1;
13350   u32 tag1 = ~0;
13351   u32 tag2 = ~0;
13352   int ret;
13353
13354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13355     {
13356       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13357         sw_if_index_set = 1;
13358       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13359         sw_if_index_set = 1;
13360       else if (unformat (i, "vtr_op %d", &vtr_op))
13361         vtr_op_set = 1;
13362 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13363       foreach_vtr_op
13364 #undef _
13365         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13366         ;
13367       else if (unformat (i, "tag1 %d", &tag1))
13368         ;
13369       else if (unformat (i, "tag2 %d", &tag2))
13370         ;
13371       else
13372         {
13373           clib_warning ("parse error '%U'", format_unformat_error, i);
13374           return -99;
13375         }
13376     }
13377
13378   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13379     {
13380       errmsg ("missing vtr operation or sw_if_index");
13381       return -99;
13382     }
13383
13384   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13385   mp->sw_if_index = ntohl (sw_if_index);
13386   mp->vtr_op = ntohl (vtr_op);
13387   mp->push_dot1q = ntohl (push_dot1q);
13388   mp->tag1 = ntohl (tag1);
13389   mp->tag2 = ntohl (tag2);
13390
13391   S (mp);
13392   W (ret);
13393   return ret;
13394 }
13395
13396 static int
13397 api_create_vhost_user_if (vat_main_t * vam)
13398 {
13399   unformat_input_t *i = vam->input;
13400   vl_api_create_vhost_user_if_t *mp;
13401   u8 *file_name;
13402   u8 is_server = 0;
13403   u8 file_name_set = 0;
13404   u32 custom_dev_instance = ~0;
13405   u8 hwaddr[6];
13406   u8 use_custom_mac = 0;
13407   u8 *tag = 0;
13408   int ret;
13409
13410   /* Shut up coverity */
13411   memset (hwaddr, 0, sizeof (hwaddr));
13412
13413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13414     {
13415       if (unformat (i, "socket %s", &file_name))
13416         {
13417           file_name_set = 1;
13418         }
13419       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13420         ;
13421       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13422         use_custom_mac = 1;
13423       else if (unformat (i, "server"))
13424         is_server = 1;
13425       else if (unformat (i, "tag %s", &tag))
13426         ;
13427       else
13428         break;
13429     }
13430
13431   if (file_name_set == 0)
13432     {
13433       errmsg ("missing socket file name");
13434       return -99;
13435     }
13436
13437   if (vec_len (file_name) > 255)
13438     {
13439       errmsg ("socket file name too long");
13440       return -99;
13441     }
13442   vec_add1 (file_name, 0);
13443
13444   M (CREATE_VHOST_USER_IF, mp);
13445
13446   mp->is_server = is_server;
13447   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13448   vec_free (file_name);
13449   if (custom_dev_instance != ~0)
13450     {
13451       mp->renumber = 1;
13452       mp->custom_dev_instance = ntohl (custom_dev_instance);
13453     }
13454   mp->use_custom_mac = use_custom_mac;
13455   clib_memcpy (mp->mac_address, hwaddr, 6);
13456   if (tag)
13457     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13458   vec_free (tag);
13459
13460   S (mp);
13461   W (ret);
13462   return ret;
13463 }
13464
13465 static int
13466 api_modify_vhost_user_if (vat_main_t * vam)
13467 {
13468   unformat_input_t *i = vam->input;
13469   vl_api_modify_vhost_user_if_t *mp;
13470   u8 *file_name;
13471   u8 is_server = 0;
13472   u8 file_name_set = 0;
13473   u32 custom_dev_instance = ~0;
13474   u8 sw_if_index_set = 0;
13475   u32 sw_if_index = (u32) ~ 0;
13476   int ret;
13477
13478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13479     {
13480       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13481         sw_if_index_set = 1;
13482       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13483         sw_if_index_set = 1;
13484       else if (unformat (i, "socket %s", &file_name))
13485         {
13486           file_name_set = 1;
13487         }
13488       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13489         ;
13490       else if (unformat (i, "server"))
13491         is_server = 1;
13492       else
13493         break;
13494     }
13495
13496   if (sw_if_index_set == 0)
13497     {
13498       errmsg ("missing sw_if_index or interface name");
13499       return -99;
13500     }
13501
13502   if (file_name_set == 0)
13503     {
13504       errmsg ("missing socket file name");
13505       return -99;
13506     }
13507
13508   if (vec_len (file_name) > 255)
13509     {
13510       errmsg ("socket file name too long");
13511       return -99;
13512     }
13513   vec_add1 (file_name, 0);
13514
13515   M (MODIFY_VHOST_USER_IF, mp);
13516
13517   mp->sw_if_index = ntohl (sw_if_index);
13518   mp->is_server = is_server;
13519   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13520   vec_free (file_name);
13521   if (custom_dev_instance != ~0)
13522     {
13523       mp->renumber = 1;
13524       mp->custom_dev_instance = ntohl (custom_dev_instance);
13525     }
13526
13527   S (mp);
13528   W (ret);
13529   return ret;
13530 }
13531
13532 static int
13533 api_delete_vhost_user_if (vat_main_t * vam)
13534 {
13535   unformat_input_t *i = vam->input;
13536   vl_api_delete_vhost_user_if_t *mp;
13537   u32 sw_if_index = ~0;
13538   u8 sw_if_index_set = 0;
13539   int ret;
13540
13541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13542     {
13543       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13544         sw_if_index_set = 1;
13545       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13546         sw_if_index_set = 1;
13547       else
13548         break;
13549     }
13550
13551   if (sw_if_index_set == 0)
13552     {
13553       errmsg ("missing sw_if_index or interface name");
13554       return -99;
13555     }
13556
13557
13558   M (DELETE_VHOST_USER_IF, mp);
13559
13560   mp->sw_if_index = ntohl (sw_if_index);
13561
13562   S (mp);
13563   W (ret);
13564   return ret;
13565 }
13566
13567 static void vl_api_sw_interface_vhost_user_details_t_handler
13568   (vl_api_sw_interface_vhost_user_details_t * mp)
13569 {
13570   vat_main_t *vam = &vat_main;
13571
13572   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13573          (char *) mp->interface_name,
13574          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13575          clib_net_to_host_u64 (mp->features), mp->is_server,
13576          ntohl (mp->num_regions), (char *) mp->sock_filename);
13577   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13578 }
13579
13580 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13581   (vl_api_sw_interface_vhost_user_details_t * mp)
13582 {
13583   vat_main_t *vam = &vat_main;
13584   vat_json_node_t *node = NULL;
13585
13586   if (VAT_JSON_ARRAY != vam->json_tree.type)
13587     {
13588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13589       vat_json_init_array (&vam->json_tree);
13590     }
13591   node = vat_json_array_add (&vam->json_tree);
13592
13593   vat_json_init_object (node);
13594   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13595   vat_json_object_add_string_copy (node, "interface_name",
13596                                    mp->interface_name);
13597   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13598                             ntohl (mp->virtio_net_hdr_sz));
13599   vat_json_object_add_uint (node, "features",
13600                             clib_net_to_host_u64 (mp->features));
13601   vat_json_object_add_uint (node, "is_server", mp->is_server);
13602   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13603   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13604   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13605 }
13606
13607 static int
13608 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13609 {
13610   vl_api_sw_interface_vhost_user_dump_t *mp;
13611   vl_api_control_ping_t *mp_ping;
13612   int ret;
13613   print (vam->ofp,
13614          "Interface name            idx hdr_sz features server regions filename");
13615
13616   /* Get list of vhost-user interfaces */
13617   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13618   S (mp);
13619
13620   /* Use a control ping for synchronization */
13621   MPING (CONTROL_PING, mp_ping);
13622   S (mp_ping);
13623
13624   W (ret);
13625   return ret;
13626 }
13627
13628 static int
13629 api_show_version (vat_main_t * vam)
13630 {
13631   vl_api_show_version_t *mp;
13632   int ret;
13633
13634   M (SHOW_VERSION, mp);
13635
13636   S (mp);
13637   W (ret);
13638   return ret;
13639 }
13640
13641
13642 static int
13643 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13644 {
13645   unformat_input_t *line_input = vam->input;
13646   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13647   ip4_address_t local4, remote4;
13648   ip6_address_t local6, remote6;
13649   u8 is_add = 1;
13650   u8 ipv4_set = 0, ipv6_set = 0;
13651   u8 local_set = 0;
13652   u8 remote_set = 0;
13653   u8 grp_set = 0;
13654   u32 mcast_sw_if_index = ~0;
13655   u32 encap_vrf_id = 0;
13656   u32 decap_vrf_id = 0;
13657   u8 protocol = ~0;
13658   u32 vni;
13659   u8 vni_set = 0;
13660   int ret;
13661
13662   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13663   memset (&local4, 0, sizeof local4);
13664   memset (&remote4, 0, sizeof remote4);
13665   memset (&local6, 0, sizeof local6);
13666   memset (&remote6, 0, sizeof remote6);
13667
13668   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13669     {
13670       if (unformat (line_input, "del"))
13671         is_add = 0;
13672       else if (unformat (line_input, "local %U",
13673                          unformat_ip4_address, &local4))
13674         {
13675           local_set = 1;
13676           ipv4_set = 1;
13677         }
13678       else if (unformat (line_input, "remote %U",
13679                          unformat_ip4_address, &remote4))
13680         {
13681           remote_set = 1;
13682           ipv4_set = 1;
13683         }
13684       else if (unformat (line_input, "local %U",
13685                          unformat_ip6_address, &local6))
13686         {
13687           local_set = 1;
13688           ipv6_set = 1;
13689         }
13690       else if (unformat (line_input, "remote %U",
13691                          unformat_ip6_address, &remote6))
13692         {
13693           remote_set = 1;
13694           ipv6_set = 1;
13695         }
13696       else if (unformat (line_input, "group %U %U",
13697                          unformat_ip4_address, &remote4,
13698                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13699         {
13700           grp_set = remote_set = 1;
13701           ipv4_set = 1;
13702         }
13703       else if (unformat (line_input, "group %U",
13704                          unformat_ip4_address, &remote4))
13705         {
13706           grp_set = remote_set = 1;
13707           ipv4_set = 1;
13708         }
13709       else if (unformat (line_input, "group %U %U",
13710                          unformat_ip6_address, &remote6,
13711                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13712         {
13713           grp_set = remote_set = 1;
13714           ipv6_set = 1;
13715         }
13716       else if (unformat (line_input, "group %U",
13717                          unformat_ip6_address, &remote6))
13718         {
13719           grp_set = remote_set = 1;
13720           ipv6_set = 1;
13721         }
13722       else
13723         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13724         ;
13725       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13726         ;
13727       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13728         ;
13729       else if (unformat (line_input, "vni %d", &vni))
13730         vni_set = 1;
13731       else if (unformat (line_input, "next-ip4"))
13732         protocol = 1;
13733       else if (unformat (line_input, "next-ip6"))
13734         protocol = 2;
13735       else if (unformat (line_input, "next-ethernet"))
13736         protocol = 3;
13737       else if (unformat (line_input, "next-nsh"))
13738         protocol = 4;
13739       else
13740         {
13741           errmsg ("parse error '%U'", format_unformat_error, line_input);
13742           return -99;
13743         }
13744     }
13745
13746   if (local_set == 0)
13747     {
13748       errmsg ("tunnel local address not specified");
13749       return -99;
13750     }
13751   if (remote_set == 0)
13752     {
13753       errmsg ("tunnel remote address not specified");
13754       return -99;
13755     }
13756   if (grp_set && mcast_sw_if_index == ~0)
13757     {
13758       errmsg ("tunnel nonexistent multicast device");
13759       return -99;
13760     }
13761   if (ipv4_set && ipv6_set)
13762     {
13763       errmsg ("both IPv4 and IPv6 addresses specified");
13764       return -99;
13765     }
13766
13767   if (vni_set == 0)
13768     {
13769       errmsg ("vni not specified");
13770       return -99;
13771     }
13772
13773   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13774
13775
13776   if (ipv6_set)
13777     {
13778       clib_memcpy (&mp->local, &local6, sizeof (local6));
13779       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13780     }
13781   else
13782     {
13783       clib_memcpy (&mp->local, &local4, sizeof (local4));
13784       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13785     }
13786
13787   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13788   mp->encap_vrf_id = ntohl (encap_vrf_id);
13789   mp->decap_vrf_id = ntohl (decap_vrf_id);
13790   mp->protocol = protocol;
13791   mp->vni = ntohl (vni);
13792   mp->is_add = is_add;
13793   mp->is_ipv6 = ipv6_set;
13794
13795   S (mp);
13796   W (ret);
13797   return ret;
13798 }
13799
13800 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13801   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13802 {
13803   vat_main_t *vam = &vat_main;
13804   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13805   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13806
13807   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13808          ntohl (mp->sw_if_index),
13809          format_ip46_address, &local, IP46_TYPE_ANY,
13810          format_ip46_address, &remote, IP46_TYPE_ANY,
13811          ntohl (mp->vni), mp->protocol,
13812          ntohl (mp->mcast_sw_if_index),
13813          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13814 }
13815
13816
13817 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13818   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13819 {
13820   vat_main_t *vam = &vat_main;
13821   vat_json_node_t *node = NULL;
13822   struct in_addr ip4;
13823   struct in6_addr ip6;
13824
13825   if (VAT_JSON_ARRAY != vam->json_tree.type)
13826     {
13827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13828       vat_json_init_array (&vam->json_tree);
13829     }
13830   node = vat_json_array_add (&vam->json_tree);
13831
13832   vat_json_init_object (node);
13833   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13834   if (mp->is_ipv6)
13835     {
13836       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13837       vat_json_object_add_ip6 (node, "local", ip6);
13838       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13839       vat_json_object_add_ip6 (node, "remote", ip6);
13840     }
13841   else
13842     {
13843       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13844       vat_json_object_add_ip4 (node, "local", ip4);
13845       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13846       vat_json_object_add_ip4 (node, "remote", ip4);
13847     }
13848   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13849   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13850   vat_json_object_add_uint (node, "mcast_sw_if_index",
13851                             ntohl (mp->mcast_sw_if_index));
13852   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13853   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13854   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13855 }
13856
13857 static int
13858 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13859 {
13860   unformat_input_t *i = vam->input;
13861   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13862   vl_api_control_ping_t *mp_ping;
13863   u32 sw_if_index;
13864   u8 sw_if_index_set = 0;
13865   int ret;
13866
13867   /* Parse args required to build the message */
13868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13869     {
13870       if (unformat (i, "sw_if_index %d", &sw_if_index))
13871         sw_if_index_set = 1;
13872       else
13873         break;
13874     }
13875
13876   if (sw_if_index_set == 0)
13877     {
13878       sw_if_index = ~0;
13879     }
13880
13881   if (!vam->json_output)
13882     {
13883       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13884              "sw_if_index", "local", "remote", "vni",
13885              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13886     }
13887
13888   /* Get list of vxlan-tunnel interfaces */
13889   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13890
13891   mp->sw_if_index = htonl (sw_if_index);
13892
13893   S (mp);
13894
13895   /* Use a control ping for synchronization */
13896   MPING (CONTROL_PING, mp_ping);
13897   S (mp_ping);
13898
13899   W (ret);
13900   return ret;
13901 }
13902
13903 static void vl_api_l2_fib_table_details_t_handler
13904   (vl_api_l2_fib_table_details_t * mp)
13905 {
13906   vat_main_t *vam = &vat_main;
13907
13908   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13909          "       %d       %d     %d",
13910          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13911          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13912          mp->bvi_mac);
13913 }
13914
13915 static void vl_api_l2_fib_table_details_t_handler_json
13916   (vl_api_l2_fib_table_details_t * mp)
13917 {
13918   vat_main_t *vam = &vat_main;
13919   vat_json_node_t *node = NULL;
13920
13921   if (VAT_JSON_ARRAY != vam->json_tree.type)
13922     {
13923       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13924       vat_json_init_array (&vam->json_tree);
13925     }
13926   node = vat_json_array_add (&vam->json_tree);
13927
13928   vat_json_init_object (node);
13929   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13930   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13931   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13932   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13933   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13934   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13935 }
13936
13937 static int
13938 api_l2_fib_table_dump (vat_main_t * vam)
13939 {
13940   unformat_input_t *i = vam->input;
13941   vl_api_l2_fib_table_dump_t *mp;
13942   vl_api_control_ping_t *mp_ping;
13943   u32 bd_id;
13944   u8 bd_id_set = 0;
13945   int ret;
13946
13947   /* Parse args required to build the message */
13948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13949     {
13950       if (unformat (i, "bd_id %d", &bd_id))
13951         bd_id_set = 1;
13952       else
13953         break;
13954     }
13955
13956   if (bd_id_set == 0)
13957     {
13958       errmsg ("missing bridge domain");
13959       return -99;
13960     }
13961
13962   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13963
13964   /* Get list of l2 fib entries */
13965   M (L2_FIB_TABLE_DUMP, mp);
13966
13967   mp->bd_id = ntohl (bd_id);
13968   S (mp);
13969
13970   /* Use a control ping for synchronization */
13971   MPING (CONTROL_PING, mp_ping);
13972   S (mp_ping);
13973
13974   W (ret);
13975   return ret;
13976 }
13977
13978
13979 static int
13980 api_interface_name_renumber (vat_main_t * vam)
13981 {
13982   unformat_input_t *line_input = vam->input;
13983   vl_api_interface_name_renumber_t *mp;
13984   u32 sw_if_index = ~0;
13985   u32 new_show_dev_instance = ~0;
13986   int ret;
13987
13988   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13989     {
13990       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13991                     &sw_if_index))
13992         ;
13993       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13994         ;
13995       else if (unformat (line_input, "new_show_dev_instance %d",
13996                          &new_show_dev_instance))
13997         ;
13998       else
13999         break;
14000     }
14001
14002   if (sw_if_index == ~0)
14003     {
14004       errmsg ("missing interface name or sw_if_index");
14005       return -99;
14006     }
14007
14008   if (new_show_dev_instance == ~0)
14009     {
14010       errmsg ("missing new_show_dev_instance");
14011       return -99;
14012     }
14013
14014   M (INTERFACE_NAME_RENUMBER, mp);
14015
14016   mp->sw_if_index = ntohl (sw_if_index);
14017   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14018
14019   S (mp);
14020   W (ret);
14021   return ret;
14022 }
14023
14024 static int
14025 api_want_ip4_arp_events (vat_main_t * vam)
14026 {
14027   unformat_input_t *line_input = vam->input;
14028   vl_api_want_ip4_arp_events_t *mp;
14029   ip4_address_t address;
14030   int address_set = 0;
14031   u32 enable_disable = 1;
14032   int ret;
14033
14034   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14035     {
14036       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14037         address_set = 1;
14038       else if (unformat (line_input, "del"))
14039         enable_disable = 0;
14040       else
14041         break;
14042     }
14043
14044   if (address_set == 0)
14045     {
14046       errmsg ("missing addresses");
14047       return -99;
14048     }
14049
14050   M (WANT_IP4_ARP_EVENTS, mp);
14051   mp->enable_disable = enable_disable;
14052   mp->pid = htonl (getpid ());
14053   mp->address = address.as_u32;
14054
14055   S (mp);
14056   W (ret);
14057   return ret;
14058 }
14059
14060 static int
14061 api_want_ip6_nd_events (vat_main_t * vam)
14062 {
14063   unformat_input_t *line_input = vam->input;
14064   vl_api_want_ip6_nd_events_t *mp;
14065   ip6_address_t address;
14066   int address_set = 0;
14067   u32 enable_disable = 1;
14068   int ret;
14069
14070   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14071     {
14072       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14073         address_set = 1;
14074       else if (unformat (line_input, "del"))
14075         enable_disable = 0;
14076       else
14077         break;
14078     }
14079
14080   if (address_set == 0)
14081     {
14082       errmsg ("missing addresses");
14083       return -99;
14084     }
14085
14086   M (WANT_IP6_ND_EVENTS, mp);
14087   mp->enable_disable = enable_disable;
14088   mp->pid = htonl (getpid ());
14089   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14090
14091   S (mp);
14092   W (ret);
14093   return ret;
14094 }
14095
14096 static int
14097 api_want_l2_macs_events (vat_main_t * vam)
14098 {
14099   unformat_input_t *line_input = vam->input;
14100   vl_api_want_l2_macs_events_t *mp;
14101   u8 enable_disable = 1;
14102   u32 scan_delay = 0;
14103   u32 max_macs_in_event = 0;
14104   u32 learn_limit = 0;
14105   int ret;
14106
14107   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14108     {
14109       if (unformat (line_input, "learn-limit %d", &learn_limit))
14110         ;
14111       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14112         ;
14113       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14114         ;
14115       else if (unformat (line_input, "disable"))
14116         enable_disable = 0;
14117       else
14118         break;
14119     }
14120
14121   M (WANT_L2_MACS_EVENTS, mp);
14122   mp->enable_disable = enable_disable;
14123   mp->pid = htonl (getpid ());
14124   mp->learn_limit = htonl (learn_limit);
14125   mp->scan_delay = (u8) scan_delay;
14126   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14127   S (mp);
14128   W (ret);
14129   return ret;
14130 }
14131
14132 static int
14133 api_input_acl_set_interface (vat_main_t * vam)
14134 {
14135   unformat_input_t *i = vam->input;
14136   vl_api_input_acl_set_interface_t *mp;
14137   u32 sw_if_index;
14138   int sw_if_index_set;
14139   u32 ip4_table_index = ~0;
14140   u32 ip6_table_index = ~0;
14141   u32 l2_table_index = ~0;
14142   u8 is_add = 1;
14143   int ret;
14144
14145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14146     {
14147       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14148         sw_if_index_set = 1;
14149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14150         sw_if_index_set = 1;
14151       else if (unformat (i, "del"))
14152         is_add = 0;
14153       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14154         ;
14155       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14156         ;
14157       else if (unformat (i, "l2-table %d", &l2_table_index))
14158         ;
14159       else
14160         {
14161           clib_warning ("parse error '%U'", format_unformat_error, i);
14162           return -99;
14163         }
14164     }
14165
14166   if (sw_if_index_set == 0)
14167     {
14168       errmsg ("missing interface name or sw_if_index");
14169       return -99;
14170     }
14171
14172   M (INPUT_ACL_SET_INTERFACE, mp);
14173
14174   mp->sw_if_index = ntohl (sw_if_index);
14175   mp->ip4_table_index = ntohl (ip4_table_index);
14176   mp->ip6_table_index = ntohl (ip6_table_index);
14177   mp->l2_table_index = ntohl (l2_table_index);
14178   mp->is_add = is_add;
14179
14180   S (mp);
14181   W (ret);
14182   return ret;
14183 }
14184
14185 static int
14186 api_ip_address_dump (vat_main_t * vam)
14187 {
14188   unformat_input_t *i = vam->input;
14189   vl_api_ip_address_dump_t *mp;
14190   vl_api_control_ping_t *mp_ping;
14191   u32 sw_if_index = ~0;
14192   u8 sw_if_index_set = 0;
14193   u8 ipv4_set = 0;
14194   u8 ipv6_set = 0;
14195   int ret;
14196
14197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14198     {
14199       if (unformat (i, "sw_if_index %d", &sw_if_index))
14200         sw_if_index_set = 1;
14201       else
14202         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14203         sw_if_index_set = 1;
14204       else if (unformat (i, "ipv4"))
14205         ipv4_set = 1;
14206       else if (unformat (i, "ipv6"))
14207         ipv6_set = 1;
14208       else
14209         break;
14210     }
14211
14212   if (ipv4_set && ipv6_set)
14213     {
14214       errmsg ("ipv4 and ipv6 flags cannot be both set");
14215       return -99;
14216     }
14217
14218   if ((!ipv4_set) && (!ipv6_set))
14219     {
14220       errmsg ("no ipv4 nor ipv6 flag set");
14221       return -99;
14222     }
14223
14224   if (sw_if_index_set == 0)
14225     {
14226       errmsg ("missing interface name or sw_if_index");
14227       return -99;
14228     }
14229
14230   vam->current_sw_if_index = sw_if_index;
14231   vam->is_ipv6 = ipv6_set;
14232
14233   M (IP_ADDRESS_DUMP, mp);
14234   mp->sw_if_index = ntohl (sw_if_index);
14235   mp->is_ipv6 = ipv6_set;
14236   S (mp);
14237
14238   /* Use a control ping for synchronization */
14239   MPING (CONTROL_PING, mp_ping);
14240   S (mp_ping);
14241
14242   W (ret);
14243   return ret;
14244 }
14245
14246 static int
14247 api_ip_dump (vat_main_t * vam)
14248 {
14249   vl_api_ip_dump_t *mp;
14250   vl_api_control_ping_t *mp_ping;
14251   unformat_input_t *in = vam->input;
14252   int ipv4_set = 0;
14253   int ipv6_set = 0;
14254   int is_ipv6;
14255   int i;
14256   int ret;
14257
14258   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14259     {
14260       if (unformat (in, "ipv4"))
14261         ipv4_set = 1;
14262       else if (unformat (in, "ipv6"))
14263         ipv6_set = 1;
14264       else
14265         break;
14266     }
14267
14268   if (ipv4_set && ipv6_set)
14269     {
14270       errmsg ("ipv4 and ipv6 flags cannot be both set");
14271       return -99;
14272     }
14273
14274   if ((!ipv4_set) && (!ipv6_set))
14275     {
14276       errmsg ("no ipv4 nor ipv6 flag set");
14277       return -99;
14278     }
14279
14280   is_ipv6 = ipv6_set;
14281   vam->is_ipv6 = is_ipv6;
14282
14283   /* free old data */
14284   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14285     {
14286       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14287     }
14288   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14289
14290   M (IP_DUMP, mp);
14291   mp->is_ipv6 = ipv6_set;
14292   S (mp);
14293
14294   /* Use a control ping for synchronization */
14295   MPING (CONTROL_PING, mp_ping);
14296   S (mp_ping);
14297
14298   W (ret);
14299   return ret;
14300 }
14301
14302 static int
14303 api_ipsec_spd_add_del (vat_main_t * vam)
14304 {
14305   unformat_input_t *i = vam->input;
14306   vl_api_ipsec_spd_add_del_t *mp;
14307   u32 spd_id = ~0;
14308   u8 is_add = 1;
14309   int ret;
14310
14311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14312     {
14313       if (unformat (i, "spd_id %d", &spd_id))
14314         ;
14315       else if (unformat (i, "del"))
14316         is_add = 0;
14317       else
14318         {
14319           clib_warning ("parse error '%U'", format_unformat_error, i);
14320           return -99;
14321         }
14322     }
14323   if (spd_id == ~0)
14324     {
14325       errmsg ("spd_id must be set");
14326       return -99;
14327     }
14328
14329   M (IPSEC_SPD_ADD_DEL, mp);
14330
14331   mp->spd_id = ntohl (spd_id);
14332   mp->is_add = is_add;
14333
14334   S (mp);
14335   W (ret);
14336   return ret;
14337 }
14338
14339 static int
14340 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14341 {
14342   unformat_input_t *i = vam->input;
14343   vl_api_ipsec_interface_add_del_spd_t *mp;
14344   u32 sw_if_index;
14345   u8 sw_if_index_set = 0;
14346   u32 spd_id = (u32) ~ 0;
14347   u8 is_add = 1;
14348   int ret;
14349
14350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14351     {
14352       if (unformat (i, "del"))
14353         is_add = 0;
14354       else if (unformat (i, "spd_id %d", &spd_id))
14355         ;
14356       else
14357         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14358         sw_if_index_set = 1;
14359       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14360         sw_if_index_set = 1;
14361       else
14362         {
14363           clib_warning ("parse error '%U'", format_unformat_error, i);
14364           return -99;
14365         }
14366
14367     }
14368
14369   if (spd_id == (u32) ~ 0)
14370     {
14371       errmsg ("spd_id must be set");
14372       return -99;
14373     }
14374
14375   if (sw_if_index_set == 0)
14376     {
14377       errmsg ("missing interface name or sw_if_index");
14378       return -99;
14379     }
14380
14381   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14382
14383   mp->spd_id = ntohl (spd_id);
14384   mp->sw_if_index = ntohl (sw_if_index);
14385   mp->is_add = is_add;
14386
14387   S (mp);
14388   W (ret);
14389   return ret;
14390 }
14391
14392 static int
14393 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14394 {
14395   unformat_input_t *i = vam->input;
14396   vl_api_ipsec_spd_add_del_entry_t *mp;
14397   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14398   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14399   i32 priority = 0;
14400   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14401   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14402   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14403   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14404   int ret;
14405
14406   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14407   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14408   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14409   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14410   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14411   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14412
14413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14414     {
14415       if (unformat (i, "del"))
14416         is_add = 0;
14417       if (unformat (i, "outbound"))
14418         is_outbound = 1;
14419       if (unformat (i, "inbound"))
14420         is_outbound = 0;
14421       else if (unformat (i, "spd_id %d", &spd_id))
14422         ;
14423       else if (unformat (i, "sa_id %d", &sa_id))
14424         ;
14425       else if (unformat (i, "priority %d", &priority))
14426         ;
14427       else if (unformat (i, "protocol %d", &protocol))
14428         ;
14429       else if (unformat (i, "lport_start %d", &lport_start))
14430         ;
14431       else if (unformat (i, "lport_stop %d", &lport_stop))
14432         ;
14433       else if (unformat (i, "rport_start %d", &rport_start))
14434         ;
14435       else if (unformat (i, "rport_stop %d", &rport_stop))
14436         ;
14437       else
14438         if (unformat
14439             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14440         {
14441           is_ipv6 = 0;
14442           is_ip_any = 0;
14443         }
14444       else
14445         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14446         {
14447           is_ipv6 = 0;
14448           is_ip_any = 0;
14449         }
14450       else
14451         if (unformat
14452             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14453         {
14454           is_ipv6 = 0;
14455           is_ip_any = 0;
14456         }
14457       else
14458         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14459         {
14460           is_ipv6 = 0;
14461           is_ip_any = 0;
14462         }
14463       else
14464         if (unformat
14465             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14466         {
14467           is_ipv6 = 1;
14468           is_ip_any = 0;
14469         }
14470       else
14471         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14472         {
14473           is_ipv6 = 1;
14474           is_ip_any = 0;
14475         }
14476       else
14477         if (unformat
14478             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14479         {
14480           is_ipv6 = 1;
14481           is_ip_any = 0;
14482         }
14483       else
14484         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14485         {
14486           is_ipv6 = 1;
14487           is_ip_any = 0;
14488         }
14489       else
14490         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14491         {
14492           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14493             {
14494               clib_warning ("unsupported action: 'resolve'");
14495               return -99;
14496             }
14497         }
14498       else
14499         {
14500           clib_warning ("parse error '%U'", format_unformat_error, i);
14501           return -99;
14502         }
14503
14504     }
14505
14506   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14507
14508   mp->spd_id = ntohl (spd_id);
14509   mp->priority = ntohl (priority);
14510   mp->is_outbound = is_outbound;
14511
14512   mp->is_ipv6 = is_ipv6;
14513   if (is_ipv6 || is_ip_any)
14514     {
14515       clib_memcpy (mp->remote_address_start, &raddr6_start,
14516                    sizeof (ip6_address_t));
14517       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14518                    sizeof (ip6_address_t));
14519       clib_memcpy (mp->local_address_start, &laddr6_start,
14520                    sizeof (ip6_address_t));
14521       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14522                    sizeof (ip6_address_t));
14523     }
14524   else
14525     {
14526       clib_memcpy (mp->remote_address_start, &raddr4_start,
14527                    sizeof (ip4_address_t));
14528       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14529                    sizeof (ip4_address_t));
14530       clib_memcpy (mp->local_address_start, &laddr4_start,
14531                    sizeof (ip4_address_t));
14532       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14533                    sizeof (ip4_address_t));
14534     }
14535   mp->protocol = (u8) protocol;
14536   mp->local_port_start = ntohs ((u16) lport_start);
14537   mp->local_port_stop = ntohs ((u16) lport_stop);
14538   mp->remote_port_start = ntohs ((u16) rport_start);
14539   mp->remote_port_stop = ntohs ((u16) rport_stop);
14540   mp->policy = (u8) policy;
14541   mp->sa_id = ntohl (sa_id);
14542   mp->is_add = is_add;
14543   mp->is_ip_any = is_ip_any;
14544   S (mp);
14545   W (ret);
14546   return ret;
14547 }
14548
14549 static int
14550 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14551 {
14552   unformat_input_t *i = vam->input;
14553   vl_api_ipsec_sad_add_del_entry_t *mp;
14554   u32 sad_id = 0, spi = 0;
14555   u8 *ck = 0, *ik = 0;
14556   u8 is_add = 1;
14557
14558   u8 protocol = IPSEC_PROTOCOL_AH;
14559   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14560   u32 crypto_alg = 0, integ_alg = 0;
14561   ip4_address_t tun_src4;
14562   ip4_address_t tun_dst4;
14563   ip6_address_t tun_src6;
14564   ip6_address_t tun_dst6;
14565   int ret;
14566
14567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14568     {
14569       if (unformat (i, "del"))
14570         is_add = 0;
14571       else if (unformat (i, "sad_id %d", &sad_id))
14572         ;
14573       else if (unformat (i, "spi %d", &spi))
14574         ;
14575       else if (unformat (i, "esp"))
14576         protocol = IPSEC_PROTOCOL_ESP;
14577       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14578         {
14579           is_tunnel = 1;
14580           is_tunnel_ipv6 = 0;
14581         }
14582       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14583         {
14584           is_tunnel = 1;
14585           is_tunnel_ipv6 = 0;
14586         }
14587       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14588         {
14589           is_tunnel = 1;
14590           is_tunnel_ipv6 = 1;
14591         }
14592       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14593         {
14594           is_tunnel = 1;
14595           is_tunnel_ipv6 = 1;
14596         }
14597       else
14598         if (unformat
14599             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14600         {
14601           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14602               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14603             {
14604               clib_warning ("unsupported crypto-alg: '%U'",
14605                             format_ipsec_crypto_alg, crypto_alg);
14606               return -99;
14607             }
14608         }
14609       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14610         ;
14611       else
14612         if (unformat
14613             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14614         {
14615           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14616               integ_alg >= IPSEC_INTEG_N_ALG)
14617             {
14618               clib_warning ("unsupported integ-alg: '%U'",
14619                             format_ipsec_integ_alg, integ_alg);
14620               return -99;
14621             }
14622         }
14623       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14624         ;
14625       else
14626         {
14627           clib_warning ("parse error '%U'", format_unformat_error, i);
14628           return -99;
14629         }
14630
14631     }
14632
14633   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14634
14635   mp->sad_id = ntohl (sad_id);
14636   mp->is_add = is_add;
14637   mp->protocol = protocol;
14638   mp->spi = ntohl (spi);
14639   mp->is_tunnel = is_tunnel;
14640   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14641   mp->crypto_algorithm = crypto_alg;
14642   mp->integrity_algorithm = integ_alg;
14643   mp->crypto_key_length = vec_len (ck);
14644   mp->integrity_key_length = vec_len (ik);
14645
14646   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14647     mp->crypto_key_length = sizeof (mp->crypto_key);
14648
14649   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14650     mp->integrity_key_length = sizeof (mp->integrity_key);
14651
14652   if (ck)
14653     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14654   if (ik)
14655     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14656
14657   if (is_tunnel)
14658     {
14659       if (is_tunnel_ipv6)
14660         {
14661           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14662                        sizeof (ip6_address_t));
14663           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14664                        sizeof (ip6_address_t));
14665         }
14666       else
14667         {
14668           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14669                        sizeof (ip4_address_t));
14670           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14671                        sizeof (ip4_address_t));
14672         }
14673     }
14674
14675   S (mp);
14676   W (ret);
14677   return ret;
14678 }
14679
14680 static int
14681 api_ipsec_sa_set_key (vat_main_t * vam)
14682 {
14683   unformat_input_t *i = vam->input;
14684   vl_api_ipsec_sa_set_key_t *mp;
14685   u32 sa_id;
14686   u8 *ck = 0, *ik = 0;
14687   int ret;
14688
14689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14690     {
14691       if (unformat (i, "sa_id %d", &sa_id))
14692         ;
14693       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14694         ;
14695       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14696         ;
14697       else
14698         {
14699           clib_warning ("parse error '%U'", format_unformat_error, i);
14700           return -99;
14701         }
14702     }
14703
14704   M (IPSEC_SA_SET_KEY, mp);
14705
14706   mp->sa_id = ntohl (sa_id);
14707   mp->crypto_key_length = vec_len (ck);
14708   mp->integrity_key_length = vec_len (ik);
14709
14710   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14711     mp->crypto_key_length = sizeof (mp->crypto_key);
14712
14713   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14714     mp->integrity_key_length = sizeof (mp->integrity_key);
14715
14716   if (ck)
14717     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14718   if (ik)
14719     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14720
14721   S (mp);
14722   W (ret);
14723   return ret;
14724 }
14725
14726 static int
14727 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14728 {
14729   unformat_input_t *i = vam->input;
14730   vl_api_ipsec_tunnel_if_add_del_t *mp;
14731   u32 local_spi = 0, remote_spi = 0;
14732   u32 crypto_alg = 0, integ_alg = 0;
14733   u8 *lck = NULL, *rck = NULL;
14734   u8 *lik = NULL, *rik = NULL;
14735   ip4_address_t local_ip = { {0} };
14736   ip4_address_t remote_ip = { {0} };
14737   u8 is_add = 1;
14738   u8 esn = 0;
14739   u8 anti_replay = 0;
14740   int ret;
14741
14742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14743     {
14744       if (unformat (i, "del"))
14745         is_add = 0;
14746       else if (unformat (i, "esn"))
14747         esn = 1;
14748       else if (unformat (i, "anti_replay"))
14749         anti_replay = 1;
14750       else if (unformat (i, "local_spi %d", &local_spi))
14751         ;
14752       else if (unformat (i, "remote_spi %d", &remote_spi))
14753         ;
14754       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14755         ;
14756       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14757         ;
14758       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14759         ;
14760       else
14761         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14762         ;
14763       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14764         ;
14765       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14766         ;
14767       else
14768         if (unformat
14769             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14770         {
14771           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14772               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14773             {
14774               errmsg ("unsupported crypto-alg: '%U'\n",
14775                       format_ipsec_crypto_alg, crypto_alg);
14776               return -99;
14777             }
14778         }
14779       else
14780         if (unformat
14781             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14782         {
14783           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14784               integ_alg >= IPSEC_INTEG_N_ALG)
14785             {
14786               errmsg ("unsupported integ-alg: '%U'\n",
14787                       format_ipsec_integ_alg, integ_alg);
14788               return -99;
14789             }
14790         }
14791       else
14792         {
14793           errmsg ("parse error '%U'\n", format_unformat_error, i);
14794           return -99;
14795         }
14796     }
14797
14798   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14799
14800   mp->is_add = is_add;
14801   mp->esn = esn;
14802   mp->anti_replay = anti_replay;
14803
14804   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14805   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14806
14807   mp->local_spi = htonl (local_spi);
14808   mp->remote_spi = htonl (remote_spi);
14809   mp->crypto_alg = (u8) crypto_alg;
14810
14811   mp->local_crypto_key_len = 0;
14812   if (lck)
14813     {
14814       mp->local_crypto_key_len = vec_len (lck);
14815       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14816         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14817       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14818     }
14819
14820   mp->remote_crypto_key_len = 0;
14821   if (rck)
14822     {
14823       mp->remote_crypto_key_len = vec_len (rck);
14824       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14825         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14826       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14827     }
14828
14829   mp->integ_alg = (u8) integ_alg;
14830
14831   mp->local_integ_key_len = 0;
14832   if (lik)
14833     {
14834       mp->local_integ_key_len = vec_len (lik);
14835       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14836         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14837       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14838     }
14839
14840   mp->remote_integ_key_len = 0;
14841   if (rik)
14842     {
14843       mp->remote_integ_key_len = vec_len (rik);
14844       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14845         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14846       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14847     }
14848
14849   S (mp);
14850   W (ret);
14851   return ret;
14852 }
14853
14854 static void
14855 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14856 {
14857   vat_main_t *vam = &vat_main;
14858
14859   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14860          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14861          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14862          "tunnel_src_addr %U tunnel_dst_addr %U "
14863          "salt %u seq_outbound %lu last_seq_inbound %lu "
14864          "replay_window %lu total_data_size %lu\n",
14865          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14866          mp->protocol,
14867          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14868          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14869          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14870          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14871          mp->tunnel_src_addr,
14872          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14873          mp->tunnel_dst_addr,
14874          ntohl (mp->salt),
14875          clib_net_to_host_u64 (mp->seq_outbound),
14876          clib_net_to_host_u64 (mp->last_seq_inbound),
14877          clib_net_to_host_u64 (mp->replay_window),
14878          clib_net_to_host_u64 (mp->total_data_size));
14879 }
14880
14881 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14882 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14883
14884 static void vl_api_ipsec_sa_details_t_handler_json
14885   (vl_api_ipsec_sa_details_t * mp)
14886 {
14887   vat_main_t *vam = &vat_main;
14888   vat_json_node_t *node = NULL;
14889   struct in_addr src_ip4, dst_ip4;
14890   struct in6_addr src_ip6, dst_ip6;
14891
14892   if (VAT_JSON_ARRAY != vam->json_tree.type)
14893     {
14894       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14895       vat_json_init_array (&vam->json_tree);
14896     }
14897   node = vat_json_array_add (&vam->json_tree);
14898
14899   vat_json_init_object (node);
14900   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14901   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14902   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14903   vat_json_object_add_uint (node, "proto", mp->protocol);
14904   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14905   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14906   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14907   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14908   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14909   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14910   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14911                              mp->crypto_key_len);
14912   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14913                              mp->integ_key_len);
14914   if (mp->is_tunnel_ip6)
14915     {
14916       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14917       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14918       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14919       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14920     }
14921   else
14922     {
14923       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14924       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14925       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14926       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14927     }
14928   vat_json_object_add_uint (node, "replay_window",
14929                             clib_net_to_host_u64 (mp->replay_window));
14930   vat_json_object_add_uint (node, "total_data_size",
14931                             clib_net_to_host_u64 (mp->total_data_size));
14932
14933 }
14934
14935 static int
14936 api_ipsec_sa_dump (vat_main_t * vam)
14937 {
14938   unformat_input_t *i = vam->input;
14939   vl_api_ipsec_sa_dump_t *mp;
14940   vl_api_control_ping_t *mp_ping;
14941   u32 sa_id = ~0;
14942   int ret;
14943
14944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14945     {
14946       if (unformat (i, "sa_id %d", &sa_id))
14947         ;
14948       else
14949         {
14950           clib_warning ("parse error '%U'", format_unformat_error, i);
14951           return -99;
14952         }
14953     }
14954
14955   M (IPSEC_SA_DUMP, mp);
14956
14957   mp->sa_id = ntohl (sa_id);
14958
14959   S (mp);
14960
14961   /* Use a control ping for synchronization */
14962   M (CONTROL_PING, mp_ping);
14963   S (mp_ping);
14964
14965   W (ret);
14966   return ret;
14967 }
14968
14969 static int
14970 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14971 {
14972   unformat_input_t *i = vam->input;
14973   vl_api_ipsec_tunnel_if_set_key_t *mp;
14974   u32 sw_if_index = ~0;
14975   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14976   u8 *key = 0;
14977   u32 alg = ~0;
14978   int ret;
14979
14980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14981     {
14982       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14983         ;
14984       else
14985         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14986         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14987       else
14988         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14989         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14990       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14991         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14992       else
14993         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14994         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14995       else if (unformat (i, "%U", unformat_hex_string, &key))
14996         ;
14997       else
14998         {
14999           clib_warning ("parse error '%U'", format_unformat_error, i);
15000           return -99;
15001         }
15002     }
15003
15004   if (sw_if_index == ~0)
15005     {
15006       errmsg ("interface must be specified");
15007       return -99;
15008     }
15009
15010   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15011     {
15012       errmsg ("key type must be specified");
15013       return -99;
15014     }
15015
15016   if (alg == ~0)
15017     {
15018       errmsg ("algorithm must be specified");
15019       return -99;
15020     }
15021
15022   if (vec_len (key) == 0)
15023     {
15024       errmsg ("key must be specified");
15025       return -99;
15026     }
15027
15028   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15029
15030   mp->sw_if_index = htonl (sw_if_index);
15031   mp->alg = alg;
15032   mp->key_type = key_type;
15033   mp->key_len = vec_len (key);
15034   clib_memcpy (mp->key, key, vec_len (key));
15035
15036   S (mp);
15037   W (ret);
15038
15039   return ret;
15040 }
15041
15042 static int
15043 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15044 {
15045   unformat_input_t *i = vam->input;
15046   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15047   u32 sw_if_index = ~0;
15048   u32 sa_id = ~0;
15049   u8 is_outbound = (u8) ~ 0;
15050   int ret;
15051
15052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15053     {
15054       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15055         ;
15056       else if (unformat (i, "sa_id %d", &sa_id))
15057         ;
15058       else if (unformat (i, "outbound"))
15059         is_outbound = 1;
15060       else if (unformat (i, "inbound"))
15061         is_outbound = 0;
15062       else
15063         {
15064           clib_warning ("parse error '%U'", format_unformat_error, i);
15065           return -99;
15066         }
15067     }
15068
15069   if (sw_if_index == ~0)
15070     {
15071       errmsg ("interface must be specified");
15072       return -99;
15073     }
15074
15075   if (sa_id == ~0)
15076     {
15077       errmsg ("SA ID must be specified");
15078       return -99;
15079     }
15080
15081   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15082
15083   mp->sw_if_index = htonl (sw_if_index);
15084   mp->sa_id = htonl (sa_id);
15085   mp->is_outbound = is_outbound;
15086
15087   S (mp);
15088   W (ret);
15089
15090   return ret;
15091 }
15092
15093 static int
15094 api_ikev2_profile_add_del (vat_main_t * vam)
15095 {
15096   unformat_input_t *i = vam->input;
15097   vl_api_ikev2_profile_add_del_t *mp;
15098   u8 is_add = 1;
15099   u8 *name = 0;
15100   int ret;
15101
15102   const char *valid_chars = "a-zA-Z0-9_";
15103
15104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15105     {
15106       if (unformat (i, "del"))
15107         is_add = 0;
15108       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15109         vec_add1 (name, 0);
15110       else
15111         {
15112           errmsg ("parse error '%U'", format_unformat_error, i);
15113           return -99;
15114         }
15115     }
15116
15117   if (!vec_len (name))
15118     {
15119       errmsg ("profile name must be specified");
15120       return -99;
15121     }
15122
15123   if (vec_len (name) > 64)
15124     {
15125       errmsg ("profile name too long");
15126       return -99;
15127     }
15128
15129   M (IKEV2_PROFILE_ADD_DEL, mp);
15130
15131   clib_memcpy (mp->name, name, vec_len (name));
15132   mp->is_add = is_add;
15133   vec_free (name);
15134
15135   S (mp);
15136   W (ret);
15137   return ret;
15138 }
15139
15140 static int
15141 api_ikev2_profile_set_auth (vat_main_t * vam)
15142 {
15143   unformat_input_t *i = vam->input;
15144   vl_api_ikev2_profile_set_auth_t *mp;
15145   u8 *name = 0;
15146   u8 *data = 0;
15147   u32 auth_method = 0;
15148   u8 is_hex = 0;
15149   int ret;
15150
15151   const char *valid_chars = "a-zA-Z0-9_";
15152
15153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15154     {
15155       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15156         vec_add1 (name, 0);
15157       else if (unformat (i, "auth_method %U",
15158                          unformat_ikev2_auth_method, &auth_method))
15159         ;
15160       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15161         is_hex = 1;
15162       else if (unformat (i, "auth_data %v", &data))
15163         ;
15164       else
15165         {
15166           errmsg ("parse error '%U'", format_unformat_error, i);
15167           return -99;
15168         }
15169     }
15170
15171   if (!vec_len (name))
15172     {
15173       errmsg ("profile name must be specified");
15174       return -99;
15175     }
15176
15177   if (vec_len (name) > 64)
15178     {
15179       errmsg ("profile name too long");
15180       return -99;
15181     }
15182
15183   if (!vec_len (data))
15184     {
15185       errmsg ("auth_data must be specified");
15186       return -99;
15187     }
15188
15189   if (!auth_method)
15190     {
15191       errmsg ("auth_method must be specified");
15192       return -99;
15193     }
15194
15195   M (IKEV2_PROFILE_SET_AUTH, mp);
15196
15197   mp->is_hex = is_hex;
15198   mp->auth_method = (u8) auth_method;
15199   mp->data_len = vec_len (data);
15200   clib_memcpy (mp->name, name, vec_len (name));
15201   clib_memcpy (mp->data, data, vec_len (data));
15202   vec_free (name);
15203   vec_free (data);
15204
15205   S (mp);
15206   W (ret);
15207   return ret;
15208 }
15209
15210 static int
15211 api_ikev2_profile_set_id (vat_main_t * vam)
15212 {
15213   unformat_input_t *i = vam->input;
15214   vl_api_ikev2_profile_set_id_t *mp;
15215   u8 *name = 0;
15216   u8 *data = 0;
15217   u8 is_local = 0;
15218   u32 id_type = 0;
15219   ip4_address_t ip4;
15220   int ret;
15221
15222   const char *valid_chars = "a-zA-Z0-9_";
15223
15224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15225     {
15226       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15227         vec_add1 (name, 0);
15228       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15229         ;
15230       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15231         {
15232           data = vec_new (u8, 4);
15233           clib_memcpy (data, ip4.as_u8, 4);
15234         }
15235       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15236         ;
15237       else if (unformat (i, "id_data %v", &data))
15238         ;
15239       else if (unformat (i, "local"))
15240         is_local = 1;
15241       else if (unformat (i, "remote"))
15242         is_local = 0;
15243       else
15244         {
15245           errmsg ("parse error '%U'", format_unformat_error, i);
15246           return -99;
15247         }
15248     }
15249
15250   if (!vec_len (name))
15251     {
15252       errmsg ("profile name must be specified");
15253       return -99;
15254     }
15255
15256   if (vec_len (name) > 64)
15257     {
15258       errmsg ("profile name too long");
15259       return -99;
15260     }
15261
15262   if (!vec_len (data))
15263     {
15264       errmsg ("id_data must be specified");
15265       return -99;
15266     }
15267
15268   if (!id_type)
15269     {
15270       errmsg ("id_type must be specified");
15271       return -99;
15272     }
15273
15274   M (IKEV2_PROFILE_SET_ID, mp);
15275
15276   mp->is_local = is_local;
15277   mp->id_type = (u8) id_type;
15278   mp->data_len = vec_len (data);
15279   clib_memcpy (mp->name, name, vec_len (name));
15280   clib_memcpy (mp->data, data, vec_len (data));
15281   vec_free (name);
15282   vec_free (data);
15283
15284   S (mp);
15285   W (ret);
15286   return ret;
15287 }
15288
15289 static int
15290 api_ikev2_profile_set_ts (vat_main_t * vam)
15291 {
15292   unformat_input_t *i = vam->input;
15293   vl_api_ikev2_profile_set_ts_t *mp;
15294   u8 *name = 0;
15295   u8 is_local = 0;
15296   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15297   ip4_address_t start_addr, end_addr;
15298
15299   const char *valid_chars = "a-zA-Z0-9_";
15300   int ret;
15301
15302   start_addr.as_u32 = 0;
15303   end_addr.as_u32 = (u32) ~ 0;
15304
15305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15306     {
15307       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15308         vec_add1 (name, 0);
15309       else if (unformat (i, "protocol %d", &proto))
15310         ;
15311       else if (unformat (i, "start_port %d", &start_port))
15312         ;
15313       else if (unformat (i, "end_port %d", &end_port))
15314         ;
15315       else
15316         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15317         ;
15318       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15319         ;
15320       else if (unformat (i, "local"))
15321         is_local = 1;
15322       else if (unformat (i, "remote"))
15323         is_local = 0;
15324       else
15325         {
15326           errmsg ("parse error '%U'", format_unformat_error, i);
15327           return -99;
15328         }
15329     }
15330
15331   if (!vec_len (name))
15332     {
15333       errmsg ("profile name must be specified");
15334       return -99;
15335     }
15336
15337   if (vec_len (name) > 64)
15338     {
15339       errmsg ("profile name too long");
15340       return -99;
15341     }
15342
15343   M (IKEV2_PROFILE_SET_TS, mp);
15344
15345   mp->is_local = is_local;
15346   mp->proto = (u8) proto;
15347   mp->start_port = (u16) start_port;
15348   mp->end_port = (u16) end_port;
15349   mp->start_addr = start_addr.as_u32;
15350   mp->end_addr = end_addr.as_u32;
15351   clib_memcpy (mp->name, name, vec_len (name));
15352   vec_free (name);
15353
15354   S (mp);
15355   W (ret);
15356   return ret;
15357 }
15358
15359 static int
15360 api_ikev2_set_local_key (vat_main_t * vam)
15361 {
15362   unformat_input_t *i = vam->input;
15363   vl_api_ikev2_set_local_key_t *mp;
15364   u8 *file = 0;
15365   int ret;
15366
15367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15368     {
15369       if (unformat (i, "file %v", &file))
15370         vec_add1 (file, 0);
15371       else
15372         {
15373           errmsg ("parse error '%U'", format_unformat_error, i);
15374           return -99;
15375         }
15376     }
15377
15378   if (!vec_len (file))
15379     {
15380       errmsg ("RSA key file must be specified");
15381       return -99;
15382     }
15383
15384   if (vec_len (file) > 256)
15385     {
15386       errmsg ("file name too long");
15387       return -99;
15388     }
15389
15390   M (IKEV2_SET_LOCAL_KEY, mp);
15391
15392   clib_memcpy (mp->key_file, file, vec_len (file));
15393   vec_free (file);
15394
15395   S (mp);
15396   W (ret);
15397   return ret;
15398 }
15399
15400 static int
15401 api_ikev2_set_responder (vat_main_t * vam)
15402 {
15403   unformat_input_t *i = vam->input;
15404   vl_api_ikev2_set_responder_t *mp;
15405   int ret;
15406   u8 *name = 0;
15407   u32 sw_if_index = ~0;
15408   ip4_address_t address;
15409
15410   const char *valid_chars = "a-zA-Z0-9_";
15411
15412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15413     {
15414       if (unformat
15415           (i, "%U interface %d address %U", unformat_token, valid_chars,
15416            &name, &sw_if_index, unformat_ip4_address, &address))
15417         vec_add1 (name, 0);
15418       else
15419         {
15420           errmsg ("parse error '%U'", format_unformat_error, i);
15421           return -99;
15422         }
15423     }
15424
15425   if (!vec_len (name))
15426     {
15427       errmsg ("profile name must be specified");
15428       return -99;
15429     }
15430
15431   if (vec_len (name) > 64)
15432     {
15433       errmsg ("profile name too long");
15434       return -99;
15435     }
15436
15437   M (IKEV2_SET_RESPONDER, mp);
15438
15439   clib_memcpy (mp->name, name, vec_len (name));
15440   vec_free (name);
15441
15442   mp->sw_if_index = sw_if_index;
15443   clib_memcpy (mp->address, &address, sizeof (address));
15444
15445   S (mp);
15446   W (ret);
15447   return ret;
15448 }
15449
15450 static int
15451 api_ikev2_set_ike_transforms (vat_main_t * vam)
15452 {
15453   unformat_input_t *i = vam->input;
15454   vl_api_ikev2_set_ike_transforms_t *mp;
15455   int ret;
15456   u8 *name = 0;
15457   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15458
15459   const char *valid_chars = "a-zA-Z0-9_";
15460
15461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15462     {
15463       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15464                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15465         vec_add1 (name, 0);
15466       else
15467         {
15468           errmsg ("parse error '%U'", format_unformat_error, i);
15469           return -99;
15470         }
15471     }
15472
15473   if (!vec_len (name))
15474     {
15475       errmsg ("profile name must be specified");
15476       return -99;
15477     }
15478
15479   if (vec_len (name) > 64)
15480     {
15481       errmsg ("profile name too long");
15482       return -99;
15483     }
15484
15485   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15486
15487   clib_memcpy (mp->name, name, vec_len (name));
15488   vec_free (name);
15489   mp->crypto_alg = crypto_alg;
15490   mp->crypto_key_size = crypto_key_size;
15491   mp->integ_alg = integ_alg;
15492   mp->dh_group = dh_group;
15493
15494   S (mp);
15495   W (ret);
15496   return ret;
15497 }
15498
15499
15500 static int
15501 api_ikev2_set_esp_transforms (vat_main_t * vam)
15502 {
15503   unformat_input_t *i = vam->input;
15504   vl_api_ikev2_set_esp_transforms_t *mp;
15505   int ret;
15506   u8 *name = 0;
15507   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15508
15509   const char *valid_chars = "a-zA-Z0-9_";
15510
15511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15512     {
15513       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15514                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15515         vec_add1 (name, 0);
15516       else
15517         {
15518           errmsg ("parse error '%U'", format_unformat_error, i);
15519           return -99;
15520         }
15521     }
15522
15523   if (!vec_len (name))
15524     {
15525       errmsg ("profile name must be specified");
15526       return -99;
15527     }
15528
15529   if (vec_len (name) > 64)
15530     {
15531       errmsg ("profile name too long");
15532       return -99;
15533     }
15534
15535   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15536
15537   clib_memcpy (mp->name, name, vec_len (name));
15538   vec_free (name);
15539   mp->crypto_alg = crypto_alg;
15540   mp->crypto_key_size = crypto_key_size;
15541   mp->integ_alg = integ_alg;
15542   mp->dh_group = dh_group;
15543
15544   S (mp);
15545   W (ret);
15546   return ret;
15547 }
15548
15549 static int
15550 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15551 {
15552   unformat_input_t *i = vam->input;
15553   vl_api_ikev2_set_sa_lifetime_t *mp;
15554   int ret;
15555   u8 *name = 0;
15556   u64 lifetime, lifetime_maxdata;
15557   u32 lifetime_jitter, handover;
15558
15559   const char *valid_chars = "a-zA-Z0-9_";
15560
15561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15562     {
15563       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15564                     &lifetime, &lifetime_jitter, &handover,
15565                     &lifetime_maxdata))
15566         vec_add1 (name, 0);
15567       else
15568         {
15569           errmsg ("parse error '%U'", format_unformat_error, i);
15570           return -99;
15571         }
15572     }
15573
15574   if (!vec_len (name))
15575     {
15576       errmsg ("profile name must be specified");
15577       return -99;
15578     }
15579
15580   if (vec_len (name) > 64)
15581     {
15582       errmsg ("profile name too long");
15583       return -99;
15584     }
15585
15586   M (IKEV2_SET_SA_LIFETIME, mp);
15587
15588   clib_memcpy (mp->name, name, vec_len (name));
15589   vec_free (name);
15590   mp->lifetime = lifetime;
15591   mp->lifetime_jitter = lifetime_jitter;
15592   mp->handover = handover;
15593   mp->lifetime_maxdata = lifetime_maxdata;
15594
15595   S (mp);
15596   W (ret);
15597   return ret;
15598 }
15599
15600 static int
15601 api_ikev2_initiate_sa_init (vat_main_t * vam)
15602 {
15603   unformat_input_t *i = vam->input;
15604   vl_api_ikev2_initiate_sa_init_t *mp;
15605   int ret;
15606   u8 *name = 0;
15607
15608   const char *valid_chars = "a-zA-Z0-9_";
15609
15610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15611     {
15612       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15613         vec_add1 (name, 0);
15614       else
15615         {
15616           errmsg ("parse error '%U'", format_unformat_error, i);
15617           return -99;
15618         }
15619     }
15620
15621   if (!vec_len (name))
15622     {
15623       errmsg ("profile name must be specified");
15624       return -99;
15625     }
15626
15627   if (vec_len (name) > 64)
15628     {
15629       errmsg ("profile name too long");
15630       return -99;
15631     }
15632
15633   M (IKEV2_INITIATE_SA_INIT, mp);
15634
15635   clib_memcpy (mp->name, name, vec_len (name));
15636   vec_free (name);
15637
15638   S (mp);
15639   W (ret);
15640   return ret;
15641 }
15642
15643 static int
15644 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15645 {
15646   unformat_input_t *i = vam->input;
15647   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15648   int ret;
15649   u64 ispi;
15650
15651
15652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15653     {
15654       if (unformat (i, "%lx", &ispi))
15655         ;
15656       else
15657         {
15658           errmsg ("parse error '%U'", format_unformat_error, i);
15659           return -99;
15660         }
15661     }
15662
15663   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15664
15665   mp->ispi = ispi;
15666
15667   S (mp);
15668   W (ret);
15669   return ret;
15670 }
15671
15672 static int
15673 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15674 {
15675   unformat_input_t *i = vam->input;
15676   vl_api_ikev2_initiate_del_child_sa_t *mp;
15677   int ret;
15678   u32 ispi;
15679
15680
15681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15682     {
15683       if (unformat (i, "%x", &ispi))
15684         ;
15685       else
15686         {
15687           errmsg ("parse error '%U'", format_unformat_error, i);
15688           return -99;
15689         }
15690     }
15691
15692   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15693
15694   mp->ispi = ispi;
15695
15696   S (mp);
15697   W (ret);
15698   return ret;
15699 }
15700
15701 static int
15702 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15703 {
15704   unformat_input_t *i = vam->input;
15705   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15706   int ret;
15707   u32 ispi;
15708
15709
15710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15711     {
15712       if (unformat (i, "%x", &ispi))
15713         ;
15714       else
15715         {
15716           errmsg ("parse error '%U'", format_unformat_error, i);
15717           return -99;
15718         }
15719     }
15720
15721   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15722
15723   mp->ispi = ispi;
15724
15725   S (mp);
15726   W (ret);
15727   return ret;
15728 }
15729
15730 /*
15731  * MAP
15732  */
15733 static int
15734 api_map_add_domain (vat_main_t * vam)
15735 {
15736   unformat_input_t *i = vam->input;
15737   vl_api_map_add_domain_t *mp;
15738
15739   ip4_address_t ip4_prefix;
15740   ip6_address_t ip6_prefix;
15741   ip6_address_t ip6_src;
15742   u32 num_m_args = 0;
15743   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15744     0, psid_length = 0;
15745   u8 is_translation = 0;
15746   u32 mtu = 0;
15747   u32 ip6_src_len = 128;
15748   int ret;
15749
15750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15751     {
15752       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15753                     &ip4_prefix, &ip4_prefix_len))
15754         num_m_args++;
15755       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15756                          &ip6_prefix, &ip6_prefix_len))
15757         num_m_args++;
15758       else
15759         if (unformat
15760             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15761              &ip6_src_len))
15762         num_m_args++;
15763       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15764         num_m_args++;
15765       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15766         num_m_args++;
15767       else if (unformat (i, "psid-offset %d", &psid_offset))
15768         num_m_args++;
15769       else if (unformat (i, "psid-len %d", &psid_length))
15770         num_m_args++;
15771       else if (unformat (i, "mtu %d", &mtu))
15772         num_m_args++;
15773       else if (unformat (i, "map-t"))
15774         is_translation = 1;
15775       else
15776         {
15777           clib_warning ("parse error '%U'", format_unformat_error, i);
15778           return -99;
15779         }
15780     }
15781
15782   if (num_m_args < 3)
15783     {
15784       errmsg ("mandatory argument(s) missing");
15785       return -99;
15786     }
15787
15788   /* Construct the API message */
15789   M (MAP_ADD_DOMAIN, mp);
15790
15791   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15792   mp->ip4_prefix_len = ip4_prefix_len;
15793
15794   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15795   mp->ip6_prefix_len = ip6_prefix_len;
15796
15797   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15798   mp->ip6_src_prefix_len = ip6_src_len;
15799
15800   mp->ea_bits_len = ea_bits_len;
15801   mp->psid_offset = psid_offset;
15802   mp->psid_length = psid_length;
15803   mp->is_translation = is_translation;
15804   mp->mtu = htons (mtu);
15805
15806   /* send it... */
15807   S (mp);
15808
15809   /* Wait for a reply, return good/bad news  */
15810   W (ret);
15811   return ret;
15812 }
15813
15814 static int
15815 api_map_del_domain (vat_main_t * vam)
15816 {
15817   unformat_input_t *i = vam->input;
15818   vl_api_map_del_domain_t *mp;
15819
15820   u32 num_m_args = 0;
15821   u32 index;
15822   int ret;
15823
15824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15825     {
15826       if (unformat (i, "index %d", &index))
15827         num_m_args++;
15828       else
15829         {
15830           clib_warning ("parse error '%U'", format_unformat_error, i);
15831           return -99;
15832         }
15833     }
15834
15835   if (num_m_args != 1)
15836     {
15837       errmsg ("mandatory argument(s) missing");
15838       return -99;
15839     }
15840
15841   /* Construct the API message */
15842   M (MAP_DEL_DOMAIN, mp);
15843
15844   mp->index = ntohl (index);
15845
15846   /* send it... */
15847   S (mp);
15848
15849   /* Wait for a reply, return good/bad news  */
15850   W (ret);
15851   return ret;
15852 }
15853
15854 static int
15855 api_map_add_del_rule (vat_main_t * vam)
15856 {
15857   unformat_input_t *i = vam->input;
15858   vl_api_map_add_del_rule_t *mp;
15859   u8 is_add = 1;
15860   ip6_address_t ip6_dst;
15861   u32 num_m_args = 0, index, psid = 0;
15862   int ret;
15863
15864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15865     {
15866       if (unformat (i, "index %d", &index))
15867         num_m_args++;
15868       else if (unformat (i, "psid %d", &psid))
15869         num_m_args++;
15870       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15871         num_m_args++;
15872       else if (unformat (i, "del"))
15873         {
15874           is_add = 0;
15875         }
15876       else
15877         {
15878           clib_warning ("parse error '%U'", format_unformat_error, i);
15879           return -99;
15880         }
15881     }
15882
15883   /* Construct the API message */
15884   M (MAP_ADD_DEL_RULE, mp);
15885
15886   mp->index = ntohl (index);
15887   mp->is_add = is_add;
15888   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15889   mp->psid = ntohs (psid);
15890
15891   /* send it... */
15892   S (mp);
15893
15894   /* Wait for a reply, return good/bad news  */
15895   W (ret);
15896   return ret;
15897 }
15898
15899 static int
15900 api_map_domain_dump (vat_main_t * vam)
15901 {
15902   vl_api_map_domain_dump_t *mp;
15903   vl_api_control_ping_t *mp_ping;
15904   int ret;
15905
15906   /* Construct the API message */
15907   M (MAP_DOMAIN_DUMP, mp);
15908
15909   /* send it... */
15910   S (mp);
15911
15912   /* Use a control ping for synchronization */
15913   MPING (CONTROL_PING, mp_ping);
15914   S (mp_ping);
15915
15916   W (ret);
15917   return ret;
15918 }
15919
15920 static int
15921 api_map_rule_dump (vat_main_t * vam)
15922 {
15923   unformat_input_t *i = vam->input;
15924   vl_api_map_rule_dump_t *mp;
15925   vl_api_control_ping_t *mp_ping;
15926   u32 domain_index = ~0;
15927   int ret;
15928
15929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15930     {
15931       if (unformat (i, "index %u", &domain_index))
15932         ;
15933       else
15934         break;
15935     }
15936
15937   if (domain_index == ~0)
15938     {
15939       clib_warning ("parse error: domain index expected");
15940       return -99;
15941     }
15942
15943   /* Construct the API message */
15944   M (MAP_RULE_DUMP, mp);
15945
15946   mp->domain_index = htonl (domain_index);
15947
15948   /* send it... */
15949   S (mp);
15950
15951   /* Use a control ping for synchronization */
15952   MPING (CONTROL_PING, mp_ping);
15953   S (mp_ping);
15954
15955   W (ret);
15956   return ret;
15957 }
15958
15959 static void vl_api_map_add_domain_reply_t_handler
15960   (vl_api_map_add_domain_reply_t * mp)
15961 {
15962   vat_main_t *vam = &vat_main;
15963   i32 retval = ntohl (mp->retval);
15964
15965   if (vam->async_mode)
15966     {
15967       vam->async_errors += (retval < 0);
15968     }
15969   else
15970     {
15971       vam->retval = retval;
15972       vam->result_ready = 1;
15973     }
15974 }
15975
15976 static void vl_api_map_add_domain_reply_t_handler_json
15977   (vl_api_map_add_domain_reply_t * mp)
15978 {
15979   vat_main_t *vam = &vat_main;
15980   vat_json_node_t node;
15981
15982   vat_json_init_object (&node);
15983   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15984   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15985
15986   vat_json_print (vam->ofp, &node);
15987   vat_json_free (&node);
15988
15989   vam->retval = ntohl (mp->retval);
15990   vam->result_ready = 1;
15991 }
15992
15993 static int
15994 api_get_first_msg_id (vat_main_t * vam)
15995 {
15996   vl_api_get_first_msg_id_t *mp;
15997   unformat_input_t *i = vam->input;
15998   u8 *name;
15999   u8 name_set = 0;
16000   int ret;
16001
16002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16003     {
16004       if (unformat (i, "client %s", &name))
16005         name_set = 1;
16006       else
16007         break;
16008     }
16009
16010   if (name_set == 0)
16011     {
16012       errmsg ("missing client name");
16013       return -99;
16014     }
16015   vec_add1 (name, 0);
16016
16017   if (vec_len (name) > 63)
16018     {
16019       errmsg ("client name too long");
16020       return -99;
16021     }
16022
16023   M (GET_FIRST_MSG_ID, mp);
16024   clib_memcpy (mp->name, name, vec_len (name));
16025   S (mp);
16026   W (ret);
16027   return ret;
16028 }
16029
16030 static int
16031 api_cop_interface_enable_disable (vat_main_t * vam)
16032 {
16033   unformat_input_t *line_input = vam->input;
16034   vl_api_cop_interface_enable_disable_t *mp;
16035   u32 sw_if_index = ~0;
16036   u8 enable_disable = 1;
16037   int ret;
16038
16039   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16040     {
16041       if (unformat (line_input, "disable"))
16042         enable_disable = 0;
16043       if (unformat (line_input, "enable"))
16044         enable_disable = 1;
16045       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16046                          vam, &sw_if_index))
16047         ;
16048       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16049         ;
16050       else
16051         break;
16052     }
16053
16054   if (sw_if_index == ~0)
16055     {
16056       errmsg ("missing interface name or sw_if_index");
16057       return -99;
16058     }
16059
16060   /* Construct the API message */
16061   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16062   mp->sw_if_index = ntohl (sw_if_index);
16063   mp->enable_disable = enable_disable;
16064
16065   /* send it... */
16066   S (mp);
16067   /* Wait for the reply */
16068   W (ret);
16069   return ret;
16070 }
16071
16072 static int
16073 api_cop_whitelist_enable_disable (vat_main_t * vam)
16074 {
16075   unformat_input_t *line_input = vam->input;
16076   vl_api_cop_whitelist_enable_disable_t *mp;
16077   u32 sw_if_index = ~0;
16078   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16079   u32 fib_id = 0;
16080   int ret;
16081
16082   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16083     {
16084       if (unformat (line_input, "ip4"))
16085         ip4 = 1;
16086       else if (unformat (line_input, "ip6"))
16087         ip6 = 1;
16088       else if (unformat (line_input, "default"))
16089         default_cop = 1;
16090       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16091                          vam, &sw_if_index))
16092         ;
16093       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16094         ;
16095       else if (unformat (line_input, "fib-id %d", &fib_id))
16096         ;
16097       else
16098         break;
16099     }
16100
16101   if (sw_if_index == ~0)
16102     {
16103       errmsg ("missing interface name or sw_if_index");
16104       return -99;
16105     }
16106
16107   /* Construct the API message */
16108   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16109   mp->sw_if_index = ntohl (sw_if_index);
16110   mp->fib_id = ntohl (fib_id);
16111   mp->ip4 = ip4;
16112   mp->ip6 = ip6;
16113   mp->default_cop = default_cop;
16114
16115   /* send it... */
16116   S (mp);
16117   /* Wait for the reply */
16118   W (ret);
16119   return ret;
16120 }
16121
16122 static int
16123 api_get_node_graph (vat_main_t * vam)
16124 {
16125   vl_api_get_node_graph_t *mp;
16126   int ret;
16127
16128   M (GET_NODE_GRAPH, mp);
16129
16130   /* send it... */
16131   S (mp);
16132   /* Wait for the reply */
16133   W (ret);
16134   return ret;
16135 }
16136
16137 /* *INDENT-OFF* */
16138 /** Used for parsing LISP eids */
16139 typedef CLIB_PACKED(struct{
16140   u8 addr[16];   /**< eid address */
16141   u32 len;       /**< prefix length if IP */
16142   u8 type;      /**< type of eid */
16143 }) lisp_eid_vat_t;
16144 /* *INDENT-ON* */
16145
16146 static uword
16147 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16148 {
16149   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16150
16151   memset (a, 0, sizeof (a[0]));
16152
16153   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16154     {
16155       a->type = 0;              /* ipv4 type */
16156     }
16157   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16158     {
16159       a->type = 1;              /* ipv6 type */
16160     }
16161   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16162     {
16163       a->type = 2;              /* mac type */
16164     }
16165   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16166     {
16167       a->type = 3;              /* NSH type */
16168       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16169       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16170     }
16171   else
16172     {
16173       return 0;
16174     }
16175
16176   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16177     {
16178       return 0;
16179     }
16180
16181   return 1;
16182 }
16183
16184 static int
16185 lisp_eid_size_vat (u8 type)
16186 {
16187   switch (type)
16188     {
16189     case 0:
16190       return 4;
16191     case 1:
16192       return 16;
16193     case 2:
16194       return 6;
16195     case 3:
16196       return 5;
16197     }
16198   return 0;
16199 }
16200
16201 static void
16202 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16203 {
16204   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16205 }
16206
16207 static int
16208 api_one_add_del_locator_set (vat_main_t * vam)
16209 {
16210   unformat_input_t *input = vam->input;
16211   vl_api_one_add_del_locator_set_t *mp;
16212   u8 is_add = 1;
16213   u8 *locator_set_name = NULL;
16214   u8 locator_set_name_set = 0;
16215   vl_api_local_locator_t locator, *locators = 0;
16216   u32 sw_if_index, priority, weight;
16217   u32 data_len = 0;
16218
16219   int ret;
16220   /* Parse args required to build the message */
16221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16222     {
16223       if (unformat (input, "del"))
16224         {
16225           is_add = 0;
16226         }
16227       else if (unformat (input, "locator-set %s", &locator_set_name))
16228         {
16229           locator_set_name_set = 1;
16230         }
16231       else if (unformat (input, "sw_if_index %u p %u w %u",
16232                          &sw_if_index, &priority, &weight))
16233         {
16234           locator.sw_if_index = htonl (sw_if_index);
16235           locator.priority = priority;
16236           locator.weight = weight;
16237           vec_add1 (locators, locator);
16238         }
16239       else
16240         if (unformat
16241             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16242              &sw_if_index, &priority, &weight))
16243         {
16244           locator.sw_if_index = htonl (sw_if_index);
16245           locator.priority = priority;
16246           locator.weight = weight;
16247           vec_add1 (locators, locator);
16248         }
16249       else
16250         break;
16251     }
16252
16253   if (locator_set_name_set == 0)
16254     {
16255       errmsg ("missing locator-set name");
16256       vec_free (locators);
16257       return -99;
16258     }
16259
16260   if (vec_len (locator_set_name) > 64)
16261     {
16262       errmsg ("locator-set name too long");
16263       vec_free (locator_set_name);
16264       vec_free (locators);
16265       return -99;
16266     }
16267   vec_add1 (locator_set_name, 0);
16268
16269   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16270
16271   /* Construct the API message */
16272   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16273
16274   mp->is_add = is_add;
16275   clib_memcpy (mp->locator_set_name, locator_set_name,
16276                vec_len (locator_set_name));
16277   vec_free (locator_set_name);
16278
16279   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16280   if (locators)
16281     clib_memcpy (mp->locators, locators, data_len);
16282   vec_free (locators);
16283
16284   /* send it... */
16285   S (mp);
16286
16287   /* Wait for a reply... */
16288   W (ret);
16289   return ret;
16290 }
16291
16292 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16293
16294 static int
16295 api_one_add_del_locator (vat_main_t * vam)
16296 {
16297   unformat_input_t *input = vam->input;
16298   vl_api_one_add_del_locator_t *mp;
16299   u32 tmp_if_index = ~0;
16300   u32 sw_if_index = ~0;
16301   u8 sw_if_index_set = 0;
16302   u8 sw_if_index_if_name_set = 0;
16303   u32 priority = ~0;
16304   u8 priority_set = 0;
16305   u32 weight = ~0;
16306   u8 weight_set = 0;
16307   u8 is_add = 1;
16308   u8 *locator_set_name = NULL;
16309   u8 locator_set_name_set = 0;
16310   int ret;
16311
16312   /* Parse args required to build the message */
16313   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16314     {
16315       if (unformat (input, "del"))
16316         {
16317           is_add = 0;
16318         }
16319       else if (unformat (input, "locator-set %s", &locator_set_name))
16320         {
16321           locator_set_name_set = 1;
16322         }
16323       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16324                          &tmp_if_index))
16325         {
16326           sw_if_index_if_name_set = 1;
16327           sw_if_index = tmp_if_index;
16328         }
16329       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16330         {
16331           sw_if_index_set = 1;
16332           sw_if_index = tmp_if_index;
16333         }
16334       else if (unformat (input, "p %d", &priority))
16335         {
16336           priority_set = 1;
16337         }
16338       else if (unformat (input, "w %d", &weight))
16339         {
16340           weight_set = 1;
16341         }
16342       else
16343         break;
16344     }
16345
16346   if (locator_set_name_set == 0)
16347     {
16348       errmsg ("missing locator-set name");
16349       return -99;
16350     }
16351
16352   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16353     {
16354       errmsg ("missing sw_if_index");
16355       vec_free (locator_set_name);
16356       return -99;
16357     }
16358
16359   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16360     {
16361       errmsg ("cannot use both params interface name and sw_if_index");
16362       vec_free (locator_set_name);
16363       return -99;
16364     }
16365
16366   if (priority_set == 0)
16367     {
16368       errmsg ("missing locator-set priority");
16369       vec_free (locator_set_name);
16370       return -99;
16371     }
16372
16373   if (weight_set == 0)
16374     {
16375       errmsg ("missing locator-set weight");
16376       vec_free (locator_set_name);
16377       return -99;
16378     }
16379
16380   if (vec_len (locator_set_name) > 64)
16381     {
16382       errmsg ("locator-set name too long");
16383       vec_free (locator_set_name);
16384       return -99;
16385     }
16386   vec_add1 (locator_set_name, 0);
16387
16388   /* Construct the API message */
16389   M (ONE_ADD_DEL_LOCATOR, mp);
16390
16391   mp->is_add = is_add;
16392   mp->sw_if_index = ntohl (sw_if_index);
16393   mp->priority = priority;
16394   mp->weight = weight;
16395   clib_memcpy (mp->locator_set_name, locator_set_name,
16396                vec_len (locator_set_name));
16397   vec_free (locator_set_name);
16398
16399   /* send it... */
16400   S (mp);
16401
16402   /* Wait for a reply... */
16403   W (ret);
16404   return ret;
16405 }
16406
16407 #define api_lisp_add_del_locator api_one_add_del_locator
16408
16409 uword
16410 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16411 {
16412   u32 *key_id = va_arg (*args, u32 *);
16413   u8 *s = 0;
16414
16415   if (unformat (input, "%s", &s))
16416     {
16417       if (!strcmp ((char *) s, "sha1"))
16418         key_id[0] = HMAC_SHA_1_96;
16419       else if (!strcmp ((char *) s, "sha256"))
16420         key_id[0] = HMAC_SHA_256_128;
16421       else
16422         {
16423           clib_warning ("invalid key_id: '%s'", s);
16424           key_id[0] = HMAC_NO_KEY;
16425         }
16426     }
16427   else
16428     return 0;
16429
16430   vec_free (s);
16431   return 1;
16432 }
16433
16434 static int
16435 api_one_add_del_local_eid (vat_main_t * vam)
16436 {
16437   unformat_input_t *input = vam->input;
16438   vl_api_one_add_del_local_eid_t *mp;
16439   u8 is_add = 1;
16440   u8 eid_set = 0;
16441   lisp_eid_vat_t _eid, *eid = &_eid;
16442   u8 *locator_set_name = 0;
16443   u8 locator_set_name_set = 0;
16444   u32 vni = 0;
16445   u16 key_id = 0;
16446   u8 *key = 0;
16447   int ret;
16448
16449   /* Parse args required to build the message */
16450   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16451     {
16452       if (unformat (input, "del"))
16453         {
16454           is_add = 0;
16455         }
16456       else if (unformat (input, "vni %d", &vni))
16457         {
16458           ;
16459         }
16460       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16461         {
16462           eid_set = 1;
16463         }
16464       else if (unformat (input, "locator-set %s", &locator_set_name))
16465         {
16466           locator_set_name_set = 1;
16467         }
16468       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16469         ;
16470       else if (unformat (input, "secret-key %_%v%_", &key))
16471         ;
16472       else
16473         break;
16474     }
16475
16476   if (locator_set_name_set == 0)
16477     {
16478       errmsg ("missing locator-set name");
16479       return -99;
16480     }
16481
16482   if (0 == eid_set)
16483     {
16484       errmsg ("EID address not set!");
16485       vec_free (locator_set_name);
16486       return -99;
16487     }
16488
16489   if (key && (0 == key_id))
16490     {
16491       errmsg ("invalid key_id!");
16492       return -99;
16493     }
16494
16495   if (vec_len (key) > 64)
16496     {
16497       errmsg ("key too long");
16498       vec_free (key);
16499       return -99;
16500     }
16501
16502   if (vec_len (locator_set_name) > 64)
16503     {
16504       errmsg ("locator-set name too long");
16505       vec_free (locator_set_name);
16506       return -99;
16507     }
16508   vec_add1 (locator_set_name, 0);
16509
16510   /* Construct the API message */
16511   M (ONE_ADD_DEL_LOCAL_EID, mp);
16512
16513   mp->is_add = is_add;
16514   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16515   mp->eid_type = eid->type;
16516   mp->prefix_len = eid->len;
16517   mp->vni = clib_host_to_net_u32 (vni);
16518   mp->key_id = clib_host_to_net_u16 (key_id);
16519   clib_memcpy (mp->locator_set_name, locator_set_name,
16520                vec_len (locator_set_name));
16521   clib_memcpy (mp->key, key, vec_len (key));
16522
16523   vec_free (locator_set_name);
16524   vec_free (key);
16525
16526   /* send it... */
16527   S (mp);
16528
16529   /* Wait for a reply... */
16530   W (ret);
16531   return ret;
16532 }
16533
16534 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16535
16536 static int
16537 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16538 {
16539   u32 dp_table = 0, vni = 0;;
16540   unformat_input_t *input = vam->input;
16541   vl_api_gpe_add_del_fwd_entry_t *mp;
16542   u8 is_add = 1;
16543   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16544   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16545   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16546   u32 action = ~0, w;
16547   ip4_address_t rmt_rloc4, lcl_rloc4;
16548   ip6_address_t rmt_rloc6, lcl_rloc6;
16549   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16550   int ret;
16551
16552   memset (&rloc, 0, sizeof (rloc));
16553
16554   /* Parse args required to build the message */
16555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16556     {
16557       if (unformat (input, "del"))
16558         is_add = 0;
16559       else if (unformat (input, "add"))
16560         is_add = 1;
16561       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16562         {
16563           rmt_eid_set = 1;
16564         }
16565       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16566         {
16567           lcl_eid_set = 1;
16568         }
16569       else if (unformat (input, "vrf %d", &dp_table))
16570         ;
16571       else if (unformat (input, "bd %d", &dp_table))
16572         ;
16573       else if (unformat (input, "vni %d", &vni))
16574         ;
16575       else if (unformat (input, "w %d", &w))
16576         {
16577           if (!curr_rloc)
16578             {
16579               errmsg ("No RLOC configured for setting priority/weight!");
16580               return -99;
16581             }
16582           curr_rloc->weight = w;
16583         }
16584       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16585                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16586         {
16587           rloc.is_ip4 = 1;
16588
16589           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16590           rloc.weight = 0;
16591           vec_add1 (lcl_locs, rloc);
16592
16593           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16594           vec_add1 (rmt_locs, rloc);
16595           /* weight saved in rmt loc */
16596           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16597         }
16598       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16599                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16600         {
16601           rloc.is_ip4 = 0;
16602           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16603           rloc.weight = 0;
16604           vec_add1 (lcl_locs, rloc);
16605
16606           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16607           vec_add1 (rmt_locs, rloc);
16608           /* weight saved in rmt loc */
16609           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16610         }
16611       else if (unformat (input, "action %d", &action))
16612         {
16613           ;
16614         }
16615       else
16616         {
16617           clib_warning ("parse error '%U'", format_unformat_error, input);
16618           return -99;
16619         }
16620     }
16621
16622   if (!rmt_eid_set)
16623     {
16624       errmsg ("remote eid addresses not set");
16625       return -99;
16626     }
16627
16628   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16629     {
16630       errmsg ("eid types don't match");
16631       return -99;
16632     }
16633
16634   if (0 == rmt_locs && (u32) ~ 0 == action)
16635     {
16636       errmsg ("action not set for negative mapping");
16637       return -99;
16638     }
16639
16640   /* Construct the API message */
16641   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16642       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16643
16644   mp->is_add = is_add;
16645   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16646   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16647   mp->eid_type = rmt_eid->type;
16648   mp->dp_table = clib_host_to_net_u32 (dp_table);
16649   mp->vni = clib_host_to_net_u32 (vni);
16650   mp->rmt_len = rmt_eid->len;
16651   mp->lcl_len = lcl_eid->len;
16652   mp->action = action;
16653
16654   if (0 != rmt_locs && 0 != lcl_locs)
16655     {
16656       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16657       clib_memcpy (mp->locs, lcl_locs,
16658                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16659
16660       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16661       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16662                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16663     }
16664   vec_free (lcl_locs);
16665   vec_free (rmt_locs);
16666
16667   /* send it... */
16668   S (mp);
16669
16670   /* Wait for a reply... */
16671   W (ret);
16672   return ret;
16673 }
16674
16675 static int
16676 api_one_add_del_map_server (vat_main_t * vam)
16677 {
16678   unformat_input_t *input = vam->input;
16679   vl_api_one_add_del_map_server_t *mp;
16680   u8 is_add = 1;
16681   u8 ipv4_set = 0;
16682   u8 ipv6_set = 0;
16683   ip4_address_t ipv4;
16684   ip6_address_t ipv6;
16685   int ret;
16686
16687   /* Parse args required to build the message */
16688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16689     {
16690       if (unformat (input, "del"))
16691         {
16692           is_add = 0;
16693         }
16694       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16695         {
16696           ipv4_set = 1;
16697         }
16698       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16699         {
16700           ipv6_set = 1;
16701         }
16702       else
16703         break;
16704     }
16705
16706   if (ipv4_set && ipv6_set)
16707     {
16708       errmsg ("both eid v4 and v6 addresses set");
16709       return -99;
16710     }
16711
16712   if (!ipv4_set && !ipv6_set)
16713     {
16714       errmsg ("eid addresses not set");
16715       return -99;
16716     }
16717
16718   /* Construct the API message */
16719   M (ONE_ADD_DEL_MAP_SERVER, mp);
16720
16721   mp->is_add = is_add;
16722   if (ipv6_set)
16723     {
16724       mp->is_ipv6 = 1;
16725       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16726     }
16727   else
16728     {
16729       mp->is_ipv6 = 0;
16730       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16731     }
16732
16733   /* send it... */
16734   S (mp);
16735
16736   /* Wait for a reply... */
16737   W (ret);
16738   return ret;
16739 }
16740
16741 #define api_lisp_add_del_map_server api_one_add_del_map_server
16742
16743 static int
16744 api_one_add_del_map_resolver (vat_main_t * vam)
16745 {
16746   unformat_input_t *input = vam->input;
16747   vl_api_one_add_del_map_resolver_t *mp;
16748   u8 is_add = 1;
16749   u8 ipv4_set = 0;
16750   u8 ipv6_set = 0;
16751   ip4_address_t ipv4;
16752   ip6_address_t ipv6;
16753   int ret;
16754
16755   /* Parse args required to build the message */
16756   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16757     {
16758       if (unformat (input, "del"))
16759         {
16760           is_add = 0;
16761         }
16762       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16763         {
16764           ipv4_set = 1;
16765         }
16766       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16767         {
16768           ipv6_set = 1;
16769         }
16770       else
16771         break;
16772     }
16773
16774   if (ipv4_set && ipv6_set)
16775     {
16776       errmsg ("both eid v4 and v6 addresses set");
16777       return -99;
16778     }
16779
16780   if (!ipv4_set && !ipv6_set)
16781     {
16782       errmsg ("eid addresses not set");
16783       return -99;
16784     }
16785
16786   /* Construct the API message */
16787   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16788
16789   mp->is_add = is_add;
16790   if (ipv6_set)
16791     {
16792       mp->is_ipv6 = 1;
16793       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16794     }
16795   else
16796     {
16797       mp->is_ipv6 = 0;
16798       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16799     }
16800
16801   /* send it... */
16802   S (mp);
16803
16804   /* Wait for a reply... */
16805   W (ret);
16806   return ret;
16807 }
16808
16809 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16810
16811 static int
16812 api_lisp_gpe_enable_disable (vat_main_t * vam)
16813 {
16814   unformat_input_t *input = vam->input;
16815   vl_api_gpe_enable_disable_t *mp;
16816   u8 is_set = 0;
16817   u8 is_en = 1;
16818   int ret;
16819
16820   /* Parse args required to build the message */
16821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16822     {
16823       if (unformat (input, "enable"))
16824         {
16825           is_set = 1;
16826           is_en = 1;
16827         }
16828       else if (unformat (input, "disable"))
16829         {
16830           is_set = 1;
16831           is_en = 0;
16832         }
16833       else
16834         break;
16835     }
16836
16837   if (is_set == 0)
16838     {
16839       errmsg ("Value not set");
16840       return -99;
16841     }
16842
16843   /* Construct the API message */
16844   M (GPE_ENABLE_DISABLE, mp);
16845
16846   mp->is_en = is_en;
16847
16848   /* send it... */
16849   S (mp);
16850
16851   /* Wait for a reply... */
16852   W (ret);
16853   return ret;
16854 }
16855
16856 static int
16857 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16858 {
16859   unformat_input_t *input = vam->input;
16860   vl_api_one_rloc_probe_enable_disable_t *mp;
16861   u8 is_set = 0;
16862   u8 is_en = 0;
16863   int ret;
16864
16865   /* Parse args required to build the message */
16866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16867     {
16868       if (unformat (input, "enable"))
16869         {
16870           is_set = 1;
16871           is_en = 1;
16872         }
16873       else if (unformat (input, "disable"))
16874         is_set = 1;
16875       else
16876         break;
16877     }
16878
16879   if (!is_set)
16880     {
16881       errmsg ("Value not set");
16882       return -99;
16883     }
16884
16885   /* Construct the API message */
16886   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16887
16888   mp->is_enabled = is_en;
16889
16890   /* send it... */
16891   S (mp);
16892
16893   /* Wait for a reply... */
16894   W (ret);
16895   return ret;
16896 }
16897
16898 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16899
16900 static int
16901 api_one_map_register_enable_disable (vat_main_t * vam)
16902 {
16903   unformat_input_t *input = vam->input;
16904   vl_api_one_map_register_enable_disable_t *mp;
16905   u8 is_set = 0;
16906   u8 is_en = 0;
16907   int ret;
16908
16909   /* Parse args required to build the message */
16910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16911     {
16912       if (unformat (input, "enable"))
16913         {
16914           is_set = 1;
16915           is_en = 1;
16916         }
16917       else if (unformat (input, "disable"))
16918         is_set = 1;
16919       else
16920         break;
16921     }
16922
16923   if (!is_set)
16924     {
16925       errmsg ("Value not set");
16926       return -99;
16927     }
16928
16929   /* Construct the API message */
16930   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16931
16932   mp->is_enabled = is_en;
16933
16934   /* send it... */
16935   S (mp);
16936
16937   /* Wait for a reply... */
16938   W (ret);
16939   return ret;
16940 }
16941
16942 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16943
16944 static int
16945 api_one_enable_disable (vat_main_t * vam)
16946 {
16947   unformat_input_t *input = vam->input;
16948   vl_api_one_enable_disable_t *mp;
16949   u8 is_set = 0;
16950   u8 is_en = 0;
16951   int ret;
16952
16953   /* Parse args required to build the message */
16954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16955     {
16956       if (unformat (input, "enable"))
16957         {
16958           is_set = 1;
16959           is_en = 1;
16960         }
16961       else if (unformat (input, "disable"))
16962         {
16963           is_set = 1;
16964         }
16965       else
16966         break;
16967     }
16968
16969   if (!is_set)
16970     {
16971       errmsg ("Value not set");
16972       return -99;
16973     }
16974
16975   /* Construct the API message */
16976   M (ONE_ENABLE_DISABLE, mp);
16977
16978   mp->is_en = is_en;
16979
16980   /* send it... */
16981   S (mp);
16982
16983   /* Wait for a reply... */
16984   W (ret);
16985   return ret;
16986 }
16987
16988 #define api_lisp_enable_disable api_one_enable_disable
16989
16990 static int
16991 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16992 {
16993   unformat_input_t *input = vam->input;
16994   vl_api_one_enable_disable_xtr_mode_t *mp;
16995   u8 is_set = 0;
16996   u8 is_en = 0;
16997   int ret;
16998
16999   /* Parse args required to build the message */
17000   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17001     {
17002       if (unformat (input, "enable"))
17003         {
17004           is_set = 1;
17005           is_en = 1;
17006         }
17007       else if (unformat (input, "disable"))
17008         {
17009           is_set = 1;
17010         }
17011       else
17012         break;
17013     }
17014
17015   if (!is_set)
17016     {
17017       errmsg ("Value not set");
17018       return -99;
17019     }
17020
17021   /* Construct the API message */
17022   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17023
17024   mp->is_en = is_en;
17025
17026   /* send it... */
17027   S (mp);
17028
17029   /* Wait for a reply... */
17030   W (ret);
17031   return ret;
17032 }
17033
17034 static int
17035 api_one_show_xtr_mode (vat_main_t * vam)
17036 {
17037   vl_api_one_show_xtr_mode_t *mp;
17038   int ret;
17039
17040   /* Construct the API message */
17041   M (ONE_SHOW_XTR_MODE, mp);
17042
17043   /* send it... */
17044   S (mp);
17045
17046   /* Wait for a reply... */
17047   W (ret);
17048   return ret;
17049 }
17050
17051 static int
17052 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17053 {
17054   unformat_input_t *input = vam->input;
17055   vl_api_one_enable_disable_pitr_mode_t *mp;
17056   u8 is_set = 0;
17057   u8 is_en = 0;
17058   int ret;
17059
17060   /* Parse args required to build the message */
17061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17062     {
17063       if (unformat (input, "enable"))
17064         {
17065           is_set = 1;
17066           is_en = 1;
17067         }
17068       else if (unformat (input, "disable"))
17069         {
17070           is_set = 1;
17071         }
17072       else
17073         break;
17074     }
17075
17076   if (!is_set)
17077     {
17078       errmsg ("Value not set");
17079       return -99;
17080     }
17081
17082   /* Construct the API message */
17083   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17084
17085   mp->is_en = is_en;
17086
17087   /* send it... */
17088   S (mp);
17089
17090   /* Wait for a reply... */
17091   W (ret);
17092   return ret;
17093 }
17094
17095 static int
17096 api_one_show_pitr_mode (vat_main_t * vam)
17097 {
17098   vl_api_one_show_pitr_mode_t *mp;
17099   int ret;
17100
17101   /* Construct the API message */
17102   M (ONE_SHOW_PITR_MODE, mp);
17103
17104   /* send it... */
17105   S (mp);
17106
17107   /* Wait for a reply... */
17108   W (ret);
17109   return ret;
17110 }
17111
17112 static int
17113 api_one_enable_disable_petr_mode (vat_main_t * vam)
17114 {
17115   unformat_input_t *input = vam->input;
17116   vl_api_one_enable_disable_petr_mode_t *mp;
17117   u8 is_set = 0;
17118   u8 is_en = 0;
17119   int ret;
17120
17121   /* Parse args required to build the message */
17122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17123     {
17124       if (unformat (input, "enable"))
17125         {
17126           is_set = 1;
17127           is_en = 1;
17128         }
17129       else if (unformat (input, "disable"))
17130         {
17131           is_set = 1;
17132         }
17133       else
17134         break;
17135     }
17136
17137   if (!is_set)
17138     {
17139       errmsg ("Value not set");
17140       return -99;
17141     }
17142
17143   /* Construct the API message */
17144   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17145
17146   mp->is_en = is_en;
17147
17148   /* send it... */
17149   S (mp);
17150
17151   /* Wait for a reply... */
17152   W (ret);
17153   return ret;
17154 }
17155
17156 static int
17157 api_one_show_petr_mode (vat_main_t * vam)
17158 {
17159   vl_api_one_show_petr_mode_t *mp;
17160   int ret;
17161
17162   /* Construct the API message */
17163   M (ONE_SHOW_PETR_MODE, mp);
17164
17165   /* send it... */
17166   S (mp);
17167
17168   /* Wait for a reply... */
17169   W (ret);
17170   return ret;
17171 }
17172
17173 static int
17174 api_show_one_map_register_state (vat_main_t * vam)
17175 {
17176   vl_api_show_one_map_register_state_t *mp;
17177   int ret;
17178
17179   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17180
17181   /* send */
17182   S (mp);
17183
17184   /* wait for reply */
17185   W (ret);
17186   return ret;
17187 }
17188
17189 #define api_show_lisp_map_register_state api_show_one_map_register_state
17190
17191 static int
17192 api_show_one_rloc_probe_state (vat_main_t * vam)
17193 {
17194   vl_api_show_one_rloc_probe_state_t *mp;
17195   int ret;
17196
17197   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17198
17199   /* send */
17200   S (mp);
17201
17202   /* wait for reply */
17203   W (ret);
17204   return ret;
17205 }
17206
17207 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17208
17209 static int
17210 api_one_add_del_ndp_entry (vat_main_t * vam)
17211 {
17212   vl_api_one_add_del_ndp_entry_t *mp;
17213   unformat_input_t *input = vam->input;
17214   u8 is_add = 1;
17215   u8 mac_set = 0;
17216   u8 bd_set = 0;
17217   u8 ip_set = 0;
17218   u8 mac[6] = { 0, };
17219   u8 ip6[16] = { 0, };
17220   u32 bd = ~0;
17221   int ret;
17222
17223   /* Parse args required to build the message */
17224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17225     {
17226       if (unformat (input, "del"))
17227         is_add = 0;
17228       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17229         mac_set = 1;
17230       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17231         ip_set = 1;
17232       else if (unformat (input, "bd %d", &bd))
17233         bd_set = 1;
17234       else
17235         {
17236           errmsg ("parse error '%U'", format_unformat_error, input);
17237           return -99;
17238         }
17239     }
17240
17241   if (!bd_set || !ip_set || (!mac_set && is_add))
17242     {
17243       errmsg ("Missing BD, IP or MAC!");
17244       return -99;
17245     }
17246
17247   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17248   mp->is_add = is_add;
17249   clib_memcpy (mp->mac, mac, 6);
17250   mp->bd = clib_host_to_net_u32 (bd);
17251   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17252
17253   /* send */
17254   S (mp);
17255
17256   /* wait for reply */
17257   W (ret);
17258   return ret;
17259 }
17260
17261 static int
17262 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17263 {
17264   vl_api_one_add_del_l2_arp_entry_t *mp;
17265   unformat_input_t *input = vam->input;
17266   u8 is_add = 1;
17267   u8 mac_set = 0;
17268   u8 bd_set = 0;
17269   u8 ip_set = 0;
17270   u8 mac[6] = { 0, };
17271   u32 ip4 = 0, bd = ~0;
17272   int ret;
17273
17274   /* Parse args required to build the message */
17275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17276     {
17277       if (unformat (input, "del"))
17278         is_add = 0;
17279       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17280         mac_set = 1;
17281       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17282         ip_set = 1;
17283       else if (unformat (input, "bd %d", &bd))
17284         bd_set = 1;
17285       else
17286         {
17287           errmsg ("parse error '%U'", format_unformat_error, input);
17288           return -99;
17289         }
17290     }
17291
17292   if (!bd_set || !ip_set || (!mac_set && is_add))
17293     {
17294       errmsg ("Missing BD, IP or MAC!");
17295       return -99;
17296     }
17297
17298   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17299   mp->is_add = is_add;
17300   clib_memcpy (mp->mac, mac, 6);
17301   mp->bd = clib_host_to_net_u32 (bd);
17302   mp->ip4 = ip4;
17303
17304   /* send */
17305   S (mp);
17306
17307   /* wait for reply */
17308   W (ret);
17309   return ret;
17310 }
17311
17312 static int
17313 api_one_ndp_bd_get (vat_main_t * vam)
17314 {
17315   vl_api_one_ndp_bd_get_t *mp;
17316   int ret;
17317
17318   M (ONE_NDP_BD_GET, mp);
17319
17320   /* send */
17321   S (mp);
17322
17323   /* wait for reply */
17324   W (ret);
17325   return ret;
17326 }
17327
17328 static int
17329 api_one_ndp_entries_get (vat_main_t * vam)
17330 {
17331   vl_api_one_ndp_entries_get_t *mp;
17332   unformat_input_t *input = vam->input;
17333   u8 bd_set = 0;
17334   u32 bd = ~0;
17335   int ret;
17336
17337   /* Parse args required to build the message */
17338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17339     {
17340       if (unformat (input, "bd %d", &bd))
17341         bd_set = 1;
17342       else
17343         {
17344           errmsg ("parse error '%U'", format_unformat_error, input);
17345           return -99;
17346         }
17347     }
17348
17349   if (!bd_set)
17350     {
17351       errmsg ("Expected bridge domain!");
17352       return -99;
17353     }
17354
17355   M (ONE_NDP_ENTRIES_GET, mp);
17356   mp->bd = clib_host_to_net_u32 (bd);
17357
17358   /* send */
17359   S (mp);
17360
17361   /* wait for reply */
17362   W (ret);
17363   return ret;
17364 }
17365
17366 static int
17367 api_one_l2_arp_bd_get (vat_main_t * vam)
17368 {
17369   vl_api_one_l2_arp_bd_get_t *mp;
17370   int ret;
17371
17372   M (ONE_L2_ARP_BD_GET, mp);
17373
17374   /* send */
17375   S (mp);
17376
17377   /* wait for reply */
17378   W (ret);
17379   return ret;
17380 }
17381
17382 static int
17383 api_one_l2_arp_entries_get (vat_main_t * vam)
17384 {
17385   vl_api_one_l2_arp_entries_get_t *mp;
17386   unformat_input_t *input = vam->input;
17387   u8 bd_set = 0;
17388   u32 bd = ~0;
17389   int ret;
17390
17391   /* Parse args required to build the message */
17392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17393     {
17394       if (unformat (input, "bd %d", &bd))
17395         bd_set = 1;
17396       else
17397         {
17398           errmsg ("parse error '%U'", format_unformat_error, input);
17399           return -99;
17400         }
17401     }
17402
17403   if (!bd_set)
17404     {
17405       errmsg ("Expected bridge domain!");
17406       return -99;
17407     }
17408
17409   M (ONE_L2_ARP_ENTRIES_GET, mp);
17410   mp->bd = clib_host_to_net_u32 (bd);
17411
17412   /* send */
17413   S (mp);
17414
17415   /* wait for reply */
17416   W (ret);
17417   return ret;
17418 }
17419
17420 static int
17421 api_one_stats_enable_disable (vat_main_t * vam)
17422 {
17423   vl_api_one_stats_enable_disable_t *mp;
17424   unformat_input_t *input = vam->input;
17425   u8 is_set = 0;
17426   u8 is_en = 0;
17427   int ret;
17428
17429   /* Parse args required to build the message */
17430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17431     {
17432       if (unformat (input, "enable"))
17433         {
17434           is_set = 1;
17435           is_en = 1;
17436         }
17437       else if (unformat (input, "disable"))
17438         {
17439           is_set = 1;
17440         }
17441       else
17442         break;
17443     }
17444
17445   if (!is_set)
17446     {
17447       errmsg ("Value not set");
17448       return -99;
17449     }
17450
17451   M (ONE_STATS_ENABLE_DISABLE, mp);
17452   mp->is_en = is_en;
17453
17454   /* send */
17455   S (mp);
17456
17457   /* wait for reply */
17458   W (ret);
17459   return ret;
17460 }
17461
17462 static int
17463 api_show_one_stats_enable_disable (vat_main_t * vam)
17464 {
17465   vl_api_show_one_stats_enable_disable_t *mp;
17466   int ret;
17467
17468   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17469
17470   /* send */
17471   S (mp);
17472
17473   /* wait for reply */
17474   W (ret);
17475   return ret;
17476 }
17477
17478 static int
17479 api_show_one_map_request_mode (vat_main_t * vam)
17480 {
17481   vl_api_show_one_map_request_mode_t *mp;
17482   int ret;
17483
17484   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17485
17486   /* send */
17487   S (mp);
17488
17489   /* wait for reply */
17490   W (ret);
17491   return ret;
17492 }
17493
17494 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17495
17496 static int
17497 api_one_map_request_mode (vat_main_t * vam)
17498 {
17499   unformat_input_t *input = vam->input;
17500   vl_api_one_map_request_mode_t *mp;
17501   u8 mode = 0;
17502   int ret;
17503
17504   /* Parse args required to build the message */
17505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17506     {
17507       if (unformat (input, "dst-only"))
17508         mode = 0;
17509       else if (unformat (input, "src-dst"))
17510         mode = 1;
17511       else
17512         {
17513           errmsg ("parse error '%U'", format_unformat_error, input);
17514           return -99;
17515         }
17516     }
17517
17518   M (ONE_MAP_REQUEST_MODE, mp);
17519
17520   mp->mode = mode;
17521
17522   /* send */
17523   S (mp);
17524
17525   /* wait for reply */
17526   W (ret);
17527   return ret;
17528 }
17529
17530 #define api_lisp_map_request_mode api_one_map_request_mode
17531
17532 /**
17533  * Enable/disable ONE proxy ITR.
17534  *
17535  * @param vam vpp API test context
17536  * @return return code
17537  */
17538 static int
17539 api_one_pitr_set_locator_set (vat_main_t * vam)
17540 {
17541   u8 ls_name_set = 0;
17542   unformat_input_t *input = vam->input;
17543   vl_api_one_pitr_set_locator_set_t *mp;
17544   u8 is_add = 1;
17545   u8 *ls_name = 0;
17546   int ret;
17547
17548   /* Parse args required to build the message */
17549   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17550     {
17551       if (unformat (input, "del"))
17552         is_add = 0;
17553       else if (unformat (input, "locator-set %s", &ls_name))
17554         ls_name_set = 1;
17555       else
17556         {
17557           errmsg ("parse error '%U'", format_unformat_error, input);
17558           return -99;
17559         }
17560     }
17561
17562   if (!ls_name_set)
17563     {
17564       errmsg ("locator-set name not set!");
17565       return -99;
17566     }
17567
17568   M (ONE_PITR_SET_LOCATOR_SET, mp);
17569
17570   mp->is_add = is_add;
17571   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17572   vec_free (ls_name);
17573
17574   /* send */
17575   S (mp);
17576
17577   /* wait for reply */
17578   W (ret);
17579   return ret;
17580 }
17581
17582 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17583
17584 static int
17585 api_one_nsh_set_locator_set (vat_main_t * vam)
17586 {
17587   u8 ls_name_set = 0;
17588   unformat_input_t *input = vam->input;
17589   vl_api_one_nsh_set_locator_set_t *mp;
17590   u8 is_add = 1;
17591   u8 *ls_name = 0;
17592   int ret;
17593
17594   /* Parse args required to build the message */
17595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17596     {
17597       if (unformat (input, "del"))
17598         is_add = 0;
17599       else if (unformat (input, "ls %s", &ls_name))
17600         ls_name_set = 1;
17601       else
17602         {
17603           errmsg ("parse error '%U'", format_unformat_error, input);
17604           return -99;
17605         }
17606     }
17607
17608   if (!ls_name_set && is_add)
17609     {
17610       errmsg ("locator-set name not set!");
17611       return -99;
17612     }
17613
17614   M (ONE_NSH_SET_LOCATOR_SET, mp);
17615
17616   mp->is_add = is_add;
17617   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17618   vec_free (ls_name);
17619
17620   /* send */
17621   S (mp);
17622
17623   /* wait for reply */
17624   W (ret);
17625   return ret;
17626 }
17627
17628 static int
17629 api_show_one_pitr (vat_main_t * vam)
17630 {
17631   vl_api_show_one_pitr_t *mp;
17632   int ret;
17633
17634   if (!vam->json_output)
17635     {
17636       print (vam->ofp, "%=20s", "lisp status:");
17637     }
17638
17639   M (SHOW_ONE_PITR, mp);
17640   /* send it... */
17641   S (mp);
17642
17643   /* Wait for a reply... */
17644   W (ret);
17645   return ret;
17646 }
17647
17648 #define api_show_lisp_pitr api_show_one_pitr
17649
17650 static int
17651 api_one_use_petr (vat_main_t * vam)
17652 {
17653   unformat_input_t *input = vam->input;
17654   vl_api_one_use_petr_t *mp;
17655   u8 is_add = 0;
17656   ip_address_t ip;
17657   int ret;
17658
17659   memset (&ip, 0, sizeof (ip));
17660
17661   /* Parse args required to build the message */
17662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17663     {
17664       if (unformat (input, "disable"))
17665         is_add = 0;
17666       else
17667         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17668         {
17669           is_add = 1;
17670           ip_addr_version (&ip) = IP4;
17671         }
17672       else
17673         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17674         {
17675           is_add = 1;
17676           ip_addr_version (&ip) = IP6;
17677         }
17678       else
17679         {
17680           errmsg ("parse error '%U'", format_unformat_error, input);
17681           return -99;
17682         }
17683     }
17684
17685   M (ONE_USE_PETR, mp);
17686
17687   mp->is_add = is_add;
17688   if (is_add)
17689     {
17690       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17691       if (mp->is_ip4)
17692         clib_memcpy (mp->address, &ip, 4);
17693       else
17694         clib_memcpy (mp->address, &ip, 16);
17695     }
17696
17697   /* send */
17698   S (mp);
17699
17700   /* wait for reply */
17701   W (ret);
17702   return ret;
17703 }
17704
17705 #define api_lisp_use_petr api_one_use_petr
17706
17707 static int
17708 api_show_one_nsh_mapping (vat_main_t * vam)
17709 {
17710   vl_api_show_one_use_petr_t *mp;
17711   int ret;
17712
17713   if (!vam->json_output)
17714     {
17715       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17716     }
17717
17718   M (SHOW_ONE_NSH_MAPPING, mp);
17719   /* send it... */
17720   S (mp);
17721
17722   /* Wait for a reply... */
17723   W (ret);
17724   return ret;
17725 }
17726
17727 static int
17728 api_show_one_use_petr (vat_main_t * vam)
17729 {
17730   vl_api_show_one_use_petr_t *mp;
17731   int ret;
17732
17733   if (!vam->json_output)
17734     {
17735       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17736     }
17737
17738   M (SHOW_ONE_USE_PETR, mp);
17739   /* send it... */
17740   S (mp);
17741
17742   /* Wait for a reply... */
17743   W (ret);
17744   return ret;
17745 }
17746
17747 #define api_show_lisp_use_petr api_show_one_use_petr
17748
17749 /**
17750  * Add/delete mapping between vni and vrf
17751  */
17752 static int
17753 api_one_eid_table_add_del_map (vat_main_t * vam)
17754 {
17755   unformat_input_t *input = vam->input;
17756   vl_api_one_eid_table_add_del_map_t *mp;
17757   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17758   u32 vni, vrf, bd_index;
17759   int ret;
17760
17761   /* Parse args required to build the message */
17762   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17763     {
17764       if (unformat (input, "del"))
17765         is_add = 0;
17766       else if (unformat (input, "vrf %d", &vrf))
17767         vrf_set = 1;
17768       else if (unformat (input, "bd_index %d", &bd_index))
17769         bd_index_set = 1;
17770       else if (unformat (input, "vni %d", &vni))
17771         vni_set = 1;
17772       else
17773         break;
17774     }
17775
17776   if (!vni_set || (!vrf_set && !bd_index_set))
17777     {
17778       errmsg ("missing arguments!");
17779       return -99;
17780     }
17781
17782   if (vrf_set && bd_index_set)
17783     {
17784       errmsg ("error: both vrf and bd entered!");
17785       return -99;
17786     }
17787
17788   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17789
17790   mp->is_add = is_add;
17791   mp->vni = htonl (vni);
17792   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17793   mp->is_l2 = bd_index_set;
17794
17795   /* send */
17796   S (mp);
17797
17798   /* wait for reply */
17799   W (ret);
17800   return ret;
17801 }
17802
17803 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17804
17805 uword
17806 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17807 {
17808   u32 *action = va_arg (*args, u32 *);
17809   u8 *s = 0;
17810
17811   if (unformat (input, "%s", &s))
17812     {
17813       if (!strcmp ((char *) s, "no-action"))
17814         action[0] = 0;
17815       else if (!strcmp ((char *) s, "natively-forward"))
17816         action[0] = 1;
17817       else if (!strcmp ((char *) s, "send-map-request"))
17818         action[0] = 2;
17819       else if (!strcmp ((char *) s, "drop"))
17820         action[0] = 3;
17821       else
17822         {
17823           clib_warning ("invalid action: '%s'", s);
17824           action[0] = 3;
17825         }
17826     }
17827   else
17828     return 0;
17829
17830   vec_free (s);
17831   return 1;
17832 }
17833
17834 /**
17835  * Add/del remote mapping to/from ONE control plane
17836  *
17837  * @param vam vpp API test context
17838  * @return return code
17839  */
17840 static int
17841 api_one_add_del_remote_mapping (vat_main_t * vam)
17842 {
17843   unformat_input_t *input = vam->input;
17844   vl_api_one_add_del_remote_mapping_t *mp;
17845   u32 vni = 0;
17846   lisp_eid_vat_t _eid, *eid = &_eid;
17847   lisp_eid_vat_t _seid, *seid = &_seid;
17848   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17849   u32 action = ~0, p, w, data_len;
17850   ip4_address_t rloc4;
17851   ip6_address_t rloc6;
17852   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17853   int ret;
17854
17855   memset (&rloc, 0, sizeof (rloc));
17856
17857   /* Parse args required to build the message */
17858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17859     {
17860       if (unformat (input, "del-all"))
17861         {
17862           del_all = 1;
17863         }
17864       else if (unformat (input, "del"))
17865         {
17866           is_add = 0;
17867         }
17868       else if (unformat (input, "add"))
17869         {
17870           is_add = 1;
17871         }
17872       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17873         {
17874           eid_set = 1;
17875         }
17876       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17877         {
17878           seid_set = 1;
17879         }
17880       else if (unformat (input, "vni %d", &vni))
17881         {
17882           ;
17883         }
17884       else if (unformat (input, "p %d w %d", &p, &w))
17885         {
17886           if (!curr_rloc)
17887             {
17888               errmsg ("No RLOC configured for setting priority/weight!");
17889               return -99;
17890             }
17891           curr_rloc->priority = p;
17892           curr_rloc->weight = w;
17893         }
17894       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17895         {
17896           rloc.is_ip4 = 1;
17897           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17898           vec_add1 (rlocs, rloc);
17899           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17900         }
17901       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17902         {
17903           rloc.is_ip4 = 0;
17904           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17905           vec_add1 (rlocs, rloc);
17906           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17907         }
17908       else if (unformat (input, "action %U",
17909                          unformat_negative_mapping_action, &action))
17910         {
17911           ;
17912         }
17913       else
17914         {
17915           clib_warning ("parse error '%U'", format_unformat_error, input);
17916           return -99;
17917         }
17918     }
17919
17920   if (0 == eid_set)
17921     {
17922       errmsg ("missing params!");
17923       return -99;
17924     }
17925
17926   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17927     {
17928       errmsg ("no action set for negative map-reply!");
17929       return -99;
17930     }
17931
17932   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17933
17934   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17935   mp->is_add = is_add;
17936   mp->vni = htonl (vni);
17937   mp->action = (u8) action;
17938   mp->is_src_dst = seid_set;
17939   mp->eid_len = eid->len;
17940   mp->seid_len = seid->len;
17941   mp->del_all = del_all;
17942   mp->eid_type = eid->type;
17943   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17944   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17945
17946   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17947   clib_memcpy (mp->rlocs, rlocs, data_len);
17948   vec_free (rlocs);
17949
17950   /* send it... */
17951   S (mp);
17952
17953   /* Wait for a reply... */
17954   W (ret);
17955   return ret;
17956 }
17957
17958 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17959
17960 /**
17961  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17962  * forwarding entries in data-plane accordingly.
17963  *
17964  * @param vam vpp API test context
17965  * @return return code
17966  */
17967 static int
17968 api_one_add_del_adjacency (vat_main_t * vam)
17969 {
17970   unformat_input_t *input = vam->input;
17971   vl_api_one_add_del_adjacency_t *mp;
17972   u32 vni = 0;
17973   ip4_address_t leid4, reid4;
17974   ip6_address_t leid6, reid6;
17975   u8 reid_mac[6] = { 0 };
17976   u8 leid_mac[6] = { 0 };
17977   u8 reid_type, leid_type;
17978   u32 leid_len = 0, reid_len = 0, len;
17979   u8 is_add = 1;
17980   int ret;
17981
17982   leid_type = reid_type = (u8) ~ 0;
17983
17984   /* Parse args required to build the message */
17985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17986     {
17987       if (unformat (input, "del"))
17988         {
17989           is_add = 0;
17990         }
17991       else if (unformat (input, "add"))
17992         {
17993           is_add = 1;
17994         }
17995       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17996                          &reid4, &len))
17997         {
17998           reid_type = 0;        /* ipv4 */
17999           reid_len = len;
18000         }
18001       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18002                          &reid6, &len))
18003         {
18004           reid_type = 1;        /* ipv6 */
18005           reid_len = len;
18006         }
18007       else if (unformat (input, "reid %U", unformat_ethernet_address,
18008                          reid_mac))
18009         {
18010           reid_type = 2;        /* mac */
18011         }
18012       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18013                          &leid4, &len))
18014         {
18015           leid_type = 0;        /* ipv4 */
18016           leid_len = len;
18017         }
18018       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18019                          &leid6, &len))
18020         {
18021           leid_type = 1;        /* ipv6 */
18022           leid_len = len;
18023         }
18024       else if (unformat (input, "leid %U", unformat_ethernet_address,
18025                          leid_mac))
18026         {
18027           leid_type = 2;        /* mac */
18028         }
18029       else if (unformat (input, "vni %d", &vni))
18030         {
18031           ;
18032         }
18033       else
18034         {
18035           errmsg ("parse error '%U'", format_unformat_error, input);
18036           return -99;
18037         }
18038     }
18039
18040   if ((u8) ~ 0 == reid_type)
18041     {
18042       errmsg ("missing params!");
18043       return -99;
18044     }
18045
18046   if (leid_type != reid_type)
18047     {
18048       errmsg ("remote and local EIDs are of different types!");
18049       return -99;
18050     }
18051
18052   M (ONE_ADD_DEL_ADJACENCY, mp);
18053   mp->is_add = is_add;
18054   mp->vni = htonl (vni);
18055   mp->leid_len = leid_len;
18056   mp->reid_len = reid_len;
18057   mp->eid_type = reid_type;
18058
18059   switch (mp->eid_type)
18060     {
18061     case 0:
18062       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18063       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18064       break;
18065     case 1:
18066       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18067       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18068       break;
18069     case 2:
18070       clib_memcpy (mp->leid, leid_mac, 6);
18071       clib_memcpy (mp->reid, reid_mac, 6);
18072       break;
18073     default:
18074       errmsg ("unknown EID type %d!", mp->eid_type);
18075       return 0;
18076     }
18077
18078   /* send it... */
18079   S (mp);
18080
18081   /* Wait for a reply... */
18082   W (ret);
18083   return ret;
18084 }
18085
18086 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18087
18088 uword
18089 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18090 {
18091   u32 *mode = va_arg (*args, u32 *);
18092
18093   if (unformat (input, "lisp"))
18094     *mode = 0;
18095   else if (unformat (input, "vxlan"))
18096     *mode = 1;
18097   else
18098     return 0;
18099
18100   return 1;
18101 }
18102
18103 static int
18104 api_gpe_get_encap_mode (vat_main_t * vam)
18105 {
18106   vl_api_gpe_get_encap_mode_t *mp;
18107   int ret;
18108
18109   /* Construct the API message */
18110   M (GPE_GET_ENCAP_MODE, mp);
18111
18112   /* send it... */
18113   S (mp);
18114
18115   /* Wait for a reply... */
18116   W (ret);
18117   return ret;
18118 }
18119
18120 static int
18121 api_gpe_set_encap_mode (vat_main_t * vam)
18122 {
18123   unformat_input_t *input = vam->input;
18124   vl_api_gpe_set_encap_mode_t *mp;
18125   int ret;
18126   u32 mode = 0;
18127
18128   /* Parse args required to build the message */
18129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18130     {
18131       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18132         ;
18133       else
18134         break;
18135     }
18136
18137   /* Construct the API message */
18138   M (GPE_SET_ENCAP_MODE, mp);
18139
18140   mp->mode = mode;
18141
18142   /* send it... */
18143   S (mp);
18144
18145   /* Wait for a reply... */
18146   W (ret);
18147   return ret;
18148 }
18149
18150 static int
18151 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18152 {
18153   unformat_input_t *input = vam->input;
18154   vl_api_gpe_add_del_iface_t *mp;
18155   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18156   u32 dp_table = 0, vni = 0;
18157   int ret;
18158
18159   /* Parse args required to build the message */
18160   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18161     {
18162       if (unformat (input, "up"))
18163         {
18164           action_set = 1;
18165           is_add = 1;
18166         }
18167       else if (unformat (input, "down"))
18168         {
18169           action_set = 1;
18170           is_add = 0;
18171         }
18172       else if (unformat (input, "table_id %d", &dp_table))
18173         {
18174           dp_table_set = 1;
18175         }
18176       else if (unformat (input, "bd_id %d", &dp_table))
18177         {
18178           dp_table_set = 1;
18179           is_l2 = 1;
18180         }
18181       else if (unformat (input, "vni %d", &vni))
18182         {
18183           vni_set = 1;
18184         }
18185       else
18186         break;
18187     }
18188
18189   if (action_set == 0)
18190     {
18191       errmsg ("Action not set");
18192       return -99;
18193     }
18194   if (dp_table_set == 0 || vni_set == 0)
18195     {
18196       errmsg ("vni and dp_table must be set");
18197       return -99;
18198     }
18199
18200   /* Construct the API message */
18201   M (GPE_ADD_DEL_IFACE, mp);
18202
18203   mp->is_add = is_add;
18204   mp->dp_table = clib_host_to_net_u32 (dp_table);
18205   mp->is_l2 = is_l2;
18206   mp->vni = clib_host_to_net_u32 (vni);
18207
18208   /* send it... */
18209   S (mp);
18210
18211   /* Wait for a reply... */
18212   W (ret);
18213   return ret;
18214 }
18215
18216 static int
18217 api_one_map_register_fallback_threshold (vat_main_t * vam)
18218 {
18219   unformat_input_t *input = vam->input;
18220   vl_api_one_map_register_fallback_threshold_t *mp;
18221   u32 value = 0;
18222   u8 is_set = 0;
18223   int ret;
18224
18225   /* Parse args required to build the message */
18226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18227     {
18228       if (unformat (input, "%u", &value))
18229         is_set = 1;
18230       else
18231         {
18232           clib_warning ("parse error '%U'", format_unformat_error, input);
18233           return -99;
18234         }
18235     }
18236
18237   if (!is_set)
18238     {
18239       errmsg ("fallback threshold value is missing!");
18240       return -99;
18241     }
18242
18243   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18244   mp->value = clib_host_to_net_u32 (value);
18245
18246   /* send it... */
18247   S (mp);
18248
18249   /* Wait for a reply... */
18250   W (ret);
18251   return ret;
18252 }
18253
18254 static int
18255 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18256 {
18257   vl_api_show_one_map_register_fallback_threshold_t *mp;
18258   int ret;
18259
18260   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18261
18262   /* send it... */
18263   S (mp);
18264
18265   /* Wait for a reply... */
18266   W (ret);
18267   return ret;
18268 }
18269
18270 uword
18271 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18272 {
18273   u32 *proto = va_arg (*args, u32 *);
18274
18275   if (unformat (input, "udp"))
18276     *proto = 1;
18277   else if (unformat (input, "api"))
18278     *proto = 2;
18279   else
18280     return 0;
18281
18282   return 1;
18283 }
18284
18285 static int
18286 api_one_set_transport_protocol (vat_main_t * vam)
18287 {
18288   unformat_input_t *input = vam->input;
18289   vl_api_one_set_transport_protocol_t *mp;
18290   u8 is_set = 0;
18291   u32 protocol = 0;
18292   int ret;
18293
18294   /* Parse args required to build the message */
18295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18296     {
18297       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18298         is_set = 1;
18299       else
18300         {
18301           clib_warning ("parse error '%U'", format_unformat_error, input);
18302           return -99;
18303         }
18304     }
18305
18306   if (!is_set)
18307     {
18308       errmsg ("Transport protocol missing!");
18309       return -99;
18310     }
18311
18312   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18313   mp->protocol = (u8) protocol;
18314
18315   /* send it... */
18316   S (mp);
18317
18318   /* Wait for a reply... */
18319   W (ret);
18320   return ret;
18321 }
18322
18323 static int
18324 api_one_get_transport_protocol (vat_main_t * vam)
18325 {
18326   vl_api_one_get_transport_protocol_t *mp;
18327   int ret;
18328
18329   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18330
18331   /* send it... */
18332   S (mp);
18333
18334   /* Wait for a reply... */
18335   W (ret);
18336   return ret;
18337 }
18338
18339 static int
18340 api_one_map_register_set_ttl (vat_main_t * vam)
18341 {
18342   unformat_input_t *input = vam->input;
18343   vl_api_one_map_register_set_ttl_t *mp;
18344   u32 ttl = 0;
18345   u8 is_set = 0;
18346   int ret;
18347
18348   /* Parse args required to build the message */
18349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18350     {
18351       if (unformat (input, "%u", &ttl))
18352         is_set = 1;
18353       else
18354         {
18355           clib_warning ("parse error '%U'", format_unformat_error, input);
18356           return -99;
18357         }
18358     }
18359
18360   if (!is_set)
18361     {
18362       errmsg ("TTL value missing!");
18363       return -99;
18364     }
18365
18366   M (ONE_MAP_REGISTER_SET_TTL, mp);
18367   mp->ttl = clib_host_to_net_u32 (ttl);
18368
18369   /* send it... */
18370   S (mp);
18371
18372   /* Wait for a reply... */
18373   W (ret);
18374   return ret;
18375 }
18376
18377 static int
18378 api_show_one_map_register_ttl (vat_main_t * vam)
18379 {
18380   vl_api_show_one_map_register_ttl_t *mp;
18381   int ret;
18382
18383   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18384
18385   /* send it... */
18386   S (mp);
18387
18388   /* Wait for a reply... */
18389   W (ret);
18390   return ret;
18391 }
18392
18393 /**
18394  * Add/del map request itr rlocs from ONE control plane and updates
18395  *
18396  * @param vam vpp API test context
18397  * @return return code
18398  */
18399 static int
18400 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18401 {
18402   unformat_input_t *input = vam->input;
18403   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18404   u8 *locator_set_name = 0;
18405   u8 locator_set_name_set = 0;
18406   u8 is_add = 1;
18407   int ret;
18408
18409   /* Parse args required to build the message */
18410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18411     {
18412       if (unformat (input, "del"))
18413         {
18414           is_add = 0;
18415         }
18416       else if (unformat (input, "%_%v%_", &locator_set_name))
18417         {
18418           locator_set_name_set = 1;
18419         }
18420       else
18421         {
18422           clib_warning ("parse error '%U'", format_unformat_error, input);
18423           return -99;
18424         }
18425     }
18426
18427   if (is_add && !locator_set_name_set)
18428     {
18429       errmsg ("itr-rloc is not set!");
18430       return -99;
18431     }
18432
18433   if (is_add && vec_len (locator_set_name) > 64)
18434     {
18435       errmsg ("itr-rloc locator-set name too long");
18436       vec_free (locator_set_name);
18437       return -99;
18438     }
18439
18440   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18441   mp->is_add = is_add;
18442   if (is_add)
18443     {
18444       clib_memcpy (mp->locator_set_name, locator_set_name,
18445                    vec_len (locator_set_name));
18446     }
18447   else
18448     {
18449       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18450     }
18451   vec_free (locator_set_name);
18452
18453   /* send it... */
18454   S (mp);
18455
18456   /* Wait for a reply... */
18457   W (ret);
18458   return ret;
18459 }
18460
18461 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18462
18463 static int
18464 api_one_locator_dump (vat_main_t * vam)
18465 {
18466   unformat_input_t *input = vam->input;
18467   vl_api_one_locator_dump_t *mp;
18468   vl_api_control_ping_t *mp_ping;
18469   u8 is_index_set = 0, is_name_set = 0;
18470   u8 *ls_name = 0;
18471   u32 ls_index = ~0;
18472   int ret;
18473
18474   /* Parse args required to build the message */
18475   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18476     {
18477       if (unformat (input, "ls_name %_%v%_", &ls_name))
18478         {
18479           is_name_set = 1;
18480         }
18481       else if (unformat (input, "ls_index %d", &ls_index))
18482         {
18483           is_index_set = 1;
18484         }
18485       else
18486         {
18487           errmsg ("parse error '%U'", format_unformat_error, input);
18488           return -99;
18489         }
18490     }
18491
18492   if (!is_index_set && !is_name_set)
18493     {
18494       errmsg ("error: expected one of index or name!");
18495       return -99;
18496     }
18497
18498   if (is_index_set && is_name_set)
18499     {
18500       errmsg ("error: only one param expected!");
18501       return -99;
18502     }
18503
18504   if (vec_len (ls_name) > 62)
18505     {
18506       errmsg ("error: locator set name too long!");
18507       return -99;
18508     }
18509
18510   if (!vam->json_output)
18511     {
18512       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18513     }
18514
18515   M (ONE_LOCATOR_DUMP, mp);
18516   mp->is_index_set = is_index_set;
18517
18518   if (is_index_set)
18519     mp->ls_index = clib_host_to_net_u32 (ls_index);
18520   else
18521     {
18522       vec_add1 (ls_name, 0);
18523       strncpy ((char *) mp->ls_name, (char *) ls_name,
18524                sizeof (mp->ls_name) - 1);
18525     }
18526
18527   /* send it... */
18528   S (mp);
18529
18530   /* Use a control ping for synchronization */
18531   MPING (CONTROL_PING, mp_ping);
18532   S (mp_ping);
18533
18534   /* Wait for a reply... */
18535   W (ret);
18536   return ret;
18537 }
18538
18539 #define api_lisp_locator_dump api_one_locator_dump
18540
18541 static int
18542 api_one_locator_set_dump (vat_main_t * vam)
18543 {
18544   vl_api_one_locator_set_dump_t *mp;
18545   vl_api_control_ping_t *mp_ping;
18546   unformat_input_t *input = vam->input;
18547   u8 filter = 0;
18548   int ret;
18549
18550   /* Parse args required to build the message */
18551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18552     {
18553       if (unformat (input, "local"))
18554         {
18555           filter = 1;
18556         }
18557       else if (unformat (input, "remote"))
18558         {
18559           filter = 2;
18560         }
18561       else
18562         {
18563           errmsg ("parse error '%U'", format_unformat_error, input);
18564           return -99;
18565         }
18566     }
18567
18568   if (!vam->json_output)
18569     {
18570       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18571     }
18572
18573   M (ONE_LOCATOR_SET_DUMP, mp);
18574
18575   mp->filter = filter;
18576
18577   /* send it... */
18578   S (mp);
18579
18580   /* Use a control ping for synchronization */
18581   MPING (CONTROL_PING, mp_ping);
18582   S (mp_ping);
18583
18584   /* Wait for a reply... */
18585   W (ret);
18586   return ret;
18587 }
18588
18589 #define api_lisp_locator_set_dump api_one_locator_set_dump
18590
18591 static int
18592 api_one_eid_table_map_dump (vat_main_t * vam)
18593 {
18594   u8 is_l2 = 0;
18595   u8 mode_set = 0;
18596   unformat_input_t *input = vam->input;
18597   vl_api_one_eid_table_map_dump_t *mp;
18598   vl_api_control_ping_t *mp_ping;
18599   int ret;
18600
18601   /* Parse args required to build the message */
18602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18603     {
18604       if (unformat (input, "l2"))
18605         {
18606           is_l2 = 1;
18607           mode_set = 1;
18608         }
18609       else if (unformat (input, "l3"))
18610         {
18611           is_l2 = 0;
18612           mode_set = 1;
18613         }
18614       else
18615         {
18616           errmsg ("parse error '%U'", format_unformat_error, input);
18617           return -99;
18618         }
18619     }
18620
18621   if (!mode_set)
18622     {
18623       errmsg ("expected one of 'l2' or 'l3' parameter!");
18624       return -99;
18625     }
18626
18627   if (!vam->json_output)
18628     {
18629       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18630     }
18631
18632   M (ONE_EID_TABLE_MAP_DUMP, mp);
18633   mp->is_l2 = is_l2;
18634
18635   /* send it... */
18636   S (mp);
18637
18638   /* Use a control ping for synchronization */
18639   MPING (CONTROL_PING, mp_ping);
18640   S (mp_ping);
18641
18642   /* Wait for a reply... */
18643   W (ret);
18644   return ret;
18645 }
18646
18647 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18648
18649 static int
18650 api_one_eid_table_vni_dump (vat_main_t * vam)
18651 {
18652   vl_api_one_eid_table_vni_dump_t *mp;
18653   vl_api_control_ping_t *mp_ping;
18654   int ret;
18655
18656   if (!vam->json_output)
18657     {
18658       print (vam->ofp, "VNI");
18659     }
18660
18661   M (ONE_EID_TABLE_VNI_DUMP, mp);
18662
18663   /* send it... */
18664   S (mp);
18665
18666   /* Use a control ping for synchronization */
18667   MPING (CONTROL_PING, mp_ping);
18668   S (mp_ping);
18669
18670   /* Wait for a reply... */
18671   W (ret);
18672   return ret;
18673 }
18674
18675 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18676
18677 static int
18678 api_one_eid_table_dump (vat_main_t * vam)
18679 {
18680   unformat_input_t *i = vam->input;
18681   vl_api_one_eid_table_dump_t *mp;
18682   vl_api_control_ping_t *mp_ping;
18683   struct in_addr ip4;
18684   struct in6_addr ip6;
18685   u8 mac[6];
18686   u8 eid_type = ~0, eid_set = 0;
18687   u32 prefix_length = ~0, t, vni = 0;
18688   u8 filter = 0;
18689   int ret;
18690   lisp_nsh_api_t nsh;
18691
18692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18693     {
18694       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18695         {
18696           eid_set = 1;
18697           eid_type = 0;
18698           prefix_length = t;
18699         }
18700       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18701         {
18702           eid_set = 1;
18703           eid_type = 1;
18704           prefix_length = t;
18705         }
18706       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18707         {
18708           eid_set = 1;
18709           eid_type = 2;
18710         }
18711       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18712         {
18713           eid_set = 1;
18714           eid_type = 3;
18715         }
18716       else if (unformat (i, "vni %d", &t))
18717         {
18718           vni = t;
18719         }
18720       else if (unformat (i, "local"))
18721         {
18722           filter = 1;
18723         }
18724       else if (unformat (i, "remote"))
18725         {
18726           filter = 2;
18727         }
18728       else
18729         {
18730           errmsg ("parse error '%U'", format_unformat_error, i);
18731           return -99;
18732         }
18733     }
18734
18735   if (!vam->json_output)
18736     {
18737       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18738              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18739     }
18740
18741   M (ONE_EID_TABLE_DUMP, mp);
18742
18743   mp->filter = filter;
18744   if (eid_set)
18745     {
18746       mp->eid_set = 1;
18747       mp->vni = htonl (vni);
18748       mp->eid_type = eid_type;
18749       switch (eid_type)
18750         {
18751         case 0:
18752           mp->prefix_length = prefix_length;
18753           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18754           break;
18755         case 1:
18756           mp->prefix_length = prefix_length;
18757           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18758           break;
18759         case 2:
18760           clib_memcpy (mp->eid, mac, sizeof (mac));
18761           break;
18762         case 3:
18763           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18764           break;
18765         default:
18766           errmsg ("unknown EID type %d!", eid_type);
18767           return -99;
18768         }
18769     }
18770
18771   /* send it... */
18772   S (mp);
18773
18774   /* Use a control ping for synchronization */
18775   MPING (CONTROL_PING, mp_ping);
18776   S (mp_ping);
18777
18778   /* Wait for a reply... */
18779   W (ret);
18780   return ret;
18781 }
18782
18783 #define api_lisp_eid_table_dump api_one_eid_table_dump
18784
18785 static int
18786 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18787 {
18788   unformat_input_t *i = vam->input;
18789   vl_api_gpe_fwd_entries_get_t *mp;
18790   u8 vni_set = 0;
18791   u32 vni = ~0;
18792   int ret;
18793
18794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18795     {
18796       if (unformat (i, "vni %d", &vni))
18797         {
18798           vni_set = 1;
18799         }
18800       else
18801         {
18802           errmsg ("parse error '%U'", format_unformat_error, i);
18803           return -99;
18804         }
18805     }
18806
18807   if (!vni_set)
18808     {
18809       errmsg ("vni not set!");
18810       return -99;
18811     }
18812
18813   if (!vam->json_output)
18814     {
18815       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18816              "leid", "reid");
18817     }
18818
18819   M (GPE_FWD_ENTRIES_GET, mp);
18820   mp->vni = clib_host_to_net_u32 (vni);
18821
18822   /* send it... */
18823   S (mp);
18824
18825   /* Wait for a reply... */
18826   W (ret);
18827   return ret;
18828 }
18829
18830 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18831 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18832 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18833 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18834 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18835 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18836 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18837 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18838
18839 static int
18840 api_one_adjacencies_get (vat_main_t * vam)
18841 {
18842   unformat_input_t *i = vam->input;
18843   vl_api_one_adjacencies_get_t *mp;
18844   u8 vni_set = 0;
18845   u32 vni = ~0;
18846   int ret;
18847
18848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18849     {
18850       if (unformat (i, "vni %d", &vni))
18851         {
18852           vni_set = 1;
18853         }
18854       else
18855         {
18856           errmsg ("parse error '%U'", format_unformat_error, i);
18857           return -99;
18858         }
18859     }
18860
18861   if (!vni_set)
18862     {
18863       errmsg ("vni not set!");
18864       return -99;
18865     }
18866
18867   if (!vam->json_output)
18868     {
18869       print (vam->ofp, "%s %40s", "leid", "reid");
18870     }
18871
18872   M (ONE_ADJACENCIES_GET, mp);
18873   mp->vni = clib_host_to_net_u32 (vni);
18874
18875   /* send it... */
18876   S (mp);
18877
18878   /* Wait for a reply... */
18879   W (ret);
18880   return ret;
18881 }
18882
18883 #define api_lisp_adjacencies_get api_one_adjacencies_get
18884
18885 static int
18886 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18887 {
18888   unformat_input_t *i = vam->input;
18889   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18890   int ret;
18891   u8 ip_family_set = 0, is_ip4 = 1;
18892
18893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18894     {
18895       if (unformat (i, "ip4"))
18896         {
18897           ip_family_set = 1;
18898           is_ip4 = 1;
18899         }
18900       else if (unformat (i, "ip6"))
18901         {
18902           ip_family_set = 1;
18903           is_ip4 = 0;
18904         }
18905       else
18906         {
18907           errmsg ("parse error '%U'", format_unformat_error, i);
18908           return -99;
18909         }
18910     }
18911
18912   if (!ip_family_set)
18913     {
18914       errmsg ("ip family not set!");
18915       return -99;
18916     }
18917
18918   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18919   mp->is_ip4 = is_ip4;
18920
18921   /* send it... */
18922   S (mp);
18923
18924   /* Wait for a reply... */
18925   W (ret);
18926   return ret;
18927 }
18928
18929 static int
18930 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18931 {
18932   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18933   int ret;
18934
18935   if (!vam->json_output)
18936     {
18937       print (vam->ofp, "VNIs");
18938     }
18939
18940   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18941
18942   /* send it... */
18943   S (mp);
18944
18945   /* Wait for a reply... */
18946   W (ret);
18947   return ret;
18948 }
18949
18950 static int
18951 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18952 {
18953   unformat_input_t *i = vam->input;
18954   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18955   int ret = 0;
18956   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18957   struct in_addr ip4;
18958   struct in6_addr ip6;
18959   u32 table_id = 0, nh_sw_if_index = ~0;
18960
18961   memset (&ip4, 0, sizeof (ip4));
18962   memset (&ip6, 0, sizeof (ip6));
18963
18964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18965     {
18966       if (unformat (i, "del"))
18967         is_add = 0;
18968       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18969                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18970         {
18971           ip_set = 1;
18972           is_ip4 = 1;
18973         }
18974       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18975                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18976         {
18977           ip_set = 1;
18978           is_ip4 = 0;
18979         }
18980       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18981         {
18982           ip_set = 1;
18983           is_ip4 = 1;
18984           nh_sw_if_index = ~0;
18985         }
18986       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18987         {
18988           ip_set = 1;
18989           is_ip4 = 0;
18990           nh_sw_if_index = ~0;
18991         }
18992       else if (unformat (i, "table %d", &table_id))
18993         ;
18994       else
18995         {
18996           errmsg ("parse error '%U'", format_unformat_error, i);
18997           return -99;
18998         }
18999     }
19000
19001   if (!ip_set)
19002     {
19003       errmsg ("nh addr not set!");
19004       return -99;
19005     }
19006
19007   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19008   mp->is_add = is_add;
19009   mp->table_id = clib_host_to_net_u32 (table_id);
19010   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19011   mp->is_ip4 = is_ip4;
19012   if (is_ip4)
19013     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19014   else
19015     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19016
19017   /* send it... */
19018   S (mp);
19019
19020   /* Wait for a reply... */
19021   W (ret);
19022   return ret;
19023 }
19024
19025 static int
19026 api_one_map_server_dump (vat_main_t * vam)
19027 {
19028   vl_api_one_map_server_dump_t *mp;
19029   vl_api_control_ping_t *mp_ping;
19030   int ret;
19031
19032   if (!vam->json_output)
19033     {
19034       print (vam->ofp, "%=20s", "Map server");
19035     }
19036
19037   M (ONE_MAP_SERVER_DUMP, mp);
19038   /* send it... */
19039   S (mp);
19040
19041   /* Use a control ping for synchronization */
19042   MPING (CONTROL_PING, mp_ping);
19043   S (mp_ping);
19044
19045   /* Wait for a reply... */
19046   W (ret);
19047   return ret;
19048 }
19049
19050 #define api_lisp_map_server_dump api_one_map_server_dump
19051
19052 static int
19053 api_one_map_resolver_dump (vat_main_t * vam)
19054 {
19055   vl_api_one_map_resolver_dump_t *mp;
19056   vl_api_control_ping_t *mp_ping;
19057   int ret;
19058
19059   if (!vam->json_output)
19060     {
19061       print (vam->ofp, "%=20s", "Map resolver");
19062     }
19063
19064   M (ONE_MAP_RESOLVER_DUMP, mp);
19065   /* send it... */
19066   S (mp);
19067
19068   /* Use a control ping for synchronization */
19069   MPING (CONTROL_PING, mp_ping);
19070   S (mp_ping);
19071
19072   /* Wait for a reply... */
19073   W (ret);
19074   return ret;
19075 }
19076
19077 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19078
19079 static int
19080 api_one_stats_flush (vat_main_t * vam)
19081 {
19082   vl_api_one_stats_flush_t *mp;
19083   int ret = 0;
19084
19085   M (ONE_STATS_FLUSH, mp);
19086   S (mp);
19087   W (ret);
19088   return ret;
19089 }
19090
19091 static int
19092 api_one_stats_dump (vat_main_t * vam)
19093 {
19094   vl_api_one_stats_dump_t *mp;
19095   vl_api_control_ping_t *mp_ping;
19096   int ret;
19097
19098   M (ONE_STATS_DUMP, mp);
19099   /* send it... */
19100   S (mp);
19101
19102   /* Use a control ping for synchronization */
19103   MPING (CONTROL_PING, mp_ping);
19104   S (mp_ping);
19105
19106   /* Wait for a reply... */
19107   W (ret);
19108   return ret;
19109 }
19110
19111 static int
19112 api_show_one_status (vat_main_t * vam)
19113 {
19114   vl_api_show_one_status_t *mp;
19115   int ret;
19116
19117   if (!vam->json_output)
19118     {
19119       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19120     }
19121
19122   M (SHOW_ONE_STATUS, mp);
19123   /* send it... */
19124   S (mp);
19125   /* Wait for a reply... */
19126   W (ret);
19127   return ret;
19128 }
19129
19130 #define api_show_lisp_status api_show_one_status
19131
19132 static int
19133 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19134 {
19135   vl_api_gpe_fwd_entry_path_dump_t *mp;
19136   vl_api_control_ping_t *mp_ping;
19137   unformat_input_t *i = vam->input;
19138   u32 fwd_entry_index = ~0;
19139   int ret;
19140
19141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19142     {
19143       if (unformat (i, "index %d", &fwd_entry_index))
19144         ;
19145       else
19146         break;
19147     }
19148
19149   if (~0 == fwd_entry_index)
19150     {
19151       errmsg ("no index specified!");
19152       return -99;
19153     }
19154
19155   if (!vam->json_output)
19156     {
19157       print (vam->ofp, "first line");
19158     }
19159
19160   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19161
19162   /* send it... */
19163   S (mp);
19164   /* Use a control ping for synchronization */
19165   MPING (CONTROL_PING, mp_ping);
19166   S (mp_ping);
19167
19168   /* Wait for a reply... */
19169   W (ret);
19170   return ret;
19171 }
19172
19173 static int
19174 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19175 {
19176   vl_api_one_get_map_request_itr_rlocs_t *mp;
19177   int ret;
19178
19179   if (!vam->json_output)
19180     {
19181       print (vam->ofp, "%=20s", "itr-rlocs:");
19182     }
19183
19184   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19185   /* send it... */
19186   S (mp);
19187   /* Wait for a reply... */
19188   W (ret);
19189   return ret;
19190 }
19191
19192 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19193
19194 static int
19195 api_af_packet_create (vat_main_t * vam)
19196 {
19197   unformat_input_t *i = vam->input;
19198   vl_api_af_packet_create_t *mp;
19199   u8 *host_if_name = 0;
19200   u8 hw_addr[6];
19201   u8 random_hw_addr = 1;
19202   int ret;
19203
19204   memset (hw_addr, 0, sizeof (hw_addr));
19205
19206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19207     {
19208       if (unformat (i, "name %s", &host_if_name))
19209         vec_add1 (host_if_name, 0);
19210       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19211         random_hw_addr = 0;
19212       else
19213         break;
19214     }
19215
19216   if (!vec_len (host_if_name))
19217     {
19218       errmsg ("host-interface name must be specified");
19219       return -99;
19220     }
19221
19222   if (vec_len (host_if_name) > 64)
19223     {
19224       errmsg ("host-interface name too long");
19225       return -99;
19226     }
19227
19228   M (AF_PACKET_CREATE, mp);
19229
19230   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19231   clib_memcpy (mp->hw_addr, hw_addr, 6);
19232   mp->use_random_hw_addr = random_hw_addr;
19233   vec_free (host_if_name);
19234
19235   S (mp);
19236
19237   /* *INDENT-OFF* */
19238   W2 (ret,
19239       ({
19240         if (ret == 0)
19241           fprintf (vam->ofp ? vam->ofp : stderr,
19242                    " new sw_if_index = %d\n", vam->sw_if_index);
19243       }));
19244   /* *INDENT-ON* */
19245   return ret;
19246 }
19247
19248 static int
19249 api_af_packet_delete (vat_main_t * vam)
19250 {
19251   unformat_input_t *i = vam->input;
19252   vl_api_af_packet_delete_t *mp;
19253   u8 *host_if_name = 0;
19254   int ret;
19255
19256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19257     {
19258       if (unformat (i, "name %s", &host_if_name))
19259         vec_add1 (host_if_name, 0);
19260       else
19261         break;
19262     }
19263
19264   if (!vec_len (host_if_name))
19265     {
19266       errmsg ("host-interface name must be specified");
19267       return -99;
19268     }
19269
19270   if (vec_len (host_if_name) > 64)
19271     {
19272       errmsg ("host-interface name too long");
19273       return -99;
19274     }
19275
19276   M (AF_PACKET_DELETE, mp);
19277
19278   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19279   vec_free (host_if_name);
19280
19281   S (mp);
19282   W (ret);
19283   return ret;
19284 }
19285
19286 static int
19287 api_policer_add_del (vat_main_t * vam)
19288 {
19289   unformat_input_t *i = vam->input;
19290   vl_api_policer_add_del_t *mp;
19291   u8 is_add = 1;
19292   u8 *name = 0;
19293   u32 cir = 0;
19294   u32 eir = 0;
19295   u64 cb = 0;
19296   u64 eb = 0;
19297   u8 rate_type = 0;
19298   u8 round_type = 0;
19299   u8 type = 0;
19300   u8 color_aware = 0;
19301   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19302   int ret;
19303
19304   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19305   conform_action.dscp = 0;
19306   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19307   exceed_action.dscp = 0;
19308   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19309   violate_action.dscp = 0;
19310
19311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19312     {
19313       if (unformat (i, "del"))
19314         is_add = 0;
19315       else if (unformat (i, "name %s", &name))
19316         vec_add1 (name, 0);
19317       else if (unformat (i, "cir %u", &cir))
19318         ;
19319       else if (unformat (i, "eir %u", &eir))
19320         ;
19321       else if (unformat (i, "cb %u", &cb))
19322         ;
19323       else if (unformat (i, "eb %u", &eb))
19324         ;
19325       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19326                          &rate_type))
19327         ;
19328       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19329                          &round_type))
19330         ;
19331       else if (unformat (i, "type %U", unformat_policer_type, &type))
19332         ;
19333       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19334                          &conform_action))
19335         ;
19336       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19337                          &exceed_action))
19338         ;
19339       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19340                          &violate_action))
19341         ;
19342       else if (unformat (i, "color-aware"))
19343         color_aware = 1;
19344       else
19345         break;
19346     }
19347
19348   if (!vec_len (name))
19349     {
19350       errmsg ("policer name must be specified");
19351       return -99;
19352     }
19353
19354   if (vec_len (name) > 64)
19355     {
19356       errmsg ("policer name too long");
19357       return -99;
19358     }
19359
19360   M (POLICER_ADD_DEL, mp);
19361
19362   clib_memcpy (mp->name, name, vec_len (name));
19363   vec_free (name);
19364   mp->is_add = is_add;
19365   mp->cir = ntohl (cir);
19366   mp->eir = ntohl (eir);
19367   mp->cb = clib_net_to_host_u64 (cb);
19368   mp->eb = clib_net_to_host_u64 (eb);
19369   mp->rate_type = rate_type;
19370   mp->round_type = round_type;
19371   mp->type = type;
19372   mp->conform_action_type = conform_action.action_type;
19373   mp->conform_dscp = conform_action.dscp;
19374   mp->exceed_action_type = exceed_action.action_type;
19375   mp->exceed_dscp = exceed_action.dscp;
19376   mp->violate_action_type = violate_action.action_type;
19377   mp->violate_dscp = violate_action.dscp;
19378   mp->color_aware = color_aware;
19379
19380   S (mp);
19381   W (ret);
19382   return ret;
19383 }
19384
19385 static int
19386 api_policer_dump (vat_main_t * vam)
19387 {
19388   unformat_input_t *i = vam->input;
19389   vl_api_policer_dump_t *mp;
19390   vl_api_control_ping_t *mp_ping;
19391   u8 *match_name = 0;
19392   u8 match_name_valid = 0;
19393   int ret;
19394
19395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19396     {
19397       if (unformat (i, "name %s", &match_name))
19398         {
19399           vec_add1 (match_name, 0);
19400           match_name_valid = 1;
19401         }
19402       else
19403         break;
19404     }
19405
19406   M (POLICER_DUMP, mp);
19407   mp->match_name_valid = match_name_valid;
19408   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19409   vec_free (match_name);
19410   /* send it... */
19411   S (mp);
19412
19413   /* Use a control ping for synchronization */
19414   MPING (CONTROL_PING, mp_ping);
19415   S (mp_ping);
19416
19417   /* Wait for a reply... */
19418   W (ret);
19419   return ret;
19420 }
19421
19422 static int
19423 api_policer_classify_set_interface (vat_main_t * vam)
19424 {
19425   unformat_input_t *i = vam->input;
19426   vl_api_policer_classify_set_interface_t *mp;
19427   u32 sw_if_index;
19428   int sw_if_index_set;
19429   u32 ip4_table_index = ~0;
19430   u32 ip6_table_index = ~0;
19431   u32 l2_table_index = ~0;
19432   u8 is_add = 1;
19433   int ret;
19434
19435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19436     {
19437       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19438         sw_if_index_set = 1;
19439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19440         sw_if_index_set = 1;
19441       else if (unformat (i, "del"))
19442         is_add = 0;
19443       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19444         ;
19445       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19446         ;
19447       else if (unformat (i, "l2-table %d", &l2_table_index))
19448         ;
19449       else
19450         {
19451           clib_warning ("parse error '%U'", format_unformat_error, i);
19452           return -99;
19453         }
19454     }
19455
19456   if (sw_if_index_set == 0)
19457     {
19458       errmsg ("missing interface name or sw_if_index");
19459       return -99;
19460     }
19461
19462   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19463
19464   mp->sw_if_index = ntohl (sw_if_index);
19465   mp->ip4_table_index = ntohl (ip4_table_index);
19466   mp->ip6_table_index = ntohl (ip6_table_index);
19467   mp->l2_table_index = ntohl (l2_table_index);
19468   mp->is_add = is_add;
19469
19470   S (mp);
19471   W (ret);
19472   return ret;
19473 }
19474
19475 static int
19476 api_policer_classify_dump (vat_main_t * vam)
19477 {
19478   unformat_input_t *i = vam->input;
19479   vl_api_policer_classify_dump_t *mp;
19480   vl_api_control_ping_t *mp_ping;
19481   u8 type = POLICER_CLASSIFY_N_TABLES;
19482   int ret;
19483
19484   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19485     ;
19486   else
19487     {
19488       errmsg ("classify table type must be specified");
19489       return -99;
19490     }
19491
19492   if (!vam->json_output)
19493     {
19494       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19495     }
19496
19497   M (POLICER_CLASSIFY_DUMP, mp);
19498   mp->type = type;
19499   /* send it... */
19500   S (mp);
19501
19502   /* Use a control ping for synchronization */
19503   MPING (CONTROL_PING, mp_ping);
19504   S (mp_ping);
19505
19506   /* Wait for a reply... */
19507   W (ret);
19508   return ret;
19509 }
19510
19511 static int
19512 api_netmap_create (vat_main_t * vam)
19513 {
19514   unformat_input_t *i = vam->input;
19515   vl_api_netmap_create_t *mp;
19516   u8 *if_name = 0;
19517   u8 hw_addr[6];
19518   u8 random_hw_addr = 1;
19519   u8 is_pipe = 0;
19520   u8 is_master = 0;
19521   int ret;
19522
19523   memset (hw_addr, 0, sizeof (hw_addr));
19524
19525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19526     {
19527       if (unformat (i, "name %s", &if_name))
19528         vec_add1 (if_name, 0);
19529       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19530         random_hw_addr = 0;
19531       else if (unformat (i, "pipe"))
19532         is_pipe = 1;
19533       else if (unformat (i, "master"))
19534         is_master = 1;
19535       else if (unformat (i, "slave"))
19536         is_master = 0;
19537       else
19538         break;
19539     }
19540
19541   if (!vec_len (if_name))
19542     {
19543       errmsg ("interface name must be specified");
19544       return -99;
19545     }
19546
19547   if (vec_len (if_name) > 64)
19548     {
19549       errmsg ("interface name too long");
19550       return -99;
19551     }
19552
19553   M (NETMAP_CREATE, mp);
19554
19555   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19556   clib_memcpy (mp->hw_addr, hw_addr, 6);
19557   mp->use_random_hw_addr = random_hw_addr;
19558   mp->is_pipe = is_pipe;
19559   mp->is_master = is_master;
19560   vec_free (if_name);
19561
19562   S (mp);
19563   W (ret);
19564   return ret;
19565 }
19566
19567 static int
19568 api_netmap_delete (vat_main_t * vam)
19569 {
19570   unformat_input_t *i = vam->input;
19571   vl_api_netmap_delete_t *mp;
19572   u8 *if_name = 0;
19573   int ret;
19574
19575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19576     {
19577       if (unformat (i, "name %s", &if_name))
19578         vec_add1 (if_name, 0);
19579       else
19580         break;
19581     }
19582
19583   if (!vec_len (if_name))
19584     {
19585       errmsg ("interface name must be specified");
19586       return -99;
19587     }
19588
19589   if (vec_len (if_name) > 64)
19590     {
19591       errmsg ("interface name too long");
19592       return -99;
19593     }
19594
19595   M (NETMAP_DELETE, mp);
19596
19597   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19598   vec_free (if_name);
19599
19600   S (mp);
19601   W (ret);
19602   return ret;
19603 }
19604
19605 static void
19606 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19607 {
19608   if (fp->afi == IP46_TYPE_IP6)
19609     print (vam->ofp,
19610            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19611            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19612            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19613            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19614            format_ip6_address, fp->next_hop);
19615   else if (fp->afi == IP46_TYPE_IP4)
19616     print (vam->ofp,
19617            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19618            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19619            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19620            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19621            format_ip4_address, fp->next_hop);
19622 }
19623
19624 static void
19625 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19626                                  vl_api_fib_path2_t * fp)
19627 {
19628   struct in_addr ip4;
19629   struct in6_addr ip6;
19630
19631   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19632   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19633   vat_json_object_add_uint (node, "is_local", fp->is_local);
19634   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19635   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19636   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19637   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19638   if (fp->afi == IP46_TYPE_IP4)
19639     {
19640       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19641       vat_json_object_add_ip4 (node, "next_hop", ip4);
19642     }
19643   else if (fp->afi == IP46_TYPE_IP6)
19644     {
19645       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19646       vat_json_object_add_ip6 (node, "next_hop", ip6);
19647     }
19648 }
19649
19650 static void
19651 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19652 {
19653   vat_main_t *vam = &vat_main;
19654   int count = ntohl (mp->mt_count);
19655   vl_api_fib_path2_t *fp;
19656   i32 i;
19657
19658   print (vam->ofp, "[%d]: sw_if_index %d via:",
19659          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19660   fp = mp->mt_paths;
19661   for (i = 0; i < count; i++)
19662     {
19663       vl_api_mpls_fib_path_print (vam, fp);
19664       fp++;
19665     }
19666
19667   print (vam->ofp, "");
19668 }
19669
19670 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19671 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19672
19673 static void
19674 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19675 {
19676   vat_main_t *vam = &vat_main;
19677   vat_json_node_t *node = NULL;
19678   int count = ntohl (mp->mt_count);
19679   vl_api_fib_path2_t *fp;
19680   i32 i;
19681
19682   if (VAT_JSON_ARRAY != vam->json_tree.type)
19683     {
19684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19685       vat_json_init_array (&vam->json_tree);
19686     }
19687   node = vat_json_array_add (&vam->json_tree);
19688
19689   vat_json_init_object (node);
19690   vat_json_object_add_uint (node, "tunnel_index",
19691                             ntohl (mp->mt_tunnel_index));
19692   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19693
19694   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19695
19696   fp = mp->mt_paths;
19697   for (i = 0; i < count; i++)
19698     {
19699       vl_api_mpls_fib_path_json_print (node, fp);
19700       fp++;
19701     }
19702 }
19703
19704 static int
19705 api_mpls_tunnel_dump (vat_main_t * vam)
19706 {
19707   vl_api_mpls_tunnel_dump_t *mp;
19708   vl_api_control_ping_t *mp_ping;
19709   i32 index = -1;
19710   int ret;
19711
19712   /* Parse args required to build the message */
19713   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19714     {
19715       if (!unformat (vam->input, "tunnel_index %d", &index))
19716         {
19717           index = -1;
19718           break;
19719         }
19720     }
19721
19722   print (vam->ofp, "  tunnel_index %d", index);
19723
19724   M (MPLS_TUNNEL_DUMP, mp);
19725   mp->tunnel_index = htonl (index);
19726   S (mp);
19727
19728   /* Use a control ping for synchronization */
19729   MPING (CONTROL_PING, mp_ping);
19730   S (mp_ping);
19731
19732   W (ret);
19733   return ret;
19734 }
19735
19736 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19737 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19738
19739
19740 static void
19741 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19742 {
19743   vat_main_t *vam = &vat_main;
19744   int count = ntohl (mp->count);
19745   vl_api_fib_path2_t *fp;
19746   int i;
19747
19748   print (vam->ofp,
19749          "table-id %d, label %u, ess_bit %u",
19750          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19751   fp = mp->path;
19752   for (i = 0; i < count; i++)
19753     {
19754       vl_api_mpls_fib_path_print (vam, fp);
19755       fp++;
19756     }
19757 }
19758
19759 static void vl_api_mpls_fib_details_t_handler_json
19760   (vl_api_mpls_fib_details_t * mp)
19761 {
19762   vat_main_t *vam = &vat_main;
19763   int count = ntohl (mp->count);
19764   vat_json_node_t *node = NULL;
19765   vl_api_fib_path2_t *fp;
19766   int i;
19767
19768   if (VAT_JSON_ARRAY != vam->json_tree.type)
19769     {
19770       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19771       vat_json_init_array (&vam->json_tree);
19772     }
19773   node = vat_json_array_add (&vam->json_tree);
19774
19775   vat_json_init_object (node);
19776   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19777   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19778   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19779   vat_json_object_add_uint (node, "path_count", count);
19780   fp = mp->path;
19781   for (i = 0; i < count; i++)
19782     {
19783       vl_api_mpls_fib_path_json_print (node, fp);
19784       fp++;
19785     }
19786 }
19787
19788 static int
19789 api_mpls_fib_dump (vat_main_t * vam)
19790 {
19791   vl_api_mpls_fib_dump_t *mp;
19792   vl_api_control_ping_t *mp_ping;
19793   int ret;
19794
19795   M (MPLS_FIB_DUMP, mp);
19796   S (mp);
19797
19798   /* Use a control ping for synchronization */
19799   MPING (CONTROL_PING, mp_ping);
19800   S (mp_ping);
19801
19802   W (ret);
19803   return ret;
19804 }
19805
19806 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19807 #define vl_api_ip_fib_details_t_print vl_noop_handler
19808
19809 static void
19810 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19811 {
19812   vat_main_t *vam = &vat_main;
19813   int count = ntohl (mp->count);
19814   vl_api_fib_path_t *fp;
19815   int i;
19816
19817   print (vam->ofp,
19818          "table-id %d, prefix %U/%d",
19819          ntohl (mp->table_id), format_ip4_address, mp->address,
19820          mp->address_length);
19821   fp = mp->path;
19822   for (i = 0; i < count; i++)
19823     {
19824       if (fp->afi == IP46_TYPE_IP6)
19825         print (vam->ofp,
19826                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19827                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19828                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19829                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19830                format_ip6_address, fp->next_hop);
19831       else if (fp->afi == IP46_TYPE_IP4)
19832         print (vam->ofp,
19833                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19834                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19835                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19836                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19837                format_ip4_address, fp->next_hop);
19838       fp++;
19839     }
19840 }
19841
19842 static void vl_api_ip_fib_details_t_handler_json
19843   (vl_api_ip_fib_details_t * mp)
19844 {
19845   vat_main_t *vam = &vat_main;
19846   int count = ntohl (mp->count);
19847   vat_json_node_t *node = NULL;
19848   struct in_addr ip4;
19849   struct in6_addr ip6;
19850   vl_api_fib_path_t *fp;
19851   int i;
19852
19853   if (VAT_JSON_ARRAY != vam->json_tree.type)
19854     {
19855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19856       vat_json_init_array (&vam->json_tree);
19857     }
19858   node = vat_json_array_add (&vam->json_tree);
19859
19860   vat_json_init_object (node);
19861   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19862   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19863   vat_json_object_add_ip4 (node, "prefix", ip4);
19864   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19865   vat_json_object_add_uint (node, "path_count", count);
19866   fp = mp->path;
19867   for (i = 0; i < count; i++)
19868     {
19869       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19870       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19871       vat_json_object_add_uint (node, "is_local", fp->is_local);
19872       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19873       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19874       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19875       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19876       if (fp->afi == IP46_TYPE_IP4)
19877         {
19878           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19879           vat_json_object_add_ip4 (node, "next_hop", ip4);
19880         }
19881       else if (fp->afi == IP46_TYPE_IP6)
19882         {
19883           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19884           vat_json_object_add_ip6 (node, "next_hop", ip6);
19885         }
19886     }
19887 }
19888
19889 static int
19890 api_ip_fib_dump (vat_main_t * vam)
19891 {
19892   vl_api_ip_fib_dump_t *mp;
19893   vl_api_control_ping_t *mp_ping;
19894   int ret;
19895
19896   M (IP_FIB_DUMP, mp);
19897   S (mp);
19898
19899   /* Use a control ping for synchronization */
19900   MPING (CONTROL_PING, mp_ping);
19901   S (mp_ping);
19902
19903   W (ret);
19904   return ret;
19905 }
19906
19907 static int
19908 api_ip_mfib_dump (vat_main_t * vam)
19909 {
19910   vl_api_ip_mfib_dump_t *mp;
19911   vl_api_control_ping_t *mp_ping;
19912   int ret;
19913
19914   M (IP_MFIB_DUMP, mp);
19915   S (mp);
19916
19917   /* Use a control ping for synchronization */
19918   MPING (CONTROL_PING, mp_ping);
19919   S (mp_ping);
19920
19921   W (ret);
19922   return ret;
19923 }
19924
19925 static void vl_api_ip_neighbor_details_t_handler
19926   (vl_api_ip_neighbor_details_t * mp)
19927 {
19928   vat_main_t *vam = &vat_main;
19929
19930   print (vam->ofp, "%c %U %U",
19931          (mp->is_static) ? 'S' : 'D',
19932          format_ethernet_address, &mp->mac_address,
19933          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19934          &mp->ip_address);
19935 }
19936
19937 static void vl_api_ip_neighbor_details_t_handler_json
19938   (vl_api_ip_neighbor_details_t * mp)
19939 {
19940
19941   vat_main_t *vam = &vat_main;
19942   vat_json_node_t *node;
19943   struct in_addr ip4;
19944   struct in6_addr ip6;
19945
19946   if (VAT_JSON_ARRAY != vam->json_tree.type)
19947     {
19948       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19949       vat_json_init_array (&vam->json_tree);
19950     }
19951   node = vat_json_array_add (&vam->json_tree);
19952
19953   vat_json_init_object (node);
19954   vat_json_object_add_string_copy (node, "flag",
19955                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19956                                    "dynamic");
19957
19958   vat_json_object_add_string_copy (node, "link_layer",
19959                                    format (0, "%U", format_ethernet_address,
19960                                            &mp->mac_address));
19961
19962   if (mp->is_ipv6)
19963     {
19964       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19965       vat_json_object_add_ip6 (node, "ip_address", ip6);
19966     }
19967   else
19968     {
19969       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19970       vat_json_object_add_ip4 (node, "ip_address", ip4);
19971     }
19972 }
19973
19974 static int
19975 api_ip_neighbor_dump (vat_main_t * vam)
19976 {
19977   unformat_input_t *i = vam->input;
19978   vl_api_ip_neighbor_dump_t *mp;
19979   vl_api_control_ping_t *mp_ping;
19980   u8 is_ipv6 = 0;
19981   u32 sw_if_index = ~0;
19982   int ret;
19983
19984   /* Parse args required to build the message */
19985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19986     {
19987       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19988         ;
19989       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19990         ;
19991       else if (unformat (i, "ip6"))
19992         is_ipv6 = 1;
19993       else
19994         break;
19995     }
19996
19997   if (sw_if_index == ~0)
19998     {
19999       errmsg ("missing interface name or sw_if_index");
20000       return -99;
20001     }
20002
20003   M (IP_NEIGHBOR_DUMP, mp);
20004   mp->is_ipv6 = (u8) is_ipv6;
20005   mp->sw_if_index = ntohl (sw_if_index);
20006   S (mp);
20007
20008   /* Use a control ping for synchronization */
20009   MPING (CONTROL_PING, mp_ping);
20010   S (mp_ping);
20011
20012   W (ret);
20013   return ret;
20014 }
20015
20016 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20017 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20018
20019 static void
20020 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20021 {
20022   vat_main_t *vam = &vat_main;
20023   int count = ntohl (mp->count);
20024   vl_api_fib_path_t *fp;
20025   int i;
20026
20027   print (vam->ofp,
20028          "table-id %d, prefix %U/%d",
20029          ntohl (mp->table_id), format_ip6_address, mp->address,
20030          mp->address_length);
20031   fp = mp->path;
20032   for (i = 0; i < count; i++)
20033     {
20034       if (fp->afi == IP46_TYPE_IP6)
20035         print (vam->ofp,
20036                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20037                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20038                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20039                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20040                format_ip6_address, fp->next_hop);
20041       else if (fp->afi == IP46_TYPE_IP4)
20042         print (vam->ofp,
20043                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20044                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20045                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20046                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20047                format_ip4_address, fp->next_hop);
20048       fp++;
20049     }
20050 }
20051
20052 static void vl_api_ip6_fib_details_t_handler_json
20053   (vl_api_ip6_fib_details_t * mp)
20054 {
20055   vat_main_t *vam = &vat_main;
20056   int count = ntohl (mp->count);
20057   vat_json_node_t *node = NULL;
20058   struct in_addr ip4;
20059   struct in6_addr ip6;
20060   vl_api_fib_path_t *fp;
20061   int i;
20062
20063   if (VAT_JSON_ARRAY != vam->json_tree.type)
20064     {
20065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20066       vat_json_init_array (&vam->json_tree);
20067     }
20068   node = vat_json_array_add (&vam->json_tree);
20069
20070   vat_json_init_object (node);
20071   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20072   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20073   vat_json_object_add_ip6 (node, "prefix", ip6);
20074   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20075   vat_json_object_add_uint (node, "path_count", count);
20076   fp = mp->path;
20077   for (i = 0; i < count; i++)
20078     {
20079       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20080       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20081       vat_json_object_add_uint (node, "is_local", fp->is_local);
20082       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20083       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20084       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20085       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20086       if (fp->afi == IP46_TYPE_IP4)
20087         {
20088           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20089           vat_json_object_add_ip4 (node, "next_hop", ip4);
20090         }
20091       else if (fp->afi == IP46_TYPE_IP6)
20092         {
20093           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20094           vat_json_object_add_ip6 (node, "next_hop", ip6);
20095         }
20096     }
20097 }
20098
20099 static int
20100 api_ip6_fib_dump (vat_main_t * vam)
20101 {
20102   vl_api_ip6_fib_dump_t *mp;
20103   vl_api_control_ping_t *mp_ping;
20104   int ret;
20105
20106   M (IP6_FIB_DUMP, mp);
20107   S (mp);
20108
20109   /* Use a control ping for synchronization */
20110   MPING (CONTROL_PING, mp_ping);
20111   S (mp_ping);
20112
20113   W (ret);
20114   return ret;
20115 }
20116
20117 static int
20118 api_ip6_mfib_dump (vat_main_t * vam)
20119 {
20120   vl_api_ip6_mfib_dump_t *mp;
20121   vl_api_control_ping_t *mp_ping;
20122   int ret;
20123
20124   M (IP6_MFIB_DUMP, mp);
20125   S (mp);
20126
20127   /* Use a control ping for synchronization */
20128   MPING (CONTROL_PING, mp_ping);
20129   S (mp_ping);
20130
20131   W (ret);
20132   return ret;
20133 }
20134
20135 int
20136 api_classify_table_ids (vat_main_t * vam)
20137 {
20138   vl_api_classify_table_ids_t *mp;
20139   int ret;
20140
20141   /* Construct the API message */
20142   M (CLASSIFY_TABLE_IDS, mp);
20143   mp->context = 0;
20144
20145   S (mp);
20146   W (ret);
20147   return ret;
20148 }
20149
20150 int
20151 api_classify_table_by_interface (vat_main_t * vam)
20152 {
20153   unformat_input_t *input = vam->input;
20154   vl_api_classify_table_by_interface_t *mp;
20155
20156   u32 sw_if_index = ~0;
20157   int ret;
20158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20159     {
20160       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20161         ;
20162       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20163         ;
20164       else
20165         break;
20166     }
20167   if (sw_if_index == ~0)
20168     {
20169       errmsg ("missing interface name or sw_if_index");
20170       return -99;
20171     }
20172
20173   /* Construct the API message */
20174   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20175   mp->context = 0;
20176   mp->sw_if_index = ntohl (sw_if_index);
20177
20178   S (mp);
20179   W (ret);
20180   return ret;
20181 }
20182
20183 int
20184 api_classify_table_info (vat_main_t * vam)
20185 {
20186   unformat_input_t *input = vam->input;
20187   vl_api_classify_table_info_t *mp;
20188
20189   u32 table_id = ~0;
20190   int ret;
20191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20192     {
20193       if (unformat (input, "table_id %d", &table_id))
20194         ;
20195       else
20196         break;
20197     }
20198   if (table_id == ~0)
20199     {
20200       errmsg ("missing table id");
20201       return -99;
20202     }
20203
20204   /* Construct the API message */
20205   M (CLASSIFY_TABLE_INFO, mp);
20206   mp->context = 0;
20207   mp->table_id = ntohl (table_id);
20208
20209   S (mp);
20210   W (ret);
20211   return ret;
20212 }
20213
20214 int
20215 api_classify_session_dump (vat_main_t * vam)
20216 {
20217   unformat_input_t *input = vam->input;
20218   vl_api_classify_session_dump_t *mp;
20219   vl_api_control_ping_t *mp_ping;
20220
20221   u32 table_id = ~0;
20222   int ret;
20223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20224     {
20225       if (unformat (input, "table_id %d", &table_id))
20226         ;
20227       else
20228         break;
20229     }
20230   if (table_id == ~0)
20231     {
20232       errmsg ("missing table id");
20233       return -99;
20234     }
20235
20236   /* Construct the API message */
20237   M (CLASSIFY_SESSION_DUMP, mp);
20238   mp->context = 0;
20239   mp->table_id = ntohl (table_id);
20240   S (mp);
20241
20242   /* Use a control ping for synchronization */
20243   MPING (CONTROL_PING, mp_ping);
20244   S (mp_ping);
20245
20246   W (ret);
20247   return ret;
20248 }
20249
20250 static void
20251 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20252 {
20253   vat_main_t *vam = &vat_main;
20254
20255   print (vam->ofp, "collector_address %U, collector_port %d, "
20256          "src_address %U, vrf_id %d, path_mtu %u, "
20257          "template_interval %u, udp_checksum %d",
20258          format_ip4_address, mp->collector_address,
20259          ntohs (mp->collector_port),
20260          format_ip4_address, mp->src_address,
20261          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20262          ntohl (mp->template_interval), mp->udp_checksum);
20263
20264   vam->retval = 0;
20265   vam->result_ready = 1;
20266 }
20267
20268 static void
20269   vl_api_ipfix_exporter_details_t_handler_json
20270   (vl_api_ipfix_exporter_details_t * mp)
20271 {
20272   vat_main_t *vam = &vat_main;
20273   vat_json_node_t node;
20274   struct in_addr collector_address;
20275   struct in_addr src_address;
20276
20277   vat_json_init_object (&node);
20278   clib_memcpy (&collector_address, &mp->collector_address,
20279                sizeof (collector_address));
20280   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20281   vat_json_object_add_uint (&node, "collector_port",
20282                             ntohs (mp->collector_port));
20283   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20284   vat_json_object_add_ip4 (&node, "src_address", src_address);
20285   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20286   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20287   vat_json_object_add_uint (&node, "template_interval",
20288                             ntohl (mp->template_interval));
20289   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20290
20291   vat_json_print (vam->ofp, &node);
20292   vat_json_free (&node);
20293   vam->retval = 0;
20294   vam->result_ready = 1;
20295 }
20296
20297 int
20298 api_ipfix_exporter_dump (vat_main_t * vam)
20299 {
20300   vl_api_ipfix_exporter_dump_t *mp;
20301   int ret;
20302
20303   /* Construct the API message */
20304   M (IPFIX_EXPORTER_DUMP, mp);
20305   mp->context = 0;
20306
20307   S (mp);
20308   W (ret);
20309   return ret;
20310 }
20311
20312 static int
20313 api_ipfix_classify_stream_dump (vat_main_t * vam)
20314 {
20315   vl_api_ipfix_classify_stream_dump_t *mp;
20316   int ret;
20317
20318   /* Construct the API message */
20319   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20320   mp->context = 0;
20321
20322   S (mp);
20323   W (ret);
20324   return ret;
20325   /* NOTREACHED */
20326   return 0;
20327 }
20328
20329 static void
20330   vl_api_ipfix_classify_stream_details_t_handler
20331   (vl_api_ipfix_classify_stream_details_t * mp)
20332 {
20333   vat_main_t *vam = &vat_main;
20334   print (vam->ofp, "domain_id %d, src_port %d",
20335          ntohl (mp->domain_id), ntohs (mp->src_port));
20336   vam->retval = 0;
20337   vam->result_ready = 1;
20338 }
20339
20340 static void
20341   vl_api_ipfix_classify_stream_details_t_handler_json
20342   (vl_api_ipfix_classify_stream_details_t * mp)
20343 {
20344   vat_main_t *vam = &vat_main;
20345   vat_json_node_t node;
20346
20347   vat_json_init_object (&node);
20348   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20349   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20350
20351   vat_json_print (vam->ofp, &node);
20352   vat_json_free (&node);
20353   vam->retval = 0;
20354   vam->result_ready = 1;
20355 }
20356
20357 static int
20358 api_ipfix_classify_table_dump (vat_main_t * vam)
20359 {
20360   vl_api_ipfix_classify_table_dump_t *mp;
20361   vl_api_control_ping_t *mp_ping;
20362   int ret;
20363
20364   if (!vam->json_output)
20365     {
20366       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20367              "transport_protocol");
20368     }
20369
20370   /* Construct the API message */
20371   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20372
20373   /* send it... */
20374   S (mp);
20375
20376   /* Use a control ping for synchronization */
20377   MPING (CONTROL_PING, mp_ping);
20378   S (mp_ping);
20379
20380   W (ret);
20381   return ret;
20382 }
20383
20384 static void
20385   vl_api_ipfix_classify_table_details_t_handler
20386   (vl_api_ipfix_classify_table_details_t * mp)
20387 {
20388   vat_main_t *vam = &vat_main;
20389   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20390          mp->transport_protocol);
20391 }
20392
20393 static void
20394   vl_api_ipfix_classify_table_details_t_handler_json
20395   (vl_api_ipfix_classify_table_details_t * mp)
20396 {
20397   vat_json_node_t *node = NULL;
20398   vat_main_t *vam = &vat_main;
20399
20400   if (VAT_JSON_ARRAY != vam->json_tree.type)
20401     {
20402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20403       vat_json_init_array (&vam->json_tree);
20404     }
20405
20406   node = vat_json_array_add (&vam->json_tree);
20407   vat_json_init_object (node);
20408
20409   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20410   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20411   vat_json_object_add_uint (node, "transport_protocol",
20412                             mp->transport_protocol);
20413 }
20414
20415 static int
20416 api_sw_interface_span_enable_disable (vat_main_t * vam)
20417 {
20418   unformat_input_t *i = vam->input;
20419   vl_api_sw_interface_span_enable_disable_t *mp;
20420   u32 src_sw_if_index = ~0;
20421   u32 dst_sw_if_index = ~0;
20422   u8 state = 3;
20423   int ret;
20424   u8 is_l2 = 0;
20425
20426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20427     {
20428       if (unformat
20429           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20430         ;
20431       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20432         ;
20433       else
20434         if (unformat
20435             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20436         ;
20437       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20438         ;
20439       else if (unformat (i, "disable"))
20440         state = 0;
20441       else if (unformat (i, "rx"))
20442         state = 1;
20443       else if (unformat (i, "tx"))
20444         state = 2;
20445       else if (unformat (i, "both"))
20446         state = 3;
20447       else if (unformat (i, "l2"))
20448         is_l2 = 1;
20449       else
20450         break;
20451     }
20452
20453   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20454
20455   mp->sw_if_index_from = htonl (src_sw_if_index);
20456   mp->sw_if_index_to = htonl (dst_sw_if_index);
20457   mp->state = state;
20458   mp->is_l2 = is_l2;
20459
20460   S (mp);
20461   W (ret);
20462   return ret;
20463 }
20464
20465 static void
20466 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20467                                             * mp)
20468 {
20469   vat_main_t *vam = &vat_main;
20470   u8 *sw_if_from_name = 0;
20471   u8 *sw_if_to_name = 0;
20472   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20473   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20474   char *states[] = { "none", "rx", "tx", "both" };
20475   hash_pair_t *p;
20476
20477   /* *INDENT-OFF* */
20478   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20479   ({
20480     if ((u32) p->value[0] == sw_if_index_from)
20481       {
20482         sw_if_from_name = (u8 *)(p->key);
20483         if (sw_if_to_name)
20484           break;
20485       }
20486     if ((u32) p->value[0] == sw_if_index_to)
20487       {
20488         sw_if_to_name = (u8 *)(p->key);
20489         if (sw_if_from_name)
20490           break;
20491       }
20492   }));
20493   /* *INDENT-ON* */
20494   print (vam->ofp, "%20s => %20s (%s)",
20495          sw_if_from_name, sw_if_to_name, states[mp->state]);
20496 }
20497
20498 static void
20499   vl_api_sw_interface_span_details_t_handler_json
20500   (vl_api_sw_interface_span_details_t * mp)
20501 {
20502   vat_main_t *vam = &vat_main;
20503   vat_json_node_t *node = NULL;
20504   u8 *sw_if_from_name = 0;
20505   u8 *sw_if_to_name = 0;
20506   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20507   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20508   hash_pair_t *p;
20509
20510   /* *INDENT-OFF* */
20511   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20512   ({
20513     if ((u32) p->value[0] == sw_if_index_from)
20514       {
20515         sw_if_from_name = (u8 *)(p->key);
20516         if (sw_if_to_name)
20517           break;
20518       }
20519     if ((u32) p->value[0] == sw_if_index_to)
20520       {
20521         sw_if_to_name = (u8 *)(p->key);
20522         if (sw_if_from_name)
20523           break;
20524       }
20525   }));
20526   /* *INDENT-ON* */
20527
20528   if (VAT_JSON_ARRAY != vam->json_tree.type)
20529     {
20530       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20531       vat_json_init_array (&vam->json_tree);
20532     }
20533   node = vat_json_array_add (&vam->json_tree);
20534
20535   vat_json_init_object (node);
20536   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20537   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20538   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20539   if (0 != sw_if_to_name)
20540     {
20541       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20542     }
20543   vat_json_object_add_uint (node, "state", mp->state);
20544 }
20545
20546 static int
20547 api_sw_interface_span_dump (vat_main_t * vam)
20548 {
20549   unformat_input_t *input = vam->input;
20550   vl_api_sw_interface_span_dump_t *mp;
20551   vl_api_control_ping_t *mp_ping;
20552   u8 is_l2 = 0;
20553   int ret;
20554
20555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20556     {
20557       if (unformat (input, "l2"))
20558         is_l2 = 1;
20559       else
20560         break;
20561     }
20562
20563   M (SW_INTERFACE_SPAN_DUMP, mp);
20564   mp->is_l2 = is_l2;
20565   S (mp);
20566
20567   /* Use a control ping for synchronization */
20568   MPING (CONTROL_PING, mp_ping);
20569   S (mp_ping);
20570
20571   W (ret);
20572   return ret;
20573 }
20574
20575 int
20576 api_pg_create_interface (vat_main_t * vam)
20577 {
20578   unformat_input_t *input = vam->input;
20579   vl_api_pg_create_interface_t *mp;
20580
20581   u32 if_id = ~0;
20582   int ret;
20583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20584     {
20585       if (unformat (input, "if_id %d", &if_id))
20586         ;
20587       else
20588         break;
20589     }
20590   if (if_id == ~0)
20591     {
20592       errmsg ("missing pg interface index");
20593       return -99;
20594     }
20595
20596   /* Construct the API message */
20597   M (PG_CREATE_INTERFACE, mp);
20598   mp->context = 0;
20599   mp->interface_id = ntohl (if_id);
20600
20601   S (mp);
20602   W (ret);
20603   return ret;
20604 }
20605
20606 int
20607 api_pg_capture (vat_main_t * vam)
20608 {
20609   unformat_input_t *input = vam->input;
20610   vl_api_pg_capture_t *mp;
20611
20612   u32 if_id = ~0;
20613   u8 enable = 1;
20614   u32 count = 1;
20615   u8 pcap_file_set = 0;
20616   u8 *pcap_file = 0;
20617   int ret;
20618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20619     {
20620       if (unformat (input, "if_id %d", &if_id))
20621         ;
20622       else if (unformat (input, "pcap %s", &pcap_file))
20623         pcap_file_set = 1;
20624       else if (unformat (input, "count %d", &count))
20625         ;
20626       else if (unformat (input, "disable"))
20627         enable = 0;
20628       else
20629         break;
20630     }
20631   if (if_id == ~0)
20632     {
20633       errmsg ("missing pg interface index");
20634       return -99;
20635     }
20636   if (pcap_file_set > 0)
20637     {
20638       if (vec_len (pcap_file) > 255)
20639         {
20640           errmsg ("pcap file name is too long");
20641           return -99;
20642         }
20643     }
20644
20645   u32 name_len = vec_len (pcap_file);
20646   /* Construct the API message */
20647   M (PG_CAPTURE, mp);
20648   mp->context = 0;
20649   mp->interface_id = ntohl (if_id);
20650   mp->is_enabled = enable;
20651   mp->count = ntohl (count);
20652   mp->pcap_name_length = ntohl (name_len);
20653   if (pcap_file_set != 0)
20654     {
20655       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20656     }
20657   vec_free (pcap_file);
20658
20659   S (mp);
20660   W (ret);
20661   return ret;
20662 }
20663
20664 int
20665 api_pg_enable_disable (vat_main_t * vam)
20666 {
20667   unformat_input_t *input = vam->input;
20668   vl_api_pg_enable_disable_t *mp;
20669
20670   u8 enable = 1;
20671   u8 stream_name_set = 0;
20672   u8 *stream_name = 0;
20673   int ret;
20674   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20675     {
20676       if (unformat (input, "stream %s", &stream_name))
20677         stream_name_set = 1;
20678       else if (unformat (input, "disable"))
20679         enable = 0;
20680       else
20681         break;
20682     }
20683
20684   if (stream_name_set > 0)
20685     {
20686       if (vec_len (stream_name) > 255)
20687         {
20688           errmsg ("stream name too long");
20689           return -99;
20690         }
20691     }
20692
20693   u32 name_len = vec_len (stream_name);
20694   /* Construct the API message */
20695   M (PG_ENABLE_DISABLE, mp);
20696   mp->context = 0;
20697   mp->is_enabled = enable;
20698   if (stream_name_set != 0)
20699     {
20700       mp->stream_name_length = ntohl (name_len);
20701       clib_memcpy (mp->stream_name, stream_name, name_len);
20702     }
20703   vec_free (stream_name);
20704
20705   S (mp);
20706   W (ret);
20707   return ret;
20708 }
20709
20710 int
20711 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20712 {
20713   unformat_input_t *input = vam->input;
20714   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20715
20716   u16 *low_ports = 0;
20717   u16 *high_ports = 0;
20718   u16 this_low;
20719   u16 this_hi;
20720   ip4_address_t ip4_addr;
20721   ip6_address_t ip6_addr;
20722   u32 length;
20723   u32 tmp, tmp2;
20724   u8 prefix_set = 0;
20725   u32 vrf_id = ~0;
20726   u8 is_add = 1;
20727   u8 is_ipv6 = 0;
20728   int ret;
20729
20730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20731     {
20732       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20733         {
20734           prefix_set = 1;
20735         }
20736       else
20737         if (unformat
20738             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20739         {
20740           prefix_set = 1;
20741           is_ipv6 = 1;
20742         }
20743       else if (unformat (input, "vrf %d", &vrf_id))
20744         ;
20745       else if (unformat (input, "del"))
20746         is_add = 0;
20747       else if (unformat (input, "port %d", &tmp))
20748         {
20749           if (tmp == 0 || tmp > 65535)
20750             {
20751               errmsg ("port %d out of range", tmp);
20752               return -99;
20753             }
20754           this_low = tmp;
20755           this_hi = this_low + 1;
20756           vec_add1 (low_ports, this_low);
20757           vec_add1 (high_ports, this_hi);
20758         }
20759       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20760         {
20761           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20762             {
20763               errmsg ("incorrect range parameters");
20764               return -99;
20765             }
20766           this_low = tmp;
20767           /* Note: in debug CLI +1 is added to high before
20768              passing to real fn that does "the work"
20769              (ip_source_and_port_range_check_add_del).
20770              This fn is a wrapper around the binary API fn a
20771              control plane will call, which expects this increment
20772              to have occurred. Hence letting the binary API control
20773              plane fn do the increment for consistency between VAT
20774              and other control planes.
20775            */
20776           this_hi = tmp2;
20777           vec_add1 (low_ports, this_low);
20778           vec_add1 (high_ports, this_hi);
20779         }
20780       else
20781         break;
20782     }
20783
20784   if (prefix_set == 0)
20785     {
20786       errmsg ("<address>/<mask> not specified");
20787       return -99;
20788     }
20789
20790   if (vrf_id == ~0)
20791     {
20792       errmsg ("VRF ID required, not specified");
20793       return -99;
20794     }
20795
20796   if (vrf_id == 0)
20797     {
20798       errmsg
20799         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20800       return -99;
20801     }
20802
20803   if (vec_len (low_ports) == 0)
20804     {
20805       errmsg ("At least one port or port range required");
20806       return -99;
20807     }
20808
20809   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20810
20811   mp->is_add = is_add;
20812
20813   if (is_ipv6)
20814     {
20815       mp->is_ipv6 = 1;
20816       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20817     }
20818   else
20819     {
20820       mp->is_ipv6 = 0;
20821       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20822     }
20823
20824   mp->mask_length = length;
20825   mp->number_of_ranges = vec_len (low_ports);
20826
20827   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20828   vec_free (low_ports);
20829
20830   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20831   vec_free (high_ports);
20832
20833   mp->vrf_id = ntohl (vrf_id);
20834
20835   S (mp);
20836   W (ret);
20837   return ret;
20838 }
20839
20840 int
20841 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20842 {
20843   unformat_input_t *input = vam->input;
20844   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20845   u32 sw_if_index = ~0;
20846   int vrf_set = 0;
20847   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20848   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20849   u8 is_add = 1;
20850   int ret;
20851
20852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20853     {
20854       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20855         ;
20856       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20857         ;
20858       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20859         vrf_set = 1;
20860       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20861         vrf_set = 1;
20862       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20863         vrf_set = 1;
20864       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20865         vrf_set = 1;
20866       else if (unformat (input, "del"))
20867         is_add = 0;
20868       else
20869         break;
20870     }
20871
20872   if (sw_if_index == ~0)
20873     {
20874       errmsg ("Interface required but not specified");
20875       return -99;
20876     }
20877
20878   if (vrf_set == 0)
20879     {
20880       errmsg ("VRF ID required but not specified");
20881       return -99;
20882     }
20883
20884   if (tcp_out_vrf_id == 0
20885       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20886     {
20887       errmsg
20888         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20889       return -99;
20890     }
20891
20892   /* Construct the API message */
20893   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20894
20895   mp->sw_if_index = ntohl (sw_if_index);
20896   mp->is_add = is_add;
20897   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20898   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20899   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20900   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20901
20902   /* send it... */
20903   S (mp);
20904
20905   /* Wait for a reply... */
20906   W (ret);
20907   return ret;
20908 }
20909
20910 static int
20911 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20912 {
20913   unformat_input_t *i = vam->input;
20914   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20915   u32 local_sa_id = 0;
20916   u32 remote_sa_id = 0;
20917   ip4_address_t src_address;
20918   ip4_address_t dst_address;
20919   u8 is_add = 1;
20920   int ret;
20921
20922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20923     {
20924       if (unformat (i, "local_sa %d", &local_sa_id))
20925         ;
20926       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20927         ;
20928       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20929         ;
20930       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20931         ;
20932       else if (unformat (i, "del"))
20933         is_add = 0;
20934       else
20935         {
20936           clib_warning ("parse error '%U'", format_unformat_error, i);
20937           return -99;
20938         }
20939     }
20940
20941   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20942
20943   mp->local_sa_id = ntohl (local_sa_id);
20944   mp->remote_sa_id = ntohl (remote_sa_id);
20945   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20946   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20947   mp->is_add = is_add;
20948
20949   S (mp);
20950   W (ret);
20951   return ret;
20952 }
20953
20954 static int
20955 api_punt (vat_main_t * vam)
20956 {
20957   unformat_input_t *i = vam->input;
20958   vl_api_punt_t *mp;
20959   u32 ipv = ~0;
20960   u32 protocol = ~0;
20961   u32 port = ~0;
20962   int is_add = 1;
20963   int ret;
20964
20965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20966     {
20967       if (unformat (i, "ip %d", &ipv))
20968         ;
20969       else if (unformat (i, "protocol %d", &protocol))
20970         ;
20971       else if (unformat (i, "port %d", &port))
20972         ;
20973       else if (unformat (i, "del"))
20974         is_add = 0;
20975       else
20976         {
20977           clib_warning ("parse error '%U'", format_unformat_error, i);
20978           return -99;
20979         }
20980     }
20981
20982   M (PUNT, mp);
20983
20984   mp->is_add = (u8) is_add;
20985   mp->ipv = (u8) ipv;
20986   mp->l4_protocol = (u8) protocol;
20987   mp->l4_port = htons ((u16) port);
20988
20989   S (mp);
20990   W (ret);
20991   return ret;
20992 }
20993
20994 static void vl_api_ipsec_gre_tunnel_details_t_handler
20995   (vl_api_ipsec_gre_tunnel_details_t * mp)
20996 {
20997   vat_main_t *vam = &vat_main;
20998
20999   print (vam->ofp, "%11d%15U%15U%14d%14d",
21000          ntohl (mp->sw_if_index),
21001          format_ip4_address, &mp->src_address,
21002          format_ip4_address, &mp->dst_address,
21003          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21004 }
21005
21006 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21007   (vl_api_ipsec_gre_tunnel_details_t * mp)
21008 {
21009   vat_main_t *vam = &vat_main;
21010   vat_json_node_t *node = NULL;
21011   struct in_addr ip4;
21012
21013   if (VAT_JSON_ARRAY != vam->json_tree.type)
21014     {
21015       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21016       vat_json_init_array (&vam->json_tree);
21017     }
21018   node = vat_json_array_add (&vam->json_tree);
21019
21020   vat_json_init_object (node);
21021   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21022   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21023   vat_json_object_add_ip4 (node, "src_address", ip4);
21024   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21025   vat_json_object_add_ip4 (node, "dst_address", ip4);
21026   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21027   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21028 }
21029
21030 static int
21031 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21032 {
21033   unformat_input_t *i = vam->input;
21034   vl_api_ipsec_gre_tunnel_dump_t *mp;
21035   vl_api_control_ping_t *mp_ping;
21036   u32 sw_if_index;
21037   u8 sw_if_index_set = 0;
21038   int ret;
21039
21040   /* Parse args required to build the message */
21041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21042     {
21043       if (unformat (i, "sw_if_index %d", &sw_if_index))
21044         sw_if_index_set = 1;
21045       else
21046         break;
21047     }
21048
21049   if (sw_if_index_set == 0)
21050     {
21051       sw_if_index = ~0;
21052     }
21053
21054   if (!vam->json_output)
21055     {
21056       print (vam->ofp, "%11s%15s%15s%14s%14s",
21057              "sw_if_index", "src_address", "dst_address",
21058              "local_sa_id", "remote_sa_id");
21059     }
21060
21061   /* Get list of gre-tunnel interfaces */
21062   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21063
21064   mp->sw_if_index = htonl (sw_if_index);
21065
21066   S (mp);
21067
21068   /* Use a control ping for synchronization */
21069   MPING (CONTROL_PING, mp_ping);
21070   S (mp_ping);
21071
21072   W (ret);
21073   return ret;
21074 }
21075
21076 static int
21077 api_delete_subif (vat_main_t * vam)
21078 {
21079   unformat_input_t *i = vam->input;
21080   vl_api_delete_subif_t *mp;
21081   u32 sw_if_index = ~0;
21082   int ret;
21083
21084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21085     {
21086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21087         ;
21088       if (unformat (i, "sw_if_index %d", &sw_if_index))
21089         ;
21090       else
21091         break;
21092     }
21093
21094   if (sw_if_index == ~0)
21095     {
21096       errmsg ("missing sw_if_index");
21097       return -99;
21098     }
21099
21100   /* Construct the API message */
21101   M (DELETE_SUBIF, mp);
21102   mp->sw_if_index = ntohl (sw_if_index);
21103
21104   S (mp);
21105   W (ret);
21106   return ret;
21107 }
21108
21109 #define foreach_pbb_vtr_op      \
21110 _("disable",  L2_VTR_DISABLED)  \
21111 _("pop",  L2_VTR_POP_2)         \
21112 _("push",  L2_VTR_PUSH_2)
21113
21114 static int
21115 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21116 {
21117   unformat_input_t *i = vam->input;
21118   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21119   u32 sw_if_index = ~0, vtr_op = ~0;
21120   u16 outer_tag = ~0;
21121   u8 dmac[6], smac[6];
21122   u8 dmac_set = 0, smac_set = 0;
21123   u16 vlanid = 0;
21124   u32 sid = ~0;
21125   u32 tmp;
21126   int ret;
21127
21128   /* Shut up coverity */
21129   memset (dmac, 0, sizeof (dmac));
21130   memset (smac, 0, sizeof (smac));
21131
21132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21133     {
21134       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21135         ;
21136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21137         ;
21138       else if (unformat (i, "vtr_op %d", &vtr_op))
21139         ;
21140 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21141       foreach_pbb_vtr_op
21142 #undef _
21143         else if (unformat (i, "translate_pbb_stag"))
21144         {
21145           if (unformat (i, "%d", &tmp))
21146             {
21147               vtr_op = L2_VTR_TRANSLATE_2_1;
21148               outer_tag = tmp;
21149             }
21150           else
21151             {
21152               errmsg
21153                 ("translate_pbb_stag operation requires outer tag definition");
21154               return -99;
21155             }
21156         }
21157       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21158         dmac_set++;
21159       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21160         smac_set++;
21161       else if (unformat (i, "sid %d", &sid))
21162         ;
21163       else if (unformat (i, "vlanid %d", &tmp))
21164         vlanid = tmp;
21165       else
21166         {
21167           clib_warning ("parse error '%U'", format_unformat_error, i);
21168           return -99;
21169         }
21170     }
21171
21172   if ((sw_if_index == ~0) || (vtr_op == ~0))
21173     {
21174       errmsg ("missing sw_if_index or vtr operation");
21175       return -99;
21176     }
21177   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21178       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21179     {
21180       errmsg
21181         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21182       return -99;
21183     }
21184
21185   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21186   mp->sw_if_index = ntohl (sw_if_index);
21187   mp->vtr_op = ntohl (vtr_op);
21188   mp->outer_tag = ntohs (outer_tag);
21189   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21190   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21191   mp->b_vlanid = ntohs (vlanid);
21192   mp->i_sid = ntohl (sid);
21193
21194   S (mp);
21195   W (ret);
21196   return ret;
21197 }
21198
21199 static int
21200 api_flow_classify_set_interface (vat_main_t * vam)
21201 {
21202   unformat_input_t *i = vam->input;
21203   vl_api_flow_classify_set_interface_t *mp;
21204   u32 sw_if_index;
21205   int sw_if_index_set;
21206   u32 ip4_table_index = ~0;
21207   u32 ip6_table_index = ~0;
21208   u8 is_add = 1;
21209   int ret;
21210
21211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21212     {
21213       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21214         sw_if_index_set = 1;
21215       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21216         sw_if_index_set = 1;
21217       else if (unformat (i, "del"))
21218         is_add = 0;
21219       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21220         ;
21221       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21222         ;
21223       else
21224         {
21225           clib_warning ("parse error '%U'", format_unformat_error, i);
21226           return -99;
21227         }
21228     }
21229
21230   if (sw_if_index_set == 0)
21231     {
21232       errmsg ("missing interface name or sw_if_index");
21233       return -99;
21234     }
21235
21236   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21237
21238   mp->sw_if_index = ntohl (sw_if_index);
21239   mp->ip4_table_index = ntohl (ip4_table_index);
21240   mp->ip6_table_index = ntohl (ip6_table_index);
21241   mp->is_add = is_add;
21242
21243   S (mp);
21244   W (ret);
21245   return ret;
21246 }
21247
21248 static int
21249 api_flow_classify_dump (vat_main_t * vam)
21250 {
21251   unformat_input_t *i = vam->input;
21252   vl_api_flow_classify_dump_t *mp;
21253   vl_api_control_ping_t *mp_ping;
21254   u8 type = FLOW_CLASSIFY_N_TABLES;
21255   int ret;
21256
21257   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21258     ;
21259   else
21260     {
21261       errmsg ("classify table type must be specified");
21262       return -99;
21263     }
21264
21265   if (!vam->json_output)
21266     {
21267       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21268     }
21269
21270   M (FLOW_CLASSIFY_DUMP, mp);
21271   mp->type = type;
21272   /* send it... */
21273   S (mp);
21274
21275   /* Use a control ping for synchronization */
21276   MPING (CONTROL_PING, mp_ping);
21277   S (mp_ping);
21278
21279   /* Wait for a reply... */
21280   W (ret);
21281   return ret;
21282 }
21283
21284 static int
21285 api_feature_enable_disable (vat_main_t * vam)
21286 {
21287   unformat_input_t *i = vam->input;
21288   vl_api_feature_enable_disable_t *mp;
21289   u8 *arc_name = 0;
21290   u8 *feature_name = 0;
21291   u32 sw_if_index = ~0;
21292   u8 enable = 1;
21293   int ret;
21294
21295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21296     {
21297       if (unformat (i, "arc_name %s", &arc_name))
21298         ;
21299       else if (unformat (i, "feature_name %s", &feature_name))
21300         ;
21301       else
21302         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21303         ;
21304       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21305         ;
21306       else if (unformat (i, "disable"))
21307         enable = 0;
21308       else
21309         break;
21310     }
21311
21312   if (arc_name == 0)
21313     {
21314       errmsg ("missing arc name");
21315       return -99;
21316     }
21317   if (vec_len (arc_name) > 63)
21318     {
21319       errmsg ("arc name too long");
21320     }
21321
21322   if (feature_name == 0)
21323     {
21324       errmsg ("missing feature name");
21325       return -99;
21326     }
21327   if (vec_len (feature_name) > 63)
21328     {
21329       errmsg ("feature name too long");
21330     }
21331
21332   if (sw_if_index == ~0)
21333     {
21334       errmsg ("missing interface name or sw_if_index");
21335       return -99;
21336     }
21337
21338   /* Construct the API message */
21339   M (FEATURE_ENABLE_DISABLE, mp);
21340   mp->sw_if_index = ntohl (sw_if_index);
21341   mp->enable = enable;
21342   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21343   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21344   vec_free (arc_name);
21345   vec_free (feature_name);
21346
21347   S (mp);
21348   W (ret);
21349   return ret;
21350 }
21351
21352 static int
21353 api_sw_interface_tag_add_del (vat_main_t * vam)
21354 {
21355   unformat_input_t *i = vam->input;
21356   vl_api_sw_interface_tag_add_del_t *mp;
21357   u32 sw_if_index = ~0;
21358   u8 *tag = 0;
21359   u8 enable = 1;
21360   int ret;
21361
21362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21363     {
21364       if (unformat (i, "tag %s", &tag))
21365         ;
21366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21367         ;
21368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21369         ;
21370       else if (unformat (i, "del"))
21371         enable = 0;
21372       else
21373         break;
21374     }
21375
21376   if (sw_if_index == ~0)
21377     {
21378       errmsg ("missing interface name or sw_if_index");
21379       return -99;
21380     }
21381
21382   if (enable && (tag == 0))
21383     {
21384       errmsg ("no tag specified");
21385       return -99;
21386     }
21387
21388   /* Construct the API message */
21389   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21390   mp->sw_if_index = ntohl (sw_if_index);
21391   mp->is_add = enable;
21392   if (enable)
21393     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21394   vec_free (tag);
21395
21396   S (mp);
21397   W (ret);
21398   return ret;
21399 }
21400
21401 static void vl_api_l2_xconnect_details_t_handler
21402   (vl_api_l2_xconnect_details_t * mp)
21403 {
21404   vat_main_t *vam = &vat_main;
21405
21406   print (vam->ofp, "%15d%15d",
21407          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21408 }
21409
21410 static void vl_api_l2_xconnect_details_t_handler_json
21411   (vl_api_l2_xconnect_details_t * mp)
21412 {
21413   vat_main_t *vam = &vat_main;
21414   vat_json_node_t *node = NULL;
21415
21416   if (VAT_JSON_ARRAY != vam->json_tree.type)
21417     {
21418       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21419       vat_json_init_array (&vam->json_tree);
21420     }
21421   node = vat_json_array_add (&vam->json_tree);
21422
21423   vat_json_init_object (node);
21424   vat_json_object_add_uint (node, "rx_sw_if_index",
21425                             ntohl (mp->rx_sw_if_index));
21426   vat_json_object_add_uint (node, "tx_sw_if_index",
21427                             ntohl (mp->tx_sw_if_index));
21428 }
21429
21430 static int
21431 api_l2_xconnect_dump (vat_main_t * vam)
21432 {
21433   vl_api_l2_xconnect_dump_t *mp;
21434   vl_api_control_ping_t *mp_ping;
21435   int ret;
21436
21437   if (!vam->json_output)
21438     {
21439       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21440     }
21441
21442   M (L2_XCONNECT_DUMP, mp);
21443
21444   S (mp);
21445
21446   /* Use a control ping for synchronization */
21447   MPING (CONTROL_PING, mp_ping);
21448   S (mp_ping);
21449
21450   W (ret);
21451   return ret;
21452 }
21453
21454 static int
21455 api_sw_interface_set_mtu (vat_main_t * vam)
21456 {
21457   unformat_input_t *i = vam->input;
21458   vl_api_sw_interface_set_mtu_t *mp;
21459   u32 sw_if_index = ~0;
21460   u32 mtu = 0;
21461   int ret;
21462
21463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21464     {
21465       if (unformat (i, "mtu %d", &mtu))
21466         ;
21467       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21468         ;
21469       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21470         ;
21471       else
21472         break;
21473     }
21474
21475   if (sw_if_index == ~0)
21476     {
21477       errmsg ("missing interface name or sw_if_index");
21478       return -99;
21479     }
21480
21481   if (mtu == 0)
21482     {
21483       errmsg ("no mtu specified");
21484       return -99;
21485     }
21486
21487   /* Construct the API message */
21488   M (SW_INTERFACE_SET_MTU, mp);
21489   mp->sw_if_index = ntohl (sw_if_index);
21490   mp->mtu = ntohs ((u16) mtu);
21491
21492   S (mp);
21493   W (ret);
21494   return ret;
21495 }
21496
21497 static int
21498 api_p2p_ethernet_add (vat_main_t * vam)
21499 {
21500   unformat_input_t *i = vam->input;
21501   vl_api_p2p_ethernet_add_t *mp;
21502   u32 parent_if_index = ~0;
21503   u32 sub_id = ~0;
21504   u8 remote_mac[6];
21505   u8 mac_set = 0;
21506   int ret;
21507
21508   memset (remote_mac, 0, sizeof (remote_mac));
21509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21510     {
21511       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21512         ;
21513       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21514         ;
21515       else
21516         if (unformat
21517             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21518         mac_set++;
21519       else if (unformat (i, "sub_id %d", &sub_id))
21520         ;
21521       else
21522         {
21523           clib_warning ("parse error '%U'", format_unformat_error, i);
21524           return -99;
21525         }
21526     }
21527
21528   if (parent_if_index == ~0)
21529     {
21530       errmsg ("missing interface name or sw_if_index");
21531       return -99;
21532     }
21533   if (mac_set == 0)
21534     {
21535       errmsg ("missing remote mac address");
21536       return -99;
21537     }
21538   if (sub_id == ~0)
21539     {
21540       errmsg ("missing sub-interface id");
21541       return -99;
21542     }
21543
21544   M (P2P_ETHERNET_ADD, mp);
21545   mp->parent_if_index = ntohl (parent_if_index);
21546   mp->subif_id = ntohl (sub_id);
21547   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21548
21549   S (mp);
21550   W (ret);
21551   return ret;
21552 }
21553
21554 static int
21555 api_p2p_ethernet_del (vat_main_t * vam)
21556 {
21557   unformat_input_t *i = vam->input;
21558   vl_api_p2p_ethernet_del_t *mp;
21559   u32 parent_if_index = ~0;
21560   u8 remote_mac[6];
21561   u8 mac_set = 0;
21562   int ret;
21563
21564   memset (remote_mac, 0, sizeof (remote_mac));
21565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21566     {
21567       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21568         ;
21569       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21570         ;
21571       else
21572         if (unformat
21573             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21574         mac_set++;
21575       else
21576         {
21577           clib_warning ("parse error '%U'", format_unformat_error, i);
21578           return -99;
21579         }
21580     }
21581
21582   if (parent_if_index == ~0)
21583     {
21584       errmsg ("missing interface name or sw_if_index");
21585       return -99;
21586     }
21587   if (mac_set == 0)
21588     {
21589       errmsg ("missing remote mac address");
21590       return -99;
21591     }
21592
21593   M (P2P_ETHERNET_DEL, mp);
21594   mp->parent_if_index = ntohl (parent_if_index);
21595   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21596
21597   S (mp);
21598   W (ret);
21599   return ret;
21600 }
21601
21602 static int
21603 api_lldp_config (vat_main_t * vam)
21604 {
21605   unformat_input_t *i = vam->input;
21606   vl_api_lldp_config_t *mp;
21607   int tx_hold = 0;
21608   int tx_interval = 0;
21609   u8 *sys_name = NULL;
21610   int ret;
21611
21612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21613     {
21614       if (unformat (i, "system-name %s", &sys_name))
21615         ;
21616       else if (unformat (i, "tx-hold %d", &tx_hold))
21617         ;
21618       else if (unformat (i, "tx-interval %d", &tx_interval))
21619         ;
21620       else
21621         {
21622           clib_warning ("parse error '%U'", format_unformat_error, i);
21623           return -99;
21624         }
21625     }
21626
21627   vec_add1 (sys_name, 0);
21628
21629   M (LLDP_CONFIG, mp);
21630   mp->tx_hold = htonl (tx_hold);
21631   mp->tx_interval = htonl (tx_interval);
21632   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21633   vec_free (sys_name);
21634
21635   S (mp);
21636   W (ret);
21637   return ret;
21638 }
21639
21640 static int
21641 api_sw_interface_set_lldp (vat_main_t * vam)
21642 {
21643   unformat_input_t *i = vam->input;
21644   vl_api_sw_interface_set_lldp_t *mp;
21645   u32 sw_if_index = ~0;
21646   u32 enable = 1;
21647   u8 *port_desc = NULL, *mgmt_oid = NULL;
21648   ip4_address_t ip4_addr;
21649   ip6_address_t ip6_addr;
21650   int ret;
21651
21652   memset (&ip4_addr, 0, sizeof (ip4_addr));
21653   memset (&ip6_addr, 0, sizeof (ip6_addr));
21654
21655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21656     {
21657       if (unformat (i, "disable"))
21658         enable = 0;
21659       else
21660         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21661         ;
21662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21663         ;
21664       else if (unformat (i, "port-desc %s", &port_desc))
21665         ;
21666       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21667         ;
21668       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21669         ;
21670       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21671         ;
21672       else
21673         break;
21674     }
21675
21676   if (sw_if_index == ~0)
21677     {
21678       errmsg ("missing interface name or sw_if_index");
21679       return -99;
21680     }
21681
21682   /* Construct the API message */
21683   vec_add1 (port_desc, 0);
21684   vec_add1 (mgmt_oid, 0);
21685   M (SW_INTERFACE_SET_LLDP, mp);
21686   mp->sw_if_index = ntohl (sw_if_index);
21687   mp->enable = enable;
21688   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21689   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21690   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21691   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21692   vec_free (port_desc);
21693   vec_free (mgmt_oid);
21694
21695   S (mp);
21696   W (ret);
21697   return ret;
21698 }
21699
21700 static int
21701 api_tcp_configure_src_addresses (vat_main_t * vam)
21702 {
21703   vl_api_tcp_configure_src_addresses_t *mp;
21704   unformat_input_t *i = vam->input;
21705   ip4_address_t v4first, v4last;
21706   ip6_address_t v6first, v6last;
21707   u8 range_set = 0;
21708   u32 vrf_id = 0;
21709   int ret;
21710
21711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21712     {
21713       if (unformat (i, "%U - %U",
21714                     unformat_ip4_address, &v4first,
21715                     unformat_ip4_address, &v4last))
21716         {
21717           if (range_set)
21718             {
21719               errmsg ("one range per message (range already set)");
21720               return -99;
21721             }
21722           range_set = 1;
21723         }
21724       else if (unformat (i, "%U - %U",
21725                          unformat_ip6_address, &v6first,
21726                          unformat_ip6_address, &v6last))
21727         {
21728           if (range_set)
21729             {
21730               errmsg ("one range per message (range already set)");
21731               return -99;
21732             }
21733           range_set = 2;
21734         }
21735       else if (unformat (i, "vrf %d", &vrf_id))
21736         ;
21737       else
21738         break;
21739     }
21740
21741   if (range_set == 0)
21742     {
21743       errmsg ("address range not set");
21744       return -99;
21745     }
21746
21747   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21748   mp->vrf_id = ntohl (vrf_id);
21749   /* ipv6? */
21750   if (range_set == 2)
21751     {
21752       mp->is_ipv6 = 1;
21753       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21754       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21755     }
21756   else
21757     {
21758       mp->is_ipv6 = 0;
21759       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21760       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21761     }
21762   S (mp);
21763   W (ret);
21764   return ret;
21765 }
21766
21767 static void vl_api_app_namespace_add_del_reply_t_handler
21768   (vl_api_app_namespace_add_del_reply_t * mp)
21769 {
21770   vat_main_t *vam = &vat_main;
21771   i32 retval = ntohl (mp->retval);
21772   if (vam->async_mode)
21773     {
21774       vam->async_errors += (retval < 0);
21775     }
21776   else
21777     {
21778       vam->retval = retval;
21779       if (retval == 0)
21780         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21781       vam->result_ready = 1;
21782     }
21783 }
21784
21785 static void vl_api_app_namespace_add_del_reply_t_handler_json
21786   (vl_api_app_namespace_add_del_reply_t * mp)
21787 {
21788   vat_main_t *vam = &vat_main;
21789   vat_json_node_t node;
21790
21791   vat_json_init_object (&node);
21792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21793   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21794
21795   vat_json_print (vam->ofp, &node);
21796   vat_json_free (&node);
21797
21798   vam->retval = ntohl (mp->retval);
21799   vam->result_ready = 1;
21800 }
21801
21802 static int
21803 api_app_namespace_add_del (vat_main_t * vam)
21804 {
21805   vl_api_app_namespace_add_del_t *mp;
21806   unformat_input_t *i = vam->input;
21807   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21808   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21809   u64 secret;
21810   int ret;
21811
21812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21813     {
21814       if (unformat (i, "id %_%v%_", &ns_id))
21815         ;
21816       else if (unformat (i, "secret %lu", &secret))
21817         secret_set = 1;
21818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21819         sw_if_index_set = 1;
21820       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21821         ;
21822       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21823         ;
21824       else
21825         break;
21826     }
21827   if (!ns_id || !secret_set || !sw_if_index_set)
21828     {
21829       errmsg ("namespace id, secret and sw_if_index must be set");
21830       return -99;
21831     }
21832   if (vec_len (ns_id) > 64)
21833     {
21834       errmsg ("namespace id too long");
21835       return -99;
21836     }
21837   M (APP_NAMESPACE_ADD_DEL, mp);
21838
21839   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21840   mp->namespace_id_len = vec_len (ns_id);
21841   mp->secret = clib_host_to_net_u64 (secret);
21842   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21843   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21844   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21845   vec_free (ns_id);
21846   S (mp);
21847   W (ret);
21848   return ret;
21849 }
21850
21851 static int
21852 api_memfd_segment_create (vat_main_t * vam)
21853 {
21854 #if VPP_API_TEST_BUILTIN == 0
21855   unformat_input_t *i = vam->input;
21856   vl_api_memfd_segment_create_t *mp;
21857   u64 size = 64 << 20;
21858   int ret;
21859
21860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21861     {
21862       if (unformat (i, "size %U", unformat_memory_size, &size))
21863         ;
21864       else
21865         break;
21866     }
21867
21868   M (MEMFD_SEGMENT_CREATE, mp);
21869   mp->requested_size = size;
21870   S (mp);
21871   W (ret);
21872   return ret;
21873
21874 #else
21875   errmsg ("memfd_segment_create (builtin) not supported");
21876   return -99;
21877 #endif
21878 }
21879
21880 static int
21881 api_sock_init_shm (vat_main_t * vam)
21882 {
21883 #if VPP_API_TEST_BUILTIN == 0
21884   unformat_input_t *i = vam->input;
21885   vl_api_shm_elem_config_t *config = 0;
21886   u64 size = 64 << 20;
21887   int rv;
21888
21889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21890     {
21891       if (unformat (i, "size %U", unformat_memory_size, &size))
21892         ;
21893       else
21894         break;
21895     }
21896
21897   /* Try customized config to see if it works */
21898   vec_validate (config, 3);
21899   config[0].type = VL_API_VLIB_RING;
21900   config[0].count = 256;
21901   config[0].size = 256;
21902   config[1].type = VL_API_CLIENT_RING;
21903   config[1].count = 256;
21904   config[1].size = 1024;
21905   config[2].type = VL_API_CLIENT_RING;
21906   config[2].count = 8;
21907   config[2].size = 4096;
21908   config[3].type = VL_API_QUEUE;
21909   config[3].count = 256;
21910   config[3].size = sizeof (uword);
21911   rv = vl_socket_client_init_shm (config);
21912   if (!rv)
21913     vam->client_index_invalid = 1;
21914   return rv;
21915 #else
21916   return -99;
21917 #endif
21918 }
21919
21920 static int
21921 api_dns_enable_disable (vat_main_t * vam)
21922 {
21923   unformat_input_t *line_input = vam->input;
21924   vl_api_dns_enable_disable_t *mp;
21925   u8 enable_disable = 1;
21926   int ret;
21927
21928   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21929     {
21930       if (unformat (line_input, "disable"))
21931         enable_disable = 0;
21932       if (unformat (line_input, "enable"))
21933         enable_disable = 1;
21934       else
21935         break;
21936     }
21937
21938   /* Construct the API message */
21939   M (DNS_ENABLE_DISABLE, mp);
21940   mp->enable = enable_disable;
21941
21942   /* send it... */
21943   S (mp);
21944   /* Wait for the reply */
21945   W (ret);
21946   return ret;
21947 }
21948
21949 static int
21950 api_dns_resolve_name (vat_main_t * vam)
21951 {
21952   unformat_input_t *line_input = vam->input;
21953   vl_api_dns_resolve_name_t *mp;
21954   u8 *name = 0;
21955   int ret;
21956
21957   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21958     {
21959       if (unformat (line_input, "%s", &name))
21960         ;
21961       else
21962         break;
21963     }
21964
21965   if (vec_len (name) > 127)
21966     {
21967       errmsg ("name too long");
21968       return -99;
21969     }
21970
21971   /* Construct the API message */
21972   M (DNS_RESOLVE_NAME, mp);
21973   memcpy (mp->name, name, vec_len (name));
21974   vec_free (name);
21975
21976   /* send it... */
21977   S (mp);
21978   /* Wait for the reply */
21979   W (ret);
21980   return ret;
21981 }
21982
21983 static int
21984 api_dns_resolve_ip (vat_main_t * vam)
21985 {
21986   unformat_input_t *line_input = vam->input;
21987   vl_api_dns_resolve_ip_t *mp;
21988   int is_ip6 = -1;
21989   ip4_address_t addr4;
21990   ip6_address_t addr6;
21991   int ret;
21992
21993   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21994     {
21995       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21996         is_ip6 = 1;
21997       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21998         is_ip6 = 0;
21999       else
22000         break;
22001     }
22002
22003   if (is_ip6 == -1)
22004     {
22005       errmsg ("missing address");
22006       return -99;
22007     }
22008
22009   /* Construct the API message */
22010   M (DNS_RESOLVE_IP, mp);
22011   mp->is_ip6 = is_ip6;
22012   if (is_ip6)
22013     memcpy (mp->address, &addr6, sizeof (addr6));
22014   else
22015     memcpy (mp->address, &addr4, sizeof (addr4));
22016
22017   /* send it... */
22018   S (mp);
22019   /* Wait for the reply */
22020   W (ret);
22021   return ret;
22022 }
22023
22024 static int
22025 api_dns_name_server_add_del (vat_main_t * vam)
22026 {
22027   unformat_input_t *i = vam->input;
22028   vl_api_dns_name_server_add_del_t *mp;
22029   u8 is_add = 1;
22030   ip6_address_t ip6_server;
22031   ip4_address_t ip4_server;
22032   int ip6_set = 0;
22033   int ip4_set = 0;
22034   int ret = 0;
22035
22036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22037     {
22038       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22039         ip6_set = 1;
22040       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22041         ip4_set = 1;
22042       else if (unformat (i, "del"))
22043         is_add = 0;
22044       else
22045         {
22046           clib_warning ("parse error '%U'", format_unformat_error, i);
22047           return -99;
22048         }
22049     }
22050
22051   if (ip4_set && ip6_set)
22052     {
22053       errmsg ("Only one server address allowed per message");
22054       return -99;
22055     }
22056   if ((ip4_set + ip6_set) == 0)
22057     {
22058       errmsg ("Server address required");
22059       return -99;
22060     }
22061
22062   /* Construct the API message */
22063   M (DNS_NAME_SERVER_ADD_DEL, mp);
22064
22065   if (ip6_set)
22066     {
22067       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22068       mp->is_ip6 = 1;
22069     }
22070   else
22071     {
22072       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22073       mp->is_ip6 = 0;
22074     }
22075
22076   mp->is_add = is_add;
22077
22078   /* send it... */
22079   S (mp);
22080
22081   /* Wait for a reply, return good/bad news  */
22082   W (ret);
22083   return ret;
22084 }
22085
22086 static void
22087 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22088 {
22089   vat_main_t *vam = &vat_main;
22090
22091   if (mp->is_ip4)
22092     {
22093       print (vam->ofp,
22094              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22095              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22096              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22097              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22098              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22099              clib_net_to_host_u32 (mp->action_index), mp->tag);
22100     }
22101   else
22102     {
22103       print (vam->ofp,
22104              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22105              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22106              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22107              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22108              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22109              clib_net_to_host_u32 (mp->action_index), mp->tag);
22110     }
22111 }
22112
22113 static void
22114 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22115                                              mp)
22116 {
22117   vat_main_t *vam = &vat_main;
22118   vat_json_node_t *node = NULL;
22119   struct in6_addr ip6;
22120   struct in_addr ip4;
22121
22122   if (VAT_JSON_ARRAY != vam->json_tree.type)
22123     {
22124       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22125       vat_json_init_array (&vam->json_tree);
22126     }
22127   node = vat_json_array_add (&vam->json_tree);
22128   vat_json_init_object (node);
22129
22130   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22131   vat_json_object_add_uint (node, "appns_index",
22132                             clib_net_to_host_u32 (mp->appns_index));
22133   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22134   vat_json_object_add_uint (node, "scope", mp->scope);
22135   vat_json_object_add_uint (node, "action_index",
22136                             clib_net_to_host_u32 (mp->action_index));
22137   vat_json_object_add_uint (node, "lcl_port",
22138                             clib_net_to_host_u16 (mp->lcl_port));
22139   vat_json_object_add_uint (node, "rmt_port",
22140                             clib_net_to_host_u16 (mp->rmt_port));
22141   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22142   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22143   vat_json_object_add_string_copy (node, "tag", mp->tag);
22144   if (mp->is_ip4)
22145     {
22146       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22147       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22148       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22149       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22150     }
22151   else
22152     {
22153       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22154       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22155       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22156       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22157     }
22158 }
22159
22160 static int
22161 api_session_rule_add_del (vat_main_t * vam)
22162 {
22163   vl_api_session_rule_add_del_t *mp;
22164   unformat_input_t *i = vam->input;
22165   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22166   u32 appns_index = 0, scope = 0;
22167   ip4_address_t lcl_ip4, rmt_ip4;
22168   ip6_address_t lcl_ip6, rmt_ip6;
22169   u8 is_ip4 = 1, conn_set = 0;
22170   u8 is_add = 1, *tag = 0;
22171   int ret;
22172
22173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22174     {
22175       if (unformat (i, "del"))
22176         is_add = 0;
22177       else if (unformat (i, "add"))
22178         ;
22179       else if (unformat (i, "proto tcp"))
22180         proto = 0;
22181       else if (unformat (i, "proto udp"))
22182         proto = 1;
22183       else if (unformat (i, "appns %d", &appns_index))
22184         ;
22185       else if (unformat (i, "scope %d", &scope))
22186         ;
22187       else if (unformat (i, "tag %_%v%_", &tag))
22188         ;
22189       else
22190         if (unformat
22191             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22192              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22193              &rmt_port))
22194         {
22195           is_ip4 = 1;
22196           conn_set = 1;
22197         }
22198       else
22199         if (unformat
22200             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22201              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22202              &rmt_port))
22203         {
22204           is_ip4 = 0;
22205           conn_set = 1;
22206         }
22207       else if (unformat (i, "action %d", &action))
22208         ;
22209       else
22210         break;
22211     }
22212   if (proto == ~0 || !conn_set || action == ~0)
22213     {
22214       errmsg ("transport proto, connection and action must be set");
22215       return -99;
22216     }
22217
22218   if (scope > 3)
22219     {
22220       errmsg ("scope should be 0-3");
22221       return -99;
22222     }
22223
22224   M (SESSION_RULE_ADD_DEL, mp);
22225
22226   mp->is_ip4 = is_ip4;
22227   mp->transport_proto = proto;
22228   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22229   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22230   mp->lcl_plen = lcl_plen;
22231   mp->rmt_plen = rmt_plen;
22232   mp->action_index = clib_host_to_net_u32 (action);
22233   mp->appns_index = clib_host_to_net_u32 (appns_index);
22234   mp->scope = scope;
22235   mp->is_add = is_add;
22236   if (is_ip4)
22237     {
22238       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22239       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22240     }
22241   else
22242     {
22243       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22244       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22245     }
22246   if (tag)
22247     {
22248       clib_memcpy (mp->tag, tag, vec_len (tag));
22249       vec_free (tag);
22250     }
22251
22252   S (mp);
22253   W (ret);
22254   return ret;
22255 }
22256
22257 static int
22258 api_session_rules_dump (vat_main_t * vam)
22259 {
22260   vl_api_session_rules_dump_t *mp;
22261   vl_api_control_ping_t *mp_ping;
22262   int ret;
22263
22264   if (!vam->json_output)
22265     {
22266       print (vam->ofp, "%=20s", "Session Rules");
22267     }
22268
22269   M (SESSION_RULES_DUMP, mp);
22270   /* send it... */
22271   S (mp);
22272
22273   /* Use a control ping for synchronization */
22274   MPING (CONTROL_PING, mp_ping);
22275   S (mp_ping);
22276
22277   /* Wait for a reply... */
22278   W (ret);
22279   return ret;
22280 }
22281
22282 static int
22283 api_ip_container_proxy_add_del (vat_main_t * vam)
22284 {
22285   vl_api_ip_container_proxy_add_del_t *mp;
22286   unformat_input_t *i = vam->input;
22287   u32 plen = ~0, sw_if_index = ~0;
22288   ip4_address_t ip4;
22289   ip6_address_t ip6;
22290   u8 is_ip4 = 1;
22291   u8 is_add = 1;
22292   int ret;
22293
22294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22295     {
22296       if (unformat (i, "del"))
22297         is_add = 0;
22298       else if (unformat (i, "add"))
22299         ;
22300       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22301         {
22302           is_ip4 = 1;
22303           plen = 32;
22304         }
22305       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22306         {
22307           is_ip4 = 0;
22308           plen = 128;
22309         }
22310       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22311         ;
22312       else
22313         break;
22314     }
22315   if (sw_if_index == ~0 || plen == ~0)
22316     {
22317       errmsg ("address and sw_if_index must be set");
22318       return -99;
22319     }
22320
22321   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22322
22323   mp->is_ip4 = is_ip4;
22324   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22325   mp->plen = plen;
22326   mp->is_add = is_add;
22327   if (is_ip4)
22328     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22329   else
22330     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22331
22332   S (mp);
22333   W (ret);
22334   return ret;
22335 }
22336
22337 static int
22338 q_or_quit (vat_main_t * vam)
22339 {
22340 #if VPP_API_TEST_BUILTIN == 0
22341   longjmp (vam->jump_buf, 1);
22342 #endif
22343   return 0;                     /* not so much */
22344 }
22345
22346 static int
22347 q (vat_main_t * vam)
22348 {
22349   return q_or_quit (vam);
22350 }
22351
22352 static int
22353 quit (vat_main_t * vam)
22354 {
22355   return q_or_quit (vam);
22356 }
22357
22358 static int
22359 comment (vat_main_t * vam)
22360 {
22361   return 0;
22362 }
22363
22364 static int
22365 cmd_cmp (void *a1, void *a2)
22366 {
22367   u8 **c1 = a1;
22368   u8 **c2 = a2;
22369
22370   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22371 }
22372
22373 static int
22374 help (vat_main_t * vam)
22375 {
22376   u8 **cmds = 0;
22377   u8 *name = 0;
22378   hash_pair_t *p;
22379   unformat_input_t *i = vam->input;
22380   int j;
22381
22382   if (unformat (i, "%s", &name))
22383     {
22384       uword *hs;
22385
22386       vec_add1 (name, 0);
22387
22388       hs = hash_get_mem (vam->help_by_name, name);
22389       if (hs)
22390         print (vam->ofp, "usage: %s %s", name, hs[0]);
22391       else
22392         print (vam->ofp, "No such msg / command '%s'", name);
22393       vec_free (name);
22394       return 0;
22395     }
22396
22397   print (vam->ofp, "Help is available for the following:");
22398
22399     /* *INDENT-OFF* */
22400     hash_foreach_pair (p, vam->function_by_name,
22401     ({
22402       vec_add1 (cmds, (u8 *)(p->key));
22403     }));
22404     /* *INDENT-ON* */
22405
22406   vec_sort_with_function (cmds, cmd_cmp);
22407
22408   for (j = 0; j < vec_len (cmds); j++)
22409     print (vam->ofp, "%s", cmds[j]);
22410
22411   vec_free (cmds);
22412   return 0;
22413 }
22414
22415 static int
22416 set (vat_main_t * vam)
22417 {
22418   u8 *name = 0, *value = 0;
22419   unformat_input_t *i = vam->input;
22420
22421   if (unformat (i, "%s", &name))
22422     {
22423       /* The input buffer is a vector, not a string. */
22424       value = vec_dup (i->buffer);
22425       vec_delete (value, i->index, 0);
22426       /* Almost certainly has a trailing newline */
22427       if (value[vec_len (value) - 1] == '\n')
22428         value[vec_len (value) - 1] = 0;
22429       /* Make sure it's a proper string, one way or the other */
22430       vec_add1 (value, 0);
22431       (void) clib_macro_set_value (&vam->macro_main,
22432                                    (char *) name, (char *) value);
22433     }
22434   else
22435     errmsg ("usage: set <name> <value>");
22436
22437   vec_free (name);
22438   vec_free (value);
22439   return 0;
22440 }
22441
22442 static int
22443 unset (vat_main_t * vam)
22444 {
22445   u8 *name = 0;
22446
22447   if (unformat (vam->input, "%s", &name))
22448     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22449       errmsg ("unset: %s wasn't set", name);
22450   vec_free (name);
22451   return 0;
22452 }
22453
22454 typedef struct
22455 {
22456   u8 *name;
22457   u8 *value;
22458 } macro_sort_t;
22459
22460
22461 static int
22462 macro_sort_cmp (void *a1, void *a2)
22463 {
22464   macro_sort_t *s1 = a1;
22465   macro_sort_t *s2 = a2;
22466
22467   return strcmp ((char *) (s1->name), (char *) (s2->name));
22468 }
22469
22470 static int
22471 dump_macro_table (vat_main_t * vam)
22472 {
22473   macro_sort_t *sort_me = 0, *sm;
22474   int i;
22475   hash_pair_t *p;
22476
22477     /* *INDENT-OFF* */
22478     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22479     ({
22480       vec_add2 (sort_me, sm, 1);
22481       sm->name = (u8 *)(p->key);
22482       sm->value = (u8 *) (p->value[0]);
22483     }));
22484     /* *INDENT-ON* */
22485
22486   vec_sort_with_function (sort_me, macro_sort_cmp);
22487
22488   if (vec_len (sort_me))
22489     print (vam->ofp, "%-15s%s", "Name", "Value");
22490   else
22491     print (vam->ofp, "The macro table is empty...");
22492
22493   for (i = 0; i < vec_len (sort_me); i++)
22494     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22495   return 0;
22496 }
22497
22498 static int
22499 dump_node_table (vat_main_t * vam)
22500 {
22501   int i, j;
22502   vlib_node_t *node, *next_node;
22503
22504   if (vec_len (vam->graph_nodes) == 0)
22505     {
22506       print (vam->ofp, "Node table empty, issue get_node_graph...");
22507       return 0;
22508     }
22509
22510   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22511     {
22512       node = vam->graph_nodes[i];
22513       print (vam->ofp, "[%d] %s", i, node->name);
22514       for (j = 0; j < vec_len (node->next_nodes); j++)
22515         {
22516           if (node->next_nodes[j] != ~0)
22517             {
22518               next_node = vam->graph_nodes[node->next_nodes[j]];
22519               print (vam->ofp, "  [%d] %s", j, next_node->name);
22520             }
22521         }
22522     }
22523   return 0;
22524 }
22525
22526 static int
22527 value_sort_cmp (void *a1, void *a2)
22528 {
22529   name_sort_t *n1 = a1;
22530   name_sort_t *n2 = a2;
22531
22532   if (n1->value < n2->value)
22533     return -1;
22534   if (n1->value > n2->value)
22535     return 1;
22536   return 0;
22537 }
22538
22539
22540 static int
22541 dump_msg_api_table (vat_main_t * vam)
22542 {
22543   api_main_t *am = &api_main;
22544   name_sort_t *nses = 0, *ns;
22545   hash_pair_t *hp;
22546   int i;
22547
22548   /* *INDENT-OFF* */
22549   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22550   ({
22551     vec_add2 (nses, ns, 1);
22552     ns->name = (u8 *)(hp->key);
22553     ns->value = (u32) hp->value[0];
22554   }));
22555   /* *INDENT-ON* */
22556
22557   vec_sort_with_function (nses, value_sort_cmp);
22558
22559   for (i = 0; i < vec_len (nses); i++)
22560     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22561   vec_free (nses);
22562   return 0;
22563 }
22564
22565 static int
22566 get_msg_id (vat_main_t * vam)
22567 {
22568   u8 *name_and_crc;
22569   u32 message_index;
22570
22571   if (unformat (vam->input, "%s", &name_and_crc))
22572     {
22573       message_index = vl_msg_api_get_msg_index (name_and_crc);
22574       if (message_index == ~0)
22575         {
22576           print (vam->ofp, " '%s' not found", name_and_crc);
22577           return 0;
22578         }
22579       print (vam->ofp, " '%s' has message index %d",
22580              name_and_crc, message_index);
22581       return 0;
22582     }
22583   errmsg ("name_and_crc required...");
22584   return 0;
22585 }
22586
22587 static int
22588 search_node_table (vat_main_t * vam)
22589 {
22590   unformat_input_t *line_input = vam->input;
22591   u8 *node_to_find;
22592   int j;
22593   vlib_node_t *node, *next_node;
22594   uword *p;
22595
22596   if (vam->graph_node_index_by_name == 0)
22597     {
22598       print (vam->ofp, "Node table empty, issue get_node_graph...");
22599       return 0;
22600     }
22601
22602   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22603     {
22604       if (unformat (line_input, "%s", &node_to_find))
22605         {
22606           vec_add1 (node_to_find, 0);
22607           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22608           if (p == 0)
22609             {
22610               print (vam->ofp, "%s not found...", node_to_find);
22611               goto out;
22612             }
22613           node = vam->graph_nodes[p[0]];
22614           print (vam->ofp, "[%d] %s", p[0], node->name);
22615           for (j = 0; j < vec_len (node->next_nodes); j++)
22616             {
22617               if (node->next_nodes[j] != ~0)
22618                 {
22619                   next_node = vam->graph_nodes[node->next_nodes[j]];
22620                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22621                 }
22622             }
22623         }
22624
22625       else
22626         {
22627           clib_warning ("parse error '%U'", format_unformat_error,
22628                         line_input);
22629           return -99;
22630         }
22631
22632     out:
22633       vec_free (node_to_find);
22634
22635     }
22636
22637   return 0;
22638 }
22639
22640
22641 static int
22642 script (vat_main_t * vam)
22643 {
22644 #if (VPP_API_TEST_BUILTIN==0)
22645   u8 *s = 0;
22646   char *save_current_file;
22647   unformat_input_t save_input;
22648   jmp_buf save_jump_buf;
22649   u32 save_line_number;
22650
22651   FILE *new_fp, *save_ifp;
22652
22653   if (unformat (vam->input, "%s", &s))
22654     {
22655       new_fp = fopen ((char *) s, "r");
22656       if (new_fp == 0)
22657         {
22658           errmsg ("Couldn't open script file %s", s);
22659           vec_free (s);
22660           return -99;
22661         }
22662     }
22663   else
22664     {
22665       errmsg ("Missing script name");
22666       return -99;
22667     }
22668
22669   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22670   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22671   save_ifp = vam->ifp;
22672   save_line_number = vam->input_line_number;
22673   save_current_file = (char *) vam->current_file;
22674
22675   vam->input_line_number = 0;
22676   vam->ifp = new_fp;
22677   vam->current_file = s;
22678   do_one_file (vam);
22679
22680   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22681   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22682   vam->ifp = save_ifp;
22683   vam->input_line_number = save_line_number;
22684   vam->current_file = (u8 *) save_current_file;
22685   vec_free (s);
22686
22687   return 0;
22688 #else
22689   clib_warning ("use the exec command...");
22690   return -99;
22691 #endif
22692 }
22693
22694 static int
22695 echo (vat_main_t * vam)
22696 {
22697   print (vam->ofp, "%v", vam->input->buffer);
22698   return 0;
22699 }
22700
22701 /* List of API message constructors, CLI names map to api_xxx */
22702 #define foreach_vpe_api_msg                                             \
22703 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22704 _(sw_interface_dump,"")                                                 \
22705 _(sw_interface_set_flags,                                               \
22706   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22707 _(sw_interface_add_del_address,                                         \
22708   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22709 _(sw_interface_set_rx_mode,                                             \
22710   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22711 _(sw_interface_set_table,                                               \
22712   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22713 _(sw_interface_set_mpls_enable,                                         \
22714   "<intfc> | sw_if_index [disable | dis]")                              \
22715 _(sw_interface_set_vpath,                                               \
22716   "<intfc> | sw_if_index <id> enable | disable")                        \
22717 _(sw_interface_set_vxlan_bypass,                                        \
22718   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22719 _(sw_interface_set_geneve_bypass,                                       \
22720   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22721 _(sw_interface_set_l2_xconnect,                                         \
22722   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22723   "enable | disable")                                                   \
22724 _(sw_interface_set_l2_bridge,                                           \
22725   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22726   "[shg <split-horizon-group>] [bvi]\n"                                 \
22727   "enable | disable")                                                   \
22728 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22729 _(bridge_domain_add_del,                                                \
22730   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [bd-tag <text>] [del]\n") \
22731 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22732 _(l2fib_add_del,                                                        \
22733   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22734 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22735 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22736 _(l2_flags,                                                             \
22737   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22738 _(bridge_flags,                                                         \
22739   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22740 _(tap_connect,                                                          \
22741   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22742 _(tap_modify,                                                           \
22743   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22744 _(tap_delete,                                                           \
22745   "<vpp-if-name> | sw_if_index <id>")                                   \
22746 _(sw_interface_tap_dump, "")                                            \
22747 _(tap_create_v2,                                                        \
22748   "name <name> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22749 _(tap_delete_v2,                                                        \
22750   "<vpp-if-name> | sw_if_index <id>")                                   \
22751 _(sw_interface_tap_v2_dump, "")                                         \
22752 _(ip_table_add_del,                                                     \
22753   "table-id <n> [ipv6]\n")                                              \
22754 _(ip_add_del_route,                                                     \
22755   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22756   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22757   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22758   "[multipath] [count <n>]")                                            \
22759 _(ip_mroute_add_del,                                                    \
22760   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22761   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22762 _(mpls_table_add_del,                                                   \
22763   "table-id <n>\n")                                                     \
22764 _(mpls_route_add_del,                                                   \
22765   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22766   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22767   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22768   "[multipath] [count <n>]")                                            \
22769 _(mpls_ip_bind_unbind,                                                  \
22770   "<label> <addr/len>")                                                 \
22771 _(mpls_tunnel_add_del,                                                  \
22772   " via <addr> [table-id <n>]\n"                                        \
22773   "sw_if_index <id>] [l2]  [del]")                                      \
22774 _(bier_table_add_del,                                                   \
22775   "<label> <sub-domain> <set> <bsl> [del]")                             \
22776 _(bier_route_add_del,                                                   \
22777   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22778   "[<intfc> | sw_if_index <id>]"                                        \
22779   "[weight <n>] [del] [multipath]")                                     \
22780 _(proxy_arp_add_del,                                                    \
22781   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22782 _(proxy_arp_intfc_enable_disable,                                       \
22783   "<intfc> | sw_if_index <id> enable | disable")                        \
22784 _(sw_interface_set_unnumbered,                                          \
22785   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22786 _(ip_neighbor_add_del,                                                  \
22787   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22788   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22789 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22790 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22791   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22792   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22793   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22794 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22795 _(reset_fib, "vrf <n> [ipv6]")                                          \
22796 _(dhcp_proxy_config,                                                    \
22797   "svr <v46-address> src <v46-address>\n"                               \
22798    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22799 _(dhcp_proxy_set_vss,                                                   \
22800   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22801 _(dhcp_proxy_dump, "ip6")                                               \
22802 _(dhcp_client_config,                                                   \
22803   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22804 _(set_ip_flow_hash,                                                     \
22805   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22806 _(sw_interface_ip6_enable_disable,                                      \
22807   "<intfc> | sw_if_index <id> enable | disable")                        \
22808 _(sw_interface_ip6_set_link_local_address,                              \
22809   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22810 _(ip6nd_proxy_add_del,                                                  \
22811   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22812 _(ip6nd_proxy_dump, "")                                                 \
22813 _(sw_interface_ip6nd_ra_prefix,                                         \
22814   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22815   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22816   "[nolink] [isno]")                                                    \
22817 _(sw_interface_ip6nd_ra_config,                                         \
22818   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22819   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22820   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22821 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22822 _(l2_patch_add_del,                                                     \
22823   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22824   "enable | disable")                                                   \
22825 _(sr_localsid_add_del,                                                  \
22826   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22827   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22828 _(classify_add_del_table,                                               \
22829   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22830   " [del] [del-chain] mask <mask-value>\n"                              \
22831   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22832   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22833 _(classify_add_del_session,                                             \
22834   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22835   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22836   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22837   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22838 _(classify_set_interface_ip_table,                                      \
22839   "<intfc> | sw_if_index <nn> table <nn>")                              \
22840 _(classify_set_interface_l2_tables,                                     \
22841   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22842   "  [other-table <nn>]")                                               \
22843 _(get_node_index, "node <node-name")                                    \
22844 _(add_node_next, "node <node-name> next <next-node-name>")              \
22845 _(l2tpv3_create_tunnel,                                                 \
22846   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22847   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22848   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22849 _(l2tpv3_set_tunnel_cookies,                                            \
22850   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22851   "[new_remote_cookie <nn>]\n")                                         \
22852 _(l2tpv3_interface_enable_disable,                                      \
22853   "<intfc> | sw_if_index <nn> enable | disable")                        \
22854 _(l2tpv3_set_lookup_key,                                                \
22855   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22856 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22857 _(vxlan_add_del_tunnel,                                                 \
22858   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22859   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22860   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22861 _(geneve_add_del_tunnel,                                                \
22862   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22863   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22864   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22865 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22866 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22867 _(gre_add_del_tunnel,                                                   \
22868   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22869 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22870 _(l2_fib_clear_table, "")                                               \
22871 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22872 _(l2_interface_vlan_tag_rewrite,                                        \
22873   "<intfc> | sw_if_index <nn> \n"                                       \
22874   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22875   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22876 _(create_vhost_user_if,                                                 \
22877         "socket <filename> [server] [renumber <dev_instance>] "         \
22878         "[mac <mac_address>]")                                          \
22879 _(modify_vhost_user_if,                                                 \
22880         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22881         "[server] [renumber <dev_instance>]")                           \
22882 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22883 _(sw_interface_vhost_user_dump, "")                                     \
22884 _(show_version, "")                                                     \
22885 _(vxlan_gpe_add_del_tunnel,                                             \
22886   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22887   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22888   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22889   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22890 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22891 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22892 _(interface_name_renumber,                                              \
22893   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22894 _(input_acl_set_interface,                                              \
22895   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22896   "  [l2-table <nn>] [del]")                                            \
22897 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22898 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22899 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22900 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22901 _(ip_dump, "ipv4 | ipv6")                                               \
22902 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22903 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22904   "  spid_id <n> ")                                                     \
22905 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22906   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22907   "  integ_alg <alg> integ_key <hex>")                                  \
22908 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22909   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22910   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22911   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22912 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22913 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22914   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22915   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22916   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22917 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22918 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22919   "  <alg> <hex>\n")                                                    \
22920 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22921 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22922 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22923   "(auth_data 0x<data> | auth_data <data>)")                            \
22924 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22925   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22926 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22927   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22928   "(local|remote)")                                                     \
22929 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22930 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22931 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22932 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22933 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22934 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22935 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22936 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22937 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22938 _(delete_loopback,"sw_if_index <nn>")                                   \
22939 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22940 _(map_add_domain,                                                       \
22941   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22942   "ip6-src <ip6addr> "                                                  \
22943   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22944 _(map_del_domain, "index <n>")                                          \
22945 _(map_add_del_rule,                                                     \
22946   "index <n> psid <n> dst <ip6addr> [del]")                             \
22947 _(map_domain_dump, "")                                                  \
22948 _(map_rule_dump, "index <map-domain>")                                  \
22949 _(want_interface_events,  "enable|disable")                             \
22950 _(want_stats,"enable|disable")                                          \
22951 _(get_first_msg_id, "client <name>")                                    \
22952 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22953 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22954   "fib-id <nn> [ip4][ip6][default]")                                    \
22955 _(get_node_graph, " ")                                                  \
22956 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22957 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22958 _(ioam_disable, "")                                                     \
22959 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22960                             " sw_if_index <sw_if_index> p <priority> "  \
22961                             "w <weight>] [del]")                        \
22962 _(one_add_del_locator, "locator-set <locator_name> "                    \
22963                         "iface <intf> | sw_if_index <sw_if_index> "     \
22964                         "p <priority> w <weight> [del]")                \
22965 _(one_add_del_local_eid,"vni <vni> eid "                                \
22966                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22967                          "locator-set <locator_name> [del]"             \
22968                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22969 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22970 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22971 _(one_enable_disable, "enable|disable")                                 \
22972 _(one_map_register_enable_disable, "enable|disable")                    \
22973 _(one_map_register_fallback_threshold, "<value>")                       \
22974 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22975 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22976                                "[seid <seid>] "                         \
22977                                "rloc <locator> p <prio> "               \
22978                                "w <weight> [rloc <loc> ... ] "          \
22979                                "action <action> [del-all]")             \
22980 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22981                           "<local-eid>")                                \
22982 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22983 _(one_use_petr, "ip-address> | disable")                                \
22984 _(one_map_request_mode, "src-dst|dst-only")                             \
22985 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22986 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22987 _(one_locator_set_dump, "[local | remote]")                             \
22988 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22989 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22990                        "[local] | [remote]")                            \
22991 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22992 _(one_ndp_bd_get, "")                                                   \
22993 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22994 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22995 _(one_l2_arp_bd_get, "")                                                \
22996 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22997 _(one_stats_enable_disable, "enable|disalbe")                           \
22998 _(show_one_stats_enable_disable, "")                                    \
22999 _(one_eid_table_vni_dump, "")                                           \
23000 _(one_eid_table_map_dump, "l2|l3")                                      \
23001 _(one_map_resolver_dump, "")                                            \
23002 _(one_map_server_dump, "")                                              \
23003 _(one_adjacencies_get, "vni <vni>")                                     \
23004 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23005 _(show_one_rloc_probe_state, "")                                        \
23006 _(show_one_map_register_state, "")                                      \
23007 _(show_one_status, "")                                                  \
23008 _(one_stats_dump, "")                                                   \
23009 _(one_stats_flush, "")                                                  \
23010 _(one_get_map_request_itr_rlocs, "")                                    \
23011 _(one_map_register_set_ttl, "<ttl>")                                    \
23012 _(one_set_transport_protocol, "udp|api")                                \
23013 _(one_get_transport_protocol, "")                                       \
23014 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23015 _(one_show_xtr_mode, "")                                                \
23016 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23017 _(one_show_pitr_mode, "")                                               \
23018 _(one_enable_disable_petr_mode, "enable|disable")                       \
23019 _(one_show_petr_mode, "")                                               \
23020 _(show_one_nsh_mapping, "")                                             \
23021 _(show_one_pitr, "")                                                    \
23022 _(show_one_use_petr, "")                                                \
23023 _(show_one_map_request_mode, "")                                        \
23024 _(show_one_map_register_ttl, "")                                        \
23025 _(show_one_map_register_fallback_threshold, "")                         \
23026 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23027                             " sw_if_index <sw_if_index> p <priority> "  \
23028                             "w <weight>] [del]")                        \
23029 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23030                         "iface <intf> | sw_if_index <sw_if_index> "     \
23031                         "p <priority> w <weight> [del]")                \
23032 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23033                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23034                          "locator-set <locator_name> [del]"             \
23035                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23036 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23037 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23038 _(lisp_enable_disable, "enable|disable")                                \
23039 _(lisp_map_register_enable_disable, "enable|disable")                   \
23040 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23041 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23042                                "[seid <seid>] "                         \
23043                                "rloc <locator> p <prio> "               \
23044                                "w <weight> [rloc <loc> ... ] "          \
23045                                "action <action> [del-all]")             \
23046 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23047                           "<local-eid>")                                \
23048 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23049 _(lisp_use_petr, "<ip-address> | disable")                              \
23050 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23051 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23052 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23053 _(lisp_locator_set_dump, "[local | remote]")                            \
23054 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23055 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23056                        "[local] | [remote]")                            \
23057 _(lisp_eid_table_vni_dump, "")                                          \
23058 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23059 _(lisp_map_resolver_dump, "")                                           \
23060 _(lisp_map_server_dump, "")                                             \
23061 _(lisp_adjacencies_get, "vni <vni>")                                    \
23062 _(gpe_fwd_entry_vnis_get, "")                                           \
23063 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23064 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23065                                 "[table <table-id>]")                   \
23066 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23067 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23068 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23069 _(gpe_get_encap_mode, "")                                               \
23070 _(lisp_gpe_add_del_iface, "up|down")                                    \
23071 _(lisp_gpe_enable_disable, "enable|disable")                            \
23072 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23073   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23074 _(show_lisp_rloc_probe_state, "")                                       \
23075 _(show_lisp_map_register_state, "")                                     \
23076 _(show_lisp_status, "")                                                 \
23077 _(lisp_get_map_request_itr_rlocs, "")                                   \
23078 _(show_lisp_pitr, "")                                                   \
23079 _(show_lisp_use_petr, "")                                               \
23080 _(show_lisp_map_request_mode, "")                                       \
23081 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23082 _(af_packet_delete, "name <host interface name>")                       \
23083 _(policer_add_del, "name <policer name> <params> [del]")                \
23084 _(policer_dump, "[name <policer name>]")                                \
23085 _(policer_classify_set_interface,                                       \
23086   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23087   "  [l2-table <nn>] [del]")                                            \
23088 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23089 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23090     "[master|slave]")                                                   \
23091 _(netmap_delete, "name <interface name>")                               \
23092 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23093 _(mpls_fib_dump, "")                                                    \
23094 _(classify_table_ids, "")                                               \
23095 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23096 _(classify_table_info, "table_id <nn>")                                 \
23097 _(classify_session_dump, "table_id <nn>")                               \
23098 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23099     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23100     "[template_interval <nn>] [udp_checksum]")                          \
23101 _(ipfix_exporter_dump, "")                                              \
23102 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23103 _(ipfix_classify_stream_dump, "")                                       \
23104 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23105 _(ipfix_classify_table_dump, "")                                        \
23106 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23107 _(sw_interface_span_dump, "[l2]")                                           \
23108 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23109 _(pg_create_interface, "if_id <nn>")                                    \
23110 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23111 _(pg_enable_disable, "[stream <id>] disable")                           \
23112 _(ip_source_and_port_range_check_add_del,                               \
23113   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23114 _(ip_source_and_port_range_check_interface_add_del,                     \
23115   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23116   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23117 _(ipsec_gre_add_del_tunnel,                                             \
23118   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23119 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23120 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23121 _(l2_interface_pbb_tag_rewrite,                                         \
23122   "<intfc> | sw_if_index <nn> \n"                                       \
23123   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23124   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23125 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23126 _(flow_classify_set_interface,                                          \
23127   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23128 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23129 _(ip_fib_dump, "")                                                      \
23130 _(ip_mfib_dump, "")                                                     \
23131 _(ip6_fib_dump, "")                                                     \
23132 _(ip6_mfib_dump, "")                                                    \
23133 _(feature_enable_disable, "arc_name <arc_name> "                        \
23134   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23135 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23136 "[disable]")                                                            \
23137 _(l2_xconnect_dump, "")                                                 \
23138 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23139 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23140 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23141 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23142 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23143 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23144 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23145   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23146 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23147 _(memfd_segment_create,"size <nnn>")                                    \
23148 _(sock_init_shm, "size <nnn>")                                          \
23149 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23150 _(dns_enable_disable, "[enable][disable]")                              \
23151 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23152 _(dns_resolve_name, "<hostname>")                                       \
23153 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23154 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23155 _(dns_resolve_name, "<hostname>")                                       \
23156 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23157   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23158 _(session_rules_dump, "")                                               \
23159 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23160
23161 /* List of command functions, CLI names map directly to functions */
23162 #define foreach_cli_function                                    \
23163 _(comment, "usage: comment <ignore-rest-of-line>")              \
23164 _(dump_interface_table, "usage: dump_interface_table")          \
23165 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23166 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23167 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23168 _(dump_stats_table, "usage: dump_stats_table")                  \
23169 _(dump_macro_table, "usage: dump_macro_table ")                 \
23170 _(dump_node_table, "usage: dump_node_table")                    \
23171 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23172 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23173 _(echo, "usage: echo <message>")                                \
23174 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23175 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23176 _(help, "usage: help")                                          \
23177 _(q, "usage: quit")                                             \
23178 _(quit, "usage: quit")                                          \
23179 _(search_node_table, "usage: search_node_table <name>...")      \
23180 _(set, "usage: set <variable-name> <value>")                    \
23181 _(script, "usage: script <file-name>")                          \
23182 _(unset, "usage: unset <variable-name>")
23183 #define _(N,n)                                  \
23184     static void vl_api_##n##_t_handler_uni      \
23185     (vl_api_##n##_t * mp)                       \
23186     {                                           \
23187         vat_main_t * vam = &vat_main;           \
23188         if (vam->json_output) {                 \
23189             vl_api_##n##_t_handler_json(mp);    \
23190         } else {                                \
23191             vl_api_##n##_t_handler(mp);         \
23192         }                                       \
23193     }
23194 foreach_vpe_api_reply_msg;
23195 #if VPP_API_TEST_BUILTIN == 0
23196 foreach_standalone_reply_msg;
23197 #endif
23198 #undef _
23199
23200 void
23201 vat_api_hookup (vat_main_t * vam)
23202 {
23203 #define _(N,n)                                                  \
23204     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23205                            vl_api_##n##_t_handler_uni,          \
23206                            vl_noop_handler,                     \
23207                            vl_api_##n##_t_endian,               \
23208                            vl_api_##n##_t_print,                \
23209                            sizeof(vl_api_##n##_t), 1);
23210   foreach_vpe_api_reply_msg;
23211 #if VPP_API_TEST_BUILTIN == 0
23212   foreach_standalone_reply_msg;
23213 #endif
23214 #undef _
23215
23216 #if (VPP_API_TEST_BUILTIN==0)
23217   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23218
23219   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23220
23221   vam->function_by_name = hash_create_string (0, sizeof (uword));
23222
23223   vam->help_by_name = hash_create_string (0, sizeof (uword));
23224 #endif
23225
23226   /* API messages we can send */
23227 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23228   foreach_vpe_api_msg;
23229 #undef _
23230
23231   /* Help strings */
23232 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23233   foreach_vpe_api_msg;
23234 #undef _
23235
23236   /* CLI functions */
23237 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23238   foreach_cli_function;
23239 #undef _
23240
23241   /* Help strings */
23242 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23243   foreach_cli_function;
23244 #undef _
23245 }
23246
23247 #if VPP_API_TEST_BUILTIN
23248 static clib_error_t *
23249 vat_api_hookup_shim (vlib_main_t * vm)
23250 {
23251   vat_api_hookup (&vat_main);
23252   return 0;
23253 }
23254
23255 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23256 #endif
23257
23258 /*
23259  * fd.io coding-style-patch-verification: ON
23260  *
23261  * Local Variables:
23262  * eval: (c-set-style "gnu")
23263  * End:
23264  */