Fix clang compilation on aarch64: sizeof operator error.
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/ip/ip_neighbor.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/in_out_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include "vat/json_format.h"
57
58 #include <inttypes.h>
59 #include <sys/stat.h>
60
61 #define vl_typedefs             /* define message structures */
62 #include <vpp/api/vpe_all_api_h.h>
63 #undef vl_typedefs
64
65 /* declare message handlers for each api */
66
67 #define vl_endianfun            /* define message structures */
68 #include <vpp/api/vpe_all_api_h.h>
69 #undef vl_endianfun
70
71 /* instantiate all the print functions we know about */
72 #define vl_print(handle, ...)
73 #define vl_printfun
74 #include <vpp/api/vpe_all_api_h.h>
75 #undef vl_printfun
76
77 #define __plugin_msg_base 0
78 #include <vlibapi/vat_helper_macros.h>
79
80 #if VPP_API_TEST_BUILTIN == 0
81 #include <netdb.h>
82
83 u32
84 vl (void *p)
85 {
86   return vec_len (p);
87 }
88
89 int
90 vat_socket_connect (vat_main_t * vam)
91 {
92   vam->socket_client_main = &socket_client_main;
93   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
94                                    0 /* default socket rx, tx buffer */ );
95 }
96 #else /* vpp built-in case, we don't do sockets... */
97 int
98 vat_socket_connect (vat_main_t * vam)
99 {
100   return 0;
101 }
102
103 int
104 vl_socket_client_read (int wait)
105 {
106   return -1;
107 };
108
109 int
110 vl_socket_client_write ()
111 {
112   return -1;
113 };
114
115 void *
116 vl_socket_client_msg_alloc (int nbytes)
117 {
118   return 0;
119 }
120 #endif
121
122
123 f64
124 vat_time_now (vat_main_t * vam)
125 {
126 #if VPP_API_TEST_BUILTIN
127   return vlib_time_now (vam->vlib_main);
128 #else
129   return clib_time_now (&vam->clib_time);
130 #endif
131 }
132
133 void
134 errmsg (char *fmt, ...)
135 {
136   vat_main_t *vam = &vat_main;
137   va_list va;
138   u8 *s;
139
140   va_start (va, fmt);
141   s = va_format (0, fmt, &va);
142   va_end (va);
143
144   vec_add1 (s, 0);
145
146 #if VPP_API_TEST_BUILTIN
147   vlib_cli_output (vam->vlib_main, (char *) s);
148 #else
149   {
150     if (vam->ifp != stdin)
151       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
152                vam->input_line_number);
153     fformat (vam->ofp, (char *) s);
154     fflush (vam->ofp);
155   }
156 #endif
157
158   vec_free (s);
159 }
160
161 #if VPP_API_TEST_BUILTIN == 0
162 static uword
163 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
164 {
165   vat_main_t *vam = va_arg (*args, vat_main_t *);
166   u32 *result = va_arg (*args, u32 *);
167   u8 *if_name;
168   uword *p;
169
170   if (!unformat (input, "%s", &if_name))
171     return 0;
172
173   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
174   if (p == 0)
175     return 0;
176   *result = p[0];
177   return 1;
178 }
179
180 /* Parse an IP4 address %d.%d.%d.%d. */
181 uword
182 unformat_ip4_address (unformat_input_t * input, va_list * args)
183 {
184   u8 *result = va_arg (*args, u8 *);
185   unsigned a[4];
186
187   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
188     return 0;
189
190   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
191     return 0;
192
193   result[0] = a[0];
194   result[1] = a[1];
195   result[2] = a[2];
196   result[3] = a[3];
197
198   return 1;
199 }
200
201 uword
202 unformat_ethernet_address (unformat_input_t * input, va_list * args)
203 {
204   u8 *result = va_arg (*args, u8 *);
205   u32 i, a[6];
206
207   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
208                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
209     return 0;
210
211   /* Check range. */
212   for (i = 0; i < 6; i++)
213     if (a[i] >= (1 << 8))
214       return 0;
215
216   for (i = 0; i < 6; i++)
217     result[i] = a[i];
218
219   return 1;
220 }
221
222 /* Returns ethernet type as an int in host byte order. */
223 uword
224 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
225                                         va_list * args)
226 {
227   u16 *result = va_arg (*args, u16 *);
228   int type;
229
230   /* Numeric type. */
231   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
232     {
233       if (type >= (1 << 16))
234         return 0;
235       *result = type;
236       return 1;
237     }
238   return 0;
239 }
240
241 /* Parse an IP6 address. */
242 uword
243 unformat_ip6_address (unformat_input_t * input, va_list * args)
244 {
245   ip6_address_t *result = va_arg (*args, ip6_address_t *);
246   u16 hex_quads[8];
247   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
248   uword c, n_colon, double_colon_index;
249
250   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
251   double_colon_index = ARRAY_LEN (hex_quads);
252   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
253     {
254       hex_digit = 16;
255       if (c >= '0' && c <= '9')
256         hex_digit = c - '0';
257       else if (c >= 'a' && c <= 'f')
258         hex_digit = c + 10 - 'a';
259       else if (c >= 'A' && c <= 'F')
260         hex_digit = c + 10 - 'A';
261       else if (c == ':' && n_colon < 2)
262         n_colon++;
263       else
264         {
265           unformat_put_input (input);
266           break;
267         }
268
269       /* Too many hex quads. */
270       if (n_hex_quads >= ARRAY_LEN (hex_quads))
271         return 0;
272
273       if (hex_digit < 16)
274         {
275           hex_quad = (hex_quad << 4) | hex_digit;
276
277           /* Hex quad must fit in 16 bits. */
278           if (n_hex_digits >= 4)
279             return 0;
280
281           n_colon = 0;
282           n_hex_digits++;
283         }
284
285       /* Save position of :: */
286       if (n_colon == 2)
287         {
288           /* More than one :: ? */
289           if (double_colon_index < ARRAY_LEN (hex_quads))
290             return 0;
291           double_colon_index = n_hex_quads;
292         }
293
294       if (n_colon > 0 && n_hex_digits > 0)
295         {
296           hex_quads[n_hex_quads++] = hex_quad;
297           hex_quad = 0;
298           n_hex_digits = 0;
299         }
300     }
301
302   if (n_hex_digits > 0)
303     hex_quads[n_hex_quads++] = hex_quad;
304
305   {
306     word i;
307
308     /* Expand :: to appropriate number of zero hex quads. */
309     if (double_colon_index < ARRAY_LEN (hex_quads))
310       {
311         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
312
313         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
314           hex_quads[n_zero + i] = hex_quads[i];
315
316         for (i = 0; i < n_zero; i++)
317           hex_quads[double_colon_index + i] = 0;
318
319         n_hex_quads = ARRAY_LEN (hex_quads);
320       }
321
322     /* Too few hex quads given. */
323     if (n_hex_quads < ARRAY_LEN (hex_quads))
324       return 0;
325
326     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
327       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
328
329     return 1;
330   }
331 }
332
333 uword
334 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
335 {
336   u32 *r = va_arg (*args, u32 *);
337
338   if (0);
339 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
340   foreach_ipsec_policy_action
341 #undef _
342     else
343     return 0;
344   return 1;
345 }
346
347 uword
348 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
349 {
350   u32 *r = va_arg (*args, u32 *);
351
352   if (0);
353 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
354   foreach_ipsec_crypto_alg
355 #undef _
356     else
357     return 0;
358   return 1;
359 }
360
361 u8 *
362 format_ipsec_crypto_alg (u8 * s, va_list * args)
363 {
364   u32 i = va_arg (*args, u32);
365   u8 *t = 0;
366
367   switch (i)
368     {
369 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
370       foreach_ipsec_crypto_alg
371 #undef _
372     default:
373       return format (s, "unknown");
374     }
375   return format (s, "%s", t);
376 }
377
378 uword
379 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
380 {
381   u32 *r = va_arg (*args, u32 *);
382
383   if (0);
384 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
385   foreach_ipsec_integ_alg
386 #undef _
387     else
388     return 0;
389   return 1;
390 }
391
392 u8 *
393 format_ipsec_integ_alg (u8 * s, va_list * args)
394 {
395   u32 i = va_arg (*args, u32);
396   u8 *t = 0;
397
398   switch (i)
399     {
400 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
401       foreach_ipsec_integ_alg
402 #undef _
403     default:
404       return format (s, "unknown");
405     }
406   return format (s, "%s", t);
407 }
408
409 uword
410 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
411 {
412   u32 *r = va_arg (*args, u32 *);
413
414   if (0);
415 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
416   foreach_ikev2_auth_method
417 #undef _
418     else
419     return 0;
420   return 1;
421 }
422
423 uword
424 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
425 {
426   u32 *r = va_arg (*args, u32 *);
427
428   if (0);
429 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
430   foreach_ikev2_id_type
431 #undef _
432     else
433     return 0;
434   return 1;
435 }
436 #else /* VPP_API_TEST_BUILTIN == 1 */
437 static uword
438 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
439 {
440   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
441   vnet_main_t *vnm = vnet_get_main ();
442   u32 *result = va_arg (*args, u32 *);
443   u32 sw_if_index;
444
445   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
446     return 0;
447
448   *result = sw_if_index;
449   return 1;
450 }
451 #endif /* VPP_API_TEST_BUILTIN */
452
453 static uword
454 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "kbps"))
459     *r = SSE2_QOS_RATE_KBPS;
460   else if (unformat (input, "pps"))
461     *r = SSE2_QOS_RATE_PPS;
462   else
463     return 0;
464   return 1;
465 }
466
467 static uword
468 unformat_policer_round_type (unformat_input_t * input, va_list * args)
469 {
470   u8 *r = va_arg (*args, u8 *);
471
472   if (unformat (input, "closest"))
473     *r = SSE2_QOS_ROUND_TO_CLOSEST;
474   else if (unformat (input, "up"))
475     *r = SSE2_QOS_ROUND_TO_UP;
476   else if (unformat (input, "down"))
477     *r = SSE2_QOS_ROUND_TO_DOWN;
478   else
479     return 0;
480   return 1;
481 }
482
483 static uword
484 unformat_policer_type (unformat_input_t * input, va_list * args)
485 {
486   u8 *r = va_arg (*args, u8 *);
487
488   if (unformat (input, "1r2c"))
489     *r = SSE2_QOS_POLICER_TYPE_1R2C;
490   else if (unformat (input, "1r3c"))
491     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
492   else if (unformat (input, "2r3c-2698"))
493     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
494   else if (unformat (input, "2r3c-4115"))
495     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
496   else if (unformat (input, "2r3c-mef5cf1"))
497     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
498   else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_dscp (unformat_input_t * input, va_list * va)
505 {
506   u8 *r = va_arg (*va, u8 *);
507
508   if (0);
509 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
510   foreach_vnet_dscp
511 #undef _
512     else
513     return 0;
514   return 1;
515 }
516
517 static uword
518 unformat_policer_action_type (unformat_input_t * input, va_list * va)
519 {
520   sse2_qos_pol_action_params_st *a
521     = va_arg (*va, sse2_qos_pol_action_params_st *);
522
523   if (unformat (input, "drop"))
524     a->action_type = SSE2_QOS_ACTION_DROP;
525   else if (unformat (input, "transmit"))
526     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
527   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
528     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
529   else
530     return 0;
531   return 1;
532 }
533
534 static uword
535 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
536 {
537   u32 *r = va_arg (*va, u32 *);
538   u32 tid;
539
540   if (unformat (input, "ip4"))
541     tid = POLICER_CLASSIFY_TABLE_IP4;
542   else if (unformat (input, "ip6"))
543     tid = POLICER_CLASSIFY_TABLE_IP6;
544   else if (unformat (input, "l2"))
545     tid = POLICER_CLASSIFY_TABLE_L2;
546   else
547     return 0;
548
549   *r = tid;
550   return 1;
551 }
552
553 static uword
554 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
555 {
556   u32 *r = va_arg (*va, u32 *);
557   u32 tid;
558
559   if (unformat (input, "ip4"))
560     tid = FLOW_CLASSIFY_TABLE_IP4;
561   else if (unformat (input, "ip6"))
562     tid = FLOW_CLASSIFY_TABLE_IP6;
563   else
564     return 0;
565
566   *r = tid;
567   return 1;
568 }
569
570 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
571 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
572 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
573 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
574
575 #if (VPP_API_TEST_BUILTIN==0)
576 uword
577 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
578 {
579   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
580   mfib_itf_attribute_t attr;
581
582   old = *iflags;
583   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
584   {
585     if (unformat (input, mfib_itf_flag_long_names[attr]))
586       *iflags |= (1 << attr);
587   }
588   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
589   {
590     if (unformat (input, mfib_itf_flag_names[attr]))
591       *iflags |= (1 << attr);
592   }
593
594   return (old == *iflags ? 0 : 1);
595 }
596
597 uword
598 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
599 {
600   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
601   mfib_entry_attribute_t attr;
602
603   old = *eflags;
604   FOR_EACH_MFIB_ATTRIBUTE (attr)
605   {
606     if (unformat (input, mfib_flag_long_names[attr]))
607       *eflags |= (1 << attr);
608   }
609   FOR_EACH_MFIB_ATTRIBUTE (attr)
610   {
611     if (unformat (input, mfib_flag_names[attr]))
612       *eflags |= (1 << attr);
613   }
614
615   return (old == *eflags ? 0 : 1);
616 }
617
618 u8 *
619 format_ip4_address (u8 * s, va_list * args)
620 {
621   u8 *a = va_arg (*args, u8 *);
622   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
623 }
624
625 u8 *
626 format_ip6_address (u8 * s, va_list * args)
627 {
628   ip6_address_t *a = va_arg (*args, ip6_address_t *);
629   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
630
631   i_max_n_zero = ARRAY_LEN (a->as_u16);
632   max_n_zeros = 0;
633   i_first_zero = i_max_n_zero;
634   n_zeros = 0;
635   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
636     {
637       u32 is_zero = a->as_u16[i] == 0;
638       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
639         {
640           i_first_zero = i;
641           n_zeros = 0;
642         }
643       n_zeros += is_zero;
644       if ((!is_zero && n_zeros > max_n_zeros)
645           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
646         {
647           i_max_n_zero = i_first_zero;
648           max_n_zeros = n_zeros;
649           i_first_zero = ARRAY_LEN (a->as_u16);
650           n_zeros = 0;
651         }
652     }
653
654   last_double_colon = 0;
655   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
656     {
657       if (i == i_max_n_zero && max_n_zeros > 1)
658         {
659           s = format (s, "::");
660           i += max_n_zeros - 1;
661           last_double_colon = 1;
662         }
663       else
664         {
665           s = format (s, "%s%x",
666                       (last_double_colon || i == 0) ? "" : ":",
667                       clib_net_to_host_u16 (a->as_u16[i]));
668           last_double_colon = 0;
669         }
670     }
671
672   return s;
673 }
674
675 /* Format an IP46 address. */
676 u8 *
677 format_ip46_address (u8 * s, va_list * args)
678 {
679   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
680   ip46_type_t type = va_arg (*args, ip46_type_t);
681   int is_ip4 = 1;
682
683   switch (type)
684     {
685     case IP46_TYPE_ANY:
686       is_ip4 = ip46_address_is_ip4 (ip46);
687       break;
688     case IP46_TYPE_IP4:
689       is_ip4 = 1;
690       break;
691     case IP46_TYPE_IP6:
692       is_ip4 = 0;
693       break;
694     }
695
696   return is_ip4 ?
697     format (s, "%U", format_ip4_address, &ip46->ip4) :
698     format (s, "%U", format_ip6_address, &ip46->ip6);
699 }
700
701 u8 *
702 format_ethernet_address (u8 * s, va_list * args)
703 {
704   u8 *a = va_arg (*args, u8 *);
705
706   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
707                  a[0], a[1], a[2], a[3], a[4], a[5]);
708 }
709 #endif
710
711 static void
712 increment_v4_address (ip4_address_t * a)
713 {
714   u32 v;
715
716   v = ntohl (a->as_u32) + 1;
717   a->as_u32 = ntohl (v);
718 }
719
720 static void
721 increment_v6_address (ip6_address_t * a)
722 {
723   u64 v0, v1;
724
725   v0 = clib_net_to_host_u64 (a->as_u64[0]);
726   v1 = clib_net_to_host_u64 (a->as_u64[1]);
727
728   v1 += 1;
729   if (v1 == 0)
730     v0 += 1;
731   a->as_u64[0] = clib_net_to_host_u64 (v0);
732   a->as_u64[1] = clib_net_to_host_u64 (v1);
733 }
734
735 static void
736 increment_mac_address (u8 * mac)
737 {
738   u64 tmp = *((u64 *) mac);
739   tmp = clib_net_to_host_u64 (tmp);
740   tmp += 1 << 16;               /* skip unused (least significant) octets */
741   tmp = clib_host_to_net_u64 (tmp);
742
743   clib_memcpy (mac, &tmp, 6);
744 }
745
746 static void vl_api_create_loopback_reply_t_handler
747   (vl_api_create_loopback_reply_t * mp)
748 {
749   vat_main_t *vam = &vat_main;
750   i32 retval = ntohl (mp->retval);
751
752   vam->retval = retval;
753   vam->regenerate_interface_table = 1;
754   vam->sw_if_index = ntohl (mp->sw_if_index);
755   vam->result_ready = 1;
756 }
757
758 static void vl_api_create_loopback_reply_t_handler_json
759   (vl_api_create_loopback_reply_t * mp)
760 {
761   vat_main_t *vam = &vat_main;
762   vat_json_node_t node;
763
764   vat_json_init_object (&node);
765   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
766   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
767
768   vat_json_print (vam->ofp, &node);
769   vat_json_free (&node);
770   vam->retval = ntohl (mp->retval);
771   vam->result_ready = 1;
772 }
773
774 static void vl_api_create_loopback_instance_reply_t_handler
775   (vl_api_create_loopback_instance_reply_t * mp)
776 {
777   vat_main_t *vam = &vat_main;
778   i32 retval = ntohl (mp->retval);
779
780   vam->retval = retval;
781   vam->regenerate_interface_table = 1;
782   vam->sw_if_index = ntohl (mp->sw_if_index);
783   vam->result_ready = 1;
784 }
785
786 static void vl_api_create_loopback_instance_reply_t_handler_json
787   (vl_api_create_loopback_instance_reply_t * mp)
788 {
789   vat_main_t *vam = &vat_main;
790   vat_json_node_t node;
791
792   vat_json_init_object (&node);
793   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
794   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
795
796   vat_json_print (vam->ofp, &node);
797   vat_json_free (&node);
798   vam->retval = ntohl (mp->retval);
799   vam->result_ready = 1;
800 }
801
802 static void vl_api_af_packet_create_reply_t_handler
803   (vl_api_af_packet_create_reply_t * mp)
804 {
805   vat_main_t *vam = &vat_main;
806   i32 retval = ntohl (mp->retval);
807
808   vam->retval = retval;
809   vam->regenerate_interface_table = 1;
810   vam->sw_if_index = ntohl (mp->sw_if_index);
811   vam->result_ready = 1;
812 }
813
814 static void vl_api_af_packet_create_reply_t_handler_json
815   (vl_api_af_packet_create_reply_t * mp)
816 {
817   vat_main_t *vam = &vat_main;
818   vat_json_node_t node;
819
820   vat_json_init_object (&node);
821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
822   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
823
824   vat_json_print (vam->ofp, &node);
825   vat_json_free (&node);
826
827   vam->retval = ntohl (mp->retval);
828   vam->result_ready = 1;
829 }
830
831 static void vl_api_create_vlan_subif_reply_t_handler
832   (vl_api_create_vlan_subif_reply_t * mp)
833 {
834   vat_main_t *vam = &vat_main;
835   i32 retval = ntohl (mp->retval);
836
837   vam->retval = retval;
838   vam->regenerate_interface_table = 1;
839   vam->sw_if_index = ntohl (mp->sw_if_index);
840   vam->result_ready = 1;
841 }
842
843 static void vl_api_create_vlan_subif_reply_t_handler_json
844   (vl_api_create_vlan_subif_reply_t * mp)
845 {
846   vat_main_t *vam = &vat_main;
847   vat_json_node_t node;
848
849   vat_json_init_object (&node);
850   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
851   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
852
853   vat_json_print (vam->ofp, &node);
854   vat_json_free (&node);
855
856   vam->retval = ntohl (mp->retval);
857   vam->result_ready = 1;
858 }
859
860 static void vl_api_create_subif_reply_t_handler
861   (vl_api_create_subif_reply_t * mp)
862 {
863   vat_main_t *vam = &vat_main;
864   i32 retval = ntohl (mp->retval);
865
866   vam->retval = retval;
867   vam->regenerate_interface_table = 1;
868   vam->sw_if_index = ntohl (mp->sw_if_index);
869   vam->result_ready = 1;
870 }
871
872 static void vl_api_create_subif_reply_t_handler_json
873   (vl_api_create_subif_reply_t * mp)
874 {
875   vat_main_t *vam = &vat_main;
876   vat_json_node_t node;
877
878   vat_json_init_object (&node);
879   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
880   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
881
882   vat_json_print (vam->ofp, &node);
883   vat_json_free (&node);
884
885   vam->retval = ntohl (mp->retval);
886   vam->result_ready = 1;
887 }
888
889 static void vl_api_interface_name_renumber_reply_t_handler
890   (vl_api_interface_name_renumber_reply_t * mp)
891 {
892   vat_main_t *vam = &vat_main;
893   i32 retval = ntohl (mp->retval);
894
895   vam->retval = retval;
896   vam->regenerate_interface_table = 1;
897   vam->result_ready = 1;
898 }
899
900 static void vl_api_interface_name_renumber_reply_t_handler_json
901   (vl_api_interface_name_renumber_reply_t * mp)
902 {
903   vat_main_t *vam = &vat_main;
904   vat_json_node_t node;
905
906   vat_json_init_object (&node);
907   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
908
909   vat_json_print (vam->ofp, &node);
910   vat_json_free (&node);
911
912   vam->retval = ntohl (mp->retval);
913   vam->result_ready = 1;
914 }
915
916 /*
917  * Special-case: build the interface table, maintain
918  * the next loopback sw_if_index vbl.
919  */
920 static void vl_api_sw_interface_details_t_handler
921   (vl_api_sw_interface_details_t * mp)
922 {
923   vat_main_t *vam = &vat_main;
924   u8 *s = format (0, "%s%c", mp->interface_name, 0);
925
926   hash_set_mem (vam->sw_if_index_by_interface_name, s,
927                 ntohl (mp->sw_if_index));
928
929   /* In sub interface case, fill the sub interface table entry */
930   if (mp->sw_if_index != mp->sup_sw_if_index)
931     {
932       sw_interface_subif_t *sub = NULL;
933
934       vec_add2 (vam->sw_if_subif_table, sub, 1);
935
936       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
937       strncpy ((char *) sub->interface_name, (char *) s,
938                vec_len (sub->interface_name));
939       sub->sw_if_index = ntohl (mp->sw_if_index);
940       sub->sub_id = ntohl (mp->sub_id);
941
942       sub->sub_dot1ad = mp->sub_dot1ad;
943       sub->sub_number_of_tags = mp->sub_number_of_tags;
944       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
945       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
946       sub->sub_exact_match = mp->sub_exact_match;
947       sub->sub_default = mp->sub_default;
948       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
949       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
950
951       /* vlan tag rewrite */
952       sub->vtr_op = ntohl (mp->vtr_op);
953       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
954       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
955       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
956     }
957 }
958
959 static void vl_api_sw_interface_details_t_handler_json
960   (vl_api_sw_interface_details_t * mp)
961 {
962   vat_main_t *vam = &vat_main;
963   vat_json_node_t *node = NULL;
964
965   if (VAT_JSON_ARRAY != vam->json_tree.type)
966     {
967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
968       vat_json_init_array (&vam->json_tree);
969     }
970   node = vat_json_array_add (&vam->json_tree);
971
972   vat_json_init_object (node);
973   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
974   vat_json_object_add_uint (node, "sup_sw_if_index",
975                             ntohl (mp->sup_sw_if_index));
976   vat_json_object_add_uint (node, "l2_address_length",
977                             ntohl (mp->l2_address_length));
978   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
979                              sizeof (mp->l2_address));
980   vat_json_object_add_string_copy (node, "interface_name",
981                                    mp->interface_name);
982   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
983   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
984   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
985   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
986   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
987   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
988   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
989   vat_json_object_add_uint (node, "sub_number_of_tags",
990                             mp->sub_number_of_tags);
991   vat_json_object_add_uint (node, "sub_outer_vlan_id",
992                             ntohs (mp->sub_outer_vlan_id));
993   vat_json_object_add_uint (node, "sub_inner_vlan_id",
994                             ntohs (mp->sub_inner_vlan_id));
995   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
996   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
997   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
998                             mp->sub_outer_vlan_id_any);
999   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1000                             mp->sub_inner_vlan_id_any);
1001   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1002   vat_json_object_add_uint (node, "vtr_push_dot1q",
1003                             ntohl (mp->vtr_push_dot1q));
1004   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1005   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1006   if (mp->sub_dot1ah)
1007     {
1008       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1009                                        format (0, "%U",
1010                                                format_ethernet_address,
1011                                                &mp->b_dmac));
1012       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1013                                        format (0, "%U",
1014                                                format_ethernet_address,
1015                                                &mp->b_smac));
1016       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1017       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1018     }
1019 }
1020
1021 #if VPP_API_TEST_BUILTIN == 0
1022 static void vl_api_sw_interface_event_t_handler
1023   (vl_api_sw_interface_event_t * mp)
1024 {
1025   vat_main_t *vam = &vat_main;
1026   if (vam->interface_event_display)
1027     errmsg ("interface flags: sw_if_index %d %s %s",
1028             ntohl (mp->sw_if_index),
1029             mp->admin_up_down ? "admin-up" : "admin-down",
1030             mp->link_up_down ? "link-up" : "link-down");
1031 }
1032 #endif
1033
1034 static void vl_api_sw_interface_event_t_handler_json
1035   (vl_api_sw_interface_event_t * mp)
1036 {
1037   /* JSON output not supported */
1038 }
1039
1040 static void
1041 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1042 {
1043   vat_main_t *vam = &vat_main;
1044   i32 retval = ntohl (mp->retval);
1045
1046   vam->retval = retval;
1047   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1048   vam->result_ready = 1;
1049 }
1050
1051 static void
1052 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1053 {
1054   vat_main_t *vam = &vat_main;
1055   vat_json_node_t node;
1056   api_main_t *am = &api_main;
1057   void *oldheap;
1058   u8 *reply;
1059
1060   vat_json_init_object (&node);
1061   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1062   vat_json_object_add_uint (&node, "reply_in_shmem",
1063                             ntohl (mp->reply_in_shmem));
1064   /* Toss the shared-memory original... */
1065   pthread_mutex_lock (&am->vlib_rp->mutex);
1066   oldheap = svm_push_data_heap (am->vlib_rp);
1067
1068   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1069   vec_free (reply);
1070
1071   svm_pop_heap (oldheap);
1072   pthread_mutex_unlock (&am->vlib_rp->mutex);
1073
1074   vat_json_print (vam->ofp, &node);
1075   vat_json_free (&node);
1076
1077   vam->retval = ntohl (mp->retval);
1078   vam->result_ready = 1;
1079 }
1080
1081 static void
1082 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1083 {
1084   vat_main_t *vam = &vat_main;
1085   i32 retval = ntohl (mp->retval);
1086   u32 length = ntohl (mp->length);
1087
1088   vec_reset_length (vam->cmd_reply);
1089
1090   vam->retval = retval;
1091   if (retval == 0)
1092     {
1093       vec_validate (vam->cmd_reply, length);
1094       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1095       vam->cmd_reply[length] = 0;
1096     }
1097   vam->result_ready = 1;
1098 }
1099
1100 static void
1101 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   vat_json_node_t node;
1105
1106   vec_reset_length (vam->cmd_reply);
1107
1108   vat_json_init_object (&node);
1109   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1110   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1111
1112   vat_json_print (vam->ofp, &node);
1113   vat_json_free (&node);
1114
1115   vam->retval = ntohl (mp->retval);
1116   vam->result_ready = 1;
1117 }
1118
1119 static void vl_api_classify_add_del_table_reply_t_handler
1120   (vl_api_classify_add_del_table_reply_t * mp)
1121 {
1122   vat_main_t *vam = &vat_main;
1123   i32 retval = ntohl (mp->retval);
1124   if (vam->async_mode)
1125     {
1126       vam->async_errors += (retval < 0);
1127     }
1128   else
1129     {
1130       vam->retval = retval;
1131       if (retval == 0 &&
1132           ((mp->new_table_index != 0xFFFFFFFF) ||
1133            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1134            (mp->match_n_vectors != 0xFFFFFFFF)))
1135         /*
1136          * Note: this is just barely thread-safe, depends on
1137          * the main thread spinning waiting for an answer...
1138          */
1139         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1140                 ntohl (mp->new_table_index),
1141                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1142       vam->result_ready = 1;
1143     }
1144 }
1145
1146 static void vl_api_classify_add_del_table_reply_t_handler_json
1147   (vl_api_classify_add_del_table_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   vat_json_node_t node;
1151
1152   vat_json_init_object (&node);
1153   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1154   vat_json_object_add_uint (&node, "new_table_index",
1155                             ntohl (mp->new_table_index));
1156   vat_json_object_add_uint (&node, "skip_n_vectors",
1157                             ntohl (mp->skip_n_vectors));
1158   vat_json_object_add_uint (&node, "match_n_vectors",
1159                             ntohl (mp->match_n_vectors));
1160
1161   vat_json_print (vam->ofp, &node);
1162   vat_json_free (&node);
1163
1164   vam->retval = ntohl (mp->retval);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void vl_api_get_node_index_reply_t_handler
1169   (vl_api_get_node_index_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   i32 retval = ntohl (mp->retval);
1173   if (vam->async_mode)
1174     {
1175       vam->async_errors += (retval < 0);
1176     }
1177   else
1178     {
1179       vam->retval = retval;
1180       if (retval == 0)
1181         errmsg ("node index %d", ntohl (mp->node_index));
1182       vam->result_ready = 1;
1183     }
1184 }
1185
1186 static void vl_api_get_node_index_reply_t_handler_json
1187   (vl_api_get_node_index_reply_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   vat_json_node_t node;
1191
1192   vat_json_init_object (&node);
1193   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1194   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1195
1196   vat_json_print (vam->ofp, &node);
1197   vat_json_free (&node);
1198
1199   vam->retval = ntohl (mp->retval);
1200   vam->result_ready = 1;
1201 }
1202
1203 static void vl_api_get_next_index_reply_t_handler
1204   (vl_api_get_next_index_reply_t * mp)
1205 {
1206   vat_main_t *vam = &vat_main;
1207   i32 retval = ntohl (mp->retval);
1208   if (vam->async_mode)
1209     {
1210       vam->async_errors += (retval < 0);
1211     }
1212   else
1213     {
1214       vam->retval = retval;
1215       if (retval == 0)
1216         errmsg ("next node index %d", ntohl (mp->next_index));
1217       vam->result_ready = 1;
1218     }
1219 }
1220
1221 static void vl_api_get_next_index_reply_t_handler_json
1222   (vl_api_get_next_index_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   vat_json_node_t node;
1226
1227   vat_json_init_object (&node);
1228   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1229   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1230
1231   vat_json_print (vam->ofp, &node);
1232   vat_json_free (&node);
1233
1234   vam->retval = ntohl (mp->retval);
1235   vam->result_ready = 1;
1236 }
1237
1238 static void vl_api_add_node_next_reply_t_handler
1239   (vl_api_add_node_next_reply_t * mp)
1240 {
1241   vat_main_t *vam = &vat_main;
1242   i32 retval = ntohl (mp->retval);
1243   if (vam->async_mode)
1244     {
1245       vam->async_errors += (retval < 0);
1246     }
1247   else
1248     {
1249       vam->retval = retval;
1250       if (retval == 0)
1251         errmsg ("next index %d", ntohl (mp->next_index));
1252       vam->result_ready = 1;
1253     }
1254 }
1255
1256 static void vl_api_add_node_next_reply_t_handler_json
1257   (vl_api_add_node_next_reply_t * mp)
1258 {
1259   vat_main_t *vam = &vat_main;
1260   vat_json_node_t node;
1261
1262   vat_json_init_object (&node);
1263   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1264   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1265
1266   vat_json_print (vam->ofp, &node);
1267   vat_json_free (&node);
1268
1269   vam->retval = ntohl (mp->retval);
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_show_version_reply_t_handler
1274   (vl_api_show_version_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278
1279   if (retval >= 0)
1280     {
1281       errmsg ("        program: %s", mp->program);
1282       errmsg ("        version: %s", mp->version);
1283       errmsg ("     build date: %s", mp->build_date);
1284       errmsg ("build directory: %s", mp->build_directory);
1285     }
1286   vam->retval = retval;
1287   vam->result_ready = 1;
1288 }
1289
1290 static void vl_api_show_version_reply_t_handler_json
1291   (vl_api_show_version_reply_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   vat_json_node_t node;
1295
1296   vat_json_init_object (&node);
1297   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1298   vat_json_object_add_string_copy (&node, "program", mp->program);
1299   vat_json_object_add_string_copy (&node, "version", mp->version);
1300   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1301   vat_json_object_add_string_copy (&node, "build_directory",
1302                                    mp->build_directory);
1303
1304   vat_json_print (vam->ofp, &node);
1305   vat_json_free (&node);
1306
1307   vam->retval = ntohl (mp->retval);
1308   vam->result_ready = 1;
1309 }
1310
1311 static void
1312 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1313 {
1314   u32 sw_if_index = ntohl (mp->sw_if_index);
1315   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1316           mp->mac_ip ? "mac/ip binding" : "address resolution",
1317           ntohl (mp->pid), format_ip4_address, &mp->address,
1318           format_ethernet_address, mp->new_mac, sw_if_index);
1319 }
1320
1321 static void
1322 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1323 {
1324   /* JSON output not supported */
1325 }
1326
1327 static void
1328 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1329 {
1330   u32 sw_if_index = ntohl (mp->sw_if_index);
1331   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1332           mp->mac_ip ? "mac/ip binding" : "address resolution",
1333           ntohl (mp->pid), format_ip6_address, mp->address,
1334           format_ethernet_address, mp->new_mac, sw_if_index);
1335 }
1336
1337 static void
1338 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1339 {
1340   /* JSON output not supported */
1341 }
1342
1343 static void
1344 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1345 {
1346   u32 n_macs = ntohl (mp->n_macs);
1347   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1348           ntohl (mp->pid), mp->client_index, n_macs);
1349   int i;
1350   for (i = 0; i < n_macs; i++)
1351     {
1352       vl_api_mac_entry_t *mac = &mp->mac[i];
1353       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1354               i + 1, ntohl (mac->sw_if_index),
1355               format_ethernet_address, mac->mac_addr, mac->action);
1356       if (i == 1000)
1357         break;
1358     }
1359 }
1360
1361 static void
1362 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1363 {
1364   /* JSON output not supported */
1365 }
1366
1367 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1368 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1369
1370 /*
1371  * Special-case: build the bridge domain table, maintain
1372  * the next bd id vbl.
1373  */
1374 static void vl_api_bridge_domain_details_t_handler
1375   (vl_api_bridge_domain_details_t * mp)
1376 {
1377   vat_main_t *vam = &vat_main;
1378   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1379   int i;
1380
1381   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1382          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1383
1384   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1385          ntohl (mp->bd_id), mp->learn, mp->forward,
1386          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1387
1388   if (n_sw_ifs)
1389     {
1390       vl_api_bridge_domain_sw_if_t *sw_ifs;
1391       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1392              "Interface Name");
1393
1394       sw_ifs = mp->sw_if_details;
1395       for (i = 0; i < n_sw_ifs; i++)
1396         {
1397           u8 *sw_if_name = 0;
1398           u32 sw_if_index;
1399           hash_pair_t *p;
1400
1401           sw_if_index = ntohl (sw_ifs->sw_if_index);
1402
1403           /* *INDENT-OFF* */
1404           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1405                              ({
1406                                if ((u32) p->value[0] == sw_if_index)
1407                                  {
1408                                    sw_if_name = (u8 *)(p->key);
1409                                    break;
1410                                  }
1411                              }));
1412           /* *INDENT-ON* */
1413           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1414                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1415                  "sw_if_index not found!");
1416
1417           sw_ifs++;
1418         }
1419     }
1420 }
1421
1422 static void vl_api_bridge_domain_details_t_handler_json
1423   (vl_api_bridge_domain_details_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   vat_json_node_t *node, *array = NULL;
1427   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1428
1429   if (VAT_JSON_ARRAY != vam->json_tree.type)
1430     {
1431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1432       vat_json_init_array (&vam->json_tree);
1433     }
1434   node = vat_json_array_add (&vam->json_tree);
1435
1436   vat_json_init_object (node);
1437   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1438   vat_json_object_add_uint (node, "flood", mp->flood);
1439   vat_json_object_add_uint (node, "forward", mp->forward);
1440   vat_json_object_add_uint (node, "learn", mp->learn);
1441   vat_json_object_add_uint (node, "bvi_sw_if_index",
1442                             ntohl (mp->bvi_sw_if_index));
1443   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1444   array = vat_json_object_add (node, "sw_if");
1445   vat_json_init_array (array);
1446
1447
1448
1449   if (n_sw_ifs)
1450     {
1451       vl_api_bridge_domain_sw_if_t *sw_ifs;
1452       int i;
1453
1454       sw_ifs = mp->sw_if_details;
1455       for (i = 0; i < n_sw_ifs; i++)
1456         {
1457           node = vat_json_array_add (array);
1458           vat_json_init_object (node);
1459           vat_json_object_add_uint (node, "sw_if_index",
1460                                     ntohl (sw_ifs->sw_if_index));
1461           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1462           sw_ifs++;
1463         }
1464     }
1465 }
1466
1467 static void vl_api_control_ping_reply_t_handler
1468   (vl_api_control_ping_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   i32 retval = ntohl (mp->retval);
1472   if (vam->async_mode)
1473     {
1474       vam->async_errors += (retval < 0);
1475     }
1476   else
1477     {
1478       vam->retval = retval;
1479       vam->result_ready = 1;
1480     }
1481   if (vam->socket_client_main)
1482     vam->socket_client_main->control_pings_outstanding--;
1483 }
1484
1485 static void vl_api_control_ping_reply_t_handler_json
1486   (vl_api_control_ping_reply_t * mp)
1487 {
1488   vat_main_t *vam = &vat_main;
1489   i32 retval = ntohl (mp->retval);
1490
1491   if (VAT_JSON_NONE != vam->json_tree.type)
1492     {
1493       vat_json_print (vam->ofp, &vam->json_tree);
1494       vat_json_free (&vam->json_tree);
1495       vam->json_tree.type = VAT_JSON_NONE;
1496     }
1497   else
1498     {
1499       /* just print [] */
1500       vat_json_init_array (&vam->json_tree);
1501       vat_json_print (vam->ofp, &vam->json_tree);
1502       vam->json_tree.type = VAT_JSON_NONE;
1503     }
1504
1505   vam->retval = retval;
1506   vam->result_ready = 1;
1507 }
1508
1509 static void
1510   vl_api_bridge_domain_set_mac_age_reply_t_handler
1511   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   i32 retval = ntohl (mp->retval);
1515   if (vam->async_mode)
1516     {
1517       vam->async_errors += (retval < 0);
1518     }
1519   else
1520     {
1521       vam->retval = retval;
1522       vam->result_ready = 1;
1523     }
1524 }
1525
1526 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1527   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1528 {
1529   vat_main_t *vam = &vat_main;
1530   vat_json_node_t node;
1531
1532   vat_json_init_object (&node);
1533   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1534
1535   vat_json_print (vam->ofp, &node);
1536   vat_json_free (&node);
1537
1538   vam->retval = ntohl (mp->retval);
1539   vam->result_ready = 1;
1540 }
1541
1542 static void
1543 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   i32 retval = ntohl (mp->retval);
1547   if (vam->async_mode)
1548     {
1549       vam->async_errors += (retval < 0);
1550     }
1551   else
1552     {
1553       vam->retval = retval;
1554       vam->result_ready = 1;
1555     }
1556 }
1557
1558 static void vl_api_l2_flags_reply_t_handler_json
1559   (vl_api_l2_flags_reply_t * mp)
1560 {
1561   vat_main_t *vam = &vat_main;
1562   vat_json_node_t node;
1563
1564   vat_json_init_object (&node);
1565   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1566   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1567                             ntohl (mp->resulting_feature_bitmap));
1568
1569   vat_json_print (vam->ofp, &node);
1570   vat_json_free (&node);
1571
1572   vam->retval = ntohl (mp->retval);
1573   vam->result_ready = 1;
1574 }
1575
1576 static void vl_api_bridge_flags_reply_t_handler
1577   (vl_api_bridge_flags_reply_t * mp)
1578 {
1579   vat_main_t *vam = &vat_main;
1580   i32 retval = ntohl (mp->retval);
1581   if (vam->async_mode)
1582     {
1583       vam->async_errors += (retval < 0);
1584     }
1585   else
1586     {
1587       vam->retval = retval;
1588       vam->result_ready = 1;
1589     }
1590 }
1591
1592 static void vl_api_bridge_flags_reply_t_handler_json
1593   (vl_api_bridge_flags_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   vat_json_node_t node;
1597
1598   vat_json_init_object (&node);
1599   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1600   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1601                             ntohl (mp->resulting_feature_bitmap));
1602
1603   vat_json_print (vam->ofp, &node);
1604   vat_json_free (&node);
1605
1606   vam->retval = ntohl (mp->retval);
1607   vam->result_ready = 1;
1608 }
1609
1610 static void vl_api_tap_connect_reply_t_handler
1611   (vl_api_tap_connect_reply_t * mp)
1612 {
1613   vat_main_t *vam = &vat_main;
1614   i32 retval = ntohl (mp->retval);
1615   if (vam->async_mode)
1616     {
1617       vam->async_errors += (retval < 0);
1618     }
1619   else
1620     {
1621       vam->retval = retval;
1622       vam->sw_if_index = ntohl (mp->sw_if_index);
1623       vam->result_ready = 1;
1624     }
1625
1626 }
1627
1628 static void vl_api_tap_connect_reply_t_handler_json
1629   (vl_api_tap_connect_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   vat_json_node_t node;
1633
1634   vat_json_init_object (&node);
1635   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1636   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1637
1638   vat_json_print (vam->ofp, &node);
1639   vat_json_free (&node);
1640
1641   vam->retval = ntohl (mp->retval);
1642   vam->result_ready = 1;
1643
1644 }
1645
1646 static void
1647 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1648 {
1649   vat_main_t *vam = &vat_main;
1650   i32 retval = ntohl (mp->retval);
1651   if (vam->async_mode)
1652     {
1653       vam->async_errors += (retval < 0);
1654     }
1655   else
1656     {
1657       vam->retval = retval;
1658       vam->sw_if_index = ntohl (mp->sw_if_index);
1659       vam->result_ready = 1;
1660     }
1661 }
1662
1663 static void vl_api_tap_modify_reply_t_handler_json
1664   (vl_api_tap_modify_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   vat_json_node_t node;
1668
1669   vat_json_init_object (&node);
1670   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1671   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1672
1673   vat_json_print (vam->ofp, &node);
1674   vat_json_free (&node);
1675
1676   vam->retval = ntohl (mp->retval);
1677   vam->result_ready = 1;
1678 }
1679
1680 static void
1681 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   i32 retval = ntohl (mp->retval);
1685   if (vam->async_mode)
1686     {
1687       vam->async_errors += (retval < 0);
1688     }
1689   else
1690     {
1691       vam->retval = retval;
1692       vam->result_ready = 1;
1693     }
1694 }
1695
1696 static void vl_api_tap_delete_reply_t_handler_json
1697   (vl_api_tap_delete_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   vat_json_node_t node;
1701
1702   vat_json_init_object (&node);
1703   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1704
1705   vat_json_print (vam->ofp, &node);
1706   vat_json_free (&node);
1707
1708   vam->retval = ntohl (mp->retval);
1709   vam->result_ready = 1;
1710 }
1711
1712 static void
1713 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1714 {
1715   vat_main_t *vam = &vat_main;
1716   i32 retval = ntohl (mp->retval);
1717   if (vam->async_mode)
1718     {
1719       vam->async_errors += (retval < 0);
1720     }
1721   else
1722     {
1723       vam->retval = retval;
1724       vam->sw_if_index = ntohl (mp->sw_if_index);
1725       vam->result_ready = 1;
1726     }
1727
1728 }
1729
1730 static void vl_api_tap_create_v2_reply_t_handler_json
1731   (vl_api_tap_create_v2_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   vat_json_node_t node;
1735
1736   vat_json_init_object (&node);
1737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1738   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1739
1740   vat_json_print (vam->ofp, &node);
1741   vat_json_free (&node);
1742
1743   vam->retval = ntohl (mp->retval);
1744   vam->result_ready = 1;
1745
1746 }
1747
1748 static void
1749 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1750 {
1751   vat_main_t *vam = &vat_main;
1752   i32 retval = ntohl (mp->retval);
1753   if (vam->async_mode)
1754     {
1755       vam->async_errors += (retval < 0);
1756     }
1757   else
1758     {
1759       vam->retval = retval;
1760       vam->result_ready = 1;
1761     }
1762 }
1763
1764 static void vl_api_tap_delete_v2_reply_t_handler_json
1765   (vl_api_tap_delete_v2_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   vat_json_node_t node;
1769
1770   vat_json_init_object (&node);
1771   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1772
1773   vat_json_print (vam->ofp, &node);
1774   vat_json_free (&node);
1775
1776   vam->retval = ntohl (mp->retval);
1777   vam->result_ready = 1;
1778 }
1779
1780 static void
1781 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   i32 retval = ntohl (mp->retval);
1785
1786   if (vam->async_mode)
1787     {
1788       vam->async_errors += (retval < 0);
1789     }
1790   else
1791     {
1792       vam->retval = retval;
1793       vam->sw_if_index = ntohl (mp->sw_if_index);
1794       vam->result_ready = 1;
1795     }
1796 }
1797
1798 static void vl_api_bond_create_reply_t_handler_json
1799   (vl_api_bond_create_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   vat_json_node_t node;
1803
1804   vat_json_init_object (&node);
1805   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1806   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1807
1808   vat_json_print (vam->ofp, &node);
1809   vat_json_free (&node);
1810
1811   vam->retval = ntohl (mp->retval);
1812   vam->result_ready = 1;
1813 }
1814
1815 static void
1816 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   i32 retval = ntohl (mp->retval);
1820
1821   if (vam->async_mode)
1822     {
1823       vam->async_errors += (retval < 0);
1824     }
1825   else
1826     {
1827       vam->retval = retval;
1828       vam->result_ready = 1;
1829     }
1830 }
1831
1832 static void vl_api_bond_delete_reply_t_handler_json
1833   (vl_api_bond_delete_reply_t * mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   vat_json_node_t node;
1837
1838   vat_json_init_object (&node);
1839   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1840
1841   vat_json_print (vam->ofp, &node);
1842   vat_json_free (&node);
1843
1844   vam->retval = ntohl (mp->retval);
1845   vam->result_ready = 1;
1846 }
1847
1848 static void
1849 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   i32 retval = ntohl (mp->retval);
1853
1854   if (vam->async_mode)
1855     {
1856       vam->async_errors += (retval < 0);
1857     }
1858   else
1859     {
1860       vam->retval = retval;
1861       vam->result_ready = 1;
1862     }
1863 }
1864
1865 static void vl_api_bond_enslave_reply_t_handler_json
1866   (vl_api_bond_enslave_reply_t * mp)
1867 {
1868   vat_main_t *vam = &vat_main;
1869   vat_json_node_t node;
1870
1871   vat_json_init_object (&node);
1872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1873
1874   vat_json_print (vam->ofp, &node);
1875   vat_json_free (&node);
1876
1877   vam->retval = ntohl (mp->retval);
1878   vam->result_ready = 1;
1879 }
1880
1881 static void
1882 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1883                                           mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   i32 retval = ntohl (mp->retval);
1887
1888   if (vam->async_mode)
1889     {
1890       vam->async_errors += (retval < 0);
1891     }
1892   else
1893     {
1894       vam->retval = retval;
1895       vam->result_ready = 1;
1896     }
1897 }
1898
1899 static void vl_api_bond_detach_slave_reply_t_handler_json
1900   (vl_api_bond_detach_slave_reply_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   vat_json_node_t node;
1904
1905   vat_json_init_object (&node);
1906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1907
1908   vat_json_print (vam->ofp, &node);
1909   vat_json_free (&node);
1910
1911   vam->retval = ntohl (mp->retval);
1912   vam->result_ready = 1;
1913 }
1914
1915 static void vl_api_sw_interface_bond_details_t_handler
1916   (vl_api_sw_interface_bond_details_t * mp)
1917 {
1918   vat_main_t *vam = &vat_main;
1919
1920   print (vam->ofp,
1921          "%-16s %-12d %-12U %-13U %-14u %-14u",
1922          mp->interface_name, ntohl (mp->sw_if_index),
1923          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1924          ntohl (mp->active_slaves), ntohl (mp->slaves));
1925 }
1926
1927 static void vl_api_sw_interface_bond_details_t_handler_json
1928   (vl_api_sw_interface_bond_details_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931   vat_json_node_t *node = NULL;
1932
1933   if (VAT_JSON_ARRAY != vam->json_tree.type)
1934     {
1935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1936       vat_json_init_array (&vam->json_tree);
1937     }
1938   node = vat_json_array_add (&vam->json_tree);
1939
1940   vat_json_init_object (node);
1941   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1942   vat_json_object_add_string_copy (node, "interface_name",
1943                                    mp->interface_name);
1944   vat_json_object_add_uint (node, "mode", mp->mode);
1945   vat_json_object_add_uint (node, "load_balance", mp->lb);
1946   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1947   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1948 }
1949
1950 static int
1951 api_sw_interface_bond_dump (vat_main_t * vam)
1952 {
1953   vl_api_sw_interface_bond_dump_t *mp;
1954   vl_api_control_ping_t *mp_ping;
1955   int ret;
1956
1957   print (vam->ofp,
1958          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1959          "interface name", "sw_if_index", "mode", "load balance",
1960          "active slaves", "slaves");
1961
1962   /* Get list of bond interfaces */
1963   M (SW_INTERFACE_BOND_DUMP, mp);
1964   S (mp);
1965
1966   /* Use a control ping for synchronization */
1967   MPING (CONTROL_PING, mp_ping);
1968   S (mp_ping);
1969
1970   W (ret);
1971   return ret;
1972 }
1973
1974 static void vl_api_sw_interface_slave_details_t_handler
1975   (vl_api_sw_interface_slave_details_t * mp)
1976 {
1977   vat_main_t *vam = &vat_main;
1978
1979   print (vam->ofp,
1980          "%-25s %-12d %-12d %d", mp->interface_name,
1981          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1982 }
1983
1984 static void vl_api_sw_interface_slave_details_t_handler_json
1985   (vl_api_sw_interface_slave_details_t * mp)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   vat_json_node_t *node = NULL;
1989
1990   if (VAT_JSON_ARRAY != vam->json_tree.type)
1991     {
1992       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1993       vat_json_init_array (&vam->json_tree);
1994     }
1995   node = vat_json_array_add (&vam->json_tree);
1996
1997   vat_json_init_object (node);
1998   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1999   vat_json_object_add_string_copy (node, "interface_name",
2000                                    mp->interface_name);
2001   vat_json_object_add_uint (node, "passive", mp->is_passive);
2002   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2003 }
2004
2005 static int
2006 api_sw_interface_slave_dump (vat_main_t * vam)
2007 {
2008   unformat_input_t *i = vam->input;
2009   vl_api_sw_interface_slave_dump_t *mp;
2010   vl_api_control_ping_t *mp_ping;
2011   u32 sw_if_index = ~0;
2012   u8 sw_if_index_set = 0;
2013   int ret;
2014
2015   /* Parse args required to build the message */
2016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2017     {
2018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2019         sw_if_index_set = 1;
2020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2021         sw_if_index_set = 1;
2022       else
2023         break;
2024     }
2025
2026   if (sw_if_index_set == 0)
2027     {
2028       errmsg ("missing vpp interface name. ");
2029       return -99;
2030     }
2031
2032   print (vam->ofp,
2033          "\n%-25s %-12s %-12s %s",
2034          "slave interface name", "sw_if_index", "passive", "long_timeout");
2035
2036   /* Get list of bond interfaces */
2037   M (SW_INTERFACE_SLAVE_DUMP, mp);
2038   mp->sw_if_index = ntohl (sw_if_index);
2039   S (mp);
2040
2041   /* Use a control ping for synchronization */
2042   MPING (CONTROL_PING, mp_ping);
2043   S (mp_ping);
2044
2045   W (ret);
2046   return ret;
2047 }
2048
2049 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2050   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2051 {
2052   vat_main_t *vam = &vat_main;
2053   i32 retval = ntohl (mp->retval);
2054   if (vam->async_mode)
2055     {
2056       vam->async_errors += (retval < 0);
2057     }
2058   else
2059     {
2060       vam->retval = retval;
2061       vam->result_ready = 1;
2062     }
2063 }
2064
2065 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2066   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2067 {
2068   vat_main_t *vam = &vat_main;
2069   vat_json_node_t node;
2070
2071   vat_json_init_object (&node);
2072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2074                             ntohl (mp->sw_if_index));
2075
2076   vat_json_print (vam->ofp, &node);
2077   vat_json_free (&node);
2078
2079   vam->retval = ntohl (mp->retval);
2080   vam->result_ready = 1;
2081 }
2082
2083 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2084   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2085 {
2086   vat_main_t *vam = &vat_main;
2087   i32 retval = ntohl (mp->retval);
2088   if (vam->async_mode)
2089     {
2090       vam->async_errors += (retval < 0);
2091     }
2092   else
2093     {
2094       vam->retval = retval;
2095       vam->sw_if_index = ntohl (mp->sw_if_index);
2096       vam->result_ready = 1;
2097     }
2098 }
2099
2100 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2101   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2102 {
2103   vat_main_t *vam = &vat_main;
2104   vat_json_node_t node;
2105
2106   vat_json_init_object (&node);
2107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2108   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2109
2110   vat_json_print (vam->ofp, &node);
2111   vat_json_free (&node);
2112
2113   vam->retval = ntohl (mp->retval);
2114   vam->result_ready = 1;
2115 }
2116
2117 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2118   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2119 {
2120   vat_main_t *vam = &vat_main;
2121   i32 retval = ntohl (mp->retval);
2122   if (vam->async_mode)
2123     {
2124       vam->async_errors += (retval < 0);
2125     }
2126   else
2127     {
2128       vam->retval = retval;
2129       vam->result_ready = 1;
2130     }
2131 }
2132
2133 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2134   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2135 {
2136   vat_main_t *vam = &vat_main;
2137   vat_json_node_t node;
2138
2139   vat_json_init_object (&node);
2140   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2141   vat_json_object_add_uint (&node, "fwd_entry_index",
2142                             clib_net_to_host_u32 (mp->fwd_entry_index));
2143
2144   vat_json_print (vam->ofp, &node);
2145   vat_json_free (&node);
2146
2147   vam->retval = ntohl (mp->retval);
2148   vam->result_ready = 1;
2149 }
2150
2151 u8 *
2152 format_lisp_transport_protocol (u8 * s, va_list * args)
2153 {
2154   u32 proto = va_arg (*args, u32);
2155
2156   switch (proto)
2157     {
2158     case 1:
2159       return format (s, "udp");
2160     case 2:
2161       return format (s, "api");
2162     default:
2163       return 0;
2164     }
2165   return 0;
2166 }
2167
2168 static void vl_api_one_get_transport_protocol_reply_t_handler
2169   (vl_api_one_get_transport_protocol_reply_t * mp)
2170 {
2171   vat_main_t *vam = &vat_main;
2172   i32 retval = ntohl (mp->retval);
2173   if (vam->async_mode)
2174     {
2175       vam->async_errors += (retval < 0);
2176     }
2177   else
2178     {
2179       u32 proto = mp->protocol;
2180       print (vam->ofp, "Transport protocol: %U",
2181              format_lisp_transport_protocol, proto);
2182       vam->retval = retval;
2183       vam->result_ready = 1;
2184     }
2185 }
2186
2187 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2188   (vl_api_one_get_transport_protocol_reply_t * mp)
2189 {
2190   vat_main_t *vam = &vat_main;
2191   vat_json_node_t node;
2192   u8 *s;
2193
2194   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2195   vec_add1 (s, 0);
2196
2197   vat_json_init_object (&node);
2198   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2199   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2200
2201   vec_free (s);
2202   vat_json_print (vam->ofp, &node);
2203   vat_json_free (&node);
2204
2205   vam->retval = ntohl (mp->retval);
2206   vam->result_ready = 1;
2207 }
2208
2209 static void vl_api_one_add_del_locator_set_reply_t_handler
2210   (vl_api_one_add_del_locator_set_reply_t * mp)
2211 {
2212   vat_main_t *vam = &vat_main;
2213   i32 retval = ntohl (mp->retval);
2214   if (vam->async_mode)
2215     {
2216       vam->async_errors += (retval < 0);
2217     }
2218   else
2219     {
2220       vam->retval = retval;
2221       vam->result_ready = 1;
2222     }
2223 }
2224
2225 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2226   (vl_api_one_add_del_locator_set_reply_t * mp)
2227 {
2228   vat_main_t *vam = &vat_main;
2229   vat_json_node_t node;
2230
2231   vat_json_init_object (&node);
2232   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2233   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2234
2235   vat_json_print (vam->ofp, &node);
2236   vat_json_free (&node);
2237
2238   vam->retval = ntohl (mp->retval);
2239   vam->result_ready = 1;
2240 }
2241
2242 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2243   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2244 {
2245   vat_main_t *vam = &vat_main;
2246   i32 retval = ntohl (mp->retval);
2247   if (vam->async_mode)
2248     {
2249       vam->async_errors += (retval < 0);
2250     }
2251   else
2252     {
2253       vam->retval = retval;
2254       vam->sw_if_index = ntohl (mp->sw_if_index);
2255       vam->result_ready = 1;
2256     }
2257   vam->regenerate_interface_table = 1;
2258 }
2259
2260 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2261   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2262 {
2263   vat_main_t *vam = &vat_main;
2264   vat_json_node_t node;
2265
2266   vat_json_init_object (&node);
2267   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2268   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2269
2270   vat_json_print (vam->ofp, &node);
2271   vat_json_free (&node);
2272
2273   vam->retval = ntohl (mp->retval);
2274   vam->result_ready = 1;
2275 }
2276
2277 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2278   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2279 {
2280   vat_main_t *vam = &vat_main;
2281   i32 retval = ntohl (mp->retval);
2282   if (vam->async_mode)
2283     {
2284       vam->async_errors += (retval < 0);
2285     }
2286   else
2287     {
2288       vam->retval = retval;
2289       vam->sw_if_index = ntohl (mp->sw_if_index);
2290       vam->result_ready = 1;
2291     }
2292 }
2293
2294 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2295   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2296 {
2297   vat_main_t *vam = &vat_main;
2298   vat_json_node_t node;
2299
2300   vat_json_init_object (&node);
2301   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2302   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2303
2304   vat_json_print (vam->ofp, &node);
2305   vat_json_free (&node);
2306
2307   vam->retval = ntohl (mp->retval);
2308   vam->result_ready = 1;
2309 }
2310
2311 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2312   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2313 {
2314   vat_main_t *vam = &vat_main;
2315   i32 retval = ntohl (mp->retval);
2316   if (vam->async_mode)
2317     {
2318       vam->async_errors += (retval < 0);
2319     }
2320   else
2321     {
2322       vam->retval = retval;
2323       vam->sw_if_index = ntohl (mp->sw_if_index);
2324       vam->result_ready = 1;
2325     }
2326   vam->regenerate_interface_table = 1;
2327 }
2328
2329 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2330   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   vat_json_node_t node;
2334
2335   vat_json_init_object (&node);
2336   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2337   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2338
2339   vat_json_print (vam->ofp, &node);
2340   vat_json_free (&node);
2341
2342   vam->retval = ntohl (mp->retval);
2343   vam->result_ready = 1;
2344 }
2345
2346 static void vl_api_gre_add_del_tunnel_reply_t_handler
2347   (vl_api_gre_add_del_tunnel_reply_t * mp)
2348 {
2349   vat_main_t *vam = &vat_main;
2350   i32 retval = ntohl (mp->retval);
2351   if (vam->async_mode)
2352     {
2353       vam->async_errors += (retval < 0);
2354     }
2355   else
2356     {
2357       vam->retval = retval;
2358       vam->sw_if_index = ntohl (mp->sw_if_index);
2359       vam->result_ready = 1;
2360     }
2361 }
2362
2363 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2364   (vl_api_gre_add_del_tunnel_reply_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   vat_json_node_t node;
2368
2369   vat_json_init_object (&node);
2370   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2371   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2372
2373   vat_json_print (vam->ofp, &node);
2374   vat_json_free (&node);
2375
2376   vam->retval = ntohl (mp->retval);
2377   vam->result_ready = 1;
2378 }
2379
2380 static void vl_api_create_vhost_user_if_reply_t_handler
2381   (vl_api_create_vhost_user_if_reply_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   i32 retval = ntohl (mp->retval);
2385   if (vam->async_mode)
2386     {
2387       vam->async_errors += (retval < 0);
2388     }
2389   else
2390     {
2391       vam->retval = retval;
2392       vam->sw_if_index = ntohl (mp->sw_if_index);
2393       vam->result_ready = 1;
2394     }
2395   vam->regenerate_interface_table = 1;
2396 }
2397
2398 static void vl_api_create_vhost_user_if_reply_t_handler_json
2399   (vl_api_create_vhost_user_if_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   vat_json_node_t node;
2403
2404   vat_json_init_object (&node);
2405   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2406   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2407
2408   vat_json_print (vam->ofp, &node);
2409   vat_json_free (&node);
2410
2411   vam->retval = ntohl (mp->retval);
2412   vam->result_ready = 1;
2413 }
2414
2415 static void vl_api_dns_resolve_name_reply_t_handler
2416   (vl_api_dns_resolve_name_reply_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419   i32 retval = ntohl (mp->retval);
2420   if (vam->async_mode)
2421     {
2422       vam->async_errors += (retval < 0);
2423     }
2424   else
2425     {
2426       vam->retval = retval;
2427       vam->result_ready = 1;
2428
2429       if (retval == 0)
2430         {
2431           if (mp->ip4_set)
2432             clib_warning ("ip4 address %U", format_ip4_address,
2433                           (ip4_address_t *) mp->ip4_address);
2434           if (mp->ip6_set)
2435             clib_warning ("ip6 address %U", format_ip6_address,
2436                           (ip6_address_t *) mp->ip6_address);
2437         }
2438       else
2439         clib_warning ("retval %d", retval);
2440     }
2441 }
2442
2443 static void vl_api_dns_resolve_name_reply_t_handler_json
2444   (vl_api_dns_resolve_name_reply_t * mp)
2445 {
2446   clib_warning ("not implemented");
2447 }
2448
2449 static void vl_api_dns_resolve_ip_reply_t_handler
2450   (vl_api_dns_resolve_ip_reply_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   i32 retval = ntohl (mp->retval);
2454   if (vam->async_mode)
2455     {
2456       vam->async_errors += (retval < 0);
2457     }
2458   else
2459     {
2460       vam->retval = retval;
2461       vam->result_ready = 1;
2462
2463       if (retval == 0)
2464         {
2465           clib_warning ("canonical name %s", mp->name);
2466         }
2467       else
2468         clib_warning ("retval %d", retval);
2469     }
2470 }
2471
2472 static void vl_api_dns_resolve_ip_reply_t_handler_json
2473   (vl_api_dns_resolve_ip_reply_t * mp)
2474 {
2475   clib_warning ("not implemented");
2476 }
2477
2478
2479 static void vl_api_ip_address_details_t_handler
2480   (vl_api_ip_address_details_t * mp)
2481 {
2482   vat_main_t *vam = &vat_main;
2483   static ip_address_details_t empty_ip_address_details = { {0} };
2484   ip_address_details_t *address = NULL;
2485   ip_details_t *current_ip_details = NULL;
2486   ip_details_t *details = NULL;
2487
2488   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2489
2490   if (!details || vam->current_sw_if_index >= vec_len (details)
2491       || !details[vam->current_sw_if_index].present)
2492     {
2493       errmsg ("ip address details arrived but not stored");
2494       errmsg ("ip_dump should be called first");
2495       return;
2496     }
2497
2498   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2499
2500 #define addresses (current_ip_details->addr)
2501
2502   vec_validate_init_empty (addresses, vec_len (addresses),
2503                            empty_ip_address_details);
2504
2505   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2506
2507   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2508   address->prefix_length = mp->prefix_length;
2509 #undef addresses
2510 }
2511
2512 static void vl_api_ip_address_details_t_handler_json
2513   (vl_api_ip_address_details_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   vat_json_node_t *node = NULL;
2517   struct in6_addr ip6;
2518   struct in_addr ip4;
2519
2520   if (VAT_JSON_ARRAY != vam->json_tree.type)
2521     {
2522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2523       vat_json_init_array (&vam->json_tree);
2524     }
2525   node = vat_json_array_add (&vam->json_tree);
2526
2527   vat_json_init_object (node);
2528   if (vam->is_ipv6)
2529     {
2530       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2531       vat_json_object_add_ip6 (node, "ip", ip6);
2532     }
2533   else
2534     {
2535       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2536       vat_json_object_add_ip4 (node, "ip", ip4);
2537     }
2538   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2539 }
2540
2541 static void
2542 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2543 {
2544   vat_main_t *vam = &vat_main;
2545   static ip_details_t empty_ip_details = { 0 };
2546   ip_details_t *ip = NULL;
2547   u32 sw_if_index = ~0;
2548
2549   sw_if_index = ntohl (mp->sw_if_index);
2550
2551   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2552                            sw_if_index, empty_ip_details);
2553
2554   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2555                          sw_if_index);
2556
2557   ip->present = 1;
2558 }
2559
2560 static void
2561 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2562 {
2563   vat_main_t *vam = &vat_main;
2564
2565   if (VAT_JSON_ARRAY != vam->json_tree.type)
2566     {
2567       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2568       vat_json_init_array (&vam->json_tree);
2569     }
2570   vat_json_array_add_uint (&vam->json_tree,
2571                            clib_net_to_host_u32 (mp->sw_if_index));
2572 }
2573
2574 static void vl_api_map_domain_details_t_handler_json
2575   (vl_api_map_domain_details_t * mp)
2576 {
2577   vat_json_node_t *node = NULL;
2578   vat_main_t *vam = &vat_main;
2579   struct in6_addr ip6;
2580   struct in_addr ip4;
2581
2582   if (VAT_JSON_ARRAY != vam->json_tree.type)
2583     {
2584       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2585       vat_json_init_array (&vam->json_tree);
2586     }
2587
2588   node = vat_json_array_add (&vam->json_tree);
2589   vat_json_init_object (node);
2590
2591   vat_json_object_add_uint (node, "domain_index",
2592                             clib_net_to_host_u32 (mp->domain_index));
2593   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2594   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2595   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2596   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2597   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2598   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2599   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2600   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2601   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2602   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2603   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2604   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2605   vat_json_object_add_uint (node, "flags", mp->flags);
2606   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2607   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2608 }
2609
2610 static void vl_api_map_domain_details_t_handler
2611   (vl_api_map_domain_details_t * mp)
2612 {
2613   vat_main_t *vam = &vat_main;
2614
2615   if (mp->is_translation)
2616     {
2617       print (vam->ofp,
2618              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2619              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2620              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2621              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2622              clib_net_to_host_u32 (mp->domain_index));
2623     }
2624   else
2625     {
2626       print (vam->ofp,
2627              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2628              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2629              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2630              format_ip6_address, mp->ip6_src,
2631              clib_net_to_host_u32 (mp->domain_index));
2632     }
2633   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2634          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2635          mp->is_translation ? "map-t" : "");
2636 }
2637
2638 static void vl_api_map_rule_details_t_handler_json
2639   (vl_api_map_rule_details_t * mp)
2640 {
2641   struct in6_addr ip6;
2642   vat_json_node_t *node = NULL;
2643   vat_main_t *vam = &vat_main;
2644
2645   if (VAT_JSON_ARRAY != vam->json_tree.type)
2646     {
2647       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2648       vat_json_init_array (&vam->json_tree);
2649     }
2650
2651   node = vat_json_array_add (&vam->json_tree);
2652   vat_json_init_object (node);
2653
2654   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2655   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2656   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2657 }
2658
2659 static void
2660 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2661 {
2662   vat_main_t *vam = &vat_main;
2663   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2664          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2665 }
2666
2667 static void
2668 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2669 {
2670   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2671           "router_addr %U host_mac %U",
2672           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2673           format_ip4_address, &mp->host_address,
2674           format_ip4_address, &mp->router_address,
2675           format_ethernet_address, mp->host_mac);
2676 }
2677
2678 static void vl_api_dhcp_compl_event_t_handler_json
2679   (vl_api_dhcp_compl_event_t * mp)
2680 {
2681   /* JSON output not supported */
2682 }
2683
2684 static void
2685 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2686                               u32 counter)
2687 {
2688   vat_main_t *vam = &vat_main;
2689   static u64 default_counter = 0;
2690
2691   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2692                            NULL);
2693   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2694                            sw_if_index, default_counter);
2695   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2696 }
2697
2698 static void
2699 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2700                                 interface_counter_t counter)
2701 {
2702   vat_main_t *vam = &vat_main;
2703   static interface_counter_t default_counter = { 0, };
2704
2705   vec_validate_init_empty (vam->combined_interface_counters,
2706                            vnet_counter_type, NULL);
2707   vec_validate_init_empty (vam->combined_interface_counters
2708                            [vnet_counter_type], sw_if_index, default_counter);
2709   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2710 }
2711
2712 static void vl_api_vnet_interface_simple_counters_t_handler
2713   (vl_api_vnet_interface_simple_counters_t * mp)
2714 {
2715   /* not supported */
2716 }
2717
2718 static void vl_api_vnet_interface_combined_counters_t_handler
2719   (vl_api_vnet_interface_combined_counters_t * mp)
2720 {
2721   /* not supported */
2722 }
2723
2724 static void vl_api_vnet_interface_simple_counters_t_handler_json
2725   (vl_api_vnet_interface_simple_counters_t * mp)
2726 {
2727   u64 *v_packets;
2728   u64 packets;
2729   u32 count;
2730   u32 first_sw_if_index;
2731   int i;
2732
2733   count = ntohl (mp->count);
2734   first_sw_if_index = ntohl (mp->first_sw_if_index);
2735
2736   v_packets = (u64 *) & mp->data;
2737   for (i = 0; i < count; i++)
2738     {
2739       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2740       set_simple_interface_counter (mp->vnet_counter_type,
2741                                     first_sw_if_index + i, packets);
2742       v_packets++;
2743     }
2744 }
2745
2746 static void vl_api_vnet_interface_combined_counters_t_handler_json
2747   (vl_api_vnet_interface_combined_counters_t * mp)
2748 {
2749   interface_counter_t counter;
2750   vlib_counter_t *v;
2751   u32 first_sw_if_index;
2752   int i;
2753   u32 count;
2754
2755   count = ntohl (mp->count);
2756   first_sw_if_index = ntohl (mp->first_sw_if_index);
2757
2758   v = (vlib_counter_t *) & mp->data;
2759   for (i = 0; i < count; i++)
2760     {
2761       counter.packets =
2762         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2763       counter.bytes =
2764         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2765       set_combined_interface_counter (mp->vnet_counter_type,
2766                                       first_sw_if_index + i, counter);
2767       v++;
2768     }
2769 }
2770
2771 static u32
2772 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2773 {
2774   vat_main_t *vam = &vat_main;
2775   u32 i;
2776
2777   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2778     {
2779       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2780         {
2781           return i;
2782         }
2783     }
2784   return ~0;
2785 }
2786
2787 static u32
2788 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   u32 i;
2792
2793   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2794     {
2795       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2796         {
2797           return i;
2798         }
2799     }
2800   return ~0;
2801 }
2802
2803 static void vl_api_vnet_ip4_fib_counters_t_handler
2804   (vl_api_vnet_ip4_fib_counters_t * mp)
2805 {
2806   /* not supported */
2807 }
2808
2809 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2810   (vl_api_vnet_ip4_fib_counters_t * mp)
2811 {
2812   vat_main_t *vam = &vat_main;
2813   vl_api_ip4_fib_counter_t *v;
2814   ip4_fib_counter_t *counter;
2815   struct in_addr ip4;
2816   u32 vrf_id;
2817   u32 vrf_index;
2818   u32 count;
2819   int i;
2820
2821   vrf_id = ntohl (mp->vrf_id);
2822   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2823   if (~0 == vrf_index)
2824     {
2825       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2826       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2827       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2828       vec_validate (vam->ip4_fib_counters, vrf_index);
2829       vam->ip4_fib_counters[vrf_index] = NULL;
2830     }
2831
2832   vec_free (vam->ip4_fib_counters[vrf_index]);
2833   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2834   count = ntohl (mp->count);
2835   for (i = 0; i < count; i++)
2836     {
2837       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2838       counter = &vam->ip4_fib_counters[vrf_index][i];
2839       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2840       counter->address = ip4;
2841       counter->address_length = v->address_length;
2842       counter->packets = clib_net_to_host_u64 (v->packets);
2843       counter->bytes = clib_net_to_host_u64 (v->bytes);
2844       v++;
2845     }
2846 }
2847
2848 static void vl_api_vnet_ip4_nbr_counters_t_handler
2849   (vl_api_vnet_ip4_nbr_counters_t * mp)
2850 {
2851   /* not supported */
2852 }
2853
2854 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2855   (vl_api_vnet_ip4_nbr_counters_t * mp)
2856 {
2857   vat_main_t *vam = &vat_main;
2858   vl_api_ip4_nbr_counter_t *v;
2859   ip4_nbr_counter_t *counter;
2860   u32 sw_if_index;
2861   u32 count;
2862   int i;
2863
2864   sw_if_index = ntohl (mp->sw_if_index);
2865   count = ntohl (mp->count);
2866   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2867
2868   if (mp->begin)
2869     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2870
2871   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2872   for (i = 0; i < count; i++)
2873     {
2874       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2875       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2876       counter->address.s_addr = v->address;
2877       counter->packets = clib_net_to_host_u64 (v->packets);
2878       counter->bytes = clib_net_to_host_u64 (v->bytes);
2879       counter->linkt = v->link_type;
2880       v++;
2881     }
2882 }
2883
2884 static void vl_api_vnet_ip6_fib_counters_t_handler
2885   (vl_api_vnet_ip6_fib_counters_t * mp)
2886 {
2887   /* not supported */
2888 }
2889
2890 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2891   (vl_api_vnet_ip6_fib_counters_t * mp)
2892 {
2893   vat_main_t *vam = &vat_main;
2894   vl_api_ip6_fib_counter_t *v;
2895   ip6_fib_counter_t *counter;
2896   struct in6_addr ip6;
2897   u32 vrf_id;
2898   u32 vrf_index;
2899   u32 count;
2900   int i;
2901
2902   vrf_id = ntohl (mp->vrf_id);
2903   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2904   if (~0 == vrf_index)
2905     {
2906       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2907       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2908       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2909       vec_validate (vam->ip6_fib_counters, vrf_index);
2910       vam->ip6_fib_counters[vrf_index] = NULL;
2911     }
2912
2913   vec_free (vam->ip6_fib_counters[vrf_index]);
2914   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2915   count = ntohl (mp->count);
2916   for (i = 0; i < count; i++)
2917     {
2918       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2919       counter = &vam->ip6_fib_counters[vrf_index][i];
2920       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2921       counter->address = ip6;
2922       counter->address_length = v->address_length;
2923       counter->packets = clib_net_to_host_u64 (v->packets);
2924       counter->bytes = clib_net_to_host_u64 (v->bytes);
2925       v++;
2926     }
2927 }
2928
2929 static void vl_api_vnet_ip6_nbr_counters_t_handler
2930   (vl_api_vnet_ip6_nbr_counters_t * mp)
2931 {
2932   /* not supported */
2933 }
2934
2935 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2936   (vl_api_vnet_ip6_nbr_counters_t * mp)
2937 {
2938   vat_main_t *vam = &vat_main;
2939   vl_api_ip6_nbr_counter_t *v;
2940   ip6_nbr_counter_t *counter;
2941   struct in6_addr ip6;
2942   u32 sw_if_index;
2943   u32 count;
2944   int i;
2945
2946   sw_if_index = ntohl (mp->sw_if_index);
2947   count = ntohl (mp->count);
2948   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2949
2950   if (mp->begin)
2951     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2952
2953   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2954   for (i = 0; i < count; i++)
2955     {
2956       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2957       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2958       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2959       counter->address = ip6;
2960       counter->packets = clib_net_to_host_u64 (v->packets);
2961       counter->bytes = clib_net_to_host_u64 (v->bytes);
2962       v++;
2963     }
2964 }
2965
2966 static void vl_api_get_first_msg_id_reply_t_handler
2967   (vl_api_get_first_msg_id_reply_t * mp)
2968 {
2969   vat_main_t *vam = &vat_main;
2970   i32 retval = ntohl (mp->retval);
2971
2972   if (vam->async_mode)
2973     {
2974       vam->async_errors += (retval < 0);
2975     }
2976   else
2977     {
2978       vam->retval = retval;
2979       vam->result_ready = 1;
2980     }
2981   if (retval >= 0)
2982     {
2983       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2984     }
2985 }
2986
2987 static void vl_api_get_first_msg_id_reply_t_handler_json
2988   (vl_api_get_first_msg_id_reply_t * mp)
2989 {
2990   vat_main_t *vam = &vat_main;
2991   vat_json_node_t node;
2992
2993   vat_json_init_object (&node);
2994   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2995   vat_json_object_add_uint (&node, "first_msg_id",
2996                             (uint) ntohs (mp->first_msg_id));
2997
2998   vat_json_print (vam->ofp, &node);
2999   vat_json_free (&node);
3000
3001   vam->retval = ntohl (mp->retval);
3002   vam->result_ready = 1;
3003 }
3004
3005 static void vl_api_get_node_graph_reply_t_handler
3006   (vl_api_get_node_graph_reply_t * mp)
3007 {
3008   vat_main_t *vam = &vat_main;
3009   api_main_t *am = &api_main;
3010   i32 retval = ntohl (mp->retval);
3011   u8 *pvt_copy, *reply;
3012   void *oldheap;
3013   vlib_node_t *node;
3014   int i;
3015
3016   if (vam->async_mode)
3017     {
3018       vam->async_errors += (retval < 0);
3019     }
3020   else
3021     {
3022       vam->retval = retval;
3023       vam->result_ready = 1;
3024     }
3025
3026   /* "Should never happen..." */
3027   if (retval != 0)
3028     return;
3029
3030   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3031   pvt_copy = vec_dup (reply);
3032
3033   /* Toss the shared-memory original... */
3034   pthread_mutex_lock (&am->vlib_rp->mutex);
3035   oldheap = svm_push_data_heap (am->vlib_rp);
3036
3037   vec_free (reply);
3038
3039   svm_pop_heap (oldheap);
3040   pthread_mutex_unlock (&am->vlib_rp->mutex);
3041
3042   if (vam->graph_nodes)
3043     {
3044       hash_free (vam->graph_node_index_by_name);
3045
3046       for (i = 0; i < vec_len (vam->graph_nodes); i++)
3047         {
3048           node = vam->graph_nodes[i];
3049           vec_free (node->name);
3050           vec_free (node->next_nodes);
3051           vec_free (node);
3052         }
3053       vec_free (vam->graph_nodes);
3054     }
3055
3056   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3057   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3058   vec_free (pvt_copy);
3059
3060   for (i = 0; i < vec_len (vam->graph_nodes); i++)
3061     {
3062       node = vam->graph_nodes[i];
3063       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3064     }
3065 }
3066
3067 static void vl_api_get_node_graph_reply_t_handler_json
3068   (vl_api_get_node_graph_reply_t * mp)
3069 {
3070   vat_main_t *vam = &vat_main;
3071   api_main_t *am = &api_main;
3072   void *oldheap;
3073   vat_json_node_t node;
3074   u8 *reply;
3075
3076   /* $$$$ make this real? */
3077   vat_json_init_object (&node);
3078   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3079   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3080
3081   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3082
3083   /* Toss the shared-memory original... */
3084   pthread_mutex_lock (&am->vlib_rp->mutex);
3085   oldheap = svm_push_data_heap (am->vlib_rp);
3086
3087   vec_free (reply);
3088
3089   svm_pop_heap (oldheap);
3090   pthread_mutex_unlock (&am->vlib_rp->mutex);
3091
3092   vat_json_print (vam->ofp, &node);
3093   vat_json_free (&node);
3094
3095   vam->retval = ntohl (mp->retval);
3096   vam->result_ready = 1;
3097 }
3098
3099 static void
3100 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3101 {
3102   vat_main_t *vam = &vat_main;
3103   u8 *s = 0;
3104
3105   if (mp->local)
3106     {
3107       s = format (s, "%=16d%=16d%=16d",
3108                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3109     }
3110   else
3111     {
3112       s = format (s, "%=16U%=16d%=16d",
3113                   mp->is_ipv6 ? format_ip6_address :
3114                   format_ip4_address,
3115                   mp->ip_address, mp->priority, mp->weight);
3116     }
3117
3118   print (vam->ofp, "%v", s);
3119   vec_free (s);
3120 }
3121
3122 static void
3123 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3124 {
3125   vat_main_t *vam = &vat_main;
3126   vat_json_node_t *node = NULL;
3127   struct in6_addr ip6;
3128   struct in_addr ip4;
3129
3130   if (VAT_JSON_ARRAY != vam->json_tree.type)
3131     {
3132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3133       vat_json_init_array (&vam->json_tree);
3134     }
3135   node = vat_json_array_add (&vam->json_tree);
3136   vat_json_init_object (node);
3137
3138   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3139   vat_json_object_add_uint (node, "priority", mp->priority);
3140   vat_json_object_add_uint (node, "weight", mp->weight);
3141
3142   if (mp->local)
3143     vat_json_object_add_uint (node, "sw_if_index",
3144                               clib_net_to_host_u32 (mp->sw_if_index));
3145   else
3146     {
3147       if (mp->is_ipv6)
3148         {
3149           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3150           vat_json_object_add_ip6 (node, "address", ip6);
3151         }
3152       else
3153         {
3154           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3155           vat_json_object_add_ip4 (node, "address", ip4);
3156         }
3157     }
3158 }
3159
3160 static void
3161 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3162                                           mp)
3163 {
3164   vat_main_t *vam = &vat_main;
3165   u8 *ls_name = 0;
3166
3167   ls_name = format (0, "%s", mp->ls_name);
3168
3169   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3170          ls_name);
3171   vec_free (ls_name);
3172 }
3173
3174 static void
3175   vl_api_one_locator_set_details_t_handler_json
3176   (vl_api_one_locator_set_details_t * mp)
3177 {
3178   vat_main_t *vam = &vat_main;
3179   vat_json_node_t *node = 0;
3180   u8 *ls_name = 0;
3181
3182   ls_name = format (0, "%s", mp->ls_name);
3183   vec_add1 (ls_name, 0);
3184
3185   if (VAT_JSON_ARRAY != vam->json_tree.type)
3186     {
3187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3188       vat_json_init_array (&vam->json_tree);
3189     }
3190   node = vat_json_array_add (&vam->json_tree);
3191
3192   vat_json_init_object (node);
3193   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3194   vat_json_object_add_uint (node, "ls_index",
3195                             clib_net_to_host_u32 (mp->ls_index));
3196   vec_free (ls_name);
3197 }
3198
3199 typedef struct
3200 {
3201   u32 spi;
3202   u8 si;
3203 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3204
3205 uword
3206 unformat_nsh_address (unformat_input_t * input, va_list * args)
3207 {
3208   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3209   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3210 }
3211
3212 u8 *
3213 format_nsh_address_vat (u8 * s, va_list * args)
3214 {
3215   nsh_t *a = va_arg (*args, nsh_t *);
3216   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3217 }
3218
3219 static u8 *
3220 format_lisp_flat_eid (u8 * s, va_list * args)
3221 {
3222   u32 type = va_arg (*args, u32);
3223   u8 *eid = va_arg (*args, u8 *);
3224   u32 eid_len = va_arg (*args, u32);
3225
3226   switch (type)
3227     {
3228     case 0:
3229       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3230     case 1:
3231       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3232     case 2:
3233       return format (s, "%U", format_ethernet_address, eid);
3234     case 3:
3235       return format (s, "%U", format_nsh_address_vat, eid);
3236     }
3237   return 0;
3238 }
3239
3240 static u8 *
3241 format_lisp_eid_vat (u8 * s, va_list * args)
3242 {
3243   u32 type = va_arg (*args, u32);
3244   u8 *eid = va_arg (*args, u8 *);
3245   u32 eid_len = va_arg (*args, u32);
3246   u8 *seid = va_arg (*args, u8 *);
3247   u32 seid_len = va_arg (*args, u32);
3248   u32 is_src_dst = va_arg (*args, u32);
3249
3250   if (is_src_dst)
3251     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3252
3253   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3254
3255   return s;
3256 }
3257
3258 static void
3259 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3260 {
3261   vat_main_t *vam = &vat_main;
3262   u8 *s = 0, *eid = 0;
3263
3264   if (~0 == mp->locator_set_index)
3265     s = format (0, "action: %d", mp->action);
3266   else
3267     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3268
3269   eid = format (0, "%U", format_lisp_eid_vat,
3270                 mp->eid_type,
3271                 mp->eid,
3272                 mp->eid_prefix_len,
3273                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3274   vec_add1 (eid, 0);
3275
3276   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3277          clib_net_to_host_u32 (mp->vni),
3278          eid,
3279          mp->is_local ? "local" : "remote",
3280          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3281          clib_net_to_host_u16 (mp->key_id), mp->key);
3282
3283   vec_free (s);
3284   vec_free (eid);
3285 }
3286
3287 static void
3288 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3289                                              * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   vat_json_node_t *node = 0;
3293   u8 *eid = 0;
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
3302   vat_json_init_object (node);
3303   if (~0 == mp->locator_set_index)
3304     vat_json_object_add_uint (node, "action", mp->action);
3305   else
3306     vat_json_object_add_uint (node, "locator_set_index",
3307                               clib_net_to_host_u32 (mp->locator_set_index));
3308
3309   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3310   if (mp->eid_type == 3)
3311     {
3312       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3313       vat_json_init_object (nsh_json);
3314       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3315       vat_json_object_add_uint (nsh_json, "spi",
3316                                 clib_net_to_host_u32 (nsh->spi));
3317       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3318     }
3319   else
3320     {
3321       eid = format (0, "%U", format_lisp_eid_vat,
3322                     mp->eid_type,
3323                     mp->eid,
3324                     mp->eid_prefix_len,
3325                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3326       vec_add1 (eid, 0);
3327       vat_json_object_add_string_copy (node, "eid", eid);
3328       vec_free (eid);
3329     }
3330   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3331   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3332   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3333
3334   if (mp->key_id)
3335     {
3336       vat_json_object_add_uint (node, "key_id",
3337                                 clib_net_to_host_u16 (mp->key_id));
3338       vat_json_object_add_string_copy (node, "key", mp->key);
3339     }
3340 }
3341
3342 static void
3343 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3344 {
3345   vat_main_t *vam = &vat_main;
3346   u8 *seid = 0, *deid = 0;
3347   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3348
3349   deid = format (0, "%U", format_lisp_eid_vat,
3350                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3351
3352   seid = format (0, "%U", format_lisp_eid_vat,
3353                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3354
3355   vec_add1 (deid, 0);
3356   vec_add1 (seid, 0);
3357
3358   if (mp->is_ip4)
3359     format_ip_address_fcn = format_ip4_address;
3360   else
3361     format_ip_address_fcn = format_ip6_address;
3362
3363
3364   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3365          clib_net_to_host_u32 (mp->vni),
3366          seid, deid,
3367          format_ip_address_fcn, mp->lloc,
3368          format_ip_address_fcn, mp->rloc,
3369          clib_net_to_host_u32 (mp->pkt_count),
3370          clib_net_to_host_u32 (mp->bytes));
3371
3372   vec_free (deid);
3373   vec_free (seid);
3374 }
3375
3376 static void
3377 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3378 {
3379   struct in6_addr ip6;
3380   struct in_addr ip4;
3381   vat_main_t *vam = &vat_main;
3382   vat_json_node_t *node = 0;
3383   u8 *deid = 0, *seid = 0;
3384
3385   if (VAT_JSON_ARRAY != vam->json_tree.type)
3386     {
3387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3388       vat_json_init_array (&vam->json_tree);
3389     }
3390   node = vat_json_array_add (&vam->json_tree);
3391
3392   vat_json_init_object (node);
3393   deid = format (0, "%U", format_lisp_eid_vat,
3394                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3395
3396   seid = format (0, "%U", format_lisp_eid_vat,
3397                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3398
3399   vec_add1 (deid, 0);
3400   vec_add1 (seid, 0);
3401
3402   vat_json_object_add_string_copy (node, "seid", seid);
3403   vat_json_object_add_string_copy (node, "deid", deid);
3404   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3405
3406   if (mp->is_ip4)
3407     {
3408       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3409       vat_json_object_add_ip4 (node, "lloc", ip4);
3410       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3411       vat_json_object_add_ip4 (node, "rloc", ip4);
3412     }
3413   else
3414     {
3415       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3416       vat_json_object_add_ip6 (node, "lloc", ip6);
3417       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3418       vat_json_object_add_ip6 (node, "rloc", ip6);
3419     }
3420   vat_json_object_add_uint (node, "pkt_count",
3421                             clib_net_to_host_u32 (mp->pkt_count));
3422   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3423
3424   vec_free (deid);
3425   vec_free (seid);
3426 }
3427
3428 static void
3429   vl_api_one_eid_table_map_details_t_handler
3430   (vl_api_one_eid_table_map_details_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   u8 *line = format (0, "%=10d%=10d",
3435                      clib_net_to_host_u32 (mp->vni),
3436                      clib_net_to_host_u32 (mp->dp_table));
3437   print (vam->ofp, "%v", line);
3438   vec_free (line);
3439 }
3440
3441 static void
3442   vl_api_one_eid_table_map_details_t_handler_json
3443   (vl_api_one_eid_table_map_details_t * mp)
3444 {
3445   vat_main_t *vam = &vat_main;
3446   vat_json_node_t *node = NULL;
3447
3448   if (VAT_JSON_ARRAY != vam->json_tree.type)
3449     {
3450       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3451       vat_json_init_array (&vam->json_tree);
3452     }
3453   node = vat_json_array_add (&vam->json_tree);
3454   vat_json_init_object (node);
3455   vat_json_object_add_uint (node, "dp_table",
3456                             clib_net_to_host_u32 (mp->dp_table));
3457   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3458 }
3459
3460 static void
3461   vl_api_one_eid_table_vni_details_t_handler
3462   (vl_api_one_eid_table_vni_details_t * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465
3466   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3467   print (vam->ofp, "%v", line);
3468   vec_free (line);
3469 }
3470
3471 static void
3472   vl_api_one_eid_table_vni_details_t_handler_json
3473   (vl_api_one_eid_table_vni_details_t * mp)
3474 {
3475   vat_main_t *vam = &vat_main;
3476   vat_json_node_t *node = NULL;
3477
3478   if (VAT_JSON_ARRAY != vam->json_tree.type)
3479     {
3480       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3481       vat_json_init_array (&vam->json_tree);
3482     }
3483   node = vat_json_array_add (&vam->json_tree);
3484   vat_json_init_object (node);
3485   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3486 }
3487
3488 static void
3489   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3490   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3491 {
3492   vat_main_t *vam = &vat_main;
3493   int retval = clib_net_to_host_u32 (mp->retval);
3494
3495   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3496   print (vam->ofp, "fallback threshold value: %d", mp->value);
3497
3498   vam->retval = retval;
3499   vam->result_ready = 1;
3500 }
3501
3502 static void
3503   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3504   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3505 {
3506   vat_main_t *vam = &vat_main;
3507   vat_json_node_t _node, *node = &_node;
3508   int retval = clib_net_to_host_u32 (mp->retval);
3509
3510   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3511   vat_json_init_object (node);
3512   vat_json_object_add_uint (node, "value", mp->value);
3513
3514   vat_json_print (vam->ofp, node);
3515   vat_json_free (node);
3516
3517   vam->retval = retval;
3518   vam->result_ready = 1;
3519 }
3520
3521 static void
3522   vl_api_show_one_map_register_state_reply_t_handler
3523   (vl_api_show_one_map_register_state_reply_t * mp)
3524 {
3525   vat_main_t *vam = &vat_main;
3526   int retval = clib_net_to_host_u32 (mp->retval);
3527
3528   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3529
3530   vam->retval = retval;
3531   vam->result_ready = 1;
3532 }
3533
3534 static void
3535   vl_api_show_one_map_register_state_reply_t_handler_json
3536   (vl_api_show_one_map_register_state_reply_t * mp)
3537 {
3538   vat_main_t *vam = &vat_main;
3539   vat_json_node_t _node, *node = &_node;
3540   int retval = clib_net_to_host_u32 (mp->retval);
3541
3542   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3543
3544   vat_json_init_object (node);
3545   vat_json_object_add_string_copy (node, "state", s);
3546
3547   vat_json_print (vam->ofp, node);
3548   vat_json_free (node);
3549
3550   vam->retval = retval;
3551   vam->result_ready = 1;
3552   vec_free (s);
3553 }
3554
3555 static void
3556   vl_api_show_one_rloc_probe_state_reply_t_handler
3557   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3558 {
3559   vat_main_t *vam = &vat_main;
3560   int retval = clib_net_to_host_u32 (mp->retval);
3561
3562   if (retval)
3563     goto end;
3564
3565   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3566 end:
3567   vam->retval = retval;
3568   vam->result_ready = 1;
3569 }
3570
3571 static void
3572   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3573   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3574 {
3575   vat_main_t *vam = &vat_main;
3576   vat_json_node_t _node, *node = &_node;
3577   int retval = clib_net_to_host_u32 (mp->retval);
3578
3579   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3580   vat_json_init_object (node);
3581   vat_json_object_add_string_copy (node, "state", s);
3582
3583   vat_json_print (vam->ofp, node);
3584   vat_json_free (node);
3585
3586   vam->retval = retval;
3587   vam->result_ready = 1;
3588   vec_free (s);
3589 }
3590
3591 static void
3592   vl_api_show_one_stats_enable_disable_reply_t_handler
3593   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   int retval = clib_net_to_host_u32 (mp->retval);
3597
3598   if (retval)
3599     goto end;
3600
3601   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3602 end:
3603   vam->retval = retval;
3604   vam->result_ready = 1;
3605 }
3606
3607 static void
3608   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3609   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3610 {
3611   vat_main_t *vam = &vat_main;
3612   vat_json_node_t _node, *node = &_node;
3613   int retval = clib_net_to_host_u32 (mp->retval);
3614
3615   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3616   vat_json_init_object (node);
3617   vat_json_object_add_string_copy (node, "state", s);
3618
3619   vat_json_print (vam->ofp, node);
3620   vat_json_free (node);
3621
3622   vam->retval = retval;
3623   vam->result_ready = 1;
3624   vec_free (s);
3625 }
3626
3627 static void
3628 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3629 {
3630   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3631   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3632   e->vni = clib_net_to_host_u32 (e->vni);
3633 }
3634
3635 static void
3636   gpe_fwd_entries_get_reply_t_net_to_host
3637   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3638 {
3639   u32 i;
3640
3641   mp->count = clib_net_to_host_u32 (mp->count);
3642   for (i = 0; i < mp->count; i++)
3643     {
3644       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3645     }
3646 }
3647
3648 static u8 *
3649 format_gpe_encap_mode (u8 * s, va_list * args)
3650 {
3651   u32 mode = va_arg (*args, u32);
3652
3653   switch (mode)
3654     {
3655     case 0:
3656       return format (s, "lisp");
3657     case 1:
3658       return format (s, "vxlan");
3659     }
3660   return 0;
3661 }
3662
3663 static void
3664   vl_api_gpe_get_encap_mode_reply_t_handler
3665   (vl_api_gpe_get_encap_mode_reply_t * mp)
3666 {
3667   vat_main_t *vam = &vat_main;
3668
3669   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3670   vam->retval = ntohl (mp->retval);
3671   vam->result_ready = 1;
3672 }
3673
3674 static void
3675   vl_api_gpe_get_encap_mode_reply_t_handler_json
3676   (vl_api_gpe_get_encap_mode_reply_t * mp)
3677 {
3678   vat_main_t *vam = &vat_main;
3679   vat_json_node_t node;
3680
3681   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3682   vec_add1 (encap_mode, 0);
3683
3684   vat_json_init_object (&node);
3685   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3686
3687   vec_free (encap_mode);
3688   vat_json_print (vam->ofp, &node);
3689   vat_json_free (&node);
3690
3691   vam->retval = ntohl (mp->retval);
3692   vam->result_ready = 1;
3693 }
3694
3695 static void
3696   vl_api_gpe_fwd_entry_path_details_t_handler
3697   (vl_api_gpe_fwd_entry_path_details_t * mp)
3698 {
3699   vat_main_t *vam = &vat_main;
3700   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3701
3702   if (mp->lcl_loc.is_ip4)
3703     format_ip_address_fcn = format_ip4_address;
3704   else
3705     format_ip_address_fcn = format_ip6_address;
3706
3707   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3708          format_ip_address_fcn, &mp->lcl_loc,
3709          format_ip_address_fcn, &mp->rmt_loc);
3710 }
3711
3712 static void
3713 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3714 {
3715   struct in6_addr ip6;
3716   struct in_addr ip4;
3717
3718   if (loc->is_ip4)
3719     {
3720       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3721       vat_json_object_add_ip4 (n, "address", ip4);
3722     }
3723   else
3724     {
3725       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3726       vat_json_object_add_ip6 (n, "address", ip6);
3727     }
3728   vat_json_object_add_uint (n, "weight", loc->weight);
3729 }
3730
3731 static void
3732   vl_api_gpe_fwd_entry_path_details_t_handler_json
3733   (vl_api_gpe_fwd_entry_path_details_t * mp)
3734 {
3735   vat_main_t *vam = &vat_main;
3736   vat_json_node_t *node = NULL;
3737   vat_json_node_t *loc_node;
3738
3739   if (VAT_JSON_ARRAY != vam->json_tree.type)
3740     {
3741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3742       vat_json_init_array (&vam->json_tree);
3743     }
3744   node = vat_json_array_add (&vam->json_tree);
3745   vat_json_init_object (node);
3746
3747   loc_node = vat_json_object_add (node, "local_locator");
3748   vat_json_init_object (loc_node);
3749   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3750
3751   loc_node = vat_json_object_add (node, "remote_locator");
3752   vat_json_init_object (loc_node);
3753   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3754 }
3755
3756 static void
3757   vl_api_gpe_fwd_entries_get_reply_t_handler
3758   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3759 {
3760   vat_main_t *vam = &vat_main;
3761   u32 i;
3762   int retval = clib_net_to_host_u32 (mp->retval);
3763   vl_api_gpe_fwd_entry_t *e;
3764
3765   if (retval)
3766     goto end;
3767
3768   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3769
3770   for (i = 0; i < mp->count; i++)
3771     {
3772       e = &mp->entries[i];
3773       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3774              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3775              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3776     }
3777
3778 end:
3779   vam->retval = retval;
3780   vam->result_ready = 1;
3781 }
3782
3783 static void
3784   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3785   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3786 {
3787   u8 *s = 0;
3788   vat_main_t *vam = &vat_main;
3789   vat_json_node_t *e = 0, root;
3790   u32 i;
3791   int retval = clib_net_to_host_u32 (mp->retval);
3792   vl_api_gpe_fwd_entry_t *fwd;
3793
3794   if (retval)
3795     goto end;
3796
3797   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3798   vat_json_init_array (&root);
3799
3800   for (i = 0; i < mp->count; i++)
3801     {
3802       e = vat_json_array_add (&root);
3803       fwd = &mp->entries[i];
3804
3805       vat_json_init_object (e);
3806       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3807       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3808       vat_json_object_add_int (e, "vni", fwd->vni);
3809       vat_json_object_add_int (e, "action", fwd->action);
3810
3811       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3812                   fwd->leid_prefix_len);
3813       vec_add1 (s, 0);
3814       vat_json_object_add_string_copy (e, "leid", s);
3815       vec_free (s);
3816
3817       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3818                   fwd->reid_prefix_len);
3819       vec_add1 (s, 0);
3820       vat_json_object_add_string_copy (e, "reid", s);
3821       vec_free (s);
3822     }
3823
3824   vat_json_print (vam->ofp, &root);
3825   vat_json_free (&root);
3826
3827 end:
3828   vam->retval = retval;
3829   vam->result_ready = 1;
3830 }
3831
3832 static void
3833   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3834   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3835 {
3836   vat_main_t *vam = &vat_main;
3837   u32 i, n;
3838   int retval = clib_net_to_host_u32 (mp->retval);
3839   vl_api_gpe_native_fwd_rpath_t *r;
3840
3841   if (retval)
3842     goto end;
3843
3844   n = clib_net_to_host_u32 (mp->count);
3845
3846   for (i = 0; i < n; i++)
3847     {
3848       r = &mp->entries[i];
3849       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3850              clib_net_to_host_u32 (r->fib_index),
3851              clib_net_to_host_u32 (r->nh_sw_if_index),
3852              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3853     }
3854
3855 end:
3856   vam->retval = retval;
3857   vam->result_ready = 1;
3858 }
3859
3860 static void
3861   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3862   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3863 {
3864   vat_main_t *vam = &vat_main;
3865   vat_json_node_t root, *e;
3866   u32 i, n;
3867   int retval = clib_net_to_host_u32 (mp->retval);
3868   vl_api_gpe_native_fwd_rpath_t *r;
3869   u8 *s;
3870
3871   if (retval)
3872     goto end;
3873
3874   n = clib_net_to_host_u32 (mp->count);
3875   vat_json_init_array (&root);
3876
3877   for (i = 0; i < n; i++)
3878     {
3879       e = vat_json_array_add (&root);
3880       vat_json_init_object (e);
3881       r = &mp->entries[i];
3882       s =
3883         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3884                 r->nh_addr);
3885       vec_add1 (s, 0);
3886       vat_json_object_add_string_copy (e, "ip4", s);
3887       vec_free (s);
3888
3889       vat_json_object_add_uint (e, "fib_index",
3890                                 clib_net_to_host_u32 (r->fib_index));
3891       vat_json_object_add_uint (e, "nh_sw_if_index",
3892                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3893     }
3894
3895   vat_json_print (vam->ofp, &root);
3896   vat_json_free (&root);
3897
3898 end:
3899   vam->retval = retval;
3900   vam->result_ready = 1;
3901 }
3902
3903 static void
3904   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3905   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3906 {
3907   vat_main_t *vam = &vat_main;
3908   u32 i, n;
3909   int retval = clib_net_to_host_u32 (mp->retval);
3910
3911   if (retval)
3912     goto end;
3913
3914   n = clib_net_to_host_u32 (mp->count);
3915
3916   for (i = 0; i < n; i++)
3917     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3918
3919 end:
3920   vam->retval = retval;
3921   vam->result_ready = 1;
3922 }
3923
3924 static void
3925   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3926   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3927 {
3928   vat_main_t *vam = &vat_main;
3929   vat_json_node_t root;
3930   u32 i, n;
3931   int retval = clib_net_to_host_u32 (mp->retval);
3932
3933   if (retval)
3934     goto end;
3935
3936   n = clib_net_to_host_u32 (mp->count);
3937   vat_json_init_array (&root);
3938
3939   for (i = 0; i < n; i++)
3940     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3941
3942   vat_json_print (vam->ofp, &root);
3943   vat_json_free (&root);
3944
3945 end:
3946   vam->retval = retval;
3947   vam->result_ready = 1;
3948 }
3949
3950 static void
3951   vl_api_one_ndp_entries_get_reply_t_handler
3952   (vl_api_one_ndp_entries_get_reply_t * mp)
3953 {
3954   vat_main_t *vam = &vat_main;
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
3963   for (i = 0; i < n; i++)
3964     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3965            format_ethernet_address, mp->entries[i].mac);
3966
3967 end:
3968   vam->retval = retval;
3969   vam->result_ready = 1;
3970 }
3971
3972 static void
3973   vl_api_one_ndp_entries_get_reply_t_handler_json
3974   (vl_api_one_ndp_entries_get_reply_t * mp)
3975 {
3976   u8 *s = 0;
3977   vat_main_t *vam = &vat_main;
3978   vat_json_node_t *e = 0, root;
3979   u32 i, n;
3980   int retval = clib_net_to_host_u32 (mp->retval);
3981   vl_api_one_ndp_entry_t *arp_entry;
3982
3983   if (retval)
3984     goto end;
3985
3986   n = clib_net_to_host_u32 (mp->count);
3987   vat_json_init_array (&root);
3988
3989   for (i = 0; i < n; i++)
3990     {
3991       e = vat_json_array_add (&root);
3992       arp_entry = &mp->entries[i];
3993
3994       vat_json_init_object (e);
3995       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3996       vec_add1 (s, 0);
3997
3998       vat_json_object_add_string_copy (e, "mac", s);
3999       vec_free (s);
4000
4001       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4002       vec_add1 (s, 0);
4003       vat_json_object_add_string_copy (e, "ip6", s);
4004       vec_free (s);
4005     }
4006
4007   vat_json_print (vam->ofp, &root);
4008   vat_json_free (&root);
4009
4010 end:
4011   vam->retval = retval;
4012   vam->result_ready = 1;
4013 }
4014
4015 static void
4016   vl_api_one_l2_arp_entries_get_reply_t_handler
4017   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4018 {
4019   vat_main_t *vam = &vat_main;
4020   u32 i, n;
4021   int retval = clib_net_to_host_u32 (mp->retval);
4022
4023   if (retval)
4024     goto end;
4025
4026   n = clib_net_to_host_u32 (mp->count);
4027
4028   for (i = 0; i < n; i++)
4029     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4030            format_ethernet_address, mp->entries[i].mac);
4031
4032 end:
4033   vam->retval = retval;
4034   vam->result_ready = 1;
4035 }
4036
4037 static void
4038   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4039   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4040 {
4041   u8 *s = 0;
4042   vat_main_t *vam = &vat_main;
4043   vat_json_node_t *e = 0, root;
4044   u32 i, n;
4045   int retval = clib_net_to_host_u32 (mp->retval);
4046   vl_api_one_l2_arp_entry_t *arp_entry;
4047
4048   if (retval)
4049     goto end;
4050
4051   n = clib_net_to_host_u32 (mp->count);
4052   vat_json_init_array (&root);
4053
4054   for (i = 0; i < n; i++)
4055     {
4056       e = vat_json_array_add (&root);
4057       arp_entry = &mp->entries[i];
4058
4059       vat_json_init_object (e);
4060       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4061       vec_add1 (s, 0);
4062
4063       vat_json_object_add_string_copy (e, "mac", s);
4064       vec_free (s);
4065
4066       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4067       vec_add1 (s, 0);
4068       vat_json_object_add_string_copy (e, "ip4", s);
4069       vec_free (s);
4070     }
4071
4072   vat_json_print (vam->ofp, &root);
4073   vat_json_free (&root);
4074
4075 end:
4076   vam->retval = retval;
4077   vam->result_ready = 1;
4078 }
4079
4080 static void
4081 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4082 {
4083   vat_main_t *vam = &vat_main;
4084   u32 i, n;
4085   int retval = clib_net_to_host_u32 (mp->retval);
4086
4087   if (retval)
4088     goto end;
4089
4090   n = clib_net_to_host_u32 (mp->count);
4091
4092   for (i = 0; i < n; i++)
4093     {
4094       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4095     }
4096
4097 end:
4098   vam->retval = retval;
4099   vam->result_ready = 1;
4100 }
4101
4102 static void
4103   vl_api_one_ndp_bd_get_reply_t_handler_json
4104   (vl_api_one_ndp_bd_get_reply_t * mp)
4105 {
4106   vat_main_t *vam = &vat_main;
4107   vat_json_node_t root;
4108   u32 i, n;
4109   int retval = clib_net_to_host_u32 (mp->retval);
4110
4111   if (retval)
4112     goto end;
4113
4114   n = clib_net_to_host_u32 (mp->count);
4115   vat_json_init_array (&root);
4116
4117   for (i = 0; i < n; i++)
4118     {
4119       vat_json_array_add_uint (&root,
4120                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4121     }
4122
4123   vat_json_print (vam->ofp, &root);
4124   vat_json_free (&root);
4125
4126 end:
4127   vam->retval = retval;
4128   vam->result_ready = 1;
4129 }
4130
4131 static void
4132   vl_api_one_l2_arp_bd_get_reply_t_handler
4133   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4134 {
4135   vat_main_t *vam = &vat_main;
4136   u32 i, n;
4137   int retval = clib_net_to_host_u32 (mp->retval);
4138
4139   if (retval)
4140     goto end;
4141
4142   n = clib_net_to_host_u32 (mp->count);
4143
4144   for (i = 0; i < n; i++)
4145     {
4146       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4147     }
4148
4149 end:
4150   vam->retval = retval;
4151   vam->result_ready = 1;
4152 }
4153
4154 static void
4155   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4156   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4157 {
4158   vat_main_t *vam = &vat_main;
4159   vat_json_node_t root;
4160   u32 i, n;
4161   int retval = clib_net_to_host_u32 (mp->retval);
4162
4163   if (retval)
4164     goto end;
4165
4166   n = clib_net_to_host_u32 (mp->count);
4167   vat_json_init_array (&root);
4168
4169   for (i = 0; i < n; i++)
4170     {
4171       vat_json_array_add_uint (&root,
4172                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4173     }
4174
4175   vat_json_print (vam->ofp, &root);
4176   vat_json_free (&root);
4177
4178 end:
4179   vam->retval = retval;
4180   vam->result_ready = 1;
4181 }
4182
4183 static void
4184   vl_api_one_adjacencies_get_reply_t_handler
4185   (vl_api_one_adjacencies_get_reply_t * mp)
4186 {
4187   vat_main_t *vam = &vat_main;
4188   u32 i, n;
4189   int retval = clib_net_to_host_u32 (mp->retval);
4190   vl_api_one_adjacency_t *a;
4191
4192   if (retval)
4193     goto end;
4194
4195   n = clib_net_to_host_u32 (mp->count);
4196
4197   for (i = 0; i < n; i++)
4198     {
4199       a = &mp->adjacencies[i];
4200       print (vam->ofp, "%U %40U",
4201              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4202              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4203     }
4204
4205 end:
4206   vam->retval = retval;
4207   vam->result_ready = 1;
4208 }
4209
4210 static void
4211   vl_api_one_adjacencies_get_reply_t_handler_json
4212   (vl_api_one_adjacencies_get_reply_t * mp)
4213 {
4214   u8 *s = 0;
4215   vat_main_t *vam = &vat_main;
4216   vat_json_node_t *e = 0, root;
4217   u32 i, n;
4218   int retval = clib_net_to_host_u32 (mp->retval);
4219   vl_api_one_adjacency_t *a;
4220
4221   if (retval)
4222     goto end;
4223
4224   n = clib_net_to_host_u32 (mp->count);
4225   vat_json_init_array (&root);
4226
4227   for (i = 0; i < n; i++)
4228     {
4229       e = vat_json_array_add (&root);
4230       a = &mp->adjacencies[i];
4231
4232       vat_json_init_object (e);
4233       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4234                   a->leid_prefix_len);
4235       vec_add1 (s, 0);
4236       vat_json_object_add_string_copy (e, "leid", s);
4237       vec_free (s);
4238
4239       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4240                   a->reid_prefix_len);
4241       vec_add1 (s, 0);
4242       vat_json_object_add_string_copy (e, "reid", s);
4243       vec_free (s);
4244     }
4245
4246   vat_json_print (vam->ofp, &root);
4247   vat_json_free (&root);
4248
4249 end:
4250   vam->retval = retval;
4251   vam->result_ready = 1;
4252 }
4253
4254 static void
4255 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4256 {
4257   vat_main_t *vam = &vat_main;
4258
4259   print (vam->ofp, "%=20U",
4260          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4261          mp->ip_address);
4262 }
4263
4264 static void
4265   vl_api_one_map_server_details_t_handler_json
4266   (vl_api_one_map_server_details_t * mp)
4267 {
4268   vat_main_t *vam = &vat_main;
4269   vat_json_node_t *node = NULL;
4270   struct in6_addr ip6;
4271   struct in_addr ip4;
4272
4273   if (VAT_JSON_ARRAY != vam->json_tree.type)
4274     {
4275       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4276       vat_json_init_array (&vam->json_tree);
4277     }
4278   node = vat_json_array_add (&vam->json_tree);
4279
4280   vat_json_init_object (node);
4281   if (mp->is_ipv6)
4282     {
4283       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4284       vat_json_object_add_ip6 (node, "map-server", ip6);
4285     }
4286   else
4287     {
4288       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4289       vat_json_object_add_ip4 (node, "map-server", ip4);
4290     }
4291 }
4292
4293 static void
4294 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4295                                            * mp)
4296 {
4297   vat_main_t *vam = &vat_main;
4298
4299   print (vam->ofp, "%=20U",
4300          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4301          mp->ip_address);
4302 }
4303
4304 static void
4305   vl_api_one_map_resolver_details_t_handler_json
4306   (vl_api_one_map_resolver_details_t * mp)
4307 {
4308   vat_main_t *vam = &vat_main;
4309   vat_json_node_t *node = NULL;
4310   struct in6_addr ip6;
4311   struct in_addr ip4;
4312
4313   if (VAT_JSON_ARRAY != vam->json_tree.type)
4314     {
4315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4316       vat_json_init_array (&vam->json_tree);
4317     }
4318   node = vat_json_array_add (&vam->json_tree);
4319
4320   vat_json_init_object (node);
4321   if (mp->is_ipv6)
4322     {
4323       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4324       vat_json_object_add_ip6 (node, "map resolver", ip6);
4325     }
4326   else
4327     {
4328       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4329       vat_json_object_add_ip4 (node, "map resolver", ip4);
4330     }
4331 }
4332
4333 static void
4334 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4335 {
4336   vat_main_t *vam = &vat_main;
4337   i32 retval = ntohl (mp->retval);
4338
4339   if (0 <= retval)
4340     {
4341       print (vam->ofp, "feature: %s\ngpe: %s",
4342              mp->feature_status ? "enabled" : "disabled",
4343              mp->gpe_status ? "enabled" : "disabled");
4344     }
4345
4346   vam->retval = retval;
4347   vam->result_ready = 1;
4348 }
4349
4350 static void
4351   vl_api_show_one_status_reply_t_handler_json
4352   (vl_api_show_one_status_reply_t * mp)
4353 {
4354   vat_main_t *vam = &vat_main;
4355   vat_json_node_t node;
4356   u8 *gpe_status = NULL;
4357   u8 *feature_status = NULL;
4358
4359   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4360   feature_status = format (0, "%s",
4361                            mp->feature_status ? "enabled" : "disabled");
4362   vec_add1 (gpe_status, 0);
4363   vec_add1 (feature_status, 0);
4364
4365   vat_json_init_object (&node);
4366   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4367   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4368
4369   vec_free (gpe_status);
4370   vec_free (feature_status);
4371
4372   vat_json_print (vam->ofp, &node);
4373   vat_json_free (&node);
4374
4375   vam->retval = ntohl (mp->retval);
4376   vam->result_ready = 1;
4377 }
4378
4379 static void
4380   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4381   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4382 {
4383   vat_main_t *vam = &vat_main;
4384   i32 retval = ntohl (mp->retval);
4385
4386   if (retval >= 0)
4387     {
4388       print (vam->ofp, "%=20s", mp->locator_set_name);
4389     }
4390
4391   vam->retval = retval;
4392   vam->result_ready = 1;
4393 }
4394
4395 static void
4396   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4397   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4398 {
4399   vat_main_t *vam = &vat_main;
4400   vat_json_node_t *node = NULL;
4401
4402   if (VAT_JSON_ARRAY != vam->json_tree.type)
4403     {
4404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4405       vat_json_init_array (&vam->json_tree);
4406     }
4407   node = vat_json_array_add (&vam->json_tree);
4408
4409   vat_json_init_object (node);
4410   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4411
4412   vat_json_print (vam->ofp, node);
4413   vat_json_free (node);
4414
4415   vam->retval = ntohl (mp->retval);
4416   vam->result_ready = 1;
4417 }
4418
4419 static u8 *
4420 format_lisp_map_request_mode (u8 * s, va_list * args)
4421 {
4422   u32 mode = va_arg (*args, u32);
4423
4424   switch (mode)
4425     {
4426     case 0:
4427       return format (0, "dst-only");
4428     case 1:
4429       return format (0, "src-dst");
4430     }
4431   return 0;
4432 }
4433
4434 static void
4435   vl_api_show_one_map_request_mode_reply_t_handler
4436   (vl_api_show_one_map_request_mode_reply_t * mp)
4437 {
4438   vat_main_t *vam = &vat_main;
4439   i32 retval = ntohl (mp->retval);
4440
4441   if (0 <= retval)
4442     {
4443       u32 mode = mp->mode;
4444       print (vam->ofp, "map_request_mode: %U",
4445              format_lisp_map_request_mode, mode);
4446     }
4447
4448   vam->retval = retval;
4449   vam->result_ready = 1;
4450 }
4451
4452 static void
4453   vl_api_show_one_map_request_mode_reply_t_handler_json
4454   (vl_api_show_one_map_request_mode_reply_t * mp)
4455 {
4456   vat_main_t *vam = &vat_main;
4457   vat_json_node_t node;
4458   u8 *s = 0;
4459   u32 mode;
4460
4461   mode = mp->mode;
4462   s = format (0, "%U", format_lisp_map_request_mode, mode);
4463   vec_add1 (s, 0);
4464
4465   vat_json_init_object (&node);
4466   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4467   vat_json_print (vam->ofp, &node);
4468   vat_json_free (&node);
4469
4470   vec_free (s);
4471   vam->retval = ntohl (mp->retval);
4472   vam->result_ready = 1;
4473 }
4474
4475 static void
4476   vl_api_one_show_xtr_mode_reply_t_handler
4477   (vl_api_one_show_xtr_mode_reply_t * mp)
4478 {
4479   vat_main_t *vam = &vat_main;
4480   i32 retval = ntohl (mp->retval);
4481
4482   if (0 <= retval)
4483     {
4484       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4485     }
4486
4487   vam->retval = retval;
4488   vam->result_ready = 1;
4489 }
4490
4491 static void
4492   vl_api_one_show_xtr_mode_reply_t_handler_json
4493   (vl_api_one_show_xtr_mode_reply_t * mp)
4494 {
4495   vat_main_t *vam = &vat_main;
4496   vat_json_node_t node;
4497   u8 *status = 0;
4498
4499   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4500   vec_add1 (status, 0);
4501
4502   vat_json_init_object (&node);
4503   vat_json_object_add_string_copy (&node, "status", status);
4504
4505   vec_free (status);
4506
4507   vat_json_print (vam->ofp, &node);
4508   vat_json_free (&node);
4509
4510   vam->retval = ntohl (mp->retval);
4511   vam->result_ready = 1;
4512 }
4513
4514 static void
4515   vl_api_one_show_pitr_mode_reply_t_handler
4516   (vl_api_one_show_pitr_mode_reply_t * mp)
4517 {
4518   vat_main_t *vam = &vat_main;
4519   i32 retval = ntohl (mp->retval);
4520
4521   if (0 <= retval)
4522     {
4523       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4524     }
4525
4526   vam->retval = retval;
4527   vam->result_ready = 1;
4528 }
4529
4530 static void
4531   vl_api_one_show_pitr_mode_reply_t_handler_json
4532   (vl_api_one_show_pitr_mode_reply_t * mp)
4533 {
4534   vat_main_t *vam = &vat_main;
4535   vat_json_node_t node;
4536   u8 *status = 0;
4537
4538   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4539   vec_add1 (status, 0);
4540
4541   vat_json_init_object (&node);
4542   vat_json_object_add_string_copy (&node, "status", status);
4543
4544   vec_free (status);
4545
4546   vat_json_print (vam->ofp, &node);
4547   vat_json_free (&node);
4548
4549   vam->retval = ntohl (mp->retval);
4550   vam->result_ready = 1;
4551 }
4552
4553 static void
4554   vl_api_one_show_petr_mode_reply_t_handler
4555   (vl_api_one_show_petr_mode_reply_t * mp)
4556 {
4557   vat_main_t *vam = &vat_main;
4558   i32 retval = ntohl (mp->retval);
4559
4560   if (0 <= retval)
4561     {
4562       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4563     }
4564
4565   vam->retval = retval;
4566   vam->result_ready = 1;
4567 }
4568
4569 static void
4570   vl_api_one_show_petr_mode_reply_t_handler_json
4571   (vl_api_one_show_petr_mode_reply_t * mp)
4572 {
4573   vat_main_t *vam = &vat_main;
4574   vat_json_node_t node;
4575   u8 *status = 0;
4576
4577   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4578   vec_add1 (status, 0);
4579
4580   vat_json_init_object (&node);
4581   vat_json_object_add_string_copy (&node, "status", status);
4582
4583   vec_free (status);
4584
4585   vat_json_print (vam->ofp, &node);
4586   vat_json_free (&node);
4587
4588   vam->retval = ntohl (mp->retval);
4589   vam->result_ready = 1;
4590 }
4591
4592 static void
4593   vl_api_show_one_use_petr_reply_t_handler
4594   (vl_api_show_one_use_petr_reply_t * mp)
4595 {
4596   vat_main_t *vam = &vat_main;
4597   i32 retval = ntohl (mp->retval);
4598
4599   if (0 <= retval)
4600     {
4601       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4602       if (mp->status)
4603         {
4604           print (vam->ofp, "Proxy-ETR address; %U",
4605                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4606                  mp->address);
4607         }
4608     }
4609
4610   vam->retval = retval;
4611   vam->result_ready = 1;
4612 }
4613
4614 static void
4615   vl_api_show_one_use_petr_reply_t_handler_json
4616   (vl_api_show_one_use_petr_reply_t * mp)
4617 {
4618   vat_main_t *vam = &vat_main;
4619   vat_json_node_t node;
4620   u8 *status = 0;
4621   struct in_addr ip4;
4622   struct in6_addr ip6;
4623
4624   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4625   vec_add1 (status, 0);
4626
4627   vat_json_init_object (&node);
4628   vat_json_object_add_string_copy (&node, "status", status);
4629   if (mp->status)
4630     {
4631       if (mp->is_ip4)
4632         {
4633           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4634           vat_json_object_add_ip6 (&node, "address", ip6);
4635         }
4636       else
4637         {
4638           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4639           vat_json_object_add_ip4 (&node, "address", ip4);
4640         }
4641     }
4642
4643   vec_free (status);
4644
4645   vat_json_print (vam->ofp, &node);
4646   vat_json_free (&node);
4647
4648   vam->retval = ntohl (mp->retval);
4649   vam->result_ready = 1;
4650 }
4651
4652 static void
4653   vl_api_show_one_nsh_mapping_reply_t_handler
4654   (vl_api_show_one_nsh_mapping_reply_t * mp)
4655 {
4656   vat_main_t *vam = &vat_main;
4657   i32 retval = ntohl (mp->retval);
4658
4659   if (0 <= retval)
4660     {
4661       print (vam->ofp, "%-20s%-16s",
4662              mp->is_set ? "set" : "not-set",
4663              mp->is_set ? (char *) mp->locator_set_name : "");
4664     }
4665
4666   vam->retval = retval;
4667   vam->result_ready = 1;
4668 }
4669
4670 static void
4671   vl_api_show_one_nsh_mapping_reply_t_handler_json
4672   (vl_api_show_one_nsh_mapping_reply_t * mp)
4673 {
4674   vat_main_t *vam = &vat_main;
4675   vat_json_node_t node;
4676   u8 *status = 0;
4677
4678   status = format (0, "%s", mp->is_set ? "yes" : "no");
4679   vec_add1 (status, 0);
4680
4681   vat_json_init_object (&node);
4682   vat_json_object_add_string_copy (&node, "is_set", status);
4683   if (mp->is_set)
4684     {
4685       vat_json_object_add_string_copy (&node, "locator_set",
4686                                        mp->locator_set_name);
4687     }
4688
4689   vec_free (status);
4690
4691   vat_json_print (vam->ofp, &node);
4692   vat_json_free (&node);
4693
4694   vam->retval = ntohl (mp->retval);
4695   vam->result_ready = 1;
4696 }
4697
4698 static void
4699   vl_api_show_one_map_register_ttl_reply_t_handler
4700   (vl_api_show_one_map_register_ttl_reply_t * mp)
4701 {
4702   vat_main_t *vam = &vat_main;
4703   i32 retval = ntohl (mp->retval);
4704
4705   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4706
4707   if (0 <= retval)
4708     {
4709       print (vam->ofp, "ttl: %u", mp->ttl);
4710     }
4711
4712   vam->retval = retval;
4713   vam->result_ready = 1;
4714 }
4715
4716 static void
4717   vl_api_show_one_map_register_ttl_reply_t_handler_json
4718   (vl_api_show_one_map_register_ttl_reply_t * mp)
4719 {
4720   vat_main_t *vam = &vat_main;
4721   vat_json_node_t node;
4722
4723   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4724   vat_json_init_object (&node);
4725   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4726
4727   vat_json_print (vam->ofp, &node);
4728   vat_json_free (&node);
4729
4730   vam->retval = ntohl (mp->retval);
4731   vam->result_ready = 1;
4732 }
4733
4734 static void
4735 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4736 {
4737   vat_main_t *vam = &vat_main;
4738   i32 retval = ntohl (mp->retval);
4739
4740   if (0 <= retval)
4741     {
4742       print (vam->ofp, "%-20s%-16s",
4743              mp->status ? "enabled" : "disabled",
4744              mp->status ? (char *) mp->locator_set_name : "");
4745     }
4746
4747   vam->retval = retval;
4748   vam->result_ready = 1;
4749 }
4750
4751 static void
4752 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4753 {
4754   vat_main_t *vam = &vat_main;
4755   vat_json_node_t node;
4756   u8 *status = 0;
4757
4758   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4759   vec_add1 (status, 0);
4760
4761   vat_json_init_object (&node);
4762   vat_json_object_add_string_copy (&node, "status", status);
4763   if (mp->status)
4764     {
4765       vat_json_object_add_string_copy (&node, "locator_set",
4766                                        mp->locator_set_name);
4767     }
4768
4769   vec_free (status);
4770
4771   vat_json_print (vam->ofp, &node);
4772   vat_json_free (&node);
4773
4774   vam->retval = ntohl (mp->retval);
4775   vam->result_ready = 1;
4776 }
4777
4778 static u8 *
4779 format_policer_type (u8 * s, va_list * va)
4780 {
4781   u32 i = va_arg (*va, u32);
4782
4783   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4784     s = format (s, "1r2c");
4785   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4786     s = format (s, "1r3c");
4787   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4788     s = format (s, "2r3c-2698");
4789   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4790     s = format (s, "2r3c-4115");
4791   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4792     s = format (s, "2r3c-mef5cf1");
4793   else
4794     s = format (s, "ILLEGAL");
4795   return s;
4796 }
4797
4798 static u8 *
4799 format_policer_rate_type (u8 * s, va_list * va)
4800 {
4801   u32 i = va_arg (*va, u32);
4802
4803   if (i == SSE2_QOS_RATE_KBPS)
4804     s = format (s, "kbps");
4805   else if (i == SSE2_QOS_RATE_PPS)
4806     s = format (s, "pps");
4807   else
4808     s = format (s, "ILLEGAL");
4809   return s;
4810 }
4811
4812 static u8 *
4813 format_policer_round_type (u8 * s, va_list * va)
4814 {
4815   u32 i = va_arg (*va, u32);
4816
4817   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4818     s = format (s, "closest");
4819   else if (i == SSE2_QOS_ROUND_TO_UP)
4820     s = format (s, "up");
4821   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4822     s = format (s, "down");
4823   else
4824     s = format (s, "ILLEGAL");
4825   return s;
4826 }
4827
4828 static u8 *
4829 format_policer_action_type (u8 * s, va_list * va)
4830 {
4831   u32 i = va_arg (*va, u32);
4832
4833   if (i == SSE2_QOS_ACTION_DROP)
4834     s = format (s, "drop");
4835   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4836     s = format (s, "transmit");
4837   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4838     s = format (s, "mark-and-transmit");
4839   else
4840     s = format (s, "ILLEGAL");
4841   return s;
4842 }
4843
4844 static u8 *
4845 format_dscp (u8 * s, va_list * va)
4846 {
4847   u32 i = va_arg (*va, u32);
4848   char *t = 0;
4849
4850   switch (i)
4851     {
4852 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4853       foreach_vnet_dscp
4854 #undef _
4855     default:
4856       return format (s, "ILLEGAL");
4857     }
4858   s = format (s, "%s", t);
4859   return s;
4860 }
4861
4862 static void
4863 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4864 {
4865   vat_main_t *vam = &vat_main;
4866   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4867
4868   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4869     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4870   else
4871     conform_dscp_str = format (0, "");
4872
4873   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4874     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4875   else
4876     exceed_dscp_str = format (0, "");
4877
4878   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4879     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4880   else
4881     violate_dscp_str = format (0, "");
4882
4883   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4884          "rate type %U, round type %U, %s rate, %s color-aware, "
4885          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4886          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4887          "conform action %U%s, exceed action %U%s, violate action %U%s",
4888          mp->name,
4889          format_policer_type, mp->type,
4890          ntohl (mp->cir),
4891          ntohl (mp->eir),
4892          clib_net_to_host_u64 (mp->cb),
4893          clib_net_to_host_u64 (mp->eb),
4894          format_policer_rate_type, mp->rate_type,
4895          format_policer_round_type, mp->round_type,
4896          mp->single_rate ? "single" : "dual",
4897          mp->color_aware ? "is" : "not",
4898          ntohl (mp->cir_tokens_per_period),
4899          ntohl (mp->pir_tokens_per_period),
4900          ntohl (mp->scale),
4901          ntohl (mp->current_limit),
4902          ntohl (mp->current_bucket),
4903          ntohl (mp->extended_limit),
4904          ntohl (mp->extended_bucket),
4905          clib_net_to_host_u64 (mp->last_update_time),
4906          format_policer_action_type, mp->conform_action_type,
4907          conform_dscp_str,
4908          format_policer_action_type, mp->exceed_action_type,
4909          exceed_dscp_str,
4910          format_policer_action_type, mp->violate_action_type,
4911          violate_dscp_str);
4912
4913   vec_free (conform_dscp_str);
4914   vec_free (exceed_dscp_str);
4915   vec_free (violate_dscp_str);
4916 }
4917
4918 static void vl_api_policer_details_t_handler_json
4919   (vl_api_policer_details_t * mp)
4920 {
4921   vat_main_t *vam = &vat_main;
4922   vat_json_node_t *node;
4923   u8 *rate_type_str, *round_type_str, *type_str;
4924   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4925
4926   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4927   round_type_str =
4928     format (0, "%U", format_policer_round_type, mp->round_type);
4929   type_str = format (0, "%U", format_policer_type, mp->type);
4930   conform_action_str = format (0, "%U", format_policer_action_type,
4931                                mp->conform_action_type);
4932   exceed_action_str = format (0, "%U", format_policer_action_type,
4933                               mp->exceed_action_type);
4934   violate_action_str = format (0, "%U", format_policer_action_type,
4935                                mp->violate_action_type);
4936
4937   if (VAT_JSON_ARRAY != vam->json_tree.type)
4938     {
4939       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4940       vat_json_init_array (&vam->json_tree);
4941     }
4942   node = vat_json_array_add (&vam->json_tree);
4943
4944   vat_json_init_object (node);
4945   vat_json_object_add_string_copy (node, "name", mp->name);
4946   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4947   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4948   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4949   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4950   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4951   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4952   vat_json_object_add_string_copy (node, "type", type_str);
4953   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4954   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4955   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4956   vat_json_object_add_uint (node, "cir_tokens_per_period",
4957                             ntohl (mp->cir_tokens_per_period));
4958   vat_json_object_add_uint (node, "eir_tokens_per_period",
4959                             ntohl (mp->pir_tokens_per_period));
4960   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4961   vat_json_object_add_uint (node, "current_bucket",
4962                             ntohl (mp->current_bucket));
4963   vat_json_object_add_uint (node, "extended_limit",
4964                             ntohl (mp->extended_limit));
4965   vat_json_object_add_uint (node, "extended_bucket",
4966                             ntohl (mp->extended_bucket));
4967   vat_json_object_add_uint (node, "last_update_time",
4968                             ntohl (mp->last_update_time));
4969   vat_json_object_add_string_copy (node, "conform_action",
4970                                    conform_action_str);
4971   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4972     {
4973       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4974       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4975       vec_free (dscp_str);
4976     }
4977   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4978   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4979     {
4980       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4981       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4982       vec_free (dscp_str);
4983     }
4984   vat_json_object_add_string_copy (node, "violate_action",
4985                                    violate_action_str);
4986   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4987     {
4988       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4989       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4990       vec_free (dscp_str);
4991     }
4992
4993   vec_free (rate_type_str);
4994   vec_free (round_type_str);
4995   vec_free (type_str);
4996   vec_free (conform_action_str);
4997   vec_free (exceed_action_str);
4998   vec_free (violate_action_str);
4999 }
5000
5001 static void
5002 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5003                                            mp)
5004 {
5005   vat_main_t *vam = &vat_main;
5006   int i, count = ntohl (mp->count);
5007
5008   if (count > 0)
5009     print (vam->ofp, "classify table ids (%d) : ", count);
5010   for (i = 0; i < count; i++)
5011     {
5012       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5013       print (vam->ofp, (i < count - 1) ? "," : "");
5014     }
5015   vam->retval = ntohl (mp->retval);
5016   vam->result_ready = 1;
5017 }
5018
5019 static void
5020   vl_api_classify_table_ids_reply_t_handler_json
5021   (vl_api_classify_table_ids_reply_t * mp)
5022 {
5023   vat_main_t *vam = &vat_main;
5024   int i, count = ntohl (mp->count);
5025
5026   if (count > 0)
5027     {
5028       vat_json_node_t node;
5029
5030       vat_json_init_object (&node);
5031       for (i = 0; i < count; i++)
5032         {
5033           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5034         }
5035       vat_json_print (vam->ofp, &node);
5036       vat_json_free (&node);
5037     }
5038   vam->retval = ntohl (mp->retval);
5039   vam->result_ready = 1;
5040 }
5041
5042 static void
5043   vl_api_classify_table_by_interface_reply_t_handler
5044   (vl_api_classify_table_by_interface_reply_t * mp)
5045 {
5046   vat_main_t *vam = &vat_main;
5047   u32 table_id;
5048
5049   table_id = ntohl (mp->l2_table_id);
5050   if (table_id != ~0)
5051     print (vam->ofp, "l2 table id : %d", table_id);
5052   else
5053     print (vam->ofp, "l2 table id : No input ACL tables configured");
5054   table_id = ntohl (mp->ip4_table_id);
5055   if (table_id != ~0)
5056     print (vam->ofp, "ip4 table id : %d", table_id);
5057   else
5058     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5059   table_id = ntohl (mp->ip6_table_id);
5060   if (table_id != ~0)
5061     print (vam->ofp, "ip6 table id : %d", table_id);
5062   else
5063     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5064   vam->retval = ntohl (mp->retval);
5065   vam->result_ready = 1;
5066 }
5067
5068 static void
5069   vl_api_classify_table_by_interface_reply_t_handler_json
5070   (vl_api_classify_table_by_interface_reply_t * mp)
5071 {
5072   vat_main_t *vam = &vat_main;
5073   vat_json_node_t node;
5074
5075   vat_json_init_object (&node);
5076
5077   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5078   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5079   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5080
5081   vat_json_print (vam->ofp, &node);
5082   vat_json_free (&node);
5083
5084   vam->retval = ntohl (mp->retval);
5085   vam->result_ready = 1;
5086 }
5087
5088 static void vl_api_policer_add_del_reply_t_handler
5089   (vl_api_policer_add_del_reply_t * mp)
5090 {
5091   vat_main_t *vam = &vat_main;
5092   i32 retval = ntohl (mp->retval);
5093   if (vam->async_mode)
5094     {
5095       vam->async_errors += (retval < 0);
5096     }
5097   else
5098     {
5099       vam->retval = retval;
5100       vam->result_ready = 1;
5101       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5102         /*
5103          * Note: this is just barely thread-safe, depends on
5104          * the main thread spinning waiting for an answer...
5105          */
5106         errmsg ("policer index %d", ntohl (mp->policer_index));
5107     }
5108 }
5109
5110 static void vl_api_policer_add_del_reply_t_handler_json
5111   (vl_api_policer_add_del_reply_t * mp)
5112 {
5113   vat_main_t *vam = &vat_main;
5114   vat_json_node_t node;
5115
5116   vat_json_init_object (&node);
5117   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5118   vat_json_object_add_uint (&node, "policer_index",
5119                             ntohl (mp->policer_index));
5120
5121   vat_json_print (vam->ofp, &node);
5122   vat_json_free (&node);
5123
5124   vam->retval = ntohl (mp->retval);
5125   vam->result_ready = 1;
5126 }
5127
5128 /* Format hex dump. */
5129 u8 *
5130 format_hex_bytes (u8 * s, va_list * va)
5131 {
5132   u8 *bytes = va_arg (*va, u8 *);
5133   int n_bytes = va_arg (*va, int);
5134   uword i;
5135
5136   /* Print short or long form depending on byte count. */
5137   uword short_form = n_bytes <= 32;
5138   u32 indent = format_get_indent (s);
5139
5140   if (n_bytes == 0)
5141     return s;
5142
5143   for (i = 0; i < n_bytes; i++)
5144     {
5145       if (!short_form && (i % 32) == 0)
5146         s = format (s, "%08x: ", i);
5147       s = format (s, "%02x", bytes[i]);
5148       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5149         s = format (s, "\n%U", format_white_space, indent);
5150     }
5151
5152   return s;
5153 }
5154
5155 static void
5156 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5157                                             * mp)
5158 {
5159   vat_main_t *vam = &vat_main;
5160   i32 retval = ntohl (mp->retval);
5161   if (retval == 0)
5162     {
5163       print (vam->ofp, "classify table info :");
5164       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5165              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5166              ntohl (mp->miss_next_index));
5167       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5168              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5169              ntohl (mp->match_n_vectors));
5170       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5171              ntohl (mp->mask_length));
5172     }
5173   vam->retval = retval;
5174   vam->result_ready = 1;
5175 }
5176
5177 static void
5178   vl_api_classify_table_info_reply_t_handler_json
5179   (vl_api_classify_table_info_reply_t * mp)
5180 {
5181   vat_main_t *vam = &vat_main;
5182   vat_json_node_t node;
5183
5184   i32 retval = ntohl (mp->retval);
5185   if (retval == 0)
5186     {
5187       vat_json_init_object (&node);
5188
5189       vat_json_object_add_int (&node, "sessions",
5190                                ntohl (mp->active_sessions));
5191       vat_json_object_add_int (&node, "nexttbl",
5192                                ntohl (mp->next_table_index));
5193       vat_json_object_add_int (&node, "nextnode",
5194                                ntohl (mp->miss_next_index));
5195       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5196       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5197       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5198       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5199                       ntohl (mp->mask_length), 0);
5200       vat_json_object_add_string_copy (&node, "mask", s);
5201
5202       vat_json_print (vam->ofp, &node);
5203       vat_json_free (&node);
5204     }
5205   vam->retval = ntohl (mp->retval);
5206   vam->result_ready = 1;
5207 }
5208
5209 static void
5210 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5211                                            mp)
5212 {
5213   vat_main_t *vam = &vat_main;
5214
5215   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5216          ntohl (mp->hit_next_index), ntohl (mp->advance),
5217          ntohl (mp->opaque_index));
5218   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5219          ntohl (mp->match_length));
5220 }
5221
5222 static void
5223   vl_api_classify_session_details_t_handler_json
5224   (vl_api_classify_session_details_t * mp)
5225 {
5226   vat_main_t *vam = &vat_main;
5227   vat_json_node_t *node = NULL;
5228
5229   if (VAT_JSON_ARRAY != vam->json_tree.type)
5230     {
5231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5232       vat_json_init_array (&vam->json_tree);
5233     }
5234   node = vat_json_array_add (&vam->json_tree);
5235
5236   vat_json_init_object (node);
5237   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5238   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5239   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5240   u8 *s =
5241     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5242             0);
5243   vat_json_object_add_string_copy (node, "match", s);
5244 }
5245
5246 static void vl_api_pg_create_interface_reply_t_handler
5247   (vl_api_pg_create_interface_reply_t * mp)
5248 {
5249   vat_main_t *vam = &vat_main;
5250
5251   vam->retval = ntohl (mp->retval);
5252   vam->result_ready = 1;
5253 }
5254
5255 static void vl_api_pg_create_interface_reply_t_handler_json
5256   (vl_api_pg_create_interface_reply_t * mp)
5257 {
5258   vat_main_t *vam = &vat_main;
5259   vat_json_node_t node;
5260
5261   i32 retval = ntohl (mp->retval);
5262   if (retval == 0)
5263     {
5264       vat_json_init_object (&node);
5265
5266       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5267
5268       vat_json_print (vam->ofp, &node);
5269       vat_json_free (&node);
5270     }
5271   vam->retval = ntohl (mp->retval);
5272   vam->result_ready = 1;
5273 }
5274
5275 static void vl_api_policer_classify_details_t_handler
5276   (vl_api_policer_classify_details_t * mp)
5277 {
5278   vat_main_t *vam = &vat_main;
5279
5280   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5281          ntohl (mp->table_index));
5282 }
5283
5284 static void vl_api_policer_classify_details_t_handler_json
5285   (vl_api_policer_classify_details_t * mp)
5286 {
5287   vat_main_t *vam = &vat_main;
5288   vat_json_node_t *node;
5289
5290   if (VAT_JSON_ARRAY != vam->json_tree.type)
5291     {
5292       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5293       vat_json_init_array (&vam->json_tree);
5294     }
5295   node = vat_json_array_add (&vam->json_tree);
5296
5297   vat_json_init_object (node);
5298   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5299   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5300 }
5301
5302 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5303   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5304 {
5305   vat_main_t *vam = &vat_main;
5306   i32 retval = ntohl (mp->retval);
5307   if (vam->async_mode)
5308     {
5309       vam->async_errors += (retval < 0);
5310     }
5311   else
5312     {
5313       vam->retval = retval;
5314       vam->sw_if_index = ntohl (mp->sw_if_index);
5315       vam->result_ready = 1;
5316     }
5317   vam->regenerate_interface_table = 1;
5318 }
5319
5320 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5321   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5322 {
5323   vat_main_t *vam = &vat_main;
5324   vat_json_node_t node;
5325
5326   vat_json_init_object (&node);
5327   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5328   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5329
5330   vat_json_print (vam->ofp, &node);
5331   vat_json_free (&node);
5332
5333   vam->retval = ntohl (mp->retval);
5334   vam->result_ready = 1;
5335 }
5336
5337 static void vl_api_flow_classify_details_t_handler
5338   (vl_api_flow_classify_details_t * mp)
5339 {
5340   vat_main_t *vam = &vat_main;
5341
5342   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5343          ntohl (mp->table_index));
5344 }
5345
5346 static void vl_api_flow_classify_details_t_handler_json
5347   (vl_api_flow_classify_details_t * mp)
5348 {
5349   vat_main_t *vam = &vat_main;
5350   vat_json_node_t *node;
5351
5352   if (VAT_JSON_ARRAY != vam->json_tree.type)
5353     {
5354       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5355       vat_json_init_array (&vam->json_tree);
5356     }
5357   node = vat_json_array_add (&vam->json_tree);
5358
5359   vat_json_init_object (node);
5360   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5361   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5362 }
5363
5364 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5365 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5366 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5367 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5368 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5369 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5370 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5371 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5372 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5373 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5374 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5375 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5376 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5377 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5378 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5379 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5380 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5381 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5382 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5383 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5384 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5385 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5386
5387 /*
5388  * Generate boilerplate reply handlers, which
5389  * dig the return value out of the xxx_reply_t API message,
5390  * stick it into vam->retval, and set vam->result_ready
5391  *
5392  * Could also do this by pointing N message decode slots at
5393  * a single function, but that could break in subtle ways.
5394  */
5395
5396 #define foreach_standard_reply_retval_handler           \
5397 _(sw_interface_set_flags_reply)                         \
5398 _(sw_interface_add_del_address_reply)                   \
5399 _(sw_interface_set_rx_mode_reply)                       \
5400 _(sw_interface_set_table_reply)                         \
5401 _(sw_interface_set_mpls_enable_reply)                   \
5402 _(sw_interface_set_vpath_reply)                         \
5403 _(sw_interface_set_vxlan_bypass_reply)                  \
5404 _(sw_interface_set_geneve_bypass_reply)                 \
5405 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5406 _(sw_interface_set_l2_bridge_reply)                     \
5407 _(bridge_domain_add_del_reply)                          \
5408 _(sw_interface_set_l2_xconnect_reply)                   \
5409 _(l2fib_add_del_reply)                                  \
5410 _(l2fib_flush_int_reply)                                \
5411 _(l2fib_flush_bd_reply)                                 \
5412 _(ip_add_del_route_reply)                               \
5413 _(ip_table_add_del_reply)                               \
5414 _(ip_mroute_add_del_reply)                              \
5415 _(mpls_route_add_del_reply)                             \
5416 _(mpls_table_add_del_reply)                             \
5417 _(mpls_ip_bind_unbind_reply)                            \
5418 _(bier_route_add_del_reply)                             \
5419 _(bier_table_add_del_reply)                             \
5420 _(proxy_arp_add_del_reply)                              \
5421 _(proxy_arp_intfc_enable_disable_reply)                 \
5422 _(sw_interface_set_unnumbered_reply)                    \
5423 _(ip_neighbor_add_del_reply)                            \
5424 _(oam_add_del_reply)                                    \
5425 _(reset_fib_reply)                                      \
5426 _(dhcp_proxy_config_reply)                              \
5427 _(dhcp_proxy_set_vss_reply)                             \
5428 _(dhcp_client_config_reply)                             \
5429 _(set_ip_flow_hash_reply)                               \
5430 _(sw_interface_ip6_enable_disable_reply)                \
5431 _(sw_interface_ip6_set_link_local_address_reply)        \
5432 _(ip6nd_proxy_add_del_reply)                            \
5433 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5434 _(sw_interface_ip6nd_ra_config_reply)                   \
5435 _(set_arp_neighbor_limit_reply)                         \
5436 _(l2_patch_add_del_reply)                               \
5437 _(sr_policy_add_reply)                                  \
5438 _(sr_policy_mod_reply)                                  \
5439 _(sr_policy_del_reply)                                  \
5440 _(sr_localsid_add_del_reply)                            \
5441 _(sr_steering_add_del_reply)                            \
5442 _(classify_add_del_session_reply)                       \
5443 _(classify_set_interface_ip_table_reply)                \
5444 _(classify_set_interface_l2_tables_reply)               \
5445 _(l2tpv3_set_tunnel_cookies_reply)                      \
5446 _(l2tpv3_interface_enable_disable_reply)                \
5447 _(l2tpv3_set_lookup_key_reply)                          \
5448 _(l2_fib_clear_table_reply)                             \
5449 _(l2_interface_efp_filter_reply)                        \
5450 _(l2_interface_vlan_tag_rewrite_reply)                  \
5451 _(modify_vhost_user_if_reply)                           \
5452 _(delete_vhost_user_if_reply)                           \
5453 _(ip_probe_neighbor_reply)                              \
5454 _(ip_scan_neighbor_enable_disable_reply)                \
5455 _(want_ip4_arp_events_reply)                            \
5456 _(want_ip6_nd_events_reply)                             \
5457 _(want_l2_macs_events_reply)                            \
5458 _(input_acl_set_interface_reply)                        \
5459 _(ipsec_spd_add_del_reply)                              \
5460 _(ipsec_interface_add_del_spd_reply)                    \
5461 _(ipsec_spd_add_del_entry_reply)                        \
5462 _(ipsec_sad_add_del_entry_reply)                        \
5463 _(ipsec_sa_set_key_reply)                               \
5464 _(ipsec_tunnel_if_add_del_reply)                        \
5465 _(ipsec_tunnel_if_set_key_reply)                        \
5466 _(ipsec_tunnel_if_set_sa_reply)                         \
5467 _(ikev2_profile_add_del_reply)                          \
5468 _(ikev2_profile_set_auth_reply)                         \
5469 _(ikev2_profile_set_id_reply)                           \
5470 _(ikev2_profile_set_ts_reply)                           \
5471 _(ikev2_set_local_key_reply)                            \
5472 _(ikev2_set_responder_reply)                            \
5473 _(ikev2_set_ike_transforms_reply)                       \
5474 _(ikev2_set_esp_transforms_reply)                       \
5475 _(ikev2_set_sa_lifetime_reply)                          \
5476 _(ikev2_initiate_sa_init_reply)                         \
5477 _(ikev2_initiate_del_ike_sa_reply)                      \
5478 _(ikev2_initiate_del_child_sa_reply)                    \
5479 _(ikev2_initiate_rekey_child_sa_reply)                  \
5480 _(delete_loopback_reply)                                \
5481 _(bd_ip_mac_add_del_reply)                              \
5482 _(map_del_domain_reply)                                 \
5483 _(map_add_del_rule_reply)                               \
5484 _(want_interface_events_reply)                          \
5485 _(want_stats_reply)                                     \
5486 _(cop_interface_enable_disable_reply)                   \
5487 _(cop_whitelist_enable_disable_reply)                   \
5488 _(sw_interface_clear_stats_reply)                       \
5489 _(ioam_enable_reply)                                    \
5490 _(ioam_disable_reply)                                   \
5491 _(one_add_del_locator_reply)                            \
5492 _(one_add_del_local_eid_reply)                          \
5493 _(one_add_del_remote_mapping_reply)                     \
5494 _(one_add_del_adjacency_reply)                          \
5495 _(one_add_del_map_resolver_reply)                       \
5496 _(one_add_del_map_server_reply)                         \
5497 _(one_enable_disable_reply)                             \
5498 _(one_rloc_probe_enable_disable_reply)                  \
5499 _(one_map_register_enable_disable_reply)                \
5500 _(one_map_register_set_ttl_reply)                       \
5501 _(one_set_transport_protocol_reply)                     \
5502 _(one_map_register_fallback_threshold_reply)            \
5503 _(one_pitr_set_locator_set_reply)                       \
5504 _(one_map_request_mode_reply)                           \
5505 _(one_add_del_map_request_itr_rlocs_reply)              \
5506 _(one_eid_table_add_del_map_reply)                      \
5507 _(one_use_petr_reply)                                   \
5508 _(one_stats_enable_disable_reply)                       \
5509 _(one_add_del_l2_arp_entry_reply)                       \
5510 _(one_add_del_ndp_entry_reply)                          \
5511 _(one_stats_flush_reply)                                \
5512 _(one_enable_disable_xtr_mode_reply)                    \
5513 _(one_enable_disable_pitr_mode_reply)                   \
5514 _(one_enable_disable_petr_mode_reply)                   \
5515 _(gpe_enable_disable_reply)                             \
5516 _(gpe_set_encap_mode_reply)                             \
5517 _(gpe_add_del_iface_reply)                              \
5518 _(gpe_add_del_native_fwd_rpath_reply)                   \
5519 _(af_packet_delete_reply)                               \
5520 _(policer_classify_set_interface_reply)                 \
5521 _(netmap_create_reply)                                  \
5522 _(netmap_delete_reply)                                  \
5523 _(set_ipfix_exporter_reply)                             \
5524 _(set_ipfix_classify_stream_reply)                      \
5525 _(ipfix_classify_table_add_del_reply)                   \
5526 _(flow_classify_set_interface_reply)                    \
5527 _(sw_interface_span_enable_disable_reply)               \
5528 _(pg_capture_reply)                                     \
5529 _(pg_enable_disable_reply)                              \
5530 _(ip_source_and_port_range_check_add_del_reply)         \
5531 _(ip_source_and_port_range_check_interface_add_del_reply)\
5532 _(delete_subif_reply)                                   \
5533 _(l2_interface_pbb_tag_rewrite_reply)                   \
5534 _(punt_reply)                                           \
5535 _(feature_enable_disable_reply)                         \
5536 _(sw_interface_tag_add_del_reply)                       \
5537 _(sw_interface_set_mtu_reply)                           \
5538 _(p2p_ethernet_add_reply)                               \
5539 _(p2p_ethernet_del_reply)                               \
5540 _(lldp_config_reply)                                    \
5541 _(sw_interface_set_lldp_reply)                          \
5542 _(tcp_configure_src_addresses_reply)                    \
5543 _(dns_enable_disable_reply)                             \
5544 _(dns_name_server_add_del_reply)                        \
5545 _(session_rule_add_del_reply)                           \
5546 _(ip_container_proxy_add_del_reply)                     \
5547 _(output_acl_set_interface_reply)                       \
5548 _(qos_record_enable_disable_reply)
5549
5550 #define _(n)                                    \
5551     static void vl_api_##n##_t_handler          \
5552     (vl_api_##n##_t * mp)                       \
5553     {                                           \
5554         vat_main_t * vam = &vat_main;           \
5555         i32 retval = ntohl(mp->retval);         \
5556         if (vam->async_mode) {                  \
5557             vam->async_errors += (retval < 0);  \
5558         } else {                                \
5559             vam->retval = retval;               \
5560             vam->result_ready = 1;              \
5561         }                                       \
5562     }
5563 foreach_standard_reply_retval_handler;
5564 #undef _
5565
5566 #define _(n)                                    \
5567     static void vl_api_##n##_t_handler_json     \
5568     (vl_api_##n##_t * mp)                       \
5569     {                                           \
5570         vat_main_t * vam = &vat_main;           \
5571         vat_json_node_t node;                   \
5572         vat_json_init_object(&node);            \
5573         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5574         vat_json_print(vam->ofp, &node);        \
5575         vam->retval = ntohl(mp->retval);        \
5576         vam->result_ready = 1;                  \
5577     }
5578 foreach_standard_reply_retval_handler;
5579 #undef _
5580
5581 /*
5582  * Table of message reply handlers, must include boilerplate handlers
5583  * we just generated
5584  */
5585
5586 #define foreach_vpe_api_reply_msg                                       \
5587 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5588 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5589 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5590 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5591 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5592 _(CLI_REPLY, cli_reply)                                                 \
5593 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5594 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5595   sw_interface_add_del_address_reply)                                   \
5596 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5597 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5598 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5599 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5600 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5601 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5602 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5603 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5604   sw_interface_set_l2_xconnect_reply)                                   \
5605 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5606   sw_interface_set_l2_bridge_reply)                                     \
5607 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5608 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5609 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5610 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5611 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5612 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5613 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5614 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5615 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5616 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5617 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5618 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5619 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5620 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5621 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5622 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5623 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5624 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5625 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5626 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5627 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5628 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5629 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5630 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5631 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5632 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5633 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5634 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5635 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5636 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5637 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5638   proxy_arp_intfc_enable_disable_reply)                                 \
5639 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5640 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5641   sw_interface_set_unnumbered_reply)                                    \
5642 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5643 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5644 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5645 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5646 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5647 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5648 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5649 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5650 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5651 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5652 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5653   sw_interface_ip6_enable_disable_reply)                                \
5654 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5655   sw_interface_ip6_set_link_local_address_reply)                        \
5656 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5657 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5658 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5659   sw_interface_ip6nd_ra_prefix_reply)                                   \
5660 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5661   sw_interface_ip6nd_ra_config_reply)                                   \
5662 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5663 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5664 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5665 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5666 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5667 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5668 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5669 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5670 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5671 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5672 classify_set_interface_ip_table_reply)                                  \
5673 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5674   classify_set_interface_l2_tables_reply)                               \
5675 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5676 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5677 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5678 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5679 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5680   l2tpv3_interface_enable_disable_reply)                                \
5681 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5682 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5683 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5684 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5685 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5686 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5687 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5688 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5689 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5690 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5691 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5692 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5693 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5694 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5695 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5696 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5697 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5698 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5699 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5700 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5701 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5702 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5703 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5704 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5705 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5706 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5707 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5708 _(L2_MACS_EVENT, l2_macs_event)                                         \
5709 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5710 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5711 _(IP_DETAILS, ip_details)                                               \
5712 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5713 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5714 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5715 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5716 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5717 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5718 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5719 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5720 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5721 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5722 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5723 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5724 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5725 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5726 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5727 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5728 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5729 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5730 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5731 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5732 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5733 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5734 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5735 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5736 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5737 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5738 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5739 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5740 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5741 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5742 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5743 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5744 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5745 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5746 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5747 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5748 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5749 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5750 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5751 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5752 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5753 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5754 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5755 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5756 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5757 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5758 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5759 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5760   one_map_register_enable_disable_reply)                                \
5761 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5762 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5763 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5764 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5765   one_map_register_fallback_threshold_reply)                            \
5766 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5767   one_rloc_probe_enable_disable_reply)                                  \
5768 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5769 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5770 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5771 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5772 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5773 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5774 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5775 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5776 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5777 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5778 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5779 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5780 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5781 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5782 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5783 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5784   show_one_stats_enable_disable_reply)                                  \
5785 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5786 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5787 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5788 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5789 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5790 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5791 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5792 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5793   one_enable_disable_pitr_mode_reply)                                   \
5794 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5795   one_enable_disable_petr_mode_reply)                                   \
5796 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5797 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5798 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5799 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5800 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5801 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5802 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5803 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5804 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5805 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5806 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5807 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5808   gpe_add_del_native_fwd_rpath_reply)                                   \
5809 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5810   gpe_fwd_entry_path_details)                                           \
5811 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5812 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5813   one_add_del_map_request_itr_rlocs_reply)                              \
5814 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5815   one_get_map_request_itr_rlocs_reply)                                  \
5816 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5817 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5818 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5819 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5820 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5821 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5822   show_one_map_register_state_reply)                                    \
5823 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5824 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5825   show_one_map_register_fallback_threshold_reply)                       \
5826 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5827 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5828 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5829 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5830 _(POLICER_DETAILS, policer_details)                                     \
5831 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5832 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5833 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5834 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5835 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5836 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5837 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5838 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5839 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5840 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5841 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5842 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5843 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5844 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5845 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5846 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5847 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5848 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5849 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5850 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5851 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5852 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5853 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5854 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5855 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5856  ip_source_and_port_range_check_add_del_reply)                          \
5857 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5858  ip_source_and_port_range_check_interface_add_del_reply)                \
5859 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5860 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5861 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5862 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5863 _(PUNT_REPLY, punt_reply)                                               \
5864 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5865 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5866 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5867 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5868 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5869 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5870 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5871 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5872 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5873 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5874 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5875 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5876 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5877 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5878 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5879 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5880 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5881 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5882 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5883 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5884 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5885 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5886 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5887
5888 #define foreach_standalone_reply_msg                                    \
5889 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5890 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5891 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5892 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5893 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5894 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5895 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5896
5897 typedef struct
5898 {
5899   u8 *name;
5900   u32 value;
5901 } name_sort_t;
5902
5903 #define STR_VTR_OP_CASE(op)     \
5904     case L2_VTR_ ## op:         \
5905         return "" # op;
5906
5907 static const char *
5908 str_vtr_op (u32 vtr_op)
5909 {
5910   switch (vtr_op)
5911     {
5912       STR_VTR_OP_CASE (DISABLED);
5913       STR_VTR_OP_CASE (PUSH_1);
5914       STR_VTR_OP_CASE (PUSH_2);
5915       STR_VTR_OP_CASE (POP_1);
5916       STR_VTR_OP_CASE (POP_2);
5917       STR_VTR_OP_CASE (TRANSLATE_1_1);
5918       STR_VTR_OP_CASE (TRANSLATE_1_2);
5919       STR_VTR_OP_CASE (TRANSLATE_2_1);
5920       STR_VTR_OP_CASE (TRANSLATE_2_2);
5921     }
5922
5923   return "UNKNOWN";
5924 }
5925
5926 static int
5927 dump_sub_interface_table (vat_main_t * vam)
5928 {
5929   const sw_interface_subif_t *sub = NULL;
5930
5931   if (vam->json_output)
5932     {
5933       clib_warning
5934         ("JSON output supported only for VPE API calls and dump_stats_table");
5935       return -99;
5936     }
5937
5938   print (vam->ofp,
5939          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5940          "Interface", "sw_if_index",
5941          "sub id", "dot1ad", "tags", "outer id",
5942          "inner id", "exact", "default", "outer any", "inner any");
5943
5944   vec_foreach (sub, vam->sw_if_subif_table)
5945   {
5946     print (vam->ofp,
5947            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5948            sub->interface_name,
5949            sub->sw_if_index,
5950            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5951            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5952            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5953            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5954     if (sub->vtr_op != L2_VTR_DISABLED)
5955       {
5956         print (vam->ofp,
5957                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5958                "tag1: %d tag2: %d ]",
5959                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5960                sub->vtr_tag1, sub->vtr_tag2);
5961       }
5962   }
5963
5964   return 0;
5965 }
5966
5967 static int
5968 name_sort_cmp (void *a1, void *a2)
5969 {
5970   name_sort_t *n1 = a1;
5971   name_sort_t *n2 = a2;
5972
5973   return strcmp ((char *) n1->name, (char *) n2->name);
5974 }
5975
5976 static int
5977 dump_interface_table (vat_main_t * vam)
5978 {
5979   hash_pair_t *p;
5980   name_sort_t *nses = 0, *ns;
5981
5982   if (vam->json_output)
5983     {
5984       clib_warning
5985         ("JSON output supported only for VPE API calls and dump_stats_table");
5986       return -99;
5987     }
5988
5989   /* *INDENT-OFF* */
5990   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5991   ({
5992     vec_add2 (nses, ns, 1);
5993     ns->name = (u8 *)(p->key);
5994     ns->value = (u32) p->value[0];
5995   }));
5996   /* *INDENT-ON* */
5997
5998   vec_sort_with_function (nses, name_sort_cmp);
5999
6000   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6001   vec_foreach (ns, nses)
6002   {
6003     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6004   }
6005   vec_free (nses);
6006   return 0;
6007 }
6008
6009 static int
6010 dump_ip_table (vat_main_t * vam, int is_ipv6)
6011 {
6012   const ip_details_t *det = NULL;
6013   const ip_address_details_t *address = NULL;
6014   u32 i = ~0;
6015
6016   print (vam->ofp, "%-12s", "sw_if_index");
6017
6018   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6019   {
6020     i++;
6021     if (!det->present)
6022       {
6023         continue;
6024       }
6025     print (vam->ofp, "%-12d", i);
6026     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6027     if (!det->addr)
6028       {
6029         continue;
6030       }
6031     vec_foreach (address, det->addr)
6032     {
6033       print (vam->ofp,
6034              "            %-30U%-13d",
6035              is_ipv6 ? format_ip6_address : format_ip4_address,
6036              address->ip, address->prefix_length);
6037     }
6038   }
6039
6040   return 0;
6041 }
6042
6043 static int
6044 dump_ipv4_table (vat_main_t * vam)
6045 {
6046   if (vam->json_output)
6047     {
6048       clib_warning
6049         ("JSON output supported only for VPE API calls and dump_stats_table");
6050       return -99;
6051     }
6052
6053   return dump_ip_table (vam, 0);
6054 }
6055
6056 static int
6057 dump_ipv6_table (vat_main_t * vam)
6058 {
6059   if (vam->json_output)
6060     {
6061       clib_warning
6062         ("JSON output supported only for VPE API calls and dump_stats_table");
6063       return -99;
6064     }
6065
6066   return dump_ip_table (vam, 1);
6067 }
6068
6069 static char *
6070 counter_type_to_str (u8 counter_type, u8 is_combined)
6071 {
6072   if (!is_combined)
6073     {
6074       switch (counter_type)
6075         {
6076         case VNET_INTERFACE_COUNTER_DROP:
6077           return "drop";
6078         case VNET_INTERFACE_COUNTER_PUNT:
6079           return "punt";
6080         case VNET_INTERFACE_COUNTER_IP4:
6081           return "ip4";
6082         case VNET_INTERFACE_COUNTER_IP6:
6083           return "ip6";
6084         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6085           return "rx-no-buf";
6086         case VNET_INTERFACE_COUNTER_RX_MISS:
6087           return "rx-miss";
6088         case VNET_INTERFACE_COUNTER_RX_ERROR:
6089           return "rx-error";
6090         case VNET_INTERFACE_COUNTER_TX_ERROR:
6091           return "tx-error";
6092         default:
6093           return "INVALID-COUNTER-TYPE";
6094         }
6095     }
6096   else
6097     {
6098       switch (counter_type)
6099         {
6100         case VNET_INTERFACE_COUNTER_RX:
6101           return "rx";
6102         case VNET_INTERFACE_COUNTER_TX:
6103           return "tx";
6104         default:
6105           return "INVALID-COUNTER-TYPE";
6106         }
6107     }
6108 }
6109
6110 static int
6111 dump_stats_table (vat_main_t * vam)
6112 {
6113   vat_json_node_t node;
6114   vat_json_node_t *msg_array;
6115   vat_json_node_t *msg;
6116   vat_json_node_t *counter_array;
6117   vat_json_node_t *counter;
6118   interface_counter_t c;
6119   u64 packets;
6120   ip4_fib_counter_t *c4;
6121   ip6_fib_counter_t *c6;
6122   ip4_nbr_counter_t *n4;
6123   ip6_nbr_counter_t *n6;
6124   int i, j;
6125
6126   if (!vam->json_output)
6127     {
6128       clib_warning ("dump_stats_table supported only in JSON format");
6129       return -99;
6130     }
6131
6132   vat_json_init_object (&node);
6133
6134   /* interface counters */
6135   msg_array = vat_json_object_add (&node, "interface_counters");
6136   vat_json_init_array (msg_array);
6137   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6138     {
6139       msg = vat_json_array_add (msg_array);
6140       vat_json_init_object (msg);
6141       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6142                                        (u8 *) counter_type_to_str (i, 0));
6143       vat_json_object_add_int (msg, "is_combined", 0);
6144       counter_array = vat_json_object_add (msg, "data");
6145       vat_json_init_array (counter_array);
6146       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6147         {
6148           packets = vam->simple_interface_counters[i][j];
6149           vat_json_array_add_uint (counter_array, packets);
6150         }
6151     }
6152   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6153     {
6154       msg = vat_json_array_add (msg_array);
6155       vat_json_init_object (msg);
6156       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6157                                        (u8 *) counter_type_to_str (i, 1));
6158       vat_json_object_add_int (msg, "is_combined", 1);
6159       counter_array = vat_json_object_add (msg, "data");
6160       vat_json_init_array (counter_array);
6161       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6162         {
6163           c = vam->combined_interface_counters[i][j];
6164           counter = vat_json_array_add (counter_array);
6165           vat_json_init_object (counter);
6166           vat_json_object_add_uint (counter, "packets", c.packets);
6167           vat_json_object_add_uint (counter, "bytes", c.bytes);
6168         }
6169     }
6170
6171   /* ip4 fib counters */
6172   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6173   vat_json_init_array (msg_array);
6174   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6175     {
6176       msg = vat_json_array_add (msg_array);
6177       vat_json_init_object (msg);
6178       vat_json_object_add_uint (msg, "vrf_id",
6179                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6180       counter_array = vat_json_object_add (msg, "c");
6181       vat_json_init_array (counter_array);
6182       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6183         {
6184           counter = vat_json_array_add (counter_array);
6185           vat_json_init_object (counter);
6186           c4 = &vam->ip4_fib_counters[i][j];
6187           vat_json_object_add_ip4 (counter, "address", c4->address);
6188           vat_json_object_add_uint (counter, "address_length",
6189                                     c4->address_length);
6190           vat_json_object_add_uint (counter, "packets", c4->packets);
6191           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6192         }
6193     }
6194
6195   /* ip6 fib counters */
6196   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6197   vat_json_init_array (msg_array);
6198   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6199     {
6200       msg = vat_json_array_add (msg_array);
6201       vat_json_init_object (msg);
6202       vat_json_object_add_uint (msg, "vrf_id",
6203                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6204       counter_array = vat_json_object_add (msg, "c");
6205       vat_json_init_array (counter_array);
6206       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6207         {
6208           counter = vat_json_array_add (counter_array);
6209           vat_json_init_object (counter);
6210           c6 = &vam->ip6_fib_counters[i][j];
6211           vat_json_object_add_ip6 (counter, "address", c6->address);
6212           vat_json_object_add_uint (counter, "address_length",
6213                                     c6->address_length);
6214           vat_json_object_add_uint (counter, "packets", c6->packets);
6215           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6216         }
6217     }
6218
6219   /* ip4 nbr counters */
6220   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6221   vat_json_init_array (msg_array);
6222   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6223     {
6224       msg = vat_json_array_add (msg_array);
6225       vat_json_init_object (msg);
6226       vat_json_object_add_uint (msg, "sw_if_index", i);
6227       counter_array = vat_json_object_add (msg, "c");
6228       vat_json_init_array (counter_array);
6229       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6230         {
6231           counter = vat_json_array_add (counter_array);
6232           vat_json_init_object (counter);
6233           n4 = &vam->ip4_nbr_counters[i][j];
6234           vat_json_object_add_ip4 (counter, "address", n4->address);
6235           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6236           vat_json_object_add_uint (counter, "packets", n4->packets);
6237           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6238         }
6239     }
6240
6241   /* ip6 nbr counters */
6242   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6243   vat_json_init_array (msg_array);
6244   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6245     {
6246       msg = vat_json_array_add (msg_array);
6247       vat_json_init_object (msg);
6248       vat_json_object_add_uint (msg, "sw_if_index", i);
6249       counter_array = vat_json_object_add (msg, "c");
6250       vat_json_init_array (counter_array);
6251       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6252         {
6253           counter = vat_json_array_add (counter_array);
6254           vat_json_init_object (counter);
6255           n6 = &vam->ip6_nbr_counters[i][j];
6256           vat_json_object_add_ip6 (counter, "address", n6->address);
6257           vat_json_object_add_uint (counter, "packets", n6->packets);
6258           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6259         }
6260     }
6261
6262   vat_json_print (vam->ofp, &node);
6263   vat_json_free (&node);
6264
6265   return 0;
6266 }
6267
6268 /*
6269  * Pass CLI buffers directly in the CLI_INBAND API message,
6270  * instead of an additional shared memory area.
6271  */
6272 static int
6273 exec_inband (vat_main_t * vam)
6274 {
6275   vl_api_cli_inband_t *mp;
6276   unformat_input_t *i = vam->input;
6277   int ret;
6278
6279   if (vec_len (i->buffer) == 0)
6280     return -1;
6281
6282   if (vam->exec_mode == 0 && unformat (i, "mode"))
6283     {
6284       vam->exec_mode = 1;
6285       return 0;
6286     }
6287   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6288     {
6289       vam->exec_mode = 0;
6290       return 0;
6291     }
6292
6293   /*
6294    * In order for the CLI command to work, it
6295    * must be a vector ending in \n, not a C-string ending
6296    * in \n\0.
6297    */
6298   u32 len = vec_len (vam->input->buffer);
6299   M2 (CLI_INBAND, mp, len);
6300   clib_memcpy (mp->cmd, vam->input->buffer, len);
6301   mp->length = htonl (len);
6302
6303   S (mp);
6304   W (ret);
6305   /* json responses may or may not include a useful reply... */
6306   if (vec_len (vam->cmd_reply))
6307     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6308   return ret;
6309 }
6310
6311 int
6312 exec (vat_main_t * vam)
6313 {
6314   return exec_inband (vam);
6315 }
6316
6317 static int
6318 api_create_loopback (vat_main_t * vam)
6319 {
6320   unformat_input_t *i = vam->input;
6321   vl_api_create_loopback_t *mp;
6322   vl_api_create_loopback_instance_t *mp_lbi;
6323   u8 mac_address[6];
6324   u8 mac_set = 0;
6325   u8 is_specified = 0;
6326   u32 user_instance = 0;
6327   int ret;
6328
6329   memset (mac_address, 0, sizeof (mac_address));
6330
6331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6332     {
6333       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6334         mac_set = 1;
6335       if (unformat (i, "instance %d", &user_instance))
6336         is_specified = 1;
6337       else
6338         break;
6339     }
6340
6341   if (is_specified)
6342     {
6343       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6344       mp_lbi->is_specified = is_specified;
6345       if (is_specified)
6346         mp_lbi->user_instance = htonl (user_instance);
6347       if (mac_set)
6348         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6349       S (mp_lbi);
6350     }
6351   else
6352     {
6353       /* Construct the API message */
6354       M (CREATE_LOOPBACK, mp);
6355       if (mac_set)
6356         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6357       S (mp);
6358     }
6359
6360   W (ret);
6361   return ret;
6362 }
6363
6364 static int
6365 api_delete_loopback (vat_main_t * vam)
6366 {
6367   unformat_input_t *i = vam->input;
6368   vl_api_delete_loopback_t *mp;
6369   u32 sw_if_index = ~0;
6370   int ret;
6371
6372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6373     {
6374       if (unformat (i, "sw_if_index %d", &sw_if_index))
6375         ;
6376       else
6377         break;
6378     }
6379
6380   if (sw_if_index == ~0)
6381     {
6382       errmsg ("missing sw_if_index");
6383       return -99;
6384     }
6385
6386   /* Construct the API message */
6387   M (DELETE_LOOPBACK, mp);
6388   mp->sw_if_index = ntohl (sw_if_index);
6389
6390   S (mp);
6391   W (ret);
6392   return ret;
6393 }
6394
6395 static int
6396 api_want_stats (vat_main_t * vam)
6397 {
6398   unformat_input_t *i = vam->input;
6399   vl_api_want_stats_t *mp;
6400   int enable = -1;
6401   int ret;
6402
6403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6404     {
6405       if (unformat (i, "enable"))
6406         enable = 1;
6407       else if (unformat (i, "disable"))
6408         enable = 0;
6409       else
6410         break;
6411     }
6412
6413   if (enable == -1)
6414     {
6415       errmsg ("missing enable|disable");
6416       return -99;
6417     }
6418
6419   M (WANT_STATS, mp);
6420   mp->enable_disable = enable;
6421
6422   S (mp);
6423   W (ret);
6424   return ret;
6425 }
6426
6427 static int
6428 api_want_interface_events (vat_main_t * vam)
6429 {
6430   unformat_input_t *i = vam->input;
6431   vl_api_want_interface_events_t *mp;
6432   int enable = -1;
6433   int ret;
6434
6435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6436     {
6437       if (unformat (i, "enable"))
6438         enable = 1;
6439       else if (unformat (i, "disable"))
6440         enable = 0;
6441       else
6442         break;
6443     }
6444
6445   if (enable == -1)
6446     {
6447       errmsg ("missing enable|disable");
6448       return -99;
6449     }
6450
6451   M (WANT_INTERFACE_EVENTS, mp);
6452   mp->enable_disable = enable;
6453
6454   vam->interface_event_display = enable;
6455
6456   S (mp);
6457   W (ret);
6458   return ret;
6459 }
6460
6461
6462 /* Note: non-static, called once to set up the initial intfc table */
6463 int
6464 api_sw_interface_dump (vat_main_t * vam)
6465 {
6466   vl_api_sw_interface_dump_t *mp;
6467   vl_api_control_ping_t *mp_ping;
6468   hash_pair_t *p;
6469   name_sort_t *nses = 0, *ns;
6470   sw_interface_subif_t *sub = NULL;
6471   int ret;
6472
6473   /* Toss the old name table */
6474   /* *INDENT-OFF* */
6475   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6476   ({
6477     vec_add2 (nses, ns, 1);
6478     ns->name = (u8 *)(p->key);
6479     ns->value = (u32) p->value[0];
6480   }));
6481   /* *INDENT-ON* */
6482
6483   hash_free (vam->sw_if_index_by_interface_name);
6484
6485   vec_foreach (ns, nses) vec_free (ns->name);
6486
6487   vec_free (nses);
6488
6489   vec_foreach (sub, vam->sw_if_subif_table)
6490   {
6491     vec_free (sub->interface_name);
6492   }
6493   vec_free (vam->sw_if_subif_table);
6494
6495   /* recreate the interface name hash table */
6496   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6497
6498   /*
6499    * Ask for all interface names. Otherwise, the epic catalog of
6500    * name filters becomes ridiculously long, and vat ends up needing
6501    * to be taught about new interface types.
6502    */
6503   M (SW_INTERFACE_DUMP, mp);
6504   S (mp);
6505
6506   /* Use a control ping for synchronization */
6507   MPING (CONTROL_PING, mp_ping);
6508   S (mp_ping);
6509
6510   W (ret);
6511   return ret;
6512 }
6513
6514 static int
6515 api_sw_interface_set_flags (vat_main_t * vam)
6516 {
6517   unformat_input_t *i = vam->input;
6518   vl_api_sw_interface_set_flags_t *mp;
6519   u32 sw_if_index;
6520   u8 sw_if_index_set = 0;
6521   u8 admin_up = 0;
6522   int ret;
6523
6524   /* Parse args required to build the message */
6525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6526     {
6527       if (unformat (i, "admin-up"))
6528         admin_up = 1;
6529       else if (unformat (i, "admin-down"))
6530         admin_up = 0;
6531       else
6532         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6533         sw_if_index_set = 1;
6534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6535         sw_if_index_set = 1;
6536       else
6537         break;
6538     }
6539
6540   if (sw_if_index_set == 0)
6541     {
6542       errmsg ("missing interface name or sw_if_index");
6543       return -99;
6544     }
6545
6546   /* Construct the API message */
6547   M (SW_INTERFACE_SET_FLAGS, mp);
6548   mp->sw_if_index = ntohl (sw_if_index);
6549   mp->admin_up_down = admin_up;
6550
6551   /* send it... */
6552   S (mp);
6553
6554   /* Wait for a reply, return the good/bad news... */
6555   W (ret);
6556   return ret;
6557 }
6558
6559 static int
6560 api_sw_interface_set_rx_mode (vat_main_t * vam)
6561 {
6562   unformat_input_t *i = vam->input;
6563   vl_api_sw_interface_set_rx_mode_t *mp;
6564   u32 sw_if_index;
6565   u8 sw_if_index_set = 0;
6566   int ret;
6567   u8 queue_id_valid = 0;
6568   u32 queue_id;
6569   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6570
6571   /* Parse args required to build the message */
6572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6573     {
6574       if (unformat (i, "queue %d", &queue_id))
6575         queue_id_valid = 1;
6576       else if (unformat (i, "polling"))
6577         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6578       else if (unformat (i, "interrupt"))
6579         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6580       else if (unformat (i, "adaptive"))
6581         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6582       else
6583         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6584         sw_if_index_set = 1;
6585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6586         sw_if_index_set = 1;
6587       else
6588         break;
6589     }
6590
6591   if (sw_if_index_set == 0)
6592     {
6593       errmsg ("missing interface name or sw_if_index");
6594       return -99;
6595     }
6596   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6597     {
6598       errmsg ("missing rx-mode");
6599       return -99;
6600     }
6601
6602   /* Construct the API message */
6603   M (SW_INTERFACE_SET_RX_MODE, mp);
6604   mp->sw_if_index = ntohl (sw_if_index);
6605   mp->mode = mode;
6606   mp->queue_id_valid = queue_id_valid;
6607   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6608
6609   /* send it... */
6610   S (mp);
6611
6612   /* Wait for a reply, return the good/bad news... */
6613   W (ret);
6614   return ret;
6615 }
6616
6617 static int
6618 api_sw_interface_clear_stats (vat_main_t * vam)
6619 {
6620   unformat_input_t *i = vam->input;
6621   vl_api_sw_interface_clear_stats_t *mp;
6622   u32 sw_if_index;
6623   u8 sw_if_index_set = 0;
6624   int ret;
6625
6626   /* Parse args required to build the message */
6627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6628     {
6629       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6630         sw_if_index_set = 1;
6631       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6632         sw_if_index_set = 1;
6633       else
6634         break;
6635     }
6636
6637   /* Construct the API message */
6638   M (SW_INTERFACE_CLEAR_STATS, mp);
6639
6640   if (sw_if_index_set == 1)
6641     mp->sw_if_index = ntohl (sw_if_index);
6642   else
6643     mp->sw_if_index = ~0;
6644
6645   /* send it... */
6646   S (mp);
6647
6648   /* Wait for a reply, return the good/bad news... */
6649   W (ret);
6650   return ret;
6651 }
6652
6653 static int
6654 api_sw_interface_add_del_address (vat_main_t * vam)
6655 {
6656   unformat_input_t *i = vam->input;
6657   vl_api_sw_interface_add_del_address_t *mp;
6658   u32 sw_if_index;
6659   u8 sw_if_index_set = 0;
6660   u8 is_add = 1, del_all = 0;
6661   u32 address_length = 0;
6662   u8 v4_address_set = 0;
6663   u8 v6_address_set = 0;
6664   ip4_address_t v4address;
6665   ip6_address_t v6address;
6666   int ret;
6667
6668   /* Parse args required to build the message */
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "del-all"))
6672         del_all = 1;
6673       else if (unformat (i, "del"))
6674         is_add = 0;
6675       else
6676         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6677         sw_if_index_set = 1;
6678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6679         sw_if_index_set = 1;
6680       else if (unformat (i, "%U/%d",
6681                          unformat_ip4_address, &v4address, &address_length))
6682         v4_address_set = 1;
6683       else if (unformat (i, "%U/%d",
6684                          unformat_ip6_address, &v6address, &address_length))
6685         v6_address_set = 1;
6686       else
6687         break;
6688     }
6689
6690   if (sw_if_index_set == 0)
6691     {
6692       errmsg ("missing interface name or sw_if_index");
6693       return -99;
6694     }
6695   if (v4_address_set && v6_address_set)
6696     {
6697       errmsg ("both v4 and v6 addresses set");
6698       return -99;
6699     }
6700   if (!v4_address_set && !v6_address_set && !del_all)
6701     {
6702       errmsg ("no addresses set");
6703       return -99;
6704     }
6705
6706   /* Construct the API message */
6707   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6708
6709   mp->sw_if_index = ntohl (sw_if_index);
6710   mp->is_add = is_add;
6711   mp->del_all = del_all;
6712   if (v6_address_set)
6713     {
6714       mp->is_ipv6 = 1;
6715       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6716     }
6717   else
6718     {
6719       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6720     }
6721   mp->address_length = address_length;
6722
6723   /* send it... */
6724   S (mp);
6725
6726   /* Wait for a reply, return good/bad news  */
6727   W (ret);
6728   return ret;
6729 }
6730
6731 static int
6732 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6733 {
6734   unformat_input_t *i = vam->input;
6735   vl_api_sw_interface_set_mpls_enable_t *mp;
6736   u32 sw_if_index;
6737   u8 sw_if_index_set = 0;
6738   u8 enable = 1;
6739   int ret;
6740
6741   /* Parse args required to build the message */
6742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6743     {
6744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6745         sw_if_index_set = 1;
6746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6747         sw_if_index_set = 1;
6748       else if (unformat (i, "disable"))
6749         enable = 0;
6750       else if (unformat (i, "dis"))
6751         enable = 0;
6752       else
6753         break;
6754     }
6755
6756   if (sw_if_index_set == 0)
6757     {
6758       errmsg ("missing interface name or sw_if_index");
6759       return -99;
6760     }
6761
6762   /* Construct the API message */
6763   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6764
6765   mp->sw_if_index = ntohl (sw_if_index);
6766   mp->enable = enable;
6767
6768   /* send it... */
6769   S (mp);
6770
6771   /* Wait for a reply... */
6772   W (ret);
6773   return ret;
6774 }
6775
6776 static int
6777 api_sw_interface_set_table (vat_main_t * vam)
6778 {
6779   unformat_input_t *i = vam->input;
6780   vl_api_sw_interface_set_table_t *mp;
6781   u32 sw_if_index, vrf_id = 0;
6782   u8 sw_if_index_set = 0;
6783   u8 is_ipv6 = 0;
6784   int ret;
6785
6786   /* Parse args required to build the message */
6787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6788     {
6789       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6790         sw_if_index_set = 1;
6791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6792         sw_if_index_set = 1;
6793       else if (unformat (i, "vrf %d", &vrf_id))
6794         ;
6795       else if (unformat (i, "ipv6"))
6796         is_ipv6 = 1;
6797       else
6798         break;
6799     }
6800
6801   if (sw_if_index_set == 0)
6802     {
6803       errmsg ("missing interface name or sw_if_index");
6804       return -99;
6805     }
6806
6807   /* Construct the API message */
6808   M (SW_INTERFACE_SET_TABLE, mp);
6809
6810   mp->sw_if_index = ntohl (sw_if_index);
6811   mp->is_ipv6 = is_ipv6;
6812   mp->vrf_id = ntohl (vrf_id);
6813
6814   /* send it... */
6815   S (mp);
6816
6817   /* Wait for a reply... */
6818   W (ret);
6819   return ret;
6820 }
6821
6822 static void vl_api_sw_interface_get_table_reply_t_handler
6823   (vl_api_sw_interface_get_table_reply_t * mp)
6824 {
6825   vat_main_t *vam = &vat_main;
6826
6827   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6828
6829   vam->retval = ntohl (mp->retval);
6830   vam->result_ready = 1;
6831
6832 }
6833
6834 static void vl_api_sw_interface_get_table_reply_t_handler_json
6835   (vl_api_sw_interface_get_table_reply_t * mp)
6836 {
6837   vat_main_t *vam = &vat_main;
6838   vat_json_node_t node;
6839
6840   vat_json_init_object (&node);
6841   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6842   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6843
6844   vat_json_print (vam->ofp, &node);
6845   vat_json_free (&node);
6846
6847   vam->retval = ntohl (mp->retval);
6848   vam->result_ready = 1;
6849 }
6850
6851 static int
6852 api_sw_interface_get_table (vat_main_t * vam)
6853 {
6854   unformat_input_t *i = vam->input;
6855   vl_api_sw_interface_get_table_t *mp;
6856   u32 sw_if_index;
6857   u8 sw_if_index_set = 0;
6858   u8 is_ipv6 = 0;
6859   int ret;
6860
6861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6862     {
6863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6864         sw_if_index_set = 1;
6865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6866         sw_if_index_set = 1;
6867       else if (unformat (i, "ipv6"))
6868         is_ipv6 = 1;
6869       else
6870         break;
6871     }
6872
6873   if (sw_if_index_set == 0)
6874     {
6875       errmsg ("missing interface name or sw_if_index");
6876       return -99;
6877     }
6878
6879   M (SW_INTERFACE_GET_TABLE, mp);
6880   mp->sw_if_index = htonl (sw_if_index);
6881   mp->is_ipv6 = is_ipv6;
6882
6883   S (mp);
6884   W (ret);
6885   return ret;
6886 }
6887
6888 static int
6889 api_sw_interface_set_vpath (vat_main_t * vam)
6890 {
6891   unformat_input_t *i = vam->input;
6892   vl_api_sw_interface_set_vpath_t *mp;
6893   u32 sw_if_index = 0;
6894   u8 sw_if_index_set = 0;
6895   u8 is_enable = 0;
6896   int ret;
6897
6898   /* Parse args required to build the message */
6899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6900     {
6901       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6902         sw_if_index_set = 1;
6903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6904         sw_if_index_set = 1;
6905       else if (unformat (i, "enable"))
6906         is_enable = 1;
6907       else if (unformat (i, "disable"))
6908         is_enable = 0;
6909       else
6910         break;
6911     }
6912
6913   if (sw_if_index_set == 0)
6914     {
6915       errmsg ("missing interface name or sw_if_index");
6916       return -99;
6917     }
6918
6919   /* Construct the API message */
6920   M (SW_INTERFACE_SET_VPATH, mp);
6921
6922   mp->sw_if_index = ntohl (sw_if_index);
6923   mp->enable = is_enable;
6924
6925   /* send it... */
6926   S (mp);
6927
6928   /* Wait for a reply... */
6929   W (ret);
6930   return ret;
6931 }
6932
6933 static int
6934 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6935 {
6936   unformat_input_t *i = vam->input;
6937   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6938   u32 sw_if_index = 0;
6939   u8 sw_if_index_set = 0;
6940   u8 is_enable = 1;
6941   u8 is_ipv6 = 0;
6942   int ret;
6943
6944   /* Parse args required to build the message */
6945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6946     {
6947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6948         sw_if_index_set = 1;
6949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6950         sw_if_index_set = 1;
6951       else if (unformat (i, "enable"))
6952         is_enable = 1;
6953       else if (unformat (i, "disable"))
6954         is_enable = 0;
6955       else if (unformat (i, "ip4"))
6956         is_ipv6 = 0;
6957       else if (unformat (i, "ip6"))
6958         is_ipv6 = 1;
6959       else
6960         break;
6961     }
6962
6963   if (sw_if_index_set == 0)
6964     {
6965       errmsg ("missing interface name or sw_if_index");
6966       return -99;
6967     }
6968
6969   /* Construct the API message */
6970   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6971
6972   mp->sw_if_index = ntohl (sw_if_index);
6973   mp->enable = is_enable;
6974   mp->is_ipv6 = is_ipv6;
6975
6976   /* send it... */
6977   S (mp);
6978
6979   /* Wait for a reply... */
6980   W (ret);
6981   return ret;
6982 }
6983
6984 static int
6985 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6986 {
6987   unformat_input_t *i = vam->input;
6988   vl_api_sw_interface_set_geneve_bypass_t *mp;
6989   u32 sw_if_index = 0;
6990   u8 sw_if_index_set = 0;
6991   u8 is_enable = 1;
6992   u8 is_ipv6 = 0;
6993   int ret;
6994
6995   /* Parse args required to build the message */
6996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6997     {
6998       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6999         sw_if_index_set = 1;
7000       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7001         sw_if_index_set = 1;
7002       else if (unformat (i, "enable"))
7003         is_enable = 1;
7004       else if (unformat (i, "disable"))
7005         is_enable = 0;
7006       else if (unformat (i, "ip4"))
7007         is_ipv6 = 0;
7008       else if (unformat (i, "ip6"))
7009         is_ipv6 = 1;
7010       else
7011         break;
7012     }
7013
7014   if (sw_if_index_set == 0)
7015     {
7016       errmsg ("missing interface name or sw_if_index");
7017       return -99;
7018     }
7019
7020   /* Construct the API message */
7021   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7022
7023   mp->sw_if_index = ntohl (sw_if_index);
7024   mp->enable = is_enable;
7025   mp->is_ipv6 = is_ipv6;
7026
7027   /* send it... */
7028   S (mp);
7029
7030   /* Wait for a reply... */
7031   W (ret);
7032   return ret;
7033 }
7034
7035 static int
7036 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7037 {
7038   unformat_input_t *i = vam->input;
7039   vl_api_sw_interface_set_l2_xconnect_t *mp;
7040   u32 rx_sw_if_index;
7041   u8 rx_sw_if_index_set = 0;
7042   u32 tx_sw_if_index;
7043   u8 tx_sw_if_index_set = 0;
7044   u8 enable = 1;
7045   int ret;
7046
7047   /* Parse args required to build the message */
7048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7049     {
7050       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7051         rx_sw_if_index_set = 1;
7052       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7053         tx_sw_if_index_set = 1;
7054       else if (unformat (i, "rx"))
7055         {
7056           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7057             {
7058               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7059                             &rx_sw_if_index))
7060                 rx_sw_if_index_set = 1;
7061             }
7062           else
7063             break;
7064         }
7065       else if (unformat (i, "tx"))
7066         {
7067           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7068             {
7069               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7070                             &tx_sw_if_index))
7071                 tx_sw_if_index_set = 1;
7072             }
7073           else
7074             break;
7075         }
7076       else if (unformat (i, "enable"))
7077         enable = 1;
7078       else if (unformat (i, "disable"))
7079         enable = 0;
7080       else
7081         break;
7082     }
7083
7084   if (rx_sw_if_index_set == 0)
7085     {
7086       errmsg ("missing rx interface name or rx_sw_if_index");
7087       return -99;
7088     }
7089
7090   if (enable && (tx_sw_if_index_set == 0))
7091     {
7092       errmsg ("missing tx interface name or tx_sw_if_index");
7093       return -99;
7094     }
7095
7096   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7097
7098   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7099   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7100   mp->enable = enable;
7101
7102   S (mp);
7103   W (ret);
7104   return ret;
7105 }
7106
7107 static int
7108 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7109 {
7110   unformat_input_t *i = vam->input;
7111   vl_api_sw_interface_set_l2_bridge_t *mp;
7112   u32 rx_sw_if_index;
7113   u8 rx_sw_if_index_set = 0;
7114   u32 bd_id;
7115   u8 bd_id_set = 0;
7116   u8 bvi = 0;
7117   u32 shg = 0;
7118   u8 enable = 1;
7119   int ret;
7120
7121   /* Parse args required to build the message */
7122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7123     {
7124       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7125         rx_sw_if_index_set = 1;
7126       else if (unformat (i, "bd_id %d", &bd_id))
7127         bd_id_set = 1;
7128       else
7129         if (unformat
7130             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7131         rx_sw_if_index_set = 1;
7132       else if (unformat (i, "shg %d", &shg))
7133         ;
7134       else if (unformat (i, "bvi"))
7135         bvi = 1;
7136       else if (unformat (i, "enable"))
7137         enable = 1;
7138       else if (unformat (i, "disable"))
7139         enable = 0;
7140       else
7141         break;
7142     }
7143
7144   if (rx_sw_if_index_set == 0)
7145     {
7146       errmsg ("missing rx interface name or sw_if_index");
7147       return -99;
7148     }
7149
7150   if (enable && (bd_id_set == 0))
7151     {
7152       errmsg ("missing bridge domain");
7153       return -99;
7154     }
7155
7156   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7157
7158   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7159   mp->bd_id = ntohl (bd_id);
7160   mp->shg = (u8) shg;
7161   mp->bvi = bvi;
7162   mp->enable = enable;
7163
7164   S (mp);
7165   W (ret);
7166   return ret;
7167 }
7168
7169 static int
7170 api_bridge_domain_dump (vat_main_t * vam)
7171 {
7172   unformat_input_t *i = vam->input;
7173   vl_api_bridge_domain_dump_t *mp;
7174   vl_api_control_ping_t *mp_ping;
7175   u32 bd_id = ~0;
7176   int ret;
7177
7178   /* Parse args required to build the message */
7179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7180     {
7181       if (unformat (i, "bd_id %d", &bd_id))
7182         ;
7183       else
7184         break;
7185     }
7186
7187   M (BRIDGE_DOMAIN_DUMP, mp);
7188   mp->bd_id = ntohl (bd_id);
7189   S (mp);
7190
7191   /* Use a control ping for synchronization */
7192   MPING (CONTROL_PING, mp_ping);
7193   S (mp_ping);
7194
7195   W (ret);
7196   return ret;
7197 }
7198
7199 static int
7200 api_bridge_domain_add_del (vat_main_t * vam)
7201 {
7202   unformat_input_t *i = vam->input;
7203   vl_api_bridge_domain_add_del_t *mp;
7204   u32 bd_id = ~0;
7205   u8 is_add = 1;
7206   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7207   u8 *bd_tag = NULL;
7208   u32 mac_age = 0;
7209   int ret;
7210
7211   /* Parse args required to build the message */
7212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7213     {
7214       if (unformat (i, "bd_id %d", &bd_id))
7215         ;
7216       else if (unformat (i, "flood %d", &flood))
7217         ;
7218       else if (unformat (i, "uu-flood %d", &uu_flood))
7219         ;
7220       else if (unformat (i, "forward %d", &forward))
7221         ;
7222       else if (unformat (i, "learn %d", &learn))
7223         ;
7224       else if (unformat (i, "arp-term %d", &arp_term))
7225         ;
7226       else if (unformat (i, "mac-age %d", &mac_age))
7227         ;
7228       else if (unformat (i, "bd-tag %s", &bd_tag))
7229         ;
7230       else if (unformat (i, "del"))
7231         {
7232           is_add = 0;
7233           flood = uu_flood = forward = learn = 0;
7234         }
7235       else
7236         break;
7237     }
7238
7239   if (bd_id == ~0)
7240     {
7241       errmsg ("missing bridge domain");
7242       ret = -99;
7243       goto done;
7244     }
7245
7246   if (mac_age > 255)
7247     {
7248       errmsg ("mac age must be less than 256 ");
7249       ret = -99;
7250       goto done;
7251     }
7252
7253   if ((bd_tag) && (vec_len (bd_tag) > 63))
7254     {
7255       errmsg ("bd-tag cannot be longer than 63");
7256       ret = -99;
7257       goto done;
7258     }
7259
7260   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7261
7262   mp->bd_id = ntohl (bd_id);
7263   mp->flood = flood;
7264   mp->uu_flood = uu_flood;
7265   mp->forward = forward;
7266   mp->learn = learn;
7267   mp->arp_term = arp_term;
7268   mp->is_add = is_add;
7269   mp->mac_age = (u8) mac_age;
7270   if (bd_tag)
7271     {
7272       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7273       mp->bd_tag[vec_len (bd_tag)] = 0;
7274     }
7275   S (mp);
7276   W (ret);
7277
7278 done:
7279   vec_free (bd_tag);
7280   return ret;
7281 }
7282
7283 static int
7284 api_l2fib_flush_bd (vat_main_t * vam)
7285 {
7286   unformat_input_t *i = vam->input;
7287   vl_api_l2fib_flush_bd_t *mp;
7288   u32 bd_id = ~0;
7289   int ret;
7290
7291   /* Parse args required to build the message */
7292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7293     {
7294       if (unformat (i, "bd_id %d", &bd_id));
7295       else
7296         break;
7297     }
7298
7299   if (bd_id == ~0)
7300     {
7301       errmsg ("missing bridge domain");
7302       return -99;
7303     }
7304
7305   M (L2FIB_FLUSH_BD, mp);
7306
7307   mp->bd_id = htonl (bd_id);
7308
7309   S (mp);
7310   W (ret);
7311   return ret;
7312 }
7313
7314 static int
7315 api_l2fib_flush_int (vat_main_t * vam)
7316 {
7317   unformat_input_t *i = vam->input;
7318   vl_api_l2fib_flush_int_t *mp;
7319   u32 sw_if_index = ~0;
7320   int ret;
7321
7322   /* Parse args required to build the message */
7323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7324     {
7325       if (unformat (i, "sw_if_index %d", &sw_if_index));
7326       else
7327         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7328       else
7329         break;
7330     }
7331
7332   if (sw_if_index == ~0)
7333     {
7334       errmsg ("missing interface name or sw_if_index");
7335       return -99;
7336     }
7337
7338   M (L2FIB_FLUSH_INT, mp);
7339
7340   mp->sw_if_index = ntohl (sw_if_index);
7341
7342   S (mp);
7343   W (ret);
7344   return ret;
7345 }
7346
7347 static int
7348 api_l2fib_add_del (vat_main_t * vam)
7349 {
7350   unformat_input_t *i = vam->input;
7351   vl_api_l2fib_add_del_t *mp;
7352   f64 timeout;
7353   u8 mac[6] = { 0 };
7354   u8 mac_set = 0;
7355   u32 bd_id;
7356   u8 bd_id_set = 0;
7357   u32 sw_if_index = ~0;
7358   u8 sw_if_index_set = 0;
7359   u8 is_add = 1;
7360   u8 static_mac = 0;
7361   u8 filter_mac = 0;
7362   u8 bvi_mac = 0;
7363   int count = 1;
7364   f64 before = 0;
7365   int j;
7366
7367   /* Parse args required to build the message */
7368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7369     {
7370       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7371         mac_set = 1;
7372       else if (unformat (i, "bd_id %d", &bd_id))
7373         bd_id_set = 1;
7374       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7375         sw_if_index_set = 1;
7376       else if (unformat (i, "sw_if"))
7377         {
7378           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7379             {
7380               if (unformat
7381                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7382                 sw_if_index_set = 1;
7383             }
7384           else
7385             break;
7386         }
7387       else if (unformat (i, "static"))
7388         static_mac = 1;
7389       else if (unformat (i, "filter"))
7390         {
7391           filter_mac = 1;
7392           static_mac = 1;
7393         }
7394       else if (unformat (i, "bvi"))
7395         {
7396           bvi_mac = 1;
7397           static_mac = 1;
7398         }
7399       else if (unformat (i, "del"))
7400         is_add = 0;
7401       else if (unformat (i, "count %d", &count))
7402         ;
7403       else
7404         break;
7405     }
7406
7407   if (mac_set == 0)
7408     {
7409       errmsg ("missing mac address");
7410       return -99;
7411     }
7412
7413   if (bd_id_set == 0)
7414     {
7415       errmsg ("missing bridge domain");
7416       return -99;
7417     }
7418
7419   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7420     {
7421       errmsg ("missing interface name or sw_if_index");
7422       return -99;
7423     }
7424
7425   if (count > 1)
7426     {
7427       /* Turn on async mode */
7428       vam->async_mode = 1;
7429       vam->async_errors = 0;
7430       before = vat_time_now (vam);
7431     }
7432
7433   for (j = 0; j < count; j++)
7434     {
7435       M (L2FIB_ADD_DEL, mp);
7436
7437       clib_memcpy (mp->mac, mac, 6);
7438       mp->bd_id = ntohl (bd_id);
7439       mp->is_add = is_add;
7440
7441       if (is_add)
7442         {
7443           mp->sw_if_index = ntohl (sw_if_index);
7444           mp->static_mac = static_mac;
7445           mp->filter_mac = filter_mac;
7446           mp->bvi_mac = bvi_mac;
7447         }
7448       increment_mac_address (mac);
7449       /* send it... */
7450       S (mp);
7451     }
7452
7453   if (count > 1)
7454     {
7455       vl_api_control_ping_t *mp_ping;
7456       f64 after;
7457
7458       /* Shut off async mode */
7459       vam->async_mode = 0;
7460
7461       MPING (CONTROL_PING, mp_ping);
7462       S (mp_ping);
7463
7464       timeout = vat_time_now (vam) + 1.0;
7465       while (vat_time_now (vam) < timeout)
7466         if (vam->result_ready == 1)
7467           goto out;
7468       vam->retval = -99;
7469
7470     out:
7471       if (vam->retval == -99)
7472         errmsg ("timeout");
7473
7474       if (vam->async_errors > 0)
7475         {
7476           errmsg ("%d asynchronous errors", vam->async_errors);
7477           vam->retval = -98;
7478         }
7479       vam->async_errors = 0;
7480       after = vat_time_now (vam);
7481
7482       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7483              count, after - before, count / (after - before));
7484     }
7485   else
7486     {
7487       int ret;
7488
7489       /* Wait for a reply... */
7490       W (ret);
7491       return ret;
7492     }
7493   /* Return the good/bad news */
7494   return (vam->retval);
7495 }
7496
7497 static int
7498 api_bridge_domain_set_mac_age (vat_main_t * vam)
7499 {
7500   unformat_input_t *i = vam->input;
7501   vl_api_bridge_domain_set_mac_age_t *mp;
7502   u32 bd_id = ~0;
7503   u32 mac_age = 0;
7504   int ret;
7505
7506   /* Parse args required to build the message */
7507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7508     {
7509       if (unformat (i, "bd_id %d", &bd_id));
7510       else if (unformat (i, "mac-age %d", &mac_age));
7511       else
7512         break;
7513     }
7514
7515   if (bd_id == ~0)
7516     {
7517       errmsg ("missing bridge domain");
7518       return -99;
7519     }
7520
7521   if (mac_age > 255)
7522     {
7523       errmsg ("mac age must be less than 256 ");
7524       return -99;
7525     }
7526
7527   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7528
7529   mp->bd_id = htonl (bd_id);
7530   mp->mac_age = (u8) mac_age;
7531
7532   S (mp);
7533   W (ret);
7534   return ret;
7535 }
7536
7537 static int
7538 api_l2_flags (vat_main_t * vam)
7539 {
7540   unformat_input_t *i = vam->input;
7541   vl_api_l2_flags_t *mp;
7542   u32 sw_if_index;
7543   u32 flags = 0;
7544   u8 sw_if_index_set = 0;
7545   u8 is_set = 0;
7546   int ret;
7547
7548   /* Parse args required to build the message */
7549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7550     {
7551       if (unformat (i, "sw_if_index %d", &sw_if_index))
7552         sw_if_index_set = 1;
7553       else if (unformat (i, "sw_if"))
7554         {
7555           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7556             {
7557               if (unformat
7558                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7559                 sw_if_index_set = 1;
7560             }
7561           else
7562             break;
7563         }
7564       else if (unformat (i, "learn"))
7565         flags |= L2_LEARN;
7566       else if (unformat (i, "forward"))
7567         flags |= L2_FWD;
7568       else if (unformat (i, "flood"))
7569         flags |= L2_FLOOD;
7570       else if (unformat (i, "uu-flood"))
7571         flags |= L2_UU_FLOOD;
7572       else if (unformat (i, "arp-term"))
7573         flags |= L2_ARP_TERM;
7574       else if (unformat (i, "off"))
7575         is_set = 0;
7576       else if (unformat (i, "disable"))
7577         is_set = 0;
7578       else
7579         break;
7580     }
7581
7582   if (sw_if_index_set == 0)
7583     {
7584       errmsg ("missing interface name or sw_if_index");
7585       return -99;
7586     }
7587
7588   M (L2_FLAGS, mp);
7589
7590   mp->sw_if_index = ntohl (sw_if_index);
7591   mp->feature_bitmap = ntohl (flags);
7592   mp->is_set = is_set;
7593
7594   S (mp);
7595   W (ret);
7596   return ret;
7597 }
7598
7599 static int
7600 api_bridge_flags (vat_main_t * vam)
7601 {
7602   unformat_input_t *i = vam->input;
7603   vl_api_bridge_flags_t *mp;
7604   u32 bd_id;
7605   u8 bd_id_set = 0;
7606   u8 is_set = 1;
7607   u32 flags = 0;
7608   int ret;
7609
7610   /* Parse args required to build the message */
7611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7612     {
7613       if (unformat (i, "bd_id %d", &bd_id))
7614         bd_id_set = 1;
7615       else if (unformat (i, "learn"))
7616         flags |= L2_LEARN;
7617       else if (unformat (i, "forward"))
7618         flags |= L2_FWD;
7619       else if (unformat (i, "flood"))
7620         flags |= L2_FLOOD;
7621       else if (unformat (i, "uu-flood"))
7622         flags |= L2_UU_FLOOD;
7623       else if (unformat (i, "arp-term"))
7624         flags |= L2_ARP_TERM;
7625       else if (unformat (i, "off"))
7626         is_set = 0;
7627       else if (unformat (i, "disable"))
7628         is_set = 0;
7629       else
7630         break;
7631     }
7632
7633   if (bd_id_set == 0)
7634     {
7635       errmsg ("missing bridge domain");
7636       return -99;
7637     }
7638
7639   M (BRIDGE_FLAGS, mp);
7640
7641   mp->bd_id = ntohl (bd_id);
7642   mp->feature_bitmap = ntohl (flags);
7643   mp->is_set = is_set;
7644
7645   S (mp);
7646   W (ret);
7647   return ret;
7648 }
7649
7650 static int
7651 api_bd_ip_mac_add_del (vat_main_t * vam)
7652 {
7653   unformat_input_t *i = vam->input;
7654   vl_api_bd_ip_mac_add_del_t *mp;
7655   u32 bd_id;
7656   u8 is_ipv6 = 0;
7657   u8 is_add = 1;
7658   u8 bd_id_set = 0;
7659   u8 ip_set = 0;
7660   u8 mac_set = 0;
7661   ip4_address_t v4addr;
7662   ip6_address_t v6addr;
7663   u8 macaddr[6];
7664   int ret;
7665
7666
7667   /* Parse args required to build the message */
7668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7669     {
7670       if (unformat (i, "bd_id %d", &bd_id))
7671         {
7672           bd_id_set++;
7673         }
7674       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7675         {
7676           ip_set++;
7677         }
7678       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7679         {
7680           ip_set++;
7681           is_ipv6++;
7682         }
7683       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7684         {
7685           mac_set++;
7686         }
7687       else if (unformat (i, "del"))
7688         is_add = 0;
7689       else
7690         break;
7691     }
7692
7693   if (bd_id_set == 0)
7694     {
7695       errmsg ("missing bridge domain");
7696       return -99;
7697     }
7698   else if (ip_set == 0)
7699     {
7700       errmsg ("missing IP address");
7701       return -99;
7702     }
7703   else if (mac_set == 0)
7704     {
7705       errmsg ("missing MAC address");
7706       return -99;
7707     }
7708
7709   M (BD_IP_MAC_ADD_DEL, mp);
7710
7711   mp->bd_id = ntohl (bd_id);
7712   mp->is_ipv6 = is_ipv6;
7713   mp->is_add = is_add;
7714   if (is_ipv6)
7715     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7716   else
7717     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7718   clib_memcpy (mp->mac_address, macaddr, 6);
7719   S (mp);
7720   W (ret);
7721   return ret;
7722 }
7723
7724 static int
7725 api_tap_connect (vat_main_t * vam)
7726 {
7727   unformat_input_t *i = vam->input;
7728   vl_api_tap_connect_t *mp;
7729   u8 mac_address[6];
7730   u8 random_mac = 1;
7731   u8 name_set = 0;
7732   u8 *tap_name;
7733   u8 *tag = 0;
7734   ip4_address_t ip4_address;
7735   u32 ip4_mask_width;
7736   int ip4_address_set = 0;
7737   ip6_address_t ip6_address;
7738   u32 ip6_mask_width;
7739   int ip6_address_set = 0;
7740   int ret;
7741
7742   memset (mac_address, 0, sizeof (mac_address));
7743
7744   /* Parse args required to build the message */
7745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7746     {
7747       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7748         {
7749           random_mac = 0;
7750         }
7751       else if (unformat (i, "random-mac"))
7752         random_mac = 1;
7753       else if (unformat (i, "tapname %s", &tap_name))
7754         name_set = 1;
7755       else if (unformat (i, "tag %s", &tag))
7756         ;
7757       else if (unformat (i, "address %U/%d",
7758                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7759         ip4_address_set = 1;
7760       else if (unformat (i, "address %U/%d",
7761                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7762         ip6_address_set = 1;
7763       else
7764         break;
7765     }
7766
7767   if (name_set == 0)
7768     {
7769       errmsg ("missing tap name");
7770       return -99;
7771     }
7772   if (vec_len (tap_name) > 63)
7773     {
7774       errmsg ("tap name too long");
7775       return -99;
7776     }
7777   vec_add1 (tap_name, 0);
7778
7779   if (vec_len (tag) > 63)
7780     {
7781       errmsg ("tag too long");
7782       return -99;
7783     }
7784
7785   /* Construct the API message */
7786   M (TAP_CONNECT, mp);
7787
7788   mp->use_random_mac = random_mac;
7789   clib_memcpy (mp->mac_address, mac_address, 6);
7790   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7791   if (tag)
7792     clib_memcpy (mp->tag, tag, vec_len (tag));
7793
7794   if (ip4_address_set)
7795     {
7796       mp->ip4_address_set = 1;
7797       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7798       mp->ip4_mask_width = ip4_mask_width;
7799     }
7800   if (ip6_address_set)
7801     {
7802       mp->ip6_address_set = 1;
7803       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7804       mp->ip6_mask_width = ip6_mask_width;
7805     }
7806
7807   vec_free (tap_name);
7808   vec_free (tag);
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_modify (vat_main_t * vam)
7820 {
7821   unformat_input_t *i = vam->input;
7822   vl_api_tap_modify_t *mp;
7823   u8 mac_address[6];
7824   u8 random_mac = 1;
7825   u8 name_set = 0;
7826   u8 *tap_name;
7827   u32 sw_if_index = ~0;
7828   u8 sw_if_index_set = 0;
7829   int ret;
7830
7831   memset (mac_address, 0, sizeof (mac_address));
7832
7833   /* Parse args required to build the message */
7834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7835     {
7836       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7837         sw_if_index_set = 1;
7838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7839         sw_if_index_set = 1;
7840       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7841         {
7842           random_mac = 0;
7843         }
7844       else if (unformat (i, "random-mac"))
7845         random_mac = 1;
7846       else if (unformat (i, "tapname %s", &tap_name))
7847         name_set = 1;
7848       else
7849         break;
7850     }
7851
7852   if (sw_if_index_set == 0)
7853     {
7854       errmsg ("missing vpp interface name");
7855       return -99;
7856     }
7857   if (name_set == 0)
7858     {
7859       errmsg ("missing tap name");
7860       return -99;
7861     }
7862   if (vec_len (tap_name) > 63)
7863     {
7864       errmsg ("tap name too long");
7865     }
7866   vec_add1 (tap_name, 0);
7867
7868   /* Construct the API message */
7869   M (TAP_MODIFY, mp);
7870
7871   mp->use_random_mac = random_mac;
7872   mp->sw_if_index = ntohl (sw_if_index);
7873   clib_memcpy (mp->mac_address, mac_address, 6);
7874   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7875   vec_free (tap_name);
7876
7877   /* send it... */
7878   S (mp);
7879
7880   /* Wait for a reply... */
7881   W (ret);
7882   return ret;
7883 }
7884
7885 static int
7886 api_tap_delete (vat_main_t * vam)
7887 {
7888   unformat_input_t *i = vam->input;
7889   vl_api_tap_delete_t *mp;
7890   u32 sw_if_index = ~0;
7891   u8 sw_if_index_set = 0;
7892   int ret;
7893
7894   /* Parse args required to build the message */
7895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7896     {
7897       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7898         sw_if_index_set = 1;
7899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7900         sw_if_index_set = 1;
7901       else
7902         break;
7903     }
7904
7905   if (sw_if_index_set == 0)
7906     {
7907       errmsg ("missing vpp interface name");
7908       return -99;
7909     }
7910
7911   /* Construct the API message */
7912   M (TAP_DELETE, mp);
7913
7914   mp->sw_if_index = ntohl (sw_if_index);
7915
7916   /* send it... */
7917   S (mp);
7918
7919   /* Wait for a reply... */
7920   W (ret);
7921   return ret;
7922 }
7923
7924 static int
7925 api_tap_create_v2 (vat_main_t * vam)
7926 {
7927   unformat_input_t *i = vam->input;
7928   vl_api_tap_create_v2_t *mp;
7929   u8 mac_address[6];
7930   u8 random_mac = 1;
7931   u32 id = ~0;
7932   u8 *host_if_name = 0;
7933   u8 *host_ns = 0;
7934   u8 host_mac_addr[6];
7935   u8 host_mac_addr_set = 0;
7936   u8 *host_bridge = 0;
7937   ip4_address_t host_ip4_addr;
7938   ip4_address_t host_ip4_gw;
7939   u8 host_ip4_gw_set = 0;
7940   u32 host_ip4_prefix_len = 0;
7941   ip6_address_t host_ip6_addr;
7942   ip6_address_t host_ip6_gw;
7943   u8 host_ip6_gw_set = 0;
7944   u32 host_ip6_prefix_len = 0;
7945   int ret;
7946   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7947
7948   memset (mac_address, 0, sizeof (mac_address));
7949
7950   /* Parse args required to build the message */
7951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7952     {
7953       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7954         {
7955           random_mac = 0;
7956         }
7957       else if (unformat (i, "id %u", &id))
7958         ;
7959       else if (unformat (i, "host-if-name %s", &host_if_name))
7960         ;
7961       else if (unformat (i, "host-ns %s", &host_ns))
7962         ;
7963       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7964                          host_mac_addr))
7965         host_mac_addr_set = 1;
7966       else if (unformat (i, "host-bridge %s", &host_bridge))
7967         ;
7968       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7969                          &host_ip4_addr, &host_ip4_prefix_len))
7970         ;
7971       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7972                          &host_ip6_addr, &host_ip6_prefix_len))
7973         ;
7974       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7975                          &host_ip4_gw))
7976         host_ip4_gw_set = 1;
7977       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7978                          &host_ip6_gw))
7979         host_ip6_gw_set = 1;
7980       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7981         ;
7982       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7983         ;
7984       else
7985         break;
7986     }
7987
7988   if (vec_len (host_if_name) > 63)
7989     {
7990       errmsg ("tap name too long. ");
7991       return -99;
7992     }
7993   if (vec_len (host_ns) > 63)
7994     {
7995       errmsg ("host name space too long. ");
7996       return -99;
7997     }
7998   if (vec_len (host_bridge) > 63)
7999     {
8000       errmsg ("host bridge name too long. ");
8001       return -99;
8002     }
8003   if (host_ip4_prefix_len > 32)
8004     {
8005       errmsg ("host ip4 prefix length not valid. ");
8006       return -99;
8007     }
8008   if (host_ip6_prefix_len > 128)
8009     {
8010       errmsg ("host ip6 prefix length not valid. ");
8011       return -99;
8012     }
8013   if (!is_pow2 (rx_ring_sz))
8014     {
8015       errmsg ("rx ring size must be power of 2. ");
8016       return -99;
8017     }
8018   if (rx_ring_sz > 32768)
8019     {
8020       errmsg ("rx ring size must be 32768 or lower. ");
8021       return -99;
8022     }
8023   if (!is_pow2 (tx_ring_sz))
8024     {
8025       errmsg ("tx ring size must be power of 2. ");
8026       return -99;
8027     }
8028   if (tx_ring_sz > 32768)
8029     {
8030       errmsg ("tx ring size must be 32768 or lower. ");
8031       return -99;
8032     }
8033
8034   /* Construct the API message */
8035   M (TAP_CREATE_V2, mp);
8036
8037   mp->use_random_mac = random_mac;
8038
8039   mp->id = ntohl (id);
8040   mp->host_namespace_set = host_ns != 0;
8041   mp->host_bridge_set = host_bridge != 0;
8042   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8043   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8044   mp->rx_ring_sz = ntohs (rx_ring_sz);
8045   mp->tx_ring_sz = ntohs (tx_ring_sz);
8046
8047   if (random_mac == 0)
8048     clib_memcpy (mp->mac_address, mac_address, 6);
8049   if (host_mac_addr_set)
8050     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8051   if (host_if_name)
8052     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8053   if (host_ns)
8054     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8055   if (host_bridge)
8056     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8057   if (host_ip4_prefix_len)
8058     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8059   if (host_ip4_prefix_len)
8060     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8061   if (host_ip4_gw_set)
8062     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8063   if (host_ip6_gw_set)
8064     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8065
8066   vec_free (host_ns);
8067   vec_free (host_if_name);
8068   vec_free (host_bridge);
8069
8070   /* send it... */
8071   S (mp);
8072
8073   /* Wait for a reply... */
8074   W (ret);
8075   return ret;
8076 }
8077
8078 static int
8079 api_tap_delete_v2 (vat_main_t * vam)
8080 {
8081   unformat_input_t *i = vam->input;
8082   vl_api_tap_delete_v2_t *mp;
8083   u32 sw_if_index = ~0;
8084   u8 sw_if_index_set = 0;
8085   int ret;
8086
8087   /* Parse args required to build the message */
8088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8089     {
8090       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8091         sw_if_index_set = 1;
8092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8093         sw_if_index_set = 1;
8094       else
8095         break;
8096     }
8097
8098   if (sw_if_index_set == 0)
8099     {
8100       errmsg ("missing vpp interface name. ");
8101       return -99;
8102     }
8103
8104   /* Construct the API message */
8105   M (TAP_DELETE_V2, mp);
8106
8107   mp->sw_if_index = ntohl (sw_if_index);
8108
8109   /* send it... */
8110   S (mp);
8111
8112   /* Wait for a reply... */
8113   W (ret);
8114   return ret;
8115 }
8116
8117 static int
8118 api_bond_create (vat_main_t * vam)
8119 {
8120   unformat_input_t *i = vam->input;
8121   vl_api_bond_create_t *mp;
8122   u8 mac_address[6];
8123   u8 custom_mac = 0;
8124   int ret;
8125   u8 mode;
8126   u8 lb;
8127   u8 mode_is_set = 0;
8128
8129   memset (mac_address, 0, sizeof (mac_address));
8130   lb = BOND_LB_L2;
8131
8132   /* Parse args required to build the message */
8133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8134     {
8135       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8136         mode_is_set = 1;
8137       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8138                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8139         ;
8140       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8141                          mac_address))
8142         custom_mac = 1;
8143       else
8144         break;
8145     }
8146
8147   if (mode_is_set == 0)
8148     {
8149       errmsg ("Missing bond mode. ");
8150       return -99;
8151     }
8152
8153   /* Construct the API message */
8154   M (BOND_CREATE, mp);
8155
8156   mp->use_custom_mac = custom_mac;
8157
8158   mp->mode = mode;
8159   mp->lb = lb;
8160
8161   if (custom_mac)
8162     clib_memcpy (mp->mac_address, mac_address, 6);
8163
8164   /* send it... */
8165   S (mp);
8166
8167   /* Wait for a reply... */
8168   W (ret);
8169   return ret;
8170 }
8171
8172 static int
8173 api_bond_delete (vat_main_t * vam)
8174 {
8175   unformat_input_t *i = vam->input;
8176   vl_api_bond_delete_t *mp;
8177   u32 sw_if_index = ~0;
8178   u8 sw_if_index_set = 0;
8179   int ret;
8180
8181   /* Parse args required to build the message */
8182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8183     {
8184       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8185         sw_if_index_set = 1;
8186       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8187         sw_if_index_set = 1;
8188       else
8189         break;
8190     }
8191
8192   if (sw_if_index_set == 0)
8193     {
8194       errmsg ("missing vpp interface name. ");
8195       return -99;
8196     }
8197
8198   /* Construct the API message */
8199   M (BOND_DELETE, mp);
8200
8201   mp->sw_if_index = ntohl (sw_if_index);
8202
8203   /* send it... */
8204   S (mp);
8205
8206   /* Wait for a reply... */
8207   W (ret);
8208   return ret;
8209 }
8210
8211 static int
8212 api_bond_enslave (vat_main_t * vam)
8213 {
8214   unformat_input_t *i = vam->input;
8215   vl_api_bond_enslave_t *mp;
8216   u32 bond_sw_if_index;
8217   int ret;
8218   u8 is_passive;
8219   u8 is_long_timeout;
8220   u32 bond_sw_if_index_is_set = 0;
8221   u32 sw_if_index;
8222   u8 sw_if_index_is_set = 0;
8223
8224   /* Parse args required to build the message */
8225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8226     {
8227       if (unformat (i, "sw_if_index %d", &sw_if_index))
8228         sw_if_index_is_set = 1;
8229       else if (unformat (i, "bond %u", &bond_sw_if_index))
8230         bond_sw_if_index_is_set = 1;
8231       else if (unformat (i, "passive %d", &is_passive))
8232         ;
8233       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8234         ;
8235       else
8236         break;
8237     }
8238
8239   if (bond_sw_if_index_is_set == 0)
8240     {
8241       errmsg ("Missing bond sw_if_index. ");
8242       return -99;
8243     }
8244   if (sw_if_index_is_set == 0)
8245     {
8246       errmsg ("Missing slave sw_if_index. ");
8247       return -99;
8248     }
8249
8250   /* Construct the API message */
8251   M (BOND_ENSLAVE, mp);
8252
8253   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8254   mp->sw_if_index = ntohl (sw_if_index);
8255   mp->is_long_timeout = is_long_timeout;
8256   mp->is_passive = is_passive;
8257
8258   /* send it... */
8259   S (mp);
8260
8261   /* Wait for a reply... */
8262   W (ret);
8263   return ret;
8264 }
8265
8266 static int
8267 api_bond_detach_slave (vat_main_t * vam)
8268 {
8269   unformat_input_t *i = vam->input;
8270   vl_api_bond_detach_slave_t *mp;
8271   u32 sw_if_index = ~0;
8272   u8 sw_if_index_set = 0;
8273   int ret;
8274
8275   /* Parse args required to build the message */
8276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8277     {
8278       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8279         sw_if_index_set = 1;
8280       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8281         sw_if_index_set = 1;
8282       else
8283         break;
8284     }
8285
8286   if (sw_if_index_set == 0)
8287     {
8288       errmsg ("missing vpp interface name. ");
8289       return -99;
8290     }
8291
8292   /* Construct the API message */
8293   M (BOND_DETACH_SLAVE, mp);
8294
8295   mp->sw_if_index = ntohl (sw_if_index);
8296
8297   /* send it... */
8298   S (mp);
8299
8300   /* Wait for a reply... */
8301   W (ret);
8302   return ret;
8303 }
8304
8305 static int
8306 api_ip_table_add_del (vat_main_t * vam)
8307 {
8308   unformat_input_t *i = vam->input;
8309   vl_api_ip_table_add_del_t *mp;
8310   u32 table_id = ~0;
8311   u8 is_ipv6 = 0;
8312   u8 is_add = 1;
8313   int ret = 0;
8314
8315   /* Parse args required to build the message */
8316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8317     {
8318       if (unformat (i, "ipv6"))
8319         is_ipv6 = 1;
8320       else if (unformat (i, "del"))
8321         is_add = 0;
8322       else if (unformat (i, "add"))
8323         is_add = 1;
8324       else if (unformat (i, "table %d", &table_id))
8325         ;
8326       else
8327         {
8328           clib_warning ("parse error '%U'", format_unformat_error, i);
8329           return -99;
8330         }
8331     }
8332
8333   if (~0 == table_id)
8334     {
8335       errmsg ("missing table-ID");
8336       return -99;
8337     }
8338
8339   /* Construct the API message */
8340   M (IP_TABLE_ADD_DEL, mp);
8341
8342   mp->table_id = ntohl (table_id);
8343   mp->is_ipv6 = is_ipv6;
8344   mp->is_add = is_add;
8345
8346   /* send it... */
8347   S (mp);
8348
8349   /* Wait for a reply... */
8350   W (ret);
8351
8352   return ret;
8353 }
8354
8355 static int
8356 api_ip_add_del_route (vat_main_t * vam)
8357 {
8358   unformat_input_t *i = vam->input;
8359   vl_api_ip_add_del_route_t *mp;
8360   u32 sw_if_index = ~0, vrf_id = 0;
8361   u8 is_ipv6 = 0;
8362   u8 is_local = 0, is_drop = 0;
8363   u8 is_unreach = 0, is_prohibit = 0;
8364   u8 is_add = 1;
8365   u32 next_hop_weight = 1;
8366   u8 is_multipath = 0;
8367   u8 address_set = 0;
8368   u8 address_length_set = 0;
8369   u32 next_hop_table_id = 0;
8370   u32 resolve_attempts = 0;
8371   u32 dst_address_length = 0;
8372   u8 next_hop_set = 0;
8373   ip4_address_t v4_dst_address, v4_next_hop_address;
8374   ip6_address_t v6_dst_address, v6_next_hop_address;
8375   int count = 1;
8376   int j;
8377   f64 before = 0;
8378   u32 random_add_del = 0;
8379   u32 *random_vector = 0;
8380   uword *random_hash;
8381   u32 random_seed = 0xdeaddabe;
8382   u32 classify_table_index = ~0;
8383   u8 is_classify = 0;
8384   u8 resolve_host = 0, resolve_attached = 0;
8385   mpls_label_t *next_hop_out_label_stack = NULL;
8386   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8387   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8388
8389   /* Parse args required to build the message */
8390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8391     {
8392       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8393         ;
8394       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8395         ;
8396       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8397         {
8398           address_set = 1;
8399           is_ipv6 = 0;
8400         }
8401       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8402         {
8403           address_set = 1;
8404           is_ipv6 = 1;
8405         }
8406       else if (unformat (i, "/%d", &dst_address_length))
8407         {
8408           address_length_set = 1;
8409         }
8410
8411       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8412                                          &v4_next_hop_address))
8413         {
8414           next_hop_set = 1;
8415         }
8416       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8417                                          &v6_next_hop_address))
8418         {
8419           next_hop_set = 1;
8420         }
8421       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8422         ;
8423       else if (unformat (i, "weight %d", &next_hop_weight))
8424         ;
8425       else if (unformat (i, "drop"))
8426         {
8427           is_drop = 1;
8428         }
8429       else if (unformat (i, "null-send-unreach"))
8430         {
8431           is_unreach = 1;
8432         }
8433       else if (unformat (i, "null-send-prohibit"))
8434         {
8435           is_prohibit = 1;
8436         }
8437       else if (unformat (i, "local"))
8438         {
8439           is_local = 1;
8440         }
8441       else if (unformat (i, "classify %d", &classify_table_index))
8442         {
8443           is_classify = 1;
8444         }
8445       else if (unformat (i, "del"))
8446         is_add = 0;
8447       else if (unformat (i, "add"))
8448         is_add = 1;
8449       else if (unformat (i, "resolve-via-host"))
8450         resolve_host = 1;
8451       else if (unformat (i, "resolve-via-attached"))
8452         resolve_attached = 1;
8453       else if (unformat (i, "multipath"))
8454         is_multipath = 1;
8455       else if (unformat (i, "vrf %d", &vrf_id))
8456         ;
8457       else if (unformat (i, "count %d", &count))
8458         ;
8459       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8460         ;
8461       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8462         ;
8463       else if (unformat (i, "out-label %d", &next_hop_out_label))
8464         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8465       else if (unformat (i, "via-label %d", &next_hop_via_label))
8466         ;
8467       else if (unformat (i, "random"))
8468         random_add_del = 1;
8469       else if (unformat (i, "seed %d", &random_seed))
8470         ;
8471       else
8472         {
8473           clib_warning ("parse error '%U'", format_unformat_error, i);
8474           return -99;
8475         }
8476     }
8477
8478   if (!next_hop_set && !is_drop && !is_local &&
8479       !is_classify && !is_unreach && !is_prohibit &&
8480       MPLS_LABEL_INVALID == next_hop_via_label)
8481     {
8482       errmsg
8483         ("next hop / local / drop / unreach / prohibit / classify not set");
8484       return -99;
8485     }
8486
8487   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8488     {
8489       errmsg ("next hop and next-hop via label set");
8490       return -99;
8491     }
8492   if (address_set == 0)
8493     {
8494       errmsg ("missing addresses");
8495       return -99;
8496     }
8497
8498   if (address_length_set == 0)
8499     {
8500       errmsg ("missing address length");
8501       return -99;
8502     }
8503
8504   /* Generate a pile of unique, random routes */
8505   if (random_add_del)
8506     {
8507       u32 this_random_address;
8508       random_hash = hash_create (count, sizeof (uword));
8509
8510       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8511       for (j = 0; j <= count; j++)
8512         {
8513           do
8514             {
8515               this_random_address = random_u32 (&random_seed);
8516               this_random_address =
8517                 clib_host_to_net_u32 (this_random_address);
8518             }
8519           while (hash_get (random_hash, this_random_address));
8520           vec_add1 (random_vector, this_random_address);
8521           hash_set (random_hash, this_random_address, 1);
8522         }
8523       hash_free (random_hash);
8524       v4_dst_address.as_u32 = random_vector[0];
8525     }
8526
8527   if (count > 1)
8528     {
8529       /* Turn on async mode */
8530       vam->async_mode = 1;
8531       vam->async_errors = 0;
8532       before = vat_time_now (vam);
8533     }
8534
8535   for (j = 0; j < count; j++)
8536     {
8537       /* Construct the API message */
8538       M2 (IP_ADD_DEL_ROUTE, mp,
8539           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8540
8541       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8542       mp->table_id = ntohl (vrf_id);
8543
8544       mp->is_add = is_add;
8545       mp->is_drop = is_drop;
8546       mp->is_unreach = is_unreach;
8547       mp->is_prohibit = is_prohibit;
8548       mp->is_ipv6 = is_ipv6;
8549       mp->is_local = is_local;
8550       mp->is_classify = is_classify;
8551       mp->is_multipath = is_multipath;
8552       mp->is_resolve_host = resolve_host;
8553       mp->is_resolve_attached = resolve_attached;
8554       mp->next_hop_weight = next_hop_weight;
8555       mp->dst_address_length = dst_address_length;
8556       mp->next_hop_table_id = ntohl (next_hop_table_id);
8557       mp->classify_table_index = ntohl (classify_table_index);
8558       mp->next_hop_via_label = ntohl (next_hop_via_label);
8559       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8560       if (0 != mp->next_hop_n_out_labels)
8561         {
8562           memcpy (mp->next_hop_out_label_stack,
8563                   next_hop_out_label_stack,
8564                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8565           vec_free (next_hop_out_label_stack);
8566         }
8567
8568       if (is_ipv6)
8569         {
8570           clib_memcpy (mp->dst_address, &v6_dst_address,
8571                        sizeof (v6_dst_address));
8572           if (next_hop_set)
8573             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8574                          sizeof (v6_next_hop_address));
8575           increment_v6_address (&v6_dst_address);
8576         }
8577       else
8578         {
8579           clib_memcpy (mp->dst_address, &v4_dst_address,
8580                        sizeof (v4_dst_address));
8581           if (next_hop_set)
8582             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8583                          sizeof (v4_next_hop_address));
8584           if (random_add_del)
8585             v4_dst_address.as_u32 = random_vector[j + 1];
8586           else
8587             increment_v4_address (&v4_dst_address);
8588         }
8589       /* send it... */
8590       S (mp);
8591       /* If we receive SIGTERM, stop now... */
8592       if (vam->do_exit)
8593         break;
8594     }
8595
8596   /* When testing multiple add/del ops, use a control-ping to sync */
8597   if (count > 1)
8598     {
8599       vl_api_control_ping_t *mp_ping;
8600       f64 after;
8601       f64 timeout;
8602
8603       /* Shut off async mode */
8604       vam->async_mode = 0;
8605
8606       MPING (CONTROL_PING, mp_ping);
8607       S (mp_ping);
8608
8609       timeout = vat_time_now (vam) + 1.0;
8610       while (vat_time_now (vam) < timeout)
8611         if (vam->result_ready == 1)
8612           goto out;
8613       vam->retval = -99;
8614
8615     out:
8616       if (vam->retval == -99)
8617         errmsg ("timeout");
8618
8619       if (vam->async_errors > 0)
8620         {
8621           errmsg ("%d asynchronous errors", vam->async_errors);
8622           vam->retval = -98;
8623         }
8624       vam->async_errors = 0;
8625       after = vat_time_now (vam);
8626
8627       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8628       if (j > 0)
8629         count = j;
8630
8631       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8632              count, after - before, count / (after - before));
8633     }
8634   else
8635     {
8636       int ret;
8637
8638       /* Wait for a reply... */
8639       W (ret);
8640       return ret;
8641     }
8642
8643   /* Return the good/bad news */
8644   return (vam->retval);
8645 }
8646
8647 static int
8648 api_ip_mroute_add_del (vat_main_t * vam)
8649 {
8650   unformat_input_t *i = vam->input;
8651   vl_api_ip_mroute_add_del_t *mp;
8652   u32 sw_if_index = ~0, vrf_id = 0;
8653   u8 is_ipv6 = 0;
8654   u8 is_local = 0;
8655   u8 is_add = 1;
8656   u8 address_set = 0;
8657   u32 grp_address_length = 0;
8658   ip4_address_t v4_grp_address, v4_src_address;
8659   ip6_address_t v6_grp_address, v6_src_address;
8660   mfib_itf_flags_t iflags = 0;
8661   mfib_entry_flags_t eflags = 0;
8662   int ret;
8663
8664   /* Parse args required to build the message */
8665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8666     {
8667       if (unformat (i, "sw_if_index %d", &sw_if_index))
8668         ;
8669       else if (unformat (i, "%U %U",
8670                          unformat_ip4_address, &v4_src_address,
8671                          unformat_ip4_address, &v4_grp_address))
8672         {
8673           grp_address_length = 64;
8674           address_set = 1;
8675           is_ipv6 = 0;
8676         }
8677       else if (unformat (i, "%U %U",
8678                          unformat_ip6_address, &v6_src_address,
8679                          unformat_ip6_address, &v6_grp_address))
8680         {
8681           grp_address_length = 256;
8682           address_set = 1;
8683           is_ipv6 = 1;
8684         }
8685       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8686         {
8687           memset (&v4_src_address, 0, sizeof (v4_src_address));
8688           grp_address_length = 32;
8689           address_set = 1;
8690           is_ipv6 = 0;
8691         }
8692       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8693         {
8694           memset (&v6_src_address, 0, sizeof (v6_src_address));
8695           grp_address_length = 128;
8696           address_set = 1;
8697           is_ipv6 = 1;
8698         }
8699       else if (unformat (i, "/%d", &grp_address_length))
8700         ;
8701       else if (unformat (i, "local"))
8702         {
8703           is_local = 1;
8704         }
8705       else if (unformat (i, "del"))
8706         is_add = 0;
8707       else if (unformat (i, "add"))
8708         is_add = 1;
8709       else if (unformat (i, "vrf %d", &vrf_id))
8710         ;
8711       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8712         ;
8713       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8714         ;
8715       else
8716         {
8717           clib_warning ("parse error '%U'", format_unformat_error, i);
8718           return -99;
8719         }
8720     }
8721
8722   if (address_set == 0)
8723     {
8724       errmsg ("missing addresses\n");
8725       return -99;
8726     }
8727
8728   /* Construct the API message */
8729   M (IP_MROUTE_ADD_DEL, mp);
8730
8731   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8732   mp->table_id = ntohl (vrf_id);
8733
8734   mp->is_add = is_add;
8735   mp->is_ipv6 = is_ipv6;
8736   mp->is_local = is_local;
8737   mp->itf_flags = ntohl (iflags);
8738   mp->entry_flags = ntohl (eflags);
8739   mp->grp_address_length = grp_address_length;
8740   mp->grp_address_length = ntohs (mp->grp_address_length);
8741
8742   if (is_ipv6)
8743     {
8744       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8745       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8746     }
8747   else
8748     {
8749       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8750       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8751
8752     }
8753
8754   /* send it... */
8755   S (mp);
8756   /* Wait for a reply... */
8757   W (ret);
8758   return ret;
8759 }
8760
8761 static int
8762 api_mpls_table_add_del (vat_main_t * vam)
8763 {
8764   unformat_input_t *i = vam->input;
8765   vl_api_mpls_table_add_del_t *mp;
8766   u32 table_id = ~0;
8767   u8 is_add = 1;
8768   int ret = 0;
8769
8770   /* Parse args required to build the message */
8771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8772     {
8773       if (unformat (i, "table %d", &table_id))
8774         ;
8775       else if (unformat (i, "del"))
8776         is_add = 0;
8777       else if (unformat (i, "add"))
8778         is_add = 1;
8779       else
8780         {
8781           clib_warning ("parse error '%U'", format_unformat_error, i);
8782           return -99;
8783         }
8784     }
8785
8786   if (~0 == table_id)
8787     {
8788       errmsg ("missing table-ID");
8789       return -99;
8790     }
8791
8792   /* Construct the API message */
8793   M (MPLS_TABLE_ADD_DEL, mp);
8794
8795   mp->mt_table_id = ntohl (table_id);
8796   mp->mt_is_add = is_add;
8797
8798   /* send it... */
8799   S (mp);
8800
8801   /* Wait for a reply... */
8802   W (ret);
8803
8804   return ret;
8805 }
8806
8807 static int
8808 api_mpls_route_add_del (vat_main_t * vam)
8809 {
8810   unformat_input_t *i = vam->input;
8811   vl_api_mpls_route_add_del_t *mp;
8812   u32 sw_if_index = ~0, table_id = 0;
8813   u8 is_add = 1;
8814   u32 next_hop_weight = 1;
8815   u8 is_multipath = 0;
8816   u32 next_hop_table_id = 0;
8817   u8 next_hop_set = 0;
8818   ip4_address_t v4_next_hop_address = {
8819     .as_u32 = 0,
8820   };
8821   ip6_address_t v6_next_hop_address = { {0} };
8822   int count = 1;
8823   int j;
8824   f64 before = 0;
8825   u32 classify_table_index = ~0;
8826   u8 is_classify = 0;
8827   u8 resolve_host = 0, resolve_attached = 0;
8828   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8829   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8830   mpls_label_t *next_hop_out_label_stack = NULL;
8831   mpls_label_t local_label = MPLS_LABEL_INVALID;
8832   u8 is_eos = 0;
8833   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8834
8835   /* Parse args required to build the message */
8836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8837     {
8838       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8839         ;
8840       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8841         ;
8842       else if (unformat (i, "%d", &local_label))
8843         ;
8844       else if (unformat (i, "eos"))
8845         is_eos = 1;
8846       else if (unformat (i, "non-eos"))
8847         is_eos = 0;
8848       else if (unformat (i, "via %U", unformat_ip4_address,
8849                          &v4_next_hop_address))
8850         {
8851           next_hop_set = 1;
8852           next_hop_proto = DPO_PROTO_IP4;
8853         }
8854       else if (unformat (i, "via %U", unformat_ip6_address,
8855                          &v6_next_hop_address))
8856         {
8857           next_hop_set = 1;
8858           next_hop_proto = DPO_PROTO_IP6;
8859         }
8860       else if (unformat (i, "weight %d", &next_hop_weight))
8861         ;
8862       else if (unformat (i, "classify %d", &classify_table_index))
8863         {
8864           is_classify = 1;
8865         }
8866       else if (unformat (i, "del"))
8867         is_add = 0;
8868       else if (unformat (i, "add"))
8869         is_add = 1;
8870       else if (unformat (i, "resolve-via-host"))
8871         resolve_host = 1;
8872       else if (unformat (i, "resolve-via-attached"))
8873         resolve_attached = 1;
8874       else if (unformat (i, "multipath"))
8875         is_multipath = 1;
8876       else if (unformat (i, "count %d", &count))
8877         ;
8878       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8879         {
8880           next_hop_set = 1;
8881           next_hop_proto = DPO_PROTO_IP4;
8882         }
8883       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8884         {
8885           next_hop_set = 1;
8886           next_hop_proto = DPO_PROTO_IP6;
8887         }
8888       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8889         ;
8890       else if (unformat (i, "via-label %d", &next_hop_via_label))
8891         ;
8892       else if (unformat (i, "out-label %d", &next_hop_out_label))
8893         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8894       else
8895         {
8896           clib_warning ("parse error '%U'", format_unformat_error, i);
8897           return -99;
8898         }
8899     }
8900
8901   if (!next_hop_set && !is_classify)
8902     {
8903       errmsg ("next hop / classify not set");
8904       return -99;
8905     }
8906
8907   if (MPLS_LABEL_INVALID == local_label)
8908     {
8909       errmsg ("missing label");
8910       return -99;
8911     }
8912
8913   if (count > 1)
8914     {
8915       /* Turn on async mode */
8916       vam->async_mode = 1;
8917       vam->async_errors = 0;
8918       before = vat_time_now (vam);
8919     }
8920
8921   for (j = 0; j < count; j++)
8922     {
8923       /* Construct the API message */
8924       M2 (MPLS_ROUTE_ADD_DEL, mp,
8925           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8926
8927       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8928       mp->mr_table_id = ntohl (table_id);
8929
8930       mp->mr_is_add = is_add;
8931       mp->mr_next_hop_proto = next_hop_proto;
8932       mp->mr_is_classify = is_classify;
8933       mp->mr_is_multipath = is_multipath;
8934       mp->mr_is_resolve_host = resolve_host;
8935       mp->mr_is_resolve_attached = resolve_attached;
8936       mp->mr_next_hop_weight = next_hop_weight;
8937       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8938       mp->mr_classify_table_index = ntohl (classify_table_index);
8939       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8940       mp->mr_label = ntohl (local_label);
8941       mp->mr_eos = is_eos;
8942
8943       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8944       if (0 != mp->mr_next_hop_n_out_labels)
8945         {
8946           memcpy (mp->mr_next_hop_out_label_stack,
8947                   next_hop_out_label_stack,
8948                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8949           vec_free (next_hop_out_label_stack);
8950         }
8951
8952       if (next_hop_set)
8953         {
8954           if (DPO_PROTO_IP4 == next_hop_proto)
8955             {
8956               clib_memcpy (mp->mr_next_hop,
8957                            &v4_next_hop_address,
8958                            sizeof (v4_next_hop_address));
8959             }
8960           else if (DPO_PROTO_IP6 == next_hop_proto)
8961
8962             {
8963               clib_memcpy (mp->mr_next_hop,
8964                            &v6_next_hop_address,
8965                            sizeof (v6_next_hop_address));
8966             }
8967         }
8968       local_label++;
8969
8970       /* send it... */
8971       S (mp);
8972       /* If we receive SIGTERM, stop now... */
8973       if (vam->do_exit)
8974         break;
8975     }
8976
8977   /* When testing multiple add/del ops, use a control-ping to sync */
8978   if (count > 1)
8979     {
8980       vl_api_control_ping_t *mp_ping;
8981       f64 after;
8982       f64 timeout;
8983
8984       /* Shut off async mode */
8985       vam->async_mode = 0;
8986
8987       MPING (CONTROL_PING, mp_ping);
8988       S (mp_ping);
8989
8990       timeout = vat_time_now (vam) + 1.0;
8991       while (vat_time_now (vam) < timeout)
8992         if (vam->result_ready == 1)
8993           goto out;
8994       vam->retval = -99;
8995
8996     out:
8997       if (vam->retval == -99)
8998         errmsg ("timeout");
8999
9000       if (vam->async_errors > 0)
9001         {
9002           errmsg ("%d asynchronous errors", vam->async_errors);
9003           vam->retval = -98;
9004         }
9005       vam->async_errors = 0;
9006       after = vat_time_now (vam);
9007
9008       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9009       if (j > 0)
9010         count = j;
9011
9012       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9013              count, after - before, count / (after - before));
9014     }
9015   else
9016     {
9017       int ret;
9018
9019       /* Wait for a reply... */
9020       W (ret);
9021       return ret;
9022     }
9023
9024   /* Return the good/bad news */
9025   return (vam->retval);
9026 }
9027
9028 static int
9029 api_mpls_ip_bind_unbind (vat_main_t * vam)
9030 {
9031   unformat_input_t *i = vam->input;
9032   vl_api_mpls_ip_bind_unbind_t *mp;
9033   u32 ip_table_id = 0;
9034   u8 is_bind = 1;
9035   u8 is_ip4 = 1;
9036   ip4_address_t v4_address;
9037   ip6_address_t v6_address;
9038   u32 address_length;
9039   u8 address_set = 0;
9040   mpls_label_t local_label = MPLS_LABEL_INVALID;
9041   int ret;
9042
9043   /* Parse args required to build the message */
9044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9045     {
9046       if (unformat (i, "%U/%d", unformat_ip4_address,
9047                     &v4_address, &address_length))
9048         {
9049           is_ip4 = 1;
9050           address_set = 1;
9051         }
9052       else if (unformat (i, "%U/%d", unformat_ip6_address,
9053                          &v6_address, &address_length))
9054         {
9055           is_ip4 = 0;
9056           address_set = 1;
9057         }
9058       else if (unformat (i, "%d", &local_label))
9059         ;
9060       else if (unformat (i, "table-id %d", &ip_table_id))
9061         ;
9062       else if (unformat (i, "unbind"))
9063         is_bind = 0;
9064       else if (unformat (i, "bind"))
9065         is_bind = 1;
9066       else
9067         {
9068           clib_warning ("parse error '%U'", format_unformat_error, i);
9069           return -99;
9070         }
9071     }
9072
9073   if (!address_set)
9074     {
9075       errmsg ("IP addres not set");
9076       return -99;
9077     }
9078
9079   if (MPLS_LABEL_INVALID == local_label)
9080     {
9081       errmsg ("missing label");
9082       return -99;
9083     }
9084
9085   /* Construct the API message */
9086   M (MPLS_IP_BIND_UNBIND, mp);
9087
9088   mp->mb_is_bind = is_bind;
9089   mp->mb_is_ip4 = is_ip4;
9090   mp->mb_ip_table_id = ntohl (ip_table_id);
9091   mp->mb_mpls_table_id = 0;
9092   mp->mb_label = ntohl (local_label);
9093   mp->mb_address_length = address_length;
9094
9095   if (is_ip4)
9096     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9097   else
9098     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9099
9100   /* send it... */
9101   S (mp);
9102
9103   /* Wait for a reply... */
9104   W (ret);
9105   return ret;
9106 }
9107
9108 static int
9109 api_bier_table_add_del (vat_main_t * vam)
9110 {
9111   unformat_input_t *i = vam->input;
9112   vl_api_bier_table_add_del_t *mp;
9113   u8 is_add = 1;
9114   u32 set = 0, sub_domain = 0, hdr_len = 3;
9115   mpls_label_t local_label = MPLS_LABEL_INVALID;
9116   int ret;
9117
9118   /* Parse args required to build the message */
9119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9120     {
9121       if (unformat (i, "sub-domain %d", &sub_domain))
9122         ;
9123       else if (unformat (i, "set %d", &set))
9124         ;
9125       else if (unformat (i, "label %d", &local_label))
9126         ;
9127       else if (unformat (i, "hdr-len %d", &hdr_len))
9128         ;
9129       else if (unformat (i, "add"))
9130         is_add = 1;
9131       else if (unformat (i, "del"))
9132         is_add = 0;
9133       else
9134         {
9135           clib_warning ("parse error '%U'", format_unformat_error, i);
9136           return -99;
9137         }
9138     }
9139
9140   if (MPLS_LABEL_INVALID == local_label)
9141     {
9142       errmsg ("missing label\n");
9143       return -99;
9144     }
9145
9146   /* Construct the API message */
9147   M (BIER_TABLE_ADD_DEL, mp);
9148
9149   mp->bt_is_add = is_add;
9150   mp->bt_label = ntohl (local_label);
9151   mp->bt_tbl_id.bt_set = set;
9152   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9153   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9154
9155   /* send it... */
9156   S (mp);
9157
9158   /* Wait for a reply... */
9159   W (ret);
9160
9161   return (ret);
9162 }
9163
9164 static int
9165 api_bier_route_add_del (vat_main_t * vam)
9166 {
9167   unformat_input_t *i = vam->input;
9168   vl_api_bier_route_add_del_t *mp;
9169   u8 is_add = 1;
9170   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9171   ip4_address_t v4_next_hop_address;
9172   ip6_address_t v6_next_hop_address;
9173   u8 next_hop_set = 0;
9174   u8 next_hop_proto_is_ip4 = 1;
9175   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9176   int ret;
9177
9178   /* Parse args required to build the message */
9179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9180     {
9181       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9182         {
9183           next_hop_proto_is_ip4 = 1;
9184           next_hop_set = 1;
9185         }
9186       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9187         {
9188           next_hop_proto_is_ip4 = 0;
9189           next_hop_set = 1;
9190         }
9191       if (unformat (i, "sub-domain %d", &sub_domain))
9192         ;
9193       else if (unformat (i, "set %d", &set))
9194         ;
9195       else if (unformat (i, "hdr-len %d", &hdr_len))
9196         ;
9197       else if (unformat (i, "bp %d", &bp))
9198         ;
9199       else if (unformat (i, "add"))
9200         is_add = 1;
9201       else if (unformat (i, "del"))
9202         is_add = 0;
9203       else if (unformat (i, "out-label %d", &next_hop_out_label))
9204         ;
9205       else
9206         {
9207           clib_warning ("parse error '%U'", format_unformat_error, i);
9208           return -99;
9209         }
9210     }
9211
9212   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9213     {
9214       errmsg ("next hop / label set\n");
9215       return -99;
9216     }
9217   if (0 == bp)
9218     {
9219       errmsg ("bit=position not set\n");
9220       return -99;
9221     }
9222
9223   /* Construct the API message */
9224   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9225
9226   mp->br_is_add = is_add;
9227   mp->br_tbl_id.bt_set = set;
9228   mp->br_tbl_id.bt_sub_domain = sub_domain;
9229   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9230   mp->br_bp = ntohs (bp);
9231   mp->br_n_paths = 1;
9232   mp->br_paths[0].n_labels = 1;
9233   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9234   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9235
9236   if (next_hop_proto_is_ip4)
9237     {
9238       clib_memcpy (mp->br_paths[0].next_hop,
9239                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9240     }
9241   else
9242     {
9243       clib_memcpy (mp->br_paths[0].next_hop,
9244                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9245     }
9246
9247   /* send it... */
9248   S (mp);
9249
9250   /* Wait for a reply... */
9251   W (ret);
9252
9253   return (ret);
9254 }
9255
9256 static int
9257 api_proxy_arp_add_del (vat_main_t * vam)
9258 {
9259   unformat_input_t *i = vam->input;
9260   vl_api_proxy_arp_add_del_t *mp;
9261   u32 vrf_id = 0;
9262   u8 is_add = 1;
9263   ip4_address_t lo, hi;
9264   u8 range_set = 0;
9265   int ret;
9266
9267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9268     {
9269       if (unformat (i, "vrf %d", &vrf_id))
9270         ;
9271       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9272                          unformat_ip4_address, &hi))
9273         range_set = 1;
9274       else if (unformat (i, "del"))
9275         is_add = 0;
9276       else
9277         {
9278           clib_warning ("parse error '%U'", format_unformat_error, i);
9279           return -99;
9280         }
9281     }
9282
9283   if (range_set == 0)
9284     {
9285       errmsg ("address range not set");
9286       return -99;
9287     }
9288
9289   M (PROXY_ARP_ADD_DEL, mp);
9290
9291   mp->proxy.vrf_id = ntohl (vrf_id);
9292   mp->is_add = is_add;
9293   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9294   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9295
9296   S (mp);
9297   W (ret);
9298   return ret;
9299 }
9300
9301 static int
9302 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9303 {
9304   unformat_input_t *i = vam->input;
9305   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9306   u32 sw_if_index;
9307   u8 enable = 1;
9308   u8 sw_if_index_set = 0;
9309   int ret;
9310
9311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9312     {
9313       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9314         sw_if_index_set = 1;
9315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9316         sw_if_index_set = 1;
9317       else if (unformat (i, "enable"))
9318         enable = 1;
9319       else if (unformat (i, "disable"))
9320         enable = 0;
9321       else
9322         {
9323           clib_warning ("parse error '%U'", format_unformat_error, i);
9324           return -99;
9325         }
9326     }
9327
9328   if (sw_if_index_set == 0)
9329     {
9330       errmsg ("missing interface name or sw_if_index");
9331       return -99;
9332     }
9333
9334   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9335
9336   mp->sw_if_index = ntohl (sw_if_index);
9337   mp->enable_disable = enable;
9338
9339   S (mp);
9340   W (ret);
9341   return ret;
9342 }
9343
9344 static int
9345 api_mpls_tunnel_add_del (vat_main_t * vam)
9346 {
9347   unformat_input_t *i = vam->input;
9348   vl_api_mpls_tunnel_add_del_t *mp;
9349
9350   u8 is_add = 1;
9351   u8 l2_only = 0;
9352   u32 sw_if_index = ~0;
9353   u32 next_hop_sw_if_index = ~0;
9354   u32 next_hop_proto_is_ip4 = 1;
9355
9356   u32 next_hop_table_id = 0;
9357   ip4_address_t v4_next_hop_address = {
9358     .as_u32 = 0,
9359   };
9360   ip6_address_t v6_next_hop_address = { {0} };
9361   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9362   int ret;
9363
9364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9365     {
9366       if (unformat (i, "add"))
9367         is_add = 1;
9368       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9369         is_add = 0;
9370       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9371         ;
9372       else if (unformat (i, "via %U",
9373                          unformat_ip4_address, &v4_next_hop_address))
9374         {
9375           next_hop_proto_is_ip4 = 1;
9376         }
9377       else if (unformat (i, "via %U",
9378                          unformat_ip6_address, &v6_next_hop_address))
9379         {
9380           next_hop_proto_is_ip4 = 0;
9381         }
9382       else if (unformat (i, "l2-only"))
9383         l2_only = 1;
9384       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9385         ;
9386       else if (unformat (i, "out-label %d", &next_hop_out_label))
9387         vec_add1 (labels, ntohl (next_hop_out_label));
9388       else
9389         {
9390           clib_warning ("parse error '%U'", format_unformat_error, i);
9391           return -99;
9392         }
9393     }
9394
9395   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9396
9397   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9398   mp->mt_sw_if_index = ntohl (sw_if_index);
9399   mp->mt_is_add = is_add;
9400   mp->mt_l2_only = l2_only;
9401   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9402   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9403
9404   mp->mt_next_hop_n_out_labels = vec_len (labels);
9405
9406   if (0 != mp->mt_next_hop_n_out_labels)
9407     {
9408       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9409                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9410       vec_free (labels);
9411     }
9412
9413   if (next_hop_proto_is_ip4)
9414     {
9415       clib_memcpy (mp->mt_next_hop,
9416                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9417     }
9418   else
9419     {
9420       clib_memcpy (mp->mt_next_hop,
9421                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9422     }
9423
9424   S (mp);
9425   W (ret);
9426   return ret;
9427 }
9428
9429 static int
9430 api_sw_interface_set_unnumbered (vat_main_t * vam)
9431 {
9432   unformat_input_t *i = vam->input;
9433   vl_api_sw_interface_set_unnumbered_t *mp;
9434   u32 sw_if_index;
9435   u32 unnum_sw_index = ~0;
9436   u8 is_add = 1;
9437   u8 sw_if_index_set = 0;
9438   int ret;
9439
9440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9441     {
9442       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9443         sw_if_index_set = 1;
9444       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9445         sw_if_index_set = 1;
9446       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9447         ;
9448       else if (unformat (i, "del"))
9449         is_add = 0;
9450       else
9451         {
9452           clib_warning ("parse error '%U'", format_unformat_error, i);
9453           return -99;
9454         }
9455     }
9456
9457   if (sw_if_index_set == 0)
9458     {
9459       errmsg ("missing interface name or sw_if_index");
9460       return -99;
9461     }
9462
9463   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9464
9465   mp->sw_if_index = ntohl (sw_if_index);
9466   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9467   mp->is_add = is_add;
9468
9469   S (mp);
9470   W (ret);
9471   return ret;
9472 }
9473
9474 static int
9475 api_ip_neighbor_add_del (vat_main_t * vam)
9476 {
9477   unformat_input_t *i = vam->input;
9478   vl_api_ip_neighbor_add_del_t *mp;
9479   u32 sw_if_index;
9480   u8 sw_if_index_set = 0;
9481   u8 is_add = 1;
9482   u8 is_static = 0;
9483   u8 is_no_fib_entry = 0;
9484   u8 mac_address[6];
9485   u8 mac_set = 0;
9486   u8 v4_address_set = 0;
9487   u8 v6_address_set = 0;
9488   ip4_address_t v4address;
9489   ip6_address_t v6address;
9490   int ret;
9491
9492   memset (mac_address, 0, sizeof (mac_address));
9493
9494   /* Parse args required to build the message */
9495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9496     {
9497       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9498         {
9499           mac_set = 1;
9500         }
9501       else if (unformat (i, "del"))
9502         is_add = 0;
9503       else
9504         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9505         sw_if_index_set = 1;
9506       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9507         sw_if_index_set = 1;
9508       else if (unformat (i, "is_static"))
9509         is_static = 1;
9510       else if (unformat (i, "no-fib-entry"))
9511         is_no_fib_entry = 1;
9512       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9513         v4_address_set = 1;
9514       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9515         v6_address_set = 1;
9516       else
9517         {
9518           clib_warning ("parse error '%U'", format_unformat_error, i);
9519           return -99;
9520         }
9521     }
9522
9523   if (sw_if_index_set == 0)
9524     {
9525       errmsg ("missing interface name or sw_if_index");
9526       return -99;
9527     }
9528   if (v4_address_set && v6_address_set)
9529     {
9530       errmsg ("both v4 and v6 addresses set");
9531       return -99;
9532     }
9533   if (!v4_address_set && !v6_address_set)
9534     {
9535       errmsg ("no address set");
9536       return -99;
9537     }
9538
9539   /* Construct the API message */
9540   M (IP_NEIGHBOR_ADD_DEL, mp);
9541
9542   mp->sw_if_index = ntohl (sw_if_index);
9543   mp->is_add = is_add;
9544   mp->is_static = is_static;
9545   mp->is_no_adj_fib = is_no_fib_entry;
9546   if (mac_set)
9547     clib_memcpy (mp->mac_address, mac_address, 6);
9548   if (v6_address_set)
9549     {
9550       mp->is_ipv6 = 1;
9551       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9552     }
9553   else
9554     {
9555       /* mp->is_ipv6 = 0; via memset in M macro above */
9556       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9557     }
9558
9559   /* send it... */
9560   S (mp);
9561
9562   /* Wait for a reply, return good/bad news  */
9563   W (ret);
9564   return ret;
9565 }
9566
9567 static int
9568 api_create_vlan_subif (vat_main_t * vam)
9569 {
9570   unformat_input_t *i = vam->input;
9571   vl_api_create_vlan_subif_t *mp;
9572   u32 sw_if_index;
9573   u8 sw_if_index_set = 0;
9574   u32 vlan_id;
9575   u8 vlan_id_set = 0;
9576   int ret;
9577
9578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9579     {
9580       if (unformat (i, "sw_if_index %d", &sw_if_index))
9581         sw_if_index_set = 1;
9582       else
9583         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9584         sw_if_index_set = 1;
9585       else if (unformat (i, "vlan %d", &vlan_id))
9586         vlan_id_set = 1;
9587       else
9588         {
9589           clib_warning ("parse error '%U'", format_unformat_error, i);
9590           return -99;
9591         }
9592     }
9593
9594   if (sw_if_index_set == 0)
9595     {
9596       errmsg ("missing interface name or sw_if_index");
9597       return -99;
9598     }
9599
9600   if (vlan_id_set == 0)
9601     {
9602       errmsg ("missing vlan_id");
9603       return -99;
9604     }
9605   M (CREATE_VLAN_SUBIF, mp);
9606
9607   mp->sw_if_index = ntohl (sw_if_index);
9608   mp->vlan_id = ntohl (vlan_id);
9609
9610   S (mp);
9611   W (ret);
9612   return ret;
9613 }
9614
9615 #define foreach_create_subif_bit                \
9616 _(no_tags)                                      \
9617 _(one_tag)                                      \
9618 _(two_tags)                                     \
9619 _(dot1ad)                                       \
9620 _(exact_match)                                  \
9621 _(default_sub)                                  \
9622 _(outer_vlan_id_any)                            \
9623 _(inner_vlan_id_any)
9624
9625 static int
9626 api_create_subif (vat_main_t * vam)
9627 {
9628   unformat_input_t *i = vam->input;
9629   vl_api_create_subif_t *mp;
9630   u32 sw_if_index;
9631   u8 sw_if_index_set = 0;
9632   u32 sub_id;
9633   u8 sub_id_set = 0;
9634   u32 no_tags = 0;
9635   u32 one_tag = 0;
9636   u32 two_tags = 0;
9637   u32 dot1ad = 0;
9638   u32 exact_match = 0;
9639   u32 default_sub = 0;
9640   u32 outer_vlan_id_any = 0;
9641   u32 inner_vlan_id_any = 0;
9642   u32 tmp;
9643   u16 outer_vlan_id = 0;
9644   u16 inner_vlan_id = 0;
9645   int ret;
9646
9647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9648     {
9649       if (unformat (i, "sw_if_index %d", &sw_if_index))
9650         sw_if_index_set = 1;
9651       else
9652         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9653         sw_if_index_set = 1;
9654       else if (unformat (i, "sub_id %d", &sub_id))
9655         sub_id_set = 1;
9656       else if (unformat (i, "outer_vlan_id %d", &tmp))
9657         outer_vlan_id = tmp;
9658       else if (unformat (i, "inner_vlan_id %d", &tmp))
9659         inner_vlan_id = tmp;
9660
9661 #define _(a) else if (unformat (i, #a)) a = 1 ;
9662       foreach_create_subif_bit
9663 #undef _
9664         else
9665         {
9666           clib_warning ("parse error '%U'", format_unformat_error, i);
9667           return -99;
9668         }
9669     }
9670
9671   if (sw_if_index_set == 0)
9672     {
9673       errmsg ("missing interface name or sw_if_index");
9674       return -99;
9675     }
9676
9677   if (sub_id_set == 0)
9678     {
9679       errmsg ("missing sub_id");
9680       return -99;
9681     }
9682   M (CREATE_SUBIF, mp);
9683
9684   mp->sw_if_index = ntohl (sw_if_index);
9685   mp->sub_id = ntohl (sub_id);
9686
9687 #define _(a) mp->a = a;
9688   foreach_create_subif_bit;
9689 #undef _
9690
9691   mp->outer_vlan_id = ntohs (outer_vlan_id);
9692   mp->inner_vlan_id = ntohs (inner_vlan_id);
9693
9694   S (mp);
9695   W (ret);
9696   return ret;
9697 }
9698
9699 static int
9700 api_oam_add_del (vat_main_t * vam)
9701 {
9702   unformat_input_t *i = vam->input;
9703   vl_api_oam_add_del_t *mp;
9704   u32 vrf_id = 0;
9705   u8 is_add = 1;
9706   ip4_address_t src, dst;
9707   u8 src_set = 0;
9708   u8 dst_set = 0;
9709   int ret;
9710
9711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9712     {
9713       if (unformat (i, "vrf %d", &vrf_id))
9714         ;
9715       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9716         src_set = 1;
9717       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9718         dst_set = 1;
9719       else if (unformat (i, "del"))
9720         is_add = 0;
9721       else
9722         {
9723           clib_warning ("parse error '%U'", format_unformat_error, i);
9724           return -99;
9725         }
9726     }
9727
9728   if (src_set == 0)
9729     {
9730       errmsg ("missing src addr");
9731       return -99;
9732     }
9733
9734   if (dst_set == 0)
9735     {
9736       errmsg ("missing dst addr");
9737       return -99;
9738     }
9739
9740   M (OAM_ADD_DEL, mp);
9741
9742   mp->vrf_id = ntohl (vrf_id);
9743   mp->is_add = is_add;
9744   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9745   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9746
9747   S (mp);
9748   W (ret);
9749   return ret;
9750 }
9751
9752 static int
9753 api_reset_fib (vat_main_t * vam)
9754 {
9755   unformat_input_t *i = vam->input;
9756   vl_api_reset_fib_t *mp;
9757   u32 vrf_id = 0;
9758   u8 is_ipv6 = 0;
9759   u8 vrf_id_set = 0;
9760
9761   int ret;
9762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9763     {
9764       if (unformat (i, "vrf %d", &vrf_id))
9765         vrf_id_set = 1;
9766       else if (unformat (i, "ipv6"))
9767         is_ipv6 = 1;
9768       else
9769         {
9770           clib_warning ("parse error '%U'", format_unformat_error, i);
9771           return -99;
9772         }
9773     }
9774
9775   if (vrf_id_set == 0)
9776     {
9777       errmsg ("missing vrf id");
9778       return -99;
9779     }
9780
9781   M (RESET_FIB, mp);
9782
9783   mp->vrf_id = ntohl (vrf_id);
9784   mp->is_ipv6 = is_ipv6;
9785
9786   S (mp);
9787   W (ret);
9788   return ret;
9789 }
9790
9791 static int
9792 api_dhcp_proxy_config (vat_main_t * vam)
9793 {
9794   unformat_input_t *i = vam->input;
9795   vl_api_dhcp_proxy_config_t *mp;
9796   u32 rx_vrf_id = 0;
9797   u32 server_vrf_id = 0;
9798   u8 is_add = 1;
9799   u8 v4_address_set = 0;
9800   u8 v6_address_set = 0;
9801   ip4_address_t v4address;
9802   ip6_address_t v6address;
9803   u8 v4_src_address_set = 0;
9804   u8 v6_src_address_set = 0;
9805   ip4_address_t v4srcaddress;
9806   ip6_address_t v6srcaddress;
9807   int ret;
9808
9809   /* Parse args required to build the message */
9810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (i, "del"))
9813         is_add = 0;
9814       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9815         ;
9816       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9817         ;
9818       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9819         v4_address_set = 1;
9820       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9821         v6_address_set = 1;
9822       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9823         v4_src_address_set = 1;
9824       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9825         v6_src_address_set = 1;
9826       else
9827         break;
9828     }
9829
9830   if (v4_address_set && v6_address_set)
9831     {
9832       errmsg ("both v4 and v6 server addresses set");
9833       return -99;
9834     }
9835   if (!v4_address_set && !v6_address_set)
9836     {
9837       errmsg ("no server addresses set");
9838       return -99;
9839     }
9840
9841   if (v4_src_address_set && v6_src_address_set)
9842     {
9843       errmsg ("both v4 and v6  src addresses set");
9844       return -99;
9845     }
9846   if (!v4_src_address_set && !v6_src_address_set)
9847     {
9848       errmsg ("no src addresses set");
9849       return -99;
9850     }
9851
9852   if (!(v4_src_address_set && v4_address_set) &&
9853       !(v6_src_address_set && v6_address_set))
9854     {
9855       errmsg ("no matching server and src addresses set");
9856       return -99;
9857     }
9858
9859   /* Construct the API message */
9860   M (DHCP_PROXY_CONFIG, mp);
9861
9862   mp->is_add = is_add;
9863   mp->rx_vrf_id = ntohl (rx_vrf_id);
9864   mp->server_vrf_id = ntohl (server_vrf_id);
9865   if (v6_address_set)
9866     {
9867       mp->is_ipv6 = 1;
9868       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9869       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9870     }
9871   else
9872     {
9873       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9874       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9875     }
9876
9877   /* send it... */
9878   S (mp);
9879
9880   /* Wait for a reply, return good/bad news  */
9881   W (ret);
9882   return ret;
9883 }
9884
9885 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9886 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9887
9888 static void
9889 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9890 {
9891   vat_main_t *vam = &vat_main;
9892   u32 i, count = mp->count;
9893   vl_api_dhcp_server_t *s;
9894
9895   if (mp->is_ipv6)
9896     print (vam->ofp,
9897            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9898            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9899            ntohl (mp->rx_vrf_id),
9900            format_ip6_address, mp->dhcp_src_address,
9901            mp->vss_type, mp->vss_vpn_ascii_id,
9902            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9903   else
9904     print (vam->ofp,
9905            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9906            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9907            ntohl (mp->rx_vrf_id),
9908            format_ip4_address, mp->dhcp_src_address,
9909            mp->vss_type, mp->vss_vpn_ascii_id,
9910            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9911
9912   for (i = 0; i < count; i++)
9913     {
9914       s = &mp->servers[i];
9915
9916       if (mp->is_ipv6)
9917         print (vam->ofp,
9918                " Server Table-ID %d, Server Address %U",
9919                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9920       else
9921         print (vam->ofp,
9922                " Server Table-ID %d, Server Address %U",
9923                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9924     }
9925 }
9926
9927 static void vl_api_dhcp_proxy_details_t_handler_json
9928   (vl_api_dhcp_proxy_details_t * mp)
9929 {
9930   vat_main_t *vam = &vat_main;
9931   vat_json_node_t *node = NULL;
9932   u32 i, count = mp->count;
9933   struct in_addr ip4;
9934   struct in6_addr ip6;
9935   vl_api_dhcp_server_t *s;
9936
9937   if (VAT_JSON_ARRAY != vam->json_tree.type)
9938     {
9939       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9940       vat_json_init_array (&vam->json_tree);
9941     }
9942   node = vat_json_array_add (&vam->json_tree);
9943
9944   vat_json_init_object (node);
9945   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9946   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9947                              sizeof (mp->vss_type));
9948   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9949                                    mp->vss_vpn_ascii_id);
9950   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9951   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9952
9953   if (mp->is_ipv6)
9954     {
9955       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9956       vat_json_object_add_ip6 (node, "src_address", ip6);
9957     }
9958   else
9959     {
9960       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9961       vat_json_object_add_ip4 (node, "src_address", ip4);
9962     }
9963
9964   for (i = 0; i < count; i++)
9965     {
9966       s = &mp->servers[i];
9967
9968       vat_json_object_add_uint (node, "server-table-id",
9969                                 ntohl (s->server_vrf_id));
9970
9971       if (mp->is_ipv6)
9972         {
9973           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9974           vat_json_object_add_ip4 (node, "src_address", ip4);
9975         }
9976       else
9977         {
9978           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9979           vat_json_object_add_ip6 (node, "server_address", ip6);
9980         }
9981     }
9982 }
9983
9984 static int
9985 api_dhcp_proxy_dump (vat_main_t * vam)
9986 {
9987   unformat_input_t *i = vam->input;
9988   vl_api_control_ping_t *mp_ping;
9989   vl_api_dhcp_proxy_dump_t *mp;
9990   u8 is_ipv6 = 0;
9991   int ret;
9992
9993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9994     {
9995       if (unformat (i, "ipv6"))
9996         is_ipv6 = 1;
9997       else
9998         {
9999           clib_warning ("parse error '%U'", format_unformat_error, i);
10000           return -99;
10001         }
10002     }
10003
10004   M (DHCP_PROXY_DUMP, mp);
10005
10006   mp->is_ip6 = is_ipv6;
10007   S (mp);
10008
10009   /* Use a control ping for synchronization */
10010   MPING (CONTROL_PING, mp_ping);
10011   S (mp_ping);
10012
10013   W (ret);
10014   return ret;
10015 }
10016
10017 static int
10018 api_dhcp_proxy_set_vss (vat_main_t * vam)
10019 {
10020   unformat_input_t *i = vam->input;
10021   vl_api_dhcp_proxy_set_vss_t *mp;
10022   u8 is_ipv6 = 0;
10023   u8 is_add = 1;
10024   u32 tbl_id = ~0;
10025   u8 vss_type = VSS_TYPE_DEFAULT;
10026   u8 *vpn_ascii_id = 0;
10027   u32 oui = 0;
10028   u32 fib_id = 0;
10029   int ret;
10030
10031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10032     {
10033       if (unformat (i, "tbl_id %d", &tbl_id))
10034         ;
10035       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10036         vss_type = VSS_TYPE_ASCII;
10037       else if (unformat (i, "fib_id %d", &fib_id))
10038         vss_type = VSS_TYPE_VPN_ID;
10039       else if (unformat (i, "oui %d", &oui))
10040         vss_type = VSS_TYPE_VPN_ID;
10041       else if (unformat (i, "ipv6"))
10042         is_ipv6 = 1;
10043       else if (unformat (i, "del"))
10044         is_add = 0;
10045       else
10046         break;
10047     }
10048
10049   if (tbl_id == ~0)
10050     {
10051       errmsg ("missing tbl_id ");
10052       vec_free (vpn_ascii_id);
10053       return -99;
10054     }
10055
10056   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10057     {
10058       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10059       vec_free (vpn_ascii_id);
10060       return -99;
10061     }
10062
10063   M (DHCP_PROXY_SET_VSS, mp);
10064   mp->tbl_id = ntohl (tbl_id);
10065   mp->vss_type = vss_type;
10066   if (vpn_ascii_id)
10067     {
10068       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10069       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10070     }
10071   mp->vpn_index = ntohl (fib_id);
10072   mp->oui = ntohl (oui);
10073   mp->is_ipv6 = is_ipv6;
10074   mp->is_add = is_add;
10075
10076   S (mp);
10077   W (ret);
10078
10079   vec_free (vpn_ascii_id);
10080   return ret;
10081 }
10082
10083 static int
10084 api_dhcp_client_config (vat_main_t * vam)
10085 {
10086   unformat_input_t *i = vam->input;
10087   vl_api_dhcp_client_config_t *mp;
10088   u32 sw_if_index;
10089   u8 sw_if_index_set = 0;
10090   u8 is_add = 1;
10091   u8 *hostname = 0;
10092   u8 disable_event = 0;
10093   int ret;
10094
10095   /* Parse args required to build the message */
10096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10097     {
10098       if (unformat (i, "del"))
10099         is_add = 0;
10100       else
10101         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10102         sw_if_index_set = 1;
10103       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10104         sw_if_index_set = 1;
10105       else if (unformat (i, "hostname %s", &hostname))
10106         ;
10107       else if (unformat (i, "disable_event"))
10108         disable_event = 1;
10109       else
10110         break;
10111     }
10112
10113   if (sw_if_index_set == 0)
10114     {
10115       errmsg ("missing interface name or sw_if_index");
10116       return -99;
10117     }
10118
10119   if (vec_len (hostname) > 63)
10120     {
10121       errmsg ("hostname too long");
10122     }
10123   vec_add1 (hostname, 0);
10124
10125   /* Construct the API message */
10126   M (DHCP_CLIENT_CONFIG, mp);
10127
10128   mp->sw_if_index = htonl (sw_if_index);
10129   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
10130   vec_free (hostname);
10131   mp->is_add = is_add;
10132   mp->want_dhcp_event = disable_event ? 0 : 1;
10133   mp->pid = htonl (getpid ());
10134
10135   /* send it... */
10136   S (mp);
10137
10138   /* Wait for a reply, return good/bad news  */
10139   W (ret);
10140   return ret;
10141 }
10142
10143 static int
10144 api_set_ip_flow_hash (vat_main_t * vam)
10145 {
10146   unformat_input_t *i = vam->input;
10147   vl_api_set_ip_flow_hash_t *mp;
10148   u32 vrf_id = 0;
10149   u8 is_ipv6 = 0;
10150   u8 vrf_id_set = 0;
10151   u8 src = 0;
10152   u8 dst = 0;
10153   u8 sport = 0;
10154   u8 dport = 0;
10155   u8 proto = 0;
10156   u8 reverse = 0;
10157   int ret;
10158
10159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10160     {
10161       if (unformat (i, "vrf %d", &vrf_id))
10162         vrf_id_set = 1;
10163       else if (unformat (i, "ipv6"))
10164         is_ipv6 = 1;
10165       else if (unformat (i, "src"))
10166         src = 1;
10167       else if (unformat (i, "dst"))
10168         dst = 1;
10169       else if (unformat (i, "sport"))
10170         sport = 1;
10171       else if (unformat (i, "dport"))
10172         dport = 1;
10173       else if (unformat (i, "proto"))
10174         proto = 1;
10175       else if (unformat (i, "reverse"))
10176         reverse = 1;
10177
10178       else
10179         {
10180           clib_warning ("parse error '%U'", format_unformat_error, i);
10181           return -99;
10182         }
10183     }
10184
10185   if (vrf_id_set == 0)
10186     {
10187       errmsg ("missing vrf id");
10188       return -99;
10189     }
10190
10191   M (SET_IP_FLOW_HASH, mp);
10192   mp->src = src;
10193   mp->dst = dst;
10194   mp->sport = sport;
10195   mp->dport = dport;
10196   mp->proto = proto;
10197   mp->reverse = reverse;
10198   mp->vrf_id = ntohl (vrf_id);
10199   mp->is_ipv6 = is_ipv6;
10200
10201   S (mp);
10202   W (ret);
10203   return ret;
10204 }
10205
10206 static int
10207 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10208 {
10209   unformat_input_t *i = vam->input;
10210   vl_api_sw_interface_ip6_enable_disable_t *mp;
10211   u32 sw_if_index;
10212   u8 sw_if_index_set = 0;
10213   u8 enable = 0;
10214   int ret;
10215
10216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10217     {
10218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10219         sw_if_index_set = 1;
10220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10221         sw_if_index_set = 1;
10222       else if (unformat (i, "enable"))
10223         enable = 1;
10224       else if (unformat (i, "disable"))
10225         enable = 0;
10226       else
10227         {
10228           clib_warning ("parse error '%U'", format_unformat_error, i);
10229           return -99;
10230         }
10231     }
10232
10233   if (sw_if_index_set == 0)
10234     {
10235       errmsg ("missing interface name or sw_if_index");
10236       return -99;
10237     }
10238
10239   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10240
10241   mp->sw_if_index = ntohl (sw_if_index);
10242   mp->enable = enable;
10243
10244   S (mp);
10245   W (ret);
10246   return ret;
10247 }
10248
10249 static int
10250 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10251 {
10252   unformat_input_t *i = vam->input;
10253   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10254   u32 sw_if_index;
10255   u8 sw_if_index_set = 0;
10256   u8 v6_address_set = 0;
10257   ip6_address_t v6address;
10258   int ret;
10259
10260   /* Parse args required to build the message */
10261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10262     {
10263       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10264         sw_if_index_set = 1;
10265       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10266         sw_if_index_set = 1;
10267       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10268         v6_address_set = 1;
10269       else
10270         break;
10271     }
10272
10273   if (sw_if_index_set == 0)
10274     {
10275       errmsg ("missing interface name or sw_if_index");
10276       return -99;
10277     }
10278   if (!v6_address_set)
10279     {
10280       errmsg ("no address set");
10281       return -99;
10282     }
10283
10284   /* Construct the API message */
10285   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10286
10287   mp->sw_if_index = ntohl (sw_if_index);
10288   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10289
10290   /* send it... */
10291   S (mp);
10292
10293   /* Wait for a reply, return good/bad news  */
10294   W (ret);
10295   return ret;
10296 }
10297
10298 static int
10299 api_ip6nd_proxy_add_del (vat_main_t * vam)
10300 {
10301   unformat_input_t *i = vam->input;
10302   vl_api_ip6nd_proxy_add_del_t *mp;
10303   u32 sw_if_index = ~0;
10304   u8 v6_address_set = 0;
10305   ip6_address_t v6address;
10306   u8 is_del = 0;
10307   int ret;
10308
10309   /* Parse args required to build the message */
10310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10311     {
10312       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10313         ;
10314       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10315         ;
10316       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10317         v6_address_set = 1;
10318       if (unformat (i, "del"))
10319         is_del = 1;
10320       else
10321         {
10322           clib_warning ("parse error '%U'", format_unformat_error, i);
10323           return -99;
10324         }
10325     }
10326
10327   if (sw_if_index == ~0)
10328     {
10329       errmsg ("missing interface name or sw_if_index");
10330       return -99;
10331     }
10332   if (!v6_address_set)
10333     {
10334       errmsg ("no address set");
10335       return -99;
10336     }
10337
10338   /* Construct the API message */
10339   M (IP6ND_PROXY_ADD_DEL, mp);
10340
10341   mp->is_del = is_del;
10342   mp->sw_if_index = ntohl (sw_if_index);
10343   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10344
10345   /* send it... */
10346   S (mp);
10347
10348   /* Wait for a reply, return good/bad news  */
10349   W (ret);
10350   return ret;
10351 }
10352
10353 static int
10354 api_ip6nd_proxy_dump (vat_main_t * vam)
10355 {
10356   vl_api_ip6nd_proxy_dump_t *mp;
10357   vl_api_control_ping_t *mp_ping;
10358   int ret;
10359
10360   M (IP6ND_PROXY_DUMP, mp);
10361
10362   S (mp);
10363
10364   /* Use a control ping for synchronization */
10365   MPING (CONTROL_PING, mp_ping);
10366   S (mp_ping);
10367
10368   W (ret);
10369   return ret;
10370 }
10371
10372 static void vl_api_ip6nd_proxy_details_t_handler
10373   (vl_api_ip6nd_proxy_details_t * mp)
10374 {
10375   vat_main_t *vam = &vat_main;
10376
10377   print (vam->ofp, "host %U sw_if_index %d",
10378          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10379 }
10380
10381 static void vl_api_ip6nd_proxy_details_t_handler_json
10382   (vl_api_ip6nd_proxy_details_t * mp)
10383 {
10384   vat_main_t *vam = &vat_main;
10385   struct in6_addr ip6;
10386   vat_json_node_t *node = NULL;
10387
10388   if (VAT_JSON_ARRAY != vam->json_tree.type)
10389     {
10390       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10391       vat_json_init_array (&vam->json_tree);
10392     }
10393   node = vat_json_array_add (&vam->json_tree);
10394
10395   vat_json_init_object (node);
10396   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10397
10398   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10399   vat_json_object_add_ip6 (node, "host", ip6);
10400 }
10401
10402 static int
10403 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10404 {
10405   unformat_input_t *i = vam->input;
10406   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10407   u32 sw_if_index;
10408   u8 sw_if_index_set = 0;
10409   u32 address_length = 0;
10410   u8 v6_address_set = 0;
10411   ip6_address_t v6address;
10412   u8 use_default = 0;
10413   u8 no_advertise = 0;
10414   u8 off_link = 0;
10415   u8 no_autoconfig = 0;
10416   u8 no_onlink = 0;
10417   u8 is_no = 0;
10418   u32 val_lifetime = 0;
10419   u32 pref_lifetime = 0;
10420   int ret;
10421
10422   /* Parse args required to build the message */
10423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10424     {
10425       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10426         sw_if_index_set = 1;
10427       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10428         sw_if_index_set = 1;
10429       else if (unformat (i, "%U/%d",
10430                          unformat_ip6_address, &v6address, &address_length))
10431         v6_address_set = 1;
10432       else if (unformat (i, "val_life %d", &val_lifetime))
10433         ;
10434       else if (unformat (i, "pref_life %d", &pref_lifetime))
10435         ;
10436       else if (unformat (i, "def"))
10437         use_default = 1;
10438       else if (unformat (i, "noadv"))
10439         no_advertise = 1;
10440       else if (unformat (i, "offl"))
10441         off_link = 1;
10442       else if (unformat (i, "noauto"))
10443         no_autoconfig = 1;
10444       else if (unformat (i, "nolink"))
10445         no_onlink = 1;
10446       else if (unformat (i, "isno"))
10447         is_no = 1;
10448       else
10449         {
10450           clib_warning ("parse error '%U'", format_unformat_error, i);
10451           return -99;
10452         }
10453     }
10454
10455   if (sw_if_index_set == 0)
10456     {
10457       errmsg ("missing interface name or sw_if_index");
10458       return -99;
10459     }
10460   if (!v6_address_set)
10461     {
10462       errmsg ("no address set");
10463       return -99;
10464     }
10465
10466   /* Construct the API message */
10467   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10468
10469   mp->sw_if_index = ntohl (sw_if_index);
10470   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10471   mp->address_length = address_length;
10472   mp->use_default = use_default;
10473   mp->no_advertise = no_advertise;
10474   mp->off_link = off_link;
10475   mp->no_autoconfig = no_autoconfig;
10476   mp->no_onlink = no_onlink;
10477   mp->is_no = is_no;
10478   mp->val_lifetime = ntohl (val_lifetime);
10479   mp->pref_lifetime = ntohl (pref_lifetime);
10480
10481   /* send it... */
10482   S (mp);
10483
10484   /* Wait for a reply, return good/bad news  */
10485   W (ret);
10486   return ret;
10487 }
10488
10489 static int
10490 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10491 {
10492   unformat_input_t *i = vam->input;
10493   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10494   u32 sw_if_index;
10495   u8 sw_if_index_set = 0;
10496   u8 suppress = 0;
10497   u8 managed = 0;
10498   u8 other = 0;
10499   u8 ll_option = 0;
10500   u8 send_unicast = 0;
10501   u8 cease = 0;
10502   u8 is_no = 0;
10503   u8 default_router = 0;
10504   u32 max_interval = 0;
10505   u32 min_interval = 0;
10506   u32 lifetime = 0;
10507   u32 initial_count = 0;
10508   u32 initial_interval = 0;
10509   int ret;
10510
10511
10512   /* Parse args required to build the message */
10513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10514     {
10515       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10516         sw_if_index_set = 1;
10517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10518         sw_if_index_set = 1;
10519       else if (unformat (i, "maxint %d", &max_interval))
10520         ;
10521       else if (unformat (i, "minint %d", &min_interval))
10522         ;
10523       else if (unformat (i, "life %d", &lifetime))
10524         ;
10525       else if (unformat (i, "count %d", &initial_count))
10526         ;
10527       else if (unformat (i, "interval %d", &initial_interval))
10528         ;
10529       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10530         suppress = 1;
10531       else if (unformat (i, "managed"))
10532         managed = 1;
10533       else if (unformat (i, "other"))
10534         other = 1;
10535       else if (unformat (i, "ll"))
10536         ll_option = 1;
10537       else if (unformat (i, "send"))
10538         send_unicast = 1;
10539       else if (unformat (i, "cease"))
10540         cease = 1;
10541       else if (unformat (i, "isno"))
10542         is_no = 1;
10543       else if (unformat (i, "def"))
10544         default_router = 1;
10545       else
10546         {
10547           clib_warning ("parse error '%U'", format_unformat_error, i);
10548           return -99;
10549         }
10550     }
10551
10552   if (sw_if_index_set == 0)
10553     {
10554       errmsg ("missing interface name or sw_if_index");
10555       return -99;
10556     }
10557
10558   /* Construct the API message */
10559   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10560
10561   mp->sw_if_index = ntohl (sw_if_index);
10562   mp->max_interval = ntohl (max_interval);
10563   mp->min_interval = ntohl (min_interval);
10564   mp->lifetime = ntohl (lifetime);
10565   mp->initial_count = ntohl (initial_count);
10566   mp->initial_interval = ntohl (initial_interval);
10567   mp->suppress = suppress;
10568   mp->managed = managed;
10569   mp->other = other;
10570   mp->ll_option = ll_option;
10571   mp->send_unicast = send_unicast;
10572   mp->cease = cease;
10573   mp->is_no = is_no;
10574   mp->default_router = default_router;
10575
10576   /* send it... */
10577   S (mp);
10578
10579   /* Wait for a reply, return good/bad news  */
10580   W (ret);
10581   return ret;
10582 }
10583
10584 static int
10585 api_set_arp_neighbor_limit (vat_main_t * vam)
10586 {
10587   unformat_input_t *i = vam->input;
10588   vl_api_set_arp_neighbor_limit_t *mp;
10589   u32 arp_nbr_limit;
10590   u8 limit_set = 0;
10591   u8 is_ipv6 = 0;
10592   int ret;
10593
10594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10595     {
10596       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10597         limit_set = 1;
10598       else if (unformat (i, "ipv6"))
10599         is_ipv6 = 1;
10600       else
10601         {
10602           clib_warning ("parse error '%U'", format_unformat_error, i);
10603           return -99;
10604         }
10605     }
10606
10607   if (limit_set == 0)
10608     {
10609       errmsg ("missing limit value");
10610       return -99;
10611     }
10612
10613   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10614
10615   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10616   mp->is_ipv6 = is_ipv6;
10617
10618   S (mp);
10619   W (ret);
10620   return ret;
10621 }
10622
10623 static int
10624 api_l2_patch_add_del (vat_main_t * vam)
10625 {
10626   unformat_input_t *i = vam->input;
10627   vl_api_l2_patch_add_del_t *mp;
10628   u32 rx_sw_if_index;
10629   u8 rx_sw_if_index_set = 0;
10630   u32 tx_sw_if_index;
10631   u8 tx_sw_if_index_set = 0;
10632   u8 is_add = 1;
10633   int ret;
10634
10635   /* Parse args required to build the message */
10636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10637     {
10638       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10639         rx_sw_if_index_set = 1;
10640       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10641         tx_sw_if_index_set = 1;
10642       else if (unformat (i, "rx"))
10643         {
10644           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10645             {
10646               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10647                             &rx_sw_if_index))
10648                 rx_sw_if_index_set = 1;
10649             }
10650           else
10651             break;
10652         }
10653       else if (unformat (i, "tx"))
10654         {
10655           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10656             {
10657               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10658                             &tx_sw_if_index))
10659                 tx_sw_if_index_set = 1;
10660             }
10661           else
10662             break;
10663         }
10664       else if (unformat (i, "del"))
10665         is_add = 0;
10666       else
10667         break;
10668     }
10669
10670   if (rx_sw_if_index_set == 0)
10671     {
10672       errmsg ("missing rx interface name or rx_sw_if_index");
10673       return -99;
10674     }
10675
10676   if (tx_sw_if_index_set == 0)
10677     {
10678       errmsg ("missing tx interface name or tx_sw_if_index");
10679       return -99;
10680     }
10681
10682   M (L2_PATCH_ADD_DEL, mp);
10683
10684   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10685   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10686   mp->is_add = is_add;
10687
10688   S (mp);
10689   W (ret);
10690   return ret;
10691 }
10692
10693 u8 is_del;
10694 u8 localsid_addr[16];
10695 u8 end_psp;
10696 u8 behavior;
10697 u32 sw_if_index;
10698 u32 vlan_index;
10699 u32 fib_table;
10700 u8 nh_addr[16];
10701
10702 static int
10703 api_sr_localsid_add_del (vat_main_t * vam)
10704 {
10705   unformat_input_t *i = vam->input;
10706   vl_api_sr_localsid_add_del_t *mp;
10707
10708   u8 is_del;
10709   ip6_address_t localsid;
10710   u8 end_psp = 0;
10711   u8 behavior = ~0;
10712   u32 sw_if_index;
10713   u32 fib_table = ~(u32) 0;
10714   ip6_address_t next_hop;
10715
10716   bool nexthop_set = 0;
10717
10718   int ret;
10719
10720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10721     {
10722       if (unformat (i, "del"))
10723         is_del = 1;
10724       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10725       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10726         nexthop_set = 1;
10727       else if (unformat (i, "behavior %u", &behavior));
10728       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10729       else if (unformat (i, "fib-table %u", &fib_table));
10730       else if (unformat (i, "end.psp %u", &behavior));
10731       else
10732         break;
10733     }
10734
10735   M (SR_LOCALSID_ADD_DEL, mp);
10736
10737   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10738   if (nexthop_set)
10739     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10740   mp->behavior = behavior;
10741   mp->sw_if_index = ntohl (sw_if_index);
10742   mp->fib_table = ntohl (fib_table);
10743   mp->end_psp = end_psp;
10744   mp->is_del = is_del;
10745
10746   S (mp);
10747   W (ret);
10748   return ret;
10749 }
10750
10751 static int
10752 api_ioam_enable (vat_main_t * vam)
10753 {
10754   unformat_input_t *input = vam->input;
10755   vl_api_ioam_enable_t *mp;
10756   u32 id = 0;
10757   int has_trace_option = 0;
10758   int has_pot_option = 0;
10759   int has_seqno_option = 0;
10760   int has_analyse_option = 0;
10761   int ret;
10762
10763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10764     {
10765       if (unformat (input, "trace"))
10766         has_trace_option = 1;
10767       else if (unformat (input, "pot"))
10768         has_pot_option = 1;
10769       else if (unformat (input, "seqno"))
10770         has_seqno_option = 1;
10771       else if (unformat (input, "analyse"))
10772         has_analyse_option = 1;
10773       else
10774         break;
10775     }
10776   M (IOAM_ENABLE, mp);
10777   mp->id = htons (id);
10778   mp->seqno = has_seqno_option;
10779   mp->analyse = has_analyse_option;
10780   mp->pot_enable = has_pot_option;
10781   mp->trace_enable = has_trace_option;
10782
10783   S (mp);
10784   W (ret);
10785   return ret;
10786 }
10787
10788
10789 static int
10790 api_ioam_disable (vat_main_t * vam)
10791 {
10792   vl_api_ioam_disable_t *mp;
10793   int ret;
10794
10795   M (IOAM_DISABLE, mp);
10796   S (mp);
10797   W (ret);
10798   return ret;
10799 }
10800
10801 #define foreach_tcp_proto_field                 \
10802 _(src_port)                                     \
10803 _(dst_port)
10804
10805 #define foreach_udp_proto_field                 \
10806 _(src_port)                                     \
10807 _(dst_port)
10808
10809 #define foreach_ip4_proto_field                 \
10810 _(src_address)                                  \
10811 _(dst_address)                                  \
10812 _(tos)                                          \
10813 _(length)                                       \
10814 _(fragment_id)                                  \
10815 _(ttl)                                          \
10816 _(protocol)                                     \
10817 _(checksum)
10818
10819 typedef struct
10820 {
10821   u16 src_port, dst_port;
10822 } tcpudp_header_t;
10823
10824 #if VPP_API_TEST_BUILTIN == 0
10825 uword
10826 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10827 {
10828   u8 **maskp = va_arg (*args, u8 **);
10829   u8 *mask = 0;
10830   u8 found_something = 0;
10831   tcp_header_t *tcp;
10832
10833 #define _(a) u8 a=0;
10834   foreach_tcp_proto_field;
10835 #undef _
10836
10837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10838     {
10839       if (0);
10840 #define _(a) else if (unformat (input, #a)) a=1;
10841       foreach_tcp_proto_field
10842 #undef _
10843         else
10844         break;
10845     }
10846
10847 #define _(a) found_something += a;
10848   foreach_tcp_proto_field;
10849 #undef _
10850
10851   if (found_something == 0)
10852     return 0;
10853
10854   vec_validate (mask, sizeof (*tcp) - 1);
10855
10856   tcp = (tcp_header_t *) mask;
10857
10858 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10859   foreach_tcp_proto_field;
10860 #undef _
10861
10862   *maskp = mask;
10863   return 1;
10864 }
10865
10866 uword
10867 unformat_udp_mask (unformat_input_t * input, va_list * args)
10868 {
10869   u8 **maskp = va_arg (*args, u8 **);
10870   u8 *mask = 0;
10871   u8 found_something = 0;
10872   udp_header_t *udp;
10873
10874 #define _(a) u8 a=0;
10875   foreach_udp_proto_field;
10876 #undef _
10877
10878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10879     {
10880       if (0);
10881 #define _(a) else if (unformat (input, #a)) a=1;
10882       foreach_udp_proto_field
10883 #undef _
10884         else
10885         break;
10886     }
10887
10888 #define _(a) found_something += a;
10889   foreach_udp_proto_field;
10890 #undef _
10891
10892   if (found_something == 0)
10893     return 0;
10894
10895   vec_validate (mask, sizeof (*udp) - 1);
10896
10897   udp = (udp_header_t *) mask;
10898
10899 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10900   foreach_udp_proto_field;
10901 #undef _
10902
10903   *maskp = mask;
10904   return 1;
10905 }
10906
10907 uword
10908 unformat_l4_mask (unformat_input_t * input, va_list * args)
10909 {
10910   u8 **maskp = va_arg (*args, u8 **);
10911   u16 src_port = 0, dst_port = 0;
10912   tcpudp_header_t *tcpudp;
10913
10914   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10915     {
10916       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10917         return 1;
10918       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10919         return 1;
10920       else if (unformat (input, "src_port"))
10921         src_port = 0xFFFF;
10922       else if (unformat (input, "dst_port"))
10923         dst_port = 0xFFFF;
10924       else
10925         return 0;
10926     }
10927
10928   if (!src_port && !dst_port)
10929     return 0;
10930
10931   u8 *mask = 0;
10932   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10933
10934   tcpudp = (tcpudp_header_t *) mask;
10935   tcpudp->src_port = src_port;
10936   tcpudp->dst_port = dst_port;
10937
10938   *maskp = mask;
10939
10940   return 1;
10941 }
10942
10943 uword
10944 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10945 {
10946   u8 **maskp = va_arg (*args, u8 **);
10947   u8 *mask = 0;
10948   u8 found_something = 0;
10949   ip4_header_t *ip;
10950
10951 #define _(a) u8 a=0;
10952   foreach_ip4_proto_field;
10953 #undef _
10954   u8 version = 0;
10955   u8 hdr_length = 0;
10956
10957
10958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10959     {
10960       if (unformat (input, "version"))
10961         version = 1;
10962       else if (unformat (input, "hdr_length"))
10963         hdr_length = 1;
10964       else if (unformat (input, "src"))
10965         src_address = 1;
10966       else if (unformat (input, "dst"))
10967         dst_address = 1;
10968       else if (unformat (input, "proto"))
10969         protocol = 1;
10970
10971 #define _(a) else if (unformat (input, #a)) a=1;
10972       foreach_ip4_proto_field
10973 #undef _
10974         else
10975         break;
10976     }
10977
10978 #define _(a) found_something += a;
10979   foreach_ip4_proto_field;
10980 #undef _
10981
10982   if (found_something == 0)
10983     return 0;
10984
10985   vec_validate (mask, sizeof (*ip) - 1);
10986
10987   ip = (ip4_header_t *) mask;
10988
10989 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10990   foreach_ip4_proto_field;
10991 #undef _
10992
10993   ip->ip_version_and_header_length = 0;
10994
10995   if (version)
10996     ip->ip_version_and_header_length |= 0xF0;
10997
10998   if (hdr_length)
10999     ip->ip_version_and_header_length |= 0x0F;
11000
11001   *maskp = mask;
11002   return 1;
11003 }
11004
11005 #define foreach_ip6_proto_field                 \
11006 _(src_address)                                  \
11007 _(dst_address)                                  \
11008 _(payload_length)                               \
11009 _(hop_limit)                                    \
11010 _(protocol)
11011
11012 uword
11013 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11014 {
11015   u8 **maskp = va_arg (*args, u8 **);
11016   u8 *mask = 0;
11017   u8 found_something = 0;
11018   ip6_header_t *ip;
11019   u32 ip_version_traffic_class_and_flow_label;
11020
11021 #define _(a) u8 a=0;
11022   foreach_ip6_proto_field;
11023 #undef _
11024   u8 version = 0;
11025   u8 traffic_class = 0;
11026   u8 flow_label = 0;
11027
11028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11029     {
11030       if (unformat (input, "version"))
11031         version = 1;
11032       else if (unformat (input, "traffic-class"))
11033         traffic_class = 1;
11034       else if (unformat (input, "flow-label"))
11035         flow_label = 1;
11036       else if (unformat (input, "src"))
11037         src_address = 1;
11038       else if (unformat (input, "dst"))
11039         dst_address = 1;
11040       else if (unformat (input, "proto"))
11041         protocol = 1;
11042
11043 #define _(a) else if (unformat (input, #a)) a=1;
11044       foreach_ip6_proto_field
11045 #undef _
11046         else
11047         break;
11048     }
11049
11050 #define _(a) found_something += a;
11051   foreach_ip6_proto_field;
11052 #undef _
11053
11054   if (found_something == 0)
11055     return 0;
11056
11057   vec_validate (mask, sizeof (*ip) - 1);
11058
11059   ip = (ip6_header_t *) mask;
11060
11061 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11062   foreach_ip6_proto_field;
11063 #undef _
11064
11065   ip_version_traffic_class_and_flow_label = 0;
11066
11067   if (version)
11068     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11069
11070   if (traffic_class)
11071     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11072
11073   if (flow_label)
11074     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11075
11076   ip->ip_version_traffic_class_and_flow_label =
11077     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11078
11079   *maskp = mask;
11080   return 1;
11081 }
11082
11083 uword
11084 unformat_l3_mask (unformat_input_t * input, va_list * args)
11085 {
11086   u8 **maskp = va_arg (*args, u8 **);
11087
11088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11089     {
11090       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11091         return 1;
11092       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11093         return 1;
11094       else
11095         break;
11096     }
11097   return 0;
11098 }
11099
11100 uword
11101 unformat_l2_mask (unformat_input_t * input, va_list * args)
11102 {
11103   u8 **maskp = va_arg (*args, u8 **);
11104   u8 *mask = 0;
11105   u8 src = 0;
11106   u8 dst = 0;
11107   u8 proto = 0;
11108   u8 tag1 = 0;
11109   u8 tag2 = 0;
11110   u8 ignore_tag1 = 0;
11111   u8 ignore_tag2 = 0;
11112   u8 cos1 = 0;
11113   u8 cos2 = 0;
11114   u8 dot1q = 0;
11115   u8 dot1ad = 0;
11116   int len = 14;
11117
11118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11119     {
11120       if (unformat (input, "src"))
11121         src = 1;
11122       else if (unformat (input, "dst"))
11123         dst = 1;
11124       else if (unformat (input, "proto"))
11125         proto = 1;
11126       else if (unformat (input, "tag1"))
11127         tag1 = 1;
11128       else if (unformat (input, "tag2"))
11129         tag2 = 1;
11130       else if (unformat (input, "ignore-tag1"))
11131         ignore_tag1 = 1;
11132       else if (unformat (input, "ignore-tag2"))
11133         ignore_tag2 = 1;
11134       else if (unformat (input, "cos1"))
11135         cos1 = 1;
11136       else if (unformat (input, "cos2"))
11137         cos2 = 1;
11138       else if (unformat (input, "dot1q"))
11139         dot1q = 1;
11140       else if (unformat (input, "dot1ad"))
11141         dot1ad = 1;
11142       else
11143         break;
11144     }
11145   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11146        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11147     return 0;
11148
11149   if (tag1 || ignore_tag1 || cos1 || dot1q)
11150     len = 18;
11151   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11152     len = 22;
11153
11154   vec_validate (mask, len - 1);
11155
11156   if (dst)
11157     memset (mask, 0xff, 6);
11158
11159   if (src)
11160     memset (mask + 6, 0xff, 6);
11161
11162   if (tag2 || dot1ad)
11163     {
11164       /* inner vlan tag */
11165       if (tag2)
11166         {
11167           mask[19] = 0xff;
11168           mask[18] = 0x0f;
11169         }
11170       if (cos2)
11171         mask[18] |= 0xe0;
11172       if (proto)
11173         mask[21] = mask[20] = 0xff;
11174       if (tag1)
11175         {
11176           mask[15] = 0xff;
11177           mask[14] = 0x0f;
11178         }
11179       if (cos1)
11180         mask[14] |= 0xe0;
11181       *maskp = mask;
11182       return 1;
11183     }
11184   if (tag1 | dot1q)
11185     {
11186       if (tag1)
11187         {
11188           mask[15] = 0xff;
11189           mask[14] = 0x0f;
11190         }
11191       if (cos1)
11192         mask[14] |= 0xe0;
11193       if (proto)
11194         mask[16] = mask[17] = 0xff;
11195
11196       *maskp = mask;
11197       return 1;
11198     }
11199   if (cos2)
11200     mask[18] |= 0xe0;
11201   if (cos1)
11202     mask[14] |= 0xe0;
11203   if (proto)
11204     mask[12] = mask[13] = 0xff;
11205
11206   *maskp = mask;
11207   return 1;
11208 }
11209
11210 uword
11211 unformat_classify_mask (unformat_input_t * input, va_list * args)
11212 {
11213   u8 **maskp = va_arg (*args, u8 **);
11214   u32 *skipp = va_arg (*args, u32 *);
11215   u32 *matchp = va_arg (*args, u32 *);
11216   u32 match;
11217   u8 *mask = 0;
11218   u8 *l2 = 0;
11219   u8 *l3 = 0;
11220   u8 *l4 = 0;
11221   int i;
11222
11223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11224     {
11225       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11226         ;
11227       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11228         ;
11229       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11230         ;
11231       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11232         ;
11233       else
11234         break;
11235     }
11236
11237   if (l4 && !l3)
11238     {
11239       vec_free (mask);
11240       vec_free (l2);
11241       vec_free (l4);
11242       return 0;
11243     }
11244
11245   if (mask || l2 || l3 || l4)
11246     {
11247       if (l2 || l3 || l4)
11248         {
11249           /* "With a free Ethernet header in every package" */
11250           if (l2 == 0)
11251             vec_validate (l2, 13);
11252           mask = l2;
11253           if (vec_len (l3))
11254             {
11255               vec_append (mask, l3);
11256               vec_free (l3);
11257             }
11258           if (vec_len (l4))
11259             {
11260               vec_append (mask, l4);
11261               vec_free (l4);
11262             }
11263         }
11264
11265       /* Scan forward looking for the first significant mask octet */
11266       for (i = 0; i < vec_len (mask); i++)
11267         if (mask[i])
11268           break;
11269
11270       /* compute (skip, match) params */
11271       *skipp = i / sizeof (u32x4);
11272       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11273
11274       /* Pad mask to an even multiple of the vector size */
11275       while (vec_len (mask) % sizeof (u32x4))
11276         vec_add1 (mask, 0);
11277
11278       match = vec_len (mask) / sizeof (u32x4);
11279
11280       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11281         {
11282           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11283           if (*tmp || *(tmp + 1))
11284             break;
11285           match--;
11286         }
11287       if (match == 0)
11288         clib_warning ("BUG: match 0");
11289
11290       _vec_len (mask) = match * sizeof (u32x4);
11291
11292       *matchp = match;
11293       *maskp = mask;
11294
11295       return 1;
11296     }
11297
11298   return 0;
11299 }
11300 #endif /* VPP_API_TEST_BUILTIN */
11301
11302 #define foreach_l2_next                         \
11303 _(drop, DROP)                                   \
11304 _(ethernet, ETHERNET_INPUT)                     \
11305 _(ip4, IP4_INPUT)                               \
11306 _(ip6, IP6_INPUT)
11307
11308 uword
11309 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11310 {
11311   u32 *miss_next_indexp = va_arg (*args, u32 *);
11312   u32 next_index = 0;
11313   u32 tmp;
11314
11315 #define _(n,N) \
11316   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11317   foreach_l2_next;
11318 #undef _
11319
11320   if (unformat (input, "%d", &tmp))
11321     {
11322       next_index = tmp;
11323       goto out;
11324     }
11325
11326   return 0;
11327
11328 out:
11329   *miss_next_indexp = next_index;
11330   return 1;
11331 }
11332
11333 #define foreach_ip_next                         \
11334 _(drop, DROP)                                   \
11335 _(local, LOCAL)                                 \
11336 _(rewrite, REWRITE)
11337
11338 uword
11339 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11340 {
11341   u32 *miss_next_indexp = va_arg (*args, u32 *);
11342   u32 next_index = 0;
11343   u32 tmp;
11344
11345 #define _(n,N) \
11346   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11347   foreach_ip_next;
11348 #undef _
11349
11350   if (unformat (input, "%d", &tmp))
11351     {
11352       next_index = tmp;
11353       goto out;
11354     }
11355
11356   return 0;
11357
11358 out:
11359   *miss_next_indexp = next_index;
11360   return 1;
11361 }
11362
11363 #define foreach_acl_next                        \
11364 _(deny, DENY)
11365
11366 uword
11367 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11368 {
11369   u32 *miss_next_indexp = va_arg (*args, u32 *);
11370   u32 next_index = 0;
11371   u32 tmp;
11372
11373 #define _(n,N) \
11374   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11375   foreach_acl_next;
11376 #undef _
11377
11378   if (unformat (input, "permit"))
11379     {
11380       next_index = ~0;
11381       goto out;
11382     }
11383   else if (unformat (input, "%d", &tmp))
11384     {
11385       next_index = tmp;
11386       goto out;
11387     }
11388
11389   return 0;
11390
11391 out:
11392   *miss_next_indexp = next_index;
11393   return 1;
11394 }
11395
11396 uword
11397 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11398 {
11399   u32 *r = va_arg (*args, u32 *);
11400
11401   if (unformat (input, "conform-color"))
11402     *r = POLICE_CONFORM;
11403   else if (unformat (input, "exceed-color"))
11404     *r = POLICE_EXCEED;
11405   else
11406     return 0;
11407
11408   return 1;
11409 }
11410
11411 static int
11412 api_classify_add_del_table (vat_main_t * vam)
11413 {
11414   unformat_input_t *i = vam->input;
11415   vl_api_classify_add_del_table_t *mp;
11416
11417   u32 nbuckets = 2;
11418   u32 skip = ~0;
11419   u32 match = ~0;
11420   int is_add = 1;
11421   int del_chain = 0;
11422   u32 table_index = ~0;
11423   u32 next_table_index = ~0;
11424   u32 miss_next_index = ~0;
11425   u32 memory_size = 32 << 20;
11426   u8 *mask = 0;
11427   u32 current_data_flag = 0;
11428   int current_data_offset = 0;
11429   int ret;
11430
11431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11432     {
11433       if (unformat (i, "del"))
11434         is_add = 0;
11435       else if (unformat (i, "del-chain"))
11436         {
11437           is_add = 0;
11438           del_chain = 1;
11439         }
11440       else if (unformat (i, "buckets %d", &nbuckets))
11441         ;
11442       else if (unformat (i, "memory_size %d", &memory_size))
11443         ;
11444       else if (unformat (i, "skip %d", &skip))
11445         ;
11446       else if (unformat (i, "match %d", &match))
11447         ;
11448       else if (unformat (i, "table %d", &table_index))
11449         ;
11450       else if (unformat (i, "mask %U", unformat_classify_mask,
11451                          &mask, &skip, &match))
11452         ;
11453       else if (unformat (i, "next-table %d", &next_table_index))
11454         ;
11455       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11456                          &miss_next_index))
11457         ;
11458       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11459                          &miss_next_index))
11460         ;
11461       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11462                          &miss_next_index))
11463         ;
11464       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11465         ;
11466       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11467         ;
11468       else
11469         break;
11470     }
11471
11472   if (is_add && mask == 0)
11473     {
11474       errmsg ("Mask required");
11475       return -99;
11476     }
11477
11478   if (is_add && skip == ~0)
11479     {
11480       errmsg ("skip count required");
11481       return -99;
11482     }
11483
11484   if (is_add && match == ~0)
11485     {
11486       errmsg ("match count required");
11487       return -99;
11488     }
11489
11490   if (!is_add && table_index == ~0)
11491     {
11492       errmsg ("table index required for delete");
11493       return -99;
11494     }
11495
11496   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11497
11498   mp->is_add = is_add;
11499   mp->del_chain = del_chain;
11500   mp->table_index = ntohl (table_index);
11501   mp->nbuckets = ntohl (nbuckets);
11502   mp->memory_size = ntohl (memory_size);
11503   mp->skip_n_vectors = ntohl (skip);
11504   mp->match_n_vectors = ntohl (match);
11505   mp->next_table_index = ntohl (next_table_index);
11506   mp->miss_next_index = ntohl (miss_next_index);
11507   mp->current_data_flag = ntohl (current_data_flag);
11508   mp->current_data_offset = ntohl (current_data_offset);
11509   clib_memcpy (mp->mask, mask, vec_len (mask));
11510
11511   vec_free (mask);
11512
11513   S (mp);
11514   W (ret);
11515   return ret;
11516 }
11517
11518 #if VPP_API_TEST_BUILTIN == 0
11519 uword
11520 unformat_l4_match (unformat_input_t * input, va_list * args)
11521 {
11522   u8 **matchp = va_arg (*args, u8 **);
11523
11524   u8 *proto_header = 0;
11525   int src_port = 0;
11526   int dst_port = 0;
11527
11528   tcpudp_header_t h;
11529
11530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11531     {
11532       if (unformat (input, "src_port %d", &src_port))
11533         ;
11534       else if (unformat (input, "dst_port %d", &dst_port))
11535         ;
11536       else
11537         return 0;
11538     }
11539
11540   h.src_port = clib_host_to_net_u16 (src_port);
11541   h.dst_port = clib_host_to_net_u16 (dst_port);
11542   vec_validate (proto_header, sizeof (h) - 1);
11543   memcpy (proto_header, &h, sizeof (h));
11544
11545   *matchp = proto_header;
11546
11547   return 1;
11548 }
11549
11550 uword
11551 unformat_ip4_match (unformat_input_t * input, va_list * args)
11552 {
11553   u8 **matchp = va_arg (*args, u8 **);
11554   u8 *match = 0;
11555   ip4_header_t *ip;
11556   int version = 0;
11557   u32 version_val;
11558   int hdr_length = 0;
11559   u32 hdr_length_val;
11560   int src = 0, dst = 0;
11561   ip4_address_t src_val, dst_val;
11562   int proto = 0;
11563   u32 proto_val;
11564   int tos = 0;
11565   u32 tos_val;
11566   int length = 0;
11567   u32 length_val;
11568   int fragment_id = 0;
11569   u32 fragment_id_val;
11570   int ttl = 0;
11571   int ttl_val;
11572   int checksum = 0;
11573   u32 checksum_val;
11574
11575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11576     {
11577       if (unformat (input, "version %d", &version_val))
11578         version = 1;
11579       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11580         hdr_length = 1;
11581       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11582         src = 1;
11583       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11584         dst = 1;
11585       else if (unformat (input, "proto %d", &proto_val))
11586         proto = 1;
11587       else if (unformat (input, "tos %d", &tos_val))
11588         tos = 1;
11589       else if (unformat (input, "length %d", &length_val))
11590         length = 1;
11591       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11592         fragment_id = 1;
11593       else if (unformat (input, "ttl %d", &ttl_val))
11594         ttl = 1;
11595       else if (unformat (input, "checksum %d", &checksum_val))
11596         checksum = 1;
11597       else
11598         break;
11599     }
11600
11601   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11602       + ttl + checksum == 0)
11603     return 0;
11604
11605   /*
11606    * Aligned because we use the real comparison functions
11607    */
11608   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11609
11610   ip = (ip4_header_t *) match;
11611
11612   /* These are realistically matched in practice */
11613   if (src)
11614     ip->src_address.as_u32 = src_val.as_u32;
11615
11616   if (dst)
11617     ip->dst_address.as_u32 = dst_val.as_u32;
11618
11619   if (proto)
11620     ip->protocol = proto_val;
11621
11622
11623   /* These are not, but they're included for completeness */
11624   if (version)
11625     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11626
11627   if (hdr_length)
11628     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11629
11630   if (tos)
11631     ip->tos = tos_val;
11632
11633   if (length)
11634     ip->length = clib_host_to_net_u16 (length_val);
11635
11636   if (ttl)
11637     ip->ttl = ttl_val;
11638
11639   if (checksum)
11640     ip->checksum = clib_host_to_net_u16 (checksum_val);
11641
11642   *matchp = match;
11643   return 1;
11644 }
11645
11646 uword
11647 unformat_ip6_match (unformat_input_t * input, va_list * args)
11648 {
11649   u8 **matchp = va_arg (*args, u8 **);
11650   u8 *match = 0;
11651   ip6_header_t *ip;
11652   int version = 0;
11653   u32 version_val;
11654   u8 traffic_class = 0;
11655   u32 traffic_class_val = 0;
11656   u8 flow_label = 0;
11657   u8 flow_label_val;
11658   int src = 0, dst = 0;
11659   ip6_address_t src_val, dst_val;
11660   int proto = 0;
11661   u32 proto_val;
11662   int payload_length = 0;
11663   u32 payload_length_val;
11664   int hop_limit = 0;
11665   int hop_limit_val;
11666   u32 ip_version_traffic_class_and_flow_label;
11667
11668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11669     {
11670       if (unformat (input, "version %d", &version_val))
11671         version = 1;
11672       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11673         traffic_class = 1;
11674       else if (unformat (input, "flow_label %d", &flow_label_val))
11675         flow_label = 1;
11676       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11677         src = 1;
11678       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11679         dst = 1;
11680       else if (unformat (input, "proto %d", &proto_val))
11681         proto = 1;
11682       else if (unformat (input, "payload_length %d", &payload_length_val))
11683         payload_length = 1;
11684       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11685         hop_limit = 1;
11686       else
11687         break;
11688     }
11689
11690   if (version + traffic_class + flow_label + src + dst + proto +
11691       payload_length + hop_limit == 0)
11692     return 0;
11693
11694   /*
11695    * Aligned because we use the real comparison functions
11696    */
11697   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11698
11699   ip = (ip6_header_t *) match;
11700
11701   if (src)
11702     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11703
11704   if (dst)
11705     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11706
11707   if (proto)
11708     ip->protocol = proto_val;
11709
11710   ip_version_traffic_class_and_flow_label = 0;
11711
11712   if (version)
11713     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11714
11715   if (traffic_class)
11716     ip_version_traffic_class_and_flow_label |=
11717       (traffic_class_val & 0xFF) << 20;
11718
11719   if (flow_label)
11720     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11721
11722   ip->ip_version_traffic_class_and_flow_label =
11723     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11724
11725   if (payload_length)
11726     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11727
11728   if (hop_limit)
11729     ip->hop_limit = hop_limit_val;
11730
11731   *matchp = match;
11732   return 1;
11733 }
11734
11735 uword
11736 unformat_l3_match (unformat_input_t * input, va_list * args)
11737 {
11738   u8 **matchp = va_arg (*args, u8 **);
11739
11740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11741     {
11742       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11743         return 1;
11744       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11745         return 1;
11746       else
11747         break;
11748     }
11749   return 0;
11750 }
11751
11752 uword
11753 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11754 {
11755   u8 *tagp = va_arg (*args, u8 *);
11756   u32 tag;
11757
11758   if (unformat (input, "%d", &tag))
11759     {
11760       tagp[0] = (tag >> 8) & 0x0F;
11761       tagp[1] = tag & 0xFF;
11762       return 1;
11763     }
11764
11765   return 0;
11766 }
11767
11768 uword
11769 unformat_l2_match (unformat_input_t * input, va_list * args)
11770 {
11771   u8 **matchp = va_arg (*args, u8 **);
11772   u8 *match = 0;
11773   u8 src = 0;
11774   u8 src_val[6];
11775   u8 dst = 0;
11776   u8 dst_val[6];
11777   u8 proto = 0;
11778   u16 proto_val;
11779   u8 tag1 = 0;
11780   u8 tag1_val[2];
11781   u8 tag2 = 0;
11782   u8 tag2_val[2];
11783   int len = 14;
11784   u8 ignore_tag1 = 0;
11785   u8 ignore_tag2 = 0;
11786   u8 cos1 = 0;
11787   u8 cos2 = 0;
11788   u32 cos1_val = 0;
11789   u32 cos2_val = 0;
11790
11791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11792     {
11793       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11794         src = 1;
11795       else
11796         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11797         dst = 1;
11798       else if (unformat (input, "proto %U",
11799                          unformat_ethernet_type_host_byte_order, &proto_val))
11800         proto = 1;
11801       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11802         tag1 = 1;
11803       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11804         tag2 = 1;
11805       else if (unformat (input, "ignore-tag1"))
11806         ignore_tag1 = 1;
11807       else if (unformat (input, "ignore-tag2"))
11808         ignore_tag2 = 1;
11809       else if (unformat (input, "cos1 %d", &cos1_val))
11810         cos1 = 1;
11811       else if (unformat (input, "cos2 %d", &cos2_val))
11812         cos2 = 1;
11813       else
11814         break;
11815     }
11816   if ((src + dst + proto + tag1 + tag2 +
11817        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11818     return 0;
11819
11820   if (tag1 || ignore_tag1 || cos1)
11821     len = 18;
11822   if (tag2 || ignore_tag2 || cos2)
11823     len = 22;
11824
11825   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11826
11827   if (dst)
11828     clib_memcpy (match, dst_val, 6);
11829
11830   if (src)
11831     clib_memcpy (match + 6, src_val, 6);
11832
11833   if (tag2)
11834     {
11835       /* inner vlan tag */
11836       match[19] = tag2_val[1];
11837       match[18] = tag2_val[0];
11838       if (cos2)
11839         match[18] |= (cos2_val & 0x7) << 5;
11840       if (proto)
11841         {
11842           match[21] = proto_val & 0xff;
11843           match[20] = proto_val >> 8;
11844         }
11845       if (tag1)
11846         {
11847           match[15] = tag1_val[1];
11848           match[14] = tag1_val[0];
11849         }
11850       if (cos1)
11851         match[14] |= (cos1_val & 0x7) << 5;
11852       *matchp = match;
11853       return 1;
11854     }
11855   if (tag1)
11856     {
11857       match[15] = tag1_val[1];
11858       match[14] = tag1_val[0];
11859       if (proto)
11860         {
11861           match[17] = proto_val & 0xff;
11862           match[16] = proto_val >> 8;
11863         }
11864       if (cos1)
11865         match[14] |= (cos1_val & 0x7) << 5;
11866
11867       *matchp = match;
11868       return 1;
11869     }
11870   if (cos2)
11871     match[18] |= (cos2_val & 0x7) << 5;
11872   if (cos1)
11873     match[14] |= (cos1_val & 0x7) << 5;
11874   if (proto)
11875     {
11876       match[13] = proto_val & 0xff;
11877       match[12] = proto_val >> 8;
11878     }
11879
11880   *matchp = match;
11881   return 1;
11882 }
11883
11884 uword
11885 unformat_qos_source (unformat_input_t * input, va_list * args)
11886 {
11887   int *qs = va_arg (*args, int *);
11888
11889   if (unformat (input, "ip"))
11890     *qs = QOS_SOURCE_IP;
11891   else if (unformat (input, "mpls"))
11892     *qs = QOS_SOURCE_MPLS;
11893   else if (unformat (input, "ext"))
11894     *qs = QOS_SOURCE_EXT;
11895   else if (unformat (input, "vlan"))
11896     *qs = QOS_SOURCE_VLAN;
11897   else
11898     return 0;
11899
11900   return 1;
11901 }
11902 #endif
11903
11904 uword
11905 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11906 {
11907   u8 **matchp = va_arg (*args, u8 **);
11908   u32 skip_n_vectors = va_arg (*args, u32);
11909   u32 match_n_vectors = va_arg (*args, u32);
11910
11911   u8 *match = 0;
11912   u8 *l2 = 0;
11913   u8 *l3 = 0;
11914   u8 *l4 = 0;
11915
11916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11917     {
11918       if (unformat (input, "hex %U", unformat_hex_string, &match))
11919         ;
11920       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11921         ;
11922       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11923         ;
11924       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11925         ;
11926       else
11927         break;
11928     }
11929
11930   if (l4 && !l3)
11931     {
11932       vec_free (match);
11933       vec_free (l2);
11934       vec_free (l4);
11935       return 0;
11936     }
11937
11938   if (match || l2 || l3 || l4)
11939     {
11940       if (l2 || l3 || l4)
11941         {
11942           /* "Win a free Ethernet header in every packet" */
11943           if (l2 == 0)
11944             vec_validate_aligned (l2, 13, sizeof (u32x4));
11945           match = l2;
11946           if (vec_len (l3))
11947             {
11948               vec_append_aligned (match, l3, sizeof (u32x4));
11949               vec_free (l3);
11950             }
11951           if (vec_len (l4))
11952             {
11953               vec_append_aligned (match, l4, sizeof (u32x4));
11954               vec_free (l4);
11955             }
11956         }
11957
11958       /* Make sure the vector is big enough even if key is all 0's */
11959       vec_validate_aligned
11960         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11961          sizeof (u32x4));
11962
11963       /* Set size, include skipped vectors */
11964       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11965
11966       *matchp = match;
11967
11968       return 1;
11969     }
11970
11971   return 0;
11972 }
11973
11974 static int
11975 api_classify_add_del_session (vat_main_t * vam)
11976 {
11977   unformat_input_t *i = vam->input;
11978   vl_api_classify_add_del_session_t *mp;
11979   int is_add = 1;
11980   u32 table_index = ~0;
11981   u32 hit_next_index = ~0;
11982   u32 opaque_index = ~0;
11983   u8 *match = 0;
11984   i32 advance = 0;
11985   u32 skip_n_vectors = 0;
11986   u32 match_n_vectors = 0;
11987   u32 action = 0;
11988   u32 metadata = 0;
11989   int ret;
11990
11991   /*
11992    * Warning: you have to supply skip_n and match_n
11993    * because the API client cant simply look at the classify
11994    * table object.
11995    */
11996
11997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11998     {
11999       if (unformat (i, "del"))
12000         is_add = 0;
12001       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12002                          &hit_next_index))
12003         ;
12004       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12005                          &hit_next_index))
12006         ;
12007       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12008                          &hit_next_index))
12009         ;
12010       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12011         ;
12012       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12013         ;
12014       else if (unformat (i, "opaque-index %d", &opaque_index))
12015         ;
12016       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12017         ;
12018       else if (unformat (i, "match_n %d", &match_n_vectors))
12019         ;
12020       else if (unformat (i, "match %U", api_unformat_classify_match,
12021                          &match, skip_n_vectors, match_n_vectors))
12022         ;
12023       else if (unformat (i, "advance %d", &advance))
12024         ;
12025       else if (unformat (i, "table-index %d", &table_index))
12026         ;
12027       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12028         action = 1;
12029       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12030         action = 2;
12031       else if (unformat (i, "action %d", &action))
12032         ;
12033       else if (unformat (i, "metadata %d", &metadata))
12034         ;
12035       else
12036         break;
12037     }
12038
12039   if (table_index == ~0)
12040     {
12041       errmsg ("Table index required");
12042       return -99;
12043     }
12044
12045   if (is_add && match == 0)
12046     {
12047       errmsg ("Match value required");
12048       return -99;
12049     }
12050
12051   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12052
12053   mp->is_add = is_add;
12054   mp->table_index = ntohl (table_index);
12055   mp->hit_next_index = ntohl (hit_next_index);
12056   mp->opaque_index = ntohl (opaque_index);
12057   mp->advance = ntohl (advance);
12058   mp->action = action;
12059   mp->metadata = ntohl (metadata);
12060   clib_memcpy (mp->match, match, vec_len (match));
12061   vec_free (match);
12062
12063   S (mp);
12064   W (ret);
12065   return ret;
12066 }
12067
12068 static int
12069 api_classify_set_interface_ip_table (vat_main_t * vam)
12070 {
12071   unformat_input_t *i = vam->input;
12072   vl_api_classify_set_interface_ip_table_t *mp;
12073   u32 sw_if_index;
12074   int sw_if_index_set;
12075   u32 table_index = ~0;
12076   u8 is_ipv6 = 0;
12077   int ret;
12078
12079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12080     {
12081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12082         sw_if_index_set = 1;
12083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12084         sw_if_index_set = 1;
12085       else if (unformat (i, "table %d", &table_index))
12086         ;
12087       else
12088         {
12089           clib_warning ("parse error '%U'", format_unformat_error, i);
12090           return -99;
12091         }
12092     }
12093
12094   if (sw_if_index_set == 0)
12095     {
12096       errmsg ("missing interface name or sw_if_index");
12097       return -99;
12098     }
12099
12100
12101   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12102
12103   mp->sw_if_index = ntohl (sw_if_index);
12104   mp->table_index = ntohl (table_index);
12105   mp->is_ipv6 = is_ipv6;
12106
12107   S (mp);
12108   W (ret);
12109   return ret;
12110 }
12111
12112 static int
12113 api_classify_set_interface_l2_tables (vat_main_t * vam)
12114 {
12115   unformat_input_t *i = vam->input;
12116   vl_api_classify_set_interface_l2_tables_t *mp;
12117   u32 sw_if_index;
12118   int sw_if_index_set;
12119   u32 ip4_table_index = ~0;
12120   u32 ip6_table_index = ~0;
12121   u32 other_table_index = ~0;
12122   u32 is_input = 1;
12123   int ret;
12124
12125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12126     {
12127       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12128         sw_if_index_set = 1;
12129       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12130         sw_if_index_set = 1;
12131       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12132         ;
12133       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12134         ;
12135       else if (unformat (i, "other-table %d", &other_table_index))
12136         ;
12137       else if (unformat (i, "is-input %d", &is_input))
12138         ;
12139       else
12140         {
12141           clib_warning ("parse error '%U'", format_unformat_error, i);
12142           return -99;
12143         }
12144     }
12145
12146   if (sw_if_index_set == 0)
12147     {
12148       errmsg ("missing interface name or sw_if_index");
12149       return -99;
12150     }
12151
12152
12153   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12154
12155   mp->sw_if_index = ntohl (sw_if_index);
12156   mp->ip4_table_index = ntohl (ip4_table_index);
12157   mp->ip6_table_index = ntohl (ip6_table_index);
12158   mp->other_table_index = ntohl (other_table_index);
12159   mp->is_input = (u8) is_input;
12160
12161   S (mp);
12162   W (ret);
12163   return ret;
12164 }
12165
12166 static int
12167 api_set_ipfix_exporter (vat_main_t * vam)
12168 {
12169   unformat_input_t *i = vam->input;
12170   vl_api_set_ipfix_exporter_t *mp;
12171   ip4_address_t collector_address;
12172   u8 collector_address_set = 0;
12173   u32 collector_port = ~0;
12174   ip4_address_t src_address;
12175   u8 src_address_set = 0;
12176   u32 vrf_id = ~0;
12177   u32 path_mtu = ~0;
12178   u32 template_interval = ~0;
12179   u8 udp_checksum = 0;
12180   int ret;
12181
12182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12183     {
12184       if (unformat (i, "collector_address %U", unformat_ip4_address,
12185                     &collector_address))
12186         collector_address_set = 1;
12187       else if (unformat (i, "collector_port %d", &collector_port))
12188         ;
12189       else if (unformat (i, "src_address %U", unformat_ip4_address,
12190                          &src_address))
12191         src_address_set = 1;
12192       else if (unformat (i, "vrf_id %d", &vrf_id))
12193         ;
12194       else if (unformat (i, "path_mtu %d", &path_mtu))
12195         ;
12196       else if (unformat (i, "template_interval %d", &template_interval))
12197         ;
12198       else if (unformat (i, "udp_checksum"))
12199         udp_checksum = 1;
12200       else
12201         break;
12202     }
12203
12204   if (collector_address_set == 0)
12205     {
12206       errmsg ("collector_address required");
12207       return -99;
12208     }
12209
12210   if (src_address_set == 0)
12211     {
12212       errmsg ("src_address required");
12213       return -99;
12214     }
12215
12216   M (SET_IPFIX_EXPORTER, mp);
12217
12218   memcpy (mp->collector_address, collector_address.data,
12219           sizeof (collector_address.data));
12220   mp->collector_port = htons ((u16) collector_port);
12221   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12222   mp->vrf_id = htonl (vrf_id);
12223   mp->path_mtu = htonl (path_mtu);
12224   mp->template_interval = htonl (template_interval);
12225   mp->udp_checksum = udp_checksum;
12226
12227   S (mp);
12228   W (ret);
12229   return ret;
12230 }
12231
12232 static int
12233 api_set_ipfix_classify_stream (vat_main_t * vam)
12234 {
12235   unformat_input_t *i = vam->input;
12236   vl_api_set_ipfix_classify_stream_t *mp;
12237   u32 domain_id = 0;
12238   u32 src_port = UDP_DST_PORT_ipfix;
12239   int ret;
12240
12241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12242     {
12243       if (unformat (i, "domain %d", &domain_id))
12244         ;
12245       else if (unformat (i, "src_port %d", &src_port))
12246         ;
12247       else
12248         {
12249           errmsg ("unknown input `%U'", format_unformat_error, i);
12250           return -99;
12251         }
12252     }
12253
12254   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12255
12256   mp->domain_id = htonl (domain_id);
12257   mp->src_port = htons ((u16) src_port);
12258
12259   S (mp);
12260   W (ret);
12261   return ret;
12262 }
12263
12264 static int
12265 api_ipfix_classify_table_add_del (vat_main_t * vam)
12266 {
12267   unformat_input_t *i = vam->input;
12268   vl_api_ipfix_classify_table_add_del_t *mp;
12269   int is_add = -1;
12270   u32 classify_table_index = ~0;
12271   u8 ip_version = 0;
12272   u8 transport_protocol = 255;
12273   int ret;
12274
12275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12276     {
12277       if (unformat (i, "add"))
12278         is_add = 1;
12279       else if (unformat (i, "del"))
12280         is_add = 0;
12281       else if (unformat (i, "table %d", &classify_table_index))
12282         ;
12283       else if (unformat (i, "ip4"))
12284         ip_version = 4;
12285       else if (unformat (i, "ip6"))
12286         ip_version = 6;
12287       else if (unformat (i, "tcp"))
12288         transport_protocol = 6;
12289       else if (unformat (i, "udp"))
12290         transport_protocol = 17;
12291       else
12292         {
12293           errmsg ("unknown input `%U'", format_unformat_error, i);
12294           return -99;
12295         }
12296     }
12297
12298   if (is_add == -1)
12299     {
12300       errmsg ("expecting: add|del");
12301       return -99;
12302     }
12303   if (classify_table_index == ~0)
12304     {
12305       errmsg ("classifier table not specified");
12306       return -99;
12307     }
12308   if (ip_version == 0)
12309     {
12310       errmsg ("IP version not specified");
12311       return -99;
12312     }
12313
12314   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12315
12316   mp->is_add = is_add;
12317   mp->table_id = htonl (classify_table_index);
12318   mp->ip_version = ip_version;
12319   mp->transport_protocol = transport_protocol;
12320
12321   S (mp);
12322   W (ret);
12323   return ret;
12324 }
12325
12326 static int
12327 api_get_node_index (vat_main_t * vam)
12328 {
12329   unformat_input_t *i = vam->input;
12330   vl_api_get_node_index_t *mp;
12331   u8 *name = 0;
12332   int ret;
12333
12334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12335     {
12336       if (unformat (i, "node %s", &name))
12337         ;
12338       else
12339         break;
12340     }
12341   if (name == 0)
12342     {
12343       errmsg ("node name required");
12344       return -99;
12345     }
12346   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12347     {
12348       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12349       return -99;
12350     }
12351
12352   M (GET_NODE_INDEX, mp);
12353   clib_memcpy (mp->node_name, name, vec_len (name));
12354   vec_free (name);
12355
12356   S (mp);
12357   W (ret);
12358   return ret;
12359 }
12360
12361 static int
12362 api_get_next_index (vat_main_t * vam)
12363 {
12364   unformat_input_t *i = vam->input;
12365   vl_api_get_next_index_t *mp;
12366   u8 *node_name = 0, *next_node_name = 0;
12367   int ret;
12368
12369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12370     {
12371       if (unformat (i, "node-name %s", &node_name))
12372         ;
12373       else if (unformat (i, "next-node-name %s", &next_node_name))
12374         break;
12375     }
12376
12377   if (node_name == 0)
12378     {
12379       errmsg ("node name required");
12380       return -99;
12381     }
12382   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12383     {
12384       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12385       return -99;
12386     }
12387
12388   if (next_node_name == 0)
12389     {
12390       errmsg ("next node name required");
12391       return -99;
12392     }
12393   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12394     {
12395       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12396       return -99;
12397     }
12398
12399   M (GET_NEXT_INDEX, mp);
12400   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12401   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12402   vec_free (node_name);
12403   vec_free (next_node_name);
12404
12405   S (mp);
12406   W (ret);
12407   return ret;
12408 }
12409
12410 static int
12411 api_add_node_next (vat_main_t * vam)
12412 {
12413   unformat_input_t *i = vam->input;
12414   vl_api_add_node_next_t *mp;
12415   u8 *name = 0;
12416   u8 *next = 0;
12417   int ret;
12418
12419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12420     {
12421       if (unformat (i, "node %s", &name))
12422         ;
12423       else if (unformat (i, "next %s", &next))
12424         ;
12425       else
12426         break;
12427     }
12428   if (name == 0)
12429     {
12430       errmsg ("node name required");
12431       return -99;
12432     }
12433   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12434     {
12435       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12436       return -99;
12437     }
12438   if (next == 0)
12439     {
12440       errmsg ("next node required");
12441       return -99;
12442     }
12443   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12444     {
12445       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12446       return -99;
12447     }
12448
12449   M (ADD_NODE_NEXT, mp);
12450   clib_memcpy (mp->node_name, name, vec_len (name));
12451   clib_memcpy (mp->next_name, next, vec_len (next));
12452   vec_free (name);
12453   vec_free (next);
12454
12455   S (mp);
12456   W (ret);
12457   return ret;
12458 }
12459
12460 static int
12461 api_l2tpv3_create_tunnel (vat_main_t * vam)
12462 {
12463   unformat_input_t *i = vam->input;
12464   ip6_address_t client_address, our_address;
12465   int client_address_set = 0;
12466   int our_address_set = 0;
12467   u32 local_session_id = 0;
12468   u32 remote_session_id = 0;
12469   u64 local_cookie = 0;
12470   u64 remote_cookie = 0;
12471   u8 l2_sublayer_present = 0;
12472   vl_api_l2tpv3_create_tunnel_t *mp;
12473   int ret;
12474
12475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12476     {
12477       if (unformat (i, "client_address %U", unformat_ip6_address,
12478                     &client_address))
12479         client_address_set = 1;
12480       else if (unformat (i, "our_address %U", unformat_ip6_address,
12481                          &our_address))
12482         our_address_set = 1;
12483       else if (unformat (i, "local_session_id %d", &local_session_id))
12484         ;
12485       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12486         ;
12487       else if (unformat (i, "local_cookie %lld", &local_cookie))
12488         ;
12489       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12490         ;
12491       else if (unformat (i, "l2-sublayer-present"))
12492         l2_sublayer_present = 1;
12493       else
12494         break;
12495     }
12496
12497   if (client_address_set == 0)
12498     {
12499       errmsg ("client_address required");
12500       return -99;
12501     }
12502
12503   if (our_address_set == 0)
12504     {
12505       errmsg ("our_address required");
12506       return -99;
12507     }
12508
12509   M (L2TPV3_CREATE_TUNNEL, mp);
12510
12511   clib_memcpy (mp->client_address, client_address.as_u8,
12512                sizeof (mp->client_address));
12513
12514   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12515
12516   mp->local_session_id = ntohl (local_session_id);
12517   mp->remote_session_id = ntohl (remote_session_id);
12518   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12519   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12520   mp->l2_sublayer_present = l2_sublayer_present;
12521   mp->is_ipv6 = 1;
12522
12523   S (mp);
12524   W (ret);
12525   return ret;
12526 }
12527
12528 static int
12529 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12530 {
12531   unformat_input_t *i = vam->input;
12532   u32 sw_if_index;
12533   u8 sw_if_index_set = 0;
12534   u64 new_local_cookie = 0;
12535   u64 new_remote_cookie = 0;
12536   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12537   int ret;
12538
12539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12540     {
12541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12542         sw_if_index_set = 1;
12543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12544         sw_if_index_set = 1;
12545       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12546         ;
12547       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12548         ;
12549       else
12550         break;
12551     }
12552
12553   if (sw_if_index_set == 0)
12554     {
12555       errmsg ("missing interface name or sw_if_index");
12556       return -99;
12557     }
12558
12559   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12560
12561   mp->sw_if_index = ntohl (sw_if_index);
12562   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12563   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12564
12565   S (mp);
12566   W (ret);
12567   return ret;
12568 }
12569
12570 static int
12571 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12572 {
12573   unformat_input_t *i = vam->input;
12574   vl_api_l2tpv3_interface_enable_disable_t *mp;
12575   u32 sw_if_index;
12576   u8 sw_if_index_set = 0;
12577   u8 enable_disable = 1;
12578   int ret;
12579
12580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12581     {
12582       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12583         sw_if_index_set = 1;
12584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12585         sw_if_index_set = 1;
12586       else if (unformat (i, "enable"))
12587         enable_disable = 1;
12588       else if (unformat (i, "disable"))
12589         enable_disable = 0;
12590       else
12591         break;
12592     }
12593
12594   if (sw_if_index_set == 0)
12595     {
12596       errmsg ("missing interface name or sw_if_index");
12597       return -99;
12598     }
12599
12600   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12601
12602   mp->sw_if_index = ntohl (sw_if_index);
12603   mp->enable_disable = enable_disable;
12604
12605   S (mp);
12606   W (ret);
12607   return ret;
12608 }
12609
12610 static int
12611 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12612 {
12613   unformat_input_t *i = vam->input;
12614   vl_api_l2tpv3_set_lookup_key_t *mp;
12615   u8 key = ~0;
12616   int ret;
12617
12618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12619     {
12620       if (unformat (i, "lookup_v6_src"))
12621         key = L2T_LOOKUP_SRC_ADDRESS;
12622       else if (unformat (i, "lookup_v6_dst"))
12623         key = L2T_LOOKUP_DST_ADDRESS;
12624       else if (unformat (i, "lookup_session_id"))
12625         key = L2T_LOOKUP_SESSION_ID;
12626       else
12627         break;
12628     }
12629
12630   if (key == (u8) ~ 0)
12631     {
12632       errmsg ("l2tp session lookup key unset");
12633       return -99;
12634     }
12635
12636   M (L2TPV3_SET_LOOKUP_KEY, mp);
12637
12638   mp->key = key;
12639
12640   S (mp);
12641   W (ret);
12642   return ret;
12643 }
12644
12645 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12646   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12647 {
12648   vat_main_t *vam = &vat_main;
12649
12650   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12651          format_ip6_address, mp->our_address,
12652          format_ip6_address, mp->client_address,
12653          clib_net_to_host_u32 (mp->sw_if_index));
12654
12655   print (vam->ofp,
12656          "   local cookies %016llx %016llx remote cookie %016llx",
12657          clib_net_to_host_u64 (mp->local_cookie[0]),
12658          clib_net_to_host_u64 (mp->local_cookie[1]),
12659          clib_net_to_host_u64 (mp->remote_cookie));
12660
12661   print (vam->ofp, "   local session-id %d remote session-id %d",
12662          clib_net_to_host_u32 (mp->local_session_id),
12663          clib_net_to_host_u32 (mp->remote_session_id));
12664
12665   print (vam->ofp, "   l2 specific sublayer %s\n",
12666          mp->l2_sublayer_present ? "preset" : "absent");
12667
12668 }
12669
12670 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12671   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12672 {
12673   vat_main_t *vam = &vat_main;
12674   vat_json_node_t *node = NULL;
12675   struct in6_addr addr;
12676
12677   if (VAT_JSON_ARRAY != vam->json_tree.type)
12678     {
12679       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12680       vat_json_init_array (&vam->json_tree);
12681     }
12682   node = vat_json_array_add (&vam->json_tree);
12683
12684   vat_json_init_object (node);
12685
12686   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12687   vat_json_object_add_ip6 (node, "our_address", addr);
12688   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12689   vat_json_object_add_ip6 (node, "client_address", addr);
12690
12691   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12692   vat_json_init_array (lc);
12693   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12694   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12695   vat_json_object_add_uint (node, "remote_cookie",
12696                             clib_net_to_host_u64 (mp->remote_cookie));
12697
12698   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12699   vat_json_object_add_uint (node, "local_session_id",
12700                             clib_net_to_host_u32 (mp->local_session_id));
12701   vat_json_object_add_uint (node, "remote_session_id",
12702                             clib_net_to_host_u32 (mp->remote_session_id));
12703   vat_json_object_add_string_copy (node, "l2_sublayer",
12704                                    mp->l2_sublayer_present ? (u8 *) "present"
12705                                    : (u8 *) "absent");
12706 }
12707
12708 static int
12709 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12710 {
12711   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12712   vl_api_control_ping_t *mp_ping;
12713   int ret;
12714
12715   /* Get list of l2tpv3-tunnel interfaces */
12716   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12717   S (mp);
12718
12719   /* Use a control ping for synchronization */
12720   MPING (CONTROL_PING, mp_ping);
12721   S (mp_ping);
12722
12723   W (ret);
12724   return ret;
12725 }
12726
12727
12728 static void vl_api_sw_interface_tap_details_t_handler
12729   (vl_api_sw_interface_tap_details_t * mp)
12730 {
12731   vat_main_t *vam = &vat_main;
12732
12733   print (vam->ofp, "%-16s %d",
12734          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12735 }
12736
12737 static void vl_api_sw_interface_tap_details_t_handler_json
12738   (vl_api_sw_interface_tap_details_t * mp)
12739 {
12740   vat_main_t *vam = &vat_main;
12741   vat_json_node_t *node = NULL;
12742
12743   if (VAT_JSON_ARRAY != vam->json_tree.type)
12744     {
12745       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12746       vat_json_init_array (&vam->json_tree);
12747     }
12748   node = vat_json_array_add (&vam->json_tree);
12749
12750   vat_json_init_object (node);
12751   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12752   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12753 }
12754
12755 static int
12756 api_sw_interface_tap_dump (vat_main_t * vam)
12757 {
12758   vl_api_sw_interface_tap_dump_t *mp;
12759   vl_api_control_ping_t *mp_ping;
12760   int ret;
12761
12762   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12763   /* Get list of tap interfaces */
12764   M (SW_INTERFACE_TAP_DUMP, mp);
12765   S (mp);
12766
12767   /* Use a control ping for synchronization */
12768   MPING (CONTROL_PING, mp_ping);
12769   S (mp_ping);
12770
12771   W (ret);
12772   return ret;
12773 }
12774
12775 static void vl_api_sw_interface_tap_v2_details_t_handler
12776   (vl_api_sw_interface_tap_v2_details_t * mp)
12777 {
12778   vat_main_t *vam = &vat_main;
12779
12780   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12781                     mp->host_ip4_prefix_len);
12782   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12783                     mp->host_ip6_prefix_len);
12784
12785   print (vam->ofp,
12786          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12787          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12788          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12789          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12790          mp->host_bridge, ip4, ip6);
12791
12792   vec_free (ip4);
12793   vec_free (ip6);
12794 }
12795
12796 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12797   (vl_api_sw_interface_tap_v2_details_t * mp)
12798 {
12799   vat_main_t *vam = &vat_main;
12800   vat_json_node_t *node = NULL;
12801
12802   if (VAT_JSON_ARRAY != vam->json_tree.type)
12803     {
12804       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12805       vat_json_init_array (&vam->json_tree);
12806     }
12807   node = vat_json_array_add (&vam->json_tree);
12808
12809   vat_json_init_object (node);
12810   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12811   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12812   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12813   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12814   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12815   vat_json_object_add_string_copy (node, "host_mac_addr",
12816                                    format (0, "%U", format_ethernet_address,
12817                                            &mp->host_mac_addr));
12818   vat_json_object_add_string_copy (node, "host_namespace",
12819                                    mp->host_namespace);
12820   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12821   vat_json_object_add_string_copy (node, "host_ip4_addr",
12822                                    format (0, "%U/%d", format_ip4_address,
12823                                            mp->host_ip4_addr,
12824                                            mp->host_ip4_prefix_len));
12825   vat_json_object_add_string_copy (node, "host_ip6_addr",
12826                                    format (0, "%U/%d", format_ip6_address,
12827                                            mp->host_ip6_addr,
12828                                            mp->host_ip6_prefix_len));
12829
12830 }
12831
12832 static int
12833 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12834 {
12835   vl_api_sw_interface_tap_v2_dump_t *mp;
12836   vl_api_control_ping_t *mp_ping;
12837   int ret;
12838
12839   print (vam->ofp,
12840          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12841          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12842          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12843          "host_ip6_addr");
12844
12845   /* Get list of tap interfaces */
12846   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12847   S (mp);
12848
12849   /* Use a control ping for synchronization */
12850   MPING (CONTROL_PING, mp_ping);
12851   S (mp_ping);
12852
12853   W (ret);
12854   return ret;
12855 }
12856
12857 static uword unformat_vxlan_decap_next
12858   (unformat_input_t * input, va_list * args)
12859 {
12860   u32 *result = va_arg (*args, u32 *);
12861   u32 tmp;
12862
12863   if (unformat (input, "l2"))
12864     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12865   else if (unformat (input, "%d", &tmp))
12866     *result = tmp;
12867   else
12868     return 0;
12869   return 1;
12870 }
12871
12872 static int
12873 api_vxlan_add_del_tunnel (vat_main_t * vam)
12874 {
12875   unformat_input_t *line_input = vam->input;
12876   vl_api_vxlan_add_del_tunnel_t *mp;
12877   ip46_address_t src, dst;
12878   u8 is_add = 1;
12879   u8 ipv4_set = 0, ipv6_set = 0;
12880   u8 src_set = 0;
12881   u8 dst_set = 0;
12882   u8 grp_set = 0;
12883   u32 instance = ~0;
12884   u32 mcast_sw_if_index = ~0;
12885   u32 encap_vrf_id = 0;
12886   u32 decap_next_index = ~0;
12887   u32 vni = 0;
12888   int ret;
12889
12890   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12891   memset (&src, 0, sizeof src);
12892   memset (&dst, 0, sizeof dst);
12893
12894   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12895     {
12896       if (unformat (line_input, "del"))
12897         is_add = 0;
12898       else if (unformat (line_input, "instance %d", &instance))
12899         ;
12900       else
12901         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12902         {
12903           ipv4_set = 1;
12904           src_set = 1;
12905         }
12906       else
12907         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12908         {
12909           ipv4_set = 1;
12910           dst_set = 1;
12911         }
12912       else
12913         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12914         {
12915           ipv6_set = 1;
12916           src_set = 1;
12917         }
12918       else
12919         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12920         {
12921           ipv6_set = 1;
12922           dst_set = 1;
12923         }
12924       else if (unformat (line_input, "group %U %U",
12925                          unformat_ip4_address, &dst.ip4,
12926                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12927         {
12928           grp_set = dst_set = 1;
12929           ipv4_set = 1;
12930         }
12931       else if (unformat (line_input, "group %U",
12932                          unformat_ip4_address, &dst.ip4))
12933         {
12934           grp_set = dst_set = 1;
12935           ipv4_set = 1;
12936         }
12937       else if (unformat (line_input, "group %U %U",
12938                          unformat_ip6_address, &dst.ip6,
12939                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12940         {
12941           grp_set = dst_set = 1;
12942           ipv6_set = 1;
12943         }
12944       else if (unformat (line_input, "group %U",
12945                          unformat_ip6_address, &dst.ip6))
12946         {
12947           grp_set = dst_set = 1;
12948           ipv6_set = 1;
12949         }
12950       else
12951         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12952         ;
12953       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12954         ;
12955       else if (unformat (line_input, "decap-next %U",
12956                          unformat_vxlan_decap_next, &decap_next_index))
12957         ;
12958       else if (unformat (line_input, "vni %d", &vni))
12959         ;
12960       else
12961         {
12962           errmsg ("parse error '%U'", format_unformat_error, line_input);
12963           return -99;
12964         }
12965     }
12966
12967   if (src_set == 0)
12968     {
12969       errmsg ("tunnel src address not specified");
12970       return -99;
12971     }
12972   if (dst_set == 0)
12973     {
12974       errmsg ("tunnel dst address not specified");
12975       return -99;
12976     }
12977
12978   if (grp_set && !ip46_address_is_multicast (&dst))
12979     {
12980       errmsg ("tunnel group address not multicast");
12981       return -99;
12982     }
12983   if (grp_set && mcast_sw_if_index == ~0)
12984     {
12985       errmsg ("tunnel nonexistent multicast device");
12986       return -99;
12987     }
12988   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12989     {
12990       errmsg ("tunnel dst address must be unicast");
12991       return -99;
12992     }
12993
12994
12995   if (ipv4_set && ipv6_set)
12996     {
12997       errmsg ("both IPv4 and IPv6 addresses specified");
12998       return -99;
12999     }
13000
13001   if ((vni == 0) || (vni >> 24))
13002     {
13003       errmsg ("vni not specified or out of range");
13004       return -99;
13005     }
13006
13007   M (VXLAN_ADD_DEL_TUNNEL, mp);
13008
13009   if (ipv6_set)
13010     {
13011       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13012       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13013     }
13014   else
13015     {
13016       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13017       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13018     }
13019
13020   mp->instance = htonl (instance);
13021   mp->encap_vrf_id = ntohl (encap_vrf_id);
13022   mp->decap_next_index = ntohl (decap_next_index);
13023   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13024   mp->vni = ntohl (vni);
13025   mp->is_add = is_add;
13026   mp->is_ipv6 = ipv6_set;
13027
13028   S (mp);
13029   W (ret);
13030   return ret;
13031 }
13032
13033 static void vl_api_vxlan_tunnel_details_t_handler
13034   (vl_api_vxlan_tunnel_details_t * mp)
13035 {
13036   vat_main_t *vam = &vat_main;
13037   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13038   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13039
13040   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13041          ntohl (mp->sw_if_index),
13042          ntohl (mp->instance),
13043          format_ip46_address, &src, IP46_TYPE_ANY,
13044          format_ip46_address, &dst, IP46_TYPE_ANY,
13045          ntohl (mp->encap_vrf_id),
13046          ntohl (mp->decap_next_index), ntohl (mp->vni),
13047          ntohl (mp->mcast_sw_if_index));
13048 }
13049
13050 static void vl_api_vxlan_tunnel_details_t_handler_json
13051   (vl_api_vxlan_tunnel_details_t * mp)
13052 {
13053   vat_main_t *vam = &vat_main;
13054   vat_json_node_t *node = NULL;
13055
13056   if (VAT_JSON_ARRAY != vam->json_tree.type)
13057     {
13058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13059       vat_json_init_array (&vam->json_tree);
13060     }
13061   node = vat_json_array_add (&vam->json_tree);
13062
13063   vat_json_init_object (node);
13064   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13065
13066   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13067
13068   if (mp->is_ipv6)
13069     {
13070       struct in6_addr ip6;
13071
13072       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13073       vat_json_object_add_ip6 (node, "src_address", ip6);
13074       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13075       vat_json_object_add_ip6 (node, "dst_address", ip6);
13076     }
13077   else
13078     {
13079       struct in_addr ip4;
13080
13081       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13082       vat_json_object_add_ip4 (node, "src_address", ip4);
13083       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13084       vat_json_object_add_ip4 (node, "dst_address", ip4);
13085     }
13086   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13087   vat_json_object_add_uint (node, "decap_next_index",
13088                             ntohl (mp->decap_next_index));
13089   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13090   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13091   vat_json_object_add_uint (node, "mcast_sw_if_index",
13092                             ntohl (mp->mcast_sw_if_index));
13093 }
13094
13095 static int
13096 api_vxlan_tunnel_dump (vat_main_t * vam)
13097 {
13098   unformat_input_t *i = vam->input;
13099   vl_api_vxlan_tunnel_dump_t *mp;
13100   vl_api_control_ping_t *mp_ping;
13101   u32 sw_if_index;
13102   u8 sw_if_index_set = 0;
13103   int ret;
13104
13105   /* Parse args required to build the message */
13106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13107     {
13108       if (unformat (i, "sw_if_index %d", &sw_if_index))
13109         sw_if_index_set = 1;
13110       else
13111         break;
13112     }
13113
13114   if (sw_if_index_set == 0)
13115     {
13116       sw_if_index = ~0;
13117     }
13118
13119   if (!vam->json_output)
13120     {
13121       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13122              "sw_if_index", "instance", "src_address", "dst_address",
13123              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13124     }
13125
13126   /* Get list of vxlan-tunnel interfaces */
13127   M (VXLAN_TUNNEL_DUMP, mp);
13128
13129   mp->sw_if_index = htonl (sw_if_index);
13130
13131   S (mp);
13132
13133   /* Use a control ping for synchronization */
13134   MPING (CONTROL_PING, mp_ping);
13135   S (mp_ping);
13136
13137   W (ret);
13138   return ret;
13139 }
13140
13141 static uword unformat_geneve_decap_next
13142   (unformat_input_t * input, va_list * args)
13143 {
13144   u32 *result = va_arg (*args, u32 *);
13145   u32 tmp;
13146
13147   if (unformat (input, "l2"))
13148     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13149   else if (unformat (input, "%d", &tmp))
13150     *result = tmp;
13151   else
13152     return 0;
13153   return 1;
13154 }
13155
13156 static int
13157 api_geneve_add_del_tunnel (vat_main_t * vam)
13158 {
13159   unformat_input_t *line_input = vam->input;
13160   vl_api_geneve_add_del_tunnel_t *mp;
13161   ip46_address_t src, dst;
13162   u8 is_add = 1;
13163   u8 ipv4_set = 0, ipv6_set = 0;
13164   u8 src_set = 0;
13165   u8 dst_set = 0;
13166   u8 grp_set = 0;
13167   u32 mcast_sw_if_index = ~0;
13168   u32 encap_vrf_id = 0;
13169   u32 decap_next_index = ~0;
13170   u32 vni = 0;
13171   int ret;
13172
13173   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13174   memset (&src, 0, sizeof src);
13175   memset (&dst, 0, sizeof dst);
13176
13177   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13178     {
13179       if (unformat (line_input, "del"))
13180         is_add = 0;
13181       else
13182         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13183         {
13184           ipv4_set = 1;
13185           src_set = 1;
13186         }
13187       else
13188         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13189         {
13190           ipv4_set = 1;
13191           dst_set = 1;
13192         }
13193       else
13194         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13195         {
13196           ipv6_set = 1;
13197           src_set = 1;
13198         }
13199       else
13200         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13201         {
13202           ipv6_set = 1;
13203           dst_set = 1;
13204         }
13205       else if (unformat (line_input, "group %U %U",
13206                          unformat_ip4_address, &dst.ip4,
13207                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13208         {
13209           grp_set = dst_set = 1;
13210           ipv4_set = 1;
13211         }
13212       else if (unformat (line_input, "group %U",
13213                          unformat_ip4_address, &dst.ip4))
13214         {
13215           grp_set = dst_set = 1;
13216           ipv4_set = 1;
13217         }
13218       else if (unformat (line_input, "group %U %U",
13219                          unformat_ip6_address, &dst.ip6,
13220                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13221         {
13222           grp_set = dst_set = 1;
13223           ipv6_set = 1;
13224         }
13225       else if (unformat (line_input, "group %U",
13226                          unformat_ip6_address, &dst.ip6))
13227         {
13228           grp_set = dst_set = 1;
13229           ipv6_set = 1;
13230         }
13231       else
13232         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13233         ;
13234       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13235         ;
13236       else if (unformat (line_input, "decap-next %U",
13237                          unformat_geneve_decap_next, &decap_next_index))
13238         ;
13239       else if (unformat (line_input, "vni %d", &vni))
13240         ;
13241       else
13242         {
13243           errmsg ("parse error '%U'", format_unformat_error, line_input);
13244           return -99;
13245         }
13246     }
13247
13248   if (src_set == 0)
13249     {
13250       errmsg ("tunnel src address not specified");
13251       return -99;
13252     }
13253   if (dst_set == 0)
13254     {
13255       errmsg ("tunnel dst address not specified");
13256       return -99;
13257     }
13258
13259   if (grp_set && !ip46_address_is_multicast (&dst))
13260     {
13261       errmsg ("tunnel group address not multicast");
13262       return -99;
13263     }
13264   if (grp_set && mcast_sw_if_index == ~0)
13265     {
13266       errmsg ("tunnel nonexistent multicast device");
13267       return -99;
13268     }
13269   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13270     {
13271       errmsg ("tunnel dst address must be unicast");
13272       return -99;
13273     }
13274
13275
13276   if (ipv4_set && ipv6_set)
13277     {
13278       errmsg ("both IPv4 and IPv6 addresses specified");
13279       return -99;
13280     }
13281
13282   if ((vni == 0) || (vni >> 24))
13283     {
13284       errmsg ("vni not specified or out of range");
13285       return -99;
13286     }
13287
13288   M (GENEVE_ADD_DEL_TUNNEL, mp);
13289
13290   if (ipv6_set)
13291     {
13292       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13293       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13294     }
13295   else
13296     {
13297       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13298       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13299     }
13300   mp->encap_vrf_id = ntohl (encap_vrf_id);
13301   mp->decap_next_index = ntohl (decap_next_index);
13302   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13303   mp->vni = ntohl (vni);
13304   mp->is_add = is_add;
13305   mp->is_ipv6 = ipv6_set;
13306
13307   S (mp);
13308   W (ret);
13309   return ret;
13310 }
13311
13312 static void vl_api_geneve_tunnel_details_t_handler
13313   (vl_api_geneve_tunnel_details_t * mp)
13314 {
13315   vat_main_t *vam = &vat_main;
13316   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13317   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13318
13319   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13320          ntohl (mp->sw_if_index),
13321          format_ip46_address, &src, IP46_TYPE_ANY,
13322          format_ip46_address, &dst, IP46_TYPE_ANY,
13323          ntohl (mp->encap_vrf_id),
13324          ntohl (mp->decap_next_index), ntohl (mp->vni),
13325          ntohl (mp->mcast_sw_if_index));
13326 }
13327
13328 static void vl_api_geneve_tunnel_details_t_handler_json
13329   (vl_api_geneve_tunnel_details_t * mp)
13330 {
13331   vat_main_t *vam = &vat_main;
13332   vat_json_node_t *node = NULL;
13333
13334   if (VAT_JSON_ARRAY != vam->json_tree.type)
13335     {
13336       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13337       vat_json_init_array (&vam->json_tree);
13338     }
13339   node = vat_json_array_add (&vam->json_tree);
13340
13341   vat_json_init_object (node);
13342   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13343   if (mp->is_ipv6)
13344     {
13345       struct in6_addr ip6;
13346
13347       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13348       vat_json_object_add_ip6 (node, "src_address", ip6);
13349       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13350       vat_json_object_add_ip6 (node, "dst_address", ip6);
13351     }
13352   else
13353     {
13354       struct in_addr ip4;
13355
13356       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13357       vat_json_object_add_ip4 (node, "src_address", ip4);
13358       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13359       vat_json_object_add_ip4 (node, "dst_address", ip4);
13360     }
13361   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13362   vat_json_object_add_uint (node, "decap_next_index",
13363                             ntohl (mp->decap_next_index));
13364   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13365   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13366   vat_json_object_add_uint (node, "mcast_sw_if_index",
13367                             ntohl (mp->mcast_sw_if_index));
13368 }
13369
13370 static int
13371 api_geneve_tunnel_dump (vat_main_t * vam)
13372 {
13373   unformat_input_t *i = vam->input;
13374   vl_api_geneve_tunnel_dump_t *mp;
13375   vl_api_control_ping_t *mp_ping;
13376   u32 sw_if_index;
13377   u8 sw_if_index_set = 0;
13378   int ret;
13379
13380   /* Parse args required to build the message */
13381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13382     {
13383       if (unformat (i, "sw_if_index %d", &sw_if_index))
13384         sw_if_index_set = 1;
13385       else
13386         break;
13387     }
13388
13389   if (sw_if_index_set == 0)
13390     {
13391       sw_if_index = ~0;
13392     }
13393
13394   if (!vam->json_output)
13395     {
13396       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13397              "sw_if_index", "local_address", "remote_address",
13398              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13399     }
13400
13401   /* Get list of geneve-tunnel interfaces */
13402   M (GENEVE_TUNNEL_DUMP, mp);
13403
13404   mp->sw_if_index = htonl (sw_if_index);
13405
13406   S (mp);
13407
13408   /* Use a control ping for synchronization */
13409   M (CONTROL_PING, mp_ping);
13410   S (mp_ping);
13411
13412   W (ret);
13413   return ret;
13414 }
13415
13416 static int
13417 api_gre_add_del_tunnel (vat_main_t * vam)
13418 {
13419   unformat_input_t *line_input = vam->input;
13420   vl_api_gre_add_del_tunnel_t *mp;
13421   ip4_address_t src4, dst4;
13422   ip6_address_t src6, dst6;
13423   u8 is_add = 1;
13424   u8 ipv4_set = 0;
13425   u8 ipv6_set = 0;
13426   u8 t_type = GRE_TUNNEL_TYPE_L3;
13427   u8 src_set = 0;
13428   u8 dst_set = 0;
13429   u32 outer_fib_id = 0;
13430   u32 session_id = 0;
13431   u32 instance = ~0;
13432   int ret;
13433
13434   memset (&src4, 0, sizeof src4);
13435   memset (&dst4, 0, sizeof dst4);
13436   memset (&src6, 0, sizeof src6);
13437   memset (&dst6, 0, sizeof dst6);
13438
13439   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13440     {
13441       if (unformat (line_input, "del"))
13442         is_add = 0;
13443       else if (unformat (line_input, "instance %d", &instance))
13444         ;
13445       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13446         {
13447           src_set = 1;
13448           ipv4_set = 1;
13449         }
13450       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13451         {
13452           dst_set = 1;
13453           ipv4_set = 1;
13454         }
13455       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13456         {
13457           src_set = 1;
13458           ipv6_set = 1;
13459         }
13460       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13461         {
13462           dst_set = 1;
13463           ipv6_set = 1;
13464         }
13465       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13466         ;
13467       else if (unformat (line_input, "teb"))
13468         t_type = GRE_TUNNEL_TYPE_TEB;
13469       else if (unformat (line_input, "erspan %d", &session_id))
13470         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13471       else
13472         {
13473           errmsg ("parse error '%U'", format_unformat_error, line_input);
13474           return -99;
13475         }
13476     }
13477
13478   if (src_set == 0)
13479     {
13480       errmsg ("tunnel src address not specified");
13481       return -99;
13482     }
13483   if (dst_set == 0)
13484     {
13485       errmsg ("tunnel dst address not specified");
13486       return -99;
13487     }
13488   if (ipv4_set && ipv6_set)
13489     {
13490       errmsg ("both IPv4 and IPv6 addresses specified");
13491       return -99;
13492     }
13493
13494
13495   M (GRE_ADD_DEL_TUNNEL, mp);
13496
13497   if (ipv4_set)
13498     {
13499       clib_memcpy (&mp->src_address, &src4, 4);
13500       clib_memcpy (&mp->dst_address, &dst4, 4);
13501     }
13502   else
13503     {
13504       clib_memcpy (&mp->src_address, &src6, 16);
13505       clib_memcpy (&mp->dst_address, &dst6, 16);
13506     }
13507   mp->instance = htonl (instance);
13508   mp->outer_fib_id = htonl (outer_fib_id);
13509   mp->is_add = is_add;
13510   mp->session_id = htons ((u16) session_id);
13511   mp->tunnel_type = t_type;
13512   mp->is_ipv6 = ipv6_set;
13513
13514   S (mp);
13515   W (ret);
13516   return ret;
13517 }
13518
13519 static void vl_api_gre_tunnel_details_t_handler
13520   (vl_api_gre_tunnel_details_t * mp)
13521 {
13522   vat_main_t *vam = &vat_main;
13523   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13524   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13525
13526   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13527          ntohl (mp->sw_if_index),
13528          ntohl (mp->instance),
13529          format_ip46_address, &src, IP46_TYPE_ANY,
13530          format_ip46_address, &dst, IP46_TYPE_ANY,
13531          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13532 }
13533
13534 static void vl_api_gre_tunnel_details_t_handler_json
13535   (vl_api_gre_tunnel_details_t * mp)
13536 {
13537   vat_main_t *vam = &vat_main;
13538   vat_json_node_t *node = NULL;
13539   struct in_addr ip4;
13540   struct in6_addr ip6;
13541
13542   if (VAT_JSON_ARRAY != vam->json_tree.type)
13543     {
13544       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13545       vat_json_init_array (&vam->json_tree);
13546     }
13547   node = vat_json_array_add (&vam->json_tree);
13548
13549   vat_json_init_object (node);
13550   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13551   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13552   if (!mp->is_ipv6)
13553     {
13554       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13555       vat_json_object_add_ip4 (node, "src_address", ip4);
13556       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13557       vat_json_object_add_ip4 (node, "dst_address", ip4);
13558     }
13559   else
13560     {
13561       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13562       vat_json_object_add_ip6 (node, "src_address", ip6);
13563       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13564       vat_json_object_add_ip6 (node, "dst_address", ip6);
13565     }
13566   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13567   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13568   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13569   vat_json_object_add_uint (node, "session_id", mp->session_id);
13570 }
13571
13572 static int
13573 api_gre_tunnel_dump (vat_main_t * vam)
13574 {
13575   unformat_input_t *i = vam->input;
13576   vl_api_gre_tunnel_dump_t *mp;
13577   vl_api_control_ping_t *mp_ping;
13578   u32 sw_if_index;
13579   u8 sw_if_index_set = 0;
13580   int ret;
13581
13582   /* Parse args required to build the message */
13583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13584     {
13585       if (unformat (i, "sw_if_index %d", &sw_if_index))
13586         sw_if_index_set = 1;
13587       else
13588         break;
13589     }
13590
13591   if (sw_if_index_set == 0)
13592     {
13593       sw_if_index = ~0;
13594     }
13595
13596   if (!vam->json_output)
13597     {
13598       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13599              "sw_if_index", "instance", "src_address", "dst_address",
13600              "tunnel_type", "outer_fib_id", "session_id");
13601     }
13602
13603   /* Get list of gre-tunnel interfaces */
13604   M (GRE_TUNNEL_DUMP, mp);
13605
13606   mp->sw_if_index = htonl (sw_if_index);
13607
13608   S (mp);
13609
13610   /* Use a control ping for synchronization */
13611   MPING (CONTROL_PING, mp_ping);
13612   S (mp_ping);
13613
13614   W (ret);
13615   return ret;
13616 }
13617
13618 static int
13619 api_l2_fib_clear_table (vat_main_t * vam)
13620 {
13621 //  unformat_input_t * i = vam->input;
13622   vl_api_l2_fib_clear_table_t *mp;
13623   int ret;
13624
13625   M (L2_FIB_CLEAR_TABLE, mp);
13626
13627   S (mp);
13628   W (ret);
13629   return ret;
13630 }
13631
13632 static int
13633 api_l2_interface_efp_filter (vat_main_t * vam)
13634 {
13635   unformat_input_t *i = vam->input;
13636   vl_api_l2_interface_efp_filter_t *mp;
13637   u32 sw_if_index;
13638   u8 enable = 1;
13639   u8 sw_if_index_set = 0;
13640   int ret;
13641
13642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13643     {
13644       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13645         sw_if_index_set = 1;
13646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13647         sw_if_index_set = 1;
13648       else if (unformat (i, "enable"))
13649         enable = 1;
13650       else if (unformat (i, "disable"))
13651         enable = 0;
13652       else
13653         {
13654           clib_warning ("parse error '%U'", format_unformat_error, i);
13655           return -99;
13656         }
13657     }
13658
13659   if (sw_if_index_set == 0)
13660     {
13661       errmsg ("missing sw_if_index");
13662       return -99;
13663     }
13664
13665   M (L2_INTERFACE_EFP_FILTER, mp);
13666
13667   mp->sw_if_index = ntohl (sw_if_index);
13668   mp->enable_disable = enable;
13669
13670   S (mp);
13671   W (ret);
13672   return ret;
13673 }
13674
13675 #define foreach_vtr_op                          \
13676 _("disable",  L2_VTR_DISABLED)                  \
13677 _("push-1",  L2_VTR_PUSH_1)                     \
13678 _("push-2",  L2_VTR_PUSH_2)                     \
13679 _("pop-1",  L2_VTR_POP_1)                       \
13680 _("pop-2",  L2_VTR_POP_2)                       \
13681 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13682 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13683 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13684 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13685
13686 static int
13687 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13688 {
13689   unformat_input_t *i = vam->input;
13690   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13691   u32 sw_if_index;
13692   u8 sw_if_index_set = 0;
13693   u8 vtr_op_set = 0;
13694   u32 vtr_op = 0;
13695   u32 push_dot1q = 1;
13696   u32 tag1 = ~0;
13697   u32 tag2 = ~0;
13698   int ret;
13699
13700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13701     {
13702       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13703         sw_if_index_set = 1;
13704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13705         sw_if_index_set = 1;
13706       else if (unformat (i, "vtr_op %d", &vtr_op))
13707         vtr_op_set = 1;
13708 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13709       foreach_vtr_op
13710 #undef _
13711         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13712         ;
13713       else if (unformat (i, "tag1 %d", &tag1))
13714         ;
13715       else if (unformat (i, "tag2 %d", &tag2))
13716         ;
13717       else
13718         {
13719           clib_warning ("parse error '%U'", format_unformat_error, i);
13720           return -99;
13721         }
13722     }
13723
13724   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13725     {
13726       errmsg ("missing vtr operation or sw_if_index");
13727       return -99;
13728     }
13729
13730   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13731   mp->sw_if_index = ntohl (sw_if_index);
13732   mp->vtr_op = ntohl (vtr_op);
13733   mp->push_dot1q = ntohl (push_dot1q);
13734   mp->tag1 = ntohl (tag1);
13735   mp->tag2 = ntohl (tag2);
13736
13737   S (mp);
13738   W (ret);
13739   return ret;
13740 }
13741
13742 static int
13743 api_create_vhost_user_if (vat_main_t * vam)
13744 {
13745   unformat_input_t *i = vam->input;
13746   vl_api_create_vhost_user_if_t *mp;
13747   u8 *file_name;
13748   u8 is_server = 0;
13749   u8 file_name_set = 0;
13750   u32 custom_dev_instance = ~0;
13751   u8 hwaddr[6];
13752   u8 use_custom_mac = 0;
13753   u8 *tag = 0;
13754   int ret;
13755
13756   /* Shut up coverity */
13757   memset (hwaddr, 0, sizeof (hwaddr));
13758
13759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13760     {
13761       if (unformat (i, "socket %s", &file_name))
13762         {
13763           file_name_set = 1;
13764         }
13765       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13766         ;
13767       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13768         use_custom_mac = 1;
13769       else if (unformat (i, "server"))
13770         is_server = 1;
13771       else if (unformat (i, "tag %s", &tag))
13772         ;
13773       else
13774         break;
13775     }
13776
13777   if (file_name_set == 0)
13778     {
13779       errmsg ("missing socket file name");
13780       return -99;
13781     }
13782
13783   if (vec_len (file_name) > 255)
13784     {
13785       errmsg ("socket file name too long");
13786       return -99;
13787     }
13788   vec_add1 (file_name, 0);
13789
13790   M (CREATE_VHOST_USER_IF, mp);
13791
13792   mp->is_server = is_server;
13793   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13794   vec_free (file_name);
13795   if (custom_dev_instance != ~0)
13796     {
13797       mp->renumber = 1;
13798       mp->custom_dev_instance = ntohl (custom_dev_instance);
13799     }
13800   mp->use_custom_mac = use_custom_mac;
13801   clib_memcpy (mp->mac_address, hwaddr, 6);
13802   if (tag)
13803     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13804   vec_free (tag);
13805
13806   S (mp);
13807   W (ret);
13808   return ret;
13809 }
13810
13811 static int
13812 api_modify_vhost_user_if (vat_main_t * vam)
13813 {
13814   unformat_input_t *i = vam->input;
13815   vl_api_modify_vhost_user_if_t *mp;
13816   u8 *file_name;
13817   u8 is_server = 0;
13818   u8 file_name_set = 0;
13819   u32 custom_dev_instance = ~0;
13820   u8 sw_if_index_set = 0;
13821   u32 sw_if_index = (u32) ~ 0;
13822   int ret;
13823
13824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13825     {
13826       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13827         sw_if_index_set = 1;
13828       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13829         sw_if_index_set = 1;
13830       else if (unformat (i, "socket %s", &file_name))
13831         {
13832           file_name_set = 1;
13833         }
13834       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13835         ;
13836       else if (unformat (i, "server"))
13837         is_server = 1;
13838       else
13839         break;
13840     }
13841
13842   if (sw_if_index_set == 0)
13843     {
13844       errmsg ("missing sw_if_index or interface name");
13845       return -99;
13846     }
13847
13848   if (file_name_set == 0)
13849     {
13850       errmsg ("missing socket file name");
13851       return -99;
13852     }
13853
13854   if (vec_len (file_name) > 255)
13855     {
13856       errmsg ("socket file name too long");
13857       return -99;
13858     }
13859   vec_add1 (file_name, 0);
13860
13861   M (MODIFY_VHOST_USER_IF, mp);
13862
13863   mp->sw_if_index = ntohl (sw_if_index);
13864   mp->is_server = is_server;
13865   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13866   vec_free (file_name);
13867   if (custom_dev_instance != ~0)
13868     {
13869       mp->renumber = 1;
13870       mp->custom_dev_instance = ntohl (custom_dev_instance);
13871     }
13872
13873   S (mp);
13874   W (ret);
13875   return ret;
13876 }
13877
13878 static int
13879 api_delete_vhost_user_if (vat_main_t * vam)
13880 {
13881   unformat_input_t *i = vam->input;
13882   vl_api_delete_vhost_user_if_t *mp;
13883   u32 sw_if_index = ~0;
13884   u8 sw_if_index_set = 0;
13885   int ret;
13886
13887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13888     {
13889       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13890         sw_if_index_set = 1;
13891       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13892         sw_if_index_set = 1;
13893       else
13894         break;
13895     }
13896
13897   if (sw_if_index_set == 0)
13898     {
13899       errmsg ("missing sw_if_index or interface name");
13900       return -99;
13901     }
13902
13903
13904   M (DELETE_VHOST_USER_IF, mp);
13905
13906   mp->sw_if_index = ntohl (sw_if_index);
13907
13908   S (mp);
13909   W (ret);
13910   return ret;
13911 }
13912
13913 static void vl_api_sw_interface_vhost_user_details_t_handler
13914   (vl_api_sw_interface_vhost_user_details_t * mp)
13915 {
13916   vat_main_t *vam = &vat_main;
13917
13918   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13919          (char *) mp->interface_name,
13920          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13921          clib_net_to_host_u64 (mp->features), mp->is_server,
13922          ntohl (mp->num_regions), (char *) mp->sock_filename);
13923   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13924 }
13925
13926 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13927   (vl_api_sw_interface_vhost_user_details_t * mp)
13928 {
13929   vat_main_t *vam = &vat_main;
13930   vat_json_node_t *node = NULL;
13931
13932   if (VAT_JSON_ARRAY != vam->json_tree.type)
13933     {
13934       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13935       vat_json_init_array (&vam->json_tree);
13936     }
13937   node = vat_json_array_add (&vam->json_tree);
13938
13939   vat_json_init_object (node);
13940   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13941   vat_json_object_add_string_copy (node, "interface_name",
13942                                    mp->interface_name);
13943   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13944                             ntohl (mp->virtio_net_hdr_sz));
13945   vat_json_object_add_uint (node, "features",
13946                             clib_net_to_host_u64 (mp->features));
13947   vat_json_object_add_uint (node, "is_server", mp->is_server);
13948   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13949   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13950   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13951 }
13952
13953 static int
13954 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13955 {
13956   vl_api_sw_interface_vhost_user_dump_t *mp;
13957   vl_api_control_ping_t *mp_ping;
13958   int ret;
13959   print (vam->ofp,
13960          "Interface name            idx hdr_sz features server regions filename");
13961
13962   /* Get list of vhost-user interfaces */
13963   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13964   S (mp);
13965
13966   /* Use a control ping for synchronization */
13967   MPING (CONTROL_PING, mp_ping);
13968   S (mp_ping);
13969
13970   W (ret);
13971   return ret;
13972 }
13973
13974 static int
13975 api_show_version (vat_main_t * vam)
13976 {
13977   vl_api_show_version_t *mp;
13978   int ret;
13979
13980   M (SHOW_VERSION, mp);
13981
13982   S (mp);
13983   W (ret);
13984   return ret;
13985 }
13986
13987
13988 static int
13989 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13990 {
13991   unformat_input_t *line_input = vam->input;
13992   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13993   ip4_address_t local4, remote4;
13994   ip6_address_t local6, remote6;
13995   u8 is_add = 1;
13996   u8 ipv4_set = 0, ipv6_set = 0;
13997   u8 local_set = 0;
13998   u8 remote_set = 0;
13999   u8 grp_set = 0;
14000   u32 mcast_sw_if_index = ~0;
14001   u32 encap_vrf_id = 0;
14002   u32 decap_vrf_id = 0;
14003   u8 protocol = ~0;
14004   u32 vni;
14005   u8 vni_set = 0;
14006   int ret;
14007
14008   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14009   memset (&local4, 0, sizeof local4);
14010   memset (&remote4, 0, sizeof remote4);
14011   memset (&local6, 0, sizeof local6);
14012   memset (&remote6, 0, sizeof remote6);
14013
14014   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14015     {
14016       if (unformat (line_input, "del"))
14017         is_add = 0;
14018       else if (unformat (line_input, "local %U",
14019                          unformat_ip4_address, &local4))
14020         {
14021           local_set = 1;
14022           ipv4_set = 1;
14023         }
14024       else if (unformat (line_input, "remote %U",
14025                          unformat_ip4_address, &remote4))
14026         {
14027           remote_set = 1;
14028           ipv4_set = 1;
14029         }
14030       else if (unformat (line_input, "local %U",
14031                          unformat_ip6_address, &local6))
14032         {
14033           local_set = 1;
14034           ipv6_set = 1;
14035         }
14036       else if (unformat (line_input, "remote %U",
14037                          unformat_ip6_address, &remote6))
14038         {
14039           remote_set = 1;
14040           ipv6_set = 1;
14041         }
14042       else if (unformat (line_input, "group %U %U",
14043                          unformat_ip4_address, &remote4,
14044                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14045         {
14046           grp_set = remote_set = 1;
14047           ipv4_set = 1;
14048         }
14049       else if (unformat (line_input, "group %U",
14050                          unformat_ip4_address, &remote4))
14051         {
14052           grp_set = remote_set = 1;
14053           ipv4_set = 1;
14054         }
14055       else if (unformat (line_input, "group %U %U",
14056                          unformat_ip6_address, &remote6,
14057                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14058         {
14059           grp_set = remote_set = 1;
14060           ipv6_set = 1;
14061         }
14062       else if (unformat (line_input, "group %U",
14063                          unformat_ip6_address, &remote6))
14064         {
14065           grp_set = remote_set = 1;
14066           ipv6_set = 1;
14067         }
14068       else
14069         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14070         ;
14071       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14072         ;
14073       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14074         ;
14075       else if (unformat (line_input, "vni %d", &vni))
14076         vni_set = 1;
14077       else if (unformat (line_input, "next-ip4"))
14078         protocol = 1;
14079       else if (unformat (line_input, "next-ip6"))
14080         protocol = 2;
14081       else if (unformat (line_input, "next-ethernet"))
14082         protocol = 3;
14083       else if (unformat (line_input, "next-nsh"))
14084         protocol = 4;
14085       else
14086         {
14087           errmsg ("parse error '%U'", format_unformat_error, line_input);
14088           return -99;
14089         }
14090     }
14091
14092   if (local_set == 0)
14093     {
14094       errmsg ("tunnel local address not specified");
14095       return -99;
14096     }
14097   if (remote_set == 0)
14098     {
14099       errmsg ("tunnel remote address not specified");
14100       return -99;
14101     }
14102   if (grp_set && mcast_sw_if_index == ~0)
14103     {
14104       errmsg ("tunnel nonexistent multicast device");
14105       return -99;
14106     }
14107   if (ipv4_set && ipv6_set)
14108     {
14109       errmsg ("both IPv4 and IPv6 addresses specified");
14110       return -99;
14111     }
14112
14113   if (vni_set == 0)
14114     {
14115       errmsg ("vni not specified");
14116       return -99;
14117     }
14118
14119   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14120
14121
14122   if (ipv6_set)
14123     {
14124       clib_memcpy (&mp->local, &local6, sizeof (local6));
14125       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14126     }
14127   else
14128     {
14129       clib_memcpy (&mp->local, &local4, sizeof (local4));
14130       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14131     }
14132
14133   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14134   mp->encap_vrf_id = ntohl (encap_vrf_id);
14135   mp->decap_vrf_id = ntohl (decap_vrf_id);
14136   mp->protocol = protocol;
14137   mp->vni = ntohl (vni);
14138   mp->is_add = is_add;
14139   mp->is_ipv6 = ipv6_set;
14140
14141   S (mp);
14142   W (ret);
14143   return ret;
14144 }
14145
14146 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14147   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14148 {
14149   vat_main_t *vam = &vat_main;
14150   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14151   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14152
14153   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14154          ntohl (mp->sw_if_index),
14155          format_ip46_address, &local, IP46_TYPE_ANY,
14156          format_ip46_address, &remote, IP46_TYPE_ANY,
14157          ntohl (mp->vni), mp->protocol,
14158          ntohl (mp->mcast_sw_if_index),
14159          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14160 }
14161
14162
14163 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14164   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14165 {
14166   vat_main_t *vam = &vat_main;
14167   vat_json_node_t *node = NULL;
14168   struct in_addr ip4;
14169   struct in6_addr ip6;
14170
14171   if (VAT_JSON_ARRAY != vam->json_tree.type)
14172     {
14173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14174       vat_json_init_array (&vam->json_tree);
14175     }
14176   node = vat_json_array_add (&vam->json_tree);
14177
14178   vat_json_init_object (node);
14179   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14180   if (mp->is_ipv6)
14181     {
14182       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14183       vat_json_object_add_ip6 (node, "local", ip6);
14184       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14185       vat_json_object_add_ip6 (node, "remote", ip6);
14186     }
14187   else
14188     {
14189       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14190       vat_json_object_add_ip4 (node, "local", ip4);
14191       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14192       vat_json_object_add_ip4 (node, "remote", ip4);
14193     }
14194   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14195   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14196   vat_json_object_add_uint (node, "mcast_sw_if_index",
14197                             ntohl (mp->mcast_sw_if_index));
14198   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14199   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14200   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14201 }
14202
14203 static int
14204 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14205 {
14206   unformat_input_t *i = vam->input;
14207   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14208   vl_api_control_ping_t *mp_ping;
14209   u32 sw_if_index;
14210   u8 sw_if_index_set = 0;
14211   int ret;
14212
14213   /* Parse args required to build the message */
14214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14215     {
14216       if (unformat (i, "sw_if_index %d", &sw_if_index))
14217         sw_if_index_set = 1;
14218       else
14219         break;
14220     }
14221
14222   if (sw_if_index_set == 0)
14223     {
14224       sw_if_index = ~0;
14225     }
14226
14227   if (!vam->json_output)
14228     {
14229       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14230              "sw_if_index", "local", "remote", "vni",
14231              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14232     }
14233
14234   /* Get list of vxlan-tunnel interfaces */
14235   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14236
14237   mp->sw_if_index = htonl (sw_if_index);
14238
14239   S (mp);
14240
14241   /* Use a control ping for synchronization */
14242   MPING (CONTROL_PING, mp_ping);
14243   S (mp_ping);
14244
14245   W (ret);
14246   return ret;
14247 }
14248
14249 static void vl_api_l2_fib_table_details_t_handler
14250   (vl_api_l2_fib_table_details_t * mp)
14251 {
14252   vat_main_t *vam = &vat_main;
14253
14254   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14255          "       %d       %d     %d",
14256          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14257          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14258          mp->bvi_mac);
14259 }
14260
14261 static void vl_api_l2_fib_table_details_t_handler_json
14262   (vl_api_l2_fib_table_details_t * mp)
14263 {
14264   vat_main_t *vam = &vat_main;
14265   vat_json_node_t *node = NULL;
14266
14267   if (VAT_JSON_ARRAY != vam->json_tree.type)
14268     {
14269       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14270       vat_json_init_array (&vam->json_tree);
14271     }
14272   node = vat_json_array_add (&vam->json_tree);
14273
14274   vat_json_init_object (node);
14275   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14276   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14277   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14278   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14279   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14280   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14281 }
14282
14283 static int
14284 api_l2_fib_table_dump (vat_main_t * vam)
14285 {
14286   unformat_input_t *i = vam->input;
14287   vl_api_l2_fib_table_dump_t *mp;
14288   vl_api_control_ping_t *mp_ping;
14289   u32 bd_id;
14290   u8 bd_id_set = 0;
14291   int ret;
14292
14293   /* Parse args required to build the message */
14294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14295     {
14296       if (unformat (i, "bd_id %d", &bd_id))
14297         bd_id_set = 1;
14298       else
14299         break;
14300     }
14301
14302   if (bd_id_set == 0)
14303     {
14304       errmsg ("missing bridge domain");
14305       return -99;
14306     }
14307
14308   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14309
14310   /* Get list of l2 fib entries */
14311   M (L2_FIB_TABLE_DUMP, mp);
14312
14313   mp->bd_id = ntohl (bd_id);
14314   S (mp);
14315
14316   /* Use a control ping for synchronization */
14317   MPING (CONTROL_PING, mp_ping);
14318   S (mp_ping);
14319
14320   W (ret);
14321   return ret;
14322 }
14323
14324
14325 static int
14326 api_interface_name_renumber (vat_main_t * vam)
14327 {
14328   unformat_input_t *line_input = vam->input;
14329   vl_api_interface_name_renumber_t *mp;
14330   u32 sw_if_index = ~0;
14331   u32 new_show_dev_instance = ~0;
14332   int ret;
14333
14334   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14335     {
14336       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14337                     &sw_if_index))
14338         ;
14339       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14340         ;
14341       else if (unformat (line_input, "new_show_dev_instance %d",
14342                          &new_show_dev_instance))
14343         ;
14344       else
14345         break;
14346     }
14347
14348   if (sw_if_index == ~0)
14349     {
14350       errmsg ("missing interface name or sw_if_index");
14351       return -99;
14352     }
14353
14354   if (new_show_dev_instance == ~0)
14355     {
14356       errmsg ("missing new_show_dev_instance");
14357       return -99;
14358     }
14359
14360   M (INTERFACE_NAME_RENUMBER, mp);
14361
14362   mp->sw_if_index = ntohl (sw_if_index);
14363   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14364
14365   S (mp);
14366   W (ret);
14367   return ret;
14368 }
14369
14370 static int
14371 api_ip_probe_neighbor (vat_main_t * vam)
14372 {
14373   unformat_input_t *i = vam->input;
14374   vl_api_ip_probe_neighbor_t *mp;
14375   u8 int_set = 0;
14376   u8 adr_set = 0;
14377   u8 is_ipv6 = 0;
14378   u8 dst_adr[16];
14379   u32 sw_if_index;
14380   int ret;
14381
14382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14383     {
14384       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14385         int_set = 1;
14386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14387         int_set = 1;
14388       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14389         adr_set = 1;
14390       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14391         {
14392           adr_set = 1;
14393           is_ipv6 = 1;
14394         }
14395       else
14396         break;
14397     }
14398
14399   if (int_set == 0)
14400     {
14401       errmsg ("missing interface");
14402       return -99;
14403     }
14404
14405   if (adr_set == 0)
14406     {
14407       errmsg ("missing addresses");
14408       return -99;
14409     }
14410
14411   M (IP_PROBE_NEIGHBOR, mp);
14412
14413   mp->sw_if_index = ntohl (sw_if_index);
14414   mp->is_ipv6 = is_ipv6;
14415   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14416
14417   S (mp);
14418   W (ret);
14419   return ret;
14420 }
14421
14422 static int
14423 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14424 {
14425   unformat_input_t *i = vam->input;
14426   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14427   u8 mode = IP_SCAN_V46_NEIGHBORS;
14428   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14429   int ret;
14430
14431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14432     {
14433       if (unformat (i, "ip4"))
14434         mode = IP_SCAN_V4_NEIGHBORS;
14435       else if (unformat (i, "ip6"))
14436         mode = IP_SCAN_V6_NEIGHBORS;
14437       if (unformat (i, "both"))
14438         mode = IP_SCAN_V46_NEIGHBORS;
14439       else if (unformat (i, "disable"))
14440         mode = IP_SCAN_DISABLED;
14441       else if (unformat (i, "interval %d", &interval))
14442         ;
14443       else if (unformat (i, "max-time %d", &time))
14444         ;
14445       else if (unformat (i, "max-update %d", &update))
14446         ;
14447       else if (unformat (i, "delay %d", &delay))
14448         ;
14449       else if (unformat (i, "stale %d", &stale))
14450         ;
14451       else
14452         break;
14453     }
14454
14455   if (interval > 255)
14456     {
14457       errmsg ("interval cannot exceed 255 minutes.");
14458       return -99;
14459     }
14460   if (time > 255)
14461     {
14462       errmsg ("max-time cannot exceed 255 usec.");
14463       return -99;
14464     }
14465   if (update > 255)
14466     {
14467       errmsg ("max-update cannot exceed 255.");
14468       return -99;
14469     }
14470   if (delay > 255)
14471     {
14472       errmsg ("delay cannot exceed 255 msec.");
14473       return -99;
14474     }
14475   if (stale > 255)
14476     {
14477       errmsg ("stale cannot exceed 255 minutes.");
14478       return -99;
14479     }
14480
14481   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14482   mp->mode = mode;
14483   mp->scan_interval = interval;
14484   mp->max_proc_time = time;
14485   mp->max_update = update;
14486   mp->scan_int_delay = delay;
14487   mp->stale_threshold = stale;
14488
14489   S (mp);
14490   W (ret);
14491   return ret;
14492 }
14493
14494 static int
14495 api_want_ip4_arp_events (vat_main_t * vam)
14496 {
14497   unformat_input_t *line_input = vam->input;
14498   vl_api_want_ip4_arp_events_t *mp;
14499   ip4_address_t address;
14500   int address_set = 0;
14501   u32 enable_disable = 1;
14502   int ret;
14503
14504   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14505     {
14506       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14507         address_set = 1;
14508       else if (unformat (line_input, "del"))
14509         enable_disable = 0;
14510       else
14511         break;
14512     }
14513
14514   if (address_set == 0)
14515     {
14516       errmsg ("missing addresses");
14517       return -99;
14518     }
14519
14520   M (WANT_IP4_ARP_EVENTS, mp);
14521   mp->enable_disable = enable_disable;
14522   mp->pid = htonl (getpid ());
14523   mp->address = address.as_u32;
14524
14525   S (mp);
14526   W (ret);
14527   return ret;
14528 }
14529
14530 static int
14531 api_want_ip6_nd_events (vat_main_t * vam)
14532 {
14533   unformat_input_t *line_input = vam->input;
14534   vl_api_want_ip6_nd_events_t *mp;
14535   ip6_address_t address;
14536   int address_set = 0;
14537   u32 enable_disable = 1;
14538   int ret;
14539
14540   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14541     {
14542       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14543         address_set = 1;
14544       else if (unformat (line_input, "del"))
14545         enable_disable = 0;
14546       else
14547         break;
14548     }
14549
14550   if (address_set == 0)
14551     {
14552       errmsg ("missing addresses");
14553       return -99;
14554     }
14555
14556   M (WANT_IP6_ND_EVENTS, mp);
14557   mp->enable_disable = enable_disable;
14558   mp->pid = htonl (getpid ());
14559   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14560
14561   S (mp);
14562   W (ret);
14563   return ret;
14564 }
14565
14566 static int
14567 api_want_l2_macs_events (vat_main_t * vam)
14568 {
14569   unformat_input_t *line_input = vam->input;
14570   vl_api_want_l2_macs_events_t *mp;
14571   u8 enable_disable = 1;
14572   u32 scan_delay = 0;
14573   u32 max_macs_in_event = 0;
14574   u32 learn_limit = 0;
14575   int ret;
14576
14577   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14578     {
14579       if (unformat (line_input, "learn-limit %d", &learn_limit))
14580         ;
14581       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14582         ;
14583       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14584         ;
14585       else if (unformat (line_input, "disable"))
14586         enable_disable = 0;
14587       else
14588         break;
14589     }
14590
14591   M (WANT_L2_MACS_EVENTS, mp);
14592   mp->enable_disable = enable_disable;
14593   mp->pid = htonl (getpid ());
14594   mp->learn_limit = htonl (learn_limit);
14595   mp->scan_delay = (u8) scan_delay;
14596   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14597   S (mp);
14598   W (ret);
14599   return ret;
14600 }
14601
14602 static int
14603 api_input_acl_set_interface (vat_main_t * vam)
14604 {
14605   unformat_input_t *i = vam->input;
14606   vl_api_input_acl_set_interface_t *mp;
14607   u32 sw_if_index;
14608   int sw_if_index_set;
14609   u32 ip4_table_index = ~0;
14610   u32 ip6_table_index = ~0;
14611   u32 l2_table_index = ~0;
14612   u8 is_add = 1;
14613   int ret;
14614
14615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14616     {
14617       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14618         sw_if_index_set = 1;
14619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14620         sw_if_index_set = 1;
14621       else if (unformat (i, "del"))
14622         is_add = 0;
14623       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14624         ;
14625       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14626         ;
14627       else if (unformat (i, "l2-table %d", &l2_table_index))
14628         ;
14629       else
14630         {
14631           clib_warning ("parse error '%U'", format_unformat_error, i);
14632           return -99;
14633         }
14634     }
14635
14636   if (sw_if_index_set == 0)
14637     {
14638       errmsg ("missing interface name or sw_if_index");
14639       return -99;
14640     }
14641
14642   M (INPUT_ACL_SET_INTERFACE, mp);
14643
14644   mp->sw_if_index = ntohl (sw_if_index);
14645   mp->ip4_table_index = ntohl (ip4_table_index);
14646   mp->ip6_table_index = ntohl (ip6_table_index);
14647   mp->l2_table_index = ntohl (l2_table_index);
14648   mp->is_add = is_add;
14649
14650   S (mp);
14651   W (ret);
14652   return ret;
14653 }
14654
14655 static int
14656 api_output_acl_set_interface (vat_main_t * vam)
14657 {
14658   unformat_input_t *i = vam->input;
14659   vl_api_output_acl_set_interface_t *mp;
14660   u32 sw_if_index;
14661   int sw_if_index_set;
14662   u32 ip4_table_index = ~0;
14663   u32 ip6_table_index = ~0;
14664   u32 l2_table_index = ~0;
14665   u8 is_add = 1;
14666   int ret;
14667
14668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14669     {
14670       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14671         sw_if_index_set = 1;
14672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14673         sw_if_index_set = 1;
14674       else if (unformat (i, "del"))
14675         is_add = 0;
14676       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14677         ;
14678       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14679         ;
14680       else if (unformat (i, "l2-table %d", &l2_table_index))
14681         ;
14682       else
14683         {
14684           clib_warning ("parse error '%U'", format_unformat_error, i);
14685           return -99;
14686         }
14687     }
14688
14689   if (sw_if_index_set == 0)
14690     {
14691       errmsg ("missing interface name or sw_if_index");
14692       return -99;
14693     }
14694
14695   M (OUTPUT_ACL_SET_INTERFACE, mp);
14696
14697   mp->sw_if_index = ntohl (sw_if_index);
14698   mp->ip4_table_index = ntohl (ip4_table_index);
14699   mp->ip6_table_index = ntohl (ip6_table_index);
14700   mp->l2_table_index = ntohl (l2_table_index);
14701   mp->is_add = is_add;
14702
14703   S (mp);
14704   W (ret);
14705   return ret;
14706 }
14707
14708 static int
14709 api_ip_address_dump (vat_main_t * vam)
14710 {
14711   unformat_input_t *i = vam->input;
14712   vl_api_ip_address_dump_t *mp;
14713   vl_api_control_ping_t *mp_ping;
14714   u32 sw_if_index = ~0;
14715   u8 sw_if_index_set = 0;
14716   u8 ipv4_set = 0;
14717   u8 ipv6_set = 0;
14718   int ret;
14719
14720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14721     {
14722       if (unformat (i, "sw_if_index %d", &sw_if_index))
14723         sw_if_index_set = 1;
14724       else
14725         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14726         sw_if_index_set = 1;
14727       else if (unformat (i, "ipv4"))
14728         ipv4_set = 1;
14729       else if (unformat (i, "ipv6"))
14730         ipv6_set = 1;
14731       else
14732         break;
14733     }
14734
14735   if (ipv4_set && ipv6_set)
14736     {
14737       errmsg ("ipv4 and ipv6 flags cannot be both set");
14738       return -99;
14739     }
14740
14741   if ((!ipv4_set) && (!ipv6_set))
14742     {
14743       errmsg ("no ipv4 nor ipv6 flag set");
14744       return -99;
14745     }
14746
14747   if (sw_if_index_set == 0)
14748     {
14749       errmsg ("missing interface name or sw_if_index");
14750       return -99;
14751     }
14752
14753   vam->current_sw_if_index = sw_if_index;
14754   vam->is_ipv6 = ipv6_set;
14755
14756   M (IP_ADDRESS_DUMP, mp);
14757   mp->sw_if_index = ntohl (sw_if_index);
14758   mp->is_ipv6 = ipv6_set;
14759   S (mp);
14760
14761   /* Use a control ping for synchronization */
14762   MPING (CONTROL_PING, mp_ping);
14763   S (mp_ping);
14764
14765   W (ret);
14766   return ret;
14767 }
14768
14769 static int
14770 api_ip_dump (vat_main_t * vam)
14771 {
14772   vl_api_ip_dump_t *mp;
14773   vl_api_control_ping_t *mp_ping;
14774   unformat_input_t *in = vam->input;
14775   int ipv4_set = 0;
14776   int ipv6_set = 0;
14777   int is_ipv6;
14778   int i;
14779   int ret;
14780
14781   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14782     {
14783       if (unformat (in, "ipv4"))
14784         ipv4_set = 1;
14785       else if (unformat (in, "ipv6"))
14786         ipv6_set = 1;
14787       else
14788         break;
14789     }
14790
14791   if (ipv4_set && ipv6_set)
14792     {
14793       errmsg ("ipv4 and ipv6 flags cannot be both set");
14794       return -99;
14795     }
14796
14797   if ((!ipv4_set) && (!ipv6_set))
14798     {
14799       errmsg ("no ipv4 nor ipv6 flag set");
14800       return -99;
14801     }
14802
14803   is_ipv6 = ipv6_set;
14804   vam->is_ipv6 = is_ipv6;
14805
14806   /* free old data */
14807   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14808     {
14809       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14810     }
14811   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14812
14813   M (IP_DUMP, mp);
14814   mp->is_ipv6 = ipv6_set;
14815   S (mp);
14816
14817   /* Use a control ping for synchronization */
14818   MPING (CONTROL_PING, mp_ping);
14819   S (mp_ping);
14820
14821   W (ret);
14822   return ret;
14823 }
14824
14825 static int
14826 api_ipsec_spd_add_del (vat_main_t * vam)
14827 {
14828   unformat_input_t *i = vam->input;
14829   vl_api_ipsec_spd_add_del_t *mp;
14830   u32 spd_id = ~0;
14831   u8 is_add = 1;
14832   int ret;
14833
14834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14835     {
14836       if (unformat (i, "spd_id %d", &spd_id))
14837         ;
14838       else if (unformat (i, "del"))
14839         is_add = 0;
14840       else
14841         {
14842           clib_warning ("parse error '%U'", format_unformat_error, i);
14843           return -99;
14844         }
14845     }
14846   if (spd_id == ~0)
14847     {
14848       errmsg ("spd_id must be set");
14849       return -99;
14850     }
14851
14852   M (IPSEC_SPD_ADD_DEL, mp);
14853
14854   mp->spd_id = ntohl (spd_id);
14855   mp->is_add = is_add;
14856
14857   S (mp);
14858   W (ret);
14859   return ret;
14860 }
14861
14862 static int
14863 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14864 {
14865   unformat_input_t *i = vam->input;
14866   vl_api_ipsec_interface_add_del_spd_t *mp;
14867   u32 sw_if_index;
14868   u8 sw_if_index_set = 0;
14869   u32 spd_id = (u32) ~ 0;
14870   u8 is_add = 1;
14871   int ret;
14872
14873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14874     {
14875       if (unformat (i, "del"))
14876         is_add = 0;
14877       else if (unformat (i, "spd_id %d", &spd_id))
14878         ;
14879       else
14880         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14881         sw_if_index_set = 1;
14882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14883         sw_if_index_set = 1;
14884       else
14885         {
14886           clib_warning ("parse error '%U'", format_unformat_error, i);
14887           return -99;
14888         }
14889
14890     }
14891
14892   if (spd_id == (u32) ~ 0)
14893     {
14894       errmsg ("spd_id must be set");
14895       return -99;
14896     }
14897
14898   if (sw_if_index_set == 0)
14899     {
14900       errmsg ("missing interface name or sw_if_index");
14901       return -99;
14902     }
14903
14904   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14905
14906   mp->spd_id = ntohl (spd_id);
14907   mp->sw_if_index = ntohl (sw_if_index);
14908   mp->is_add = is_add;
14909
14910   S (mp);
14911   W (ret);
14912   return ret;
14913 }
14914
14915 static int
14916 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14917 {
14918   unformat_input_t *i = vam->input;
14919   vl_api_ipsec_spd_add_del_entry_t *mp;
14920   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14921   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14922   i32 priority = 0;
14923   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14924   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14925   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14926   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14927   int ret;
14928
14929   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14930   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14931   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14932   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14933   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14934   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14935
14936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14937     {
14938       if (unformat (i, "del"))
14939         is_add = 0;
14940       if (unformat (i, "outbound"))
14941         is_outbound = 1;
14942       if (unformat (i, "inbound"))
14943         is_outbound = 0;
14944       else if (unformat (i, "spd_id %d", &spd_id))
14945         ;
14946       else if (unformat (i, "sa_id %d", &sa_id))
14947         ;
14948       else if (unformat (i, "priority %d", &priority))
14949         ;
14950       else if (unformat (i, "protocol %d", &protocol))
14951         ;
14952       else if (unformat (i, "lport_start %d", &lport_start))
14953         ;
14954       else if (unformat (i, "lport_stop %d", &lport_stop))
14955         ;
14956       else if (unformat (i, "rport_start %d", &rport_start))
14957         ;
14958       else if (unformat (i, "rport_stop %d", &rport_stop))
14959         ;
14960       else
14961         if (unformat
14962             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14963         {
14964           is_ipv6 = 0;
14965           is_ip_any = 0;
14966         }
14967       else
14968         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14969         {
14970           is_ipv6 = 0;
14971           is_ip_any = 0;
14972         }
14973       else
14974         if (unformat
14975             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14976         {
14977           is_ipv6 = 0;
14978           is_ip_any = 0;
14979         }
14980       else
14981         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14982         {
14983           is_ipv6 = 0;
14984           is_ip_any = 0;
14985         }
14986       else
14987         if (unformat
14988             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14989         {
14990           is_ipv6 = 1;
14991           is_ip_any = 0;
14992         }
14993       else
14994         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14995         {
14996           is_ipv6 = 1;
14997           is_ip_any = 0;
14998         }
14999       else
15000         if (unformat
15001             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15002         {
15003           is_ipv6 = 1;
15004           is_ip_any = 0;
15005         }
15006       else
15007         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15008         {
15009           is_ipv6 = 1;
15010           is_ip_any = 0;
15011         }
15012       else
15013         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15014         {
15015           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15016             {
15017               clib_warning ("unsupported action: 'resolve'");
15018               return -99;
15019             }
15020         }
15021       else
15022         {
15023           clib_warning ("parse error '%U'", format_unformat_error, i);
15024           return -99;
15025         }
15026
15027     }
15028
15029   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15030
15031   mp->spd_id = ntohl (spd_id);
15032   mp->priority = ntohl (priority);
15033   mp->is_outbound = is_outbound;
15034
15035   mp->is_ipv6 = is_ipv6;
15036   if (is_ipv6 || is_ip_any)
15037     {
15038       clib_memcpy (mp->remote_address_start, &raddr6_start,
15039                    sizeof (ip6_address_t));
15040       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15041                    sizeof (ip6_address_t));
15042       clib_memcpy (mp->local_address_start, &laddr6_start,
15043                    sizeof (ip6_address_t));
15044       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15045                    sizeof (ip6_address_t));
15046     }
15047   else
15048     {
15049       clib_memcpy (mp->remote_address_start, &raddr4_start,
15050                    sizeof (ip4_address_t));
15051       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15052                    sizeof (ip4_address_t));
15053       clib_memcpy (mp->local_address_start, &laddr4_start,
15054                    sizeof (ip4_address_t));
15055       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15056                    sizeof (ip4_address_t));
15057     }
15058   mp->protocol = (u8) protocol;
15059   mp->local_port_start = ntohs ((u16) lport_start);
15060   mp->local_port_stop = ntohs ((u16) lport_stop);
15061   mp->remote_port_start = ntohs ((u16) rport_start);
15062   mp->remote_port_stop = ntohs ((u16) rport_stop);
15063   mp->policy = (u8) policy;
15064   mp->sa_id = ntohl (sa_id);
15065   mp->is_add = is_add;
15066   mp->is_ip_any = is_ip_any;
15067   S (mp);
15068   W (ret);
15069   return ret;
15070 }
15071
15072 static int
15073 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15074 {
15075   unformat_input_t *i = vam->input;
15076   vl_api_ipsec_sad_add_del_entry_t *mp;
15077   u32 sad_id = 0, spi = 0;
15078   u8 *ck = 0, *ik = 0;
15079   u8 is_add = 1;
15080
15081   u8 protocol = IPSEC_PROTOCOL_AH;
15082   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15083   u32 crypto_alg = 0, integ_alg = 0;
15084   ip4_address_t tun_src4;
15085   ip4_address_t tun_dst4;
15086   ip6_address_t tun_src6;
15087   ip6_address_t tun_dst6;
15088   int ret;
15089
15090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15091     {
15092       if (unformat (i, "del"))
15093         is_add = 0;
15094       else if (unformat (i, "sad_id %d", &sad_id))
15095         ;
15096       else if (unformat (i, "spi %d", &spi))
15097         ;
15098       else if (unformat (i, "esp"))
15099         protocol = IPSEC_PROTOCOL_ESP;
15100       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15101         {
15102           is_tunnel = 1;
15103           is_tunnel_ipv6 = 0;
15104         }
15105       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15106         {
15107           is_tunnel = 1;
15108           is_tunnel_ipv6 = 0;
15109         }
15110       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15111         {
15112           is_tunnel = 1;
15113           is_tunnel_ipv6 = 1;
15114         }
15115       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15116         {
15117           is_tunnel = 1;
15118           is_tunnel_ipv6 = 1;
15119         }
15120       else
15121         if (unformat
15122             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15123         {
15124           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15125               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15126             {
15127               clib_warning ("unsupported crypto-alg: '%U'",
15128                             format_ipsec_crypto_alg, crypto_alg);
15129               return -99;
15130             }
15131         }
15132       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15133         ;
15134       else
15135         if (unformat
15136             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15137         {
15138           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15139               integ_alg >= IPSEC_INTEG_N_ALG)
15140             {
15141               clib_warning ("unsupported integ-alg: '%U'",
15142                             format_ipsec_integ_alg, integ_alg);
15143               return -99;
15144             }
15145         }
15146       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15147         ;
15148       else
15149         {
15150           clib_warning ("parse error '%U'", format_unformat_error, i);
15151           return -99;
15152         }
15153
15154     }
15155
15156   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15157
15158   mp->sad_id = ntohl (sad_id);
15159   mp->is_add = is_add;
15160   mp->protocol = protocol;
15161   mp->spi = ntohl (spi);
15162   mp->is_tunnel = is_tunnel;
15163   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15164   mp->crypto_algorithm = crypto_alg;
15165   mp->integrity_algorithm = integ_alg;
15166   mp->crypto_key_length = vec_len (ck);
15167   mp->integrity_key_length = vec_len (ik);
15168
15169   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15170     mp->crypto_key_length = sizeof (mp->crypto_key);
15171
15172   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15173     mp->integrity_key_length = sizeof (mp->integrity_key);
15174
15175   if (ck)
15176     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15177   if (ik)
15178     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15179
15180   if (is_tunnel)
15181     {
15182       if (is_tunnel_ipv6)
15183         {
15184           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15185                        sizeof (ip6_address_t));
15186           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15187                        sizeof (ip6_address_t));
15188         }
15189       else
15190         {
15191           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15192                        sizeof (ip4_address_t));
15193           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15194                        sizeof (ip4_address_t));
15195         }
15196     }
15197
15198   S (mp);
15199   W (ret);
15200   return ret;
15201 }
15202
15203 static int
15204 api_ipsec_sa_set_key (vat_main_t * vam)
15205 {
15206   unformat_input_t *i = vam->input;
15207   vl_api_ipsec_sa_set_key_t *mp;
15208   u32 sa_id;
15209   u8 *ck = 0, *ik = 0;
15210   int ret;
15211
15212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15213     {
15214       if (unformat (i, "sa_id %d", &sa_id))
15215         ;
15216       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15217         ;
15218       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15219         ;
15220       else
15221         {
15222           clib_warning ("parse error '%U'", format_unformat_error, i);
15223           return -99;
15224         }
15225     }
15226
15227   M (IPSEC_SA_SET_KEY, mp);
15228
15229   mp->sa_id = ntohl (sa_id);
15230   mp->crypto_key_length = vec_len (ck);
15231   mp->integrity_key_length = vec_len (ik);
15232
15233   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15234     mp->crypto_key_length = sizeof (mp->crypto_key);
15235
15236   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15237     mp->integrity_key_length = sizeof (mp->integrity_key);
15238
15239   if (ck)
15240     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15241   if (ik)
15242     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15243
15244   S (mp);
15245   W (ret);
15246   return ret;
15247 }
15248
15249 static int
15250 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15251 {
15252   unformat_input_t *i = vam->input;
15253   vl_api_ipsec_tunnel_if_add_del_t *mp;
15254   u32 local_spi = 0, remote_spi = 0;
15255   u32 crypto_alg = 0, integ_alg = 0;
15256   u8 *lck = NULL, *rck = NULL;
15257   u8 *lik = NULL, *rik = NULL;
15258   ip4_address_t local_ip = { {0} };
15259   ip4_address_t remote_ip = { {0} };
15260   u8 is_add = 1;
15261   u8 esn = 0;
15262   u8 anti_replay = 0;
15263   u8 renumber = 0;
15264   u32 instance = ~0;
15265   int ret;
15266
15267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15268     {
15269       if (unformat (i, "del"))
15270         is_add = 0;
15271       else if (unformat (i, "esn"))
15272         esn = 1;
15273       else if (unformat (i, "anti_replay"))
15274         anti_replay = 1;
15275       else if (unformat (i, "local_spi %d", &local_spi))
15276         ;
15277       else if (unformat (i, "remote_spi %d", &remote_spi))
15278         ;
15279       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15280         ;
15281       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15282         ;
15283       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15284         ;
15285       else
15286         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15287         ;
15288       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15289         ;
15290       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15291         ;
15292       else
15293         if (unformat
15294             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15295         {
15296           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15297               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15298             {
15299               errmsg ("unsupported crypto-alg: '%U'\n",
15300                       format_ipsec_crypto_alg, crypto_alg);
15301               return -99;
15302             }
15303         }
15304       else
15305         if (unformat
15306             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15307         {
15308           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15309               integ_alg >= IPSEC_INTEG_N_ALG)
15310             {
15311               errmsg ("unsupported integ-alg: '%U'\n",
15312                       format_ipsec_integ_alg, integ_alg);
15313               return -99;
15314             }
15315         }
15316       else if (unformat (i, "instance %u", &instance))
15317         renumber = 1;
15318       else
15319         {
15320           errmsg ("parse error '%U'\n", format_unformat_error, i);
15321           return -99;
15322         }
15323     }
15324
15325   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15326
15327   mp->is_add = is_add;
15328   mp->esn = esn;
15329   mp->anti_replay = anti_replay;
15330
15331   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15332   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15333
15334   mp->local_spi = htonl (local_spi);
15335   mp->remote_spi = htonl (remote_spi);
15336   mp->crypto_alg = (u8) crypto_alg;
15337
15338   mp->local_crypto_key_len = 0;
15339   if (lck)
15340     {
15341       mp->local_crypto_key_len = vec_len (lck);
15342       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15343         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15344       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15345     }
15346
15347   mp->remote_crypto_key_len = 0;
15348   if (rck)
15349     {
15350       mp->remote_crypto_key_len = vec_len (rck);
15351       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15352         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15353       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15354     }
15355
15356   mp->integ_alg = (u8) integ_alg;
15357
15358   mp->local_integ_key_len = 0;
15359   if (lik)
15360     {
15361       mp->local_integ_key_len = vec_len (lik);
15362       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15363         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15364       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15365     }
15366
15367   mp->remote_integ_key_len = 0;
15368   if (rik)
15369     {
15370       mp->remote_integ_key_len = vec_len (rik);
15371       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15372         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15373       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15374     }
15375
15376   if (renumber)
15377     {
15378       mp->renumber = renumber;
15379       mp->show_instance = ntohl (instance);
15380     }
15381
15382   S (mp);
15383   W (ret);
15384   return ret;
15385 }
15386
15387 static void
15388 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15389 {
15390   vat_main_t *vam = &vat_main;
15391
15392   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15393          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15394          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15395          "tunnel_src_addr %U tunnel_dst_addr %U "
15396          "salt %u seq_outbound %lu last_seq_inbound %lu "
15397          "replay_window %lu total_data_size %lu\n",
15398          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15399          mp->protocol,
15400          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15401          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15402          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15403          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15404          mp->tunnel_src_addr,
15405          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15406          mp->tunnel_dst_addr,
15407          ntohl (mp->salt),
15408          clib_net_to_host_u64 (mp->seq_outbound),
15409          clib_net_to_host_u64 (mp->last_seq_inbound),
15410          clib_net_to_host_u64 (mp->replay_window),
15411          clib_net_to_host_u64 (mp->total_data_size));
15412 }
15413
15414 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15415 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15416
15417 static void vl_api_ipsec_sa_details_t_handler_json
15418   (vl_api_ipsec_sa_details_t * mp)
15419 {
15420   vat_main_t *vam = &vat_main;
15421   vat_json_node_t *node = NULL;
15422   struct in_addr src_ip4, dst_ip4;
15423   struct in6_addr src_ip6, dst_ip6;
15424
15425   if (VAT_JSON_ARRAY != vam->json_tree.type)
15426     {
15427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15428       vat_json_init_array (&vam->json_tree);
15429     }
15430   node = vat_json_array_add (&vam->json_tree);
15431
15432   vat_json_init_object (node);
15433   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15434   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15435   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15436   vat_json_object_add_uint (node, "proto", mp->protocol);
15437   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15438   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15439   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15440   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15441   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15442   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15443   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15444                              mp->crypto_key_len);
15445   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15446                              mp->integ_key_len);
15447   if (mp->is_tunnel_ip6)
15448     {
15449       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15450       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15451       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15452       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15453     }
15454   else
15455     {
15456       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15457       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15458       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15459       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15460     }
15461   vat_json_object_add_uint (node, "replay_window",
15462                             clib_net_to_host_u64 (mp->replay_window));
15463   vat_json_object_add_uint (node, "total_data_size",
15464                             clib_net_to_host_u64 (mp->total_data_size));
15465
15466 }
15467
15468 static int
15469 api_ipsec_sa_dump (vat_main_t * vam)
15470 {
15471   unformat_input_t *i = vam->input;
15472   vl_api_ipsec_sa_dump_t *mp;
15473   vl_api_control_ping_t *mp_ping;
15474   u32 sa_id = ~0;
15475   int ret;
15476
15477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15478     {
15479       if (unformat (i, "sa_id %d", &sa_id))
15480         ;
15481       else
15482         {
15483           clib_warning ("parse error '%U'", format_unformat_error, i);
15484           return -99;
15485         }
15486     }
15487
15488   M (IPSEC_SA_DUMP, mp);
15489
15490   mp->sa_id = ntohl (sa_id);
15491
15492   S (mp);
15493
15494   /* Use a control ping for synchronization */
15495   M (CONTROL_PING, mp_ping);
15496   S (mp_ping);
15497
15498   W (ret);
15499   return ret;
15500 }
15501
15502 static int
15503 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15504 {
15505   unformat_input_t *i = vam->input;
15506   vl_api_ipsec_tunnel_if_set_key_t *mp;
15507   u32 sw_if_index = ~0;
15508   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15509   u8 *key = 0;
15510   u32 alg = ~0;
15511   int ret;
15512
15513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15514     {
15515       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15516         ;
15517       else
15518         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15519         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15520       else
15521         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15522         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15523       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15524         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15525       else
15526         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15527         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15528       else if (unformat (i, "%U", unformat_hex_string, &key))
15529         ;
15530       else
15531         {
15532           clib_warning ("parse error '%U'", format_unformat_error, i);
15533           return -99;
15534         }
15535     }
15536
15537   if (sw_if_index == ~0)
15538     {
15539       errmsg ("interface must be specified");
15540       return -99;
15541     }
15542
15543   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15544     {
15545       errmsg ("key type must be specified");
15546       return -99;
15547     }
15548
15549   if (alg == ~0)
15550     {
15551       errmsg ("algorithm must be specified");
15552       return -99;
15553     }
15554
15555   if (vec_len (key) == 0)
15556     {
15557       errmsg ("key must be specified");
15558       return -99;
15559     }
15560
15561   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15562
15563   mp->sw_if_index = htonl (sw_if_index);
15564   mp->alg = alg;
15565   mp->key_type = key_type;
15566   mp->key_len = vec_len (key);
15567   clib_memcpy (mp->key, key, vec_len (key));
15568
15569   S (mp);
15570   W (ret);
15571
15572   return ret;
15573 }
15574
15575 static int
15576 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15577 {
15578   unformat_input_t *i = vam->input;
15579   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15580   u32 sw_if_index = ~0;
15581   u32 sa_id = ~0;
15582   u8 is_outbound = (u8) ~ 0;
15583   int ret;
15584
15585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15586     {
15587       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15588         ;
15589       else if (unformat (i, "sa_id %d", &sa_id))
15590         ;
15591       else if (unformat (i, "outbound"))
15592         is_outbound = 1;
15593       else if (unformat (i, "inbound"))
15594         is_outbound = 0;
15595       else
15596         {
15597           clib_warning ("parse error '%U'", format_unformat_error, i);
15598           return -99;
15599         }
15600     }
15601
15602   if (sw_if_index == ~0)
15603     {
15604       errmsg ("interface must be specified");
15605       return -99;
15606     }
15607
15608   if (sa_id == ~0)
15609     {
15610       errmsg ("SA ID must be specified");
15611       return -99;
15612     }
15613
15614   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15615
15616   mp->sw_if_index = htonl (sw_if_index);
15617   mp->sa_id = htonl (sa_id);
15618   mp->is_outbound = is_outbound;
15619
15620   S (mp);
15621   W (ret);
15622
15623   return ret;
15624 }
15625
15626 static int
15627 api_ikev2_profile_add_del (vat_main_t * vam)
15628 {
15629   unformat_input_t *i = vam->input;
15630   vl_api_ikev2_profile_add_del_t *mp;
15631   u8 is_add = 1;
15632   u8 *name = 0;
15633   int ret;
15634
15635   const char *valid_chars = "a-zA-Z0-9_";
15636
15637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15638     {
15639       if (unformat (i, "del"))
15640         is_add = 0;
15641       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15642         vec_add1 (name, 0);
15643       else
15644         {
15645           errmsg ("parse error '%U'", format_unformat_error, i);
15646           return -99;
15647         }
15648     }
15649
15650   if (!vec_len (name))
15651     {
15652       errmsg ("profile name must be specified");
15653       return -99;
15654     }
15655
15656   if (vec_len (name) > 64)
15657     {
15658       errmsg ("profile name too long");
15659       return -99;
15660     }
15661
15662   M (IKEV2_PROFILE_ADD_DEL, mp);
15663
15664   clib_memcpy (mp->name, name, vec_len (name));
15665   mp->is_add = is_add;
15666   vec_free (name);
15667
15668   S (mp);
15669   W (ret);
15670   return ret;
15671 }
15672
15673 static int
15674 api_ikev2_profile_set_auth (vat_main_t * vam)
15675 {
15676   unformat_input_t *i = vam->input;
15677   vl_api_ikev2_profile_set_auth_t *mp;
15678   u8 *name = 0;
15679   u8 *data = 0;
15680   u32 auth_method = 0;
15681   u8 is_hex = 0;
15682   int ret;
15683
15684   const char *valid_chars = "a-zA-Z0-9_";
15685
15686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15687     {
15688       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15689         vec_add1 (name, 0);
15690       else if (unformat (i, "auth_method %U",
15691                          unformat_ikev2_auth_method, &auth_method))
15692         ;
15693       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15694         is_hex = 1;
15695       else if (unformat (i, "auth_data %v", &data))
15696         ;
15697       else
15698         {
15699           errmsg ("parse error '%U'", format_unformat_error, i);
15700           return -99;
15701         }
15702     }
15703
15704   if (!vec_len (name))
15705     {
15706       errmsg ("profile name must be specified");
15707       return -99;
15708     }
15709
15710   if (vec_len (name) > 64)
15711     {
15712       errmsg ("profile name too long");
15713       return -99;
15714     }
15715
15716   if (!vec_len (data))
15717     {
15718       errmsg ("auth_data must be specified");
15719       return -99;
15720     }
15721
15722   if (!auth_method)
15723     {
15724       errmsg ("auth_method must be specified");
15725       return -99;
15726     }
15727
15728   M (IKEV2_PROFILE_SET_AUTH, mp);
15729
15730   mp->is_hex = is_hex;
15731   mp->auth_method = (u8) auth_method;
15732   mp->data_len = vec_len (data);
15733   clib_memcpy (mp->name, name, vec_len (name));
15734   clib_memcpy (mp->data, data, vec_len (data));
15735   vec_free (name);
15736   vec_free (data);
15737
15738   S (mp);
15739   W (ret);
15740   return ret;
15741 }
15742
15743 static int
15744 api_ikev2_profile_set_id (vat_main_t * vam)
15745 {
15746   unformat_input_t *i = vam->input;
15747   vl_api_ikev2_profile_set_id_t *mp;
15748   u8 *name = 0;
15749   u8 *data = 0;
15750   u8 is_local = 0;
15751   u32 id_type = 0;
15752   ip4_address_t ip4;
15753   int ret;
15754
15755   const char *valid_chars = "a-zA-Z0-9_";
15756
15757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15758     {
15759       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15760         vec_add1 (name, 0);
15761       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15762         ;
15763       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15764         {
15765           data = vec_new (u8, 4);
15766           clib_memcpy (data, ip4.as_u8, 4);
15767         }
15768       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15769         ;
15770       else if (unformat (i, "id_data %v", &data))
15771         ;
15772       else if (unformat (i, "local"))
15773         is_local = 1;
15774       else if (unformat (i, "remote"))
15775         is_local = 0;
15776       else
15777         {
15778           errmsg ("parse error '%U'", format_unformat_error, i);
15779           return -99;
15780         }
15781     }
15782
15783   if (!vec_len (name))
15784     {
15785       errmsg ("profile name must be specified");
15786       return -99;
15787     }
15788
15789   if (vec_len (name) > 64)
15790     {
15791       errmsg ("profile name too long");
15792       return -99;
15793     }
15794
15795   if (!vec_len (data))
15796     {
15797       errmsg ("id_data must be specified");
15798       return -99;
15799     }
15800
15801   if (!id_type)
15802     {
15803       errmsg ("id_type must be specified");
15804       return -99;
15805     }
15806
15807   M (IKEV2_PROFILE_SET_ID, mp);
15808
15809   mp->is_local = is_local;
15810   mp->id_type = (u8) id_type;
15811   mp->data_len = vec_len (data);
15812   clib_memcpy (mp->name, name, vec_len (name));
15813   clib_memcpy (mp->data, data, vec_len (data));
15814   vec_free (name);
15815   vec_free (data);
15816
15817   S (mp);
15818   W (ret);
15819   return ret;
15820 }
15821
15822 static int
15823 api_ikev2_profile_set_ts (vat_main_t * vam)
15824 {
15825   unformat_input_t *i = vam->input;
15826   vl_api_ikev2_profile_set_ts_t *mp;
15827   u8 *name = 0;
15828   u8 is_local = 0;
15829   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15830   ip4_address_t start_addr, end_addr;
15831
15832   const char *valid_chars = "a-zA-Z0-9_";
15833   int ret;
15834
15835   start_addr.as_u32 = 0;
15836   end_addr.as_u32 = (u32) ~ 0;
15837
15838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15839     {
15840       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15841         vec_add1 (name, 0);
15842       else if (unformat (i, "protocol %d", &proto))
15843         ;
15844       else if (unformat (i, "start_port %d", &start_port))
15845         ;
15846       else if (unformat (i, "end_port %d", &end_port))
15847         ;
15848       else
15849         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15850         ;
15851       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15852         ;
15853       else if (unformat (i, "local"))
15854         is_local = 1;
15855       else if (unformat (i, "remote"))
15856         is_local = 0;
15857       else
15858         {
15859           errmsg ("parse error '%U'", format_unformat_error, i);
15860           return -99;
15861         }
15862     }
15863
15864   if (!vec_len (name))
15865     {
15866       errmsg ("profile name must be specified");
15867       return -99;
15868     }
15869
15870   if (vec_len (name) > 64)
15871     {
15872       errmsg ("profile name too long");
15873       return -99;
15874     }
15875
15876   M (IKEV2_PROFILE_SET_TS, mp);
15877
15878   mp->is_local = is_local;
15879   mp->proto = (u8) proto;
15880   mp->start_port = (u16) start_port;
15881   mp->end_port = (u16) end_port;
15882   mp->start_addr = start_addr.as_u32;
15883   mp->end_addr = end_addr.as_u32;
15884   clib_memcpy (mp->name, name, vec_len (name));
15885   vec_free (name);
15886
15887   S (mp);
15888   W (ret);
15889   return ret;
15890 }
15891
15892 static int
15893 api_ikev2_set_local_key (vat_main_t * vam)
15894 {
15895   unformat_input_t *i = vam->input;
15896   vl_api_ikev2_set_local_key_t *mp;
15897   u8 *file = 0;
15898   int ret;
15899
15900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15901     {
15902       if (unformat (i, "file %v", &file))
15903         vec_add1 (file, 0);
15904       else
15905         {
15906           errmsg ("parse error '%U'", format_unformat_error, i);
15907           return -99;
15908         }
15909     }
15910
15911   if (!vec_len (file))
15912     {
15913       errmsg ("RSA key file must be specified");
15914       return -99;
15915     }
15916
15917   if (vec_len (file) > 256)
15918     {
15919       errmsg ("file name too long");
15920       return -99;
15921     }
15922
15923   M (IKEV2_SET_LOCAL_KEY, mp);
15924
15925   clib_memcpy (mp->key_file, file, vec_len (file));
15926   vec_free (file);
15927
15928   S (mp);
15929   W (ret);
15930   return ret;
15931 }
15932
15933 static int
15934 api_ikev2_set_responder (vat_main_t * vam)
15935 {
15936   unformat_input_t *i = vam->input;
15937   vl_api_ikev2_set_responder_t *mp;
15938   int ret;
15939   u8 *name = 0;
15940   u32 sw_if_index = ~0;
15941   ip4_address_t address;
15942
15943   const char *valid_chars = "a-zA-Z0-9_";
15944
15945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15946     {
15947       if (unformat
15948           (i, "%U interface %d address %U", unformat_token, valid_chars,
15949            &name, &sw_if_index, unformat_ip4_address, &address))
15950         vec_add1 (name, 0);
15951       else
15952         {
15953           errmsg ("parse error '%U'", format_unformat_error, i);
15954           return -99;
15955         }
15956     }
15957
15958   if (!vec_len (name))
15959     {
15960       errmsg ("profile name must be specified");
15961       return -99;
15962     }
15963
15964   if (vec_len (name) > 64)
15965     {
15966       errmsg ("profile name too long");
15967       return -99;
15968     }
15969
15970   M (IKEV2_SET_RESPONDER, mp);
15971
15972   clib_memcpy (mp->name, name, vec_len (name));
15973   vec_free (name);
15974
15975   mp->sw_if_index = sw_if_index;
15976   clib_memcpy (mp->address, &address, sizeof (address));
15977
15978   S (mp);
15979   W (ret);
15980   return ret;
15981 }
15982
15983 static int
15984 api_ikev2_set_ike_transforms (vat_main_t * vam)
15985 {
15986   unformat_input_t *i = vam->input;
15987   vl_api_ikev2_set_ike_transforms_t *mp;
15988   int ret;
15989   u8 *name = 0;
15990   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15991
15992   const char *valid_chars = "a-zA-Z0-9_";
15993
15994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15995     {
15996       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15997                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15998         vec_add1 (name, 0);
15999       else
16000         {
16001           errmsg ("parse error '%U'", format_unformat_error, i);
16002           return -99;
16003         }
16004     }
16005
16006   if (!vec_len (name))
16007     {
16008       errmsg ("profile name must be specified");
16009       return -99;
16010     }
16011
16012   if (vec_len (name) > 64)
16013     {
16014       errmsg ("profile name too long");
16015       return -99;
16016     }
16017
16018   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16019
16020   clib_memcpy (mp->name, name, vec_len (name));
16021   vec_free (name);
16022   mp->crypto_alg = crypto_alg;
16023   mp->crypto_key_size = crypto_key_size;
16024   mp->integ_alg = integ_alg;
16025   mp->dh_group = dh_group;
16026
16027   S (mp);
16028   W (ret);
16029   return ret;
16030 }
16031
16032
16033 static int
16034 api_ikev2_set_esp_transforms (vat_main_t * vam)
16035 {
16036   unformat_input_t *i = vam->input;
16037   vl_api_ikev2_set_esp_transforms_t *mp;
16038   int ret;
16039   u8 *name = 0;
16040   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16041
16042   const char *valid_chars = "a-zA-Z0-9_";
16043
16044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16045     {
16046       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16047                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16048         vec_add1 (name, 0);
16049       else
16050         {
16051           errmsg ("parse error '%U'", format_unformat_error, i);
16052           return -99;
16053         }
16054     }
16055
16056   if (!vec_len (name))
16057     {
16058       errmsg ("profile name must be specified");
16059       return -99;
16060     }
16061
16062   if (vec_len (name) > 64)
16063     {
16064       errmsg ("profile name too long");
16065       return -99;
16066     }
16067
16068   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16069
16070   clib_memcpy (mp->name, name, vec_len (name));
16071   vec_free (name);
16072   mp->crypto_alg = crypto_alg;
16073   mp->crypto_key_size = crypto_key_size;
16074   mp->integ_alg = integ_alg;
16075   mp->dh_group = dh_group;
16076
16077   S (mp);
16078   W (ret);
16079   return ret;
16080 }
16081
16082 static int
16083 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16084 {
16085   unformat_input_t *i = vam->input;
16086   vl_api_ikev2_set_sa_lifetime_t *mp;
16087   int ret;
16088   u8 *name = 0;
16089   u64 lifetime, lifetime_maxdata;
16090   u32 lifetime_jitter, handover;
16091
16092   const char *valid_chars = "a-zA-Z0-9_";
16093
16094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16095     {
16096       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16097                     &lifetime, &lifetime_jitter, &handover,
16098                     &lifetime_maxdata))
16099         vec_add1 (name, 0);
16100       else
16101         {
16102           errmsg ("parse error '%U'", format_unformat_error, i);
16103           return -99;
16104         }
16105     }
16106
16107   if (!vec_len (name))
16108     {
16109       errmsg ("profile name must be specified");
16110       return -99;
16111     }
16112
16113   if (vec_len (name) > 64)
16114     {
16115       errmsg ("profile name too long");
16116       return -99;
16117     }
16118
16119   M (IKEV2_SET_SA_LIFETIME, mp);
16120
16121   clib_memcpy (mp->name, name, vec_len (name));
16122   vec_free (name);
16123   mp->lifetime = lifetime;
16124   mp->lifetime_jitter = lifetime_jitter;
16125   mp->handover = handover;
16126   mp->lifetime_maxdata = lifetime_maxdata;
16127
16128   S (mp);
16129   W (ret);
16130   return ret;
16131 }
16132
16133 static int
16134 api_ikev2_initiate_sa_init (vat_main_t * vam)
16135 {
16136   unformat_input_t *i = vam->input;
16137   vl_api_ikev2_initiate_sa_init_t *mp;
16138   int ret;
16139   u8 *name = 0;
16140
16141   const char *valid_chars = "a-zA-Z0-9_";
16142
16143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16144     {
16145       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16146         vec_add1 (name, 0);
16147       else
16148         {
16149           errmsg ("parse error '%U'", format_unformat_error, i);
16150           return -99;
16151         }
16152     }
16153
16154   if (!vec_len (name))
16155     {
16156       errmsg ("profile name must be specified");
16157       return -99;
16158     }
16159
16160   if (vec_len (name) > 64)
16161     {
16162       errmsg ("profile name too long");
16163       return -99;
16164     }
16165
16166   M (IKEV2_INITIATE_SA_INIT, mp);
16167
16168   clib_memcpy (mp->name, name, vec_len (name));
16169   vec_free (name);
16170
16171   S (mp);
16172   W (ret);
16173   return ret;
16174 }
16175
16176 static int
16177 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16178 {
16179   unformat_input_t *i = vam->input;
16180   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16181   int ret;
16182   u64 ispi;
16183
16184
16185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16186     {
16187       if (unformat (i, "%lx", &ispi))
16188         ;
16189       else
16190         {
16191           errmsg ("parse error '%U'", format_unformat_error, i);
16192           return -99;
16193         }
16194     }
16195
16196   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16197
16198   mp->ispi = ispi;
16199
16200   S (mp);
16201   W (ret);
16202   return ret;
16203 }
16204
16205 static int
16206 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16207 {
16208   unformat_input_t *i = vam->input;
16209   vl_api_ikev2_initiate_del_child_sa_t *mp;
16210   int ret;
16211   u32 ispi;
16212
16213
16214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16215     {
16216       if (unformat (i, "%x", &ispi))
16217         ;
16218       else
16219         {
16220           errmsg ("parse error '%U'", format_unformat_error, i);
16221           return -99;
16222         }
16223     }
16224
16225   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16226
16227   mp->ispi = ispi;
16228
16229   S (mp);
16230   W (ret);
16231   return ret;
16232 }
16233
16234 static int
16235 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16236 {
16237   unformat_input_t *i = vam->input;
16238   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16239   int ret;
16240   u32 ispi;
16241
16242
16243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16244     {
16245       if (unformat (i, "%x", &ispi))
16246         ;
16247       else
16248         {
16249           errmsg ("parse error '%U'", format_unformat_error, i);
16250           return -99;
16251         }
16252     }
16253
16254   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16255
16256   mp->ispi = ispi;
16257
16258   S (mp);
16259   W (ret);
16260   return ret;
16261 }
16262
16263 /*
16264  * MAP
16265  */
16266 static int
16267 api_map_add_domain (vat_main_t * vam)
16268 {
16269   unformat_input_t *i = vam->input;
16270   vl_api_map_add_domain_t *mp;
16271
16272   ip4_address_t ip4_prefix;
16273   ip6_address_t ip6_prefix;
16274   ip6_address_t ip6_src;
16275   u32 num_m_args = 0;
16276   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16277     0, psid_length = 0;
16278   u8 is_translation = 0;
16279   u32 mtu = 0;
16280   u32 ip6_src_len = 128;
16281   int ret;
16282
16283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16284     {
16285       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16286                     &ip4_prefix, &ip4_prefix_len))
16287         num_m_args++;
16288       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16289                          &ip6_prefix, &ip6_prefix_len))
16290         num_m_args++;
16291       else
16292         if (unformat
16293             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16294              &ip6_src_len))
16295         num_m_args++;
16296       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16297         num_m_args++;
16298       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16299         num_m_args++;
16300       else if (unformat (i, "psid-offset %d", &psid_offset))
16301         num_m_args++;
16302       else if (unformat (i, "psid-len %d", &psid_length))
16303         num_m_args++;
16304       else if (unformat (i, "mtu %d", &mtu))
16305         num_m_args++;
16306       else if (unformat (i, "map-t"))
16307         is_translation = 1;
16308       else
16309         {
16310           clib_warning ("parse error '%U'", format_unformat_error, i);
16311           return -99;
16312         }
16313     }
16314
16315   if (num_m_args < 3)
16316     {
16317       errmsg ("mandatory argument(s) missing");
16318       return -99;
16319     }
16320
16321   /* Construct the API message */
16322   M (MAP_ADD_DOMAIN, mp);
16323
16324   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16325   mp->ip4_prefix_len = ip4_prefix_len;
16326
16327   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16328   mp->ip6_prefix_len = ip6_prefix_len;
16329
16330   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16331   mp->ip6_src_prefix_len = ip6_src_len;
16332
16333   mp->ea_bits_len = ea_bits_len;
16334   mp->psid_offset = psid_offset;
16335   mp->psid_length = psid_length;
16336   mp->is_translation = is_translation;
16337   mp->mtu = htons (mtu);
16338
16339   /* send it... */
16340   S (mp);
16341
16342   /* Wait for a reply, return good/bad news  */
16343   W (ret);
16344   return ret;
16345 }
16346
16347 static int
16348 api_map_del_domain (vat_main_t * vam)
16349 {
16350   unformat_input_t *i = vam->input;
16351   vl_api_map_del_domain_t *mp;
16352
16353   u32 num_m_args = 0;
16354   u32 index;
16355   int ret;
16356
16357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16358     {
16359       if (unformat (i, "index %d", &index))
16360         num_m_args++;
16361       else
16362         {
16363           clib_warning ("parse error '%U'", format_unformat_error, i);
16364           return -99;
16365         }
16366     }
16367
16368   if (num_m_args != 1)
16369     {
16370       errmsg ("mandatory argument(s) missing");
16371       return -99;
16372     }
16373
16374   /* Construct the API message */
16375   M (MAP_DEL_DOMAIN, mp);
16376
16377   mp->index = ntohl (index);
16378
16379   /* send it... */
16380   S (mp);
16381
16382   /* Wait for a reply, return good/bad news  */
16383   W (ret);
16384   return ret;
16385 }
16386
16387 static int
16388 api_map_add_del_rule (vat_main_t * vam)
16389 {
16390   unformat_input_t *i = vam->input;
16391   vl_api_map_add_del_rule_t *mp;
16392   u8 is_add = 1;
16393   ip6_address_t ip6_dst;
16394   u32 num_m_args = 0, index, psid = 0;
16395   int ret;
16396
16397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16398     {
16399       if (unformat (i, "index %d", &index))
16400         num_m_args++;
16401       else if (unformat (i, "psid %d", &psid))
16402         num_m_args++;
16403       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16404         num_m_args++;
16405       else if (unformat (i, "del"))
16406         {
16407           is_add = 0;
16408         }
16409       else
16410         {
16411           clib_warning ("parse error '%U'", format_unformat_error, i);
16412           return -99;
16413         }
16414     }
16415
16416   /* Construct the API message */
16417   M (MAP_ADD_DEL_RULE, mp);
16418
16419   mp->index = ntohl (index);
16420   mp->is_add = is_add;
16421   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16422   mp->psid = ntohs (psid);
16423
16424   /* send it... */
16425   S (mp);
16426
16427   /* Wait for a reply, return good/bad news  */
16428   W (ret);
16429   return ret;
16430 }
16431
16432 static int
16433 api_map_domain_dump (vat_main_t * vam)
16434 {
16435   vl_api_map_domain_dump_t *mp;
16436   vl_api_control_ping_t *mp_ping;
16437   int ret;
16438
16439   /* Construct the API message */
16440   M (MAP_DOMAIN_DUMP, mp);
16441
16442   /* send it... */
16443   S (mp);
16444
16445   /* Use a control ping for synchronization */
16446   MPING (CONTROL_PING, mp_ping);
16447   S (mp_ping);
16448
16449   W (ret);
16450   return ret;
16451 }
16452
16453 static int
16454 api_map_rule_dump (vat_main_t * vam)
16455 {
16456   unformat_input_t *i = vam->input;
16457   vl_api_map_rule_dump_t *mp;
16458   vl_api_control_ping_t *mp_ping;
16459   u32 domain_index = ~0;
16460   int ret;
16461
16462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16463     {
16464       if (unformat (i, "index %u", &domain_index))
16465         ;
16466       else
16467         break;
16468     }
16469
16470   if (domain_index == ~0)
16471     {
16472       clib_warning ("parse error: domain index expected");
16473       return -99;
16474     }
16475
16476   /* Construct the API message */
16477   M (MAP_RULE_DUMP, mp);
16478
16479   mp->domain_index = htonl (domain_index);
16480
16481   /* send it... */
16482   S (mp);
16483
16484   /* Use a control ping for synchronization */
16485   MPING (CONTROL_PING, mp_ping);
16486   S (mp_ping);
16487
16488   W (ret);
16489   return ret;
16490 }
16491
16492 static void vl_api_map_add_domain_reply_t_handler
16493   (vl_api_map_add_domain_reply_t * mp)
16494 {
16495   vat_main_t *vam = &vat_main;
16496   i32 retval = ntohl (mp->retval);
16497
16498   if (vam->async_mode)
16499     {
16500       vam->async_errors += (retval < 0);
16501     }
16502   else
16503     {
16504       vam->retval = retval;
16505       vam->result_ready = 1;
16506     }
16507 }
16508
16509 static void vl_api_map_add_domain_reply_t_handler_json
16510   (vl_api_map_add_domain_reply_t * mp)
16511 {
16512   vat_main_t *vam = &vat_main;
16513   vat_json_node_t node;
16514
16515   vat_json_init_object (&node);
16516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16517   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16518
16519   vat_json_print (vam->ofp, &node);
16520   vat_json_free (&node);
16521
16522   vam->retval = ntohl (mp->retval);
16523   vam->result_ready = 1;
16524 }
16525
16526 static int
16527 api_get_first_msg_id (vat_main_t * vam)
16528 {
16529   vl_api_get_first_msg_id_t *mp;
16530   unformat_input_t *i = vam->input;
16531   u8 *name;
16532   u8 name_set = 0;
16533   int ret;
16534
16535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16536     {
16537       if (unformat (i, "client %s", &name))
16538         name_set = 1;
16539       else
16540         break;
16541     }
16542
16543   if (name_set == 0)
16544     {
16545       errmsg ("missing client name");
16546       return -99;
16547     }
16548   vec_add1 (name, 0);
16549
16550   if (vec_len (name) > 63)
16551     {
16552       errmsg ("client name too long");
16553       return -99;
16554     }
16555
16556   M (GET_FIRST_MSG_ID, mp);
16557   clib_memcpy (mp->name, name, vec_len (name));
16558   S (mp);
16559   W (ret);
16560   return ret;
16561 }
16562
16563 static int
16564 api_cop_interface_enable_disable (vat_main_t * vam)
16565 {
16566   unformat_input_t *line_input = vam->input;
16567   vl_api_cop_interface_enable_disable_t *mp;
16568   u32 sw_if_index = ~0;
16569   u8 enable_disable = 1;
16570   int ret;
16571
16572   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16573     {
16574       if (unformat (line_input, "disable"))
16575         enable_disable = 0;
16576       if (unformat (line_input, "enable"))
16577         enable_disable = 1;
16578       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16579                          vam, &sw_if_index))
16580         ;
16581       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16582         ;
16583       else
16584         break;
16585     }
16586
16587   if (sw_if_index == ~0)
16588     {
16589       errmsg ("missing interface name or sw_if_index");
16590       return -99;
16591     }
16592
16593   /* Construct the API message */
16594   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16595   mp->sw_if_index = ntohl (sw_if_index);
16596   mp->enable_disable = enable_disable;
16597
16598   /* send it... */
16599   S (mp);
16600   /* Wait for the reply */
16601   W (ret);
16602   return ret;
16603 }
16604
16605 static int
16606 api_cop_whitelist_enable_disable (vat_main_t * vam)
16607 {
16608   unformat_input_t *line_input = vam->input;
16609   vl_api_cop_whitelist_enable_disable_t *mp;
16610   u32 sw_if_index = ~0;
16611   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16612   u32 fib_id = 0;
16613   int ret;
16614
16615   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16616     {
16617       if (unformat (line_input, "ip4"))
16618         ip4 = 1;
16619       else if (unformat (line_input, "ip6"))
16620         ip6 = 1;
16621       else if (unformat (line_input, "default"))
16622         default_cop = 1;
16623       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16624                          vam, &sw_if_index))
16625         ;
16626       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16627         ;
16628       else if (unformat (line_input, "fib-id %d", &fib_id))
16629         ;
16630       else
16631         break;
16632     }
16633
16634   if (sw_if_index == ~0)
16635     {
16636       errmsg ("missing interface name or sw_if_index");
16637       return -99;
16638     }
16639
16640   /* Construct the API message */
16641   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16642   mp->sw_if_index = ntohl (sw_if_index);
16643   mp->fib_id = ntohl (fib_id);
16644   mp->ip4 = ip4;
16645   mp->ip6 = ip6;
16646   mp->default_cop = default_cop;
16647
16648   /* send it... */
16649   S (mp);
16650   /* Wait for the reply */
16651   W (ret);
16652   return ret;
16653 }
16654
16655 static int
16656 api_get_node_graph (vat_main_t * vam)
16657 {
16658   vl_api_get_node_graph_t *mp;
16659   int ret;
16660
16661   M (GET_NODE_GRAPH, mp);
16662
16663   /* send it... */
16664   S (mp);
16665   /* Wait for the reply */
16666   W (ret);
16667   return ret;
16668 }
16669
16670 /* *INDENT-OFF* */
16671 /** Used for parsing LISP eids */
16672 typedef CLIB_PACKED(struct{
16673   u8 addr[16];   /**< eid address */
16674   u32 len;       /**< prefix length if IP */
16675   u8 type;      /**< type of eid */
16676 }) lisp_eid_vat_t;
16677 /* *INDENT-ON* */
16678
16679 static uword
16680 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16681 {
16682   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16683
16684   memset (a, 0, sizeof (a[0]));
16685
16686   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16687     {
16688       a->type = 0;              /* ipv4 type */
16689     }
16690   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16691     {
16692       a->type = 1;              /* ipv6 type */
16693     }
16694   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16695     {
16696       a->type = 2;              /* mac type */
16697     }
16698   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16699     {
16700       a->type = 3;              /* NSH type */
16701       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16702       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16703     }
16704   else
16705     {
16706       return 0;
16707     }
16708
16709   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16710     {
16711       return 0;
16712     }
16713
16714   return 1;
16715 }
16716
16717 static int
16718 lisp_eid_size_vat (u8 type)
16719 {
16720   switch (type)
16721     {
16722     case 0:
16723       return 4;
16724     case 1:
16725       return 16;
16726     case 2:
16727       return 6;
16728     case 3:
16729       return 5;
16730     }
16731   return 0;
16732 }
16733
16734 static void
16735 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16736 {
16737   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16738 }
16739
16740 static int
16741 api_one_add_del_locator_set (vat_main_t * vam)
16742 {
16743   unformat_input_t *input = vam->input;
16744   vl_api_one_add_del_locator_set_t *mp;
16745   u8 is_add = 1;
16746   u8 *locator_set_name = NULL;
16747   u8 locator_set_name_set = 0;
16748   vl_api_local_locator_t locator, *locators = 0;
16749   u32 sw_if_index, priority, weight;
16750   u32 data_len = 0;
16751
16752   int ret;
16753   /* Parse args required to build the message */
16754   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16755     {
16756       if (unformat (input, "del"))
16757         {
16758           is_add = 0;
16759         }
16760       else if (unformat (input, "locator-set %s", &locator_set_name))
16761         {
16762           locator_set_name_set = 1;
16763         }
16764       else if (unformat (input, "sw_if_index %u p %u w %u",
16765                          &sw_if_index, &priority, &weight))
16766         {
16767           locator.sw_if_index = htonl (sw_if_index);
16768           locator.priority = priority;
16769           locator.weight = weight;
16770           vec_add1 (locators, locator);
16771         }
16772       else
16773         if (unformat
16774             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16775              &sw_if_index, &priority, &weight))
16776         {
16777           locator.sw_if_index = htonl (sw_if_index);
16778           locator.priority = priority;
16779           locator.weight = weight;
16780           vec_add1 (locators, locator);
16781         }
16782       else
16783         break;
16784     }
16785
16786   if (locator_set_name_set == 0)
16787     {
16788       errmsg ("missing locator-set name");
16789       vec_free (locators);
16790       return -99;
16791     }
16792
16793   if (vec_len (locator_set_name) > 64)
16794     {
16795       errmsg ("locator-set name too long");
16796       vec_free (locator_set_name);
16797       vec_free (locators);
16798       return -99;
16799     }
16800   vec_add1 (locator_set_name, 0);
16801
16802   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16803
16804   /* Construct the API message */
16805   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16806
16807   mp->is_add = is_add;
16808   clib_memcpy (mp->locator_set_name, locator_set_name,
16809                vec_len (locator_set_name));
16810   vec_free (locator_set_name);
16811
16812   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16813   if (locators)
16814     clib_memcpy (mp->locators, locators, data_len);
16815   vec_free (locators);
16816
16817   /* send it... */
16818   S (mp);
16819
16820   /* Wait for a reply... */
16821   W (ret);
16822   return ret;
16823 }
16824
16825 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16826
16827 static int
16828 api_one_add_del_locator (vat_main_t * vam)
16829 {
16830   unformat_input_t *input = vam->input;
16831   vl_api_one_add_del_locator_t *mp;
16832   u32 tmp_if_index = ~0;
16833   u32 sw_if_index = ~0;
16834   u8 sw_if_index_set = 0;
16835   u8 sw_if_index_if_name_set = 0;
16836   u32 priority = ~0;
16837   u8 priority_set = 0;
16838   u32 weight = ~0;
16839   u8 weight_set = 0;
16840   u8 is_add = 1;
16841   u8 *locator_set_name = NULL;
16842   u8 locator_set_name_set = 0;
16843   int ret;
16844
16845   /* Parse args required to build the message */
16846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16847     {
16848       if (unformat (input, "del"))
16849         {
16850           is_add = 0;
16851         }
16852       else if (unformat (input, "locator-set %s", &locator_set_name))
16853         {
16854           locator_set_name_set = 1;
16855         }
16856       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16857                          &tmp_if_index))
16858         {
16859           sw_if_index_if_name_set = 1;
16860           sw_if_index = tmp_if_index;
16861         }
16862       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16863         {
16864           sw_if_index_set = 1;
16865           sw_if_index = tmp_if_index;
16866         }
16867       else if (unformat (input, "p %d", &priority))
16868         {
16869           priority_set = 1;
16870         }
16871       else if (unformat (input, "w %d", &weight))
16872         {
16873           weight_set = 1;
16874         }
16875       else
16876         break;
16877     }
16878
16879   if (locator_set_name_set == 0)
16880     {
16881       errmsg ("missing locator-set name");
16882       return -99;
16883     }
16884
16885   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16886     {
16887       errmsg ("missing sw_if_index");
16888       vec_free (locator_set_name);
16889       return -99;
16890     }
16891
16892   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16893     {
16894       errmsg ("cannot use both params interface name and sw_if_index");
16895       vec_free (locator_set_name);
16896       return -99;
16897     }
16898
16899   if (priority_set == 0)
16900     {
16901       errmsg ("missing locator-set priority");
16902       vec_free (locator_set_name);
16903       return -99;
16904     }
16905
16906   if (weight_set == 0)
16907     {
16908       errmsg ("missing locator-set weight");
16909       vec_free (locator_set_name);
16910       return -99;
16911     }
16912
16913   if (vec_len (locator_set_name) > 64)
16914     {
16915       errmsg ("locator-set name too long");
16916       vec_free (locator_set_name);
16917       return -99;
16918     }
16919   vec_add1 (locator_set_name, 0);
16920
16921   /* Construct the API message */
16922   M (ONE_ADD_DEL_LOCATOR, mp);
16923
16924   mp->is_add = is_add;
16925   mp->sw_if_index = ntohl (sw_if_index);
16926   mp->priority = priority;
16927   mp->weight = weight;
16928   clib_memcpy (mp->locator_set_name, locator_set_name,
16929                vec_len (locator_set_name));
16930   vec_free (locator_set_name);
16931
16932   /* send it... */
16933   S (mp);
16934
16935   /* Wait for a reply... */
16936   W (ret);
16937   return ret;
16938 }
16939
16940 #define api_lisp_add_del_locator api_one_add_del_locator
16941
16942 uword
16943 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16944 {
16945   u32 *key_id = va_arg (*args, u32 *);
16946   u8 *s = 0;
16947
16948   if (unformat (input, "%s", &s))
16949     {
16950       if (!strcmp ((char *) s, "sha1"))
16951         key_id[0] = HMAC_SHA_1_96;
16952       else if (!strcmp ((char *) s, "sha256"))
16953         key_id[0] = HMAC_SHA_256_128;
16954       else
16955         {
16956           clib_warning ("invalid key_id: '%s'", s);
16957           key_id[0] = HMAC_NO_KEY;
16958         }
16959     }
16960   else
16961     return 0;
16962
16963   vec_free (s);
16964   return 1;
16965 }
16966
16967 static int
16968 api_one_add_del_local_eid (vat_main_t * vam)
16969 {
16970   unformat_input_t *input = vam->input;
16971   vl_api_one_add_del_local_eid_t *mp;
16972   u8 is_add = 1;
16973   u8 eid_set = 0;
16974   lisp_eid_vat_t _eid, *eid = &_eid;
16975   u8 *locator_set_name = 0;
16976   u8 locator_set_name_set = 0;
16977   u32 vni = 0;
16978   u16 key_id = 0;
16979   u8 *key = 0;
16980   int ret;
16981
16982   /* Parse args required to build the message */
16983   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16984     {
16985       if (unformat (input, "del"))
16986         {
16987           is_add = 0;
16988         }
16989       else if (unformat (input, "vni %d", &vni))
16990         {
16991           ;
16992         }
16993       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16994         {
16995           eid_set = 1;
16996         }
16997       else if (unformat (input, "locator-set %s", &locator_set_name))
16998         {
16999           locator_set_name_set = 1;
17000         }
17001       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17002         ;
17003       else if (unformat (input, "secret-key %_%v%_", &key))
17004         ;
17005       else
17006         break;
17007     }
17008
17009   if (locator_set_name_set == 0)
17010     {
17011       errmsg ("missing locator-set name");
17012       return -99;
17013     }
17014
17015   if (0 == eid_set)
17016     {
17017       errmsg ("EID address not set!");
17018       vec_free (locator_set_name);
17019       return -99;
17020     }
17021
17022   if (key && (0 == key_id))
17023     {
17024       errmsg ("invalid key_id!");
17025       return -99;
17026     }
17027
17028   if (vec_len (key) > 64)
17029     {
17030       errmsg ("key too long");
17031       vec_free (key);
17032       return -99;
17033     }
17034
17035   if (vec_len (locator_set_name) > 64)
17036     {
17037       errmsg ("locator-set name too long");
17038       vec_free (locator_set_name);
17039       return -99;
17040     }
17041   vec_add1 (locator_set_name, 0);
17042
17043   /* Construct the API message */
17044   M (ONE_ADD_DEL_LOCAL_EID, mp);
17045
17046   mp->is_add = is_add;
17047   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17048   mp->eid_type = eid->type;
17049   mp->prefix_len = eid->len;
17050   mp->vni = clib_host_to_net_u32 (vni);
17051   mp->key_id = clib_host_to_net_u16 (key_id);
17052   clib_memcpy (mp->locator_set_name, locator_set_name,
17053                vec_len (locator_set_name));
17054   clib_memcpy (mp->key, key, vec_len (key));
17055
17056   vec_free (locator_set_name);
17057   vec_free (key);
17058
17059   /* send it... */
17060   S (mp);
17061
17062   /* Wait for a reply... */
17063   W (ret);
17064   return ret;
17065 }
17066
17067 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17068
17069 static int
17070 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17071 {
17072   u32 dp_table = 0, vni = 0;;
17073   unformat_input_t *input = vam->input;
17074   vl_api_gpe_add_del_fwd_entry_t *mp;
17075   u8 is_add = 1;
17076   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17077   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17078   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17079   u32 action = ~0, w;
17080   ip4_address_t rmt_rloc4, lcl_rloc4;
17081   ip6_address_t rmt_rloc6, lcl_rloc6;
17082   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17083   int ret;
17084
17085   memset (&rloc, 0, sizeof (rloc));
17086
17087   /* Parse args required to build the message */
17088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17089     {
17090       if (unformat (input, "del"))
17091         is_add = 0;
17092       else if (unformat (input, "add"))
17093         is_add = 1;
17094       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17095         {
17096           rmt_eid_set = 1;
17097         }
17098       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17099         {
17100           lcl_eid_set = 1;
17101         }
17102       else if (unformat (input, "vrf %d", &dp_table))
17103         ;
17104       else if (unformat (input, "bd %d", &dp_table))
17105         ;
17106       else if (unformat (input, "vni %d", &vni))
17107         ;
17108       else if (unformat (input, "w %d", &w))
17109         {
17110           if (!curr_rloc)
17111             {
17112               errmsg ("No RLOC configured for setting priority/weight!");
17113               return -99;
17114             }
17115           curr_rloc->weight = w;
17116         }
17117       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17118                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17119         {
17120           rloc.is_ip4 = 1;
17121
17122           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17123           rloc.weight = 0;
17124           vec_add1 (lcl_locs, rloc);
17125
17126           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17127           vec_add1 (rmt_locs, rloc);
17128           /* weight saved in rmt loc */
17129           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17130         }
17131       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17132                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17133         {
17134           rloc.is_ip4 = 0;
17135           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17136           rloc.weight = 0;
17137           vec_add1 (lcl_locs, rloc);
17138
17139           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17140           vec_add1 (rmt_locs, rloc);
17141           /* weight saved in rmt loc */
17142           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17143         }
17144       else if (unformat (input, "action %d", &action))
17145         {
17146           ;
17147         }
17148       else
17149         {
17150           clib_warning ("parse error '%U'", format_unformat_error, input);
17151           return -99;
17152         }
17153     }
17154
17155   if (!rmt_eid_set)
17156     {
17157       errmsg ("remote eid addresses not set");
17158       return -99;
17159     }
17160
17161   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17162     {
17163       errmsg ("eid types don't match");
17164       return -99;
17165     }
17166
17167   if (0 == rmt_locs && (u32) ~ 0 == action)
17168     {
17169       errmsg ("action not set for negative mapping");
17170       return -99;
17171     }
17172
17173   /* Construct the API message */
17174   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17175       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17176
17177   mp->is_add = is_add;
17178   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17179   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17180   mp->eid_type = rmt_eid->type;
17181   mp->dp_table = clib_host_to_net_u32 (dp_table);
17182   mp->vni = clib_host_to_net_u32 (vni);
17183   mp->rmt_len = rmt_eid->len;
17184   mp->lcl_len = lcl_eid->len;
17185   mp->action = action;
17186
17187   if (0 != rmt_locs && 0 != lcl_locs)
17188     {
17189       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17190       clib_memcpy (mp->locs, lcl_locs,
17191                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17192
17193       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17194       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17195                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17196     }
17197   vec_free (lcl_locs);
17198   vec_free (rmt_locs);
17199
17200   /* send it... */
17201   S (mp);
17202
17203   /* Wait for a reply... */
17204   W (ret);
17205   return ret;
17206 }
17207
17208 static int
17209 api_one_add_del_map_server (vat_main_t * vam)
17210 {
17211   unformat_input_t *input = vam->input;
17212   vl_api_one_add_del_map_server_t *mp;
17213   u8 is_add = 1;
17214   u8 ipv4_set = 0;
17215   u8 ipv6_set = 0;
17216   ip4_address_t ipv4;
17217   ip6_address_t ipv6;
17218   int ret;
17219
17220   /* Parse args required to build the message */
17221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17222     {
17223       if (unformat (input, "del"))
17224         {
17225           is_add = 0;
17226         }
17227       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17228         {
17229           ipv4_set = 1;
17230         }
17231       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17232         {
17233           ipv6_set = 1;
17234         }
17235       else
17236         break;
17237     }
17238
17239   if (ipv4_set && ipv6_set)
17240     {
17241       errmsg ("both eid v4 and v6 addresses set");
17242       return -99;
17243     }
17244
17245   if (!ipv4_set && !ipv6_set)
17246     {
17247       errmsg ("eid addresses not set");
17248       return -99;
17249     }
17250
17251   /* Construct the API message */
17252   M (ONE_ADD_DEL_MAP_SERVER, mp);
17253
17254   mp->is_add = is_add;
17255   if (ipv6_set)
17256     {
17257       mp->is_ipv6 = 1;
17258       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17259     }
17260   else
17261     {
17262       mp->is_ipv6 = 0;
17263       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17264     }
17265
17266   /* send it... */
17267   S (mp);
17268
17269   /* Wait for a reply... */
17270   W (ret);
17271   return ret;
17272 }
17273
17274 #define api_lisp_add_del_map_server api_one_add_del_map_server
17275
17276 static int
17277 api_one_add_del_map_resolver (vat_main_t * vam)
17278 {
17279   unformat_input_t *input = vam->input;
17280   vl_api_one_add_del_map_resolver_t *mp;
17281   u8 is_add = 1;
17282   u8 ipv4_set = 0;
17283   u8 ipv6_set = 0;
17284   ip4_address_t ipv4;
17285   ip6_address_t ipv6;
17286   int ret;
17287
17288   /* Parse args required to build the message */
17289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17290     {
17291       if (unformat (input, "del"))
17292         {
17293           is_add = 0;
17294         }
17295       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17296         {
17297           ipv4_set = 1;
17298         }
17299       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17300         {
17301           ipv6_set = 1;
17302         }
17303       else
17304         break;
17305     }
17306
17307   if (ipv4_set && ipv6_set)
17308     {
17309       errmsg ("both eid v4 and v6 addresses set");
17310       return -99;
17311     }
17312
17313   if (!ipv4_set && !ipv6_set)
17314     {
17315       errmsg ("eid addresses not set");
17316       return -99;
17317     }
17318
17319   /* Construct the API message */
17320   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17321
17322   mp->is_add = is_add;
17323   if (ipv6_set)
17324     {
17325       mp->is_ipv6 = 1;
17326       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17327     }
17328   else
17329     {
17330       mp->is_ipv6 = 0;
17331       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17332     }
17333
17334   /* send it... */
17335   S (mp);
17336
17337   /* Wait for a reply... */
17338   W (ret);
17339   return ret;
17340 }
17341
17342 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17343
17344 static int
17345 api_lisp_gpe_enable_disable (vat_main_t * vam)
17346 {
17347   unformat_input_t *input = vam->input;
17348   vl_api_gpe_enable_disable_t *mp;
17349   u8 is_set = 0;
17350   u8 is_en = 1;
17351   int ret;
17352
17353   /* Parse args required to build the message */
17354   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17355     {
17356       if (unformat (input, "enable"))
17357         {
17358           is_set = 1;
17359           is_en = 1;
17360         }
17361       else if (unformat (input, "disable"))
17362         {
17363           is_set = 1;
17364           is_en = 0;
17365         }
17366       else
17367         break;
17368     }
17369
17370   if (is_set == 0)
17371     {
17372       errmsg ("Value not set");
17373       return -99;
17374     }
17375
17376   /* Construct the API message */
17377   M (GPE_ENABLE_DISABLE, mp);
17378
17379   mp->is_en = is_en;
17380
17381   /* send it... */
17382   S (mp);
17383
17384   /* Wait for a reply... */
17385   W (ret);
17386   return ret;
17387 }
17388
17389 static int
17390 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17391 {
17392   unformat_input_t *input = vam->input;
17393   vl_api_one_rloc_probe_enable_disable_t *mp;
17394   u8 is_set = 0;
17395   u8 is_en = 0;
17396   int ret;
17397
17398   /* Parse args required to build the message */
17399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17400     {
17401       if (unformat (input, "enable"))
17402         {
17403           is_set = 1;
17404           is_en = 1;
17405         }
17406       else if (unformat (input, "disable"))
17407         is_set = 1;
17408       else
17409         break;
17410     }
17411
17412   if (!is_set)
17413     {
17414       errmsg ("Value not set");
17415       return -99;
17416     }
17417
17418   /* Construct the API message */
17419   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17420
17421   mp->is_enabled = is_en;
17422
17423   /* send it... */
17424   S (mp);
17425
17426   /* Wait for a reply... */
17427   W (ret);
17428   return ret;
17429 }
17430
17431 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17432
17433 static int
17434 api_one_map_register_enable_disable (vat_main_t * vam)
17435 {
17436   unformat_input_t *input = vam->input;
17437   vl_api_one_map_register_enable_disable_t *mp;
17438   u8 is_set = 0;
17439   u8 is_en = 0;
17440   int ret;
17441
17442   /* Parse args required to build the message */
17443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17444     {
17445       if (unformat (input, "enable"))
17446         {
17447           is_set = 1;
17448           is_en = 1;
17449         }
17450       else if (unformat (input, "disable"))
17451         is_set = 1;
17452       else
17453         break;
17454     }
17455
17456   if (!is_set)
17457     {
17458       errmsg ("Value not set");
17459       return -99;
17460     }
17461
17462   /* Construct the API message */
17463   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17464
17465   mp->is_enabled = is_en;
17466
17467   /* send it... */
17468   S (mp);
17469
17470   /* Wait for a reply... */
17471   W (ret);
17472   return ret;
17473 }
17474
17475 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17476
17477 static int
17478 api_one_enable_disable (vat_main_t * vam)
17479 {
17480   unformat_input_t *input = vam->input;
17481   vl_api_one_enable_disable_t *mp;
17482   u8 is_set = 0;
17483   u8 is_en = 0;
17484   int ret;
17485
17486   /* Parse args required to build the message */
17487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17488     {
17489       if (unformat (input, "enable"))
17490         {
17491           is_set = 1;
17492           is_en = 1;
17493         }
17494       else if (unformat (input, "disable"))
17495         {
17496           is_set = 1;
17497         }
17498       else
17499         break;
17500     }
17501
17502   if (!is_set)
17503     {
17504       errmsg ("Value not set");
17505       return -99;
17506     }
17507
17508   /* Construct the API message */
17509   M (ONE_ENABLE_DISABLE, mp);
17510
17511   mp->is_en = is_en;
17512
17513   /* send it... */
17514   S (mp);
17515
17516   /* Wait for a reply... */
17517   W (ret);
17518   return ret;
17519 }
17520
17521 #define api_lisp_enable_disable api_one_enable_disable
17522
17523 static int
17524 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17525 {
17526   unformat_input_t *input = vam->input;
17527   vl_api_one_enable_disable_xtr_mode_t *mp;
17528   u8 is_set = 0;
17529   u8 is_en = 0;
17530   int ret;
17531
17532   /* Parse args required to build the message */
17533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17534     {
17535       if (unformat (input, "enable"))
17536         {
17537           is_set = 1;
17538           is_en = 1;
17539         }
17540       else if (unformat (input, "disable"))
17541         {
17542           is_set = 1;
17543         }
17544       else
17545         break;
17546     }
17547
17548   if (!is_set)
17549     {
17550       errmsg ("Value not set");
17551       return -99;
17552     }
17553
17554   /* Construct the API message */
17555   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17556
17557   mp->is_en = is_en;
17558
17559   /* send it... */
17560   S (mp);
17561
17562   /* Wait for a reply... */
17563   W (ret);
17564   return ret;
17565 }
17566
17567 static int
17568 api_one_show_xtr_mode (vat_main_t * vam)
17569 {
17570   vl_api_one_show_xtr_mode_t *mp;
17571   int ret;
17572
17573   /* Construct the API message */
17574   M (ONE_SHOW_XTR_MODE, mp);
17575
17576   /* send it... */
17577   S (mp);
17578
17579   /* Wait for a reply... */
17580   W (ret);
17581   return ret;
17582 }
17583
17584 static int
17585 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17586 {
17587   unformat_input_t *input = vam->input;
17588   vl_api_one_enable_disable_pitr_mode_t *mp;
17589   u8 is_set = 0;
17590   u8 is_en = 0;
17591   int ret;
17592
17593   /* Parse args required to build the message */
17594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17595     {
17596       if (unformat (input, "enable"))
17597         {
17598           is_set = 1;
17599           is_en = 1;
17600         }
17601       else if (unformat (input, "disable"))
17602         {
17603           is_set = 1;
17604         }
17605       else
17606         break;
17607     }
17608
17609   if (!is_set)
17610     {
17611       errmsg ("Value not set");
17612       return -99;
17613     }
17614
17615   /* Construct the API message */
17616   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17617
17618   mp->is_en = is_en;
17619
17620   /* send it... */
17621   S (mp);
17622
17623   /* Wait for a reply... */
17624   W (ret);
17625   return ret;
17626 }
17627
17628 static int
17629 api_one_show_pitr_mode (vat_main_t * vam)
17630 {
17631   vl_api_one_show_pitr_mode_t *mp;
17632   int ret;
17633
17634   /* Construct the API message */
17635   M (ONE_SHOW_PITR_MODE, mp);
17636
17637   /* send it... */
17638   S (mp);
17639
17640   /* Wait for a reply... */
17641   W (ret);
17642   return ret;
17643 }
17644
17645 static int
17646 api_one_enable_disable_petr_mode (vat_main_t * vam)
17647 {
17648   unformat_input_t *input = vam->input;
17649   vl_api_one_enable_disable_petr_mode_t *mp;
17650   u8 is_set = 0;
17651   u8 is_en = 0;
17652   int ret;
17653
17654   /* Parse args required to build the message */
17655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17656     {
17657       if (unformat (input, "enable"))
17658         {
17659           is_set = 1;
17660           is_en = 1;
17661         }
17662       else if (unformat (input, "disable"))
17663         {
17664           is_set = 1;
17665         }
17666       else
17667         break;
17668     }
17669
17670   if (!is_set)
17671     {
17672       errmsg ("Value not set");
17673       return -99;
17674     }
17675
17676   /* Construct the API message */
17677   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17678
17679   mp->is_en = is_en;
17680
17681   /* send it... */
17682   S (mp);
17683
17684   /* Wait for a reply... */
17685   W (ret);
17686   return ret;
17687 }
17688
17689 static int
17690 api_one_show_petr_mode (vat_main_t * vam)
17691 {
17692   vl_api_one_show_petr_mode_t *mp;
17693   int ret;
17694
17695   /* Construct the API message */
17696   M (ONE_SHOW_PETR_MODE, mp);
17697
17698   /* send it... */
17699   S (mp);
17700
17701   /* Wait for a reply... */
17702   W (ret);
17703   return ret;
17704 }
17705
17706 static int
17707 api_show_one_map_register_state (vat_main_t * vam)
17708 {
17709   vl_api_show_one_map_register_state_t *mp;
17710   int ret;
17711
17712   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17713
17714   /* send */
17715   S (mp);
17716
17717   /* wait for reply */
17718   W (ret);
17719   return ret;
17720 }
17721
17722 #define api_show_lisp_map_register_state api_show_one_map_register_state
17723
17724 static int
17725 api_show_one_rloc_probe_state (vat_main_t * vam)
17726 {
17727   vl_api_show_one_rloc_probe_state_t *mp;
17728   int ret;
17729
17730   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17731
17732   /* send */
17733   S (mp);
17734
17735   /* wait for reply */
17736   W (ret);
17737   return ret;
17738 }
17739
17740 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17741
17742 static int
17743 api_one_add_del_ndp_entry (vat_main_t * vam)
17744 {
17745   vl_api_one_add_del_ndp_entry_t *mp;
17746   unformat_input_t *input = vam->input;
17747   u8 is_add = 1;
17748   u8 mac_set = 0;
17749   u8 bd_set = 0;
17750   u8 ip_set = 0;
17751   u8 mac[6] = { 0, };
17752   u8 ip6[16] = { 0, };
17753   u32 bd = ~0;
17754   int ret;
17755
17756   /* Parse args required to build the message */
17757   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17758     {
17759       if (unformat (input, "del"))
17760         is_add = 0;
17761       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17762         mac_set = 1;
17763       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17764         ip_set = 1;
17765       else if (unformat (input, "bd %d", &bd))
17766         bd_set = 1;
17767       else
17768         {
17769           errmsg ("parse error '%U'", format_unformat_error, input);
17770           return -99;
17771         }
17772     }
17773
17774   if (!bd_set || !ip_set || (!mac_set && is_add))
17775     {
17776       errmsg ("Missing BD, IP or MAC!");
17777       return -99;
17778     }
17779
17780   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17781   mp->is_add = is_add;
17782   clib_memcpy (mp->mac, mac, 6);
17783   mp->bd = clib_host_to_net_u32 (bd);
17784   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17785
17786   /* send */
17787   S (mp);
17788
17789   /* wait for reply */
17790   W (ret);
17791   return ret;
17792 }
17793
17794 static int
17795 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17796 {
17797   vl_api_one_add_del_l2_arp_entry_t *mp;
17798   unformat_input_t *input = vam->input;
17799   u8 is_add = 1;
17800   u8 mac_set = 0;
17801   u8 bd_set = 0;
17802   u8 ip_set = 0;
17803   u8 mac[6] = { 0, };
17804   u32 ip4 = 0, bd = ~0;
17805   int ret;
17806
17807   /* Parse args required to build the message */
17808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17809     {
17810       if (unformat (input, "del"))
17811         is_add = 0;
17812       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17813         mac_set = 1;
17814       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17815         ip_set = 1;
17816       else if (unformat (input, "bd %d", &bd))
17817         bd_set = 1;
17818       else
17819         {
17820           errmsg ("parse error '%U'", format_unformat_error, input);
17821           return -99;
17822         }
17823     }
17824
17825   if (!bd_set || !ip_set || (!mac_set && is_add))
17826     {
17827       errmsg ("Missing BD, IP or MAC!");
17828       return -99;
17829     }
17830
17831   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17832   mp->is_add = is_add;
17833   clib_memcpy (mp->mac, mac, 6);
17834   mp->bd = clib_host_to_net_u32 (bd);
17835   mp->ip4 = ip4;
17836
17837   /* send */
17838   S (mp);
17839
17840   /* wait for reply */
17841   W (ret);
17842   return ret;
17843 }
17844
17845 static int
17846 api_one_ndp_bd_get (vat_main_t * vam)
17847 {
17848   vl_api_one_ndp_bd_get_t *mp;
17849   int ret;
17850
17851   M (ONE_NDP_BD_GET, mp);
17852
17853   /* send */
17854   S (mp);
17855
17856   /* wait for reply */
17857   W (ret);
17858   return ret;
17859 }
17860
17861 static int
17862 api_one_ndp_entries_get (vat_main_t * vam)
17863 {
17864   vl_api_one_ndp_entries_get_t *mp;
17865   unformat_input_t *input = vam->input;
17866   u8 bd_set = 0;
17867   u32 bd = ~0;
17868   int ret;
17869
17870   /* Parse args required to build the message */
17871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17872     {
17873       if (unformat (input, "bd %d", &bd))
17874         bd_set = 1;
17875       else
17876         {
17877           errmsg ("parse error '%U'", format_unformat_error, input);
17878           return -99;
17879         }
17880     }
17881
17882   if (!bd_set)
17883     {
17884       errmsg ("Expected bridge domain!");
17885       return -99;
17886     }
17887
17888   M (ONE_NDP_ENTRIES_GET, mp);
17889   mp->bd = clib_host_to_net_u32 (bd);
17890
17891   /* send */
17892   S (mp);
17893
17894   /* wait for reply */
17895   W (ret);
17896   return ret;
17897 }
17898
17899 static int
17900 api_one_l2_arp_bd_get (vat_main_t * vam)
17901 {
17902   vl_api_one_l2_arp_bd_get_t *mp;
17903   int ret;
17904
17905   M (ONE_L2_ARP_BD_GET, mp);
17906
17907   /* send */
17908   S (mp);
17909
17910   /* wait for reply */
17911   W (ret);
17912   return ret;
17913 }
17914
17915 static int
17916 api_one_l2_arp_entries_get (vat_main_t * vam)
17917 {
17918   vl_api_one_l2_arp_entries_get_t *mp;
17919   unformat_input_t *input = vam->input;
17920   u8 bd_set = 0;
17921   u32 bd = ~0;
17922   int ret;
17923
17924   /* Parse args required to build the message */
17925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17926     {
17927       if (unformat (input, "bd %d", &bd))
17928         bd_set = 1;
17929       else
17930         {
17931           errmsg ("parse error '%U'", format_unformat_error, input);
17932           return -99;
17933         }
17934     }
17935
17936   if (!bd_set)
17937     {
17938       errmsg ("Expected bridge domain!");
17939       return -99;
17940     }
17941
17942   M (ONE_L2_ARP_ENTRIES_GET, mp);
17943   mp->bd = clib_host_to_net_u32 (bd);
17944
17945   /* send */
17946   S (mp);
17947
17948   /* wait for reply */
17949   W (ret);
17950   return ret;
17951 }
17952
17953 static int
17954 api_one_stats_enable_disable (vat_main_t * vam)
17955 {
17956   vl_api_one_stats_enable_disable_t *mp;
17957   unformat_input_t *input = vam->input;
17958   u8 is_set = 0;
17959   u8 is_en = 0;
17960   int ret;
17961
17962   /* Parse args required to build the message */
17963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17964     {
17965       if (unformat (input, "enable"))
17966         {
17967           is_set = 1;
17968           is_en = 1;
17969         }
17970       else if (unformat (input, "disable"))
17971         {
17972           is_set = 1;
17973         }
17974       else
17975         break;
17976     }
17977
17978   if (!is_set)
17979     {
17980       errmsg ("Value not set");
17981       return -99;
17982     }
17983
17984   M (ONE_STATS_ENABLE_DISABLE, mp);
17985   mp->is_en = is_en;
17986
17987   /* send */
17988   S (mp);
17989
17990   /* wait for reply */
17991   W (ret);
17992   return ret;
17993 }
17994
17995 static int
17996 api_show_one_stats_enable_disable (vat_main_t * vam)
17997 {
17998   vl_api_show_one_stats_enable_disable_t *mp;
17999   int ret;
18000
18001   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18002
18003   /* send */
18004   S (mp);
18005
18006   /* wait for reply */
18007   W (ret);
18008   return ret;
18009 }
18010
18011 static int
18012 api_show_one_map_request_mode (vat_main_t * vam)
18013 {
18014   vl_api_show_one_map_request_mode_t *mp;
18015   int ret;
18016
18017   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18018
18019   /* send */
18020   S (mp);
18021
18022   /* wait for reply */
18023   W (ret);
18024   return ret;
18025 }
18026
18027 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18028
18029 static int
18030 api_one_map_request_mode (vat_main_t * vam)
18031 {
18032   unformat_input_t *input = vam->input;
18033   vl_api_one_map_request_mode_t *mp;
18034   u8 mode = 0;
18035   int ret;
18036
18037   /* Parse args required to build the message */
18038   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18039     {
18040       if (unformat (input, "dst-only"))
18041         mode = 0;
18042       else if (unformat (input, "src-dst"))
18043         mode = 1;
18044       else
18045         {
18046           errmsg ("parse error '%U'", format_unformat_error, input);
18047           return -99;
18048         }
18049     }
18050
18051   M (ONE_MAP_REQUEST_MODE, mp);
18052
18053   mp->mode = mode;
18054
18055   /* send */
18056   S (mp);
18057
18058   /* wait for reply */
18059   W (ret);
18060   return ret;
18061 }
18062
18063 #define api_lisp_map_request_mode api_one_map_request_mode
18064
18065 /**
18066  * Enable/disable ONE proxy ITR.
18067  *
18068  * @param vam vpp API test context
18069  * @return return code
18070  */
18071 static int
18072 api_one_pitr_set_locator_set (vat_main_t * vam)
18073 {
18074   u8 ls_name_set = 0;
18075   unformat_input_t *input = vam->input;
18076   vl_api_one_pitr_set_locator_set_t *mp;
18077   u8 is_add = 1;
18078   u8 *ls_name = 0;
18079   int ret;
18080
18081   /* Parse args required to build the message */
18082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18083     {
18084       if (unformat (input, "del"))
18085         is_add = 0;
18086       else if (unformat (input, "locator-set %s", &ls_name))
18087         ls_name_set = 1;
18088       else
18089         {
18090           errmsg ("parse error '%U'", format_unformat_error, input);
18091           return -99;
18092         }
18093     }
18094
18095   if (!ls_name_set)
18096     {
18097       errmsg ("locator-set name not set!");
18098       return -99;
18099     }
18100
18101   M (ONE_PITR_SET_LOCATOR_SET, mp);
18102
18103   mp->is_add = is_add;
18104   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18105   vec_free (ls_name);
18106
18107   /* send */
18108   S (mp);
18109
18110   /* wait for reply */
18111   W (ret);
18112   return ret;
18113 }
18114
18115 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18116
18117 static int
18118 api_one_nsh_set_locator_set (vat_main_t * vam)
18119 {
18120   u8 ls_name_set = 0;
18121   unformat_input_t *input = vam->input;
18122   vl_api_one_nsh_set_locator_set_t *mp;
18123   u8 is_add = 1;
18124   u8 *ls_name = 0;
18125   int ret;
18126
18127   /* Parse args required to build the message */
18128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18129     {
18130       if (unformat (input, "del"))
18131         is_add = 0;
18132       else if (unformat (input, "ls %s", &ls_name))
18133         ls_name_set = 1;
18134       else
18135         {
18136           errmsg ("parse error '%U'", format_unformat_error, input);
18137           return -99;
18138         }
18139     }
18140
18141   if (!ls_name_set && is_add)
18142     {
18143       errmsg ("locator-set name not set!");
18144       return -99;
18145     }
18146
18147   M (ONE_NSH_SET_LOCATOR_SET, mp);
18148
18149   mp->is_add = is_add;
18150   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18151   vec_free (ls_name);
18152
18153   /* send */
18154   S (mp);
18155
18156   /* wait for reply */
18157   W (ret);
18158   return ret;
18159 }
18160
18161 static int
18162 api_show_one_pitr (vat_main_t * vam)
18163 {
18164   vl_api_show_one_pitr_t *mp;
18165   int ret;
18166
18167   if (!vam->json_output)
18168     {
18169       print (vam->ofp, "%=20s", "lisp status:");
18170     }
18171
18172   M (SHOW_ONE_PITR, mp);
18173   /* send it... */
18174   S (mp);
18175
18176   /* Wait for a reply... */
18177   W (ret);
18178   return ret;
18179 }
18180
18181 #define api_show_lisp_pitr api_show_one_pitr
18182
18183 static int
18184 api_one_use_petr (vat_main_t * vam)
18185 {
18186   unformat_input_t *input = vam->input;
18187   vl_api_one_use_petr_t *mp;
18188   u8 is_add = 0;
18189   ip_address_t ip;
18190   int ret;
18191
18192   memset (&ip, 0, sizeof (ip));
18193
18194   /* Parse args required to build the message */
18195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18196     {
18197       if (unformat (input, "disable"))
18198         is_add = 0;
18199       else
18200         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18201         {
18202           is_add = 1;
18203           ip_addr_version (&ip) = IP4;
18204         }
18205       else
18206         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18207         {
18208           is_add = 1;
18209           ip_addr_version (&ip) = IP6;
18210         }
18211       else
18212         {
18213           errmsg ("parse error '%U'", format_unformat_error, input);
18214           return -99;
18215         }
18216     }
18217
18218   M (ONE_USE_PETR, mp);
18219
18220   mp->is_add = is_add;
18221   if (is_add)
18222     {
18223       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18224       if (mp->is_ip4)
18225         clib_memcpy (mp->address, &ip, 4);
18226       else
18227         clib_memcpy (mp->address, &ip, 16);
18228     }
18229
18230   /* send */
18231   S (mp);
18232
18233   /* wait for reply */
18234   W (ret);
18235   return ret;
18236 }
18237
18238 #define api_lisp_use_petr api_one_use_petr
18239
18240 static int
18241 api_show_one_nsh_mapping (vat_main_t * vam)
18242 {
18243   vl_api_show_one_use_petr_t *mp;
18244   int ret;
18245
18246   if (!vam->json_output)
18247     {
18248       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18249     }
18250
18251   M (SHOW_ONE_NSH_MAPPING, mp);
18252   /* send it... */
18253   S (mp);
18254
18255   /* Wait for a reply... */
18256   W (ret);
18257   return ret;
18258 }
18259
18260 static int
18261 api_show_one_use_petr (vat_main_t * vam)
18262 {
18263   vl_api_show_one_use_petr_t *mp;
18264   int ret;
18265
18266   if (!vam->json_output)
18267     {
18268       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18269     }
18270
18271   M (SHOW_ONE_USE_PETR, mp);
18272   /* send it... */
18273   S (mp);
18274
18275   /* Wait for a reply... */
18276   W (ret);
18277   return ret;
18278 }
18279
18280 #define api_show_lisp_use_petr api_show_one_use_petr
18281
18282 /**
18283  * Add/delete mapping between vni and vrf
18284  */
18285 static int
18286 api_one_eid_table_add_del_map (vat_main_t * vam)
18287 {
18288   unformat_input_t *input = vam->input;
18289   vl_api_one_eid_table_add_del_map_t *mp;
18290   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18291   u32 vni, vrf, bd_index;
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, "del"))
18298         is_add = 0;
18299       else if (unformat (input, "vrf %d", &vrf))
18300         vrf_set = 1;
18301       else if (unformat (input, "bd_index %d", &bd_index))
18302         bd_index_set = 1;
18303       else if (unformat (input, "vni %d", &vni))
18304         vni_set = 1;
18305       else
18306         break;
18307     }
18308
18309   if (!vni_set || (!vrf_set && !bd_index_set))
18310     {
18311       errmsg ("missing arguments!");
18312       return -99;
18313     }
18314
18315   if (vrf_set && bd_index_set)
18316     {
18317       errmsg ("error: both vrf and bd entered!");
18318       return -99;
18319     }
18320
18321   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18322
18323   mp->is_add = is_add;
18324   mp->vni = htonl (vni);
18325   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18326   mp->is_l2 = bd_index_set;
18327
18328   /* send */
18329   S (mp);
18330
18331   /* wait for reply */
18332   W (ret);
18333   return ret;
18334 }
18335
18336 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18337
18338 uword
18339 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18340 {
18341   u32 *action = va_arg (*args, u32 *);
18342   u8 *s = 0;
18343
18344   if (unformat (input, "%s", &s))
18345     {
18346       if (!strcmp ((char *) s, "no-action"))
18347         action[0] = 0;
18348       else if (!strcmp ((char *) s, "natively-forward"))
18349         action[0] = 1;
18350       else if (!strcmp ((char *) s, "send-map-request"))
18351         action[0] = 2;
18352       else if (!strcmp ((char *) s, "drop"))
18353         action[0] = 3;
18354       else
18355         {
18356           clib_warning ("invalid action: '%s'", s);
18357           action[0] = 3;
18358         }
18359     }
18360   else
18361     return 0;
18362
18363   vec_free (s);
18364   return 1;
18365 }
18366
18367 /**
18368  * Add/del remote mapping to/from ONE control plane
18369  *
18370  * @param vam vpp API test context
18371  * @return return code
18372  */
18373 static int
18374 api_one_add_del_remote_mapping (vat_main_t * vam)
18375 {
18376   unformat_input_t *input = vam->input;
18377   vl_api_one_add_del_remote_mapping_t *mp;
18378   u32 vni = 0;
18379   lisp_eid_vat_t _eid, *eid = &_eid;
18380   lisp_eid_vat_t _seid, *seid = &_seid;
18381   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18382   u32 action = ~0, p, w, data_len;
18383   ip4_address_t rloc4;
18384   ip6_address_t rloc6;
18385   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18386   int ret;
18387
18388   memset (&rloc, 0, sizeof (rloc));
18389
18390   /* Parse args required to build the message */
18391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18392     {
18393       if (unformat (input, "del-all"))
18394         {
18395           del_all = 1;
18396         }
18397       else if (unformat (input, "del"))
18398         {
18399           is_add = 0;
18400         }
18401       else if (unformat (input, "add"))
18402         {
18403           is_add = 1;
18404         }
18405       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18406         {
18407           eid_set = 1;
18408         }
18409       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18410         {
18411           seid_set = 1;
18412         }
18413       else if (unformat (input, "vni %d", &vni))
18414         {
18415           ;
18416         }
18417       else if (unformat (input, "p %d w %d", &p, &w))
18418         {
18419           if (!curr_rloc)
18420             {
18421               errmsg ("No RLOC configured for setting priority/weight!");
18422               return -99;
18423             }
18424           curr_rloc->priority = p;
18425           curr_rloc->weight = w;
18426         }
18427       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18428         {
18429           rloc.is_ip4 = 1;
18430           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18431           vec_add1 (rlocs, rloc);
18432           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18433         }
18434       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18435         {
18436           rloc.is_ip4 = 0;
18437           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18438           vec_add1 (rlocs, rloc);
18439           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18440         }
18441       else if (unformat (input, "action %U",
18442                          unformat_negative_mapping_action, &action))
18443         {
18444           ;
18445         }
18446       else
18447         {
18448           clib_warning ("parse error '%U'", format_unformat_error, input);
18449           return -99;
18450         }
18451     }
18452
18453   if (0 == eid_set)
18454     {
18455       errmsg ("missing params!");
18456       return -99;
18457     }
18458
18459   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18460     {
18461       errmsg ("no action set for negative map-reply!");
18462       return -99;
18463     }
18464
18465   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18466
18467   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18468   mp->is_add = is_add;
18469   mp->vni = htonl (vni);
18470   mp->action = (u8) action;
18471   mp->is_src_dst = seid_set;
18472   mp->eid_len = eid->len;
18473   mp->seid_len = seid->len;
18474   mp->del_all = del_all;
18475   mp->eid_type = eid->type;
18476   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18477   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18478
18479   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18480   clib_memcpy (mp->rlocs, rlocs, data_len);
18481   vec_free (rlocs);
18482
18483   /* send it... */
18484   S (mp);
18485
18486   /* Wait for a reply... */
18487   W (ret);
18488   return ret;
18489 }
18490
18491 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18492
18493 /**
18494  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18495  * forwarding entries in data-plane accordingly.
18496  *
18497  * @param vam vpp API test context
18498  * @return return code
18499  */
18500 static int
18501 api_one_add_del_adjacency (vat_main_t * vam)
18502 {
18503   unformat_input_t *input = vam->input;
18504   vl_api_one_add_del_adjacency_t *mp;
18505   u32 vni = 0;
18506   ip4_address_t leid4, reid4;
18507   ip6_address_t leid6, reid6;
18508   u8 reid_mac[6] = { 0 };
18509   u8 leid_mac[6] = { 0 };
18510   u8 reid_type, leid_type;
18511   u32 leid_len = 0, reid_len = 0, len;
18512   u8 is_add = 1;
18513   int ret;
18514
18515   leid_type = reid_type = (u8) ~ 0;
18516
18517   /* Parse args required to build the message */
18518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18519     {
18520       if (unformat (input, "del"))
18521         {
18522           is_add = 0;
18523         }
18524       else if (unformat (input, "add"))
18525         {
18526           is_add = 1;
18527         }
18528       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18529                          &reid4, &len))
18530         {
18531           reid_type = 0;        /* ipv4 */
18532           reid_len = len;
18533         }
18534       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18535                          &reid6, &len))
18536         {
18537           reid_type = 1;        /* ipv6 */
18538           reid_len = len;
18539         }
18540       else if (unformat (input, "reid %U", unformat_ethernet_address,
18541                          reid_mac))
18542         {
18543           reid_type = 2;        /* mac */
18544         }
18545       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18546                          &leid4, &len))
18547         {
18548           leid_type = 0;        /* ipv4 */
18549           leid_len = len;
18550         }
18551       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18552                          &leid6, &len))
18553         {
18554           leid_type = 1;        /* ipv6 */
18555           leid_len = len;
18556         }
18557       else if (unformat (input, "leid %U", unformat_ethernet_address,
18558                          leid_mac))
18559         {
18560           leid_type = 2;        /* mac */
18561         }
18562       else if (unformat (input, "vni %d", &vni))
18563         {
18564           ;
18565         }
18566       else
18567         {
18568           errmsg ("parse error '%U'", format_unformat_error, input);
18569           return -99;
18570         }
18571     }
18572
18573   if ((u8) ~ 0 == reid_type)
18574     {
18575       errmsg ("missing params!");
18576       return -99;
18577     }
18578
18579   if (leid_type != reid_type)
18580     {
18581       errmsg ("remote and local EIDs are of different types!");
18582       return -99;
18583     }
18584
18585   M (ONE_ADD_DEL_ADJACENCY, mp);
18586   mp->is_add = is_add;
18587   mp->vni = htonl (vni);
18588   mp->leid_len = leid_len;
18589   mp->reid_len = reid_len;
18590   mp->eid_type = reid_type;
18591
18592   switch (mp->eid_type)
18593     {
18594     case 0:
18595       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18596       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18597       break;
18598     case 1:
18599       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18600       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18601       break;
18602     case 2:
18603       clib_memcpy (mp->leid, leid_mac, 6);
18604       clib_memcpy (mp->reid, reid_mac, 6);
18605       break;
18606     default:
18607       errmsg ("unknown EID type %d!", mp->eid_type);
18608       return 0;
18609     }
18610
18611   /* send it... */
18612   S (mp);
18613
18614   /* Wait for a reply... */
18615   W (ret);
18616   return ret;
18617 }
18618
18619 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18620
18621 uword
18622 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18623 {
18624   u32 *mode = va_arg (*args, u32 *);
18625
18626   if (unformat (input, "lisp"))
18627     *mode = 0;
18628   else if (unformat (input, "vxlan"))
18629     *mode = 1;
18630   else
18631     return 0;
18632
18633   return 1;
18634 }
18635
18636 static int
18637 api_gpe_get_encap_mode (vat_main_t * vam)
18638 {
18639   vl_api_gpe_get_encap_mode_t *mp;
18640   int ret;
18641
18642   /* Construct the API message */
18643   M (GPE_GET_ENCAP_MODE, mp);
18644
18645   /* send it... */
18646   S (mp);
18647
18648   /* Wait for a reply... */
18649   W (ret);
18650   return ret;
18651 }
18652
18653 static int
18654 api_gpe_set_encap_mode (vat_main_t * vam)
18655 {
18656   unformat_input_t *input = vam->input;
18657   vl_api_gpe_set_encap_mode_t *mp;
18658   int ret;
18659   u32 mode = 0;
18660
18661   /* Parse args required to build the message */
18662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18663     {
18664       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18665         ;
18666       else
18667         break;
18668     }
18669
18670   /* Construct the API message */
18671   M (GPE_SET_ENCAP_MODE, mp);
18672
18673   mp->mode = mode;
18674
18675   /* send it... */
18676   S (mp);
18677
18678   /* Wait for a reply... */
18679   W (ret);
18680   return ret;
18681 }
18682
18683 static int
18684 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18685 {
18686   unformat_input_t *input = vam->input;
18687   vl_api_gpe_add_del_iface_t *mp;
18688   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18689   u32 dp_table = 0, vni = 0;
18690   int ret;
18691
18692   /* Parse args required to build the message */
18693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18694     {
18695       if (unformat (input, "up"))
18696         {
18697           action_set = 1;
18698           is_add = 1;
18699         }
18700       else if (unformat (input, "down"))
18701         {
18702           action_set = 1;
18703           is_add = 0;
18704         }
18705       else if (unformat (input, "table_id %d", &dp_table))
18706         {
18707           dp_table_set = 1;
18708         }
18709       else if (unformat (input, "bd_id %d", &dp_table))
18710         {
18711           dp_table_set = 1;
18712           is_l2 = 1;
18713         }
18714       else if (unformat (input, "vni %d", &vni))
18715         {
18716           vni_set = 1;
18717         }
18718       else
18719         break;
18720     }
18721
18722   if (action_set == 0)
18723     {
18724       errmsg ("Action not set");
18725       return -99;
18726     }
18727   if (dp_table_set == 0 || vni_set == 0)
18728     {
18729       errmsg ("vni and dp_table must be set");
18730       return -99;
18731     }
18732
18733   /* Construct the API message */
18734   M (GPE_ADD_DEL_IFACE, mp);
18735
18736   mp->is_add = is_add;
18737   mp->dp_table = clib_host_to_net_u32 (dp_table);
18738   mp->is_l2 = is_l2;
18739   mp->vni = clib_host_to_net_u32 (vni);
18740
18741   /* send it... */
18742   S (mp);
18743
18744   /* Wait for a reply... */
18745   W (ret);
18746   return ret;
18747 }
18748
18749 static int
18750 api_one_map_register_fallback_threshold (vat_main_t * vam)
18751 {
18752   unformat_input_t *input = vam->input;
18753   vl_api_one_map_register_fallback_threshold_t *mp;
18754   u32 value = 0;
18755   u8 is_set = 0;
18756   int ret;
18757
18758   /* Parse args required to build the message */
18759   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18760     {
18761       if (unformat (input, "%u", &value))
18762         is_set = 1;
18763       else
18764         {
18765           clib_warning ("parse error '%U'", format_unformat_error, input);
18766           return -99;
18767         }
18768     }
18769
18770   if (!is_set)
18771     {
18772       errmsg ("fallback threshold value is missing!");
18773       return -99;
18774     }
18775
18776   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18777   mp->value = clib_host_to_net_u32 (value);
18778
18779   /* send it... */
18780   S (mp);
18781
18782   /* Wait for a reply... */
18783   W (ret);
18784   return ret;
18785 }
18786
18787 static int
18788 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18789 {
18790   vl_api_show_one_map_register_fallback_threshold_t *mp;
18791   int ret;
18792
18793   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18794
18795   /* send it... */
18796   S (mp);
18797
18798   /* Wait for a reply... */
18799   W (ret);
18800   return ret;
18801 }
18802
18803 uword
18804 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18805 {
18806   u32 *proto = va_arg (*args, u32 *);
18807
18808   if (unformat (input, "udp"))
18809     *proto = 1;
18810   else if (unformat (input, "api"))
18811     *proto = 2;
18812   else
18813     return 0;
18814
18815   return 1;
18816 }
18817
18818 static int
18819 api_one_set_transport_protocol (vat_main_t * vam)
18820 {
18821   unformat_input_t *input = vam->input;
18822   vl_api_one_set_transport_protocol_t *mp;
18823   u8 is_set = 0;
18824   u32 protocol = 0;
18825   int ret;
18826
18827   /* Parse args required to build the message */
18828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18829     {
18830       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18831         is_set = 1;
18832       else
18833         {
18834           clib_warning ("parse error '%U'", format_unformat_error, input);
18835           return -99;
18836         }
18837     }
18838
18839   if (!is_set)
18840     {
18841       errmsg ("Transport protocol missing!");
18842       return -99;
18843     }
18844
18845   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18846   mp->protocol = (u8) protocol;
18847
18848   /* send it... */
18849   S (mp);
18850
18851   /* Wait for a reply... */
18852   W (ret);
18853   return ret;
18854 }
18855
18856 static int
18857 api_one_get_transport_protocol (vat_main_t * vam)
18858 {
18859   vl_api_one_get_transport_protocol_t *mp;
18860   int ret;
18861
18862   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18863
18864   /* send it... */
18865   S (mp);
18866
18867   /* Wait for a reply... */
18868   W (ret);
18869   return ret;
18870 }
18871
18872 static int
18873 api_one_map_register_set_ttl (vat_main_t * vam)
18874 {
18875   unformat_input_t *input = vam->input;
18876   vl_api_one_map_register_set_ttl_t *mp;
18877   u32 ttl = 0;
18878   u8 is_set = 0;
18879   int ret;
18880
18881   /* Parse args required to build the message */
18882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18883     {
18884       if (unformat (input, "%u", &ttl))
18885         is_set = 1;
18886       else
18887         {
18888           clib_warning ("parse error '%U'", format_unformat_error, input);
18889           return -99;
18890         }
18891     }
18892
18893   if (!is_set)
18894     {
18895       errmsg ("TTL value missing!");
18896       return -99;
18897     }
18898
18899   M (ONE_MAP_REGISTER_SET_TTL, mp);
18900   mp->ttl = clib_host_to_net_u32 (ttl);
18901
18902   /* send it... */
18903   S (mp);
18904
18905   /* Wait for a reply... */
18906   W (ret);
18907   return ret;
18908 }
18909
18910 static int
18911 api_show_one_map_register_ttl (vat_main_t * vam)
18912 {
18913   vl_api_show_one_map_register_ttl_t *mp;
18914   int ret;
18915
18916   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18917
18918   /* send it... */
18919   S (mp);
18920
18921   /* Wait for a reply... */
18922   W (ret);
18923   return ret;
18924 }
18925
18926 /**
18927  * Add/del map request itr rlocs from ONE control plane and updates
18928  *
18929  * @param vam vpp API test context
18930  * @return return code
18931  */
18932 static int
18933 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18934 {
18935   unformat_input_t *input = vam->input;
18936   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18937   u8 *locator_set_name = 0;
18938   u8 locator_set_name_set = 0;
18939   u8 is_add = 1;
18940   int ret;
18941
18942   /* Parse args required to build the message */
18943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18944     {
18945       if (unformat (input, "del"))
18946         {
18947           is_add = 0;
18948         }
18949       else if (unformat (input, "%_%v%_", &locator_set_name))
18950         {
18951           locator_set_name_set = 1;
18952         }
18953       else
18954         {
18955           clib_warning ("parse error '%U'", format_unformat_error, input);
18956           return -99;
18957         }
18958     }
18959
18960   if (is_add && !locator_set_name_set)
18961     {
18962       errmsg ("itr-rloc is not set!");
18963       return -99;
18964     }
18965
18966   if (is_add && vec_len (locator_set_name) > 64)
18967     {
18968       errmsg ("itr-rloc locator-set name too long");
18969       vec_free (locator_set_name);
18970       return -99;
18971     }
18972
18973   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18974   mp->is_add = is_add;
18975   if (is_add)
18976     {
18977       clib_memcpy (mp->locator_set_name, locator_set_name,
18978                    vec_len (locator_set_name));
18979     }
18980   else
18981     {
18982       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18983     }
18984   vec_free (locator_set_name);
18985
18986   /* send it... */
18987   S (mp);
18988
18989   /* Wait for a reply... */
18990   W (ret);
18991   return ret;
18992 }
18993
18994 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18995
18996 static int
18997 api_one_locator_dump (vat_main_t * vam)
18998 {
18999   unformat_input_t *input = vam->input;
19000   vl_api_one_locator_dump_t *mp;
19001   vl_api_control_ping_t *mp_ping;
19002   u8 is_index_set = 0, is_name_set = 0;
19003   u8 *ls_name = 0;
19004   u32 ls_index = ~0;
19005   int ret;
19006
19007   /* Parse args required to build the message */
19008   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19009     {
19010       if (unformat (input, "ls_name %_%v%_", &ls_name))
19011         {
19012           is_name_set = 1;
19013         }
19014       else if (unformat (input, "ls_index %d", &ls_index))
19015         {
19016           is_index_set = 1;
19017         }
19018       else
19019         {
19020           errmsg ("parse error '%U'", format_unformat_error, input);
19021           return -99;
19022         }
19023     }
19024
19025   if (!is_index_set && !is_name_set)
19026     {
19027       errmsg ("error: expected one of index or name!");
19028       return -99;
19029     }
19030
19031   if (is_index_set && is_name_set)
19032     {
19033       errmsg ("error: only one param expected!");
19034       return -99;
19035     }
19036
19037   if (vec_len (ls_name) > 62)
19038     {
19039       errmsg ("error: locator set name too long!");
19040       return -99;
19041     }
19042
19043   if (!vam->json_output)
19044     {
19045       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19046     }
19047
19048   M (ONE_LOCATOR_DUMP, mp);
19049   mp->is_index_set = is_index_set;
19050
19051   if (is_index_set)
19052     mp->ls_index = clib_host_to_net_u32 (ls_index);
19053   else
19054     {
19055       vec_add1 (ls_name, 0);
19056       strncpy ((char *) mp->ls_name, (char *) ls_name,
19057                sizeof (mp->ls_name) - 1);
19058     }
19059
19060   /* send it... */
19061   S (mp);
19062
19063   /* Use a control ping for synchronization */
19064   MPING (CONTROL_PING, mp_ping);
19065   S (mp_ping);
19066
19067   /* Wait for a reply... */
19068   W (ret);
19069   return ret;
19070 }
19071
19072 #define api_lisp_locator_dump api_one_locator_dump
19073
19074 static int
19075 api_one_locator_set_dump (vat_main_t * vam)
19076 {
19077   vl_api_one_locator_set_dump_t *mp;
19078   vl_api_control_ping_t *mp_ping;
19079   unformat_input_t *input = vam->input;
19080   u8 filter = 0;
19081   int ret;
19082
19083   /* Parse args required to build the message */
19084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19085     {
19086       if (unformat (input, "local"))
19087         {
19088           filter = 1;
19089         }
19090       else if (unformat (input, "remote"))
19091         {
19092           filter = 2;
19093         }
19094       else
19095         {
19096           errmsg ("parse error '%U'", format_unformat_error, input);
19097           return -99;
19098         }
19099     }
19100
19101   if (!vam->json_output)
19102     {
19103       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19104     }
19105
19106   M (ONE_LOCATOR_SET_DUMP, mp);
19107
19108   mp->filter = filter;
19109
19110   /* send it... */
19111   S (mp);
19112
19113   /* Use a control ping for synchronization */
19114   MPING (CONTROL_PING, mp_ping);
19115   S (mp_ping);
19116
19117   /* Wait for a reply... */
19118   W (ret);
19119   return ret;
19120 }
19121
19122 #define api_lisp_locator_set_dump api_one_locator_set_dump
19123
19124 static int
19125 api_one_eid_table_map_dump (vat_main_t * vam)
19126 {
19127   u8 is_l2 = 0;
19128   u8 mode_set = 0;
19129   unformat_input_t *input = vam->input;
19130   vl_api_one_eid_table_map_dump_t *mp;
19131   vl_api_control_ping_t *mp_ping;
19132   int ret;
19133
19134   /* Parse args required to build the message */
19135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19136     {
19137       if (unformat (input, "l2"))
19138         {
19139           is_l2 = 1;
19140           mode_set = 1;
19141         }
19142       else if (unformat (input, "l3"))
19143         {
19144           is_l2 = 0;
19145           mode_set = 1;
19146         }
19147       else
19148         {
19149           errmsg ("parse error '%U'", format_unformat_error, input);
19150           return -99;
19151         }
19152     }
19153
19154   if (!mode_set)
19155     {
19156       errmsg ("expected one of 'l2' or 'l3' parameter!");
19157       return -99;
19158     }
19159
19160   if (!vam->json_output)
19161     {
19162       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19163     }
19164
19165   M (ONE_EID_TABLE_MAP_DUMP, mp);
19166   mp->is_l2 = is_l2;
19167
19168   /* send it... */
19169   S (mp);
19170
19171   /* Use a control ping for synchronization */
19172   MPING (CONTROL_PING, mp_ping);
19173   S (mp_ping);
19174
19175   /* Wait for a reply... */
19176   W (ret);
19177   return ret;
19178 }
19179
19180 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19181
19182 static int
19183 api_one_eid_table_vni_dump (vat_main_t * vam)
19184 {
19185   vl_api_one_eid_table_vni_dump_t *mp;
19186   vl_api_control_ping_t *mp_ping;
19187   int ret;
19188
19189   if (!vam->json_output)
19190     {
19191       print (vam->ofp, "VNI");
19192     }
19193
19194   M (ONE_EID_TABLE_VNI_DUMP, mp);
19195
19196   /* send it... */
19197   S (mp);
19198
19199   /* Use a control ping for synchronization */
19200   MPING (CONTROL_PING, mp_ping);
19201   S (mp_ping);
19202
19203   /* Wait for a reply... */
19204   W (ret);
19205   return ret;
19206 }
19207
19208 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19209
19210 static int
19211 api_one_eid_table_dump (vat_main_t * vam)
19212 {
19213   unformat_input_t *i = vam->input;
19214   vl_api_one_eid_table_dump_t *mp;
19215   vl_api_control_ping_t *mp_ping;
19216   struct in_addr ip4;
19217   struct in6_addr ip6;
19218   u8 mac[6];
19219   u8 eid_type = ~0, eid_set = 0;
19220   u32 prefix_length = ~0, t, vni = 0;
19221   u8 filter = 0;
19222   int ret;
19223   lisp_nsh_api_t nsh;
19224
19225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19226     {
19227       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19228         {
19229           eid_set = 1;
19230           eid_type = 0;
19231           prefix_length = t;
19232         }
19233       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19234         {
19235           eid_set = 1;
19236           eid_type = 1;
19237           prefix_length = t;
19238         }
19239       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19240         {
19241           eid_set = 1;
19242           eid_type = 2;
19243         }
19244       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19245         {
19246           eid_set = 1;
19247           eid_type = 3;
19248         }
19249       else if (unformat (i, "vni %d", &t))
19250         {
19251           vni = t;
19252         }
19253       else if (unformat (i, "local"))
19254         {
19255           filter = 1;
19256         }
19257       else if (unformat (i, "remote"))
19258         {
19259           filter = 2;
19260         }
19261       else
19262         {
19263           errmsg ("parse error '%U'", format_unformat_error, i);
19264           return -99;
19265         }
19266     }
19267
19268   if (!vam->json_output)
19269     {
19270       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19271              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19272     }
19273
19274   M (ONE_EID_TABLE_DUMP, mp);
19275
19276   mp->filter = filter;
19277   if (eid_set)
19278     {
19279       mp->eid_set = 1;
19280       mp->vni = htonl (vni);
19281       mp->eid_type = eid_type;
19282       switch (eid_type)
19283         {
19284         case 0:
19285           mp->prefix_length = prefix_length;
19286           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19287           break;
19288         case 1:
19289           mp->prefix_length = prefix_length;
19290           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19291           break;
19292         case 2:
19293           clib_memcpy (mp->eid, mac, sizeof (mac));
19294           break;
19295         case 3:
19296           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19297           break;
19298         default:
19299           errmsg ("unknown EID type %d!", eid_type);
19300           return -99;
19301         }
19302     }
19303
19304   /* send it... */
19305   S (mp);
19306
19307   /* Use a control ping for synchronization */
19308   MPING (CONTROL_PING, mp_ping);
19309   S (mp_ping);
19310
19311   /* Wait for a reply... */
19312   W (ret);
19313   return ret;
19314 }
19315
19316 #define api_lisp_eid_table_dump api_one_eid_table_dump
19317
19318 static int
19319 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19320 {
19321   unformat_input_t *i = vam->input;
19322   vl_api_gpe_fwd_entries_get_t *mp;
19323   u8 vni_set = 0;
19324   u32 vni = ~0;
19325   int ret;
19326
19327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19328     {
19329       if (unformat (i, "vni %d", &vni))
19330         {
19331           vni_set = 1;
19332         }
19333       else
19334         {
19335           errmsg ("parse error '%U'", format_unformat_error, i);
19336           return -99;
19337         }
19338     }
19339
19340   if (!vni_set)
19341     {
19342       errmsg ("vni not set!");
19343       return -99;
19344     }
19345
19346   if (!vam->json_output)
19347     {
19348       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19349              "leid", "reid");
19350     }
19351
19352   M (GPE_FWD_ENTRIES_GET, mp);
19353   mp->vni = clib_host_to_net_u32 (vni);
19354
19355   /* send it... */
19356   S (mp);
19357
19358   /* Wait for a reply... */
19359   W (ret);
19360   return ret;
19361 }
19362
19363 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19364 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19365 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19366 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19367 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19368 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19369 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19370 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19371
19372 static int
19373 api_one_adjacencies_get (vat_main_t * vam)
19374 {
19375   unformat_input_t *i = vam->input;
19376   vl_api_one_adjacencies_get_t *mp;
19377   u8 vni_set = 0;
19378   u32 vni = ~0;
19379   int ret;
19380
19381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19382     {
19383       if (unformat (i, "vni %d", &vni))
19384         {
19385           vni_set = 1;
19386         }
19387       else
19388         {
19389           errmsg ("parse error '%U'", format_unformat_error, i);
19390           return -99;
19391         }
19392     }
19393
19394   if (!vni_set)
19395     {
19396       errmsg ("vni not set!");
19397       return -99;
19398     }
19399
19400   if (!vam->json_output)
19401     {
19402       print (vam->ofp, "%s %40s", "leid", "reid");
19403     }
19404
19405   M (ONE_ADJACENCIES_GET, mp);
19406   mp->vni = clib_host_to_net_u32 (vni);
19407
19408   /* send it... */
19409   S (mp);
19410
19411   /* Wait for a reply... */
19412   W (ret);
19413   return ret;
19414 }
19415
19416 #define api_lisp_adjacencies_get api_one_adjacencies_get
19417
19418 static int
19419 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19420 {
19421   unformat_input_t *i = vam->input;
19422   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19423   int ret;
19424   u8 ip_family_set = 0, is_ip4 = 1;
19425
19426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19427     {
19428       if (unformat (i, "ip4"))
19429         {
19430           ip_family_set = 1;
19431           is_ip4 = 1;
19432         }
19433       else if (unformat (i, "ip6"))
19434         {
19435           ip_family_set = 1;
19436           is_ip4 = 0;
19437         }
19438       else
19439         {
19440           errmsg ("parse error '%U'", format_unformat_error, i);
19441           return -99;
19442         }
19443     }
19444
19445   if (!ip_family_set)
19446     {
19447       errmsg ("ip family not set!");
19448       return -99;
19449     }
19450
19451   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19452   mp->is_ip4 = is_ip4;
19453
19454   /* send it... */
19455   S (mp);
19456
19457   /* Wait for a reply... */
19458   W (ret);
19459   return ret;
19460 }
19461
19462 static int
19463 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19464 {
19465   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19466   int ret;
19467
19468   if (!vam->json_output)
19469     {
19470       print (vam->ofp, "VNIs");
19471     }
19472
19473   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19474
19475   /* send it... */
19476   S (mp);
19477
19478   /* Wait for a reply... */
19479   W (ret);
19480   return ret;
19481 }
19482
19483 static int
19484 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19485 {
19486   unformat_input_t *i = vam->input;
19487   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19488   int ret = 0;
19489   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19490   struct in_addr ip4;
19491   struct in6_addr ip6;
19492   u32 table_id = 0, nh_sw_if_index = ~0;
19493
19494   memset (&ip4, 0, sizeof (ip4));
19495   memset (&ip6, 0, sizeof (ip6));
19496
19497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19498     {
19499       if (unformat (i, "del"))
19500         is_add = 0;
19501       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19502                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19503         {
19504           ip_set = 1;
19505           is_ip4 = 1;
19506         }
19507       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19508                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19509         {
19510           ip_set = 1;
19511           is_ip4 = 0;
19512         }
19513       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19514         {
19515           ip_set = 1;
19516           is_ip4 = 1;
19517           nh_sw_if_index = ~0;
19518         }
19519       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19520         {
19521           ip_set = 1;
19522           is_ip4 = 0;
19523           nh_sw_if_index = ~0;
19524         }
19525       else if (unformat (i, "table %d", &table_id))
19526         ;
19527       else
19528         {
19529           errmsg ("parse error '%U'", format_unformat_error, i);
19530           return -99;
19531         }
19532     }
19533
19534   if (!ip_set)
19535     {
19536       errmsg ("nh addr not set!");
19537       return -99;
19538     }
19539
19540   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19541   mp->is_add = is_add;
19542   mp->table_id = clib_host_to_net_u32 (table_id);
19543   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19544   mp->is_ip4 = is_ip4;
19545   if (is_ip4)
19546     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19547   else
19548     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19549
19550   /* send it... */
19551   S (mp);
19552
19553   /* Wait for a reply... */
19554   W (ret);
19555   return ret;
19556 }
19557
19558 static int
19559 api_one_map_server_dump (vat_main_t * vam)
19560 {
19561   vl_api_one_map_server_dump_t *mp;
19562   vl_api_control_ping_t *mp_ping;
19563   int ret;
19564
19565   if (!vam->json_output)
19566     {
19567       print (vam->ofp, "%=20s", "Map server");
19568     }
19569
19570   M (ONE_MAP_SERVER_DUMP, mp);
19571   /* send it... */
19572   S (mp);
19573
19574   /* Use a control ping for synchronization */
19575   MPING (CONTROL_PING, mp_ping);
19576   S (mp_ping);
19577
19578   /* Wait for a reply... */
19579   W (ret);
19580   return ret;
19581 }
19582
19583 #define api_lisp_map_server_dump api_one_map_server_dump
19584
19585 static int
19586 api_one_map_resolver_dump (vat_main_t * vam)
19587 {
19588   vl_api_one_map_resolver_dump_t *mp;
19589   vl_api_control_ping_t *mp_ping;
19590   int ret;
19591
19592   if (!vam->json_output)
19593     {
19594       print (vam->ofp, "%=20s", "Map resolver");
19595     }
19596
19597   M (ONE_MAP_RESOLVER_DUMP, mp);
19598   /* send it... */
19599   S (mp);
19600
19601   /* Use a control ping for synchronization */
19602   MPING (CONTROL_PING, mp_ping);
19603   S (mp_ping);
19604
19605   /* Wait for a reply... */
19606   W (ret);
19607   return ret;
19608 }
19609
19610 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19611
19612 static int
19613 api_one_stats_flush (vat_main_t * vam)
19614 {
19615   vl_api_one_stats_flush_t *mp;
19616   int ret = 0;
19617
19618   M (ONE_STATS_FLUSH, mp);
19619   S (mp);
19620   W (ret);
19621   return ret;
19622 }
19623
19624 static int
19625 api_one_stats_dump (vat_main_t * vam)
19626 {
19627   vl_api_one_stats_dump_t *mp;
19628   vl_api_control_ping_t *mp_ping;
19629   int ret;
19630
19631   M (ONE_STATS_DUMP, mp);
19632   /* send it... */
19633   S (mp);
19634
19635   /* Use a control ping for synchronization */
19636   MPING (CONTROL_PING, mp_ping);
19637   S (mp_ping);
19638
19639   /* Wait for a reply... */
19640   W (ret);
19641   return ret;
19642 }
19643
19644 static int
19645 api_show_one_status (vat_main_t * vam)
19646 {
19647   vl_api_show_one_status_t *mp;
19648   int ret;
19649
19650   if (!vam->json_output)
19651     {
19652       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19653     }
19654
19655   M (SHOW_ONE_STATUS, mp);
19656   /* send it... */
19657   S (mp);
19658   /* Wait for a reply... */
19659   W (ret);
19660   return ret;
19661 }
19662
19663 #define api_show_lisp_status api_show_one_status
19664
19665 static int
19666 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19667 {
19668   vl_api_gpe_fwd_entry_path_dump_t *mp;
19669   vl_api_control_ping_t *mp_ping;
19670   unformat_input_t *i = vam->input;
19671   u32 fwd_entry_index = ~0;
19672   int ret;
19673
19674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19675     {
19676       if (unformat (i, "index %d", &fwd_entry_index))
19677         ;
19678       else
19679         break;
19680     }
19681
19682   if (~0 == fwd_entry_index)
19683     {
19684       errmsg ("no index specified!");
19685       return -99;
19686     }
19687
19688   if (!vam->json_output)
19689     {
19690       print (vam->ofp, "first line");
19691     }
19692
19693   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19694
19695   /* send it... */
19696   S (mp);
19697   /* Use a control ping for synchronization */
19698   MPING (CONTROL_PING, mp_ping);
19699   S (mp_ping);
19700
19701   /* Wait for a reply... */
19702   W (ret);
19703   return ret;
19704 }
19705
19706 static int
19707 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19708 {
19709   vl_api_one_get_map_request_itr_rlocs_t *mp;
19710   int ret;
19711
19712   if (!vam->json_output)
19713     {
19714       print (vam->ofp, "%=20s", "itr-rlocs:");
19715     }
19716
19717   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19718   /* send it... */
19719   S (mp);
19720   /* Wait for a reply... */
19721   W (ret);
19722   return ret;
19723 }
19724
19725 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19726
19727 static int
19728 api_af_packet_create (vat_main_t * vam)
19729 {
19730   unformat_input_t *i = vam->input;
19731   vl_api_af_packet_create_t *mp;
19732   u8 *host_if_name = 0;
19733   u8 hw_addr[6];
19734   u8 random_hw_addr = 1;
19735   int ret;
19736
19737   memset (hw_addr, 0, sizeof (hw_addr));
19738
19739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19740     {
19741       if (unformat (i, "name %s", &host_if_name))
19742         vec_add1 (host_if_name, 0);
19743       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19744         random_hw_addr = 0;
19745       else
19746         break;
19747     }
19748
19749   if (!vec_len (host_if_name))
19750     {
19751       errmsg ("host-interface name must be specified");
19752       return -99;
19753     }
19754
19755   if (vec_len (host_if_name) > 64)
19756     {
19757       errmsg ("host-interface name too long");
19758       return -99;
19759     }
19760
19761   M (AF_PACKET_CREATE, mp);
19762
19763   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19764   clib_memcpy (mp->hw_addr, hw_addr, 6);
19765   mp->use_random_hw_addr = random_hw_addr;
19766   vec_free (host_if_name);
19767
19768   S (mp);
19769
19770   /* *INDENT-OFF* */
19771   W2 (ret,
19772       ({
19773         if (ret == 0)
19774           fprintf (vam->ofp ? vam->ofp : stderr,
19775                    " new sw_if_index = %d\n", vam->sw_if_index);
19776       }));
19777   /* *INDENT-ON* */
19778   return ret;
19779 }
19780
19781 static int
19782 api_af_packet_delete (vat_main_t * vam)
19783 {
19784   unformat_input_t *i = vam->input;
19785   vl_api_af_packet_delete_t *mp;
19786   u8 *host_if_name = 0;
19787   int ret;
19788
19789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19790     {
19791       if (unformat (i, "name %s", &host_if_name))
19792         vec_add1 (host_if_name, 0);
19793       else
19794         break;
19795     }
19796
19797   if (!vec_len (host_if_name))
19798     {
19799       errmsg ("host-interface name must be specified");
19800       return -99;
19801     }
19802
19803   if (vec_len (host_if_name) > 64)
19804     {
19805       errmsg ("host-interface name too long");
19806       return -99;
19807     }
19808
19809   M (AF_PACKET_DELETE, mp);
19810
19811   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19812   vec_free (host_if_name);
19813
19814   S (mp);
19815   W (ret);
19816   return ret;
19817 }
19818
19819 static void vl_api_af_packet_details_t_handler
19820   (vl_api_af_packet_details_t * mp)
19821 {
19822   vat_main_t *vam = &vat_main;
19823
19824   print (vam->ofp, "%-16s %d",
19825          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19826 }
19827
19828 static void vl_api_af_packet_details_t_handler_json
19829   (vl_api_af_packet_details_t * mp)
19830 {
19831   vat_main_t *vam = &vat_main;
19832   vat_json_node_t *node = NULL;
19833
19834   if (VAT_JSON_ARRAY != vam->json_tree.type)
19835     {
19836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19837       vat_json_init_array (&vam->json_tree);
19838     }
19839   node = vat_json_array_add (&vam->json_tree);
19840
19841   vat_json_init_object (node);
19842   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19843   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19844 }
19845
19846 static int
19847 api_af_packet_dump (vat_main_t * vam)
19848 {
19849   vl_api_af_packet_dump_t *mp;
19850   vl_api_control_ping_t *mp_ping;
19851   int ret;
19852
19853   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19854   /* Get list of tap interfaces */
19855   M (AF_PACKET_DUMP, mp);
19856   S (mp);
19857
19858   /* Use a control ping for synchronization */
19859   MPING (CONTROL_PING, mp_ping);
19860   S (mp_ping);
19861
19862   W (ret);
19863   return ret;
19864 }
19865
19866 static int
19867 api_policer_add_del (vat_main_t * vam)
19868 {
19869   unformat_input_t *i = vam->input;
19870   vl_api_policer_add_del_t *mp;
19871   u8 is_add = 1;
19872   u8 *name = 0;
19873   u32 cir = 0;
19874   u32 eir = 0;
19875   u64 cb = 0;
19876   u64 eb = 0;
19877   u8 rate_type = 0;
19878   u8 round_type = 0;
19879   u8 type = 0;
19880   u8 color_aware = 0;
19881   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19882   int ret;
19883
19884   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19885   conform_action.dscp = 0;
19886   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19887   exceed_action.dscp = 0;
19888   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19889   violate_action.dscp = 0;
19890
19891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19892     {
19893       if (unformat (i, "del"))
19894         is_add = 0;
19895       else if (unformat (i, "name %s", &name))
19896         vec_add1 (name, 0);
19897       else if (unformat (i, "cir %u", &cir))
19898         ;
19899       else if (unformat (i, "eir %u", &eir))
19900         ;
19901       else if (unformat (i, "cb %u", &cb))
19902         ;
19903       else if (unformat (i, "eb %u", &eb))
19904         ;
19905       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19906                          &rate_type))
19907         ;
19908       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19909                          &round_type))
19910         ;
19911       else if (unformat (i, "type %U", unformat_policer_type, &type))
19912         ;
19913       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19914                          &conform_action))
19915         ;
19916       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19917                          &exceed_action))
19918         ;
19919       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19920                          &violate_action))
19921         ;
19922       else if (unformat (i, "color-aware"))
19923         color_aware = 1;
19924       else
19925         break;
19926     }
19927
19928   if (!vec_len (name))
19929     {
19930       errmsg ("policer name must be specified");
19931       return -99;
19932     }
19933
19934   if (vec_len (name) > 64)
19935     {
19936       errmsg ("policer name too long");
19937       return -99;
19938     }
19939
19940   M (POLICER_ADD_DEL, mp);
19941
19942   clib_memcpy (mp->name, name, vec_len (name));
19943   vec_free (name);
19944   mp->is_add = is_add;
19945   mp->cir = ntohl (cir);
19946   mp->eir = ntohl (eir);
19947   mp->cb = clib_net_to_host_u64 (cb);
19948   mp->eb = clib_net_to_host_u64 (eb);
19949   mp->rate_type = rate_type;
19950   mp->round_type = round_type;
19951   mp->type = type;
19952   mp->conform_action_type = conform_action.action_type;
19953   mp->conform_dscp = conform_action.dscp;
19954   mp->exceed_action_type = exceed_action.action_type;
19955   mp->exceed_dscp = exceed_action.dscp;
19956   mp->violate_action_type = violate_action.action_type;
19957   mp->violate_dscp = violate_action.dscp;
19958   mp->color_aware = color_aware;
19959
19960   S (mp);
19961   W (ret);
19962   return ret;
19963 }
19964
19965 static int
19966 api_policer_dump (vat_main_t * vam)
19967 {
19968   unformat_input_t *i = vam->input;
19969   vl_api_policer_dump_t *mp;
19970   vl_api_control_ping_t *mp_ping;
19971   u8 *match_name = 0;
19972   u8 match_name_valid = 0;
19973   int ret;
19974
19975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19976     {
19977       if (unformat (i, "name %s", &match_name))
19978         {
19979           vec_add1 (match_name, 0);
19980           match_name_valid = 1;
19981         }
19982       else
19983         break;
19984     }
19985
19986   M (POLICER_DUMP, mp);
19987   mp->match_name_valid = match_name_valid;
19988   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19989   vec_free (match_name);
19990   /* send it... */
19991   S (mp);
19992
19993   /* Use a control ping for synchronization */
19994   MPING (CONTROL_PING, mp_ping);
19995   S (mp_ping);
19996
19997   /* Wait for a reply... */
19998   W (ret);
19999   return ret;
20000 }
20001
20002 static int
20003 api_policer_classify_set_interface (vat_main_t * vam)
20004 {
20005   unformat_input_t *i = vam->input;
20006   vl_api_policer_classify_set_interface_t *mp;
20007   u32 sw_if_index;
20008   int sw_if_index_set;
20009   u32 ip4_table_index = ~0;
20010   u32 ip6_table_index = ~0;
20011   u32 l2_table_index = ~0;
20012   u8 is_add = 1;
20013   int ret;
20014
20015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20016     {
20017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20018         sw_if_index_set = 1;
20019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20020         sw_if_index_set = 1;
20021       else if (unformat (i, "del"))
20022         is_add = 0;
20023       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20024         ;
20025       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20026         ;
20027       else if (unformat (i, "l2-table %d", &l2_table_index))
20028         ;
20029       else
20030         {
20031           clib_warning ("parse error '%U'", format_unformat_error, i);
20032           return -99;
20033         }
20034     }
20035
20036   if (sw_if_index_set == 0)
20037     {
20038       errmsg ("missing interface name or sw_if_index");
20039       return -99;
20040     }
20041
20042   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20043
20044   mp->sw_if_index = ntohl (sw_if_index);
20045   mp->ip4_table_index = ntohl (ip4_table_index);
20046   mp->ip6_table_index = ntohl (ip6_table_index);
20047   mp->l2_table_index = ntohl (l2_table_index);
20048   mp->is_add = is_add;
20049
20050   S (mp);
20051   W (ret);
20052   return ret;
20053 }
20054
20055 static int
20056 api_policer_classify_dump (vat_main_t * vam)
20057 {
20058   unformat_input_t *i = vam->input;
20059   vl_api_policer_classify_dump_t *mp;
20060   vl_api_control_ping_t *mp_ping;
20061   u8 type = POLICER_CLASSIFY_N_TABLES;
20062   int ret;
20063
20064   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20065     ;
20066   else
20067     {
20068       errmsg ("classify table type must be specified");
20069       return -99;
20070     }
20071
20072   if (!vam->json_output)
20073     {
20074       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20075     }
20076
20077   M (POLICER_CLASSIFY_DUMP, mp);
20078   mp->type = type;
20079   /* send it... */
20080   S (mp);
20081
20082   /* Use a control ping for synchronization */
20083   MPING (CONTROL_PING, mp_ping);
20084   S (mp_ping);
20085
20086   /* Wait for a reply... */
20087   W (ret);
20088   return ret;
20089 }
20090
20091 static int
20092 api_netmap_create (vat_main_t * vam)
20093 {
20094   unformat_input_t *i = vam->input;
20095   vl_api_netmap_create_t *mp;
20096   u8 *if_name = 0;
20097   u8 hw_addr[6];
20098   u8 random_hw_addr = 1;
20099   u8 is_pipe = 0;
20100   u8 is_master = 0;
20101   int ret;
20102
20103   memset (hw_addr, 0, sizeof (hw_addr));
20104
20105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20106     {
20107       if (unformat (i, "name %s", &if_name))
20108         vec_add1 (if_name, 0);
20109       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20110         random_hw_addr = 0;
20111       else if (unformat (i, "pipe"))
20112         is_pipe = 1;
20113       else if (unformat (i, "master"))
20114         is_master = 1;
20115       else if (unformat (i, "slave"))
20116         is_master = 0;
20117       else
20118         break;
20119     }
20120
20121   if (!vec_len (if_name))
20122     {
20123       errmsg ("interface name must be specified");
20124       return -99;
20125     }
20126
20127   if (vec_len (if_name) > 64)
20128     {
20129       errmsg ("interface name too long");
20130       return -99;
20131     }
20132
20133   M (NETMAP_CREATE, mp);
20134
20135   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20136   clib_memcpy (mp->hw_addr, hw_addr, 6);
20137   mp->use_random_hw_addr = random_hw_addr;
20138   mp->is_pipe = is_pipe;
20139   mp->is_master = is_master;
20140   vec_free (if_name);
20141
20142   S (mp);
20143   W (ret);
20144   return ret;
20145 }
20146
20147 static int
20148 api_netmap_delete (vat_main_t * vam)
20149 {
20150   unformat_input_t *i = vam->input;
20151   vl_api_netmap_delete_t *mp;
20152   u8 *if_name = 0;
20153   int ret;
20154
20155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20156     {
20157       if (unformat (i, "name %s", &if_name))
20158         vec_add1 (if_name, 0);
20159       else
20160         break;
20161     }
20162
20163   if (!vec_len (if_name))
20164     {
20165       errmsg ("interface name must be specified");
20166       return -99;
20167     }
20168
20169   if (vec_len (if_name) > 64)
20170     {
20171       errmsg ("interface name too long");
20172       return -99;
20173     }
20174
20175   M (NETMAP_DELETE, mp);
20176
20177   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20178   vec_free (if_name);
20179
20180   S (mp);
20181   W (ret);
20182   return ret;
20183 }
20184
20185 static void
20186 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20187 {
20188   if (fp->afi == IP46_TYPE_IP6)
20189     print (vam->ofp,
20190            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20191            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20192            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20193            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20194            format_ip6_address, fp->next_hop);
20195   else if (fp->afi == IP46_TYPE_IP4)
20196     print (vam->ofp,
20197            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20198            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20199            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20200            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20201            format_ip4_address, fp->next_hop);
20202 }
20203
20204 static void
20205 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20206                                  vl_api_fib_path_t * fp)
20207 {
20208   struct in_addr ip4;
20209   struct in6_addr ip6;
20210
20211   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20212   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20213   vat_json_object_add_uint (node, "is_local", fp->is_local);
20214   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20215   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20216   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20217   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20218   if (fp->afi == IP46_TYPE_IP4)
20219     {
20220       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20221       vat_json_object_add_ip4 (node, "next_hop", ip4);
20222     }
20223   else if (fp->afi == IP46_TYPE_IP6)
20224     {
20225       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20226       vat_json_object_add_ip6 (node, "next_hop", ip6);
20227     }
20228 }
20229
20230 static void
20231 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20232 {
20233   vat_main_t *vam = &vat_main;
20234   int count = ntohl (mp->mt_count);
20235   vl_api_fib_path_t *fp;
20236   i32 i;
20237
20238   print (vam->ofp, "[%d]: sw_if_index %d via:",
20239          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20240   fp = mp->mt_paths;
20241   for (i = 0; i < count; i++)
20242     {
20243       vl_api_mpls_fib_path_print (vam, fp);
20244       fp++;
20245     }
20246
20247   print (vam->ofp, "");
20248 }
20249
20250 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20251 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20252
20253 static void
20254 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20255 {
20256   vat_main_t *vam = &vat_main;
20257   vat_json_node_t *node = NULL;
20258   int count = ntohl (mp->mt_count);
20259   vl_api_fib_path_t *fp;
20260   i32 i;
20261
20262   if (VAT_JSON_ARRAY != vam->json_tree.type)
20263     {
20264       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20265       vat_json_init_array (&vam->json_tree);
20266     }
20267   node = vat_json_array_add (&vam->json_tree);
20268
20269   vat_json_init_object (node);
20270   vat_json_object_add_uint (node, "tunnel_index",
20271                             ntohl (mp->mt_tunnel_index));
20272   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20273
20274   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20275
20276   fp = mp->mt_paths;
20277   for (i = 0; i < count; i++)
20278     {
20279       vl_api_mpls_fib_path_json_print (node, fp);
20280       fp++;
20281     }
20282 }
20283
20284 static int
20285 api_mpls_tunnel_dump (vat_main_t * vam)
20286 {
20287   vl_api_mpls_tunnel_dump_t *mp;
20288   vl_api_control_ping_t *mp_ping;
20289   i32 index = -1;
20290   int ret;
20291
20292   /* Parse args required to build the message */
20293   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20294     {
20295       if (!unformat (vam->input, "tunnel_index %d", &index))
20296         {
20297           index = -1;
20298           break;
20299         }
20300     }
20301
20302   print (vam->ofp, "  tunnel_index %d", index);
20303
20304   M (MPLS_TUNNEL_DUMP, mp);
20305   mp->tunnel_index = htonl (index);
20306   S (mp);
20307
20308   /* Use a control ping for synchronization */
20309   MPING (CONTROL_PING, mp_ping);
20310   S (mp_ping);
20311
20312   W (ret);
20313   return ret;
20314 }
20315
20316 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20317 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20318
20319
20320 static void
20321 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20322 {
20323   vat_main_t *vam = &vat_main;
20324   int count = ntohl (mp->count);
20325   vl_api_fib_path_t *fp;
20326   int i;
20327
20328   print (vam->ofp,
20329          "table-id %d, label %u, ess_bit %u",
20330          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20331   fp = mp->path;
20332   for (i = 0; i < count; i++)
20333     {
20334       vl_api_mpls_fib_path_print (vam, fp);
20335       fp++;
20336     }
20337 }
20338
20339 static void vl_api_mpls_fib_details_t_handler_json
20340   (vl_api_mpls_fib_details_t * mp)
20341 {
20342   vat_main_t *vam = &vat_main;
20343   int count = ntohl (mp->count);
20344   vat_json_node_t *node = NULL;
20345   vl_api_fib_path_t *fp;
20346   int i;
20347
20348   if (VAT_JSON_ARRAY != vam->json_tree.type)
20349     {
20350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20351       vat_json_init_array (&vam->json_tree);
20352     }
20353   node = vat_json_array_add (&vam->json_tree);
20354
20355   vat_json_init_object (node);
20356   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20357   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20358   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20359   vat_json_object_add_uint (node, "path_count", count);
20360   fp = mp->path;
20361   for (i = 0; i < count; i++)
20362     {
20363       vl_api_mpls_fib_path_json_print (node, fp);
20364       fp++;
20365     }
20366 }
20367
20368 static int
20369 api_mpls_fib_dump (vat_main_t * vam)
20370 {
20371   vl_api_mpls_fib_dump_t *mp;
20372   vl_api_control_ping_t *mp_ping;
20373   int ret;
20374
20375   M (MPLS_FIB_DUMP, mp);
20376   S (mp);
20377
20378   /* Use a control ping for synchronization */
20379   MPING (CONTROL_PING, mp_ping);
20380   S (mp_ping);
20381
20382   W (ret);
20383   return ret;
20384 }
20385
20386 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20387 #define vl_api_ip_fib_details_t_print vl_noop_handler
20388
20389 static void
20390 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20391 {
20392   vat_main_t *vam = &vat_main;
20393   int count = ntohl (mp->count);
20394   vl_api_fib_path_t *fp;
20395   int i;
20396
20397   print (vam->ofp,
20398          "table-id %d, prefix %U/%d",
20399          ntohl (mp->table_id), format_ip4_address, mp->address,
20400          mp->address_length);
20401   fp = mp->path;
20402   for (i = 0; i < count; i++)
20403     {
20404       if (fp->afi == IP46_TYPE_IP6)
20405         print (vam->ofp,
20406                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20407                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20408                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20409                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20410                format_ip6_address, fp->next_hop);
20411       else if (fp->afi == IP46_TYPE_IP4)
20412         print (vam->ofp,
20413                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20414                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20415                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20416                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20417                format_ip4_address, fp->next_hop);
20418       fp++;
20419     }
20420 }
20421
20422 static void vl_api_ip_fib_details_t_handler_json
20423   (vl_api_ip_fib_details_t * mp)
20424 {
20425   vat_main_t *vam = &vat_main;
20426   int count = ntohl (mp->count);
20427   vat_json_node_t *node = NULL;
20428   struct in_addr ip4;
20429   struct in6_addr ip6;
20430   vl_api_fib_path_t *fp;
20431   int i;
20432
20433   if (VAT_JSON_ARRAY != vam->json_tree.type)
20434     {
20435       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20436       vat_json_init_array (&vam->json_tree);
20437     }
20438   node = vat_json_array_add (&vam->json_tree);
20439
20440   vat_json_init_object (node);
20441   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20442   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20443   vat_json_object_add_ip4 (node, "prefix", ip4);
20444   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20445   vat_json_object_add_uint (node, "path_count", count);
20446   fp = mp->path;
20447   for (i = 0; i < count; i++)
20448     {
20449       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20450       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20451       vat_json_object_add_uint (node, "is_local", fp->is_local);
20452       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20453       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20454       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20455       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20456       if (fp->afi == IP46_TYPE_IP4)
20457         {
20458           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20459           vat_json_object_add_ip4 (node, "next_hop", ip4);
20460         }
20461       else if (fp->afi == IP46_TYPE_IP6)
20462         {
20463           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20464           vat_json_object_add_ip6 (node, "next_hop", ip6);
20465         }
20466     }
20467 }
20468
20469 static int
20470 api_ip_fib_dump (vat_main_t * vam)
20471 {
20472   vl_api_ip_fib_dump_t *mp;
20473   vl_api_control_ping_t *mp_ping;
20474   int ret;
20475
20476   M (IP_FIB_DUMP, mp);
20477   S (mp);
20478
20479   /* Use a control ping for synchronization */
20480   MPING (CONTROL_PING, mp_ping);
20481   S (mp_ping);
20482
20483   W (ret);
20484   return ret;
20485 }
20486
20487 static int
20488 api_ip_mfib_dump (vat_main_t * vam)
20489 {
20490   vl_api_ip_mfib_dump_t *mp;
20491   vl_api_control_ping_t *mp_ping;
20492   int ret;
20493
20494   M (IP_MFIB_DUMP, mp);
20495   S (mp);
20496
20497   /* Use a control ping for synchronization */
20498   MPING (CONTROL_PING, mp_ping);
20499   S (mp_ping);
20500
20501   W (ret);
20502   return ret;
20503 }
20504
20505 static void vl_api_ip_neighbor_details_t_handler
20506   (vl_api_ip_neighbor_details_t * mp)
20507 {
20508   vat_main_t *vam = &vat_main;
20509
20510   print (vam->ofp, "%c %U %U",
20511          (mp->is_static) ? 'S' : 'D',
20512          format_ethernet_address, &mp->mac_address,
20513          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20514          &mp->ip_address);
20515 }
20516
20517 static void vl_api_ip_neighbor_details_t_handler_json
20518   (vl_api_ip_neighbor_details_t * mp)
20519 {
20520
20521   vat_main_t *vam = &vat_main;
20522   vat_json_node_t *node;
20523   struct in_addr ip4;
20524   struct in6_addr ip6;
20525
20526   if (VAT_JSON_ARRAY != vam->json_tree.type)
20527     {
20528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20529       vat_json_init_array (&vam->json_tree);
20530     }
20531   node = vat_json_array_add (&vam->json_tree);
20532
20533   vat_json_init_object (node);
20534   vat_json_object_add_string_copy (node, "flag",
20535                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20536                                    "dynamic");
20537
20538   vat_json_object_add_string_copy (node, "link_layer",
20539                                    format (0, "%U", format_ethernet_address,
20540                                            &mp->mac_address));
20541
20542   if (mp->is_ipv6)
20543     {
20544       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20545       vat_json_object_add_ip6 (node, "ip_address", ip6);
20546     }
20547   else
20548     {
20549       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20550       vat_json_object_add_ip4 (node, "ip_address", ip4);
20551     }
20552 }
20553
20554 static int
20555 api_ip_neighbor_dump (vat_main_t * vam)
20556 {
20557   unformat_input_t *i = vam->input;
20558   vl_api_ip_neighbor_dump_t *mp;
20559   vl_api_control_ping_t *mp_ping;
20560   u8 is_ipv6 = 0;
20561   u32 sw_if_index = ~0;
20562   int ret;
20563
20564   /* Parse args required to build the message */
20565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20566     {
20567       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20568         ;
20569       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20570         ;
20571       else if (unformat (i, "ip6"))
20572         is_ipv6 = 1;
20573       else
20574         break;
20575     }
20576
20577   if (sw_if_index == ~0)
20578     {
20579       errmsg ("missing interface name or sw_if_index");
20580       return -99;
20581     }
20582
20583   M (IP_NEIGHBOR_DUMP, mp);
20584   mp->is_ipv6 = (u8) is_ipv6;
20585   mp->sw_if_index = ntohl (sw_if_index);
20586   S (mp);
20587
20588   /* Use a control ping for synchronization */
20589   MPING (CONTROL_PING, mp_ping);
20590   S (mp_ping);
20591
20592   W (ret);
20593   return ret;
20594 }
20595
20596 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20597 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20598
20599 static void
20600 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20601 {
20602   vat_main_t *vam = &vat_main;
20603   int count = ntohl (mp->count);
20604   vl_api_fib_path_t *fp;
20605   int i;
20606
20607   print (vam->ofp,
20608          "table-id %d, prefix %U/%d",
20609          ntohl (mp->table_id), format_ip6_address, mp->address,
20610          mp->address_length);
20611   fp = mp->path;
20612   for (i = 0; i < count; i++)
20613     {
20614       if (fp->afi == IP46_TYPE_IP6)
20615         print (vam->ofp,
20616                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20617                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20618                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20619                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20620                format_ip6_address, fp->next_hop);
20621       else if (fp->afi == IP46_TYPE_IP4)
20622         print (vam->ofp,
20623                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20624                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20625                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20626                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20627                format_ip4_address, fp->next_hop);
20628       fp++;
20629     }
20630 }
20631
20632 static void vl_api_ip6_fib_details_t_handler_json
20633   (vl_api_ip6_fib_details_t * mp)
20634 {
20635   vat_main_t *vam = &vat_main;
20636   int count = ntohl (mp->count);
20637   vat_json_node_t *node = NULL;
20638   struct in_addr ip4;
20639   struct in6_addr ip6;
20640   vl_api_fib_path_t *fp;
20641   int i;
20642
20643   if (VAT_JSON_ARRAY != vam->json_tree.type)
20644     {
20645       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20646       vat_json_init_array (&vam->json_tree);
20647     }
20648   node = vat_json_array_add (&vam->json_tree);
20649
20650   vat_json_init_object (node);
20651   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20652   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20653   vat_json_object_add_ip6 (node, "prefix", ip6);
20654   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20655   vat_json_object_add_uint (node, "path_count", count);
20656   fp = mp->path;
20657   for (i = 0; i < count; i++)
20658     {
20659       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20660       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20661       vat_json_object_add_uint (node, "is_local", fp->is_local);
20662       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20663       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20664       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20665       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20666       if (fp->afi == IP46_TYPE_IP4)
20667         {
20668           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20669           vat_json_object_add_ip4 (node, "next_hop", ip4);
20670         }
20671       else if (fp->afi == IP46_TYPE_IP6)
20672         {
20673           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20674           vat_json_object_add_ip6 (node, "next_hop", ip6);
20675         }
20676     }
20677 }
20678
20679 static int
20680 api_ip6_fib_dump (vat_main_t * vam)
20681 {
20682   vl_api_ip6_fib_dump_t *mp;
20683   vl_api_control_ping_t *mp_ping;
20684   int ret;
20685
20686   M (IP6_FIB_DUMP, mp);
20687   S (mp);
20688
20689   /* Use a control ping for synchronization */
20690   MPING (CONTROL_PING, mp_ping);
20691   S (mp_ping);
20692
20693   W (ret);
20694   return ret;
20695 }
20696
20697 static int
20698 api_ip6_mfib_dump (vat_main_t * vam)
20699 {
20700   vl_api_ip6_mfib_dump_t *mp;
20701   vl_api_control_ping_t *mp_ping;
20702   int ret;
20703
20704   M (IP6_MFIB_DUMP, mp);
20705   S (mp);
20706
20707   /* Use a control ping for synchronization */
20708   MPING (CONTROL_PING, mp_ping);
20709   S (mp_ping);
20710
20711   W (ret);
20712   return ret;
20713 }
20714
20715 int
20716 api_classify_table_ids (vat_main_t * vam)
20717 {
20718   vl_api_classify_table_ids_t *mp;
20719   int ret;
20720
20721   /* Construct the API message */
20722   M (CLASSIFY_TABLE_IDS, mp);
20723   mp->context = 0;
20724
20725   S (mp);
20726   W (ret);
20727   return ret;
20728 }
20729
20730 int
20731 api_classify_table_by_interface (vat_main_t * vam)
20732 {
20733   unformat_input_t *input = vam->input;
20734   vl_api_classify_table_by_interface_t *mp;
20735
20736   u32 sw_if_index = ~0;
20737   int ret;
20738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20739     {
20740       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20741         ;
20742       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20743         ;
20744       else
20745         break;
20746     }
20747   if (sw_if_index == ~0)
20748     {
20749       errmsg ("missing interface name or sw_if_index");
20750       return -99;
20751     }
20752
20753   /* Construct the API message */
20754   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20755   mp->context = 0;
20756   mp->sw_if_index = ntohl (sw_if_index);
20757
20758   S (mp);
20759   W (ret);
20760   return ret;
20761 }
20762
20763 int
20764 api_classify_table_info (vat_main_t * vam)
20765 {
20766   unformat_input_t *input = vam->input;
20767   vl_api_classify_table_info_t *mp;
20768
20769   u32 table_id = ~0;
20770   int ret;
20771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20772     {
20773       if (unformat (input, "table_id %d", &table_id))
20774         ;
20775       else
20776         break;
20777     }
20778   if (table_id == ~0)
20779     {
20780       errmsg ("missing table id");
20781       return -99;
20782     }
20783
20784   /* Construct the API message */
20785   M (CLASSIFY_TABLE_INFO, mp);
20786   mp->context = 0;
20787   mp->table_id = ntohl (table_id);
20788
20789   S (mp);
20790   W (ret);
20791   return ret;
20792 }
20793
20794 int
20795 api_classify_session_dump (vat_main_t * vam)
20796 {
20797   unformat_input_t *input = vam->input;
20798   vl_api_classify_session_dump_t *mp;
20799   vl_api_control_ping_t *mp_ping;
20800
20801   u32 table_id = ~0;
20802   int ret;
20803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20804     {
20805       if (unformat (input, "table_id %d", &table_id))
20806         ;
20807       else
20808         break;
20809     }
20810   if (table_id == ~0)
20811     {
20812       errmsg ("missing table id");
20813       return -99;
20814     }
20815
20816   /* Construct the API message */
20817   M (CLASSIFY_SESSION_DUMP, mp);
20818   mp->context = 0;
20819   mp->table_id = ntohl (table_id);
20820   S (mp);
20821
20822   /* Use a control ping for synchronization */
20823   MPING (CONTROL_PING, mp_ping);
20824   S (mp_ping);
20825
20826   W (ret);
20827   return ret;
20828 }
20829
20830 static void
20831 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20832 {
20833   vat_main_t *vam = &vat_main;
20834
20835   print (vam->ofp, "collector_address %U, collector_port %d, "
20836          "src_address %U, vrf_id %d, path_mtu %u, "
20837          "template_interval %u, udp_checksum %d",
20838          format_ip4_address, mp->collector_address,
20839          ntohs (mp->collector_port),
20840          format_ip4_address, mp->src_address,
20841          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20842          ntohl (mp->template_interval), mp->udp_checksum);
20843
20844   vam->retval = 0;
20845   vam->result_ready = 1;
20846 }
20847
20848 static void
20849   vl_api_ipfix_exporter_details_t_handler_json
20850   (vl_api_ipfix_exporter_details_t * mp)
20851 {
20852   vat_main_t *vam = &vat_main;
20853   vat_json_node_t node;
20854   struct in_addr collector_address;
20855   struct in_addr src_address;
20856
20857   vat_json_init_object (&node);
20858   clib_memcpy (&collector_address, &mp->collector_address,
20859                sizeof (collector_address));
20860   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20861   vat_json_object_add_uint (&node, "collector_port",
20862                             ntohs (mp->collector_port));
20863   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20864   vat_json_object_add_ip4 (&node, "src_address", src_address);
20865   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20866   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20867   vat_json_object_add_uint (&node, "template_interval",
20868                             ntohl (mp->template_interval));
20869   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20870
20871   vat_json_print (vam->ofp, &node);
20872   vat_json_free (&node);
20873   vam->retval = 0;
20874   vam->result_ready = 1;
20875 }
20876
20877 int
20878 api_ipfix_exporter_dump (vat_main_t * vam)
20879 {
20880   vl_api_ipfix_exporter_dump_t *mp;
20881   int ret;
20882
20883   /* Construct the API message */
20884   M (IPFIX_EXPORTER_DUMP, mp);
20885   mp->context = 0;
20886
20887   S (mp);
20888   W (ret);
20889   return ret;
20890 }
20891
20892 static int
20893 api_ipfix_classify_stream_dump (vat_main_t * vam)
20894 {
20895   vl_api_ipfix_classify_stream_dump_t *mp;
20896   int ret;
20897
20898   /* Construct the API message */
20899   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20900   mp->context = 0;
20901
20902   S (mp);
20903   W (ret);
20904   return ret;
20905   /* NOTREACHED */
20906   return 0;
20907 }
20908
20909 static void
20910   vl_api_ipfix_classify_stream_details_t_handler
20911   (vl_api_ipfix_classify_stream_details_t * mp)
20912 {
20913   vat_main_t *vam = &vat_main;
20914   print (vam->ofp, "domain_id %d, src_port %d",
20915          ntohl (mp->domain_id), ntohs (mp->src_port));
20916   vam->retval = 0;
20917   vam->result_ready = 1;
20918 }
20919
20920 static void
20921   vl_api_ipfix_classify_stream_details_t_handler_json
20922   (vl_api_ipfix_classify_stream_details_t * mp)
20923 {
20924   vat_main_t *vam = &vat_main;
20925   vat_json_node_t node;
20926
20927   vat_json_init_object (&node);
20928   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20929   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20930
20931   vat_json_print (vam->ofp, &node);
20932   vat_json_free (&node);
20933   vam->retval = 0;
20934   vam->result_ready = 1;
20935 }
20936
20937 static int
20938 api_ipfix_classify_table_dump (vat_main_t * vam)
20939 {
20940   vl_api_ipfix_classify_table_dump_t *mp;
20941   vl_api_control_ping_t *mp_ping;
20942   int ret;
20943
20944   if (!vam->json_output)
20945     {
20946       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20947              "transport_protocol");
20948     }
20949
20950   /* Construct the API message */
20951   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20952
20953   /* send it... */
20954   S (mp);
20955
20956   /* Use a control ping for synchronization */
20957   MPING (CONTROL_PING, mp_ping);
20958   S (mp_ping);
20959
20960   W (ret);
20961   return ret;
20962 }
20963
20964 static void
20965   vl_api_ipfix_classify_table_details_t_handler
20966   (vl_api_ipfix_classify_table_details_t * mp)
20967 {
20968   vat_main_t *vam = &vat_main;
20969   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20970          mp->transport_protocol);
20971 }
20972
20973 static void
20974   vl_api_ipfix_classify_table_details_t_handler_json
20975   (vl_api_ipfix_classify_table_details_t * mp)
20976 {
20977   vat_json_node_t *node = NULL;
20978   vat_main_t *vam = &vat_main;
20979
20980   if (VAT_JSON_ARRAY != vam->json_tree.type)
20981     {
20982       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20983       vat_json_init_array (&vam->json_tree);
20984     }
20985
20986   node = vat_json_array_add (&vam->json_tree);
20987   vat_json_init_object (node);
20988
20989   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20990   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20991   vat_json_object_add_uint (node, "transport_protocol",
20992                             mp->transport_protocol);
20993 }
20994
20995 static int
20996 api_sw_interface_span_enable_disable (vat_main_t * vam)
20997 {
20998   unformat_input_t *i = vam->input;
20999   vl_api_sw_interface_span_enable_disable_t *mp;
21000   u32 src_sw_if_index = ~0;
21001   u32 dst_sw_if_index = ~0;
21002   u8 state = 3;
21003   int ret;
21004   u8 is_l2 = 0;
21005
21006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21007     {
21008       if (unformat
21009           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21010         ;
21011       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21012         ;
21013       else
21014         if (unformat
21015             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21016         ;
21017       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21018         ;
21019       else if (unformat (i, "disable"))
21020         state = 0;
21021       else if (unformat (i, "rx"))
21022         state = 1;
21023       else if (unformat (i, "tx"))
21024         state = 2;
21025       else if (unformat (i, "both"))
21026         state = 3;
21027       else if (unformat (i, "l2"))
21028         is_l2 = 1;
21029       else
21030         break;
21031     }
21032
21033   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21034
21035   mp->sw_if_index_from = htonl (src_sw_if_index);
21036   mp->sw_if_index_to = htonl (dst_sw_if_index);
21037   mp->state = state;
21038   mp->is_l2 = is_l2;
21039
21040   S (mp);
21041   W (ret);
21042   return ret;
21043 }
21044
21045 static void
21046 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21047                                             * mp)
21048 {
21049   vat_main_t *vam = &vat_main;
21050   u8 *sw_if_from_name = 0;
21051   u8 *sw_if_to_name = 0;
21052   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21053   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21054   char *states[] = { "none", "rx", "tx", "both" };
21055   hash_pair_t *p;
21056
21057   /* *INDENT-OFF* */
21058   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21059   ({
21060     if ((u32) p->value[0] == sw_if_index_from)
21061       {
21062         sw_if_from_name = (u8 *)(p->key);
21063         if (sw_if_to_name)
21064           break;
21065       }
21066     if ((u32) p->value[0] == sw_if_index_to)
21067       {
21068         sw_if_to_name = (u8 *)(p->key);
21069         if (sw_if_from_name)
21070           break;
21071       }
21072   }));
21073   /* *INDENT-ON* */
21074   print (vam->ofp, "%20s => %20s (%s) %s",
21075          sw_if_from_name, sw_if_to_name, states[mp->state],
21076          mp->is_l2 ? "l2" : "device");
21077 }
21078
21079 static void
21080   vl_api_sw_interface_span_details_t_handler_json
21081   (vl_api_sw_interface_span_details_t * mp)
21082 {
21083   vat_main_t *vam = &vat_main;
21084   vat_json_node_t *node = NULL;
21085   u8 *sw_if_from_name = 0;
21086   u8 *sw_if_to_name = 0;
21087   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21088   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21089   hash_pair_t *p;
21090
21091   /* *INDENT-OFF* */
21092   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21093   ({
21094     if ((u32) p->value[0] == sw_if_index_from)
21095       {
21096         sw_if_from_name = (u8 *)(p->key);
21097         if (sw_if_to_name)
21098           break;
21099       }
21100     if ((u32) p->value[0] == sw_if_index_to)
21101       {
21102         sw_if_to_name = (u8 *)(p->key);
21103         if (sw_if_from_name)
21104           break;
21105       }
21106   }));
21107   /* *INDENT-ON* */
21108
21109   if (VAT_JSON_ARRAY != vam->json_tree.type)
21110     {
21111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21112       vat_json_init_array (&vam->json_tree);
21113     }
21114   node = vat_json_array_add (&vam->json_tree);
21115
21116   vat_json_init_object (node);
21117   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21118   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21119   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21120   if (0 != sw_if_to_name)
21121     {
21122       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21123     }
21124   vat_json_object_add_uint (node, "state", mp->state);
21125   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21126 }
21127
21128 static int
21129 api_sw_interface_span_dump (vat_main_t * vam)
21130 {
21131   unformat_input_t *input = vam->input;
21132   vl_api_sw_interface_span_dump_t *mp;
21133   vl_api_control_ping_t *mp_ping;
21134   u8 is_l2 = 0;
21135   int ret;
21136
21137   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21138     {
21139       if (unformat (input, "l2"))
21140         is_l2 = 1;
21141       else
21142         break;
21143     }
21144
21145   M (SW_INTERFACE_SPAN_DUMP, mp);
21146   mp->is_l2 = is_l2;
21147   S (mp);
21148
21149   /* Use a control ping for synchronization */
21150   MPING (CONTROL_PING, mp_ping);
21151   S (mp_ping);
21152
21153   W (ret);
21154   return ret;
21155 }
21156
21157 int
21158 api_pg_create_interface (vat_main_t * vam)
21159 {
21160   unformat_input_t *input = vam->input;
21161   vl_api_pg_create_interface_t *mp;
21162
21163   u32 if_id = ~0;
21164   int ret;
21165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21166     {
21167       if (unformat (input, "if_id %d", &if_id))
21168         ;
21169       else
21170         break;
21171     }
21172   if (if_id == ~0)
21173     {
21174       errmsg ("missing pg interface index");
21175       return -99;
21176     }
21177
21178   /* Construct the API message */
21179   M (PG_CREATE_INTERFACE, mp);
21180   mp->context = 0;
21181   mp->interface_id = ntohl (if_id);
21182
21183   S (mp);
21184   W (ret);
21185   return ret;
21186 }
21187
21188 int
21189 api_pg_capture (vat_main_t * vam)
21190 {
21191   unformat_input_t *input = vam->input;
21192   vl_api_pg_capture_t *mp;
21193
21194   u32 if_id = ~0;
21195   u8 enable = 1;
21196   u32 count = 1;
21197   u8 pcap_file_set = 0;
21198   u8 *pcap_file = 0;
21199   int ret;
21200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21201     {
21202       if (unformat (input, "if_id %d", &if_id))
21203         ;
21204       else if (unformat (input, "pcap %s", &pcap_file))
21205         pcap_file_set = 1;
21206       else if (unformat (input, "count %d", &count))
21207         ;
21208       else if (unformat (input, "disable"))
21209         enable = 0;
21210       else
21211         break;
21212     }
21213   if (if_id == ~0)
21214     {
21215       errmsg ("missing pg interface index");
21216       return -99;
21217     }
21218   if (pcap_file_set > 0)
21219     {
21220       if (vec_len (pcap_file) > 255)
21221         {
21222           errmsg ("pcap file name is too long");
21223           return -99;
21224         }
21225     }
21226
21227   u32 name_len = vec_len (pcap_file);
21228   /* Construct the API message */
21229   M (PG_CAPTURE, mp);
21230   mp->context = 0;
21231   mp->interface_id = ntohl (if_id);
21232   mp->is_enabled = enable;
21233   mp->count = ntohl (count);
21234   mp->pcap_name_length = ntohl (name_len);
21235   if (pcap_file_set != 0)
21236     {
21237       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21238     }
21239   vec_free (pcap_file);
21240
21241   S (mp);
21242   W (ret);
21243   return ret;
21244 }
21245
21246 int
21247 api_pg_enable_disable (vat_main_t * vam)
21248 {
21249   unformat_input_t *input = vam->input;
21250   vl_api_pg_enable_disable_t *mp;
21251
21252   u8 enable = 1;
21253   u8 stream_name_set = 0;
21254   u8 *stream_name = 0;
21255   int ret;
21256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21257     {
21258       if (unformat (input, "stream %s", &stream_name))
21259         stream_name_set = 1;
21260       else if (unformat (input, "disable"))
21261         enable = 0;
21262       else
21263         break;
21264     }
21265
21266   if (stream_name_set > 0)
21267     {
21268       if (vec_len (stream_name) > 255)
21269         {
21270           errmsg ("stream name too long");
21271           return -99;
21272         }
21273     }
21274
21275   u32 name_len = vec_len (stream_name);
21276   /* Construct the API message */
21277   M (PG_ENABLE_DISABLE, mp);
21278   mp->context = 0;
21279   mp->is_enabled = enable;
21280   if (stream_name_set != 0)
21281     {
21282       mp->stream_name_length = ntohl (name_len);
21283       clib_memcpy (mp->stream_name, stream_name, name_len);
21284     }
21285   vec_free (stream_name);
21286
21287   S (mp);
21288   W (ret);
21289   return ret;
21290 }
21291
21292 int
21293 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21294 {
21295   unformat_input_t *input = vam->input;
21296   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21297
21298   u16 *low_ports = 0;
21299   u16 *high_ports = 0;
21300   u16 this_low;
21301   u16 this_hi;
21302   ip4_address_t ip4_addr;
21303   ip6_address_t ip6_addr;
21304   u32 length;
21305   u32 tmp, tmp2;
21306   u8 prefix_set = 0;
21307   u32 vrf_id = ~0;
21308   u8 is_add = 1;
21309   u8 is_ipv6 = 0;
21310   int ret;
21311
21312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21313     {
21314       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21315         {
21316           prefix_set = 1;
21317         }
21318       else
21319         if (unformat
21320             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21321         {
21322           prefix_set = 1;
21323           is_ipv6 = 1;
21324         }
21325       else if (unformat (input, "vrf %d", &vrf_id))
21326         ;
21327       else if (unformat (input, "del"))
21328         is_add = 0;
21329       else if (unformat (input, "port %d", &tmp))
21330         {
21331           if (tmp == 0 || tmp > 65535)
21332             {
21333               errmsg ("port %d out of range", tmp);
21334               return -99;
21335             }
21336           this_low = tmp;
21337           this_hi = this_low + 1;
21338           vec_add1 (low_ports, this_low);
21339           vec_add1 (high_ports, this_hi);
21340         }
21341       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21342         {
21343           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21344             {
21345               errmsg ("incorrect range parameters");
21346               return -99;
21347             }
21348           this_low = tmp;
21349           /* Note: in debug CLI +1 is added to high before
21350              passing to real fn that does "the work"
21351              (ip_source_and_port_range_check_add_del).
21352              This fn is a wrapper around the binary API fn a
21353              control plane will call, which expects this increment
21354              to have occurred. Hence letting the binary API control
21355              plane fn do the increment for consistency between VAT
21356              and other control planes.
21357            */
21358           this_hi = tmp2;
21359           vec_add1 (low_ports, this_low);
21360           vec_add1 (high_ports, this_hi);
21361         }
21362       else
21363         break;
21364     }
21365
21366   if (prefix_set == 0)
21367     {
21368       errmsg ("<address>/<mask> not specified");
21369       return -99;
21370     }
21371
21372   if (vrf_id == ~0)
21373     {
21374       errmsg ("VRF ID required, not specified");
21375       return -99;
21376     }
21377
21378   if (vrf_id == 0)
21379     {
21380       errmsg
21381         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21382       return -99;
21383     }
21384
21385   if (vec_len (low_ports) == 0)
21386     {
21387       errmsg ("At least one port or port range required");
21388       return -99;
21389     }
21390
21391   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21392
21393   mp->is_add = is_add;
21394
21395   if (is_ipv6)
21396     {
21397       mp->is_ipv6 = 1;
21398       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21399     }
21400   else
21401     {
21402       mp->is_ipv6 = 0;
21403       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21404     }
21405
21406   mp->mask_length = length;
21407   mp->number_of_ranges = vec_len (low_ports);
21408
21409   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21410   vec_free (low_ports);
21411
21412   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21413   vec_free (high_ports);
21414
21415   mp->vrf_id = ntohl (vrf_id);
21416
21417   S (mp);
21418   W (ret);
21419   return ret;
21420 }
21421
21422 int
21423 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21424 {
21425   unformat_input_t *input = vam->input;
21426   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21427   u32 sw_if_index = ~0;
21428   int vrf_set = 0;
21429   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21430   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21431   u8 is_add = 1;
21432   int ret;
21433
21434   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21435     {
21436       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21437         ;
21438       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21439         ;
21440       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21441         vrf_set = 1;
21442       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21443         vrf_set = 1;
21444       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21445         vrf_set = 1;
21446       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21447         vrf_set = 1;
21448       else if (unformat (input, "del"))
21449         is_add = 0;
21450       else
21451         break;
21452     }
21453
21454   if (sw_if_index == ~0)
21455     {
21456       errmsg ("Interface required but not specified");
21457       return -99;
21458     }
21459
21460   if (vrf_set == 0)
21461     {
21462       errmsg ("VRF ID required but not specified");
21463       return -99;
21464     }
21465
21466   if (tcp_out_vrf_id == 0
21467       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21468     {
21469       errmsg
21470         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21471       return -99;
21472     }
21473
21474   /* Construct the API message */
21475   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21476
21477   mp->sw_if_index = ntohl (sw_if_index);
21478   mp->is_add = is_add;
21479   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21480   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21481   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21482   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21483
21484   /* send it... */
21485   S (mp);
21486
21487   /* Wait for a reply... */
21488   W (ret);
21489   return ret;
21490 }
21491
21492 static int
21493 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21494 {
21495   unformat_input_t *i = vam->input;
21496   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21497   u32 local_sa_id = 0;
21498   u32 remote_sa_id = 0;
21499   ip4_address_t src_address;
21500   ip4_address_t dst_address;
21501   u8 is_add = 1;
21502   int ret;
21503
21504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21505     {
21506       if (unformat (i, "local_sa %d", &local_sa_id))
21507         ;
21508       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21509         ;
21510       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21511         ;
21512       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21513         ;
21514       else if (unformat (i, "del"))
21515         is_add = 0;
21516       else
21517         {
21518           clib_warning ("parse error '%U'", format_unformat_error, i);
21519           return -99;
21520         }
21521     }
21522
21523   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21524
21525   mp->local_sa_id = ntohl (local_sa_id);
21526   mp->remote_sa_id = ntohl (remote_sa_id);
21527   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21528   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21529   mp->is_add = is_add;
21530
21531   S (mp);
21532   W (ret);
21533   return ret;
21534 }
21535
21536 static int
21537 api_punt (vat_main_t * vam)
21538 {
21539   unformat_input_t *i = vam->input;
21540   vl_api_punt_t *mp;
21541   u32 ipv = ~0;
21542   u32 protocol = ~0;
21543   u32 port = ~0;
21544   int is_add = 1;
21545   int ret;
21546
21547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21548     {
21549       if (unformat (i, "ip %d", &ipv))
21550         ;
21551       else if (unformat (i, "protocol %d", &protocol))
21552         ;
21553       else if (unformat (i, "port %d", &port))
21554         ;
21555       else if (unformat (i, "del"))
21556         is_add = 0;
21557       else
21558         {
21559           clib_warning ("parse error '%U'", format_unformat_error, i);
21560           return -99;
21561         }
21562     }
21563
21564   M (PUNT, mp);
21565
21566   mp->is_add = (u8) is_add;
21567   mp->ipv = (u8) ipv;
21568   mp->l4_protocol = (u8) protocol;
21569   mp->l4_port = htons ((u16) port);
21570
21571   S (mp);
21572   W (ret);
21573   return ret;
21574 }
21575
21576 static void vl_api_ipsec_gre_tunnel_details_t_handler
21577   (vl_api_ipsec_gre_tunnel_details_t * mp)
21578 {
21579   vat_main_t *vam = &vat_main;
21580
21581   print (vam->ofp, "%11d%15U%15U%14d%14d",
21582          ntohl (mp->sw_if_index),
21583          format_ip4_address, &mp->src_address,
21584          format_ip4_address, &mp->dst_address,
21585          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21586 }
21587
21588 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21589   (vl_api_ipsec_gre_tunnel_details_t * mp)
21590 {
21591   vat_main_t *vam = &vat_main;
21592   vat_json_node_t *node = NULL;
21593   struct in_addr ip4;
21594
21595   if (VAT_JSON_ARRAY != vam->json_tree.type)
21596     {
21597       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21598       vat_json_init_array (&vam->json_tree);
21599     }
21600   node = vat_json_array_add (&vam->json_tree);
21601
21602   vat_json_init_object (node);
21603   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21604   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21605   vat_json_object_add_ip4 (node, "src_address", ip4);
21606   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21607   vat_json_object_add_ip4 (node, "dst_address", ip4);
21608   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21609   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21610 }
21611
21612 static int
21613 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21614 {
21615   unformat_input_t *i = vam->input;
21616   vl_api_ipsec_gre_tunnel_dump_t *mp;
21617   vl_api_control_ping_t *mp_ping;
21618   u32 sw_if_index;
21619   u8 sw_if_index_set = 0;
21620   int ret;
21621
21622   /* Parse args required to build the message */
21623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21624     {
21625       if (unformat (i, "sw_if_index %d", &sw_if_index))
21626         sw_if_index_set = 1;
21627       else
21628         break;
21629     }
21630
21631   if (sw_if_index_set == 0)
21632     {
21633       sw_if_index = ~0;
21634     }
21635
21636   if (!vam->json_output)
21637     {
21638       print (vam->ofp, "%11s%15s%15s%14s%14s",
21639              "sw_if_index", "src_address", "dst_address",
21640              "local_sa_id", "remote_sa_id");
21641     }
21642
21643   /* Get list of gre-tunnel interfaces */
21644   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21645
21646   mp->sw_if_index = htonl (sw_if_index);
21647
21648   S (mp);
21649
21650   /* Use a control ping for synchronization */
21651   MPING (CONTROL_PING, mp_ping);
21652   S (mp_ping);
21653
21654   W (ret);
21655   return ret;
21656 }
21657
21658 static int
21659 api_delete_subif (vat_main_t * vam)
21660 {
21661   unformat_input_t *i = vam->input;
21662   vl_api_delete_subif_t *mp;
21663   u32 sw_if_index = ~0;
21664   int ret;
21665
21666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21667     {
21668       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21669         ;
21670       if (unformat (i, "sw_if_index %d", &sw_if_index))
21671         ;
21672       else
21673         break;
21674     }
21675
21676   if (sw_if_index == ~0)
21677     {
21678       errmsg ("missing sw_if_index");
21679       return -99;
21680     }
21681
21682   /* Construct the API message */
21683   M (DELETE_SUBIF, mp);
21684   mp->sw_if_index = ntohl (sw_if_index);
21685
21686   S (mp);
21687   W (ret);
21688   return ret;
21689 }
21690
21691 #define foreach_pbb_vtr_op      \
21692 _("disable",  L2_VTR_DISABLED)  \
21693 _("pop",  L2_VTR_POP_2)         \
21694 _("push",  L2_VTR_PUSH_2)
21695
21696 static int
21697 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21698 {
21699   unformat_input_t *i = vam->input;
21700   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21701   u32 sw_if_index = ~0, vtr_op = ~0;
21702   u16 outer_tag = ~0;
21703   u8 dmac[6], smac[6];
21704   u8 dmac_set = 0, smac_set = 0;
21705   u16 vlanid = 0;
21706   u32 sid = ~0;
21707   u32 tmp;
21708   int ret;
21709
21710   /* Shut up coverity */
21711   memset (dmac, 0, sizeof (dmac));
21712   memset (smac, 0, sizeof (smac));
21713
21714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21715     {
21716       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21717         ;
21718       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21719         ;
21720       else if (unformat (i, "vtr_op %d", &vtr_op))
21721         ;
21722 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21723       foreach_pbb_vtr_op
21724 #undef _
21725         else if (unformat (i, "translate_pbb_stag"))
21726         {
21727           if (unformat (i, "%d", &tmp))
21728             {
21729               vtr_op = L2_VTR_TRANSLATE_2_1;
21730               outer_tag = tmp;
21731             }
21732           else
21733             {
21734               errmsg
21735                 ("translate_pbb_stag operation requires outer tag definition");
21736               return -99;
21737             }
21738         }
21739       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21740         dmac_set++;
21741       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21742         smac_set++;
21743       else if (unformat (i, "sid %d", &sid))
21744         ;
21745       else if (unformat (i, "vlanid %d", &tmp))
21746         vlanid = tmp;
21747       else
21748         {
21749           clib_warning ("parse error '%U'", format_unformat_error, i);
21750           return -99;
21751         }
21752     }
21753
21754   if ((sw_if_index == ~0) || (vtr_op == ~0))
21755     {
21756       errmsg ("missing sw_if_index or vtr operation");
21757       return -99;
21758     }
21759   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21760       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21761     {
21762       errmsg
21763         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21764       return -99;
21765     }
21766
21767   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21768   mp->sw_if_index = ntohl (sw_if_index);
21769   mp->vtr_op = ntohl (vtr_op);
21770   mp->outer_tag = ntohs (outer_tag);
21771   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21772   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21773   mp->b_vlanid = ntohs (vlanid);
21774   mp->i_sid = ntohl (sid);
21775
21776   S (mp);
21777   W (ret);
21778   return ret;
21779 }
21780
21781 static int
21782 api_flow_classify_set_interface (vat_main_t * vam)
21783 {
21784   unformat_input_t *i = vam->input;
21785   vl_api_flow_classify_set_interface_t *mp;
21786   u32 sw_if_index;
21787   int sw_if_index_set;
21788   u32 ip4_table_index = ~0;
21789   u32 ip6_table_index = ~0;
21790   u8 is_add = 1;
21791   int ret;
21792
21793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21794     {
21795       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21796         sw_if_index_set = 1;
21797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21798         sw_if_index_set = 1;
21799       else if (unformat (i, "del"))
21800         is_add = 0;
21801       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21802         ;
21803       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21804         ;
21805       else
21806         {
21807           clib_warning ("parse error '%U'", format_unformat_error, i);
21808           return -99;
21809         }
21810     }
21811
21812   if (sw_if_index_set == 0)
21813     {
21814       errmsg ("missing interface name or sw_if_index");
21815       return -99;
21816     }
21817
21818   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21819
21820   mp->sw_if_index = ntohl (sw_if_index);
21821   mp->ip4_table_index = ntohl (ip4_table_index);
21822   mp->ip6_table_index = ntohl (ip6_table_index);
21823   mp->is_add = is_add;
21824
21825   S (mp);
21826   W (ret);
21827   return ret;
21828 }
21829
21830 static int
21831 api_flow_classify_dump (vat_main_t * vam)
21832 {
21833   unformat_input_t *i = vam->input;
21834   vl_api_flow_classify_dump_t *mp;
21835   vl_api_control_ping_t *mp_ping;
21836   u8 type = FLOW_CLASSIFY_N_TABLES;
21837   int ret;
21838
21839   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21840     ;
21841   else
21842     {
21843       errmsg ("classify table type must be specified");
21844       return -99;
21845     }
21846
21847   if (!vam->json_output)
21848     {
21849       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21850     }
21851
21852   M (FLOW_CLASSIFY_DUMP, mp);
21853   mp->type = type;
21854   /* send it... */
21855   S (mp);
21856
21857   /* Use a control ping for synchronization */
21858   MPING (CONTROL_PING, mp_ping);
21859   S (mp_ping);
21860
21861   /* Wait for a reply... */
21862   W (ret);
21863   return ret;
21864 }
21865
21866 static int
21867 api_feature_enable_disable (vat_main_t * vam)
21868 {
21869   unformat_input_t *i = vam->input;
21870   vl_api_feature_enable_disable_t *mp;
21871   u8 *arc_name = 0;
21872   u8 *feature_name = 0;
21873   u32 sw_if_index = ~0;
21874   u8 enable = 1;
21875   int ret;
21876
21877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21878     {
21879       if (unformat (i, "arc_name %s", &arc_name))
21880         ;
21881       else if (unformat (i, "feature_name %s", &feature_name))
21882         ;
21883       else
21884         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21885         ;
21886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21887         ;
21888       else if (unformat (i, "disable"))
21889         enable = 0;
21890       else
21891         break;
21892     }
21893
21894   if (arc_name == 0)
21895     {
21896       errmsg ("missing arc name");
21897       return -99;
21898     }
21899   if (vec_len (arc_name) > 63)
21900     {
21901       errmsg ("arc name too long");
21902     }
21903
21904   if (feature_name == 0)
21905     {
21906       errmsg ("missing feature name");
21907       return -99;
21908     }
21909   if (vec_len (feature_name) > 63)
21910     {
21911       errmsg ("feature name too long");
21912     }
21913
21914   if (sw_if_index == ~0)
21915     {
21916       errmsg ("missing interface name or sw_if_index");
21917       return -99;
21918     }
21919
21920   /* Construct the API message */
21921   M (FEATURE_ENABLE_DISABLE, mp);
21922   mp->sw_if_index = ntohl (sw_if_index);
21923   mp->enable = enable;
21924   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21925   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21926   vec_free (arc_name);
21927   vec_free (feature_name);
21928
21929   S (mp);
21930   W (ret);
21931   return ret;
21932 }
21933
21934 static int
21935 api_sw_interface_tag_add_del (vat_main_t * vam)
21936 {
21937   unformat_input_t *i = vam->input;
21938   vl_api_sw_interface_tag_add_del_t *mp;
21939   u32 sw_if_index = ~0;
21940   u8 *tag = 0;
21941   u8 enable = 1;
21942   int ret;
21943
21944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21945     {
21946       if (unformat (i, "tag %s", &tag))
21947         ;
21948       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21949         ;
21950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21951         ;
21952       else if (unformat (i, "del"))
21953         enable = 0;
21954       else
21955         break;
21956     }
21957
21958   if (sw_if_index == ~0)
21959     {
21960       errmsg ("missing interface name or sw_if_index");
21961       return -99;
21962     }
21963
21964   if (enable && (tag == 0))
21965     {
21966       errmsg ("no tag specified");
21967       return -99;
21968     }
21969
21970   /* Construct the API message */
21971   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21972   mp->sw_if_index = ntohl (sw_if_index);
21973   mp->is_add = enable;
21974   if (enable)
21975     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21976   vec_free (tag);
21977
21978   S (mp);
21979   W (ret);
21980   return ret;
21981 }
21982
21983 static void vl_api_l2_xconnect_details_t_handler
21984   (vl_api_l2_xconnect_details_t * mp)
21985 {
21986   vat_main_t *vam = &vat_main;
21987
21988   print (vam->ofp, "%15d%15d",
21989          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21990 }
21991
21992 static void vl_api_l2_xconnect_details_t_handler_json
21993   (vl_api_l2_xconnect_details_t * mp)
21994 {
21995   vat_main_t *vam = &vat_main;
21996   vat_json_node_t *node = NULL;
21997
21998   if (VAT_JSON_ARRAY != vam->json_tree.type)
21999     {
22000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22001       vat_json_init_array (&vam->json_tree);
22002     }
22003   node = vat_json_array_add (&vam->json_tree);
22004
22005   vat_json_init_object (node);
22006   vat_json_object_add_uint (node, "rx_sw_if_index",
22007                             ntohl (mp->rx_sw_if_index));
22008   vat_json_object_add_uint (node, "tx_sw_if_index",
22009                             ntohl (mp->tx_sw_if_index));
22010 }
22011
22012 static int
22013 api_l2_xconnect_dump (vat_main_t * vam)
22014 {
22015   vl_api_l2_xconnect_dump_t *mp;
22016   vl_api_control_ping_t *mp_ping;
22017   int ret;
22018
22019   if (!vam->json_output)
22020     {
22021       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22022     }
22023
22024   M (L2_XCONNECT_DUMP, mp);
22025
22026   S (mp);
22027
22028   /* Use a control ping for synchronization */
22029   MPING (CONTROL_PING, mp_ping);
22030   S (mp_ping);
22031
22032   W (ret);
22033   return ret;
22034 }
22035
22036 static int
22037 api_sw_interface_set_mtu (vat_main_t * vam)
22038 {
22039   unformat_input_t *i = vam->input;
22040   vl_api_sw_interface_set_mtu_t *mp;
22041   u32 sw_if_index = ~0;
22042   u32 mtu = 0;
22043   int ret;
22044
22045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22046     {
22047       if (unformat (i, "mtu %d", &mtu))
22048         ;
22049       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22050         ;
22051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22052         ;
22053       else
22054         break;
22055     }
22056
22057   if (sw_if_index == ~0)
22058     {
22059       errmsg ("missing interface name or sw_if_index");
22060       return -99;
22061     }
22062
22063   if (mtu == 0)
22064     {
22065       errmsg ("no mtu specified");
22066       return -99;
22067     }
22068
22069   /* Construct the API message */
22070   M (SW_INTERFACE_SET_MTU, mp);
22071   mp->sw_if_index = ntohl (sw_if_index);
22072   mp->mtu = ntohs ((u16) mtu);
22073
22074   S (mp);
22075   W (ret);
22076   return ret;
22077 }
22078
22079 static int
22080 api_p2p_ethernet_add (vat_main_t * vam)
22081 {
22082   unformat_input_t *i = vam->input;
22083   vl_api_p2p_ethernet_add_t *mp;
22084   u32 parent_if_index = ~0;
22085   u32 sub_id = ~0;
22086   u8 remote_mac[6];
22087   u8 mac_set = 0;
22088   int ret;
22089
22090   memset (remote_mac, 0, sizeof (remote_mac));
22091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22092     {
22093       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22094         ;
22095       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22096         ;
22097       else
22098         if (unformat
22099             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22100         mac_set++;
22101       else if (unformat (i, "sub_id %d", &sub_id))
22102         ;
22103       else
22104         {
22105           clib_warning ("parse error '%U'", format_unformat_error, i);
22106           return -99;
22107         }
22108     }
22109
22110   if (parent_if_index == ~0)
22111     {
22112       errmsg ("missing interface name or sw_if_index");
22113       return -99;
22114     }
22115   if (mac_set == 0)
22116     {
22117       errmsg ("missing remote mac address");
22118       return -99;
22119     }
22120   if (sub_id == ~0)
22121     {
22122       errmsg ("missing sub-interface id");
22123       return -99;
22124     }
22125
22126   M (P2P_ETHERNET_ADD, mp);
22127   mp->parent_if_index = ntohl (parent_if_index);
22128   mp->subif_id = ntohl (sub_id);
22129   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22130
22131   S (mp);
22132   W (ret);
22133   return ret;
22134 }
22135
22136 static int
22137 api_p2p_ethernet_del (vat_main_t * vam)
22138 {
22139   unformat_input_t *i = vam->input;
22140   vl_api_p2p_ethernet_del_t *mp;
22141   u32 parent_if_index = ~0;
22142   u8 remote_mac[6];
22143   u8 mac_set = 0;
22144   int ret;
22145
22146   memset (remote_mac, 0, sizeof (remote_mac));
22147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22148     {
22149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22150         ;
22151       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22152         ;
22153       else
22154         if (unformat
22155             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22156         mac_set++;
22157       else
22158         {
22159           clib_warning ("parse error '%U'", format_unformat_error, i);
22160           return -99;
22161         }
22162     }
22163
22164   if (parent_if_index == ~0)
22165     {
22166       errmsg ("missing interface name or sw_if_index");
22167       return -99;
22168     }
22169   if (mac_set == 0)
22170     {
22171       errmsg ("missing remote mac address");
22172       return -99;
22173     }
22174
22175   M (P2P_ETHERNET_DEL, mp);
22176   mp->parent_if_index = ntohl (parent_if_index);
22177   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22178
22179   S (mp);
22180   W (ret);
22181   return ret;
22182 }
22183
22184 static int
22185 api_lldp_config (vat_main_t * vam)
22186 {
22187   unformat_input_t *i = vam->input;
22188   vl_api_lldp_config_t *mp;
22189   int tx_hold = 0;
22190   int tx_interval = 0;
22191   u8 *sys_name = NULL;
22192   int ret;
22193
22194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22195     {
22196       if (unformat (i, "system-name %s", &sys_name))
22197         ;
22198       else if (unformat (i, "tx-hold %d", &tx_hold))
22199         ;
22200       else if (unformat (i, "tx-interval %d", &tx_interval))
22201         ;
22202       else
22203         {
22204           clib_warning ("parse error '%U'", format_unformat_error, i);
22205           return -99;
22206         }
22207     }
22208
22209   vec_add1 (sys_name, 0);
22210
22211   M (LLDP_CONFIG, mp);
22212   mp->tx_hold = htonl (tx_hold);
22213   mp->tx_interval = htonl (tx_interval);
22214   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22215   vec_free (sys_name);
22216
22217   S (mp);
22218   W (ret);
22219   return ret;
22220 }
22221
22222 static int
22223 api_sw_interface_set_lldp (vat_main_t * vam)
22224 {
22225   unformat_input_t *i = vam->input;
22226   vl_api_sw_interface_set_lldp_t *mp;
22227   u32 sw_if_index = ~0;
22228   u32 enable = 1;
22229   u8 *port_desc = NULL, *mgmt_oid = NULL;
22230   ip4_address_t ip4_addr;
22231   ip6_address_t ip6_addr;
22232   int ret;
22233
22234   memset (&ip4_addr, 0, sizeof (ip4_addr));
22235   memset (&ip6_addr, 0, sizeof (ip6_addr));
22236
22237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22238     {
22239       if (unformat (i, "disable"))
22240         enable = 0;
22241       else
22242         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22243         ;
22244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22245         ;
22246       else if (unformat (i, "port-desc %s", &port_desc))
22247         ;
22248       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22249         ;
22250       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22251         ;
22252       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22253         ;
22254       else
22255         break;
22256     }
22257
22258   if (sw_if_index == ~0)
22259     {
22260       errmsg ("missing interface name or sw_if_index");
22261       return -99;
22262     }
22263
22264   /* Construct the API message */
22265   vec_add1 (port_desc, 0);
22266   vec_add1 (mgmt_oid, 0);
22267   M (SW_INTERFACE_SET_LLDP, mp);
22268   mp->sw_if_index = ntohl (sw_if_index);
22269   mp->enable = enable;
22270   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22271   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22272   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22273   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22274   vec_free (port_desc);
22275   vec_free (mgmt_oid);
22276
22277   S (mp);
22278   W (ret);
22279   return ret;
22280 }
22281
22282 static int
22283 api_tcp_configure_src_addresses (vat_main_t * vam)
22284 {
22285   vl_api_tcp_configure_src_addresses_t *mp;
22286   unformat_input_t *i = vam->input;
22287   ip4_address_t v4first, v4last;
22288   ip6_address_t v6first, v6last;
22289   u8 range_set = 0;
22290   u32 vrf_id = 0;
22291   int ret;
22292
22293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22294     {
22295       if (unformat (i, "%U - %U",
22296                     unformat_ip4_address, &v4first,
22297                     unformat_ip4_address, &v4last))
22298         {
22299           if (range_set)
22300             {
22301               errmsg ("one range per message (range already set)");
22302               return -99;
22303             }
22304           range_set = 1;
22305         }
22306       else if (unformat (i, "%U - %U",
22307                          unformat_ip6_address, &v6first,
22308                          unformat_ip6_address, &v6last))
22309         {
22310           if (range_set)
22311             {
22312               errmsg ("one range per message (range already set)");
22313               return -99;
22314             }
22315           range_set = 2;
22316         }
22317       else if (unformat (i, "vrf %d", &vrf_id))
22318         ;
22319       else
22320         break;
22321     }
22322
22323   if (range_set == 0)
22324     {
22325       errmsg ("address range not set");
22326       return -99;
22327     }
22328
22329   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22330   mp->vrf_id = ntohl (vrf_id);
22331   /* ipv6? */
22332   if (range_set == 2)
22333     {
22334       mp->is_ipv6 = 1;
22335       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22336       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22337     }
22338   else
22339     {
22340       mp->is_ipv6 = 0;
22341       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22342       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22343     }
22344   S (mp);
22345   W (ret);
22346   return ret;
22347 }
22348
22349 static void vl_api_app_namespace_add_del_reply_t_handler
22350   (vl_api_app_namespace_add_del_reply_t * mp)
22351 {
22352   vat_main_t *vam = &vat_main;
22353   i32 retval = ntohl (mp->retval);
22354   if (vam->async_mode)
22355     {
22356       vam->async_errors += (retval < 0);
22357     }
22358   else
22359     {
22360       vam->retval = retval;
22361       if (retval == 0)
22362         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22363       vam->result_ready = 1;
22364     }
22365 }
22366
22367 static void vl_api_app_namespace_add_del_reply_t_handler_json
22368   (vl_api_app_namespace_add_del_reply_t * mp)
22369 {
22370   vat_main_t *vam = &vat_main;
22371   vat_json_node_t node;
22372
22373   vat_json_init_object (&node);
22374   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22375   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22376
22377   vat_json_print (vam->ofp, &node);
22378   vat_json_free (&node);
22379
22380   vam->retval = ntohl (mp->retval);
22381   vam->result_ready = 1;
22382 }
22383
22384 static int
22385 api_app_namespace_add_del (vat_main_t * vam)
22386 {
22387   vl_api_app_namespace_add_del_t *mp;
22388   unformat_input_t *i = vam->input;
22389   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22390   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22391   u64 secret;
22392   int ret;
22393
22394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22395     {
22396       if (unformat (i, "id %_%v%_", &ns_id))
22397         ;
22398       else if (unformat (i, "secret %lu", &secret))
22399         secret_set = 1;
22400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22401         sw_if_index_set = 1;
22402       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22403         ;
22404       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22405         ;
22406       else
22407         break;
22408     }
22409   if (!ns_id || !secret_set || !sw_if_index_set)
22410     {
22411       errmsg ("namespace id, secret and sw_if_index must be set");
22412       return -99;
22413     }
22414   if (vec_len (ns_id) > 64)
22415     {
22416       errmsg ("namespace id too long");
22417       return -99;
22418     }
22419   M (APP_NAMESPACE_ADD_DEL, mp);
22420
22421   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22422   mp->namespace_id_len = vec_len (ns_id);
22423   mp->secret = clib_host_to_net_u64 (secret);
22424   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22425   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22426   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22427   vec_free (ns_id);
22428   S (mp);
22429   W (ret);
22430   return ret;
22431 }
22432
22433 static int
22434 api_sock_init_shm (vat_main_t * vam)
22435 {
22436 #if VPP_API_TEST_BUILTIN == 0
22437   unformat_input_t *i = vam->input;
22438   vl_api_shm_elem_config_t *config = 0;
22439   u64 size = 64 << 20;
22440   int rv;
22441
22442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22443     {
22444       if (unformat (i, "size %U", unformat_memory_size, &size))
22445         ;
22446       else
22447         break;
22448     }
22449
22450   /*
22451    * Canned custom ring allocator config.
22452    * Should probably parse all of this
22453    */
22454   vec_validate (config, 6);
22455   config[0].type = VL_API_VLIB_RING;
22456   config[0].size = 256;
22457   config[0].count = 32;
22458
22459   config[1].type = VL_API_VLIB_RING;
22460   config[1].size = 1024;
22461   config[1].count = 16;
22462
22463   config[2].type = VL_API_VLIB_RING;
22464   config[2].size = 4096;
22465   config[2].count = 2;
22466
22467   config[3].type = VL_API_CLIENT_RING;
22468   config[3].size = 256;
22469   config[3].count = 32;
22470
22471   config[4].type = VL_API_CLIENT_RING;
22472   config[4].size = 1024;
22473   config[4].count = 16;
22474
22475   config[5].type = VL_API_CLIENT_RING;
22476   config[5].size = 4096;
22477   config[5].count = 2;
22478
22479   config[6].type = VL_API_QUEUE;
22480   config[6].count = 128;
22481   config[6].size = sizeof (uword);
22482
22483   rv = vl_socket_client_init_shm (config);
22484   if (!rv)
22485     vam->client_index_invalid = 1;
22486   return rv;
22487 #else
22488   return -99;
22489 #endif
22490 }
22491
22492 static int
22493 api_dns_enable_disable (vat_main_t * vam)
22494 {
22495   unformat_input_t *line_input = vam->input;
22496   vl_api_dns_enable_disable_t *mp;
22497   u8 enable_disable = 1;
22498   int ret;
22499
22500   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22501     {
22502       if (unformat (line_input, "disable"))
22503         enable_disable = 0;
22504       if (unformat (line_input, "enable"))
22505         enable_disable = 1;
22506       else
22507         break;
22508     }
22509
22510   /* Construct the API message */
22511   M (DNS_ENABLE_DISABLE, mp);
22512   mp->enable = enable_disable;
22513
22514   /* send it... */
22515   S (mp);
22516   /* Wait for the reply */
22517   W (ret);
22518   return ret;
22519 }
22520
22521 static int
22522 api_dns_resolve_name (vat_main_t * vam)
22523 {
22524   unformat_input_t *line_input = vam->input;
22525   vl_api_dns_resolve_name_t *mp;
22526   u8 *name = 0;
22527   int ret;
22528
22529   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22530     {
22531       if (unformat (line_input, "%s", &name))
22532         ;
22533       else
22534         break;
22535     }
22536
22537   if (vec_len (name) > 127)
22538     {
22539       errmsg ("name too long");
22540       return -99;
22541     }
22542
22543   /* Construct the API message */
22544   M (DNS_RESOLVE_NAME, mp);
22545   memcpy (mp->name, name, vec_len (name));
22546   vec_free (name);
22547
22548   /* send it... */
22549   S (mp);
22550   /* Wait for the reply */
22551   W (ret);
22552   return ret;
22553 }
22554
22555 static int
22556 api_dns_resolve_ip (vat_main_t * vam)
22557 {
22558   unformat_input_t *line_input = vam->input;
22559   vl_api_dns_resolve_ip_t *mp;
22560   int is_ip6 = -1;
22561   ip4_address_t addr4;
22562   ip6_address_t addr6;
22563   int ret;
22564
22565   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22566     {
22567       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22568         is_ip6 = 1;
22569       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22570         is_ip6 = 0;
22571       else
22572         break;
22573     }
22574
22575   if (is_ip6 == -1)
22576     {
22577       errmsg ("missing address");
22578       return -99;
22579     }
22580
22581   /* Construct the API message */
22582   M (DNS_RESOLVE_IP, mp);
22583   mp->is_ip6 = is_ip6;
22584   if (is_ip6)
22585     memcpy (mp->address, &addr6, sizeof (addr6));
22586   else
22587     memcpy (mp->address, &addr4, sizeof (addr4));
22588
22589   /* send it... */
22590   S (mp);
22591   /* Wait for the reply */
22592   W (ret);
22593   return ret;
22594 }
22595
22596 static int
22597 api_dns_name_server_add_del (vat_main_t * vam)
22598 {
22599   unformat_input_t *i = vam->input;
22600   vl_api_dns_name_server_add_del_t *mp;
22601   u8 is_add = 1;
22602   ip6_address_t ip6_server;
22603   ip4_address_t ip4_server;
22604   int ip6_set = 0;
22605   int ip4_set = 0;
22606   int ret = 0;
22607
22608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22609     {
22610       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22611         ip6_set = 1;
22612       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22613         ip4_set = 1;
22614       else if (unformat (i, "del"))
22615         is_add = 0;
22616       else
22617         {
22618           clib_warning ("parse error '%U'", format_unformat_error, i);
22619           return -99;
22620         }
22621     }
22622
22623   if (ip4_set && ip6_set)
22624     {
22625       errmsg ("Only one server address allowed per message");
22626       return -99;
22627     }
22628   if ((ip4_set + ip6_set) == 0)
22629     {
22630       errmsg ("Server address required");
22631       return -99;
22632     }
22633
22634   /* Construct the API message */
22635   M (DNS_NAME_SERVER_ADD_DEL, mp);
22636
22637   if (ip6_set)
22638     {
22639       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22640       mp->is_ip6 = 1;
22641     }
22642   else
22643     {
22644       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22645       mp->is_ip6 = 0;
22646     }
22647
22648   mp->is_add = is_add;
22649
22650   /* send it... */
22651   S (mp);
22652
22653   /* Wait for a reply, return good/bad news  */
22654   W (ret);
22655   return ret;
22656 }
22657
22658 static void
22659 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22660 {
22661   vat_main_t *vam = &vat_main;
22662
22663   if (mp->is_ip4)
22664     {
22665       print (vam->ofp,
22666              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22667              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22668              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22669              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22670              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22671              clib_net_to_host_u32 (mp->action_index), mp->tag);
22672     }
22673   else
22674     {
22675       print (vam->ofp,
22676              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22677              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22678              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22679              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22680              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22681              clib_net_to_host_u32 (mp->action_index), mp->tag);
22682     }
22683 }
22684
22685 static void
22686 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22687                                              mp)
22688 {
22689   vat_main_t *vam = &vat_main;
22690   vat_json_node_t *node = NULL;
22691   struct in6_addr ip6;
22692   struct in_addr ip4;
22693
22694   if (VAT_JSON_ARRAY != vam->json_tree.type)
22695     {
22696       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22697       vat_json_init_array (&vam->json_tree);
22698     }
22699   node = vat_json_array_add (&vam->json_tree);
22700   vat_json_init_object (node);
22701
22702   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22703   vat_json_object_add_uint (node, "appns_index",
22704                             clib_net_to_host_u32 (mp->appns_index));
22705   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22706   vat_json_object_add_uint (node, "scope", mp->scope);
22707   vat_json_object_add_uint (node, "action_index",
22708                             clib_net_to_host_u32 (mp->action_index));
22709   vat_json_object_add_uint (node, "lcl_port",
22710                             clib_net_to_host_u16 (mp->lcl_port));
22711   vat_json_object_add_uint (node, "rmt_port",
22712                             clib_net_to_host_u16 (mp->rmt_port));
22713   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22714   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22715   vat_json_object_add_string_copy (node, "tag", mp->tag);
22716   if (mp->is_ip4)
22717     {
22718       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22719       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22720       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22721       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22722     }
22723   else
22724     {
22725       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22726       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22727       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22728       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22729     }
22730 }
22731
22732 static int
22733 api_session_rule_add_del (vat_main_t * vam)
22734 {
22735   vl_api_session_rule_add_del_t *mp;
22736   unformat_input_t *i = vam->input;
22737   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22738   u32 appns_index = 0, scope = 0;
22739   ip4_address_t lcl_ip4, rmt_ip4;
22740   ip6_address_t lcl_ip6, rmt_ip6;
22741   u8 is_ip4 = 1, conn_set = 0;
22742   u8 is_add = 1, *tag = 0;
22743   int ret;
22744
22745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22746     {
22747       if (unformat (i, "del"))
22748         is_add = 0;
22749       else if (unformat (i, "add"))
22750         ;
22751       else if (unformat (i, "proto tcp"))
22752         proto = 0;
22753       else if (unformat (i, "proto udp"))
22754         proto = 1;
22755       else if (unformat (i, "appns %d", &appns_index))
22756         ;
22757       else if (unformat (i, "scope %d", &scope))
22758         ;
22759       else if (unformat (i, "tag %_%v%_", &tag))
22760         ;
22761       else
22762         if (unformat
22763             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22764              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22765              &rmt_port))
22766         {
22767           is_ip4 = 1;
22768           conn_set = 1;
22769         }
22770       else
22771         if (unformat
22772             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22773              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22774              &rmt_port))
22775         {
22776           is_ip4 = 0;
22777           conn_set = 1;
22778         }
22779       else if (unformat (i, "action %d", &action))
22780         ;
22781       else
22782         break;
22783     }
22784   if (proto == ~0 || !conn_set || action == ~0)
22785     {
22786       errmsg ("transport proto, connection and action must be set");
22787       return -99;
22788     }
22789
22790   if (scope > 3)
22791     {
22792       errmsg ("scope should be 0-3");
22793       return -99;
22794     }
22795
22796   M (SESSION_RULE_ADD_DEL, mp);
22797
22798   mp->is_ip4 = is_ip4;
22799   mp->transport_proto = proto;
22800   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22801   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22802   mp->lcl_plen = lcl_plen;
22803   mp->rmt_plen = rmt_plen;
22804   mp->action_index = clib_host_to_net_u32 (action);
22805   mp->appns_index = clib_host_to_net_u32 (appns_index);
22806   mp->scope = scope;
22807   mp->is_add = is_add;
22808   if (is_ip4)
22809     {
22810       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22811       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22812     }
22813   else
22814     {
22815       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22816       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22817     }
22818   if (tag)
22819     {
22820       clib_memcpy (mp->tag, tag, vec_len (tag));
22821       vec_free (tag);
22822     }
22823
22824   S (mp);
22825   W (ret);
22826   return ret;
22827 }
22828
22829 static int
22830 api_session_rules_dump (vat_main_t * vam)
22831 {
22832   vl_api_session_rules_dump_t *mp;
22833   vl_api_control_ping_t *mp_ping;
22834   int ret;
22835
22836   if (!vam->json_output)
22837     {
22838       print (vam->ofp, "%=20s", "Session Rules");
22839     }
22840
22841   M (SESSION_RULES_DUMP, mp);
22842   /* send it... */
22843   S (mp);
22844
22845   /* Use a control ping for synchronization */
22846   MPING (CONTROL_PING, mp_ping);
22847   S (mp_ping);
22848
22849   /* Wait for a reply... */
22850   W (ret);
22851   return ret;
22852 }
22853
22854 static int
22855 api_ip_container_proxy_add_del (vat_main_t * vam)
22856 {
22857   vl_api_ip_container_proxy_add_del_t *mp;
22858   unformat_input_t *i = vam->input;
22859   u32 plen = ~0, sw_if_index = ~0;
22860   ip4_address_t ip4;
22861   ip6_address_t ip6;
22862   u8 is_ip4 = 1;
22863   u8 is_add = 1;
22864   int ret;
22865
22866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22867     {
22868       if (unformat (i, "del"))
22869         is_add = 0;
22870       else if (unformat (i, "add"))
22871         ;
22872       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22873         {
22874           is_ip4 = 1;
22875           plen = 32;
22876         }
22877       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22878         {
22879           is_ip4 = 0;
22880           plen = 128;
22881         }
22882       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22883         ;
22884       else
22885         break;
22886     }
22887   if (sw_if_index == ~0 || plen == ~0)
22888     {
22889       errmsg ("address and sw_if_index must be set");
22890       return -99;
22891     }
22892
22893   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22894
22895   mp->is_ip4 = is_ip4;
22896   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22897   mp->plen = plen;
22898   mp->is_add = is_add;
22899   if (is_ip4)
22900     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22901   else
22902     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22903
22904   S (mp);
22905   W (ret);
22906   return ret;
22907 }
22908
22909 static int
22910 api_qos_record_enable_disable (vat_main_t * vam)
22911 {
22912   unformat_input_t *i = vam->input;
22913   vl_api_qos_record_enable_disable_t *mp;
22914   u32 sw_if_index, qs = 0xff;
22915   u8 sw_if_index_set = 0;
22916   u8 enable = 1;
22917   int ret;
22918
22919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22920     {
22921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22922         sw_if_index_set = 1;
22923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22924         sw_if_index_set = 1;
22925       else if (unformat (i, "%U", unformat_qos_source, &qs))
22926         ;
22927       else if (unformat (i, "disable"))
22928         enable = 0;
22929       else
22930         {
22931           clib_warning ("parse error '%U'", format_unformat_error, i);
22932           return -99;
22933         }
22934     }
22935
22936   if (sw_if_index_set == 0)
22937     {
22938       errmsg ("missing interface name or sw_if_index");
22939       return -99;
22940     }
22941   if (qs == 0xff)
22942     {
22943       errmsg ("input location must be specified");
22944       return -99;
22945     }
22946
22947   M (QOS_RECORD_ENABLE_DISABLE, mp);
22948
22949   mp->sw_if_index = ntohl (sw_if_index);
22950   mp->input_source = qs;
22951   mp->enable = enable;
22952
22953   S (mp);
22954   W (ret);
22955   return ret;
22956 }
22957
22958 static int
22959 q_or_quit (vat_main_t * vam)
22960 {
22961 #if VPP_API_TEST_BUILTIN == 0
22962   longjmp (vam->jump_buf, 1);
22963 #endif
22964   return 0;                     /* not so much */
22965 }
22966
22967 static int
22968 q (vat_main_t * vam)
22969 {
22970   return q_or_quit (vam);
22971 }
22972
22973 static int
22974 quit (vat_main_t * vam)
22975 {
22976   return q_or_quit (vam);
22977 }
22978
22979 static int
22980 comment (vat_main_t * vam)
22981 {
22982   return 0;
22983 }
22984
22985 static int
22986 cmd_cmp (void *a1, void *a2)
22987 {
22988   u8 **c1 = a1;
22989   u8 **c2 = a2;
22990
22991   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22992 }
22993
22994 static int
22995 help (vat_main_t * vam)
22996 {
22997   u8 **cmds = 0;
22998   u8 *name = 0;
22999   hash_pair_t *p;
23000   unformat_input_t *i = vam->input;
23001   int j;
23002
23003   if (unformat (i, "%s", &name))
23004     {
23005       uword *hs;
23006
23007       vec_add1 (name, 0);
23008
23009       hs = hash_get_mem (vam->help_by_name, name);
23010       if (hs)
23011         print (vam->ofp, "usage: %s %s", name, hs[0]);
23012       else
23013         print (vam->ofp, "No such msg / command '%s'", name);
23014       vec_free (name);
23015       return 0;
23016     }
23017
23018   print (vam->ofp, "Help is available for the following:");
23019
23020     /* *INDENT-OFF* */
23021     hash_foreach_pair (p, vam->function_by_name,
23022     ({
23023       vec_add1 (cmds, (u8 *)(p->key));
23024     }));
23025     /* *INDENT-ON* */
23026
23027   vec_sort_with_function (cmds, cmd_cmp);
23028
23029   for (j = 0; j < vec_len (cmds); j++)
23030     print (vam->ofp, "%s", cmds[j]);
23031
23032   vec_free (cmds);
23033   return 0;
23034 }
23035
23036 static int
23037 set (vat_main_t * vam)
23038 {
23039   u8 *name = 0, *value = 0;
23040   unformat_input_t *i = vam->input;
23041
23042   if (unformat (i, "%s", &name))
23043     {
23044       /* The input buffer is a vector, not a string. */
23045       value = vec_dup (i->buffer);
23046       vec_delete (value, i->index, 0);
23047       /* Almost certainly has a trailing newline */
23048       if (value[vec_len (value) - 1] == '\n')
23049         value[vec_len (value) - 1] = 0;
23050       /* Make sure it's a proper string, one way or the other */
23051       vec_add1 (value, 0);
23052       (void) clib_macro_set_value (&vam->macro_main,
23053                                    (char *) name, (char *) value);
23054     }
23055   else
23056     errmsg ("usage: set <name> <value>");
23057
23058   vec_free (name);
23059   vec_free (value);
23060   return 0;
23061 }
23062
23063 static int
23064 unset (vat_main_t * vam)
23065 {
23066   u8 *name = 0;
23067
23068   if (unformat (vam->input, "%s", &name))
23069     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23070       errmsg ("unset: %s wasn't set", name);
23071   vec_free (name);
23072   return 0;
23073 }
23074
23075 typedef struct
23076 {
23077   u8 *name;
23078   u8 *value;
23079 } macro_sort_t;
23080
23081
23082 static int
23083 macro_sort_cmp (void *a1, void *a2)
23084 {
23085   macro_sort_t *s1 = a1;
23086   macro_sort_t *s2 = a2;
23087
23088   return strcmp ((char *) (s1->name), (char *) (s2->name));
23089 }
23090
23091 static int
23092 dump_macro_table (vat_main_t * vam)
23093 {
23094   macro_sort_t *sort_me = 0, *sm;
23095   int i;
23096   hash_pair_t *p;
23097
23098     /* *INDENT-OFF* */
23099     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23100     ({
23101       vec_add2 (sort_me, sm, 1);
23102       sm->name = (u8 *)(p->key);
23103       sm->value = (u8 *) (p->value[0]);
23104     }));
23105     /* *INDENT-ON* */
23106
23107   vec_sort_with_function (sort_me, macro_sort_cmp);
23108
23109   if (vec_len (sort_me))
23110     print (vam->ofp, "%-15s%s", "Name", "Value");
23111   else
23112     print (vam->ofp, "The macro table is empty...");
23113
23114   for (i = 0; i < vec_len (sort_me); i++)
23115     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23116   return 0;
23117 }
23118
23119 static int
23120 dump_node_table (vat_main_t * vam)
23121 {
23122   int i, j;
23123   vlib_node_t *node, *next_node;
23124
23125   if (vec_len (vam->graph_nodes) == 0)
23126     {
23127       print (vam->ofp, "Node table empty, issue get_node_graph...");
23128       return 0;
23129     }
23130
23131   for (i = 0; i < vec_len (vam->graph_nodes); i++)
23132     {
23133       node = vam->graph_nodes[i];
23134       print (vam->ofp, "[%d] %s", i, node->name);
23135       for (j = 0; j < vec_len (node->next_nodes); j++)
23136         {
23137           if (node->next_nodes[j] != ~0)
23138             {
23139               next_node = vam->graph_nodes[node->next_nodes[j]];
23140               print (vam->ofp, "  [%d] %s", j, next_node->name);
23141             }
23142         }
23143     }
23144   return 0;
23145 }
23146
23147 static int
23148 value_sort_cmp (void *a1, void *a2)
23149 {
23150   name_sort_t *n1 = a1;
23151   name_sort_t *n2 = a2;
23152
23153   if (n1->value < n2->value)
23154     return -1;
23155   if (n1->value > n2->value)
23156     return 1;
23157   return 0;
23158 }
23159
23160
23161 static int
23162 dump_msg_api_table (vat_main_t * vam)
23163 {
23164   api_main_t *am = &api_main;
23165   name_sort_t *nses = 0, *ns;
23166   hash_pair_t *hp;
23167   int i;
23168
23169   /* *INDENT-OFF* */
23170   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23171   ({
23172     vec_add2 (nses, ns, 1);
23173     ns->name = (u8 *)(hp->key);
23174     ns->value = (u32) hp->value[0];
23175   }));
23176   /* *INDENT-ON* */
23177
23178   vec_sort_with_function (nses, value_sort_cmp);
23179
23180   for (i = 0; i < vec_len (nses); i++)
23181     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23182   vec_free (nses);
23183   return 0;
23184 }
23185
23186 static int
23187 get_msg_id (vat_main_t * vam)
23188 {
23189   u8 *name_and_crc;
23190   u32 message_index;
23191
23192   if (unformat (vam->input, "%s", &name_and_crc))
23193     {
23194       message_index = vl_msg_api_get_msg_index (name_and_crc);
23195       if (message_index == ~0)
23196         {
23197           print (vam->ofp, " '%s' not found", name_and_crc);
23198           return 0;
23199         }
23200       print (vam->ofp, " '%s' has message index %d",
23201              name_and_crc, message_index);
23202       return 0;
23203     }
23204   errmsg ("name_and_crc required...");
23205   return 0;
23206 }
23207
23208 static int
23209 search_node_table (vat_main_t * vam)
23210 {
23211   unformat_input_t *line_input = vam->input;
23212   u8 *node_to_find;
23213   int j;
23214   vlib_node_t *node, *next_node;
23215   uword *p;
23216
23217   if (vam->graph_node_index_by_name == 0)
23218     {
23219       print (vam->ofp, "Node table empty, issue get_node_graph...");
23220       return 0;
23221     }
23222
23223   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23224     {
23225       if (unformat (line_input, "%s", &node_to_find))
23226         {
23227           vec_add1 (node_to_find, 0);
23228           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23229           if (p == 0)
23230             {
23231               print (vam->ofp, "%s not found...", node_to_find);
23232               goto out;
23233             }
23234           node = vam->graph_nodes[p[0]];
23235           print (vam->ofp, "[%d] %s", p[0], node->name);
23236           for (j = 0; j < vec_len (node->next_nodes); j++)
23237             {
23238               if (node->next_nodes[j] != ~0)
23239                 {
23240                   next_node = vam->graph_nodes[node->next_nodes[j]];
23241                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23242                 }
23243             }
23244         }
23245
23246       else
23247         {
23248           clib_warning ("parse error '%U'", format_unformat_error,
23249                         line_input);
23250           return -99;
23251         }
23252
23253     out:
23254       vec_free (node_to_find);
23255
23256     }
23257
23258   return 0;
23259 }
23260
23261
23262 static int
23263 script (vat_main_t * vam)
23264 {
23265 #if (VPP_API_TEST_BUILTIN==0)
23266   u8 *s = 0;
23267   char *save_current_file;
23268   unformat_input_t save_input;
23269   jmp_buf save_jump_buf;
23270   u32 save_line_number;
23271
23272   FILE *new_fp, *save_ifp;
23273
23274   if (unformat (vam->input, "%s", &s))
23275     {
23276       new_fp = fopen ((char *) s, "r");
23277       if (new_fp == 0)
23278         {
23279           errmsg ("Couldn't open script file %s", s);
23280           vec_free (s);
23281           return -99;
23282         }
23283     }
23284   else
23285     {
23286       errmsg ("Missing script name");
23287       return -99;
23288     }
23289
23290   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23291   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23292   save_ifp = vam->ifp;
23293   save_line_number = vam->input_line_number;
23294   save_current_file = (char *) vam->current_file;
23295
23296   vam->input_line_number = 0;
23297   vam->ifp = new_fp;
23298   vam->current_file = s;
23299   do_one_file (vam);
23300
23301   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23302   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23303   vam->ifp = save_ifp;
23304   vam->input_line_number = save_line_number;
23305   vam->current_file = (u8 *) save_current_file;
23306   vec_free (s);
23307
23308   return 0;
23309 #else
23310   clib_warning ("use the exec command...");
23311   return -99;
23312 #endif
23313 }
23314
23315 static int
23316 echo (vat_main_t * vam)
23317 {
23318   print (vam->ofp, "%v", vam->input->buffer);
23319   return 0;
23320 }
23321
23322 /* List of API message constructors, CLI names map to api_xxx */
23323 #define foreach_vpe_api_msg                                             \
23324 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23325 _(sw_interface_dump,"")                                                 \
23326 _(sw_interface_set_flags,                                               \
23327   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23328 _(sw_interface_add_del_address,                                         \
23329   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23330 _(sw_interface_set_rx_mode,                                             \
23331   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23332 _(sw_interface_set_table,                                               \
23333   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23334 _(sw_interface_set_mpls_enable,                                         \
23335   "<intfc> | sw_if_index [disable | dis]")                              \
23336 _(sw_interface_set_vpath,                                               \
23337   "<intfc> | sw_if_index <id> enable | disable")                        \
23338 _(sw_interface_set_vxlan_bypass,                                        \
23339   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23340 _(sw_interface_set_geneve_bypass,                                       \
23341   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23342 _(sw_interface_set_l2_xconnect,                                         \
23343   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23344   "enable | disable")                                                   \
23345 _(sw_interface_set_l2_bridge,                                           \
23346   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23347   "[shg <split-horizon-group>] [bvi]\n"                                 \
23348   "enable | disable")                                                   \
23349 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23350 _(bridge_domain_add_del,                                                \
23351   "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") \
23352 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23353 _(l2fib_add_del,                                                        \
23354   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23355 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23356 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23357 _(l2_flags,                                                             \
23358   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23359 _(bridge_flags,                                                         \
23360   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23361 _(tap_connect,                                                          \
23362   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23363 _(tap_modify,                                                           \
23364   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23365 _(tap_delete,                                                           \
23366   "<vpp-if-name> | sw_if_index <id>")                                   \
23367 _(sw_interface_tap_dump, "")                                            \
23368 _(tap_create_v2,                                                        \
23369   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23370 _(tap_delete_v2,                                                        \
23371   "<vpp-if-name> | sw_if_index <id>")                                   \
23372 _(sw_interface_tap_v2_dump, "")                                         \
23373 _(bond_create,                                                          \
23374   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23375   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23376 _(bond_delete,                                                          \
23377   "<vpp-if-name> | sw_if_index <id>")                                   \
23378 _(bond_enslave,                                                         \
23379   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23380 _(bond_detach_slave,                                                    \
23381   "sw_if_index <n>")                                                    \
23382 _(sw_interface_bond_dump, "")                                           \
23383 _(sw_interface_slave_dump,                                              \
23384   "<vpp-if-name> | sw_if_index <id>")                                   \
23385 _(ip_table_add_del,                                                     \
23386   "table-id <n> [ipv6]\n")                                              \
23387 _(ip_add_del_route,                                                     \
23388   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23389   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23390   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23391   "[multipath] [count <n>]")                                            \
23392 _(ip_mroute_add_del,                                                    \
23393   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23394   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23395 _(mpls_table_add_del,                                                   \
23396   "table-id <n>\n")                                                     \
23397 _(mpls_route_add_del,                                                   \
23398   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23399   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23400   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23401   "[multipath] [count <n>]")                                            \
23402 _(mpls_ip_bind_unbind,                                                  \
23403   "<label> <addr/len>")                                                 \
23404 _(mpls_tunnel_add_del,                                                  \
23405   " via <addr> [table-id <n>]\n"                                        \
23406   "sw_if_index <id>] [l2]  [del]")                                      \
23407 _(bier_table_add_del,                                                   \
23408   "<label> <sub-domain> <set> <bsl> [del]")                             \
23409 _(bier_route_add_del,                                                   \
23410   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23411   "[<intfc> | sw_if_index <id>]"                                        \
23412   "[weight <n>] [del] [multipath]")                                     \
23413 _(proxy_arp_add_del,                                                    \
23414   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23415 _(proxy_arp_intfc_enable_disable,                                       \
23416   "<intfc> | sw_if_index <id> enable | disable")                        \
23417 _(sw_interface_set_unnumbered,                                          \
23418   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23419 _(ip_neighbor_add_del,                                                  \
23420   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23421   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23422 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23423 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23424   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23425   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23426   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23427 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23428 _(reset_fib, "vrf <n> [ipv6]")                                          \
23429 _(dhcp_proxy_config,                                                    \
23430   "svr <v46-address> src <v46-address>\n"                               \
23431    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23432 _(dhcp_proxy_set_vss,                                                   \
23433   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23434 _(dhcp_proxy_dump, "ip6")                                               \
23435 _(dhcp_client_config,                                                   \
23436   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23437 _(set_ip_flow_hash,                                                     \
23438   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23439 _(sw_interface_ip6_enable_disable,                                      \
23440   "<intfc> | sw_if_index <id> enable | disable")                        \
23441 _(sw_interface_ip6_set_link_local_address,                              \
23442   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23443 _(ip6nd_proxy_add_del,                                                  \
23444   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23445 _(ip6nd_proxy_dump, "")                                                 \
23446 _(sw_interface_ip6nd_ra_prefix,                                         \
23447   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23448   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23449   "[nolink] [isno]")                                                    \
23450 _(sw_interface_ip6nd_ra_config,                                         \
23451   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23452   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23453   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23454 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23455 _(l2_patch_add_del,                                                     \
23456   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23457   "enable | disable")                                                   \
23458 _(sr_localsid_add_del,                                                  \
23459   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23460   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23461 _(classify_add_del_table,                                               \
23462   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23463   " [del] [del-chain] mask <mask-value>\n"                              \
23464   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23465   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23466 _(classify_add_del_session,                                             \
23467   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23468   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23469   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23470   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23471 _(classify_set_interface_ip_table,                                      \
23472   "<intfc> | sw_if_index <nn> table <nn>")                              \
23473 _(classify_set_interface_l2_tables,                                     \
23474   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23475   "  [other-table <nn>]")                                               \
23476 _(get_node_index, "node <node-name")                                    \
23477 _(add_node_next, "node <node-name> next <next-node-name>")              \
23478 _(l2tpv3_create_tunnel,                                                 \
23479   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23480   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23481   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23482 _(l2tpv3_set_tunnel_cookies,                                            \
23483   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23484   "[new_remote_cookie <nn>]\n")                                         \
23485 _(l2tpv3_interface_enable_disable,                                      \
23486   "<intfc> | sw_if_index <nn> enable | disable")                        \
23487 _(l2tpv3_set_lookup_key,                                                \
23488   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23489 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23490 _(vxlan_add_del_tunnel,                                                 \
23491   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23492   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23493   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23494 _(geneve_add_del_tunnel,                                                \
23495   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23496   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23497   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23498 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23499 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23500 _(gre_add_del_tunnel,                                                   \
23501   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23502   "[teb | erspan <session-id>] [del]")                                  \
23503 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23504 _(l2_fib_clear_table, "")                                               \
23505 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23506 _(l2_interface_vlan_tag_rewrite,                                        \
23507   "<intfc> | sw_if_index <nn> \n"                                       \
23508   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23509   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23510 _(create_vhost_user_if,                                                 \
23511         "socket <filename> [server] [renumber <dev_instance>] "         \
23512         "[mac <mac_address>]")                                          \
23513 _(modify_vhost_user_if,                                                 \
23514         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23515         "[server] [renumber <dev_instance>]")                           \
23516 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23517 _(sw_interface_vhost_user_dump, "")                                     \
23518 _(show_version, "")                                                     \
23519 _(vxlan_gpe_add_del_tunnel,                                             \
23520   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23521   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23522   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23523   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23524 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23525 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23526 _(interface_name_renumber,                                              \
23527   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23528 _(input_acl_set_interface,                                              \
23529   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23530   "  [l2-table <nn>] [del]")                                            \
23531 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23532 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23533   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23534 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23535 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23536 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23537 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23538 _(ip_dump, "ipv4 | ipv6")                                               \
23539 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23540 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23541   "  spid_id <n> ")                                                     \
23542 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23543   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23544   "  integ_alg <alg> integ_key <hex>")                                  \
23545 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23546   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23547   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23548   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23549 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23550 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23551   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23552   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23553   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23554   "  [instance <n>]")     \
23555 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23556 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23557   "  <alg> <hex>\n")                                                    \
23558 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23559 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23560 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23561   "(auth_data 0x<data> | auth_data <data>)")                            \
23562 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23563   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23564 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23565   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23566   "(local|remote)")                                                     \
23567 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23568 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23569 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23570 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23571 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23572 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23573 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23574 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23575 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23576 _(delete_loopback,"sw_if_index <nn>")                                   \
23577 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23578 _(map_add_domain,                                                       \
23579   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23580   "ip6-src <ip6addr> "                                                  \
23581   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23582 _(map_del_domain, "index <n>")                                          \
23583 _(map_add_del_rule,                                                     \
23584   "index <n> psid <n> dst <ip6addr> [del]")                             \
23585 _(map_domain_dump, "")                                                  \
23586 _(map_rule_dump, "index <map-domain>")                                  \
23587 _(want_interface_events,  "enable|disable")                             \
23588 _(want_stats,"enable|disable")                                          \
23589 _(get_first_msg_id, "client <name>")                                    \
23590 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23591 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23592   "fib-id <nn> [ip4][ip6][default]")                                    \
23593 _(get_node_graph, " ")                                                  \
23594 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23595 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23596 _(ioam_disable, "")                                                     \
23597 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23598                             " sw_if_index <sw_if_index> p <priority> "  \
23599                             "w <weight>] [del]")                        \
23600 _(one_add_del_locator, "locator-set <locator_name> "                    \
23601                         "iface <intf> | sw_if_index <sw_if_index> "     \
23602                         "p <priority> w <weight> [del]")                \
23603 _(one_add_del_local_eid,"vni <vni> eid "                                \
23604                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23605                          "locator-set <locator_name> [del]"             \
23606                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23607 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23608 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23609 _(one_enable_disable, "enable|disable")                                 \
23610 _(one_map_register_enable_disable, "enable|disable")                    \
23611 _(one_map_register_fallback_threshold, "<value>")                       \
23612 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23613 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23614                                "[seid <seid>] "                         \
23615                                "rloc <locator> p <prio> "               \
23616                                "w <weight> [rloc <loc> ... ] "          \
23617                                "action <action> [del-all]")             \
23618 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23619                           "<local-eid>")                                \
23620 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23621 _(one_use_petr, "ip-address> | disable")                                \
23622 _(one_map_request_mode, "src-dst|dst-only")                             \
23623 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23624 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23625 _(one_locator_set_dump, "[local | remote]")                             \
23626 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23627 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23628                        "[local] | [remote]")                            \
23629 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23630 _(one_ndp_bd_get, "")                                                   \
23631 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23632 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23633 _(one_l2_arp_bd_get, "")                                                \
23634 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23635 _(one_stats_enable_disable, "enable|disalbe")                           \
23636 _(show_one_stats_enable_disable, "")                                    \
23637 _(one_eid_table_vni_dump, "")                                           \
23638 _(one_eid_table_map_dump, "l2|l3")                                      \
23639 _(one_map_resolver_dump, "")                                            \
23640 _(one_map_server_dump, "")                                              \
23641 _(one_adjacencies_get, "vni <vni>")                                     \
23642 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23643 _(show_one_rloc_probe_state, "")                                        \
23644 _(show_one_map_register_state, "")                                      \
23645 _(show_one_status, "")                                                  \
23646 _(one_stats_dump, "")                                                   \
23647 _(one_stats_flush, "")                                                  \
23648 _(one_get_map_request_itr_rlocs, "")                                    \
23649 _(one_map_register_set_ttl, "<ttl>")                                    \
23650 _(one_set_transport_protocol, "udp|api")                                \
23651 _(one_get_transport_protocol, "")                                       \
23652 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23653 _(one_show_xtr_mode, "")                                                \
23654 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23655 _(one_show_pitr_mode, "")                                               \
23656 _(one_enable_disable_petr_mode, "enable|disable")                       \
23657 _(one_show_petr_mode, "")                                               \
23658 _(show_one_nsh_mapping, "")                                             \
23659 _(show_one_pitr, "")                                                    \
23660 _(show_one_use_petr, "")                                                \
23661 _(show_one_map_request_mode, "")                                        \
23662 _(show_one_map_register_ttl, "")                                        \
23663 _(show_one_map_register_fallback_threshold, "")                         \
23664 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23665                             " sw_if_index <sw_if_index> p <priority> "  \
23666                             "w <weight>] [del]")                        \
23667 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23668                         "iface <intf> | sw_if_index <sw_if_index> "     \
23669                         "p <priority> w <weight> [del]")                \
23670 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23671                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23672                          "locator-set <locator_name> [del]"             \
23673                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23674 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23675 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23676 _(lisp_enable_disable, "enable|disable")                                \
23677 _(lisp_map_register_enable_disable, "enable|disable")                   \
23678 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23679 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23680                                "[seid <seid>] "                         \
23681                                "rloc <locator> p <prio> "               \
23682                                "w <weight> [rloc <loc> ... ] "          \
23683                                "action <action> [del-all]")             \
23684 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23685                           "<local-eid>")                                \
23686 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23687 _(lisp_use_petr, "<ip-address> | disable")                              \
23688 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23689 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23690 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23691 _(lisp_locator_set_dump, "[local | remote]")                            \
23692 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23693 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23694                        "[local] | [remote]")                            \
23695 _(lisp_eid_table_vni_dump, "")                                          \
23696 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23697 _(lisp_map_resolver_dump, "")                                           \
23698 _(lisp_map_server_dump, "")                                             \
23699 _(lisp_adjacencies_get, "vni <vni>")                                    \
23700 _(gpe_fwd_entry_vnis_get, "")                                           \
23701 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23702 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23703                                 "[table <table-id>]")                   \
23704 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23705 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23706 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23707 _(gpe_get_encap_mode, "")                                               \
23708 _(lisp_gpe_add_del_iface, "up|down")                                    \
23709 _(lisp_gpe_enable_disable, "enable|disable")                            \
23710 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23711   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23712 _(show_lisp_rloc_probe_state, "")                                       \
23713 _(show_lisp_map_register_state, "")                                     \
23714 _(show_lisp_status, "")                                                 \
23715 _(lisp_get_map_request_itr_rlocs, "")                                   \
23716 _(show_lisp_pitr, "")                                                   \
23717 _(show_lisp_use_petr, "")                                               \
23718 _(show_lisp_map_request_mode, "")                                       \
23719 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23720 _(af_packet_delete, "name <host interface name>")                       \
23721 _(af_packet_dump, "")                                                   \
23722 _(policer_add_del, "name <policer name> <params> [del]")                \
23723 _(policer_dump, "[name <policer name>]")                                \
23724 _(policer_classify_set_interface,                                       \
23725   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23726   "  [l2-table <nn>] [del]")                                            \
23727 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23728 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23729     "[master|slave]")                                                   \
23730 _(netmap_delete, "name <interface name>")                               \
23731 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23732 _(mpls_fib_dump, "")                                                    \
23733 _(classify_table_ids, "")                                               \
23734 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23735 _(classify_table_info, "table_id <nn>")                                 \
23736 _(classify_session_dump, "table_id <nn>")                               \
23737 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23738     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23739     "[template_interval <nn>] [udp_checksum]")                          \
23740 _(ipfix_exporter_dump, "")                                              \
23741 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23742 _(ipfix_classify_stream_dump, "")                                       \
23743 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23744 _(ipfix_classify_table_dump, "")                                        \
23745 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23746 _(sw_interface_span_dump, "[l2]")                                           \
23747 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23748 _(pg_create_interface, "if_id <nn>")                                    \
23749 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23750 _(pg_enable_disable, "[stream <id>] disable")                           \
23751 _(ip_source_and_port_range_check_add_del,                               \
23752   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23753 _(ip_source_and_port_range_check_interface_add_del,                     \
23754   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23755   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23756 _(ipsec_gre_add_del_tunnel,                                             \
23757   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23758 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23759 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23760 _(l2_interface_pbb_tag_rewrite,                                         \
23761   "<intfc> | sw_if_index <nn> \n"                                       \
23762   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23763   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23764 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23765 _(flow_classify_set_interface,                                          \
23766   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23767 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23768 _(ip_fib_dump, "")                                                      \
23769 _(ip_mfib_dump, "")                                                     \
23770 _(ip6_fib_dump, "")                                                     \
23771 _(ip6_mfib_dump, "")                                                    \
23772 _(feature_enable_disable, "arc_name <arc_name> "                        \
23773   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23774 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23775 "[disable]")                                                            \
23776 _(l2_xconnect_dump, "")                                                 \
23777 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23778 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23779 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23780 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23781 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23782 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23783 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23784   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23785 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23786 _(sock_init_shm, "size <nnn>")                                          \
23787 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23788 _(dns_enable_disable, "[enable][disable]")                              \
23789 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23790 _(dns_resolve_name, "<hostname>")                                       \
23791 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23792 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23793 _(dns_resolve_name, "<hostname>")                                       \
23794 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23795   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23796 _(session_rules_dump, "")                                               \
23797 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23798 _(output_acl_set_interface,                                             \
23799   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23800   "  [l2-table <nn>] [del]")                                            \
23801 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23802
23803 /* List of command functions, CLI names map directly to functions */
23804 #define foreach_cli_function                                    \
23805 _(comment, "usage: comment <ignore-rest-of-line>")              \
23806 _(dump_interface_table, "usage: dump_interface_table")          \
23807 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23808 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23809 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23810 _(dump_stats_table, "usage: dump_stats_table")                  \
23811 _(dump_macro_table, "usage: dump_macro_table ")                 \
23812 _(dump_node_table, "usage: dump_node_table")                    \
23813 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23814 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23815 _(echo, "usage: echo <message>")                                \
23816 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23817 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23818 _(help, "usage: help")                                          \
23819 _(q, "usage: quit")                                             \
23820 _(quit, "usage: quit")                                          \
23821 _(search_node_table, "usage: search_node_table <name>...")      \
23822 _(set, "usage: set <variable-name> <value>")                    \
23823 _(script, "usage: script <file-name>")                          \
23824 _(unset, "usage: unset <variable-name>")
23825 #define _(N,n)                                  \
23826     static void vl_api_##n##_t_handler_uni      \
23827     (vl_api_##n##_t * mp)                       \
23828     {                                           \
23829         vat_main_t * vam = &vat_main;           \
23830         if (vam->json_output) {                 \
23831             vl_api_##n##_t_handler_json(mp);    \
23832         } else {                                \
23833             vl_api_##n##_t_handler(mp);         \
23834         }                                       \
23835     }
23836 foreach_vpe_api_reply_msg;
23837 #if VPP_API_TEST_BUILTIN == 0
23838 foreach_standalone_reply_msg;
23839 #endif
23840 #undef _
23841
23842 void
23843 vat_api_hookup (vat_main_t * vam)
23844 {
23845 #define _(N,n)                                                  \
23846     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23847                            vl_api_##n##_t_handler_uni,          \
23848                            vl_noop_handler,                     \
23849                            vl_api_##n##_t_endian,               \
23850                            vl_api_##n##_t_print,                \
23851                            sizeof(vl_api_##n##_t), 1);
23852   foreach_vpe_api_reply_msg;
23853 #if VPP_API_TEST_BUILTIN == 0
23854   foreach_standalone_reply_msg;
23855 #endif
23856 #undef _
23857
23858 #if (VPP_API_TEST_BUILTIN==0)
23859   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23860
23861   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23862
23863   vam->function_by_name = hash_create_string (0, sizeof (uword));
23864
23865   vam->help_by_name = hash_create_string (0, sizeof (uword));
23866 #endif
23867
23868   /* API messages we can send */
23869 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23870   foreach_vpe_api_msg;
23871 #undef _
23872
23873   /* Help strings */
23874 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23875   foreach_vpe_api_msg;
23876 #undef _
23877
23878   /* CLI functions */
23879 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23880   foreach_cli_function;
23881 #undef _
23882
23883   /* Help strings */
23884 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23885   foreach_cli_function;
23886 #undef _
23887 }
23888
23889 #if VPP_API_TEST_BUILTIN
23890 static clib_error_t *
23891 vat_api_hookup_shim (vlib_main_t * vm)
23892 {
23893   vat_api_hookup (&vat_main);
23894   return 0;
23895 }
23896
23897 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23898 #endif
23899
23900 /*
23901  * fd.io coding-style-patch-verification: ON
23902  *
23903  * Local Variables:
23904  * eval: (c-set-style "gnu")
23905  * End:
23906  */