export counters in a memfd segment
[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->lease.is_ipv6 ? "ipv6" : "ipv4",
2673           mp->lease.hostname,
2674           format_ip4_address, &mp->lease.host_address,
2675           format_ip4_address, &mp->lease.router_address,
2676           format_ethernet_address, mp->lease.host_mac);
2677 }
2678
2679 static void vl_api_dhcp_compl_event_t_handler_json
2680   (vl_api_dhcp_compl_event_t * mp)
2681 {
2682   /* JSON output not supported */
2683 }
2684
2685 static void
2686 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2687                               u32 counter)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   static u64 default_counter = 0;
2691
2692   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2693                            NULL);
2694   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2695                            sw_if_index, default_counter);
2696   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2697 }
2698
2699 static void
2700 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2701                                 interface_counter_t counter)
2702 {
2703   vat_main_t *vam = &vat_main;
2704   static interface_counter_t default_counter = { 0, };
2705
2706   vec_validate_init_empty (vam->combined_interface_counters,
2707                            vnet_counter_type, NULL);
2708   vec_validate_init_empty (vam->combined_interface_counters
2709                            [vnet_counter_type], sw_if_index, default_counter);
2710   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2711 }
2712
2713 static void vl_api_vnet_interface_simple_counters_t_handler
2714   (vl_api_vnet_interface_simple_counters_t * mp)
2715 {
2716   /* not supported */
2717 }
2718
2719 static void vl_api_vnet_interface_combined_counters_t_handler
2720   (vl_api_vnet_interface_combined_counters_t * mp)
2721 {
2722   /* not supported */
2723 }
2724
2725 static void vl_api_vnet_interface_simple_counters_t_handler_json
2726   (vl_api_vnet_interface_simple_counters_t * mp)
2727 {
2728   u64 *v_packets;
2729   u64 packets;
2730   u32 count;
2731   u32 first_sw_if_index;
2732   int i;
2733
2734   count = ntohl (mp->count);
2735   first_sw_if_index = ntohl (mp->first_sw_if_index);
2736
2737   v_packets = (u64 *) & mp->data;
2738   for (i = 0; i < count; i++)
2739     {
2740       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2741       set_simple_interface_counter (mp->vnet_counter_type,
2742                                     first_sw_if_index + i, packets);
2743       v_packets++;
2744     }
2745 }
2746
2747 static void vl_api_vnet_interface_combined_counters_t_handler_json
2748   (vl_api_vnet_interface_combined_counters_t * mp)
2749 {
2750   interface_counter_t counter;
2751   vlib_counter_t *v;
2752   u32 first_sw_if_index;
2753   int i;
2754   u32 count;
2755
2756   count = ntohl (mp->count);
2757   first_sw_if_index = ntohl (mp->first_sw_if_index);
2758
2759   v = (vlib_counter_t *) & mp->data;
2760   for (i = 0; i < count; i++)
2761     {
2762       counter.packets =
2763         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2764       counter.bytes =
2765         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2766       set_combined_interface_counter (mp->vnet_counter_type,
2767                                       first_sw_if_index + i, counter);
2768       v++;
2769     }
2770 }
2771
2772 static u32
2773 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2774 {
2775   vat_main_t *vam = &vat_main;
2776   u32 i;
2777
2778   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2779     {
2780       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2781         {
2782           return i;
2783         }
2784     }
2785   return ~0;
2786 }
2787
2788 static u32
2789 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   u32 i;
2793
2794   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2795     {
2796       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2797         {
2798           return i;
2799         }
2800     }
2801   return ~0;
2802 }
2803
2804 static void vl_api_vnet_ip4_fib_counters_t_handler
2805   (vl_api_vnet_ip4_fib_counters_t * mp)
2806 {
2807   /* not supported */
2808 }
2809
2810 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2811   (vl_api_vnet_ip4_fib_counters_t * mp)
2812 {
2813   vat_main_t *vam = &vat_main;
2814   vl_api_ip4_fib_counter_t *v;
2815   ip4_fib_counter_t *counter;
2816   struct in_addr ip4;
2817   u32 vrf_id;
2818   u32 vrf_index;
2819   u32 count;
2820   int i;
2821
2822   vrf_id = ntohl (mp->vrf_id);
2823   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2824   if (~0 == vrf_index)
2825     {
2826       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2827       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2828       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2829       vec_validate (vam->ip4_fib_counters, vrf_index);
2830       vam->ip4_fib_counters[vrf_index] = NULL;
2831     }
2832
2833   vec_free (vam->ip4_fib_counters[vrf_index]);
2834   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2835   count = ntohl (mp->count);
2836   for (i = 0; i < count; i++)
2837     {
2838       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2839       counter = &vam->ip4_fib_counters[vrf_index][i];
2840       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2841       counter->address = ip4;
2842       counter->address_length = v->address_length;
2843       counter->packets = clib_net_to_host_u64 (v->packets);
2844       counter->bytes = clib_net_to_host_u64 (v->bytes);
2845       v++;
2846     }
2847 }
2848
2849 static void vl_api_vnet_ip4_nbr_counters_t_handler
2850   (vl_api_vnet_ip4_nbr_counters_t * mp)
2851 {
2852   /* not supported */
2853 }
2854
2855 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2856   (vl_api_vnet_ip4_nbr_counters_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   vl_api_ip4_nbr_counter_t *v;
2860   ip4_nbr_counter_t *counter;
2861   u32 sw_if_index;
2862   u32 count;
2863   int i;
2864
2865   sw_if_index = ntohl (mp->sw_if_index);
2866   count = ntohl (mp->count);
2867   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2868
2869   if (mp->begin)
2870     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2871
2872   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2873   for (i = 0; i < count; i++)
2874     {
2875       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2876       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2877       counter->address.s_addr = v->address;
2878       counter->packets = clib_net_to_host_u64 (v->packets);
2879       counter->bytes = clib_net_to_host_u64 (v->bytes);
2880       counter->linkt = v->link_type;
2881       v++;
2882     }
2883 }
2884
2885 static void vl_api_vnet_ip6_fib_counters_t_handler
2886   (vl_api_vnet_ip6_fib_counters_t * mp)
2887 {
2888   /* not supported */
2889 }
2890
2891 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2892   (vl_api_vnet_ip6_fib_counters_t * mp)
2893 {
2894   vat_main_t *vam = &vat_main;
2895   vl_api_ip6_fib_counter_t *v;
2896   ip6_fib_counter_t *counter;
2897   struct in6_addr ip6;
2898   u32 vrf_id;
2899   u32 vrf_index;
2900   u32 count;
2901   int i;
2902
2903   vrf_id = ntohl (mp->vrf_id);
2904   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2905   if (~0 == vrf_index)
2906     {
2907       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2908       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2909       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2910       vec_validate (vam->ip6_fib_counters, vrf_index);
2911       vam->ip6_fib_counters[vrf_index] = NULL;
2912     }
2913
2914   vec_free (vam->ip6_fib_counters[vrf_index]);
2915   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2916   count = ntohl (mp->count);
2917   for (i = 0; i < count; i++)
2918     {
2919       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2920       counter = &vam->ip6_fib_counters[vrf_index][i];
2921       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2922       counter->address = ip6;
2923       counter->address_length = v->address_length;
2924       counter->packets = clib_net_to_host_u64 (v->packets);
2925       counter->bytes = clib_net_to_host_u64 (v->bytes);
2926       v++;
2927     }
2928 }
2929
2930 static void vl_api_vnet_ip6_nbr_counters_t_handler
2931   (vl_api_vnet_ip6_nbr_counters_t * mp)
2932 {
2933   /* not supported */
2934 }
2935
2936 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2937   (vl_api_vnet_ip6_nbr_counters_t * mp)
2938 {
2939   vat_main_t *vam = &vat_main;
2940   vl_api_ip6_nbr_counter_t *v;
2941   ip6_nbr_counter_t *counter;
2942   struct in6_addr ip6;
2943   u32 sw_if_index;
2944   u32 count;
2945   int i;
2946
2947   sw_if_index = ntohl (mp->sw_if_index);
2948   count = ntohl (mp->count);
2949   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2950
2951   if (mp->begin)
2952     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2953
2954   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2955   for (i = 0; i < count; i++)
2956     {
2957       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2958       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2959       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2960       counter->address = ip6;
2961       counter->packets = clib_net_to_host_u64 (v->packets);
2962       counter->bytes = clib_net_to_host_u64 (v->bytes);
2963       v++;
2964     }
2965 }
2966
2967 static void vl_api_get_first_msg_id_reply_t_handler
2968   (vl_api_get_first_msg_id_reply_t * mp)
2969 {
2970   vat_main_t *vam = &vat_main;
2971   i32 retval = ntohl (mp->retval);
2972
2973   if (vam->async_mode)
2974     {
2975       vam->async_errors += (retval < 0);
2976     }
2977   else
2978     {
2979       vam->retval = retval;
2980       vam->result_ready = 1;
2981     }
2982   if (retval >= 0)
2983     {
2984       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2985     }
2986 }
2987
2988 static void vl_api_get_first_msg_id_reply_t_handler_json
2989   (vl_api_get_first_msg_id_reply_t * mp)
2990 {
2991   vat_main_t *vam = &vat_main;
2992   vat_json_node_t node;
2993
2994   vat_json_init_object (&node);
2995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2996   vat_json_object_add_uint (&node, "first_msg_id",
2997                             (uint) ntohs (mp->first_msg_id));
2998
2999   vat_json_print (vam->ofp, &node);
3000   vat_json_free (&node);
3001
3002   vam->retval = ntohl (mp->retval);
3003   vam->result_ready = 1;
3004 }
3005
3006 static void vl_api_get_node_graph_reply_t_handler
3007   (vl_api_get_node_graph_reply_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   api_main_t *am = &api_main;
3011   i32 retval = ntohl (mp->retval);
3012   u8 *pvt_copy, *reply;
3013   void *oldheap;
3014   vlib_node_t *node;
3015   int i;
3016
3017   if (vam->async_mode)
3018     {
3019       vam->async_errors += (retval < 0);
3020     }
3021   else
3022     {
3023       vam->retval = retval;
3024       vam->result_ready = 1;
3025     }
3026
3027   /* "Should never happen..." */
3028   if (retval != 0)
3029     return;
3030
3031   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3032   pvt_copy = vec_dup (reply);
3033
3034   /* Toss the shared-memory original... */
3035   pthread_mutex_lock (&am->vlib_rp->mutex);
3036   oldheap = svm_push_data_heap (am->vlib_rp);
3037
3038   vec_free (reply);
3039
3040   svm_pop_heap (oldheap);
3041   pthread_mutex_unlock (&am->vlib_rp->mutex);
3042
3043   if (vam->graph_nodes)
3044     {
3045       hash_free (vam->graph_node_index_by_name);
3046
3047       for (i = 0; i < vec_len (vam->graph_nodes); i++)
3048         {
3049           node = vam->graph_nodes[i];
3050           vec_free (node->name);
3051           vec_free (node->next_nodes);
3052           vec_free (node);
3053         }
3054       vec_free (vam->graph_nodes);
3055     }
3056
3057   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3058   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3059   vec_free (pvt_copy);
3060
3061   for (i = 0; i < vec_len (vam->graph_nodes); i++)
3062     {
3063       node = vam->graph_nodes[i];
3064       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3065     }
3066 }
3067
3068 static void vl_api_get_node_graph_reply_t_handler_json
3069   (vl_api_get_node_graph_reply_t * mp)
3070 {
3071   vat_main_t *vam = &vat_main;
3072   api_main_t *am = &api_main;
3073   void *oldheap;
3074   vat_json_node_t node;
3075   u8 *reply;
3076
3077   /* $$$$ make this real? */
3078   vat_json_init_object (&node);
3079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3080   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3081
3082   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3083
3084   /* Toss the shared-memory original... */
3085   pthread_mutex_lock (&am->vlib_rp->mutex);
3086   oldheap = svm_push_data_heap (am->vlib_rp);
3087
3088   vec_free (reply);
3089
3090   svm_pop_heap (oldheap);
3091   pthread_mutex_unlock (&am->vlib_rp->mutex);
3092
3093   vat_json_print (vam->ofp, &node);
3094   vat_json_free (&node);
3095
3096   vam->retval = ntohl (mp->retval);
3097   vam->result_ready = 1;
3098 }
3099
3100 static void
3101 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3102 {
3103   vat_main_t *vam = &vat_main;
3104   u8 *s = 0;
3105
3106   if (mp->local)
3107     {
3108       s = format (s, "%=16d%=16d%=16d",
3109                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3110     }
3111   else
3112     {
3113       s = format (s, "%=16U%=16d%=16d",
3114                   mp->is_ipv6 ? format_ip6_address :
3115                   format_ip4_address,
3116                   mp->ip_address, mp->priority, mp->weight);
3117     }
3118
3119   print (vam->ofp, "%v", s);
3120   vec_free (s);
3121 }
3122
3123 static void
3124 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3125 {
3126   vat_main_t *vam = &vat_main;
3127   vat_json_node_t *node = NULL;
3128   struct in6_addr ip6;
3129   struct in_addr ip4;
3130
3131   if (VAT_JSON_ARRAY != vam->json_tree.type)
3132     {
3133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3134       vat_json_init_array (&vam->json_tree);
3135     }
3136   node = vat_json_array_add (&vam->json_tree);
3137   vat_json_init_object (node);
3138
3139   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3140   vat_json_object_add_uint (node, "priority", mp->priority);
3141   vat_json_object_add_uint (node, "weight", mp->weight);
3142
3143   if (mp->local)
3144     vat_json_object_add_uint (node, "sw_if_index",
3145                               clib_net_to_host_u32 (mp->sw_if_index));
3146   else
3147     {
3148       if (mp->is_ipv6)
3149         {
3150           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3151           vat_json_object_add_ip6 (node, "address", ip6);
3152         }
3153       else
3154         {
3155           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3156           vat_json_object_add_ip4 (node, "address", ip4);
3157         }
3158     }
3159 }
3160
3161 static void
3162 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3163                                           mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166   u8 *ls_name = 0;
3167
3168   ls_name = format (0, "%s", mp->ls_name);
3169
3170   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3171          ls_name);
3172   vec_free (ls_name);
3173 }
3174
3175 static void
3176   vl_api_one_locator_set_details_t_handler_json
3177   (vl_api_one_locator_set_details_t * mp)
3178 {
3179   vat_main_t *vam = &vat_main;
3180   vat_json_node_t *node = 0;
3181   u8 *ls_name = 0;
3182
3183   ls_name = format (0, "%s", mp->ls_name);
3184   vec_add1 (ls_name, 0);
3185
3186   if (VAT_JSON_ARRAY != vam->json_tree.type)
3187     {
3188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3189       vat_json_init_array (&vam->json_tree);
3190     }
3191   node = vat_json_array_add (&vam->json_tree);
3192
3193   vat_json_init_object (node);
3194   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3195   vat_json_object_add_uint (node, "ls_index",
3196                             clib_net_to_host_u32 (mp->ls_index));
3197   vec_free (ls_name);
3198 }
3199
3200 typedef struct
3201 {
3202   u32 spi;
3203   u8 si;
3204 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3205
3206 uword
3207 unformat_nsh_address (unformat_input_t * input, va_list * args)
3208 {
3209   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3210   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3211 }
3212
3213 u8 *
3214 format_nsh_address_vat (u8 * s, va_list * args)
3215 {
3216   nsh_t *a = va_arg (*args, nsh_t *);
3217   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3218 }
3219
3220 static u8 *
3221 format_lisp_flat_eid (u8 * s, va_list * args)
3222 {
3223   u32 type = va_arg (*args, u32);
3224   u8 *eid = va_arg (*args, u8 *);
3225   u32 eid_len = va_arg (*args, u32);
3226
3227   switch (type)
3228     {
3229     case 0:
3230       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3231     case 1:
3232       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3233     case 2:
3234       return format (s, "%U", format_ethernet_address, eid);
3235     case 3:
3236       return format (s, "%U", format_nsh_address_vat, eid);
3237     }
3238   return 0;
3239 }
3240
3241 static u8 *
3242 format_lisp_eid_vat (u8 * s, va_list * args)
3243 {
3244   u32 type = va_arg (*args, u32);
3245   u8 *eid = va_arg (*args, u8 *);
3246   u32 eid_len = va_arg (*args, u32);
3247   u8 *seid = va_arg (*args, u8 *);
3248   u32 seid_len = va_arg (*args, u32);
3249   u32 is_src_dst = va_arg (*args, u32);
3250
3251   if (is_src_dst)
3252     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3253
3254   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3255
3256   return s;
3257 }
3258
3259 static void
3260 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3261 {
3262   vat_main_t *vam = &vat_main;
3263   u8 *s = 0, *eid = 0;
3264
3265   if (~0 == mp->locator_set_index)
3266     s = format (0, "action: %d", mp->action);
3267   else
3268     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3269
3270   eid = format (0, "%U", format_lisp_eid_vat,
3271                 mp->eid_type,
3272                 mp->eid,
3273                 mp->eid_prefix_len,
3274                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3275   vec_add1 (eid, 0);
3276
3277   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3278          clib_net_to_host_u32 (mp->vni),
3279          eid,
3280          mp->is_local ? "local" : "remote",
3281          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3282          clib_net_to_host_u16 (mp->key_id), mp->key);
3283
3284   vec_free (s);
3285   vec_free (eid);
3286 }
3287
3288 static void
3289 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3290                                              * mp)
3291 {
3292   vat_main_t *vam = &vat_main;
3293   vat_json_node_t *node = 0;
3294   u8 *eid = 0;
3295
3296   if (VAT_JSON_ARRAY != vam->json_tree.type)
3297     {
3298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3299       vat_json_init_array (&vam->json_tree);
3300     }
3301   node = vat_json_array_add (&vam->json_tree);
3302
3303   vat_json_init_object (node);
3304   if (~0 == mp->locator_set_index)
3305     vat_json_object_add_uint (node, "action", mp->action);
3306   else
3307     vat_json_object_add_uint (node, "locator_set_index",
3308                               clib_net_to_host_u32 (mp->locator_set_index));
3309
3310   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3311   if (mp->eid_type == 3)
3312     {
3313       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3314       vat_json_init_object (nsh_json);
3315       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3316       vat_json_object_add_uint (nsh_json, "spi",
3317                                 clib_net_to_host_u32 (nsh->spi));
3318       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3319     }
3320   else
3321     {
3322       eid = format (0, "%U", format_lisp_eid_vat,
3323                     mp->eid_type,
3324                     mp->eid,
3325                     mp->eid_prefix_len,
3326                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3327       vec_add1 (eid, 0);
3328       vat_json_object_add_string_copy (node, "eid", eid);
3329       vec_free (eid);
3330     }
3331   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3332   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3333   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3334
3335   if (mp->key_id)
3336     {
3337       vat_json_object_add_uint (node, "key_id",
3338                                 clib_net_to_host_u16 (mp->key_id));
3339       vat_json_object_add_string_copy (node, "key", mp->key);
3340     }
3341 }
3342
3343 static void
3344 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3345 {
3346   vat_main_t *vam = &vat_main;
3347   u8 *seid = 0, *deid = 0;
3348   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3349
3350   deid = format (0, "%U", format_lisp_eid_vat,
3351                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3352
3353   seid = format (0, "%U", format_lisp_eid_vat,
3354                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3355
3356   vec_add1 (deid, 0);
3357   vec_add1 (seid, 0);
3358
3359   if (mp->is_ip4)
3360     format_ip_address_fcn = format_ip4_address;
3361   else
3362     format_ip_address_fcn = format_ip6_address;
3363
3364
3365   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3366          clib_net_to_host_u32 (mp->vni),
3367          seid, deid,
3368          format_ip_address_fcn, mp->lloc,
3369          format_ip_address_fcn, mp->rloc,
3370          clib_net_to_host_u32 (mp->pkt_count),
3371          clib_net_to_host_u32 (mp->bytes));
3372
3373   vec_free (deid);
3374   vec_free (seid);
3375 }
3376
3377 static void
3378 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3379 {
3380   struct in6_addr ip6;
3381   struct in_addr ip4;
3382   vat_main_t *vam = &vat_main;
3383   vat_json_node_t *node = 0;
3384   u8 *deid = 0, *seid = 0;
3385
3386   if (VAT_JSON_ARRAY != vam->json_tree.type)
3387     {
3388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3389       vat_json_init_array (&vam->json_tree);
3390     }
3391   node = vat_json_array_add (&vam->json_tree);
3392
3393   vat_json_init_object (node);
3394   deid = format (0, "%U", format_lisp_eid_vat,
3395                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3396
3397   seid = format (0, "%U", format_lisp_eid_vat,
3398                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3399
3400   vec_add1 (deid, 0);
3401   vec_add1 (seid, 0);
3402
3403   vat_json_object_add_string_copy (node, "seid", seid);
3404   vat_json_object_add_string_copy (node, "deid", deid);
3405   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3406
3407   if (mp->is_ip4)
3408     {
3409       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3410       vat_json_object_add_ip4 (node, "lloc", ip4);
3411       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3412       vat_json_object_add_ip4 (node, "rloc", ip4);
3413     }
3414   else
3415     {
3416       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3417       vat_json_object_add_ip6 (node, "lloc", ip6);
3418       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3419       vat_json_object_add_ip6 (node, "rloc", ip6);
3420     }
3421   vat_json_object_add_uint (node, "pkt_count",
3422                             clib_net_to_host_u32 (mp->pkt_count));
3423   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3424
3425   vec_free (deid);
3426   vec_free (seid);
3427 }
3428
3429 static void
3430   vl_api_one_eid_table_map_details_t_handler
3431   (vl_api_one_eid_table_map_details_t * mp)
3432 {
3433   vat_main_t *vam = &vat_main;
3434
3435   u8 *line = format (0, "%=10d%=10d",
3436                      clib_net_to_host_u32 (mp->vni),
3437                      clib_net_to_host_u32 (mp->dp_table));
3438   print (vam->ofp, "%v", line);
3439   vec_free (line);
3440 }
3441
3442 static void
3443   vl_api_one_eid_table_map_details_t_handler_json
3444   (vl_api_one_eid_table_map_details_t * mp)
3445 {
3446   vat_main_t *vam = &vat_main;
3447   vat_json_node_t *node = NULL;
3448
3449   if (VAT_JSON_ARRAY != vam->json_tree.type)
3450     {
3451       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3452       vat_json_init_array (&vam->json_tree);
3453     }
3454   node = vat_json_array_add (&vam->json_tree);
3455   vat_json_init_object (node);
3456   vat_json_object_add_uint (node, "dp_table",
3457                             clib_net_to_host_u32 (mp->dp_table));
3458   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3459 }
3460
3461 static void
3462   vl_api_one_eid_table_vni_details_t_handler
3463   (vl_api_one_eid_table_vni_details_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466
3467   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3468   print (vam->ofp, "%v", line);
3469   vec_free (line);
3470 }
3471
3472 static void
3473   vl_api_one_eid_table_vni_details_t_handler_json
3474   (vl_api_one_eid_table_vni_details_t * mp)
3475 {
3476   vat_main_t *vam = &vat_main;
3477   vat_json_node_t *node = NULL;
3478
3479   if (VAT_JSON_ARRAY != vam->json_tree.type)
3480     {
3481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3482       vat_json_init_array (&vam->json_tree);
3483     }
3484   node = vat_json_array_add (&vam->json_tree);
3485   vat_json_init_object (node);
3486   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3487 }
3488
3489 static void
3490   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3491   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3492 {
3493   vat_main_t *vam = &vat_main;
3494   int retval = clib_net_to_host_u32 (mp->retval);
3495
3496   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3497   print (vam->ofp, "fallback threshold value: %d", mp->value);
3498
3499   vam->retval = retval;
3500   vam->result_ready = 1;
3501 }
3502
3503 static void
3504   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3505   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3506 {
3507   vat_main_t *vam = &vat_main;
3508   vat_json_node_t _node, *node = &_node;
3509   int retval = clib_net_to_host_u32 (mp->retval);
3510
3511   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3512   vat_json_init_object (node);
3513   vat_json_object_add_uint (node, "value", mp->value);
3514
3515   vat_json_print (vam->ofp, node);
3516   vat_json_free (node);
3517
3518   vam->retval = retval;
3519   vam->result_ready = 1;
3520 }
3521
3522 static void
3523   vl_api_show_one_map_register_state_reply_t_handler
3524   (vl_api_show_one_map_register_state_reply_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   int retval = clib_net_to_host_u32 (mp->retval);
3528
3529   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3530
3531   vam->retval = retval;
3532   vam->result_ready = 1;
3533 }
3534
3535 static void
3536   vl_api_show_one_map_register_state_reply_t_handler_json
3537   (vl_api_show_one_map_register_state_reply_t * mp)
3538 {
3539   vat_main_t *vam = &vat_main;
3540   vat_json_node_t _node, *node = &_node;
3541   int retval = clib_net_to_host_u32 (mp->retval);
3542
3543   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3544
3545   vat_json_init_object (node);
3546   vat_json_object_add_string_copy (node, "state", s);
3547
3548   vat_json_print (vam->ofp, node);
3549   vat_json_free (node);
3550
3551   vam->retval = retval;
3552   vam->result_ready = 1;
3553   vec_free (s);
3554 }
3555
3556 static void
3557   vl_api_show_one_rloc_probe_state_reply_t_handler
3558   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3559 {
3560   vat_main_t *vam = &vat_main;
3561   int retval = clib_net_to_host_u32 (mp->retval);
3562
3563   if (retval)
3564     goto end;
3565
3566   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3567 end:
3568   vam->retval = retval;
3569   vam->result_ready = 1;
3570 }
3571
3572 static void
3573   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3574   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3575 {
3576   vat_main_t *vam = &vat_main;
3577   vat_json_node_t _node, *node = &_node;
3578   int retval = clib_net_to_host_u32 (mp->retval);
3579
3580   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3581   vat_json_init_object (node);
3582   vat_json_object_add_string_copy (node, "state", s);
3583
3584   vat_json_print (vam->ofp, node);
3585   vat_json_free (node);
3586
3587   vam->retval = retval;
3588   vam->result_ready = 1;
3589   vec_free (s);
3590 }
3591
3592 static void
3593   vl_api_show_one_stats_enable_disable_reply_t_handler
3594   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3595 {
3596   vat_main_t *vam = &vat_main;
3597   int retval = clib_net_to_host_u32 (mp->retval);
3598
3599   if (retval)
3600     goto end;
3601
3602   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3603 end:
3604   vam->retval = retval;
3605   vam->result_ready = 1;
3606 }
3607
3608 static void
3609   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3610   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3611 {
3612   vat_main_t *vam = &vat_main;
3613   vat_json_node_t _node, *node = &_node;
3614   int retval = clib_net_to_host_u32 (mp->retval);
3615
3616   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3617   vat_json_init_object (node);
3618   vat_json_object_add_string_copy (node, "state", s);
3619
3620   vat_json_print (vam->ofp, node);
3621   vat_json_free (node);
3622
3623   vam->retval = retval;
3624   vam->result_ready = 1;
3625   vec_free (s);
3626 }
3627
3628 static void
3629 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3630 {
3631   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3632   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3633   e->vni = clib_net_to_host_u32 (e->vni);
3634 }
3635
3636 static void
3637   gpe_fwd_entries_get_reply_t_net_to_host
3638   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3639 {
3640   u32 i;
3641
3642   mp->count = clib_net_to_host_u32 (mp->count);
3643   for (i = 0; i < mp->count; i++)
3644     {
3645       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3646     }
3647 }
3648
3649 static u8 *
3650 format_gpe_encap_mode (u8 * s, va_list * args)
3651 {
3652   u32 mode = va_arg (*args, u32);
3653
3654   switch (mode)
3655     {
3656     case 0:
3657       return format (s, "lisp");
3658     case 1:
3659       return format (s, "vxlan");
3660     }
3661   return 0;
3662 }
3663
3664 static void
3665   vl_api_gpe_get_encap_mode_reply_t_handler
3666   (vl_api_gpe_get_encap_mode_reply_t * mp)
3667 {
3668   vat_main_t *vam = &vat_main;
3669
3670   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3671   vam->retval = ntohl (mp->retval);
3672   vam->result_ready = 1;
3673 }
3674
3675 static void
3676   vl_api_gpe_get_encap_mode_reply_t_handler_json
3677   (vl_api_gpe_get_encap_mode_reply_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680   vat_json_node_t node;
3681
3682   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3683   vec_add1 (encap_mode, 0);
3684
3685   vat_json_init_object (&node);
3686   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3687
3688   vec_free (encap_mode);
3689   vat_json_print (vam->ofp, &node);
3690   vat_json_free (&node);
3691
3692   vam->retval = ntohl (mp->retval);
3693   vam->result_ready = 1;
3694 }
3695
3696 static void
3697   vl_api_gpe_fwd_entry_path_details_t_handler
3698   (vl_api_gpe_fwd_entry_path_details_t * mp)
3699 {
3700   vat_main_t *vam = &vat_main;
3701   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3702
3703   if (mp->lcl_loc.is_ip4)
3704     format_ip_address_fcn = format_ip4_address;
3705   else
3706     format_ip_address_fcn = format_ip6_address;
3707
3708   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3709          format_ip_address_fcn, &mp->lcl_loc,
3710          format_ip_address_fcn, &mp->rmt_loc);
3711 }
3712
3713 static void
3714 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3715 {
3716   struct in6_addr ip6;
3717   struct in_addr ip4;
3718
3719   if (loc->is_ip4)
3720     {
3721       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3722       vat_json_object_add_ip4 (n, "address", ip4);
3723     }
3724   else
3725     {
3726       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3727       vat_json_object_add_ip6 (n, "address", ip6);
3728     }
3729   vat_json_object_add_uint (n, "weight", loc->weight);
3730 }
3731
3732 static void
3733   vl_api_gpe_fwd_entry_path_details_t_handler_json
3734   (vl_api_gpe_fwd_entry_path_details_t * mp)
3735 {
3736   vat_main_t *vam = &vat_main;
3737   vat_json_node_t *node = NULL;
3738   vat_json_node_t *loc_node;
3739
3740   if (VAT_JSON_ARRAY != vam->json_tree.type)
3741     {
3742       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3743       vat_json_init_array (&vam->json_tree);
3744     }
3745   node = vat_json_array_add (&vam->json_tree);
3746   vat_json_init_object (node);
3747
3748   loc_node = vat_json_object_add (node, "local_locator");
3749   vat_json_init_object (loc_node);
3750   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3751
3752   loc_node = vat_json_object_add (node, "remote_locator");
3753   vat_json_init_object (loc_node);
3754   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3755 }
3756
3757 static void
3758   vl_api_gpe_fwd_entries_get_reply_t_handler
3759   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3760 {
3761   vat_main_t *vam = &vat_main;
3762   u32 i;
3763   int retval = clib_net_to_host_u32 (mp->retval);
3764   vl_api_gpe_fwd_entry_t *e;
3765
3766   if (retval)
3767     goto end;
3768
3769   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3770
3771   for (i = 0; i < mp->count; i++)
3772     {
3773       e = &mp->entries[i];
3774       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3775              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3776              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3777     }
3778
3779 end:
3780   vam->retval = retval;
3781   vam->result_ready = 1;
3782 }
3783
3784 static void
3785   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3786   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3787 {
3788   u8 *s = 0;
3789   vat_main_t *vam = &vat_main;
3790   vat_json_node_t *e = 0, root;
3791   u32 i;
3792   int retval = clib_net_to_host_u32 (mp->retval);
3793   vl_api_gpe_fwd_entry_t *fwd;
3794
3795   if (retval)
3796     goto end;
3797
3798   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3799   vat_json_init_array (&root);
3800
3801   for (i = 0; i < mp->count; i++)
3802     {
3803       e = vat_json_array_add (&root);
3804       fwd = &mp->entries[i];
3805
3806       vat_json_init_object (e);
3807       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3808       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3809       vat_json_object_add_int (e, "vni", fwd->vni);
3810       vat_json_object_add_int (e, "action", fwd->action);
3811
3812       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3813                   fwd->leid_prefix_len);
3814       vec_add1 (s, 0);
3815       vat_json_object_add_string_copy (e, "leid", s);
3816       vec_free (s);
3817
3818       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3819                   fwd->reid_prefix_len);
3820       vec_add1 (s, 0);
3821       vat_json_object_add_string_copy (e, "reid", s);
3822       vec_free (s);
3823     }
3824
3825   vat_json_print (vam->ofp, &root);
3826   vat_json_free (&root);
3827
3828 end:
3829   vam->retval = retval;
3830   vam->result_ready = 1;
3831 }
3832
3833 static void
3834   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3835   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3836 {
3837   vat_main_t *vam = &vat_main;
3838   u32 i, n;
3839   int retval = clib_net_to_host_u32 (mp->retval);
3840   vl_api_gpe_native_fwd_rpath_t *r;
3841
3842   if (retval)
3843     goto end;
3844
3845   n = clib_net_to_host_u32 (mp->count);
3846
3847   for (i = 0; i < n; i++)
3848     {
3849       r = &mp->entries[i];
3850       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3851              clib_net_to_host_u32 (r->fib_index),
3852              clib_net_to_host_u32 (r->nh_sw_if_index),
3853              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3854     }
3855
3856 end:
3857   vam->retval = retval;
3858   vam->result_ready = 1;
3859 }
3860
3861 static void
3862   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3863   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3864 {
3865   vat_main_t *vam = &vat_main;
3866   vat_json_node_t root, *e;
3867   u32 i, n;
3868   int retval = clib_net_to_host_u32 (mp->retval);
3869   vl_api_gpe_native_fwd_rpath_t *r;
3870   u8 *s;
3871
3872   if (retval)
3873     goto end;
3874
3875   n = clib_net_to_host_u32 (mp->count);
3876   vat_json_init_array (&root);
3877
3878   for (i = 0; i < n; i++)
3879     {
3880       e = vat_json_array_add (&root);
3881       vat_json_init_object (e);
3882       r = &mp->entries[i];
3883       s =
3884         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3885                 r->nh_addr);
3886       vec_add1 (s, 0);
3887       vat_json_object_add_string_copy (e, "ip4", s);
3888       vec_free (s);
3889
3890       vat_json_object_add_uint (e, "fib_index",
3891                                 clib_net_to_host_u32 (r->fib_index));
3892       vat_json_object_add_uint (e, "nh_sw_if_index",
3893                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3894     }
3895
3896   vat_json_print (vam->ofp, &root);
3897   vat_json_free (&root);
3898
3899 end:
3900   vam->retval = retval;
3901   vam->result_ready = 1;
3902 }
3903
3904 static void
3905   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3906   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3907 {
3908   vat_main_t *vam = &vat_main;
3909   u32 i, n;
3910   int retval = clib_net_to_host_u32 (mp->retval);
3911
3912   if (retval)
3913     goto end;
3914
3915   n = clib_net_to_host_u32 (mp->count);
3916
3917   for (i = 0; i < n; i++)
3918     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3919
3920 end:
3921   vam->retval = retval;
3922   vam->result_ready = 1;
3923 }
3924
3925 static void
3926   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3927   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3928 {
3929   vat_main_t *vam = &vat_main;
3930   vat_json_node_t root;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933
3934   if (retval)
3935     goto end;
3936
3937   n = clib_net_to_host_u32 (mp->count);
3938   vat_json_init_array (&root);
3939
3940   for (i = 0; i < n; i++)
3941     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3942
3943   vat_json_print (vam->ofp, &root);
3944   vat_json_free (&root);
3945
3946 end:
3947   vam->retval = retval;
3948   vam->result_ready = 1;
3949 }
3950
3951 static void
3952   vl_api_one_ndp_entries_get_reply_t_handler
3953   (vl_api_one_ndp_entries_get_reply_t * mp)
3954 {
3955   vat_main_t *vam = &vat_main;
3956   u32 i, n;
3957   int retval = clib_net_to_host_u32 (mp->retval);
3958
3959   if (retval)
3960     goto end;
3961
3962   n = clib_net_to_host_u32 (mp->count);
3963
3964   for (i = 0; i < n; i++)
3965     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3966            format_ethernet_address, mp->entries[i].mac);
3967
3968 end:
3969   vam->retval = retval;
3970   vam->result_ready = 1;
3971 }
3972
3973 static void
3974   vl_api_one_ndp_entries_get_reply_t_handler_json
3975   (vl_api_one_ndp_entries_get_reply_t * mp)
3976 {
3977   u8 *s = 0;
3978   vat_main_t *vam = &vat_main;
3979   vat_json_node_t *e = 0, root;
3980   u32 i, n;
3981   int retval = clib_net_to_host_u32 (mp->retval);
3982   vl_api_one_ndp_entry_t *arp_entry;
3983
3984   if (retval)
3985     goto end;
3986
3987   n = clib_net_to_host_u32 (mp->count);
3988   vat_json_init_array (&root);
3989
3990   for (i = 0; i < n; i++)
3991     {
3992       e = vat_json_array_add (&root);
3993       arp_entry = &mp->entries[i];
3994
3995       vat_json_init_object (e);
3996       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3997       vec_add1 (s, 0);
3998
3999       vat_json_object_add_string_copy (e, "mac", s);
4000       vec_free (s);
4001
4002       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4003       vec_add1 (s, 0);
4004       vat_json_object_add_string_copy (e, "ip6", s);
4005       vec_free (s);
4006     }
4007
4008   vat_json_print (vam->ofp, &root);
4009   vat_json_free (&root);
4010
4011 end:
4012   vam->retval = retval;
4013   vam->result_ready = 1;
4014 }
4015
4016 static void
4017   vl_api_one_l2_arp_entries_get_reply_t_handler
4018   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4019 {
4020   vat_main_t *vam = &vat_main;
4021   u32 i, n;
4022   int retval = clib_net_to_host_u32 (mp->retval);
4023
4024   if (retval)
4025     goto end;
4026
4027   n = clib_net_to_host_u32 (mp->count);
4028
4029   for (i = 0; i < n; i++)
4030     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4031            format_ethernet_address, mp->entries[i].mac);
4032
4033 end:
4034   vam->retval = retval;
4035   vam->result_ready = 1;
4036 }
4037
4038 static void
4039   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4040   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4041 {
4042   u8 *s = 0;
4043   vat_main_t *vam = &vat_main;
4044   vat_json_node_t *e = 0, root;
4045   u32 i, n;
4046   int retval = clib_net_to_host_u32 (mp->retval);
4047   vl_api_one_l2_arp_entry_t *arp_entry;
4048
4049   if (retval)
4050     goto end;
4051
4052   n = clib_net_to_host_u32 (mp->count);
4053   vat_json_init_array (&root);
4054
4055   for (i = 0; i < n; i++)
4056     {
4057       e = vat_json_array_add (&root);
4058       arp_entry = &mp->entries[i];
4059
4060       vat_json_init_object (e);
4061       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4062       vec_add1 (s, 0);
4063
4064       vat_json_object_add_string_copy (e, "mac", s);
4065       vec_free (s);
4066
4067       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4068       vec_add1 (s, 0);
4069       vat_json_object_add_string_copy (e, "ip4", s);
4070       vec_free (s);
4071     }
4072
4073   vat_json_print (vam->ofp, &root);
4074   vat_json_free (&root);
4075
4076 end:
4077   vam->retval = retval;
4078   vam->result_ready = 1;
4079 }
4080
4081 static void
4082 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4083 {
4084   vat_main_t *vam = &vat_main;
4085   u32 i, n;
4086   int retval = clib_net_to_host_u32 (mp->retval);
4087
4088   if (retval)
4089     goto end;
4090
4091   n = clib_net_to_host_u32 (mp->count);
4092
4093   for (i = 0; i < n; i++)
4094     {
4095       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4096     }
4097
4098 end:
4099   vam->retval = retval;
4100   vam->result_ready = 1;
4101 }
4102
4103 static void
4104   vl_api_one_ndp_bd_get_reply_t_handler_json
4105   (vl_api_one_ndp_bd_get_reply_t * mp)
4106 {
4107   vat_main_t *vam = &vat_main;
4108   vat_json_node_t root;
4109   u32 i, n;
4110   int retval = clib_net_to_host_u32 (mp->retval);
4111
4112   if (retval)
4113     goto end;
4114
4115   n = clib_net_to_host_u32 (mp->count);
4116   vat_json_init_array (&root);
4117
4118   for (i = 0; i < n; i++)
4119     {
4120       vat_json_array_add_uint (&root,
4121                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4122     }
4123
4124   vat_json_print (vam->ofp, &root);
4125   vat_json_free (&root);
4126
4127 end:
4128   vam->retval = retval;
4129   vam->result_ready = 1;
4130 }
4131
4132 static void
4133   vl_api_one_l2_arp_bd_get_reply_t_handler
4134   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4135 {
4136   vat_main_t *vam = &vat_main;
4137   u32 i, n;
4138   int retval = clib_net_to_host_u32 (mp->retval);
4139
4140   if (retval)
4141     goto end;
4142
4143   n = clib_net_to_host_u32 (mp->count);
4144
4145   for (i = 0; i < n; i++)
4146     {
4147       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4148     }
4149
4150 end:
4151   vam->retval = retval;
4152   vam->result_ready = 1;
4153 }
4154
4155 static void
4156   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4157   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t root;
4161   u32 i, n;
4162   int retval = clib_net_to_host_u32 (mp->retval);
4163
4164   if (retval)
4165     goto end;
4166
4167   n = clib_net_to_host_u32 (mp->count);
4168   vat_json_init_array (&root);
4169
4170   for (i = 0; i < n; i++)
4171     {
4172       vat_json_array_add_uint (&root,
4173                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4174     }
4175
4176   vat_json_print (vam->ofp, &root);
4177   vat_json_free (&root);
4178
4179 end:
4180   vam->retval = retval;
4181   vam->result_ready = 1;
4182 }
4183
4184 static void
4185   vl_api_one_adjacencies_get_reply_t_handler
4186   (vl_api_one_adjacencies_get_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   u32 i, n;
4190   int retval = clib_net_to_host_u32 (mp->retval);
4191   vl_api_one_adjacency_t *a;
4192
4193   if (retval)
4194     goto end;
4195
4196   n = clib_net_to_host_u32 (mp->count);
4197
4198   for (i = 0; i < n; i++)
4199     {
4200       a = &mp->adjacencies[i];
4201       print (vam->ofp, "%U %40U",
4202              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4203              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4204     }
4205
4206 end:
4207   vam->retval = retval;
4208   vam->result_ready = 1;
4209 }
4210
4211 static void
4212   vl_api_one_adjacencies_get_reply_t_handler_json
4213   (vl_api_one_adjacencies_get_reply_t * mp)
4214 {
4215   u8 *s = 0;
4216   vat_main_t *vam = &vat_main;
4217   vat_json_node_t *e = 0, root;
4218   u32 i, n;
4219   int retval = clib_net_to_host_u32 (mp->retval);
4220   vl_api_one_adjacency_t *a;
4221
4222   if (retval)
4223     goto end;
4224
4225   n = clib_net_to_host_u32 (mp->count);
4226   vat_json_init_array (&root);
4227
4228   for (i = 0; i < n; i++)
4229     {
4230       e = vat_json_array_add (&root);
4231       a = &mp->adjacencies[i];
4232
4233       vat_json_init_object (e);
4234       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4235                   a->leid_prefix_len);
4236       vec_add1 (s, 0);
4237       vat_json_object_add_string_copy (e, "leid", s);
4238       vec_free (s);
4239
4240       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4241                   a->reid_prefix_len);
4242       vec_add1 (s, 0);
4243       vat_json_object_add_string_copy (e, "reid", s);
4244       vec_free (s);
4245     }
4246
4247   vat_json_print (vam->ofp, &root);
4248   vat_json_free (&root);
4249
4250 end:
4251   vam->retval = retval;
4252   vam->result_ready = 1;
4253 }
4254
4255 static void
4256 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4257 {
4258   vat_main_t *vam = &vat_main;
4259
4260   print (vam->ofp, "%=20U",
4261          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4262          mp->ip_address);
4263 }
4264
4265 static void
4266   vl_api_one_map_server_details_t_handler_json
4267   (vl_api_one_map_server_details_t * mp)
4268 {
4269   vat_main_t *vam = &vat_main;
4270   vat_json_node_t *node = NULL;
4271   struct in6_addr ip6;
4272   struct in_addr ip4;
4273
4274   if (VAT_JSON_ARRAY != vam->json_tree.type)
4275     {
4276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4277       vat_json_init_array (&vam->json_tree);
4278     }
4279   node = vat_json_array_add (&vam->json_tree);
4280
4281   vat_json_init_object (node);
4282   if (mp->is_ipv6)
4283     {
4284       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4285       vat_json_object_add_ip6 (node, "map-server", ip6);
4286     }
4287   else
4288     {
4289       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4290       vat_json_object_add_ip4 (node, "map-server", ip4);
4291     }
4292 }
4293
4294 static void
4295 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4296                                            * mp)
4297 {
4298   vat_main_t *vam = &vat_main;
4299
4300   print (vam->ofp, "%=20U",
4301          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4302          mp->ip_address);
4303 }
4304
4305 static void
4306   vl_api_one_map_resolver_details_t_handler_json
4307   (vl_api_one_map_resolver_details_t * mp)
4308 {
4309   vat_main_t *vam = &vat_main;
4310   vat_json_node_t *node = NULL;
4311   struct in6_addr ip6;
4312   struct in_addr ip4;
4313
4314   if (VAT_JSON_ARRAY != vam->json_tree.type)
4315     {
4316       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4317       vat_json_init_array (&vam->json_tree);
4318     }
4319   node = vat_json_array_add (&vam->json_tree);
4320
4321   vat_json_init_object (node);
4322   if (mp->is_ipv6)
4323     {
4324       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4325       vat_json_object_add_ip6 (node, "map resolver", ip6);
4326     }
4327   else
4328     {
4329       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4330       vat_json_object_add_ip4 (node, "map resolver", ip4);
4331     }
4332 }
4333
4334 static void
4335 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4336 {
4337   vat_main_t *vam = &vat_main;
4338   i32 retval = ntohl (mp->retval);
4339
4340   if (0 <= retval)
4341     {
4342       print (vam->ofp, "feature: %s\ngpe: %s",
4343              mp->feature_status ? "enabled" : "disabled",
4344              mp->gpe_status ? "enabled" : "disabled");
4345     }
4346
4347   vam->retval = retval;
4348   vam->result_ready = 1;
4349 }
4350
4351 static void
4352   vl_api_show_one_status_reply_t_handler_json
4353   (vl_api_show_one_status_reply_t * mp)
4354 {
4355   vat_main_t *vam = &vat_main;
4356   vat_json_node_t node;
4357   u8 *gpe_status = NULL;
4358   u8 *feature_status = NULL;
4359
4360   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4361   feature_status = format (0, "%s",
4362                            mp->feature_status ? "enabled" : "disabled");
4363   vec_add1 (gpe_status, 0);
4364   vec_add1 (feature_status, 0);
4365
4366   vat_json_init_object (&node);
4367   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4368   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4369
4370   vec_free (gpe_status);
4371   vec_free (feature_status);
4372
4373   vat_json_print (vam->ofp, &node);
4374   vat_json_free (&node);
4375
4376   vam->retval = ntohl (mp->retval);
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4382   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   i32 retval = ntohl (mp->retval);
4386
4387   if (retval >= 0)
4388     {
4389       print (vam->ofp, "%=20s", mp->locator_set_name);
4390     }
4391
4392   vam->retval = retval;
4393   vam->result_ready = 1;
4394 }
4395
4396 static void
4397   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4398   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4399 {
4400   vat_main_t *vam = &vat_main;
4401   vat_json_node_t *node = NULL;
4402
4403   if (VAT_JSON_ARRAY != vam->json_tree.type)
4404     {
4405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4406       vat_json_init_array (&vam->json_tree);
4407     }
4408   node = vat_json_array_add (&vam->json_tree);
4409
4410   vat_json_init_object (node);
4411   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4412
4413   vat_json_print (vam->ofp, node);
4414   vat_json_free (node);
4415
4416   vam->retval = ntohl (mp->retval);
4417   vam->result_ready = 1;
4418 }
4419
4420 static u8 *
4421 format_lisp_map_request_mode (u8 * s, va_list * args)
4422 {
4423   u32 mode = va_arg (*args, u32);
4424
4425   switch (mode)
4426     {
4427     case 0:
4428       return format (0, "dst-only");
4429     case 1:
4430       return format (0, "src-dst");
4431     }
4432   return 0;
4433 }
4434
4435 static void
4436   vl_api_show_one_map_request_mode_reply_t_handler
4437   (vl_api_show_one_map_request_mode_reply_t * mp)
4438 {
4439   vat_main_t *vam = &vat_main;
4440   i32 retval = ntohl (mp->retval);
4441
4442   if (0 <= retval)
4443     {
4444       u32 mode = mp->mode;
4445       print (vam->ofp, "map_request_mode: %U",
4446              format_lisp_map_request_mode, mode);
4447     }
4448
4449   vam->retval = retval;
4450   vam->result_ready = 1;
4451 }
4452
4453 static void
4454   vl_api_show_one_map_request_mode_reply_t_handler_json
4455   (vl_api_show_one_map_request_mode_reply_t * mp)
4456 {
4457   vat_main_t *vam = &vat_main;
4458   vat_json_node_t node;
4459   u8 *s = 0;
4460   u32 mode;
4461
4462   mode = mp->mode;
4463   s = format (0, "%U", format_lisp_map_request_mode, mode);
4464   vec_add1 (s, 0);
4465
4466   vat_json_init_object (&node);
4467   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4468   vat_json_print (vam->ofp, &node);
4469   vat_json_free (&node);
4470
4471   vec_free (s);
4472   vam->retval = ntohl (mp->retval);
4473   vam->result_ready = 1;
4474 }
4475
4476 static void
4477   vl_api_one_show_xtr_mode_reply_t_handler
4478   (vl_api_one_show_xtr_mode_reply_t * mp)
4479 {
4480   vat_main_t *vam = &vat_main;
4481   i32 retval = ntohl (mp->retval);
4482
4483   if (0 <= retval)
4484     {
4485       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4486     }
4487
4488   vam->retval = retval;
4489   vam->result_ready = 1;
4490 }
4491
4492 static void
4493   vl_api_one_show_xtr_mode_reply_t_handler_json
4494   (vl_api_one_show_xtr_mode_reply_t * mp)
4495 {
4496   vat_main_t *vam = &vat_main;
4497   vat_json_node_t node;
4498   u8 *status = 0;
4499
4500   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4501   vec_add1 (status, 0);
4502
4503   vat_json_init_object (&node);
4504   vat_json_object_add_string_copy (&node, "status", status);
4505
4506   vec_free (status);
4507
4508   vat_json_print (vam->ofp, &node);
4509   vat_json_free (&node);
4510
4511   vam->retval = ntohl (mp->retval);
4512   vam->result_ready = 1;
4513 }
4514
4515 static void
4516   vl_api_one_show_pitr_mode_reply_t_handler
4517   (vl_api_one_show_pitr_mode_reply_t * mp)
4518 {
4519   vat_main_t *vam = &vat_main;
4520   i32 retval = ntohl (mp->retval);
4521
4522   if (0 <= retval)
4523     {
4524       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4525     }
4526
4527   vam->retval = retval;
4528   vam->result_ready = 1;
4529 }
4530
4531 static void
4532   vl_api_one_show_pitr_mode_reply_t_handler_json
4533   (vl_api_one_show_pitr_mode_reply_t * mp)
4534 {
4535   vat_main_t *vam = &vat_main;
4536   vat_json_node_t node;
4537   u8 *status = 0;
4538
4539   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4540   vec_add1 (status, 0);
4541
4542   vat_json_init_object (&node);
4543   vat_json_object_add_string_copy (&node, "status", status);
4544
4545   vec_free (status);
4546
4547   vat_json_print (vam->ofp, &node);
4548   vat_json_free (&node);
4549
4550   vam->retval = ntohl (mp->retval);
4551   vam->result_ready = 1;
4552 }
4553
4554 static void
4555   vl_api_one_show_petr_mode_reply_t_handler
4556   (vl_api_one_show_petr_mode_reply_t * mp)
4557 {
4558   vat_main_t *vam = &vat_main;
4559   i32 retval = ntohl (mp->retval);
4560
4561   if (0 <= retval)
4562     {
4563       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4564     }
4565
4566   vam->retval = retval;
4567   vam->result_ready = 1;
4568 }
4569
4570 static void
4571   vl_api_one_show_petr_mode_reply_t_handler_json
4572   (vl_api_one_show_petr_mode_reply_t * mp)
4573 {
4574   vat_main_t *vam = &vat_main;
4575   vat_json_node_t node;
4576   u8 *status = 0;
4577
4578   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4579   vec_add1 (status, 0);
4580
4581   vat_json_init_object (&node);
4582   vat_json_object_add_string_copy (&node, "status", status);
4583
4584   vec_free (status);
4585
4586   vat_json_print (vam->ofp, &node);
4587   vat_json_free (&node);
4588
4589   vam->retval = ntohl (mp->retval);
4590   vam->result_ready = 1;
4591 }
4592
4593 static void
4594   vl_api_show_one_use_petr_reply_t_handler
4595   (vl_api_show_one_use_petr_reply_t * mp)
4596 {
4597   vat_main_t *vam = &vat_main;
4598   i32 retval = ntohl (mp->retval);
4599
4600   if (0 <= retval)
4601     {
4602       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4603       if (mp->status)
4604         {
4605           print (vam->ofp, "Proxy-ETR address; %U",
4606                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4607                  mp->address);
4608         }
4609     }
4610
4611   vam->retval = retval;
4612   vam->result_ready = 1;
4613 }
4614
4615 static void
4616   vl_api_show_one_use_petr_reply_t_handler_json
4617   (vl_api_show_one_use_petr_reply_t * mp)
4618 {
4619   vat_main_t *vam = &vat_main;
4620   vat_json_node_t node;
4621   u8 *status = 0;
4622   struct in_addr ip4;
4623   struct in6_addr ip6;
4624
4625   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4626   vec_add1 (status, 0);
4627
4628   vat_json_init_object (&node);
4629   vat_json_object_add_string_copy (&node, "status", status);
4630   if (mp->status)
4631     {
4632       if (mp->is_ip4)
4633         {
4634           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4635           vat_json_object_add_ip6 (&node, "address", ip6);
4636         }
4637       else
4638         {
4639           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4640           vat_json_object_add_ip4 (&node, "address", ip4);
4641         }
4642     }
4643
4644   vec_free (status);
4645
4646   vat_json_print (vam->ofp, &node);
4647   vat_json_free (&node);
4648
4649   vam->retval = ntohl (mp->retval);
4650   vam->result_ready = 1;
4651 }
4652
4653 static void
4654   vl_api_show_one_nsh_mapping_reply_t_handler
4655   (vl_api_show_one_nsh_mapping_reply_t * mp)
4656 {
4657   vat_main_t *vam = &vat_main;
4658   i32 retval = ntohl (mp->retval);
4659
4660   if (0 <= retval)
4661     {
4662       print (vam->ofp, "%-20s%-16s",
4663              mp->is_set ? "set" : "not-set",
4664              mp->is_set ? (char *) mp->locator_set_name : "");
4665     }
4666
4667   vam->retval = retval;
4668   vam->result_ready = 1;
4669 }
4670
4671 static void
4672   vl_api_show_one_nsh_mapping_reply_t_handler_json
4673   (vl_api_show_one_nsh_mapping_reply_t * mp)
4674 {
4675   vat_main_t *vam = &vat_main;
4676   vat_json_node_t node;
4677   u8 *status = 0;
4678
4679   status = format (0, "%s", mp->is_set ? "yes" : "no");
4680   vec_add1 (status, 0);
4681
4682   vat_json_init_object (&node);
4683   vat_json_object_add_string_copy (&node, "is_set", status);
4684   if (mp->is_set)
4685     {
4686       vat_json_object_add_string_copy (&node, "locator_set",
4687                                        mp->locator_set_name);
4688     }
4689
4690   vec_free (status);
4691
4692   vat_json_print (vam->ofp, &node);
4693   vat_json_free (&node);
4694
4695   vam->retval = ntohl (mp->retval);
4696   vam->result_ready = 1;
4697 }
4698
4699 static void
4700   vl_api_show_one_map_register_ttl_reply_t_handler
4701   (vl_api_show_one_map_register_ttl_reply_t * mp)
4702 {
4703   vat_main_t *vam = &vat_main;
4704   i32 retval = ntohl (mp->retval);
4705
4706   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4707
4708   if (0 <= retval)
4709     {
4710       print (vam->ofp, "ttl: %u", mp->ttl);
4711     }
4712
4713   vam->retval = retval;
4714   vam->result_ready = 1;
4715 }
4716
4717 static void
4718   vl_api_show_one_map_register_ttl_reply_t_handler_json
4719   (vl_api_show_one_map_register_ttl_reply_t * mp)
4720 {
4721   vat_main_t *vam = &vat_main;
4722   vat_json_node_t node;
4723
4724   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4725   vat_json_init_object (&node);
4726   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4727
4728   vat_json_print (vam->ofp, &node);
4729   vat_json_free (&node);
4730
4731   vam->retval = ntohl (mp->retval);
4732   vam->result_ready = 1;
4733 }
4734
4735 static void
4736 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4737 {
4738   vat_main_t *vam = &vat_main;
4739   i32 retval = ntohl (mp->retval);
4740
4741   if (0 <= retval)
4742     {
4743       print (vam->ofp, "%-20s%-16s",
4744              mp->status ? "enabled" : "disabled",
4745              mp->status ? (char *) mp->locator_set_name : "");
4746     }
4747
4748   vam->retval = retval;
4749   vam->result_ready = 1;
4750 }
4751
4752 static void
4753 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   vat_json_node_t node;
4757   u8 *status = 0;
4758
4759   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4760   vec_add1 (status, 0);
4761
4762   vat_json_init_object (&node);
4763   vat_json_object_add_string_copy (&node, "status", status);
4764   if (mp->status)
4765     {
4766       vat_json_object_add_string_copy (&node, "locator_set",
4767                                        mp->locator_set_name);
4768     }
4769
4770   vec_free (status);
4771
4772   vat_json_print (vam->ofp, &node);
4773   vat_json_free (&node);
4774
4775   vam->retval = ntohl (mp->retval);
4776   vam->result_ready = 1;
4777 }
4778
4779 static u8 *
4780 format_policer_type (u8 * s, va_list * va)
4781 {
4782   u32 i = va_arg (*va, u32);
4783
4784   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4785     s = format (s, "1r2c");
4786   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4787     s = format (s, "1r3c");
4788   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4789     s = format (s, "2r3c-2698");
4790   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4791     s = format (s, "2r3c-4115");
4792   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4793     s = format (s, "2r3c-mef5cf1");
4794   else
4795     s = format (s, "ILLEGAL");
4796   return s;
4797 }
4798
4799 static u8 *
4800 format_policer_rate_type (u8 * s, va_list * va)
4801 {
4802   u32 i = va_arg (*va, u32);
4803
4804   if (i == SSE2_QOS_RATE_KBPS)
4805     s = format (s, "kbps");
4806   else if (i == SSE2_QOS_RATE_PPS)
4807     s = format (s, "pps");
4808   else
4809     s = format (s, "ILLEGAL");
4810   return s;
4811 }
4812
4813 static u8 *
4814 format_policer_round_type (u8 * s, va_list * va)
4815 {
4816   u32 i = va_arg (*va, u32);
4817
4818   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4819     s = format (s, "closest");
4820   else if (i == SSE2_QOS_ROUND_TO_UP)
4821     s = format (s, "up");
4822   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4823     s = format (s, "down");
4824   else
4825     s = format (s, "ILLEGAL");
4826   return s;
4827 }
4828
4829 static u8 *
4830 format_policer_action_type (u8 * s, va_list * va)
4831 {
4832   u32 i = va_arg (*va, u32);
4833
4834   if (i == SSE2_QOS_ACTION_DROP)
4835     s = format (s, "drop");
4836   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4837     s = format (s, "transmit");
4838   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4839     s = format (s, "mark-and-transmit");
4840   else
4841     s = format (s, "ILLEGAL");
4842   return s;
4843 }
4844
4845 static u8 *
4846 format_dscp (u8 * s, va_list * va)
4847 {
4848   u32 i = va_arg (*va, u32);
4849   char *t = 0;
4850
4851   switch (i)
4852     {
4853 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4854       foreach_vnet_dscp
4855 #undef _
4856     default:
4857       return format (s, "ILLEGAL");
4858     }
4859   s = format (s, "%s", t);
4860   return s;
4861 }
4862
4863 static void
4864 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4865 {
4866   vat_main_t *vam = &vat_main;
4867   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4868
4869   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4870     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4871   else
4872     conform_dscp_str = format (0, "");
4873
4874   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4875     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4876   else
4877     exceed_dscp_str = format (0, "");
4878
4879   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4880     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4881   else
4882     violate_dscp_str = format (0, "");
4883
4884   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4885          "rate type %U, round type %U, %s rate, %s color-aware, "
4886          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4887          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4888          "conform action %U%s, exceed action %U%s, violate action %U%s",
4889          mp->name,
4890          format_policer_type, mp->type,
4891          ntohl (mp->cir),
4892          ntohl (mp->eir),
4893          clib_net_to_host_u64 (mp->cb),
4894          clib_net_to_host_u64 (mp->eb),
4895          format_policer_rate_type, mp->rate_type,
4896          format_policer_round_type, mp->round_type,
4897          mp->single_rate ? "single" : "dual",
4898          mp->color_aware ? "is" : "not",
4899          ntohl (mp->cir_tokens_per_period),
4900          ntohl (mp->pir_tokens_per_period),
4901          ntohl (mp->scale),
4902          ntohl (mp->current_limit),
4903          ntohl (mp->current_bucket),
4904          ntohl (mp->extended_limit),
4905          ntohl (mp->extended_bucket),
4906          clib_net_to_host_u64 (mp->last_update_time),
4907          format_policer_action_type, mp->conform_action_type,
4908          conform_dscp_str,
4909          format_policer_action_type, mp->exceed_action_type,
4910          exceed_dscp_str,
4911          format_policer_action_type, mp->violate_action_type,
4912          violate_dscp_str);
4913
4914   vec_free (conform_dscp_str);
4915   vec_free (exceed_dscp_str);
4916   vec_free (violate_dscp_str);
4917 }
4918
4919 static void vl_api_policer_details_t_handler_json
4920   (vl_api_policer_details_t * mp)
4921 {
4922   vat_main_t *vam = &vat_main;
4923   vat_json_node_t *node;
4924   u8 *rate_type_str, *round_type_str, *type_str;
4925   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4926
4927   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4928   round_type_str =
4929     format (0, "%U", format_policer_round_type, mp->round_type);
4930   type_str = format (0, "%U", format_policer_type, mp->type);
4931   conform_action_str = format (0, "%U", format_policer_action_type,
4932                                mp->conform_action_type);
4933   exceed_action_str = format (0, "%U", format_policer_action_type,
4934                               mp->exceed_action_type);
4935   violate_action_str = format (0, "%U", format_policer_action_type,
4936                                mp->violate_action_type);
4937
4938   if (VAT_JSON_ARRAY != vam->json_tree.type)
4939     {
4940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4941       vat_json_init_array (&vam->json_tree);
4942     }
4943   node = vat_json_array_add (&vam->json_tree);
4944
4945   vat_json_init_object (node);
4946   vat_json_object_add_string_copy (node, "name", mp->name);
4947   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4948   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4949   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4950   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4951   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4952   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4953   vat_json_object_add_string_copy (node, "type", type_str);
4954   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4955   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4956   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4957   vat_json_object_add_uint (node, "cir_tokens_per_period",
4958                             ntohl (mp->cir_tokens_per_period));
4959   vat_json_object_add_uint (node, "eir_tokens_per_period",
4960                             ntohl (mp->pir_tokens_per_period));
4961   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4962   vat_json_object_add_uint (node, "current_bucket",
4963                             ntohl (mp->current_bucket));
4964   vat_json_object_add_uint (node, "extended_limit",
4965                             ntohl (mp->extended_limit));
4966   vat_json_object_add_uint (node, "extended_bucket",
4967                             ntohl (mp->extended_bucket));
4968   vat_json_object_add_uint (node, "last_update_time",
4969                             ntohl (mp->last_update_time));
4970   vat_json_object_add_string_copy (node, "conform_action",
4971                                    conform_action_str);
4972   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4973     {
4974       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4975       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4976       vec_free (dscp_str);
4977     }
4978   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4979   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4980     {
4981       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4982       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4983       vec_free (dscp_str);
4984     }
4985   vat_json_object_add_string_copy (node, "violate_action",
4986                                    violate_action_str);
4987   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4988     {
4989       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4990       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4991       vec_free (dscp_str);
4992     }
4993
4994   vec_free (rate_type_str);
4995   vec_free (round_type_str);
4996   vec_free (type_str);
4997   vec_free (conform_action_str);
4998   vec_free (exceed_action_str);
4999   vec_free (violate_action_str);
5000 }
5001
5002 static void
5003 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5004                                            mp)
5005 {
5006   vat_main_t *vam = &vat_main;
5007   int i, count = ntohl (mp->count);
5008
5009   if (count > 0)
5010     print (vam->ofp, "classify table ids (%d) : ", count);
5011   for (i = 0; i < count; i++)
5012     {
5013       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5014       print (vam->ofp, (i < count - 1) ? "," : "");
5015     }
5016   vam->retval = ntohl (mp->retval);
5017   vam->result_ready = 1;
5018 }
5019
5020 static void
5021   vl_api_classify_table_ids_reply_t_handler_json
5022   (vl_api_classify_table_ids_reply_t * mp)
5023 {
5024   vat_main_t *vam = &vat_main;
5025   int i, count = ntohl (mp->count);
5026
5027   if (count > 0)
5028     {
5029       vat_json_node_t node;
5030
5031       vat_json_init_object (&node);
5032       for (i = 0; i < count; i++)
5033         {
5034           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5035         }
5036       vat_json_print (vam->ofp, &node);
5037       vat_json_free (&node);
5038     }
5039   vam->retval = ntohl (mp->retval);
5040   vam->result_ready = 1;
5041 }
5042
5043 static void
5044   vl_api_classify_table_by_interface_reply_t_handler
5045   (vl_api_classify_table_by_interface_reply_t * mp)
5046 {
5047   vat_main_t *vam = &vat_main;
5048   u32 table_id;
5049
5050   table_id = ntohl (mp->l2_table_id);
5051   if (table_id != ~0)
5052     print (vam->ofp, "l2 table id : %d", table_id);
5053   else
5054     print (vam->ofp, "l2 table id : No input ACL tables configured");
5055   table_id = ntohl (mp->ip4_table_id);
5056   if (table_id != ~0)
5057     print (vam->ofp, "ip4 table id : %d", table_id);
5058   else
5059     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5060   table_id = ntohl (mp->ip6_table_id);
5061   if (table_id != ~0)
5062     print (vam->ofp, "ip6 table id : %d", table_id);
5063   else
5064     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5065   vam->retval = ntohl (mp->retval);
5066   vam->result_ready = 1;
5067 }
5068
5069 static void
5070   vl_api_classify_table_by_interface_reply_t_handler_json
5071   (vl_api_classify_table_by_interface_reply_t * mp)
5072 {
5073   vat_main_t *vam = &vat_main;
5074   vat_json_node_t node;
5075
5076   vat_json_init_object (&node);
5077
5078   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5079   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5080   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5081
5082   vat_json_print (vam->ofp, &node);
5083   vat_json_free (&node);
5084
5085   vam->retval = ntohl (mp->retval);
5086   vam->result_ready = 1;
5087 }
5088
5089 static void vl_api_policer_add_del_reply_t_handler
5090   (vl_api_policer_add_del_reply_t * mp)
5091 {
5092   vat_main_t *vam = &vat_main;
5093   i32 retval = ntohl (mp->retval);
5094   if (vam->async_mode)
5095     {
5096       vam->async_errors += (retval < 0);
5097     }
5098   else
5099     {
5100       vam->retval = retval;
5101       vam->result_ready = 1;
5102       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5103         /*
5104          * Note: this is just barely thread-safe, depends on
5105          * the main thread spinning waiting for an answer...
5106          */
5107         errmsg ("policer index %d", ntohl (mp->policer_index));
5108     }
5109 }
5110
5111 static void vl_api_policer_add_del_reply_t_handler_json
5112   (vl_api_policer_add_del_reply_t * mp)
5113 {
5114   vat_main_t *vam = &vat_main;
5115   vat_json_node_t node;
5116
5117   vat_json_init_object (&node);
5118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5119   vat_json_object_add_uint (&node, "policer_index",
5120                             ntohl (mp->policer_index));
5121
5122   vat_json_print (vam->ofp, &node);
5123   vat_json_free (&node);
5124
5125   vam->retval = ntohl (mp->retval);
5126   vam->result_ready = 1;
5127 }
5128
5129 /* Format hex dump. */
5130 u8 *
5131 format_hex_bytes (u8 * s, va_list * va)
5132 {
5133   u8 *bytes = va_arg (*va, u8 *);
5134   int n_bytes = va_arg (*va, int);
5135   uword i;
5136
5137   /* Print short or long form depending on byte count. */
5138   uword short_form = n_bytes <= 32;
5139   u32 indent = format_get_indent (s);
5140
5141   if (n_bytes == 0)
5142     return s;
5143
5144   for (i = 0; i < n_bytes; i++)
5145     {
5146       if (!short_form && (i % 32) == 0)
5147         s = format (s, "%08x: ", i);
5148       s = format (s, "%02x", bytes[i]);
5149       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5150         s = format (s, "\n%U", format_white_space, indent);
5151     }
5152
5153   return s;
5154 }
5155
5156 static void
5157 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5158                                             * mp)
5159 {
5160   vat_main_t *vam = &vat_main;
5161   i32 retval = ntohl (mp->retval);
5162   if (retval == 0)
5163     {
5164       print (vam->ofp, "classify table info :");
5165       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5166              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5167              ntohl (mp->miss_next_index));
5168       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5169              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5170              ntohl (mp->match_n_vectors));
5171       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5172              ntohl (mp->mask_length));
5173     }
5174   vam->retval = retval;
5175   vam->result_ready = 1;
5176 }
5177
5178 static void
5179   vl_api_classify_table_info_reply_t_handler_json
5180   (vl_api_classify_table_info_reply_t * mp)
5181 {
5182   vat_main_t *vam = &vat_main;
5183   vat_json_node_t node;
5184
5185   i32 retval = ntohl (mp->retval);
5186   if (retval == 0)
5187     {
5188       vat_json_init_object (&node);
5189
5190       vat_json_object_add_int (&node, "sessions",
5191                                ntohl (mp->active_sessions));
5192       vat_json_object_add_int (&node, "nexttbl",
5193                                ntohl (mp->next_table_index));
5194       vat_json_object_add_int (&node, "nextnode",
5195                                ntohl (mp->miss_next_index));
5196       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5197       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5198       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5199       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5200                       ntohl (mp->mask_length), 0);
5201       vat_json_object_add_string_copy (&node, "mask", s);
5202
5203       vat_json_print (vam->ofp, &node);
5204       vat_json_free (&node);
5205     }
5206   vam->retval = ntohl (mp->retval);
5207   vam->result_ready = 1;
5208 }
5209
5210 static void
5211 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5212                                            mp)
5213 {
5214   vat_main_t *vam = &vat_main;
5215
5216   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5217          ntohl (mp->hit_next_index), ntohl (mp->advance),
5218          ntohl (mp->opaque_index));
5219   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5220          ntohl (mp->match_length));
5221 }
5222
5223 static void
5224   vl_api_classify_session_details_t_handler_json
5225   (vl_api_classify_session_details_t * mp)
5226 {
5227   vat_main_t *vam = &vat_main;
5228   vat_json_node_t *node = NULL;
5229
5230   if (VAT_JSON_ARRAY != vam->json_tree.type)
5231     {
5232       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5233       vat_json_init_array (&vam->json_tree);
5234     }
5235   node = vat_json_array_add (&vam->json_tree);
5236
5237   vat_json_init_object (node);
5238   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5239   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5240   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5241   u8 *s =
5242     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5243             0);
5244   vat_json_object_add_string_copy (node, "match", s);
5245 }
5246
5247 static void vl_api_pg_create_interface_reply_t_handler
5248   (vl_api_pg_create_interface_reply_t * mp)
5249 {
5250   vat_main_t *vam = &vat_main;
5251
5252   vam->retval = ntohl (mp->retval);
5253   vam->result_ready = 1;
5254 }
5255
5256 static void vl_api_pg_create_interface_reply_t_handler_json
5257   (vl_api_pg_create_interface_reply_t * mp)
5258 {
5259   vat_main_t *vam = &vat_main;
5260   vat_json_node_t node;
5261
5262   i32 retval = ntohl (mp->retval);
5263   if (retval == 0)
5264     {
5265       vat_json_init_object (&node);
5266
5267       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5268
5269       vat_json_print (vam->ofp, &node);
5270       vat_json_free (&node);
5271     }
5272   vam->retval = ntohl (mp->retval);
5273   vam->result_ready = 1;
5274 }
5275
5276 static void vl_api_policer_classify_details_t_handler
5277   (vl_api_policer_classify_details_t * mp)
5278 {
5279   vat_main_t *vam = &vat_main;
5280
5281   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5282          ntohl (mp->table_index));
5283 }
5284
5285 static void vl_api_policer_classify_details_t_handler_json
5286   (vl_api_policer_classify_details_t * mp)
5287 {
5288   vat_main_t *vam = &vat_main;
5289   vat_json_node_t *node;
5290
5291   if (VAT_JSON_ARRAY != vam->json_tree.type)
5292     {
5293       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5294       vat_json_init_array (&vam->json_tree);
5295     }
5296   node = vat_json_array_add (&vam->json_tree);
5297
5298   vat_json_init_object (node);
5299   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5300   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5301 }
5302
5303 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5304   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5305 {
5306   vat_main_t *vam = &vat_main;
5307   i32 retval = ntohl (mp->retval);
5308   if (vam->async_mode)
5309     {
5310       vam->async_errors += (retval < 0);
5311     }
5312   else
5313     {
5314       vam->retval = retval;
5315       vam->sw_if_index = ntohl (mp->sw_if_index);
5316       vam->result_ready = 1;
5317     }
5318   vam->regenerate_interface_table = 1;
5319 }
5320
5321 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5322   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5323 {
5324   vat_main_t *vam = &vat_main;
5325   vat_json_node_t node;
5326
5327   vat_json_init_object (&node);
5328   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5329   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5330
5331   vat_json_print (vam->ofp, &node);
5332   vat_json_free (&node);
5333
5334   vam->retval = ntohl (mp->retval);
5335   vam->result_ready = 1;
5336 }
5337
5338 static void vl_api_flow_classify_details_t_handler
5339   (vl_api_flow_classify_details_t * mp)
5340 {
5341   vat_main_t *vam = &vat_main;
5342
5343   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5344          ntohl (mp->table_index));
5345 }
5346
5347 static void vl_api_flow_classify_details_t_handler_json
5348   (vl_api_flow_classify_details_t * mp)
5349 {
5350   vat_main_t *vam = &vat_main;
5351   vat_json_node_t *node;
5352
5353   if (VAT_JSON_ARRAY != vam->json_tree.type)
5354     {
5355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5356       vat_json_init_array (&vam->json_tree);
5357     }
5358   node = vat_json_array_add (&vam->json_tree);
5359
5360   vat_json_init_object (node);
5361   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5362   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5363 }
5364
5365 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5366 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5367 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5368 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5369 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5370 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5371 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5372 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5373 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5374 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5375 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5376 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5377 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5378 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5379 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5380 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5381 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5382 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5383 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5384 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5385 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5386 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5387
5388 /*
5389  * Generate boilerplate reply handlers, which
5390  * dig the return value out of the xxx_reply_t API message,
5391  * stick it into vam->retval, and set vam->result_ready
5392  *
5393  * Could also do this by pointing N message decode slots at
5394  * a single function, but that could break in subtle ways.
5395  */
5396
5397 #define foreach_standard_reply_retval_handler           \
5398 _(sw_interface_set_flags_reply)                         \
5399 _(sw_interface_add_del_address_reply)                   \
5400 _(sw_interface_set_rx_mode_reply)                       \
5401 _(sw_interface_set_table_reply)                         \
5402 _(sw_interface_set_mpls_enable_reply)                   \
5403 _(sw_interface_set_vpath_reply)                         \
5404 _(sw_interface_set_vxlan_bypass_reply)                  \
5405 _(sw_interface_set_geneve_bypass_reply)                 \
5406 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5407 _(sw_interface_set_l2_bridge_reply)                     \
5408 _(bridge_domain_add_del_reply)                          \
5409 _(sw_interface_set_l2_xconnect_reply)                   \
5410 _(l2fib_add_del_reply)                                  \
5411 _(l2fib_flush_int_reply)                                \
5412 _(l2fib_flush_bd_reply)                                 \
5413 _(ip_add_del_route_reply)                               \
5414 _(ip_table_add_del_reply)                               \
5415 _(ip_mroute_add_del_reply)                              \
5416 _(mpls_route_add_del_reply)                             \
5417 _(mpls_table_add_del_reply)                             \
5418 _(mpls_ip_bind_unbind_reply)                            \
5419 _(bier_route_add_del_reply)                             \
5420 _(bier_table_add_del_reply)                             \
5421 _(proxy_arp_add_del_reply)                              \
5422 _(proxy_arp_intfc_enable_disable_reply)                 \
5423 _(sw_interface_set_unnumbered_reply)                    \
5424 _(ip_neighbor_add_del_reply)                            \
5425 _(oam_add_del_reply)                                    \
5426 _(reset_fib_reply)                                      \
5427 _(dhcp_proxy_config_reply)                              \
5428 _(dhcp_proxy_set_vss_reply)                             \
5429 _(dhcp_client_config_reply)                             \
5430 _(set_ip_flow_hash_reply)                               \
5431 _(sw_interface_ip6_enable_disable_reply)                \
5432 _(sw_interface_ip6_set_link_local_address_reply)        \
5433 _(ip6nd_proxy_add_del_reply)                            \
5434 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5435 _(sw_interface_ip6nd_ra_config_reply)                   \
5436 _(set_arp_neighbor_limit_reply)                         \
5437 _(l2_patch_add_del_reply)                               \
5438 _(sr_policy_add_reply)                                  \
5439 _(sr_policy_mod_reply)                                  \
5440 _(sr_policy_del_reply)                                  \
5441 _(sr_localsid_add_del_reply)                            \
5442 _(sr_steering_add_del_reply)                            \
5443 _(classify_add_del_session_reply)                       \
5444 _(classify_set_interface_ip_table_reply)                \
5445 _(classify_set_interface_l2_tables_reply)               \
5446 _(l2tpv3_set_tunnel_cookies_reply)                      \
5447 _(l2tpv3_interface_enable_disable_reply)                \
5448 _(l2tpv3_set_lookup_key_reply)                          \
5449 _(l2_fib_clear_table_reply)                             \
5450 _(l2_interface_efp_filter_reply)                        \
5451 _(l2_interface_vlan_tag_rewrite_reply)                  \
5452 _(modify_vhost_user_if_reply)                           \
5453 _(delete_vhost_user_if_reply)                           \
5454 _(ip_probe_neighbor_reply)                              \
5455 _(ip_scan_neighbor_enable_disable_reply)                \
5456 _(want_ip4_arp_events_reply)                            \
5457 _(want_ip6_nd_events_reply)                             \
5458 _(want_l2_macs_events_reply)                            \
5459 _(input_acl_set_interface_reply)                        \
5460 _(ipsec_spd_add_del_reply)                              \
5461 _(ipsec_interface_add_del_spd_reply)                    \
5462 _(ipsec_spd_add_del_entry_reply)                        \
5463 _(ipsec_sad_add_del_entry_reply)                        \
5464 _(ipsec_sa_set_key_reply)                               \
5465 _(ipsec_tunnel_if_add_del_reply)                        \
5466 _(ipsec_tunnel_if_set_key_reply)                        \
5467 _(ipsec_tunnel_if_set_sa_reply)                         \
5468 _(ikev2_profile_add_del_reply)                          \
5469 _(ikev2_profile_set_auth_reply)                         \
5470 _(ikev2_profile_set_id_reply)                           \
5471 _(ikev2_profile_set_ts_reply)                           \
5472 _(ikev2_set_local_key_reply)                            \
5473 _(ikev2_set_responder_reply)                            \
5474 _(ikev2_set_ike_transforms_reply)                       \
5475 _(ikev2_set_esp_transforms_reply)                       \
5476 _(ikev2_set_sa_lifetime_reply)                          \
5477 _(ikev2_initiate_sa_init_reply)                         \
5478 _(ikev2_initiate_del_ike_sa_reply)                      \
5479 _(ikev2_initiate_del_child_sa_reply)                    \
5480 _(ikev2_initiate_rekey_child_sa_reply)                  \
5481 _(delete_loopback_reply)                                \
5482 _(bd_ip_mac_add_del_reply)                              \
5483 _(map_del_domain_reply)                                 \
5484 _(map_add_del_rule_reply)                               \
5485 _(want_interface_events_reply)                          \
5486 _(want_stats_reply)                                     \
5487 _(cop_interface_enable_disable_reply)                   \
5488 _(cop_whitelist_enable_disable_reply)                   \
5489 _(sw_interface_clear_stats_reply)                       \
5490 _(ioam_enable_reply)                                    \
5491 _(ioam_disable_reply)                                   \
5492 _(one_add_del_locator_reply)                            \
5493 _(one_add_del_local_eid_reply)                          \
5494 _(one_add_del_remote_mapping_reply)                     \
5495 _(one_add_del_adjacency_reply)                          \
5496 _(one_add_del_map_resolver_reply)                       \
5497 _(one_add_del_map_server_reply)                         \
5498 _(one_enable_disable_reply)                             \
5499 _(one_rloc_probe_enable_disable_reply)                  \
5500 _(one_map_register_enable_disable_reply)                \
5501 _(one_map_register_set_ttl_reply)                       \
5502 _(one_set_transport_protocol_reply)                     \
5503 _(one_map_register_fallback_threshold_reply)            \
5504 _(one_pitr_set_locator_set_reply)                       \
5505 _(one_map_request_mode_reply)                           \
5506 _(one_add_del_map_request_itr_rlocs_reply)              \
5507 _(one_eid_table_add_del_map_reply)                      \
5508 _(one_use_petr_reply)                                   \
5509 _(one_stats_enable_disable_reply)                       \
5510 _(one_add_del_l2_arp_entry_reply)                       \
5511 _(one_add_del_ndp_entry_reply)                          \
5512 _(one_stats_flush_reply)                                \
5513 _(one_enable_disable_xtr_mode_reply)                    \
5514 _(one_enable_disable_pitr_mode_reply)                   \
5515 _(one_enable_disable_petr_mode_reply)                   \
5516 _(gpe_enable_disable_reply)                             \
5517 _(gpe_set_encap_mode_reply)                             \
5518 _(gpe_add_del_iface_reply)                              \
5519 _(gpe_add_del_native_fwd_rpath_reply)                   \
5520 _(af_packet_delete_reply)                               \
5521 _(policer_classify_set_interface_reply)                 \
5522 _(netmap_create_reply)                                  \
5523 _(netmap_delete_reply)                                  \
5524 _(set_ipfix_exporter_reply)                             \
5525 _(set_ipfix_classify_stream_reply)                      \
5526 _(ipfix_classify_table_add_del_reply)                   \
5527 _(flow_classify_set_interface_reply)                    \
5528 _(sw_interface_span_enable_disable_reply)               \
5529 _(pg_capture_reply)                                     \
5530 _(pg_enable_disable_reply)                              \
5531 _(ip_source_and_port_range_check_add_del_reply)         \
5532 _(ip_source_and_port_range_check_interface_add_del_reply)\
5533 _(delete_subif_reply)                                   \
5534 _(l2_interface_pbb_tag_rewrite_reply)                   \
5535 _(punt_reply)                                           \
5536 _(feature_enable_disable_reply)                         \
5537 _(sw_interface_tag_add_del_reply)                       \
5538 _(sw_interface_set_mtu_reply)                           \
5539 _(p2p_ethernet_add_reply)                               \
5540 _(p2p_ethernet_del_reply)                               \
5541 _(lldp_config_reply)                                    \
5542 _(sw_interface_set_lldp_reply)                          \
5543 _(tcp_configure_src_addresses_reply)                    \
5544 _(dns_enable_disable_reply)                             \
5545 _(dns_name_server_add_del_reply)                        \
5546 _(session_rule_add_del_reply)                           \
5547 _(ip_container_proxy_add_del_reply)                     \
5548 _(output_acl_set_interface_reply)                       \
5549 _(qos_record_enable_disable_reply)
5550
5551 #define _(n)                                    \
5552     static void vl_api_##n##_t_handler          \
5553     (vl_api_##n##_t * mp)                       \
5554     {                                           \
5555         vat_main_t * vam = &vat_main;           \
5556         i32 retval = ntohl(mp->retval);         \
5557         if (vam->async_mode) {                  \
5558             vam->async_errors += (retval < 0);  \
5559         } else {                                \
5560             vam->retval = retval;               \
5561             vam->result_ready = 1;              \
5562         }                                       \
5563     }
5564 foreach_standard_reply_retval_handler;
5565 #undef _
5566
5567 #define _(n)                                    \
5568     static void vl_api_##n##_t_handler_json     \
5569     (vl_api_##n##_t * mp)                       \
5570     {                                           \
5571         vat_main_t * vam = &vat_main;           \
5572         vat_json_node_t node;                   \
5573         vat_json_init_object(&node);            \
5574         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5575         vat_json_print(vam->ofp, &node);        \
5576         vam->retval = ntohl(mp->retval);        \
5577         vam->result_ready = 1;                  \
5578     }
5579 foreach_standard_reply_retval_handler;
5580 #undef _
5581
5582 /*
5583  * Table of message reply handlers, must include boilerplate handlers
5584  * we just generated
5585  */
5586
5587 #define foreach_vpe_api_reply_msg                                       \
5588 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5589 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5590 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5591 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5592 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5593 _(CLI_REPLY, cli_reply)                                                 \
5594 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5595 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5596   sw_interface_add_del_address_reply)                                   \
5597 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5598 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5599 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5600 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5601 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5602 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5603 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5604 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5605   sw_interface_set_l2_xconnect_reply)                                   \
5606 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5607   sw_interface_set_l2_bridge_reply)                                     \
5608 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5609 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5610 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5611 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5612 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5613 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5614 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5615 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5616 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5617 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5618 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5619 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5620 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5621 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5622 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5623 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5624 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5625 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5626 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5627 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5628 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5629 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5630 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5631 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5632 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5633 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5634 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5635 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5636 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5637 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5638 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5639   proxy_arp_intfc_enable_disable_reply)                                 \
5640 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5641 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5642   sw_interface_set_unnumbered_reply)                                    \
5643 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5644 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5645 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5646 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5647 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5648 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5649 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5650 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5651 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5652 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5653 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5654   sw_interface_ip6_enable_disable_reply)                                \
5655 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5656   sw_interface_ip6_set_link_local_address_reply)                        \
5657 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5658 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5659 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5660   sw_interface_ip6nd_ra_prefix_reply)                                   \
5661 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5662   sw_interface_ip6nd_ra_config_reply)                                   \
5663 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5664 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5665 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5666 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5667 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5668 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5669 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5670 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5671 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5672 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5673 classify_set_interface_ip_table_reply)                                  \
5674 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5675   classify_set_interface_l2_tables_reply)                               \
5676 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5677 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5678 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5679 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5680 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5681   l2tpv3_interface_enable_disable_reply)                                \
5682 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5683 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5684 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5685 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5686 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5687 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5688 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5689 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5690 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5691 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5692 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5693 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5694 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5695 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5696 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5697 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5698 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5699 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5700 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5701 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5702 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5703 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5704 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5705 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5706 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5707 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5708 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5709 _(L2_MACS_EVENT, l2_macs_event)                                         \
5710 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5711 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5712 _(IP_DETAILS, ip_details)                                               \
5713 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5714 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5715 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5716 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5717 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5718 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5719 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5720 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5721 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5722 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5723 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5724 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5725 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5726 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5727 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5728 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5729 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5730 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5731 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5732 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5733 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5734 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5735 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5736 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5737 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5738 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5739 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5740 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5741 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5742 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5743 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5744 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5745 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5746 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5747 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5748 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5749 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5750 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5751 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5752 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5753 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5754 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5755 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5756 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5757 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5758 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5759 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5760 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5761   one_map_register_enable_disable_reply)                                \
5762 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5763 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5764 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5765 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5766   one_map_register_fallback_threshold_reply)                            \
5767 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5768   one_rloc_probe_enable_disable_reply)                                  \
5769 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5770 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5771 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5772 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5773 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5774 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5775 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5776 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5777 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5778 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5779 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5780 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5781 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5782 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5783 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5784 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5785   show_one_stats_enable_disable_reply)                                  \
5786 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5787 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5788 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5789 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5790 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5791 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5792 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5793 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5794   one_enable_disable_pitr_mode_reply)                                   \
5795 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5796   one_enable_disable_petr_mode_reply)                                   \
5797 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5798 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5799 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5800 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5801 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5802 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5803 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5804 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5805 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5806 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5807 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5808 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5809   gpe_add_del_native_fwd_rpath_reply)                                   \
5810 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5811   gpe_fwd_entry_path_details)                                           \
5812 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5813 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5814   one_add_del_map_request_itr_rlocs_reply)                              \
5815 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5816   one_get_map_request_itr_rlocs_reply)                                  \
5817 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5818 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5819 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5820 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5821 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5822 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5823   show_one_map_register_state_reply)                                    \
5824 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5825 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5826   show_one_map_register_fallback_threshold_reply)                       \
5827 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5828 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5829 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5830 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5831 _(POLICER_DETAILS, policer_details)                                     \
5832 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5833 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5834 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5835 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5836 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5837 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5838 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5839 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5840 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5841 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5842 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5843 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5844 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5845 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5846 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5847 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5848 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5849 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5850 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5851 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5852 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5853 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5854 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5855 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5856 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5857  ip_source_and_port_range_check_add_del_reply)                          \
5858 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5859  ip_source_and_port_range_check_interface_add_del_reply)                \
5860 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5861 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5862 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5863 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5864 _(PUNT_REPLY, punt_reply)                                               \
5865 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5866 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5867 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5868 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5869 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5870 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5871 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5872 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5873 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5874 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5875 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5876 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5877 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5878 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5879 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5880 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5881 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5882 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5883 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5884 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5885 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5886 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5887 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)     \
5888 _(MAP_STATS_SEGMENT_REPLY, map_stats_segment_reply)
5889
5890 #define foreach_standalone_reply_msg                                    \
5891 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5892 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5893 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5894 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5895 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5896 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5897 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5898
5899 typedef struct
5900 {
5901   u8 *name;
5902   u32 value;
5903 } name_sort_t;
5904
5905 #define STR_VTR_OP_CASE(op)     \
5906     case L2_VTR_ ## op:         \
5907         return "" # op;
5908
5909 static const char *
5910 str_vtr_op (u32 vtr_op)
5911 {
5912   switch (vtr_op)
5913     {
5914       STR_VTR_OP_CASE (DISABLED);
5915       STR_VTR_OP_CASE (PUSH_1);
5916       STR_VTR_OP_CASE (PUSH_2);
5917       STR_VTR_OP_CASE (POP_1);
5918       STR_VTR_OP_CASE (POP_2);
5919       STR_VTR_OP_CASE (TRANSLATE_1_1);
5920       STR_VTR_OP_CASE (TRANSLATE_1_2);
5921       STR_VTR_OP_CASE (TRANSLATE_2_1);
5922       STR_VTR_OP_CASE (TRANSLATE_2_2);
5923     }
5924
5925   return "UNKNOWN";
5926 }
5927
5928 static int
5929 dump_sub_interface_table (vat_main_t * vam)
5930 {
5931   const sw_interface_subif_t *sub = NULL;
5932
5933   if (vam->json_output)
5934     {
5935       clib_warning
5936         ("JSON output supported only for VPE API calls and dump_stats_table");
5937       return -99;
5938     }
5939
5940   print (vam->ofp,
5941          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5942          "Interface", "sw_if_index",
5943          "sub id", "dot1ad", "tags", "outer id",
5944          "inner id", "exact", "default", "outer any", "inner any");
5945
5946   vec_foreach (sub, vam->sw_if_subif_table)
5947   {
5948     print (vam->ofp,
5949            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5950            sub->interface_name,
5951            sub->sw_if_index,
5952            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5953            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5954            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5955            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5956     if (sub->vtr_op != L2_VTR_DISABLED)
5957       {
5958         print (vam->ofp,
5959                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5960                "tag1: %d tag2: %d ]",
5961                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5962                sub->vtr_tag1, sub->vtr_tag2);
5963       }
5964   }
5965
5966   return 0;
5967 }
5968
5969 static int
5970 name_sort_cmp (void *a1, void *a2)
5971 {
5972   name_sort_t *n1 = a1;
5973   name_sort_t *n2 = a2;
5974
5975   return strcmp ((char *) n1->name, (char *) n2->name);
5976 }
5977
5978 static int
5979 dump_interface_table (vat_main_t * vam)
5980 {
5981   hash_pair_t *p;
5982   name_sort_t *nses = 0, *ns;
5983
5984   if (vam->json_output)
5985     {
5986       clib_warning
5987         ("JSON output supported only for VPE API calls and dump_stats_table");
5988       return -99;
5989     }
5990
5991   /* *INDENT-OFF* */
5992   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5993   ({
5994     vec_add2 (nses, ns, 1);
5995     ns->name = (u8 *)(p->key);
5996     ns->value = (u32) p->value[0];
5997   }));
5998   /* *INDENT-ON* */
5999
6000   vec_sort_with_function (nses, name_sort_cmp);
6001
6002   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6003   vec_foreach (ns, nses)
6004   {
6005     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6006   }
6007   vec_free (nses);
6008   return 0;
6009 }
6010
6011 static int
6012 dump_ip_table (vat_main_t * vam, int is_ipv6)
6013 {
6014   const ip_details_t *det = NULL;
6015   const ip_address_details_t *address = NULL;
6016   u32 i = ~0;
6017
6018   print (vam->ofp, "%-12s", "sw_if_index");
6019
6020   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6021   {
6022     i++;
6023     if (!det->present)
6024       {
6025         continue;
6026       }
6027     print (vam->ofp, "%-12d", i);
6028     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6029     if (!det->addr)
6030       {
6031         continue;
6032       }
6033     vec_foreach (address, det->addr)
6034     {
6035       print (vam->ofp,
6036              "            %-30U%-13d",
6037              is_ipv6 ? format_ip6_address : format_ip4_address,
6038              address->ip, address->prefix_length);
6039     }
6040   }
6041
6042   return 0;
6043 }
6044
6045 static int
6046 dump_ipv4_table (vat_main_t * vam)
6047 {
6048   if (vam->json_output)
6049     {
6050       clib_warning
6051         ("JSON output supported only for VPE API calls and dump_stats_table");
6052       return -99;
6053     }
6054
6055   return dump_ip_table (vam, 0);
6056 }
6057
6058 static int
6059 dump_ipv6_table (vat_main_t * vam)
6060 {
6061   if (vam->json_output)
6062     {
6063       clib_warning
6064         ("JSON output supported only for VPE API calls and dump_stats_table");
6065       return -99;
6066     }
6067
6068   return dump_ip_table (vam, 1);
6069 }
6070
6071 static char *
6072 counter_type_to_str (u8 counter_type, u8 is_combined)
6073 {
6074   if (!is_combined)
6075     {
6076       switch (counter_type)
6077         {
6078         case VNET_INTERFACE_COUNTER_DROP:
6079           return "drop";
6080         case VNET_INTERFACE_COUNTER_PUNT:
6081           return "punt";
6082         case VNET_INTERFACE_COUNTER_IP4:
6083           return "ip4";
6084         case VNET_INTERFACE_COUNTER_IP6:
6085           return "ip6";
6086         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6087           return "rx-no-buf";
6088         case VNET_INTERFACE_COUNTER_RX_MISS:
6089           return "rx-miss";
6090         case VNET_INTERFACE_COUNTER_RX_ERROR:
6091           return "rx-error";
6092         case VNET_INTERFACE_COUNTER_TX_ERROR:
6093           return "tx-error";
6094         default:
6095           return "INVALID-COUNTER-TYPE";
6096         }
6097     }
6098   else
6099     {
6100       switch (counter_type)
6101         {
6102         case VNET_INTERFACE_COUNTER_RX:
6103           return "rx";
6104         case VNET_INTERFACE_COUNTER_TX:
6105           return "tx";
6106         default:
6107           return "INVALID-COUNTER-TYPE";
6108         }
6109     }
6110 }
6111
6112 static int
6113 dump_stats_table (vat_main_t * vam)
6114 {
6115   vat_json_node_t node;
6116   vat_json_node_t *msg_array;
6117   vat_json_node_t *msg;
6118   vat_json_node_t *counter_array;
6119   vat_json_node_t *counter;
6120   interface_counter_t c;
6121   u64 packets;
6122   ip4_fib_counter_t *c4;
6123   ip6_fib_counter_t *c6;
6124   ip4_nbr_counter_t *n4;
6125   ip6_nbr_counter_t *n6;
6126   int i, j;
6127
6128   if (!vam->json_output)
6129     {
6130       clib_warning ("dump_stats_table supported only in JSON format");
6131       return -99;
6132     }
6133
6134   vat_json_init_object (&node);
6135
6136   /* interface counters */
6137   msg_array = vat_json_object_add (&node, "interface_counters");
6138   vat_json_init_array (msg_array);
6139   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6140     {
6141       msg = vat_json_array_add (msg_array);
6142       vat_json_init_object (msg);
6143       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6144                                        (u8 *) counter_type_to_str (i, 0));
6145       vat_json_object_add_int (msg, "is_combined", 0);
6146       counter_array = vat_json_object_add (msg, "data");
6147       vat_json_init_array (counter_array);
6148       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6149         {
6150           packets = vam->simple_interface_counters[i][j];
6151           vat_json_array_add_uint (counter_array, packets);
6152         }
6153     }
6154   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6155     {
6156       msg = vat_json_array_add (msg_array);
6157       vat_json_init_object (msg);
6158       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6159                                        (u8 *) counter_type_to_str (i, 1));
6160       vat_json_object_add_int (msg, "is_combined", 1);
6161       counter_array = vat_json_object_add (msg, "data");
6162       vat_json_init_array (counter_array);
6163       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6164         {
6165           c = vam->combined_interface_counters[i][j];
6166           counter = vat_json_array_add (counter_array);
6167           vat_json_init_object (counter);
6168           vat_json_object_add_uint (counter, "packets", c.packets);
6169           vat_json_object_add_uint (counter, "bytes", c.bytes);
6170         }
6171     }
6172
6173   /* ip4 fib counters */
6174   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6175   vat_json_init_array (msg_array);
6176   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6177     {
6178       msg = vat_json_array_add (msg_array);
6179       vat_json_init_object (msg);
6180       vat_json_object_add_uint (msg, "vrf_id",
6181                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6182       counter_array = vat_json_object_add (msg, "c");
6183       vat_json_init_array (counter_array);
6184       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6185         {
6186           counter = vat_json_array_add (counter_array);
6187           vat_json_init_object (counter);
6188           c4 = &vam->ip4_fib_counters[i][j];
6189           vat_json_object_add_ip4 (counter, "address", c4->address);
6190           vat_json_object_add_uint (counter, "address_length",
6191                                     c4->address_length);
6192           vat_json_object_add_uint (counter, "packets", c4->packets);
6193           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6194         }
6195     }
6196
6197   /* ip6 fib counters */
6198   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6199   vat_json_init_array (msg_array);
6200   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6201     {
6202       msg = vat_json_array_add (msg_array);
6203       vat_json_init_object (msg);
6204       vat_json_object_add_uint (msg, "vrf_id",
6205                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6206       counter_array = vat_json_object_add (msg, "c");
6207       vat_json_init_array (counter_array);
6208       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6209         {
6210           counter = vat_json_array_add (counter_array);
6211           vat_json_init_object (counter);
6212           c6 = &vam->ip6_fib_counters[i][j];
6213           vat_json_object_add_ip6 (counter, "address", c6->address);
6214           vat_json_object_add_uint (counter, "address_length",
6215                                     c6->address_length);
6216           vat_json_object_add_uint (counter, "packets", c6->packets);
6217           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6218         }
6219     }
6220
6221   /* ip4 nbr counters */
6222   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6223   vat_json_init_array (msg_array);
6224   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6225     {
6226       msg = vat_json_array_add (msg_array);
6227       vat_json_init_object (msg);
6228       vat_json_object_add_uint (msg, "sw_if_index", i);
6229       counter_array = vat_json_object_add (msg, "c");
6230       vat_json_init_array (counter_array);
6231       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6232         {
6233           counter = vat_json_array_add (counter_array);
6234           vat_json_init_object (counter);
6235           n4 = &vam->ip4_nbr_counters[i][j];
6236           vat_json_object_add_ip4 (counter, "address", n4->address);
6237           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6238           vat_json_object_add_uint (counter, "packets", n4->packets);
6239           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6240         }
6241     }
6242
6243   /* ip6 nbr counters */
6244   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6245   vat_json_init_array (msg_array);
6246   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6247     {
6248       msg = vat_json_array_add (msg_array);
6249       vat_json_init_object (msg);
6250       vat_json_object_add_uint (msg, "sw_if_index", i);
6251       counter_array = vat_json_object_add (msg, "c");
6252       vat_json_init_array (counter_array);
6253       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6254         {
6255           counter = vat_json_array_add (counter_array);
6256           vat_json_init_object (counter);
6257           n6 = &vam->ip6_nbr_counters[i][j];
6258           vat_json_object_add_ip6 (counter, "address", n6->address);
6259           vat_json_object_add_uint (counter, "packets", n6->packets);
6260           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6261         }
6262     }
6263
6264   vat_json_print (vam->ofp, &node);
6265   vat_json_free (&node);
6266
6267   return 0;
6268 }
6269
6270 /*
6271  * Pass CLI buffers directly in the CLI_INBAND API message,
6272  * instead of an additional shared memory area.
6273  */
6274 static int
6275 exec_inband (vat_main_t * vam)
6276 {
6277   vl_api_cli_inband_t *mp;
6278   unformat_input_t *i = vam->input;
6279   int ret;
6280
6281   if (vec_len (i->buffer) == 0)
6282     return -1;
6283
6284   if (vam->exec_mode == 0 && unformat (i, "mode"))
6285     {
6286       vam->exec_mode = 1;
6287       return 0;
6288     }
6289   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6290     {
6291       vam->exec_mode = 0;
6292       return 0;
6293     }
6294
6295   /*
6296    * In order for the CLI command to work, it
6297    * must be a vector ending in \n, not a C-string ending
6298    * in \n\0.
6299    */
6300   u32 len = vec_len (vam->input->buffer);
6301   M2 (CLI_INBAND, mp, len);
6302   clib_memcpy (mp->cmd, vam->input->buffer, len);
6303   mp->length = htonl (len);
6304
6305   S (mp);
6306   W (ret);
6307   /* json responses may or may not include a useful reply... */
6308   if (vec_len (vam->cmd_reply))
6309     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6310   return ret;
6311 }
6312
6313 int
6314 exec (vat_main_t * vam)
6315 {
6316   return exec_inband (vam);
6317 }
6318
6319 static int
6320 api_create_loopback (vat_main_t * vam)
6321 {
6322   unformat_input_t *i = vam->input;
6323   vl_api_create_loopback_t *mp;
6324   vl_api_create_loopback_instance_t *mp_lbi;
6325   u8 mac_address[6];
6326   u8 mac_set = 0;
6327   u8 is_specified = 0;
6328   u32 user_instance = 0;
6329   int ret;
6330
6331   memset (mac_address, 0, sizeof (mac_address));
6332
6333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6334     {
6335       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6336         mac_set = 1;
6337       if (unformat (i, "instance %d", &user_instance))
6338         is_specified = 1;
6339       else
6340         break;
6341     }
6342
6343   if (is_specified)
6344     {
6345       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6346       mp_lbi->is_specified = is_specified;
6347       if (is_specified)
6348         mp_lbi->user_instance = htonl (user_instance);
6349       if (mac_set)
6350         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6351       S (mp_lbi);
6352     }
6353   else
6354     {
6355       /* Construct the API message */
6356       M (CREATE_LOOPBACK, mp);
6357       if (mac_set)
6358         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6359       S (mp);
6360     }
6361
6362   W (ret);
6363   return ret;
6364 }
6365
6366 static int
6367 api_delete_loopback (vat_main_t * vam)
6368 {
6369   unformat_input_t *i = vam->input;
6370   vl_api_delete_loopback_t *mp;
6371   u32 sw_if_index = ~0;
6372   int ret;
6373
6374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6375     {
6376       if (unformat (i, "sw_if_index %d", &sw_if_index))
6377         ;
6378       else
6379         break;
6380     }
6381
6382   if (sw_if_index == ~0)
6383     {
6384       errmsg ("missing sw_if_index");
6385       return -99;
6386     }
6387
6388   /* Construct the API message */
6389   M (DELETE_LOOPBACK, mp);
6390   mp->sw_if_index = ntohl (sw_if_index);
6391
6392   S (mp);
6393   W (ret);
6394   return ret;
6395 }
6396
6397 static int
6398 api_want_stats (vat_main_t * vam)
6399 {
6400   unformat_input_t *i = vam->input;
6401   vl_api_want_stats_t *mp;
6402   int enable = -1;
6403   int ret;
6404
6405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6406     {
6407       if (unformat (i, "enable"))
6408         enable = 1;
6409       else if (unformat (i, "disable"))
6410         enable = 0;
6411       else
6412         break;
6413     }
6414
6415   if (enable == -1)
6416     {
6417       errmsg ("missing enable|disable");
6418       return -99;
6419     }
6420
6421   M (WANT_STATS, mp);
6422   mp->enable_disable = enable;
6423
6424   S (mp);
6425   W (ret);
6426   return ret;
6427 }
6428
6429 static int
6430 api_want_interface_events (vat_main_t * vam)
6431 {
6432   unformat_input_t *i = vam->input;
6433   vl_api_want_interface_events_t *mp;
6434   int enable = -1;
6435   int ret;
6436
6437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6438     {
6439       if (unformat (i, "enable"))
6440         enable = 1;
6441       else if (unformat (i, "disable"))
6442         enable = 0;
6443       else
6444         break;
6445     }
6446
6447   if (enable == -1)
6448     {
6449       errmsg ("missing enable|disable");
6450       return -99;
6451     }
6452
6453   M (WANT_INTERFACE_EVENTS, mp);
6454   mp->enable_disable = enable;
6455
6456   vam->interface_event_display = enable;
6457
6458   S (mp);
6459   W (ret);
6460   return ret;
6461 }
6462
6463
6464 /* Note: non-static, called once to set up the initial intfc table */
6465 int
6466 api_sw_interface_dump (vat_main_t * vam)
6467 {
6468   vl_api_sw_interface_dump_t *mp;
6469   vl_api_control_ping_t *mp_ping;
6470   hash_pair_t *p;
6471   name_sort_t *nses = 0, *ns;
6472   sw_interface_subif_t *sub = NULL;
6473   int ret;
6474
6475   /* Toss the old name table */
6476   /* *INDENT-OFF* */
6477   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6478   ({
6479     vec_add2 (nses, ns, 1);
6480     ns->name = (u8 *)(p->key);
6481     ns->value = (u32) p->value[0];
6482   }));
6483   /* *INDENT-ON* */
6484
6485   hash_free (vam->sw_if_index_by_interface_name);
6486
6487   vec_foreach (ns, nses) vec_free (ns->name);
6488
6489   vec_free (nses);
6490
6491   vec_foreach (sub, vam->sw_if_subif_table)
6492   {
6493     vec_free (sub->interface_name);
6494   }
6495   vec_free (vam->sw_if_subif_table);
6496
6497   /* recreate the interface name hash table */
6498   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6499
6500   /*
6501    * Ask for all interface names. Otherwise, the epic catalog of
6502    * name filters becomes ridiculously long, and vat ends up needing
6503    * to be taught about new interface types.
6504    */
6505   M (SW_INTERFACE_DUMP, mp);
6506   S (mp);
6507
6508   /* Use a control ping for synchronization */
6509   MPING (CONTROL_PING, mp_ping);
6510   S (mp_ping);
6511
6512   W (ret);
6513   return ret;
6514 }
6515
6516 static int
6517 api_sw_interface_set_flags (vat_main_t * vam)
6518 {
6519   unformat_input_t *i = vam->input;
6520   vl_api_sw_interface_set_flags_t *mp;
6521   u32 sw_if_index;
6522   u8 sw_if_index_set = 0;
6523   u8 admin_up = 0;
6524   int ret;
6525
6526   /* Parse args required to build the message */
6527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6528     {
6529       if (unformat (i, "admin-up"))
6530         admin_up = 1;
6531       else if (unformat (i, "admin-down"))
6532         admin_up = 0;
6533       else
6534         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6535         sw_if_index_set = 1;
6536       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6537         sw_if_index_set = 1;
6538       else
6539         break;
6540     }
6541
6542   if (sw_if_index_set == 0)
6543     {
6544       errmsg ("missing interface name or sw_if_index");
6545       return -99;
6546     }
6547
6548   /* Construct the API message */
6549   M (SW_INTERFACE_SET_FLAGS, mp);
6550   mp->sw_if_index = ntohl (sw_if_index);
6551   mp->admin_up_down = admin_up;
6552
6553   /* send it... */
6554   S (mp);
6555
6556   /* Wait for a reply, return the good/bad news... */
6557   W (ret);
6558   return ret;
6559 }
6560
6561 static int
6562 api_sw_interface_set_rx_mode (vat_main_t * vam)
6563 {
6564   unformat_input_t *i = vam->input;
6565   vl_api_sw_interface_set_rx_mode_t *mp;
6566   u32 sw_if_index;
6567   u8 sw_if_index_set = 0;
6568   int ret;
6569   u8 queue_id_valid = 0;
6570   u32 queue_id;
6571   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6572
6573   /* Parse args required to build the message */
6574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6575     {
6576       if (unformat (i, "queue %d", &queue_id))
6577         queue_id_valid = 1;
6578       else if (unformat (i, "polling"))
6579         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6580       else if (unformat (i, "interrupt"))
6581         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6582       else if (unformat (i, "adaptive"))
6583         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6584       else
6585         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6586         sw_if_index_set = 1;
6587       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6588         sw_if_index_set = 1;
6589       else
6590         break;
6591     }
6592
6593   if (sw_if_index_set == 0)
6594     {
6595       errmsg ("missing interface name or sw_if_index");
6596       return -99;
6597     }
6598   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6599     {
6600       errmsg ("missing rx-mode");
6601       return -99;
6602     }
6603
6604   /* Construct the API message */
6605   M (SW_INTERFACE_SET_RX_MODE, mp);
6606   mp->sw_if_index = ntohl (sw_if_index);
6607   mp->mode = mode;
6608   mp->queue_id_valid = queue_id_valid;
6609   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6610
6611   /* send it... */
6612   S (mp);
6613
6614   /* Wait for a reply, return the good/bad news... */
6615   W (ret);
6616   return ret;
6617 }
6618
6619 static int
6620 api_sw_interface_clear_stats (vat_main_t * vam)
6621 {
6622   unformat_input_t *i = vam->input;
6623   vl_api_sw_interface_clear_stats_t *mp;
6624   u32 sw_if_index;
6625   u8 sw_if_index_set = 0;
6626   int ret;
6627
6628   /* Parse args required to build the message */
6629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6630     {
6631       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6632         sw_if_index_set = 1;
6633       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6634         sw_if_index_set = 1;
6635       else
6636         break;
6637     }
6638
6639   /* Construct the API message */
6640   M (SW_INTERFACE_CLEAR_STATS, mp);
6641
6642   if (sw_if_index_set == 1)
6643     mp->sw_if_index = ntohl (sw_if_index);
6644   else
6645     mp->sw_if_index = ~0;
6646
6647   /* send it... */
6648   S (mp);
6649
6650   /* Wait for a reply, return the good/bad news... */
6651   W (ret);
6652   return ret;
6653 }
6654
6655 static int
6656 api_sw_interface_add_del_address (vat_main_t * vam)
6657 {
6658   unformat_input_t *i = vam->input;
6659   vl_api_sw_interface_add_del_address_t *mp;
6660   u32 sw_if_index;
6661   u8 sw_if_index_set = 0;
6662   u8 is_add = 1, del_all = 0;
6663   u32 address_length = 0;
6664   u8 v4_address_set = 0;
6665   u8 v6_address_set = 0;
6666   ip4_address_t v4address;
6667   ip6_address_t v6address;
6668   int ret;
6669
6670   /* Parse args required to build the message */
6671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6672     {
6673       if (unformat (i, "del-all"))
6674         del_all = 1;
6675       else if (unformat (i, "del"))
6676         is_add = 0;
6677       else
6678         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6679         sw_if_index_set = 1;
6680       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6681         sw_if_index_set = 1;
6682       else if (unformat (i, "%U/%d",
6683                          unformat_ip4_address, &v4address, &address_length))
6684         v4_address_set = 1;
6685       else if (unformat (i, "%U/%d",
6686                          unformat_ip6_address, &v6address, &address_length))
6687         v6_address_set = 1;
6688       else
6689         break;
6690     }
6691
6692   if (sw_if_index_set == 0)
6693     {
6694       errmsg ("missing interface name or sw_if_index");
6695       return -99;
6696     }
6697   if (v4_address_set && v6_address_set)
6698     {
6699       errmsg ("both v4 and v6 addresses set");
6700       return -99;
6701     }
6702   if (!v4_address_set && !v6_address_set && !del_all)
6703     {
6704       errmsg ("no addresses set");
6705       return -99;
6706     }
6707
6708   /* Construct the API message */
6709   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6710
6711   mp->sw_if_index = ntohl (sw_if_index);
6712   mp->is_add = is_add;
6713   mp->del_all = del_all;
6714   if (v6_address_set)
6715     {
6716       mp->is_ipv6 = 1;
6717       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6718     }
6719   else
6720     {
6721       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6722     }
6723   mp->address_length = address_length;
6724
6725   /* send it... */
6726   S (mp);
6727
6728   /* Wait for a reply, return good/bad news  */
6729   W (ret);
6730   return ret;
6731 }
6732
6733 static int
6734 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6735 {
6736   unformat_input_t *i = vam->input;
6737   vl_api_sw_interface_set_mpls_enable_t *mp;
6738   u32 sw_if_index;
6739   u8 sw_if_index_set = 0;
6740   u8 enable = 1;
6741   int ret;
6742
6743   /* Parse args required to build the message */
6744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6745     {
6746       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6747         sw_if_index_set = 1;
6748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6749         sw_if_index_set = 1;
6750       else if (unformat (i, "disable"))
6751         enable = 0;
6752       else if (unformat (i, "dis"))
6753         enable = 0;
6754       else
6755         break;
6756     }
6757
6758   if (sw_if_index_set == 0)
6759     {
6760       errmsg ("missing interface name or sw_if_index");
6761       return -99;
6762     }
6763
6764   /* Construct the API message */
6765   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6766
6767   mp->sw_if_index = ntohl (sw_if_index);
6768   mp->enable = enable;
6769
6770   /* send it... */
6771   S (mp);
6772
6773   /* Wait for a reply... */
6774   W (ret);
6775   return ret;
6776 }
6777
6778 static int
6779 api_sw_interface_set_table (vat_main_t * vam)
6780 {
6781   unformat_input_t *i = vam->input;
6782   vl_api_sw_interface_set_table_t *mp;
6783   u32 sw_if_index, vrf_id = 0;
6784   u8 sw_if_index_set = 0;
6785   u8 is_ipv6 = 0;
6786   int ret;
6787
6788   /* Parse args required to build the message */
6789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6790     {
6791       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6792         sw_if_index_set = 1;
6793       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6794         sw_if_index_set = 1;
6795       else if (unformat (i, "vrf %d", &vrf_id))
6796         ;
6797       else if (unformat (i, "ipv6"))
6798         is_ipv6 = 1;
6799       else
6800         break;
6801     }
6802
6803   if (sw_if_index_set == 0)
6804     {
6805       errmsg ("missing interface name or sw_if_index");
6806       return -99;
6807     }
6808
6809   /* Construct the API message */
6810   M (SW_INTERFACE_SET_TABLE, mp);
6811
6812   mp->sw_if_index = ntohl (sw_if_index);
6813   mp->is_ipv6 = is_ipv6;
6814   mp->vrf_id = ntohl (vrf_id);
6815
6816   /* send it... */
6817   S (mp);
6818
6819   /* Wait for a reply... */
6820   W (ret);
6821   return ret;
6822 }
6823
6824 static void vl_api_sw_interface_get_table_reply_t_handler
6825   (vl_api_sw_interface_get_table_reply_t * mp)
6826 {
6827   vat_main_t *vam = &vat_main;
6828
6829   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6830
6831   vam->retval = ntohl (mp->retval);
6832   vam->result_ready = 1;
6833
6834 }
6835
6836 static void vl_api_sw_interface_get_table_reply_t_handler_json
6837   (vl_api_sw_interface_get_table_reply_t * mp)
6838 {
6839   vat_main_t *vam = &vat_main;
6840   vat_json_node_t node;
6841
6842   vat_json_init_object (&node);
6843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6844   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6845
6846   vat_json_print (vam->ofp, &node);
6847   vat_json_free (&node);
6848
6849   vam->retval = ntohl (mp->retval);
6850   vam->result_ready = 1;
6851 }
6852
6853 static int
6854 api_sw_interface_get_table (vat_main_t * vam)
6855 {
6856   unformat_input_t *i = vam->input;
6857   vl_api_sw_interface_get_table_t *mp;
6858   u32 sw_if_index;
6859   u8 sw_if_index_set = 0;
6860   u8 is_ipv6 = 0;
6861   int ret;
6862
6863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6864     {
6865       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6866         sw_if_index_set = 1;
6867       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6868         sw_if_index_set = 1;
6869       else if (unformat (i, "ipv6"))
6870         is_ipv6 = 1;
6871       else
6872         break;
6873     }
6874
6875   if (sw_if_index_set == 0)
6876     {
6877       errmsg ("missing interface name or sw_if_index");
6878       return -99;
6879     }
6880
6881   M (SW_INTERFACE_GET_TABLE, mp);
6882   mp->sw_if_index = htonl (sw_if_index);
6883   mp->is_ipv6 = is_ipv6;
6884
6885   S (mp);
6886   W (ret);
6887   return ret;
6888 }
6889
6890 static int
6891 api_sw_interface_set_vpath (vat_main_t * vam)
6892 {
6893   unformat_input_t *i = vam->input;
6894   vl_api_sw_interface_set_vpath_t *mp;
6895   u32 sw_if_index = 0;
6896   u8 sw_if_index_set = 0;
6897   u8 is_enable = 0;
6898   int ret;
6899
6900   /* Parse args required to build the message */
6901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6902     {
6903       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6904         sw_if_index_set = 1;
6905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6906         sw_if_index_set = 1;
6907       else if (unformat (i, "enable"))
6908         is_enable = 1;
6909       else if (unformat (i, "disable"))
6910         is_enable = 0;
6911       else
6912         break;
6913     }
6914
6915   if (sw_if_index_set == 0)
6916     {
6917       errmsg ("missing interface name or sw_if_index");
6918       return -99;
6919     }
6920
6921   /* Construct the API message */
6922   M (SW_INTERFACE_SET_VPATH, mp);
6923
6924   mp->sw_if_index = ntohl (sw_if_index);
6925   mp->enable = is_enable;
6926
6927   /* send it... */
6928   S (mp);
6929
6930   /* Wait for a reply... */
6931   W (ret);
6932   return ret;
6933 }
6934
6935 static int
6936 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6937 {
6938   unformat_input_t *i = vam->input;
6939   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6940   u32 sw_if_index = 0;
6941   u8 sw_if_index_set = 0;
6942   u8 is_enable = 1;
6943   u8 is_ipv6 = 0;
6944   int ret;
6945
6946   /* Parse args required to build the message */
6947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6948     {
6949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6950         sw_if_index_set = 1;
6951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6952         sw_if_index_set = 1;
6953       else if (unformat (i, "enable"))
6954         is_enable = 1;
6955       else if (unformat (i, "disable"))
6956         is_enable = 0;
6957       else if (unformat (i, "ip4"))
6958         is_ipv6 = 0;
6959       else if (unformat (i, "ip6"))
6960         is_ipv6 = 1;
6961       else
6962         break;
6963     }
6964
6965   if (sw_if_index_set == 0)
6966     {
6967       errmsg ("missing interface name or sw_if_index");
6968       return -99;
6969     }
6970
6971   /* Construct the API message */
6972   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6973
6974   mp->sw_if_index = ntohl (sw_if_index);
6975   mp->enable = is_enable;
6976   mp->is_ipv6 = is_ipv6;
6977
6978   /* send it... */
6979   S (mp);
6980
6981   /* Wait for a reply... */
6982   W (ret);
6983   return ret;
6984 }
6985
6986 static int
6987 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6988 {
6989   unformat_input_t *i = vam->input;
6990   vl_api_sw_interface_set_geneve_bypass_t *mp;
6991   u32 sw_if_index = 0;
6992   u8 sw_if_index_set = 0;
6993   u8 is_enable = 1;
6994   u8 is_ipv6 = 0;
6995   int ret;
6996
6997   /* Parse args required to build the message */
6998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6999     {
7000       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7001         sw_if_index_set = 1;
7002       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7003         sw_if_index_set = 1;
7004       else if (unformat (i, "enable"))
7005         is_enable = 1;
7006       else if (unformat (i, "disable"))
7007         is_enable = 0;
7008       else if (unformat (i, "ip4"))
7009         is_ipv6 = 0;
7010       else if (unformat (i, "ip6"))
7011         is_ipv6 = 1;
7012       else
7013         break;
7014     }
7015
7016   if (sw_if_index_set == 0)
7017     {
7018       errmsg ("missing interface name or sw_if_index");
7019       return -99;
7020     }
7021
7022   /* Construct the API message */
7023   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7024
7025   mp->sw_if_index = ntohl (sw_if_index);
7026   mp->enable = is_enable;
7027   mp->is_ipv6 = is_ipv6;
7028
7029   /* send it... */
7030   S (mp);
7031
7032   /* Wait for a reply... */
7033   W (ret);
7034   return ret;
7035 }
7036
7037 static int
7038 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7039 {
7040   unformat_input_t *i = vam->input;
7041   vl_api_sw_interface_set_l2_xconnect_t *mp;
7042   u32 rx_sw_if_index;
7043   u8 rx_sw_if_index_set = 0;
7044   u32 tx_sw_if_index;
7045   u8 tx_sw_if_index_set = 0;
7046   u8 enable = 1;
7047   int ret;
7048
7049   /* Parse args required to build the message */
7050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7051     {
7052       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7053         rx_sw_if_index_set = 1;
7054       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7055         tx_sw_if_index_set = 1;
7056       else if (unformat (i, "rx"))
7057         {
7058           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7059             {
7060               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7061                             &rx_sw_if_index))
7062                 rx_sw_if_index_set = 1;
7063             }
7064           else
7065             break;
7066         }
7067       else if (unformat (i, "tx"))
7068         {
7069           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7070             {
7071               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7072                             &tx_sw_if_index))
7073                 tx_sw_if_index_set = 1;
7074             }
7075           else
7076             break;
7077         }
7078       else if (unformat (i, "enable"))
7079         enable = 1;
7080       else if (unformat (i, "disable"))
7081         enable = 0;
7082       else
7083         break;
7084     }
7085
7086   if (rx_sw_if_index_set == 0)
7087     {
7088       errmsg ("missing rx interface name or rx_sw_if_index");
7089       return -99;
7090     }
7091
7092   if (enable && (tx_sw_if_index_set == 0))
7093     {
7094       errmsg ("missing tx interface name or tx_sw_if_index");
7095       return -99;
7096     }
7097
7098   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7099
7100   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7101   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7102   mp->enable = enable;
7103
7104   S (mp);
7105   W (ret);
7106   return ret;
7107 }
7108
7109 static int
7110 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7111 {
7112   unformat_input_t *i = vam->input;
7113   vl_api_sw_interface_set_l2_bridge_t *mp;
7114   u32 rx_sw_if_index;
7115   u8 rx_sw_if_index_set = 0;
7116   u32 bd_id;
7117   u8 bd_id_set = 0;
7118   u8 bvi = 0;
7119   u32 shg = 0;
7120   u8 enable = 1;
7121   int ret;
7122
7123   /* Parse args required to build the message */
7124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7125     {
7126       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7127         rx_sw_if_index_set = 1;
7128       else if (unformat (i, "bd_id %d", &bd_id))
7129         bd_id_set = 1;
7130       else
7131         if (unformat
7132             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7133         rx_sw_if_index_set = 1;
7134       else if (unformat (i, "shg %d", &shg))
7135         ;
7136       else if (unformat (i, "bvi"))
7137         bvi = 1;
7138       else if (unformat (i, "enable"))
7139         enable = 1;
7140       else if (unformat (i, "disable"))
7141         enable = 0;
7142       else
7143         break;
7144     }
7145
7146   if (rx_sw_if_index_set == 0)
7147     {
7148       errmsg ("missing rx interface name or sw_if_index");
7149       return -99;
7150     }
7151
7152   if (enable && (bd_id_set == 0))
7153     {
7154       errmsg ("missing bridge domain");
7155       return -99;
7156     }
7157
7158   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7159
7160   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7161   mp->bd_id = ntohl (bd_id);
7162   mp->shg = (u8) shg;
7163   mp->bvi = bvi;
7164   mp->enable = enable;
7165
7166   S (mp);
7167   W (ret);
7168   return ret;
7169 }
7170
7171 static int
7172 api_bridge_domain_dump (vat_main_t * vam)
7173 {
7174   unformat_input_t *i = vam->input;
7175   vl_api_bridge_domain_dump_t *mp;
7176   vl_api_control_ping_t *mp_ping;
7177   u32 bd_id = ~0;
7178   int ret;
7179
7180   /* Parse args required to build the message */
7181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7182     {
7183       if (unformat (i, "bd_id %d", &bd_id))
7184         ;
7185       else
7186         break;
7187     }
7188
7189   M (BRIDGE_DOMAIN_DUMP, mp);
7190   mp->bd_id = ntohl (bd_id);
7191   S (mp);
7192
7193   /* Use a control ping for synchronization */
7194   MPING (CONTROL_PING, mp_ping);
7195   S (mp_ping);
7196
7197   W (ret);
7198   return ret;
7199 }
7200
7201 static int
7202 api_bridge_domain_add_del (vat_main_t * vam)
7203 {
7204   unformat_input_t *i = vam->input;
7205   vl_api_bridge_domain_add_del_t *mp;
7206   u32 bd_id = ~0;
7207   u8 is_add = 1;
7208   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7209   u8 *bd_tag = NULL;
7210   u32 mac_age = 0;
7211   int ret;
7212
7213   /* Parse args required to build the message */
7214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7215     {
7216       if (unformat (i, "bd_id %d", &bd_id))
7217         ;
7218       else if (unformat (i, "flood %d", &flood))
7219         ;
7220       else if (unformat (i, "uu-flood %d", &uu_flood))
7221         ;
7222       else if (unformat (i, "forward %d", &forward))
7223         ;
7224       else if (unformat (i, "learn %d", &learn))
7225         ;
7226       else if (unformat (i, "arp-term %d", &arp_term))
7227         ;
7228       else if (unformat (i, "mac-age %d", &mac_age))
7229         ;
7230       else if (unformat (i, "bd-tag %s", &bd_tag))
7231         ;
7232       else if (unformat (i, "del"))
7233         {
7234           is_add = 0;
7235           flood = uu_flood = forward = learn = 0;
7236         }
7237       else
7238         break;
7239     }
7240
7241   if (bd_id == ~0)
7242     {
7243       errmsg ("missing bridge domain");
7244       ret = -99;
7245       goto done;
7246     }
7247
7248   if (mac_age > 255)
7249     {
7250       errmsg ("mac age must be less than 256 ");
7251       ret = -99;
7252       goto done;
7253     }
7254
7255   if ((bd_tag) && (vec_len (bd_tag) > 63))
7256     {
7257       errmsg ("bd-tag cannot be longer than 63");
7258       ret = -99;
7259       goto done;
7260     }
7261
7262   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7263
7264   mp->bd_id = ntohl (bd_id);
7265   mp->flood = flood;
7266   mp->uu_flood = uu_flood;
7267   mp->forward = forward;
7268   mp->learn = learn;
7269   mp->arp_term = arp_term;
7270   mp->is_add = is_add;
7271   mp->mac_age = (u8) mac_age;
7272   if (bd_tag)
7273     {
7274       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7275       mp->bd_tag[vec_len (bd_tag)] = 0;
7276     }
7277   S (mp);
7278   W (ret);
7279
7280 done:
7281   vec_free (bd_tag);
7282   return ret;
7283 }
7284
7285 static int
7286 api_l2fib_flush_bd (vat_main_t * vam)
7287 {
7288   unformat_input_t *i = vam->input;
7289   vl_api_l2fib_flush_bd_t *mp;
7290   u32 bd_id = ~0;
7291   int ret;
7292
7293   /* Parse args required to build the message */
7294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7295     {
7296       if (unformat (i, "bd_id %d", &bd_id));
7297       else
7298         break;
7299     }
7300
7301   if (bd_id == ~0)
7302     {
7303       errmsg ("missing bridge domain");
7304       return -99;
7305     }
7306
7307   M (L2FIB_FLUSH_BD, mp);
7308
7309   mp->bd_id = htonl (bd_id);
7310
7311   S (mp);
7312   W (ret);
7313   return ret;
7314 }
7315
7316 static int
7317 api_l2fib_flush_int (vat_main_t * vam)
7318 {
7319   unformat_input_t *i = vam->input;
7320   vl_api_l2fib_flush_int_t *mp;
7321   u32 sw_if_index = ~0;
7322   int ret;
7323
7324   /* Parse args required to build the message */
7325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7326     {
7327       if (unformat (i, "sw_if_index %d", &sw_if_index));
7328       else
7329         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7330       else
7331         break;
7332     }
7333
7334   if (sw_if_index == ~0)
7335     {
7336       errmsg ("missing interface name or sw_if_index");
7337       return -99;
7338     }
7339
7340   M (L2FIB_FLUSH_INT, mp);
7341
7342   mp->sw_if_index = ntohl (sw_if_index);
7343
7344   S (mp);
7345   W (ret);
7346   return ret;
7347 }
7348
7349 static int
7350 api_l2fib_add_del (vat_main_t * vam)
7351 {
7352   unformat_input_t *i = vam->input;
7353   vl_api_l2fib_add_del_t *mp;
7354   f64 timeout;
7355   u8 mac[6] = { 0 };
7356   u8 mac_set = 0;
7357   u32 bd_id;
7358   u8 bd_id_set = 0;
7359   u32 sw_if_index = 0;
7360   u8 sw_if_index_set = 0;
7361   u8 is_add = 1;
7362   u8 static_mac = 0;
7363   u8 filter_mac = 0;
7364   u8 bvi_mac = 0;
7365   int count = 1;
7366   f64 before = 0;
7367   int j;
7368
7369   /* Parse args required to build the message */
7370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7371     {
7372       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7373         mac_set = 1;
7374       else if (unformat (i, "bd_id %d", &bd_id))
7375         bd_id_set = 1;
7376       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7377         sw_if_index_set = 1;
7378       else if (unformat (i, "sw_if"))
7379         {
7380           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7381             {
7382               if (unformat
7383                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7384                 sw_if_index_set = 1;
7385             }
7386           else
7387             break;
7388         }
7389       else if (unformat (i, "static"))
7390         static_mac = 1;
7391       else if (unformat (i, "filter"))
7392         {
7393           filter_mac = 1;
7394           static_mac = 1;
7395         }
7396       else if (unformat (i, "bvi"))
7397         {
7398           bvi_mac = 1;
7399           static_mac = 1;
7400         }
7401       else if (unformat (i, "del"))
7402         is_add = 0;
7403       else if (unformat (i, "count %d", &count))
7404         ;
7405       else
7406         break;
7407     }
7408
7409   if (mac_set == 0)
7410     {
7411       errmsg ("missing mac address");
7412       return -99;
7413     }
7414
7415   if (bd_id_set == 0)
7416     {
7417       errmsg ("missing bridge domain");
7418       return -99;
7419     }
7420
7421   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7422     {
7423       errmsg ("missing interface name or sw_if_index");
7424       return -99;
7425     }
7426
7427   if (count > 1)
7428     {
7429       /* Turn on async mode */
7430       vam->async_mode = 1;
7431       vam->async_errors = 0;
7432       before = vat_time_now (vam);
7433     }
7434
7435   for (j = 0; j < count; j++)
7436     {
7437       M (L2FIB_ADD_DEL, mp);
7438
7439       clib_memcpy (mp->mac, mac, 6);
7440       mp->bd_id = ntohl (bd_id);
7441       mp->is_add = is_add;
7442       mp->sw_if_index = ntohl (sw_if_index);
7443
7444       if (is_add)
7445         {
7446           mp->static_mac = static_mac;
7447           mp->filter_mac = filter_mac;
7448           mp->bvi_mac = bvi_mac;
7449         }
7450       increment_mac_address (mac);
7451       /* send it... */
7452       S (mp);
7453     }
7454
7455   if (count > 1)
7456     {
7457       vl_api_control_ping_t *mp_ping;
7458       f64 after;
7459
7460       /* Shut off async mode */
7461       vam->async_mode = 0;
7462
7463       MPING (CONTROL_PING, mp_ping);
7464       S (mp_ping);
7465
7466       timeout = vat_time_now (vam) + 1.0;
7467       while (vat_time_now (vam) < timeout)
7468         if (vam->result_ready == 1)
7469           goto out;
7470       vam->retval = -99;
7471
7472     out:
7473       if (vam->retval == -99)
7474         errmsg ("timeout");
7475
7476       if (vam->async_errors > 0)
7477         {
7478           errmsg ("%d asynchronous errors", vam->async_errors);
7479           vam->retval = -98;
7480         }
7481       vam->async_errors = 0;
7482       after = vat_time_now (vam);
7483
7484       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7485              count, after - before, count / (after - before));
7486     }
7487   else
7488     {
7489       int ret;
7490
7491       /* Wait for a reply... */
7492       W (ret);
7493       return ret;
7494     }
7495   /* Return the good/bad news */
7496   return (vam->retval);
7497 }
7498
7499 static int
7500 api_bridge_domain_set_mac_age (vat_main_t * vam)
7501 {
7502   unformat_input_t *i = vam->input;
7503   vl_api_bridge_domain_set_mac_age_t *mp;
7504   u32 bd_id = ~0;
7505   u32 mac_age = 0;
7506   int ret;
7507
7508   /* Parse args required to build the message */
7509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7510     {
7511       if (unformat (i, "bd_id %d", &bd_id));
7512       else if (unformat (i, "mac-age %d", &mac_age));
7513       else
7514         break;
7515     }
7516
7517   if (bd_id == ~0)
7518     {
7519       errmsg ("missing bridge domain");
7520       return -99;
7521     }
7522
7523   if (mac_age > 255)
7524     {
7525       errmsg ("mac age must be less than 256 ");
7526       return -99;
7527     }
7528
7529   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7530
7531   mp->bd_id = htonl (bd_id);
7532   mp->mac_age = (u8) mac_age;
7533
7534   S (mp);
7535   W (ret);
7536   return ret;
7537 }
7538
7539 static int
7540 api_l2_flags (vat_main_t * vam)
7541 {
7542   unformat_input_t *i = vam->input;
7543   vl_api_l2_flags_t *mp;
7544   u32 sw_if_index;
7545   u32 flags = 0;
7546   u8 sw_if_index_set = 0;
7547   u8 is_set = 0;
7548   int ret;
7549
7550   /* Parse args required to build the message */
7551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7552     {
7553       if (unformat (i, "sw_if_index %d", &sw_if_index))
7554         sw_if_index_set = 1;
7555       else if (unformat (i, "sw_if"))
7556         {
7557           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7558             {
7559               if (unformat
7560                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7561                 sw_if_index_set = 1;
7562             }
7563           else
7564             break;
7565         }
7566       else if (unformat (i, "learn"))
7567         flags |= L2_LEARN;
7568       else if (unformat (i, "forward"))
7569         flags |= L2_FWD;
7570       else if (unformat (i, "flood"))
7571         flags |= L2_FLOOD;
7572       else if (unformat (i, "uu-flood"))
7573         flags |= L2_UU_FLOOD;
7574       else if (unformat (i, "arp-term"))
7575         flags |= L2_ARP_TERM;
7576       else if (unformat (i, "off"))
7577         is_set = 0;
7578       else if (unformat (i, "disable"))
7579         is_set = 0;
7580       else
7581         break;
7582     }
7583
7584   if (sw_if_index_set == 0)
7585     {
7586       errmsg ("missing interface name or sw_if_index");
7587       return -99;
7588     }
7589
7590   M (L2_FLAGS, mp);
7591
7592   mp->sw_if_index = ntohl (sw_if_index);
7593   mp->feature_bitmap = ntohl (flags);
7594   mp->is_set = is_set;
7595
7596   S (mp);
7597   W (ret);
7598   return ret;
7599 }
7600
7601 static int
7602 api_bridge_flags (vat_main_t * vam)
7603 {
7604   unformat_input_t *i = vam->input;
7605   vl_api_bridge_flags_t *mp;
7606   u32 bd_id;
7607   u8 bd_id_set = 0;
7608   u8 is_set = 1;
7609   u32 flags = 0;
7610   int ret;
7611
7612   /* Parse args required to build the message */
7613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7614     {
7615       if (unformat (i, "bd_id %d", &bd_id))
7616         bd_id_set = 1;
7617       else if (unformat (i, "learn"))
7618         flags |= L2_LEARN;
7619       else if (unformat (i, "forward"))
7620         flags |= L2_FWD;
7621       else if (unformat (i, "flood"))
7622         flags |= L2_FLOOD;
7623       else if (unformat (i, "uu-flood"))
7624         flags |= L2_UU_FLOOD;
7625       else if (unformat (i, "arp-term"))
7626         flags |= L2_ARP_TERM;
7627       else if (unformat (i, "off"))
7628         is_set = 0;
7629       else if (unformat (i, "disable"))
7630         is_set = 0;
7631       else
7632         break;
7633     }
7634
7635   if (bd_id_set == 0)
7636     {
7637       errmsg ("missing bridge domain");
7638       return -99;
7639     }
7640
7641   M (BRIDGE_FLAGS, mp);
7642
7643   mp->bd_id = ntohl (bd_id);
7644   mp->feature_bitmap = ntohl (flags);
7645   mp->is_set = is_set;
7646
7647   S (mp);
7648   W (ret);
7649   return ret;
7650 }
7651
7652 static int
7653 api_bd_ip_mac_add_del (vat_main_t * vam)
7654 {
7655   unformat_input_t *i = vam->input;
7656   vl_api_bd_ip_mac_add_del_t *mp;
7657   u32 bd_id;
7658   u8 is_ipv6 = 0;
7659   u8 is_add = 1;
7660   u8 bd_id_set = 0;
7661   u8 ip_set = 0;
7662   u8 mac_set = 0;
7663   ip4_address_t v4addr;
7664   ip6_address_t v6addr;
7665   u8 macaddr[6];
7666   int ret;
7667
7668
7669   /* Parse args required to build the message */
7670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7671     {
7672       if (unformat (i, "bd_id %d", &bd_id))
7673         {
7674           bd_id_set++;
7675         }
7676       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7677         {
7678           ip_set++;
7679         }
7680       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7681         {
7682           ip_set++;
7683           is_ipv6++;
7684         }
7685       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7686         {
7687           mac_set++;
7688         }
7689       else if (unformat (i, "del"))
7690         is_add = 0;
7691       else
7692         break;
7693     }
7694
7695   if (bd_id_set == 0)
7696     {
7697       errmsg ("missing bridge domain");
7698       return -99;
7699     }
7700   else if (ip_set == 0)
7701     {
7702       errmsg ("missing IP address");
7703       return -99;
7704     }
7705   else if (mac_set == 0)
7706     {
7707       errmsg ("missing MAC address");
7708       return -99;
7709     }
7710
7711   M (BD_IP_MAC_ADD_DEL, mp);
7712
7713   mp->bd_id = ntohl (bd_id);
7714   mp->is_ipv6 = is_ipv6;
7715   mp->is_add = is_add;
7716   if (is_ipv6)
7717     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7718   else
7719     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7720   clib_memcpy (mp->mac_address, macaddr, 6);
7721   S (mp);
7722   W (ret);
7723   return ret;
7724 }
7725
7726 static int
7727 api_tap_connect (vat_main_t * vam)
7728 {
7729   unformat_input_t *i = vam->input;
7730   vl_api_tap_connect_t *mp;
7731   u8 mac_address[6];
7732   u8 random_mac = 1;
7733   u8 name_set = 0;
7734   u8 *tap_name;
7735   u8 *tag = 0;
7736   ip4_address_t ip4_address;
7737   u32 ip4_mask_width;
7738   int ip4_address_set = 0;
7739   ip6_address_t ip6_address;
7740   u32 ip6_mask_width;
7741   int ip6_address_set = 0;
7742   int ret;
7743
7744   memset (mac_address, 0, sizeof (mac_address));
7745
7746   /* Parse args required to build the message */
7747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7748     {
7749       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7750         {
7751           random_mac = 0;
7752         }
7753       else if (unformat (i, "random-mac"))
7754         random_mac = 1;
7755       else if (unformat (i, "tapname %s", &tap_name))
7756         name_set = 1;
7757       else if (unformat (i, "tag %s", &tag))
7758         ;
7759       else if (unformat (i, "address %U/%d",
7760                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7761         ip4_address_set = 1;
7762       else if (unformat (i, "address %U/%d",
7763                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7764         ip6_address_set = 1;
7765       else
7766         break;
7767     }
7768
7769   if (name_set == 0)
7770     {
7771       errmsg ("missing tap name");
7772       return -99;
7773     }
7774   if (vec_len (tap_name) > 63)
7775     {
7776       errmsg ("tap name too long");
7777       return -99;
7778     }
7779   vec_add1 (tap_name, 0);
7780
7781   if (vec_len (tag) > 63)
7782     {
7783       errmsg ("tag too long");
7784       return -99;
7785     }
7786
7787   /* Construct the API message */
7788   M (TAP_CONNECT, mp);
7789
7790   mp->use_random_mac = random_mac;
7791   clib_memcpy (mp->mac_address, mac_address, 6);
7792   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7793   if (tag)
7794     clib_memcpy (mp->tag, tag, vec_len (tag));
7795
7796   if (ip4_address_set)
7797     {
7798       mp->ip4_address_set = 1;
7799       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7800       mp->ip4_mask_width = ip4_mask_width;
7801     }
7802   if (ip6_address_set)
7803     {
7804       mp->ip6_address_set = 1;
7805       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7806       mp->ip6_mask_width = ip6_mask_width;
7807     }
7808
7809   vec_free (tap_name);
7810   vec_free (tag);
7811
7812   /* send it... */
7813   S (mp);
7814
7815   /* Wait for a reply... */
7816   W (ret);
7817   return ret;
7818 }
7819
7820 static int
7821 api_tap_modify (vat_main_t * vam)
7822 {
7823   unformat_input_t *i = vam->input;
7824   vl_api_tap_modify_t *mp;
7825   u8 mac_address[6];
7826   u8 random_mac = 1;
7827   u8 name_set = 0;
7828   u8 *tap_name;
7829   u32 sw_if_index = ~0;
7830   u8 sw_if_index_set = 0;
7831   int ret;
7832
7833   memset (mac_address, 0, sizeof (mac_address));
7834
7835   /* Parse args required to build the message */
7836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7837     {
7838       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7839         sw_if_index_set = 1;
7840       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7841         sw_if_index_set = 1;
7842       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7843         {
7844           random_mac = 0;
7845         }
7846       else if (unformat (i, "random-mac"))
7847         random_mac = 1;
7848       else if (unformat (i, "tapname %s", &tap_name))
7849         name_set = 1;
7850       else
7851         break;
7852     }
7853
7854   if (sw_if_index_set == 0)
7855     {
7856       errmsg ("missing vpp interface name");
7857       return -99;
7858     }
7859   if (name_set == 0)
7860     {
7861       errmsg ("missing tap name");
7862       return -99;
7863     }
7864   if (vec_len (tap_name) > 63)
7865     {
7866       errmsg ("tap name too long");
7867     }
7868   vec_add1 (tap_name, 0);
7869
7870   /* Construct the API message */
7871   M (TAP_MODIFY, mp);
7872
7873   mp->use_random_mac = random_mac;
7874   mp->sw_if_index = ntohl (sw_if_index);
7875   clib_memcpy (mp->mac_address, mac_address, 6);
7876   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7877   vec_free (tap_name);
7878
7879   /* send it... */
7880   S (mp);
7881
7882   /* Wait for a reply... */
7883   W (ret);
7884   return ret;
7885 }
7886
7887 static int
7888 api_tap_delete (vat_main_t * vam)
7889 {
7890   unformat_input_t *i = vam->input;
7891   vl_api_tap_delete_t *mp;
7892   u32 sw_if_index = ~0;
7893   u8 sw_if_index_set = 0;
7894   int ret;
7895
7896   /* Parse args required to build the message */
7897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7898     {
7899       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7900         sw_if_index_set = 1;
7901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7902         sw_if_index_set = 1;
7903       else
7904         break;
7905     }
7906
7907   if (sw_if_index_set == 0)
7908     {
7909       errmsg ("missing vpp interface name");
7910       return -99;
7911     }
7912
7913   /* Construct the API message */
7914   M (TAP_DELETE, mp);
7915
7916   mp->sw_if_index = ntohl (sw_if_index);
7917
7918   /* send it... */
7919   S (mp);
7920
7921   /* Wait for a reply... */
7922   W (ret);
7923   return ret;
7924 }
7925
7926 static int
7927 api_tap_create_v2 (vat_main_t * vam)
7928 {
7929   unformat_input_t *i = vam->input;
7930   vl_api_tap_create_v2_t *mp;
7931   u8 mac_address[6];
7932   u8 random_mac = 1;
7933   u32 id = ~0;
7934   u8 *host_if_name = 0;
7935   u8 *host_ns = 0;
7936   u8 host_mac_addr[6];
7937   u8 host_mac_addr_set = 0;
7938   u8 *host_bridge = 0;
7939   ip4_address_t host_ip4_addr;
7940   ip4_address_t host_ip4_gw;
7941   u8 host_ip4_gw_set = 0;
7942   u32 host_ip4_prefix_len = 0;
7943   ip6_address_t host_ip6_addr;
7944   ip6_address_t host_ip6_gw;
7945   u8 host_ip6_gw_set = 0;
7946   u32 host_ip6_prefix_len = 0;
7947   int ret;
7948   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7949
7950   memset (mac_address, 0, sizeof (mac_address));
7951
7952   /* Parse args required to build the message */
7953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7954     {
7955       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7956         {
7957           random_mac = 0;
7958         }
7959       else if (unformat (i, "id %u", &id))
7960         ;
7961       else if (unformat (i, "host-if-name %s", &host_if_name))
7962         ;
7963       else if (unformat (i, "host-ns %s", &host_ns))
7964         ;
7965       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7966                          host_mac_addr))
7967         host_mac_addr_set = 1;
7968       else if (unformat (i, "host-bridge %s", &host_bridge))
7969         ;
7970       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7971                          &host_ip4_addr, &host_ip4_prefix_len))
7972         ;
7973       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7974                          &host_ip6_addr, &host_ip6_prefix_len))
7975         ;
7976       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7977                          &host_ip4_gw))
7978         host_ip4_gw_set = 1;
7979       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7980                          &host_ip6_gw))
7981         host_ip6_gw_set = 1;
7982       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7983         ;
7984       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7985         ;
7986       else
7987         break;
7988     }
7989
7990   if (vec_len (host_if_name) > 63)
7991     {
7992       errmsg ("tap name too long. ");
7993       return -99;
7994     }
7995   if (vec_len (host_ns) > 63)
7996     {
7997       errmsg ("host name space too long. ");
7998       return -99;
7999     }
8000   if (vec_len (host_bridge) > 63)
8001     {
8002       errmsg ("host bridge name too long. ");
8003       return -99;
8004     }
8005   if (host_ip4_prefix_len > 32)
8006     {
8007       errmsg ("host ip4 prefix length not valid. ");
8008       return -99;
8009     }
8010   if (host_ip6_prefix_len > 128)
8011     {
8012       errmsg ("host ip6 prefix length not valid. ");
8013       return -99;
8014     }
8015   if (!is_pow2 (rx_ring_sz))
8016     {
8017       errmsg ("rx ring size must be power of 2. ");
8018       return -99;
8019     }
8020   if (rx_ring_sz > 32768)
8021     {
8022       errmsg ("rx ring size must be 32768 or lower. ");
8023       return -99;
8024     }
8025   if (!is_pow2 (tx_ring_sz))
8026     {
8027       errmsg ("tx ring size must be power of 2. ");
8028       return -99;
8029     }
8030   if (tx_ring_sz > 32768)
8031     {
8032       errmsg ("tx ring size must be 32768 or lower. ");
8033       return -99;
8034     }
8035
8036   /* Construct the API message */
8037   M (TAP_CREATE_V2, mp);
8038
8039   mp->use_random_mac = random_mac;
8040
8041   mp->id = ntohl (id);
8042   mp->host_namespace_set = host_ns != 0;
8043   mp->host_bridge_set = host_bridge != 0;
8044   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8045   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8046   mp->rx_ring_sz = ntohs (rx_ring_sz);
8047   mp->tx_ring_sz = ntohs (tx_ring_sz);
8048
8049   if (random_mac == 0)
8050     clib_memcpy (mp->mac_address, mac_address, 6);
8051   if (host_mac_addr_set)
8052     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8053   if (host_if_name)
8054     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8055   if (host_ns)
8056     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8057   if (host_bridge)
8058     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8059   if (host_ip4_prefix_len)
8060     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8061   if (host_ip4_prefix_len)
8062     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8063   if (host_ip4_gw_set)
8064     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8065   if (host_ip6_gw_set)
8066     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8067
8068   vec_free (host_ns);
8069   vec_free (host_if_name);
8070   vec_free (host_bridge);
8071
8072   /* send it... */
8073   S (mp);
8074
8075   /* Wait for a reply... */
8076   W (ret);
8077   return ret;
8078 }
8079
8080 static int
8081 api_tap_delete_v2 (vat_main_t * vam)
8082 {
8083   unformat_input_t *i = vam->input;
8084   vl_api_tap_delete_v2_t *mp;
8085   u32 sw_if_index = ~0;
8086   u8 sw_if_index_set = 0;
8087   int ret;
8088
8089   /* Parse args required to build the message */
8090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8091     {
8092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8093         sw_if_index_set = 1;
8094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8095         sw_if_index_set = 1;
8096       else
8097         break;
8098     }
8099
8100   if (sw_if_index_set == 0)
8101     {
8102       errmsg ("missing vpp interface name. ");
8103       return -99;
8104     }
8105
8106   /* Construct the API message */
8107   M (TAP_DELETE_V2, mp);
8108
8109   mp->sw_if_index = ntohl (sw_if_index);
8110
8111   /* send it... */
8112   S (mp);
8113
8114   /* Wait for a reply... */
8115   W (ret);
8116   return ret;
8117 }
8118
8119 static int
8120 api_bond_create (vat_main_t * vam)
8121 {
8122   unformat_input_t *i = vam->input;
8123   vl_api_bond_create_t *mp;
8124   u8 mac_address[6];
8125   u8 custom_mac = 0;
8126   int ret;
8127   u8 mode;
8128   u8 lb;
8129   u8 mode_is_set = 0;
8130
8131   memset (mac_address, 0, sizeof (mac_address));
8132   lb = BOND_LB_L2;
8133
8134   /* Parse args required to build the message */
8135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8136     {
8137       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8138         mode_is_set = 1;
8139       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8140                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8141         ;
8142       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8143                          mac_address))
8144         custom_mac = 1;
8145       else
8146         break;
8147     }
8148
8149   if (mode_is_set == 0)
8150     {
8151       errmsg ("Missing bond mode. ");
8152       return -99;
8153     }
8154
8155   /* Construct the API message */
8156   M (BOND_CREATE, mp);
8157
8158   mp->use_custom_mac = custom_mac;
8159
8160   mp->mode = mode;
8161   mp->lb = lb;
8162
8163   if (custom_mac)
8164     clib_memcpy (mp->mac_address, mac_address, 6);
8165
8166   /* send it... */
8167   S (mp);
8168
8169   /* Wait for a reply... */
8170   W (ret);
8171   return ret;
8172 }
8173
8174 static int
8175 api_bond_delete (vat_main_t * vam)
8176 {
8177   unformat_input_t *i = vam->input;
8178   vl_api_bond_delete_t *mp;
8179   u32 sw_if_index = ~0;
8180   u8 sw_if_index_set = 0;
8181   int ret;
8182
8183   /* Parse args required to build the message */
8184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8185     {
8186       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8187         sw_if_index_set = 1;
8188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8189         sw_if_index_set = 1;
8190       else
8191         break;
8192     }
8193
8194   if (sw_if_index_set == 0)
8195     {
8196       errmsg ("missing vpp interface name. ");
8197       return -99;
8198     }
8199
8200   /* Construct the API message */
8201   M (BOND_DELETE, mp);
8202
8203   mp->sw_if_index = ntohl (sw_if_index);
8204
8205   /* send it... */
8206   S (mp);
8207
8208   /* Wait for a reply... */
8209   W (ret);
8210   return ret;
8211 }
8212
8213 static int
8214 api_bond_enslave (vat_main_t * vam)
8215 {
8216   unformat_input_t *i = vam->input;
8217   vl_api_bond_enslave_t *mp;
8218   u32 bond_sw_if_index;
8219   int ret;
8220   u8 is_passive;
8221   u8 is_long_timeout;
8222   u32 bond_sw_if_index_is_set = 0;
8223   u32 sw_if_index;
8224   u8 sw_if_index_is_set = 0;
8225
8226   /* Parse args required to build the message */
8227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8228     {
8229       if (unformat (i, "sw_if_index %d", &sw_if_index))
8230         sw_if_index_is_set = 1;
8231       else if (unformat (i, "bond %u", &bond_sw_if_index))
8232         bond_sw_if_index_is_set = 1;
8233       else if (unformat (i, "passive %d", &is_passive))
8234         ;
8235       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8236         ;
8237       else
8238         break;
8239     }
8240
8241   if (bond_sw_if_index_is_set == 0)
8242     {
8243       errmsg ("Missing bond sw_if_index. ");
8244       return -99;
8245     }
8246   if (sw_if_index_is_set == 0)
8247     {
8248       errmsg ("Missing slave sw_if_index. ");
8249       return -99;
8250     }
8251
8252   /* Construct the API message */
8253   M (BOND_ENSLAVE, mp);
8254
8255   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8256   mp->sw_if_index = ntohl (sw_if_index);
8257   mp->is_long_timeout = is_long_timeout;
8258   mp->is_passive = is_passive;
8259
8260   /* send it... */
8261   S (mp);
8262
8263   /* Wait for a reply... */
8264   W (ret);
8265   return ret;
8266 }
8267
8268 static int
8269 api_bond_detach_slave (vat_main_t * vam)
8270 {
8271   unformat_input_t *i = vam->input;
8272   vl_api_bond_detach_slave_t *mp;
8273   u32 sw_if_index = ~0;
8274   u8 sw_if_index_set = 0;
8275   int ret;
8276
8277   /* Parse args required to build the message */
8278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8279     {
8280       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8281         sw_if_index_set = 1;
8282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8283         sw_if_index_set = 1;
8284       else
8285         break;
8286     }
8287
8288   if (sw_if_index_set == 0)
8289     {
8290       errmsg ("missing vpp interface name. ");
8291       return -99;
8292     }
8293
8294   /* Construct the API message */
8295   M (BOND_DETACH_SLAVE, mp);
8296
8297   mp->sw_if_index = ntohl (sw_if_index);
8298
8299   /* send it... */
8300   S (mp);
8301
8302   /* Wait for a reply... */
8303   W (ret);
8304   return ret;
8305 }
8306
8307 static int
8308 api_ip_table_add_del (vat_main_t * vam)
8309 {
8310   unformat_input_t *i = vam->input;
8311   vl_api_ip_table_add_del_t *mp;
8312   u32 table_id = ~0;
8313   u8 is_ipv6 = 0;
8314   u8 is_add = 1;
8315   int ret = 0;
8316
8317   /* Parse args required to build the message */
8318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8319     {
8320       if (unformat (i, "ipv6"))
8321         is_ipv6 = 1;
8322       else if (unformat (i, "del"))
8323         is_add = 0;
8324       else if (unformat (i, "add"))
8325         is_add = 1;
8326       else if (unformat (i, "table %d", &table_id))
8327         ;
8328       else
8329         {
8330           clib_warning ("parse error '%U'", format_unformat_error, i);
8331           return -99;
8332         }
8333     }
8334
8335   if (~0 == table_id)
8336     {
8337       errmsg ("missing table-ID");
8338       return -99;
8339     }
8340
8341   /* Construct the API message */
8342   M (IP_TABLE_ADD_DEL, mp);
8343
8344   mp->table_id = ntohl (table_id);
8345   mp->is_ipv6 = is_ipv6;
8346   mp->is_add = is_add;
8347
8348   /* send it... */
8349   S (mp);
8350
8351   /* Wait for a reply... */
8352   W (ret);
8353
8354   return ret;
8355 }
8356
8357 static int
8358 api_ip_add_del_route (vat_main_t * vam)
8359 {
8360   unformat_input_t *i = vam->input;
8361   vl_api_ip_add_del_route_t *mp;
8362   u32 sw_if_index = ~0, vrf_id = 0;
8363   u8 is_ipv6 = 0;
8364   u8 is_local = 0, is_drop = 0;
8365   u8 is_unreach = 0, is_prohibit = 0;
8366   u8 is_add = 1;
8367   u32 next_hop_weight = 1;
8368   u8 is_multipath = 0;
8369   u8 address_set = 0;
8370   u8 address_length_set = 0;
8371   u32 next_hop_table_id = 0;
8372   u32 resolve_attempts = 0;
8373   u32 dst_address_length = 0;
8374   u8 next_hop_set = 0;
8375   ip4_address_t v4_dst_address, v4_next_hop_address;
8376   ip6_address_t v6_dst_address, v6_next_hop_address;
8377   int count = 1;
8378   int j;
8379   f64 before = 0;
8380   u32 random_add_del = 0;
8381   u32 *random_vector = 0;
8382   uword *random_hash;
8383   u32 random_seed = 0xdeaddabe;
8384   u32 classify_table_index = ~0;
8385   u8 is_classify = 0;
8386   u8 resolve_host = 0, resolve_attached = 0;
8387   mpls_label_t *next_hop_out_label_stack = NULL;
8388   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8389   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8390
8391   /* Parse args required to build the message */
8392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8393     {
8394       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8395         ;
8396       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8397         ;
8398       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8399         {
8400           address_set = 1;
8401           is_ipv6 = 0;
8402         }
8403       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8404         {
8405           address_set = 1;
8406           is_ipv6 = 1;
8407         }
8408       else if (unformat (i, "/%d", &dst_address_length))
8409         {
8410           address_length_set = 1;
8411         }
8412
8413       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8414                                          &v4_next_hop_address))
8415         {
8416           next_hop_set = 1;
8417         }
8418       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8419                                          &v6_next_hop_address))
8420         {
8421           next_hop_set = 1;
8422         }
8423       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8424         ;
8425       else if (unformat (i, "weight %d", &next_hop_weight))
8426         ;
8427       else if (unformat (i, "drop"))
8428         {
8429           is_drop = 1;
8430         }
8431       else if (unformat (i, "null-send-unreach"))
8432         {
8433           is_unreach = 1;
8434         }
8435       else if (unformat (i, "null-send-prohibit"))
8436         {
8437           is_prohibit = 1;
8438         }
8439       else if (unformat (i, "local"))
8440         {
8441           is_local = 1;
8442         }
8443       else if (unformat (i, "classify %d", &classify_table_index))
8444         {
8445           is_classify = 1;
8446         }
8447       else if (unformat (i, "del"))
8448         is_add = 0;
8449       else if (unformat (i, "add"))
8450         is_add = 1;
8451       else if (unformat (i, "resolve-via-host"))
8452         resolve_host = 1;
8453       else if (unformat (i, "resolve-via-attached"))
8454         resolve_attached = 1;
8455       else if (unformat (i, "multipath"))
8456         is_multipath = 1;
8457       else if (unformat (i, "vrf %d", &vrf_id))
8458         ;
8459       else if (unformat (i, "count %d", &count))
8460         ;
8461       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8462         ;
8463       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8464         ;
8465       else if (unformat (i, "out-label %d", &next_hop_out_label))
8466         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8467       else if (unformat (i, "via-label %d", &next_hop_via_label))
8468         ;
8469       else if (unformat (i, "random"))
8470         random_add_del = 1;
8471       else if (unformat (i, "seed %d", &random_seed))
8472         ;
8473       else
8474         {
8475           clib_warning ("parse error '%U'", format_unformat_error, i);
8476           return -99;
8477         }
8478     }
8479
8480   if (!next_hop_set && !is_drop && !is_local &&
8481       !is_classify && !is_unreach && !is_prohibit &&
8482       MPLS_LABEL_INVALID == next_hop_via_label)
8483     {
8484       errmsg
8485         ("next hop / local / drop / unreach / prohibit / classify not set");
8486       return -99;
8487     }
8488
8489   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8490     {
8491       errmsg ("next hop and next-hop via label set");
8492       return -99;
8493     }
8494   if (address_set == 0)
8495     {
8496       errmsg ("missing addresses");
8497       return -99;
8498     }
8499
8500   if (address_length_set == 0)
8501     {
8502       errmsg ("missing address length");
8503       return -99;
8504     }
8505
8506   /* Generate a pile of unique, random routes */
8507   if (random_add_del)
8508     {
8509       u32 this_random_address;
8510       random_hash = hash_create (count, sizeof (uword));
8511
8512       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8513       for (j = 0; j <= count; j++)
8514         {
8515           do
8516             {
8517               this_random_address = random_u32 (&random_seed);
8518               this_random_address =
8519                 clib_host_to_net_u32 (this_random_address);
8520             }
8521           while (hash_get (random_hash, this_random_address));
8522           vec_add1 (random_vector, this_random_address);
8523           hash_set (random_hash, this_random_address, 1);
8524         }
8525       hash_free (random_hash);
8526       v4_dst_address.as_u32 = random_vector[0];
8527     }
8528
8529   if (count > 1)
8530     {
8531       /* Turn on async mode */
8532       vam->async_mode = 1;
8533       vam->async_errors = 0;
8534       before = vat_time_now (vam);
8535     }
8536
8537   for (j = 0; j < count; j++)
8538     {
8539       /* Construct the API message */
8540       M2 (IP_ADD_DEL_ROUTE, mp,
8541           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8542
8543       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8544       mp->table_id = ntohl (vrf_id);
8545
8546       mp->is_add = is_add;
8547       mp->is_drop = is_drop;
8548       mp->is_unreach = is_unreach;
8549       mp->is_prohibit = is_prohibit;
8550       mp->is_ipv6 = is_ipv6;
8551       mp->is_local = is_local;
8552       mp->is_classify = is_classify;
8553       mp->is_multipath = is_multipath;
8554       mp->is_resolve_host = resolve_host;
8555       mp->is_resolve_attached = resolve_attached;
8556       mp->next_hop_weight = next_hop_weight;
8557       mp->dst_address_length = dst_address_length;
8558       mp->next_hop_table_id = ntohl (next_hop_table_id);
8559       mp->classify_table_index = ntohl (classify_table_index);
8560       mp->next_hop_via_label = ntohl (next_hop_via_label);
8561       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8562       if (0 != mp->next_hop_n_out_labels)
8563         {
8564           memcpy (mp->next_hop_out_label_stack,
8565                   next_hop_out_label_stack,
8566                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8567           vec_free (next_hop_out_label_stack);
8568         }
8569
8570       if (is_ipv6)
8571         {
8572           clib_memcpy (mp->dst_address, &v6_dst_address,
8573                        sizeof (v6_dst_address));
8574           if (next_hop_set)
8575             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8576                          sizeof (v6_next_hop_address));
8577           increment_v6_address (&v6_dst_address);
8578         }
8579       else
8580         {
8581           clib_memcpy (mp->dst_address, &v4_dst_address,
8582                        sizeof (v4_dst_address));
8583           if (next_hop_set)
8584             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8585                          sizeof (v4_next_hop_address));
8586           if (random_add_del)
8587             v4_dst_address.as_u32 = random_vector[j + 1];
8588           else
8589             increment_v4_address (&v4_dst_address);
8590         }
8591       /* send it... */
8592       S (mp);
8593       /* If we receive SIGTERM, stop now... */
8594       if (vam->do_exit)
8595         break;
8596     }
8597
8598   /* When testing multiple add/del ops, use a control-ping to sync */
8599   if (count > 1)
8600     {
8601       vl_api_control_ping_t *mp_ping;
8602       f64 after;
8603       f64 timeout;
8604
8605       /* Shut off async mode */
8606       vam->async_mode = 0;
8607
8608       MPING (CONTROL_PING, mp_ping);
8609       S (mp_ping);
8610
8611       timeout = vat_time_now (vam) + 1.0;
8612       while (vat_time_now (vam) < timeout)
8613         if (vam->result_ready == 1)
8614           goto out;
8615       vam->retval = -99;
8616
8617     out:
8618       if (vam->retval == -99)
8619         errmsg ("timeout");
8620
8621       if (vam->async_errors > 0)
8622         {
8623           errmsg ("%d asynchronous errors", vam->async_errors);
8624           vam->retval = -98;
8625         }
8626       vam->async_errors = 0;
8627       after = vat_time_now (vam);
8628
8629       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8630       if (j > 0)
8631         count = j;
8632
8633       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8634              count, after - before, count / (after - before));
8635     }
8636   else
8637     {
8638       int ret;
8639
8640       /* Wait for a reply... */
8641       W (ret);
8642       return ret;
8643     }
8644
8645   /* Return the good/bad news */
8646   return (vam->retval);
8647 }
8648
8649 static int
8650 api_ip_mroute_add_del (vat_main_t * vam)
8651 {
8652   unformat_input_t *i = vam->input;
8653   vl_api_ip_mroute_add_del_t *mp;
8654   u32 sw_if_index = ~0, vrf_id = 0;
8655   u8 is_ipv6 = 0;
8656   u8 is_local = 0;
8657   u8 is_add = 1;
8658   u8 address_set = 0;
8659   u32 grp_address_length = 0;
8660   ip4_address_t v4_grp_address, v4_src_address;
8661   ip6_address_t v6_grp_address, v6_src_address;
8662   mfib_itf_flags_t iflags = 0;
8663   mfib_entry_flags_t eflags = 0;
8664   int ret;
8665
8666   /* Parse args required to build the message */
8667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8668     {
8669       if (unformat (i, "sw_if_index %d", &sw_if_index))
8670         ;
8671       else if (unformat (i, "%U %U",
8672                          unformat_ip4_address, &v4_src_address,
8673                          unformat_ip4_address, &v4_grp_address))
8674         {
8675           grp_address_length = 64;
8676           address_set = 1;
8677           is_ipv6 = 0;
8678         }
8679       else if (unformat (i, "%U %U",
8680                          unformat_ip6_address, &v6_src_address,
8681                          unformat_ip6_address, &v6_grp_address))
8682         {
8683           grp_address_length = 256;
8684           address_set = 1;
8685           is_ipv6 = 1;
8686         }
8687       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8688         {
8689           memset (&v4_src_address, 0, sizeof (v4_src_address));
8690           grp_address_length = 32;
8691           address_set = 1;
8692           is_ipv6 = 0;
8693         }
8694       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8695         {
8696           memset (&v6_src_address, 0, sizeof (v6_src_address));
8697           grp_address_length = 128;
8698           address_set = 1;
8699           is_ipv6 = 1;
8700         }
8701       else if (unformat (i, "/%d", &grp_address_length))
8702         ;
8703       else if (unformat (i, "local"))
8704         {
8705           is_local = 1;
8706         }
8707       else if (unformat (i, "del"))
8708         is_add = 0;
8709       else if (unformat (i, "add"))
8710         is_add = 1;
8711       else if (unformat (i, "vrf %d", &vrf_id))
8712         ;
8713       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8714         ;
8715       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8716         ;
8717       else
8718         {
8719           clib_warning ("parse error '%U'", format_unformat_error, i);
8720           return -99;
8721         }
8722     }
8723
8724   if (address_set == 0)
8725     {
8726       errmsg ("missing addresses\n");
8727       return -99;
8728     }
8729
8730   /* Construct the API message */
8731   M (IP_MROUTE_ADD_DEL, mp);
8732
8733   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8734   mp->table_id = ntohl (vrf_id);
8735
8736   mp->is_add = is_add;
8737   mp->is_ipv6 = is_ipv6;
8738   mp->is_local = is_local;
8739   mp->itf_flags = ntohl (iflags);
8740   mp->entry_flags = ntohl (eflags);
8741   mp->grp_address_length = grp_address_length;
8742   mp->grp_address_length = ntohs (mp->grp_address_length);
8743
8744   if (is_ipv6)
8745     {
8746       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8747       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8748     }
8749   else
8750     {
8751       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8752       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8753
8754     }
8755
8756   /* send it... */
8757   S (mp);
8758   /* Wait for a reply... */
8759   W (ret);
8760   return ret;
8761 }
8762
8763 static int
8764 api_mpls_table_add_del (vat_main_t * vam)
8765 {
8766   unformat_input_t *i = vam->input;
8767   vl_api_mpls_table_add_del_t *mp;
8768   u32 table_id = ~0;
8769   u8 is_add = 1;
8770   int ret = 0;
8771
8772   /* Parse args required to build the message */
8773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8774     {
8775       if (unformat (i, "table %d", &table_id))
8776         ;
8777       else if (unformat (i, "del"))
8778         is_add = 0;
8779       else if (unformat (i, "add"))
8780         is_add = 1;
8781       else
8782         {
8783           clib_warning ("parse error '%U'", format_unformat_error, i);
8784           return -99;
8785         }
8786     }
8787
8788   if (~0 == table_id)
8789     {
8790       errmsg ("missing table-ID");
8791       return -99;
8792     }
8793
8794   /* Construct the API message */
8795   M (MPLS_TABLE_ADD_DEL, mp);
8796
8797   mp->mt_table_id = ntohl (table_id);
8798   mp->mt_is_add = is_add;
8799
8800   /* send it... */
8801   S (mp);
8802
8803   /* Wait for a reply... */
8804   W (ret);
8805
8806   return ret;
8807 }
8808
8809 static int
8810 api_mpls_route_add_del (vat_main_t * vam)
8811 {
8812   unformat_input_t *i = vam->input;
8813   vl_api_mpls_route_add_del_t *mp;
8814   u32 sw_if_index = ~0, table_id = 0;
8815   u8 is_add = 1;
8816   u32 next_hop_weight = 1;
8817   u8 is_multipath = 0;
8818   u32 next_hop_table_id = 0;
8819   u8 next_hop_set = 0;
8820   ip4_address_t v4_next_hop_address = {
8821     .as_u32 = 0,
8822   };
8823   ip6_address_t v6_next_hop_address = { {0} };
8824   int count = 1;
8825   int j;
8826   f64 before = 0;
8827   u32 classify_table_index = ~0;
8828   u8 is_classify = 0;
8829   u8 resolve_host = 0, resolve_attached = 0;
8830   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8831   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8832   mpls_label_t *next_hop_out_label_stack = NULL;
8833   mpls_label_t local_label = MPLS_LABEL_INVALID;
8834   u8 is_eos = 0;
8835   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8836
8837   /* Parse args required to build the message */
8838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8839     {
8840       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8841         ;
8842       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8843         ;
8844       else if (unformat (i, "%d", &local_label))
8845         ;
8846       else if (unformat (i, "eos"))
8847         is_eos = 1;
8848       else if (unformat (i, "non-eos"))
8849         is_eos = 0;
8850       else if (unformat (i, "via %U", unformat_ip4_address,
8851                          &v4_next_hop_address))
8852         {
8853           next_hop_set = 1;
8854           next_hop_proto = DPO_PROTO_IP4;
8855         }
8856       else if (unformat (i, "via %U", unformat_ip6_address,
8857                          &v6_next_hop_address))
8858         {
8859           next_hop_set = 1;
8860           next_hop_proto = DPO_PROTO_IP6;
8861         }
8862       else if (unformat (i, "weight %d", &next_hop_weight))
8863         ;
8864       else if (unformat (i, "classify %d", &classify_table_index))
8865         {
8866           is_classify = 1;
8867         }
8868       else if (unformat (i, "del"))
8869         is_add = 0;
8870       else if (unformat (i, "add"))
8871         is_add = 1;
8872       else if (unformat (i, "resolve-via-host"))
8873         resolve_host = 1;
8874       else if (unformat (i, "resolve-via-attached"))
8875         resolve_attached = 1;
8876       else if (unformat (i, "multipath"))
8877         is_multipath = 1;
8878       else if (unformat (i, "count %d", &count))
8879         ;
8880       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8881         {
8882           next_hop_set = 1;
8883           next_hop_proto = DPO_PROTO_IP4;
8884         }
8885       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8886         {
8887           next_hop_set = 1;
8888           next_hop_proto = DPO_PROTO_IP6;
8889         }
8890       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8891         ;
8892       else if (unformat (i, "via-label %d", &next_hop_via_label))
8893         ;
8894       else if (unformat (i, "out-label %d", &next_hop_out_label))
8895         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8896       else
8897         {
8898           clib_warning ("parse error '%U'", format_unformat_error, i);
8899           return -99;
8900         }
8901     }
8902
8903   if (!next_hop_set && !is_classify)
8904     {
8905       errmsg ("next hop / classify not set");
8906       return -99;
8907     }
8908
8909   if (MPLS_LABEL_INVALID == local_label)
8910     {
8911       errmsg ("missing label");
8912       return -99;
8913     }
8914
8915   if (count > 1)
8916     {
8917       /* Turn on async mode */
8918       vam->async_mode = 1;
8919       vam->async_errors = 0;
8920       before = vat_time_now (vam);
8921     }
8922
8923   for (j = 0; j < count; j++)
8924     {
8925       /* Construct the API message */
8926       M2 (MPLS_ROUTE_ADD_DEL, mp,
8927           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8928
8929       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8930       mp->mr_table_id = ntohl (table_id);
8931
8932       mp->mr_is_add = is_add;
8933       mp->mr_next_hop_proto = next_hop_proto;
8934       mp->mr_is_classify = is_classify;
8935       mp->mr_is_multipath = is_multipath;
8936       mp->mr_is_resolve_host = resolve_host;
8937       mp->mr_is_resolve_attached = resolve_attached;
8938       mp->mr_next_hop_weight = next_hop_weight;
8939       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8940       mp->mr_classify_table_index = ntohl (classify_table_index);
8941       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8942       mp->mr_label = ntohl (local_label);
8943       mp->mr_eos = is_eos;
8944
8945       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8946       if (0 != mp->mr_next_hop_n_out_labels)
8947         {
8948           memcpy (mp->mr_next_hop_out_label_stack,
8949                   next_hop_out_label_stack,
8950                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8951           vec_free (next_hop_out_label_stack);
8952         }
8953
8954       if (next_hop_set)
8955         {
8956           if (DPO_PROTO_IP4 == next_hop_proto)
8957             {
8958               clib_memcpy (mp->mr_next_hop,
8959                            &v4_next_hop_address,
8960                            sizeof (v4_next_hop_address));
8961             }
8962           else if (DPO_PROTO_IP6 == next_hop_proto)
8963
8964             {
8965               clib_memcpy (mp->mr_next_hop,
8966                            &v6_next_hop_address,
8967                            sizeof (v6_next_hop_address));
8968             }
8969         }
8970       local_label++;
8971
8972       /* send it... */
8973       S (mp);
8974       /* If we receive SIGTERM, stop now... */
8975       if (vam->do_exit)
8976         break;
8977     }
8978
8979   /* When testing multiple add/del ops, use a control-ping to sync */
8980   if (count > 1)
8981     {
8982       vl_api_control_ping_t *mp_ping;
8983       f64 after;
8984       f64 timeout;
8985
8986       /* Shut off async mode */
8987       vam->async_mode = 0;
8988
8989       MPING (CONTROL_PING, mp_ping);
8990       S (mp_ping);
8991
8992       timeout = vat_time_now (vam) + 1.0;
8993       while (vat_time_now (vam) < timeout)
8994         if (vam->result_ready == 1)
8995           goto out;
8996       vam->retval = -99;
8997
8998     out:
8999       if (vam->retval == -99)
9000         errmsg ("timeout");
9001
9002       if (vam->async_errors > 0)
9003         {
9004           errmsg ("%d asynchronous errors", vam->async_errors);
9005           vam->retval = -98;
9006         }
9007       vam->async_errors = 0;
9008       after = vat_time_now (vam);
9009
9010       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9011       if (j > 0)
9012         count = j;
9013
9014       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9015              count, after - before, count / (after - before));
9016     }
9017   else
9018     {
9019       int ret;
9020
9021       /* Wait for a reply... */
9022       W (ret);
9023       return ret;
9024     }
9025
9026   /* Return the good/bad news */
9027   return (vam->retval);
9028 }
9029
9030 static int
9031 api_mpls_ip_bind_unbind (vat_main_t * vam)
9032 {
9033   unformat_input_t *i = vam->input;
9034   vl_api_mpls_ip_bind_unbind_t *mp;
9035   u32 ip_table_id = 0;
9036   u8 is_bind = 1;
9037   u8 is_ip4 = 1;
9038   ip4_address_t v4_address;
9039   ip6_address_t v6_address;
9040   u32 address_length;
9041   u8 address_set = 0;
9042   mpls_label_t local_label = MPLS_LABEL_INVALID;
9043   int ret;
9044
9045   /* Parse args required to build the message */
9046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9047     {
9048       if (unformat (i, "%U/%d", unformat_ip4_address,
9049                     &v4_address, &address_length))
9050         {
9051           is_ip4 = 1;
9052           address_set = 1;
9053         }
9054       else if (unformat (i, "%U/%d", unformat_ip6_address,
9055                          &v6_address, &address_length))
9056         {
9057           is_ip4 = 0;
9058           address_set = 1;
9059         }
9060       else if (unformat (i, "%d", &local_label))
9061         ;
9062       else if (unformat (i, "table-id %d", &ip_table_id))
9063         ;
9064       else if (unformat (i, "unbind"))
9065         is_bind = 0;
9066       else if (unformat (i, "bind"))
9067         is_bind = 1;
9068       else
9069         {
9070           clib_warning ("parse error '%U'", format_unformat_error, i);
9071           return -99;
9072         }
9073     }
9074
9075   if (!address_set)
9076     {
9077       errmsg ("IP addres not set");
9078       return -99;
9079     }
9080
9081   if (MPLS_LABEL_INVALID == local_label)
9082     {
9083       errmsg ("missing label");
9084       return -99;
9085     }
9086
9087   /* Construct the API message */
9088   M (MPLS_IP_BIND_UNBIND, mp);
9089
9090   mp->mb_is_bind = is_bind;
9091   mp->mb_is_ip4 = is_ip4;
9092   mp->mb_ip_table_id = ntohl (ip_table_id);
9093   mp->mb_mpls_table_id = 0;
9094   mp->mb_label = ntohl (local_label);
9095   mp->mb_address_length = address_length;
9096
9097   if (is_ip4)
9098     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9099   else
9100     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9101
9102   /* send it... */
9103   S (mp);
9104
9105   /* Wait for a reply... */
9106   W (ret);
9107   return ret;
9108 }
9109
9110 static int
9111 api_bier_table_add_del (vat_main_t * vam)
9112 {
9113   unformat_input_t *i = vam->input;
9114   vl_api_bier_table_add_del_t *mp;
9115   u8 is_add = 1;
9116   u32 set = 0, sub_domain = 0, hdr_len = 3;
9117   mpls_label_t local_label = MPLS_LABEL_INVALID;
9118   int ret;
9119
9120   /* Parse args required to build the message */
9121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9122     {
9123       if (unformat (i, "sub-domain %d", &sub_domain))
9124         ;
9125       else if (unformat (i, "set %d", &set))
9126         ;
9127       else if (unformat (i, "label %d", &local_label))
9128         ;
9129       else if (unformat (i, "hdr-len %d", &hdr_len))
9130         ;
9131       else if (unformat (i, "add"))
9132         is_add = 1;
9133       else if (unformat (i, "del"))
9134         is_add = 0;
9135       else
9136         {
9137           clib_warning ("parse error '%U'", format_unformat_error, i);
9138           return -99;
9139         }
9140     }
9141
9142   if (MPLS_LABEL_INVALID == local_label)
9143     {
9144       errmsg ("missing label\n");
9145       return -99;
9146     }
9147
9148   /* Construct the API message */
9149   M (BIER_TABLE_ADD_DEL, mp);
9150
9151   mp->bt_is_add = is_add;
9152   mp->bt_label = ntohl (local_label);
9153   mp->bt_tbl_id.bt_set = set;
9154   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9155   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9156
9157   /* send it... */
9158   S (mp);
9159
9160   /* Wait for a reply... */
9161   W (ret);
9162
9163   return (ret);
9164 }
9165
9166 static int
9167 api_bier_route_add_del (vat_main_t * vam)
9168 {
9169   unformat_input_t *i = vam->input;
9170   vl_api_bier_route_add_del_t *mp;
9171   u8 is_add = 1;
9172   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9173   ip4_address_t v4_next_hop_address;
9174   ip6_address_t v6_next_hop_address;
9175   u8 next_hop_set = 0;
9176   u8 next_hop_proto_is_ip4 = 1;
9177   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9178   int ret;
9179
9180   /* Parse args required to build the message */
9181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9182     {
9183       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9184         {
9185           next_hop_proto_is_ip4 = 1;
9186           next_hop_set = 1;
9187         }
9188       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9189         {
9190           next_hop_proto_is_ip4 = 0;
9191           next_hop_set = 1;
9192         }
9193       if (unformat (i, "sub-domain %d", &sub_domain))
9194         ;
9195       else if (unformat (i, "set %d", &set))
9196         ;
9197       else if (unformat (i, "hdr-len %d", &hdr_len))
9198         ;
9199       else if (unformat (i, "bp %d", &bp))
9200         ;
9201       else if (unformat (i, "add"))
9202         is_add = 1;
9203       else if (unformat (i, "del"))
9204         is_add = 0;
9205       else if (unformat (i, "out-label %d", &next_hop_out_label))
9206         ;
9207       else
9208         {
9209           clib_warning ("parse error '%U'", format_unformat_error, i);
9210           return -99;
9211         }
9212     }
9213
9214   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9215     {
9216       errmsg ("next hop / label set\n");
9217       return -99;
9218     }
9219   if (0 == bp)
9220     {
9221       errmsg ("bit=position not set\n");
9222       return -99;
9223     }
9224
9225   /* Construct the API message */
9226   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9227
9228   mp->br_is_add = is_add;
9229   mp->br_tbl_id.bt_set = set;
9230   mp->br_tbl_id.bt_sub_domain = sub_domain;
9231   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9232   mp->br_bp = ntohs (bp);
9233   mp->br_n_paths = 1;
9234   mp->br_paths[0].n_labels = 1;
9235   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9236   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9237
9238   if (next_hop_proto_is_ip4)
9239     {
9240       clib_memcpy (mp->br_paths[0].next_hop,
9241                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9242     }
9243   else
9244     {
9245       clib_memcpy (mp->br_paths[0].next_hop,
9246                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9247     }
9248
9249   /* send it... */
9250   S (mp);
9251
9252   /* Wait for a reply... */
9253   W (ret);
9254
9255   return (ret);
9256 }
9257
9258 static int
9259 api_proxy_arp_add_del (vat_main_t * vam)
9260 {
9261   unformat_input_t *i = vam->input;
9262   vl_api_proxy_arp_add_del_t *mp;
9263   u32 vrf_id = 0;
9264   u8 is_add = 1;
9265   ip4_address_t lo, hi;
9266   u8 range_set = 0;
9267   int ret;
9268
9269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9270     {
9271       if (unformat (i, "vrf %d", &vrf_id))
9272         ;
9273       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9274                          unformat_ip4_address, &hi))
9275         range_set = 1;
9276       else if (unformat (i, "del"))
9277         is_add = 0;
9278       else
9279         {
9280           clib_warning ("parse error '%U'", format_unformat_error, i);
9281           return -99;
9282         }
9283     }
9284
9285   if (range_set == 0)
9286     {
9287       errmsg ("address range not set");
9288       return -99;
9289     }
9290
9291   M (PROXY_ARP_ADD_DEL, mp);
9292
9293   mp->proxy.vrf_id = ntohl (vrf_id);
9294   mp->is_add = is_add;
9295   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9296   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9297
9298   S (mp);
9299   W (ret);
9300   return ret;
9301 }
9302
9303 static int
9304 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9305 {
9306   unformat_input_t *i = vam->input;
9307   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9308   u32 sw_if_index;
9309   u8 enable = 1;
9310   u8 sw_if_index_set = 0;
9311   int ret;
9312
9313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9314     {
9315       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9316         sw_if_index_set = 1;
9317       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9318         sw_if_index_set = 1;
9319       else if (unformat (i, "enable"))
9320         enable = 1;
9321       else if (unformat (i, "disable"))
9322         enable = 0;
9323       else
9324         {
9325           clib_warning ("parse error '%U'", format_unformat_error, i);
9326           return -99;
9327         }
9328     }
9329
9330   if (sw_if_index_set == 0)
9331     {
9332       errmsg ("missing interface name or sw_if_index");
9333       return -99;
9334     }
9335
9336   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9337
9338   mp->sw_if_index = ntohl (sw_if_index);
9339   mp->enable_disable = enable;
9340
9341   S (mp);
9342   W (ret);
9343   return ret;
9344 }
9345
9346 static int
9347 api_mpls_tunnel_add_del (vat_main_t * vam)
9348 {
9349   unformat_input_t *i = vam->input;
9350   vl_api_mpls_tunnel_add_del_t *mp;
9351
9352   u8 is_add = 1;
9353   u8 l2_only = 0;
9354   u32 sw_if_index = ~0;
9355   u32 next_hop_sw_if_index = ~0;
9356   u32 next_hop_proto_is_ip4 = 1;
9357
9358   u32 next_hop_table_id = 0;
9359   ip4_address_t v4_next_hop_address = {
9360     .as_u32 = 0,
9361   };
9362   ip6_address_t v6_next_hop_address = { {0} };
9363   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9364   int ret;
9365
9366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9367     {
9368       if (unformat (i, "add"))
9369         is_add = 1;
9370       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9371         is_add = 0;
9372       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9373         ;
9374       else if (unformat (i, "via %U",
9375                          unformat_ip4_address, &v4_next_hop_address))
9376         {
9377           next_hop_proto_is_ip4 = 1;
9378         }
9379       else if (unformat (i, "via %U",
9380                          unformat_ip6_address, &v6_next_hop_address))
9381         {
9382           next_hop_proto_is_ip4 = 0;
9383         }
9384       else if (unformat (i, "l2-only"))
9385         l2_only = 1;
9386       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9387         ;
9388       else if (unformat (i, "out-label %d", &next_hop_out_label))
9389         vec_add1 (labels, ntohl (next_hop_out_label));
9390       else
9391         {
9392           clib_warning ("parse error '%U'", format_unformat_error, i);
9393           return -99;
9394         }
9395     }
9396
9397   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9398
9399   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9400   mp->mt_sw_if_index = ntohl (sw_if_index);
9401   mp->mt_is_add = is_add;
9402   mp->mt_l2_only = l2_only;
9403   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9404   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9405
9406   mp->mt_next_hop_n_out_labels = vec_len (labels);
9407
9408   if (0 != mp->mt_next_hop_n_out_labels)
9409     {
9410       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9411                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9412       vec_free (labels);
9413     }
9414
9415   if (next_hop_proto_is_ip4)
9416     {
9417       clib_memcpy (mp->mt_next_hop,
9418                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9419     }
9420   else
9421     {
9422       clib_memcpy (mp->mt_next_hop,
9423                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9424     }
9425
9426   S (mp);
9427   W (ret);
9428   return ret;
9429 }
9430
9431 static int
9432 api_sw_interface_set_unnumbered (vat_main_t * vam)
9433 {
9434   unformat_input_t *i = vam->input;
9435   vl_api_sw_interface_set_unnumbered_t *mp;
9436   u32 sw_if_index;
9437   u32 unnum_sw_index = ~0;
9438   u8 is_add = 1;
9439   u8 sw_if_index_set = 0;
9440   int ret;
9441
9442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9443     {
9444       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9445         sw_if_index_set = 1;
9446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9447         sw_if_index_set = 1;
9448       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9449         ;
9450       else if (unformat (i, "del"))
9451         is_add = 0;
9452       else
9453         {
9454           clib_warning ("parse error '%U'", format_unformat_error, i);
9455           return -99;
9456         }
9457     }
9458
9459   if (sw_if_index_set == 0)
9460     {
9461       errmsg ("missing interface name or sw_if_index");
9462       return -99;
9463     }
9464
9465   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9466
9467   mp->sw_if_index = ntohl (sw_if_index);
9468   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9469   mp->is_add = is_add;
9470
9471   S (mp);
9472   W (ret);
9473   return ret;
9474 }
9475
9476 static int
9477 api_ip_neighbor_add_del (vat_main_t * vam)
9478 {
9479   unformat_input_t *i = vam->input;
9480   vl_api_ip_neighbor_add_del_t *mp;
9481   u32 sw_if_index;
9482   u8 sw_if_index_set = 0;
9483   u8 is_add = 1;
9484   u8 is_static = 0;
9485   u8 is_no_fib_entry = 0;
9486   u8 mac_address[6];
9487   u8 mac_set = 0;
9488   u8 v4_address_set = 0;
9489   u8 v6_address_set = 0;
9490   ip4_address_t v4address;
9491   ip6_address_t v6address;
9492   int ret;
9493
9494   memset (mac_address, 0, sizeof (mac_address));
9495
9496   /* Parse args required to build the message */
9497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9498     {
9499       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9500         {
9501           mac_set = 1;
9502         }
9503       else if (unformat (i, "del"))
9504         is_add = 0;
9505       else
9506         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9507         sw_if_index_set = 1;
9508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9509         sw_if_index_set = 1;
9510       else if (unformat (i, "is_static"))
9511         is_static = 1;
9512       else if (unformat (i, "no-fib-entry"))
9513         is_no_fib_entry = 1;
9514       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9515         v4_address_set = 1;
9516       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9517         v6_address_set = 1;
9518       else
9519         {
9520           clib_warning ("parse error '%U'", format_unformat_error, i);
9521           return -99;
9522         }
9523     }
9524
9525   if (sw_if_index_set == 0)
9526     {
9527       errmsg ("missing interface name or sw_if_index");
9528       return -99;
9529     }
9530   if (v4_address_set && v6_address_set)
9531     {
9532       errmsg ("both v4 and v6 addresses set");
9533       return -99;
9534     }
9535   if (!v4_address_set && !v6_address_set)
9536     {
9537       errmsg ("no address set");
9538       return -99;
9539     }
9540
9541   /* Construct the API message */
9542   M (IP_NEIGHBOR_ADD_DEL, mp);
9543
9544   mp->sw_if_index = ntohl (sw_if_index);
9545   mp->is_add = is_add;
9546   mp->is_static = is_static;
9547   mp->is_no_adj_fib = is_no_fib_entry;
9548   if (mac_set)
9549     clib_memcpy (mp->mac_address, mac_address, 6);
9550   if (v6_address_set)
9551     {
9552       mp->is_ipv6 = 1;
9553       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9554     }
9555   else
9556     {
9557       /* mp->is_ipv6 = 0; via memset in M macro above */
9558       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9559     }
9560
9561   /* send it... */
9562   S (mp);
9563
9564   /* Wait for a reply, return good/bad news  */
9565   W (ret);
9566   return ret;
9567 }
9568
9569 static int
9570 api_create_vlan_subif (vat_main_t * vam)
9571 {
9572   unformat_input_t *i = vam->input;
9573   vl_api_create_vlan_subif_t *mp;
9574   u32 sw_if_index;
9575   u8 sw_if_index_set = 0;
9576   u32 vlan_id;
9577   u8 vlan_id_set = 0;
9578   int ret;
9579
9580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9581     {
9582       if (unformat (i, "sw_if_index %d", &sw_if_index))
9583         sw_if_index_set = 1;
9584       else
9585         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9586         sw_if_index_set = 1;
9587       else if (unformat (i, "vlan %d", &vlan_id))
9588         vlan_id_set = 1;
9589       else
9590         {
9591           clib_warning ("parse error '%U'", format_unformat_error, i);
9592           return -99;
9593         }
9594     }
9595
9596   if (sw_if_index_set == 0)
9597     {
9598       errmsg ("missing interface name or sw_if_index");
9599       return -99;
9600     }
9601
9602   if (vlan_id_set == 0)
9603     {
9604       errmsg ("missing vlan_id");
9605       return -99;
9606     }
9607   M (CREATE_VLAN_SUBIF, mp);
9608
9609   mp->sw_if_index = ntohl (sw_if_index);
9610   mp->vlan_id = ntohl (vlan_id);
9611
9612   S (mp);
9613   W (ret);
9614   return ret;
9615 }
9616
9617 #define foreach_create_subif_bit                \
9618 _(no_tags)                                      \
9619 _(one_tag)                                      \
9620 _(two_tags)                                     \
9621 _(dot1ad)                                       \
9622 _(exact_match)                                  \
9623 _(default_sub)                                  \
9624 _(outer_vlan_id_any)                            \
9625 _(inner_vlan_id_any)
9626
9627 static int
9628 api_create_subif (vat_main_t * vam)
9629 {
9630   unformat_input_t *i = vam->input;
9631   vl_api_create_subif_t *mp;
9632   u32 sw_if_index;
9633   u8 sw_if_index_set = 0;
9634   u32 sub_id;
9635   u8 sub_id_set = 0;
9636   u32 no_tags = 0;
9637   u32 one_tag = 0;
9638   u32 two_tags = 0;
9639   u32 dot1ad = 0;
9640   u32 exact_match = 0;
9641   u32 default_sub = 0;
9642   u32 outer_vlan_id_any = 0;
9643   u32 inner_vlan_id_any = 0;
9644   u32 tmp;
9645   u16 outer_vlan_id = 0;
9646   u16 inner_vlan_id = 0;
9647   int ret;
9648
9649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9650     {
9651       if (unformat (i, "sw_if_index %d", &sw_if_index))
9652         sw_if_index_set = 1;
9653       else
9654         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9655         sw_if_index_set = 1;
9656       else if (unformat (i, "sub_id %d", &sub_id))
9657         sub_id_set = 1;
9658       else if (unformat (i, "outer_vlan_id %d", &tmp))
9659         outer_vlan_id = tmp;
9660       else if (unformat (i, "inner_vlan_id %d", &tmp))
9661         inner_vlan_id = tmp;
9662
9663 #define _(a) else if (unformat (i, #a)) a = 1 ;
9664       foreach_create_subif_bit
9665 #undef _
9666         else
9667         {
9668           clib_warning ("parse error '%U'", format_unformat_error, i);
9669           return -99;
9670         }
9671     }
9672
9673   if (sw_if_index_set == 0)
9674     {
9675       errmsg ("missing interface name or sw_if_index");
9676       return -99;
9677     }
9678
9679   if (sub_id_set == 0)
9680     {
9681       errmsg ("missing sub_id");
9682       return -99;
9683     }
9684   M (CREATE_SUBIF, mp);
9685
9686   mp->sw_if_index = ntohl (sw_if_index);
9687   mp->sub_id = ntohl (sub_id);
9688
9689 #define _(a) mp->a = a;
9690   foreach_create_subif_bit;
9691 #undef _
9692
9693   mp->outer_vlan_id = ntohs (outer_vlan_id);
9694   mp->inner_vlan_id = ntohs (inner_vlan_id);
9695
9696   S (mp);
9697   W (ret);
9698   return ret;
9699 }
9700
9701 static int
9702 api_oam_add_del (vat_main_t * vam)
9703 {
9704   unformat_input_t *i = vam->input;
9705   vl_api_oam_add_del_t *mp;
9706   u32 vrf_id = 0;
9707   u8 is_add = 1;
9708   ip4_address_t src, dst;
9709   u8 src_set = 0;
9710   u8 dst_set = 0;
9711   int ret;
9712
9713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9714     {
9715       if (unformat (i, "vrf %d", &vrf_id))
9716         ;
9717       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9718         src_set = 1;
9719       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9720         dst_set = 1;
9721       else if (unformat (i, "del"))
9722         is_add = 0;
9723       else
9724         {
9725           clib_warning ("parse error '%U'", format_unformat_error, i);
9726           return -99;
9727         }
9728     }
9729
9730   if (src_set == 0)
9731     {
9732       errmsg ("missing src addr");
9733       return -99;
9734     }
9735
9736   if (dst_set == 0)
9737     {
9738       errmsg ("missing dst addr");
9739       return -99;
9740     }
9741
9742   M (OAM_ADD_DEL, mp);
9743
9744   mp->vrf_id = ntohl (vrf_id);
9745   mp->is_add = is_add;
9746   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9747   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9748
9749   S (mp);
9750   W (ret);
9751   return ret;
9752 }
9753
9754 static int
9755 api_reset_fib (vat_main_t * vam)
9756 {
9757   unformat_input_t *i = vam->input;
9758   vl_api_reset_fib_t *mp;
9759   u32 vrf_id = 0;
9760   u8 is_ipv6 = 0;
9761   u8 vrf_id_set = 0;
9762
9763   int ret;
9764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9765     {
9766       if (unformat (i, "vrf %d", &vrf_id))
9767         vrf_id_set = 1;
9768       else if (unformat (i, "ipv6"))
9769         is_ipv6 = 1;
9770       else
9771         {
9772           clib_warning ("parse error '%U'", format_unformat_error, i);
9773           return -99;
9774         }
9775     }
9776
9777   if (vrf_id_set == 0)
9778     {
9779       errmsg ("missing vrf id");
9780       return -99;
9781     }
9782
9783   M (RESET_FIB, mp);
9784
9785   mp->vrf_id = ntohl (vrf_id);
9786   mp->is_ipv6 = is_ipv6;
9787
9788   S (mp);
9789   W (ret);
9790   return ret;
9791 }
9792
9793 static int
9794 api_dhcp_proxy_config (vat_main_t * vam)
9795 {
9796   unformat_input_t *i = vam->input;
9797   vl_api_dhcp_proxy_config_t *mp;
9798   u32 rx_vrf_id = 0;
9799   u32 server_vrf_id = 0;
9800   u8 is_add = 1;
9801   u8 v4_address_set = 0;
9802   u8 v6_address_set = 0;
9803   ip4_address_t v4address;
9804   ip6_address_t v6address;
9805   u8 v4_src_address_set = 0;
9806   u8 v6_src_address_set = 0;
9807   ip4_address_t v4srcaddress;
9808   ip6_address_t v6srcaddress;
9809   int ret;
9810
9811   /* Parse args required to build the message */
9812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9813     {
9814       if (unformat (i, "del"))
9815         is_add = 0;
9816       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9817         ;
9818       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9819         ;
9820       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9821         v4_address_set = 1;
9822       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9823         v6_address_set = 1;
9824       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9825         v4_src_address_set = 1;
9826       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9827         v6_src_address_set = 1;
9828       else
9829         break;
9830     }
9831
9832   if (v4_address_set && v6_address_set)
9833     {
9834       errmsg ("both v4 and v6 server addresses set");
9835       return -99;
9836     }
9837   if (!v4_address_set && !v6_address_set)
9838     {
9839       errmsg ("no server addresses set");
9840       return -99;
9841     }
9842
9843   if (v4_src_address_set && v6_src_address_set)
9844     {
9845       errmsg ("both v4 and v6  src addresses set");
9846       return -99;
9847     }
9848   if (!v4_src_address_set && !v6_src_address_set)
9849     {
9850       errmsg ("no src addresses set");
9851       return -99;
9852     }
9853
9854   if (!(v4_src_address_set && v4_address_set) &&
9855       !(v6_src_address_set && v6_address_set))
9856     {
9857       errmsg ("no matching server and src addresses set");
9858       return -99;
9859     }
9860
9861   /* Construct the API message */
9862   M (DHCP_PROXY_CONFIG, mp);
9863
9864   mp->is_add = is_add;
9865   mp->rx_vrf_id = ntohl (rx_vrf_id);
9866   mp->server_vrf_id = ntohl (server_vrf_id);
9867   if (v6_address_set)
9868     {
9869       mp->is_ipv6 = 1;
9870       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9871       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9872     }
9873   else
9874     {
9875       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9876       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9877     }
9878
9879   /* send it... */
9880   S (mp);
9881
9882   /* Wait for a reply, return good/bad news  */
9883   W (ret);
9884   return ret;
9885 }
9886
9887 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9888 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9889
9890 static void
9891 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9892 {
9893   vat_main_t *vam = &vat_main;
9894   u32 i, count = mp->count;
9895   vl_api_dhcp_server_t *s;
9896
9897   if (mp->is_ipv6)
9898     print (vam->ofp,
9899            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9900            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9901            ntohl (mp->rx_vrf_id),
9902            format_ip6_address, mp->dhcp_src_address,
9903            mp->vss_type, mp->vss_vpn_ascii_id,
9904            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9905   else
9906     print (vam->ofp,
9907            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9908            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9909            ntohl (mp->rx_vrf_id),
9910            format_ip4_address, mp->dhcp_src_address,
9911            mp->vss_type, mp->vss_vpn_ascii_id,
9912            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9913
9914   for (i = 0; i < count; i++)
9915     {
9916       s = &mp->servers[i];
9917
9918       if (mp->is_ipv6)
9919         print (vam->ofp,
9920                " Server Table-ID %d, Server Address %U",
9921                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9922       else
9923         print (vam->ofp,
9924                " Server Table-ID %d, Server Address %U",
9925                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9926     }
9927 }
9928
9929 static void vl_api_dhcp_proxy_details_t_handler_json
9930   (vl_api_dhcp_proxy_details_t * mp)
9931 {
9932   vat_main_t *vam = &vat_main;
9933   vat_json_node_t *node = NULL;
9934   u32 i, count = mp->count;
9935   struct in_addr ip4;
9936   struct in6_addr ip6;
9937   vl_api_dhcp_server_t *s;
9938
9939   if (VAT_JSON_ARRAY != vam->json_tree.type)
9940     {
9941       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9942       vat_json_init_array (&vam->json_tree);
9943     }
9944   node = vat_json_array_add (&vam->json_tree);
9945
9946   vat_json_init_object (node);
9947   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9948   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9949                              sizeof (mp->vss_type));
9950   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9951                                    mp->vss_vpn_ascii_id);
9952   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9953   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9954
9955   if (mp->is_ipv6)
9956     {
9957       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9958       vat_json_object_add_ip6 (node, "src_address", ip6);
9959     }
9960   else
9961     {
9962       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9963       vat_json_object_add_ip4 (node, "src_address", ip4);
9964     }
9965
9966   for (i = 0; i < count; i++)
9967     {
9968       s = &mp->servers[i];
9969
9970       vat_json_object_add_uint (node, "server-table-id",
9971                                 ntohl (s->server_vrf_id));
9972
9973       if (mp->is_ipv6)
9974         {
9975           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9976           vat_json_object_add_ip4 (node, "src_address", ip4);
9977         }
9978       else
9979         {
9980           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9981           vat_json_object_add_ip6 (node, "server_address", ip6);
9982         }
9983     }
9984 }
9985
9986 static int
9987 api_dhcp_proxy_dump (vat_main_t * vam)
9988 {
9989   unformat_input_t *i = vam->input;
9990   vl_api_control_ping_t *mp_ping;
9991   vl_api_dhcp_proxy_dump_t *mp;
9992   u8 is_ipv6 = 0;
9993   int ret;
9994
9995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9996     {
9997       if (unformat (i, "ipv6"))
9998         is_ipv6 = 1;
9999       else
10000         {
10001           clib_warning ("parse error '%U'", format_unformat_error, i);
10002           return -99;
10003         }
10004     }
10005
10006   M (DHCP_PROXY_DUMP, mp);
10007
10008   mp->is_ip6 = is_ipv6;
10009   S (mp);
10010
10011   /* Use a control ping for synchronization */
10012   MPING (CONTROL_PING, mp_ping);
10013   S (mp_ping);
10014
10015   W (ret);
10016   return ret;
10017 }
10018
10019 static int
10020 api_dhcp_proxy_set_vss (vat_main_t * vam)
10021 {
10022   unformat_input_t *i = vam->input;
10023   vl_api_dhcp_proxy_set_vss_t *mp;
10024   u8 is_ipv6 = 0;
10025   u8 is_add = 1;
10026   u32 tbl_id = ~0;
10027   u8 vss_type = VSS_TYPE_DEFAULT;
10028   u8 *vpn_ascii_id = 0;
10029   u32 oui = 0;
10030   u32 fib_id = 0;
10031   int ret;
10032
10033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10034     {
10035       if (unformat (i, "tbl_id %d", &tbl_id))
10036         ;
10037       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10038         vss_type = VSS_TYPE_ASCII;
10039       else if (unformat (i, "fib_id %d", &fib_id))
10040         vss_type = VSS_TYPE_VPN_ID;
10041       else if (unformat (i, "oui %d", &oui))
10042         vss_type = VSS_TYPE_VPN_ID;
10043       else if (unformat (i, "ipv6"))
10044         is_ipv6 = 1;
10045       else if (unformat (i, "del"))
10046         is_add = 0;
10047       else
10048         break;
10049     }
10050
10051   if (tbl_id == ~0)
10052     {
10053       errmsg ("missing tbl_id ");
10054       vec_free (vpn_ascii_id);
10055       return -99;
10056     }
10057
10058   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10059     {
10060       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10061       vec_free (vpn_ascii_id);
10062       return -99;
10063     }
10064
10065   M (DHCP_PROXY_SET_VSS, mp);
10066   mp->tbl_id = ntohl (tbl_id);
10067   mp->vss_type = vss_type;
10068   if (vpn_ascii_id)
10069     {
10070       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10071       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10072     }
10073   mp->vpn_index = ntohl (fib_id);
10074   mp->oui = ntohl (oui);
10075   mp->is_ipv6 = is_ipv6;
10076   mp->is_add = is_add;
10077
10078   S (mp);
10079   W (ret);
10080
10081   vec_free (vpn_ascii_id);
10082   return ret;
10083 }
10084
10085 static int
10086 api_dhcp_client_config (vat_main_t * vam)
10087 {
10088   unformat_input_t *i = vam->input;
10089   vl_api_dhcp_client_config_t *mp;
10090   u32 sw_if_index;
10091   u8 sw_if_index_set = 0;
10092   u8 is_add = 1;
10093   u8 *hostname = 0;
10094   u8 disable_event = 0;
10095   int ret;
10096
10097   /* Parse args required to build the message */
10098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10099     {
10100       if (unformat (i, "del"))
10101         is_add = 0;
10102       else
10103         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10104         sw_if_index_set = 1;
10105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10106         sw_if_index_set = 1;
10107       else if (unformat (i, "hostname %s", &hostname))
10108         ;
10109       else if (unformat (i, "disable_event"))
10110         disable_event = 1;
10111       else
10112         break;
10113     }
10114
10115   if (sw_if_index_set == 0)
10116     {
10117       errmsg ("missing interface name or sw_if_index");
10118       return -99;
10119     }
10120
10121   if (vec_len (hostname) > 63)
10122     {
10123       errmsg ("hostname too long");
10124     }
10125   vec_add1 (hostname, 0);
10126
10127   /* Construct the API message */
10128   M (DHCP_CLIENT_CONFIG, mp);
10129
10130   mp->is_add = is_add;
10131   mp->client.sw_if_index = htonl (sw_if_index);
10132   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10133   vec_free (hostname);
10134   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10135   mp->client.pid = htonl (getpid ());
10136
10137   /* send it... */
10138   S (mp);
10139
10140   /* Wait for a reply, return good/bad news  */
10141   W (ret);
10142   return ret;
10143 }
10144
10145 static int
10146 api_set_ip_flow_hash (vat_main_t * vam)
10147 {
10148   unformat_input_t *i = vam->input;
10149   vl_api_set_ip_flow_hash_t *mp;
10150   u32 vrf_id = 0;
10151   u8 is_ipv6 = 0;
10152   u8 vrf_id_set = 0;
10153   u8 src = 0;
10154   u8 dst = 0;
10155   u8 sport = 0;
10156   u8 dport = 0;
10157   u8 proto = 0;
10158   u8 reverse = 0;
10159   int ret;
10160
10161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10162     {
10163       if (unformat (i, "vrf %d", &vrf_id))
10164         vrf_id_set = 1;
10165       else if (unformat (i, "ipv6"))
10166         is_ipv6 = 1;
10167       else if (unformat (i, "src"))
10168         src = 1;
10169       else if (unformat (i, "dst"))
10170         dst = 1;
10171       else if (unformat (i, "sport"))
10172         sport = 1;
10173       else if (unformat (i, "dport"))
10174         dport = 1;
10175       else if (unformat (i, "proto"))
10176         proto = 1;
10177       else if (unformat (i, "reverse"))
10178         reverse = 1;
10179
10180       else
10181         {
10182           clib_warning ("parse error '%U'", format_unformat_error, i);
10183           return -99;
10184         }
10185     }
10186
10187   if (vrf_id_set == 0)
10188     {
10189       errmsg ("missing vrf id");
10190       return -99;
10191     }
10192
10193   M (SET_IP_FLOW_HASH, mp);
10194   mp->src = src;
10195   mp->dst = dst;
10196   mp->sport = sport;
10197   mp->dport = dport;
10198   mp->proto = proto;
10199   mp->reverse = reverse;
10200   mp->vrf_id = ntohl (vrf_id);
10201   mp->is_ipv6 = is_ipv6;
10202
10203   S (mp);
10204   W (ret);
10205   return ret;
10206 }
10207
10208 static int
10209 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10210 {
10211   unformat_input_t *i = vam->input;
10212   vl_api_sw_interface_ip6_enable_disable_t *mp;
10213   u32 sw_if_index;
10214   u8 sw_if_index_set = 0;
10215   u8 enable = 0;
10216   int ret;
10217
10218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10219     {
10220       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10221         sw_if_index_set = 1;
10222       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10223         sw_if_index_set = 1;
10224       else if (unformat (i, "enable"))
10225         enable = 1;
10226       else if (unformat (i, "disable"))
10227         enable = 0;
10228       else
10229         {
10230           clib_warning ("parse error '%U'", format_unformat_error, i);
10231           return -99;
10232         }
10233     }
10234
10235   if (sw_if_index_set == 0)
10236     {
10237       errmsg ("missing interface name or sw_if_index");
10238       return -99;
10239     }
10240
10241   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10242
10243   mp->sw_if_index = ntohl (sw_if_index);
10244   mp->enable = enable;
10245
10246   S (mp);
10247   W (ret);
10248   return ret;
10249 }
10250
10251 static int
10252 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10253 {
10254   unformat_input_t *i = vam->input;
10255   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10256   u32 sw_if_index;
10257   u8 sw_if_index_set = 0;
10258   u8 v6_address_set = 0;
10259   ip6_address_t v6address;
10260   int ret;
10261
10262   /* Parse args required to build the message */
10263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10264     {
10265       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10266         sw_if_index_set = 1;
10267       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10268         sw_if_index_set = 1;
10269       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10270         v6_address_set = 1;
10271       else
10272         break;
10273     }
10274
10275   if (sw_if_index_set == 0)
10276     {
10277       errmsg ("missing interface name or sw_if_index");
10278       return -99;
10279     }
10280   if (!v6_address_set)
10281     {
10282       errmsg ("no address set");
10283       return -99;
10284     }
10285
10286   /* Construct the API message */
10287   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10288
10289   mp->sw_if_index = ntohl (sw_if_index);
10290   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10291
10292   /* send it... */
10293   S (mp);
10294
10295   /* Wait for a reply, return good/bad news  */
10296   W (ret);
10297   return ret;
10298 }
10299
10300 static int
10301 api_ip6nd_proxy_add_del (vat_main_t * vam)
10302 {
10303   unformat_input_t *i = vam->input;
10304   vl_api_ip6nd_proxy_add_del_t *mp;
10305   u32 sw_if_index = ~0;
10306   u8 v6_address_set = 0;
10307   ip6_address_t v6address;
10308   u8 is_del = 0;
10309   int ret;
10310
10311   /* Parse args required to build the message */
10312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10313     {
10314       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10315         ;
10316       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10317         ;
10318       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10319         v6_address_set = 1;
10320       if (unformat (i, "del"))
10321         is_del = 1;
10322       else
10323         {
10324           clib_warning ("parse error '%U'", format_unformat_error, i);
10325           return -99;
10326         }
10327     }
10328
10329   if (sw_if_index == ~0)
10330     {
10331       errmsg ("missing interface name or sw_if_index");
10332       return -99;
10333     }
10334   if (!v6_address_set)
10335     {
10336       errmsg ("no address set");
10337       return -99;
10338     }
10339
10340   /* Construct the API message */
10341   M (IP6ND_PROXY_ADD_DEL, mp);
10342
10343   mp->is_del = is_del;
10344   mp->sw_if_index = ntohl (sw_if_index);
10345   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10346
10347   /* send it... */
10348   S (mp);
10349
10350   /* Wait for a reply, return good/bad news  */
10351   W (ret);
10352   return ret;
10353 }
10354
10355 static int
10356 api_ip6nd_proxy_dump (vat_main_t * vam)
10357 {
10358   vl_api_ip6nd_proxy_dump_t *mp;
10359   vl_api_control_ping_t *mp_ping;
10360   int ret;
10361
10362   M (IP6ND_PROXY_DUMP, mp);
10363
10364   S (mp);
10365
10366   /* Use a control ping for synchronization */
10367   MPING (CONTROL_PING, mp_ping);
10368   S (mp_ping);
10369
10370   W (ret);
10371   return ret;
10372 }
10373
10374 static void vl_api_ip6nd_proxy_details_t_handler
10375   (vl_api_ip6nd_proxy_details_t * mp)
10376 {
10377   vat_main_t *vam = &vat_main;
10378
10379   print (vam->ofp, "host %U sw_if_index %d",
10380          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10381 }
10382
10383 static void vl_api_ip6nd_proxy_details_t_handler_json
10384   (vl_api_ip6nd_proxy_details_t * mp)
10385 {
10386   vat_main_t *vam = &vat_main;
10387   struct in6_addr ip6;
10388   vat_json_node_t *node = NULL;
10389
10390   if (VAT_JSON_ARRAY != vam->json_tree.type)
10391     {
10392       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10393       vat_json_init_array (&vam->json_tree);
10394     }
10395   node = vat_json_array_add (&vam->json_tree);
10396
10397   vat_json_init_object (node);
10398   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10399
10400   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10401   vat_json_object_add_ip6 (node, "host", ip6);
10402 }
10403
10404 static int
10405 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10406 {
10407   unformat_input_t *i = vam->input;
10408   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10409   u32 sw_if_index;
10410   u8 sw_if_index_set = 0;
10411   u32 address_length = 0;
10412   u8 v6_address_set = 0;
10413   ip6_address_t v6address;
10414   u8 use_default = 0;
10415   u8 no_advertise = 0;
10416   u8 off_link = 0;
10417   u8 no_autoconfig = 0;
10418   u8 no_onlink = 0;
10419   u8 is_no = 0;
10420   u32 val_lifetime = 0;
10421   u32 pref_lifetime = 0;
10422   int ret;
10423
10424   /* Parse args required to build the message */
10425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10426     {
10427       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10428         sw_if_index_set = 1;
10429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10430         sw_if_index_set = 1;
10431       else if (unformat (i, "%U/%d",
10432                          unformat_ip6_address, &v6address, &address_length))
10433         v6_address_set = 1;
10434       else if (unformat (i, "val_life %d", &val_lifetime))
10435         ;
10436       else if (unformat (i, "pref_life %d", &pref_lifetime))
10437         ;
10438       else if (unformat (i, "def"))
10439         use_default = 1;
10440       else if (unformat (i, "noadv"))
10441         no_advertise = 1;
10442       else if (unformat (i, "offl"))
10443         off_link = 1;
10444       else if (unformat (i, "noauto"))
10445         no_autoconfig = 1;
10446       else if (unformat (i, "nolink"))
10447         no_onlink = 1;
10448       else if (unformat (i, "isno"))
10449         is_no = 1;
10450       else
10451         {
10452           clib_warning ("parse error '%U'", format_unformat_error, i);
10453           return -99;
10454         }
10455     }
10456
10457   if (sw_if_index_set == 0)
10458     {
10459       errmsg ("missing interface name or sw_if_index");
10460       return -99;
10461     }
10462   if (!v6_address_set)
10463     {
10464       errmsg ("no address set");
10465       return -99;
10466     }
10467
10468   /* Construct the API message */
10469   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10470
10471   mp->sw_if_index = ntohl (sw_if_index);
10472   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10473   mp->address_length = address_length;
10474   mp->use_default = use_default;
10475   mp->no_advertise = no_advertise;
10476   mp->off_link = off_link;
10477   mp->no_autoconfig = no_autoconfig;
10478   mp->no_onlink = no_onlink;
10479   mp->is_no = is_no;
10480   mp->val_lifetime = ntohl (val_lifetime);
10481   mp->pref_lifetime = ntohl (pref_lifetime);
10482
10483   /* send it... */
10484   S (mp);
10485
10486   /* Wait for a reply, return good/bad news  */
10487   W (ret);
10488   return ret;
10489 }
10490
10491 static int
10492 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10493 {
10494   unformat_input_t *i = vam->input;
10495   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10496   u32 sw_if_index;
10497   u8 sw_if_index_set = 0;
10498   u8 suppress = 0;
10499   u8 managed = 0;
10500   u8 other = 0;
10501   u8 ll_option = 0;
10502   u8 send_unicast = 0;
10503   u8 cease = 0;
10504   u8 is_no = 0;
10505   u8 default_router = 0;
10506   u32 max_interval = 0;
10507   u32 min_interval = 0;
10508   u32 lifetime = 0;
10509   u32 initial_count = 0;
10510   u32 initial_interval = 0;
10511   int ret;
10512
10513
10514   /* Parse args required to build the message */
10515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10516     {
10517       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10518         sw_if_index_set = 1;
10519       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10520         sw_if_index_set = 1;
10521       else if (unformat (i, "maxint %d", &max_interval))
10522         ;
10523       else if (unformat (i, "minint %d", &min_interval))
10524         ;
10525       else if (unformat (i, "life %d", &lifetime))
10526         ;
10527       else if (unformat (i, "count %d", &initial_count))
10528         ;
10529       else if (unformat (i, "interval %d", &initial_interval))
10530         ;
10531       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10532         suppress = 1;
10533       else if (unformat (i, "managed"))
10534         managed = 1;
10535       else if (unformat (i, "other"))
10536         other = 1;
10537       else if (unformat (i, "ll"))
10538         ll_option = 1;
10539       else if (unformat (i, "send"))
10540         send_unicast = 1;
10541       else if (unformat (i, "cease"))
10542         cease = 1;
10543       else if (unformat (i, "isno"))
10544         is_no = 1;
10545       else if (unformat (i, "def"))
10546         default_router = 1;
10547       else
10548         {
10549           clib_warning ("parse error '%U'", format_unformat_error, i);
10550           return -99;
10551         }
10552     }
10553
10554   if (sw_if_index_set == 0)
10555     {
10556       errmsg ("missing interface name or sw_if_index");
10557       return -99;
10558     }
10559
10560   /* Construct the API message */
10561   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10562
10563   mp->sw_if_index = ntohl (sw_if_index);
10564   mp->max_interval = ntohl (max_interval);
10565   mp->min_interval = ntohl (min_interval);
10566   mp->lifetime = ntohl (lifetime);
10567   mp->initial_count = ntohl (initial_count);
10568   mp->initial_interval = ntohl (initial_interval);
10569   mp->suppress = suppress;
10570   mp->managed = managed;
10571   mp->other = other;
10572   mp->ll_option = ll_option;
10573   mp->send_unicast = send_unicast;
10574   mp->cease = cease;
10575   mp->is_no = is_no;
10576   mp->default_router = default_router;
10577
10578   /* send it... */
10579   S (mp);
10580
10581   /* Wait for a reply, return good/bad news  */
10582   W (ret);
10583   return ret;
10584 }
10585
10586 static int
10587 api_set_arp_neighbor_limit (vat_main_t * vam)
10588 {
10589   unformat_input_t *i = vam->input;
10590   vl_api_set_arp_neighbor_limit_t *mp;
10591   u32 arp_nbr_limit;
10592   u8 limit_set = 0;
10593   u8 is_ipv6 = 0;
10594   int ret;
10595
10596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10597     {
10598       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10599         limit_set = 1;
10600       else if (unformat (i, "ipv6"))
10601         is_ipv6 = 1;
10602       else
10603         {
10604           clib_warning ("parse error '%U'", format_unformat_error, i);
10605           return -99;
10606         }
10607     }
10608
10609   if (limit_set == 0)
10610     {
10611       errmsg ("missing limit value");
10612       return -99;
10613     }
10614
10615   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10616
10617   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10618   mp->is_ipv6 = is_ipv6;
10619
10620   S (mp);
10621   W (ret);
10622   return ret;
10623 }
10624
10625 static int
10626 api_l2_patch_add_del (vat_main_t * vam)
10627 {
10628   unformat_input_t *i = vam->input;
10629   vl_api_l2_patch_add_del_t *mp;
10630   u32 rx_sw_if_index;
10631   u8 rx_sw_if_index_set = 0;
10632   u32 tx_sw_if_index;
10633   u8 tx_sw_if_index_set = 0;
10634   u8 is_add = 1;
10635   int ret;
10636
10637   /* Parse args required to build the message */
10638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10639     {
10640       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10641         rx_sw_if_index_set = 1;
10642       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10643         tx_sw_if_index_set = 1;
10644       else if (unformat (i, "rx"))
10645         {
10646           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10647             {
10648               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10649                             &rx_sw_if_index))
10650                 rx_sw_if_index_set = 1;
10651             }
10652           else
10653             break;
10654         }
10655       else if (unformat (i, "tx"))
10656         {
10657           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10658             {
10659               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10660                             &tx_sw_if_index))
10661                 tx_sw_if_index_set = 1;
10662             }
10663           else
10664             break;
10665         }
10666       else if (unformat (i, "del"))
10667         is_add = 0;
10668       else
10669         break;
10670     }
10671
10672   if (rx_sw_if_index_set == 0)
10673     {
10674       errmsg ("missing rx interface name or rx_sw_if_index");
10675       return -99;
10676     }
10677
10678   if (tx_sw_if_index_set == 0)
10679     {
10680       errmsg ("missing tx interface name or tx_sw_if_index");
10681       return -99;
10682     }
10683
10684   M (L2_PATCH_ADD_DEL, mp);
10685
10686   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10687   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10688   mp->is_add = is_add;
10689
10690   S (mp);
10691   W (ret);
10692   return ret;
10693 }
10694
10695 u8 is_del;
10696 u8 localsid_addr[16];
10697 u8 end_psp;
10698 u8 behavior;
10699 u32 sw_if_index;
10700 u32 vlan_index;
10701 u32 fib_table;
10702 u8 nh_addr[16];
10703
10704 static int
10705 api_sr_localsid_add_del (vat_main_t * vam)
10706 {
10707   unformat_input_t *i = vam->input;
10708   vl_api_sr_localsid_add_del_t *mp;
10709
10710   u8 is_del;
10711   ip6_address_t localsid;
10712   u8 end_psp = 0;
10713   u8 behavior = ~0;
10714   u32 sw_if_index;
10715   u32 fib_table = ~(u32) 0;
10716   ip6_address_t next_hop;
10717
10718   bool nexthop_set = 0;
10719
10720   int ret;
10721
10722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10723     {
10724       if (unformat (i, "del"))
10725         is_del = 1;
10726       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10727       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10728         nexthop_set = 1;
10729       else if (unformat (i, "behavior %u", &behavior));
10730       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10731       else if (unformat (i, "fib-table %u", &fib_table));
10732       else if (unformat (i, "end.psp %u", &behavior));
10733       else
10734         break;
10735     }
10736
10737   M (SR_LOCALSID_ADD_DEL, mp);
10738
10739   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10740   if (nexthop_set)
10741     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10742   mp->behavior = behavior;
10743   mp->sw_if_index = ntohl (sw_if_index);
10744   mp->fib_table = ntohl (fib_table);
10745   mp->end_psp = end_psp;
10746   mp->is_del = is_del;
10747
10748   S (mp);
10749   W (ret);
10750   return ret;
10751 }
10752
10753 static int
10754 api_ioam_enable (vat_main_t * vam)
10755 {
10756   unformat_input_t *input = vam->input;
10757   vl_api_ioam_enable_t *mp;
10758   u32 id = 0;
10759   int has_trace_option = 0;
10760   int has_pot_option = 0;
10761   int has_seqno_option = 0;
10762   int has_analyse_option = 0;
10763   int ret;
10764
10765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10766     {
10767       if (unformat (input, "trace"))
10768         has_trace_option = 1;
10769       else if (unformat (input, "pot"))
10770         has_pot_option = 1;
10771       else if (unformat (input, "seqno"))
10772         has_seqno_option = 1;
10773       else if (unformat (input, "analyse"))
10774         has_analyse_option = 1;
10775       else
10776         break;
10777     }
10778   M (IOAM_ENABLE, mp);
10779   mp->id = htons (id);
10780   mp->seqno = has_seqno_option;
10781   mp->analyse = has_analyse_option;
10782   mp->pot_enable = has_pot_option;
10783   mp->trace_enable = has_trace_option;
10784
10785   S (mp);
10786   W (ret);
10787   return ret;
10788 }
10789
10790
10791 static int
10792 api_ioam_disable (vat_main_t * vam)
10793 {
10794   vl_api_ioam_disable_t *mp;
10795   int ret;
10796
10797   M (IOAM_DISABLE, mp);
10798   S (mp);
10799   W (ret);
10800   return ret;
10801 }
10802
10803 #define foreach_tcp_proto_field                 \
10804 _(src_port)                                     \
10805 _(dst_port)
10806
10807 #define foreach_udp_proto_field                 \
10808 _(src_port)                                     \
10809 _(dst_port)
10810
10811 #define foreach_ip4_proto_field                 \
10812 _(src_address)                                  \
10813 _(dst_address)                                  \
10814 _(tos)                                          \
10815 _(length)                                       \
10816 _(fragment_id)                                  \
10817 _(ttl)                                          \
10818 _(protocol)                                     \
10819 _(checksum)
10820
10821 typedef struct
10822 {
10823   u16 src_port, dst_port;
10824 } tcpudp_header_t;
10825
10826 #if VPP_API_TEST_BUILTIN == 0
10827 uword
10828 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10829 {
10830   u8 **maskp = va_arg (*args, u8 **);
10831   u8 *mask = 0;
10832   u8 found_something = 0;
10833   tcp_header_t *tcp;
10834
10835 #define _(a) u8 a=0;
10836   foreach_tcp_proto_field;
10837 #undef _
10838
10839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10840     {
10841       if (0);
10842 #define _(a) else if (unformat (input, #a)) a=1;
10843       foreach_tcp_proto_field
10844 #undef _
10845         else
10846         break;
10847     }
10848
10849 #define _(a) found_something += a;
10850   foreach_tcp_proto_field;
10851 #undef _
10852
10853   if (found_something == 0)
10854     return 0;
10855
10856   vec_validate (mask, sizeof (*tcp) - 1);
10857
10858   tcp = (tcp_header_t *) mask;
10859
10860 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10861   foreach_tcp_proto_field;
10862 #undef _
10863
10864   *maskp = mask;
10865   return 1;
10866 }
10867
10868 uword
10869 unformat_udp_mask (unformat_input_t * input, va_list * args)
10870 {
10871   u8 **maskp = va_arg (*args, u8 **);
10872   u8 *mask = 0;
10873   u8 found_something = 0;
10874   udp_header_t *udp;
10875
10876 #define _(a) u8 a=0;
10877   foreach_udp_proto_field;
10878 #undef _
10879
10880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10881     {
10882       if (0);
10883 #define _(a) else if (unformat (input, #a)) a=1;
10884       foreach_udp_proto_field
10885 #undef _
10886         else
10887         break;
10888     }
10889
10890 #define _(a) found_something += a;
10891   foreach_udp_proto_field;
10892 #undef _
10893
10894   if (found_something == 0)
10895     return 0;
10896
10897   vec_validate (mask, sizeof (*udp) - 1);
10898
10899   udp = (udp_header_t *) mask;
10900
10901 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10902   foreach_udp_proto_field;
10903 #undef _
10904
10905   *maskp = mask;
10906   return 1;
10907 }
10908
10909 uword
10910 unformat_l4_mask (unformat_input_t * input, va_list * args)
10911 {
10912   u8 **maskp = va_arg (*args, u8 **);
10913   u16 src_port = 0, dst_port = 0;
10914   tcpudp_header_t *tcpudp;
10915
10916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10917     {
10918       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10919         return 1;
10920       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10921         return 1;
10922       else if (unformat (input, "src_port"))
10923         src_port = 0xFFFF;
10924       else if (unformat (input, "dst_port"))
10925         dst_port = 0xFFFF;
10926       else
10927         return 0;
10928     }
10929
10930   if (!src_port && !dst_port)
10931     return 0;
10932
10933   u8 *mask = 0;
10934   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10935
10936   tcpudp = (tcpudp_header_t *) mask;
10937   tcpudp->src_port = src_port;
10938   tcpudp->dst_port = dst_port;
10939
10940   *maskp = mask;
10941
10942   return 1;
10943 }
10944
10945 uword
10946 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10947 {
10948   u8 **maskp = va_arg (*args, u8 **);
10949   u8 *mask = 0;
10950   u8 found_something = 0;
10951   ip4_header_t *ip;
10952
10953 #define _(a) u8 a=0;
10954   foreach_ip4_proto_field;
10955 #undef _
10956   u8 version = 0;
10957   u8 hdr_length = 0;
10958
10959
10960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10961     {
10962       if (unformat (input, "version"))
10963         version = 1;
10964       else if (unformat (input, "hdr_length"))
10965         hdr_length = 1;
10966       else if (unformat (input, "src"))
10967         src_address = 1;
10968       else if (unformat (input, "dst"))
10969         dst_address = 1;
10970       else if (unformat (input, "proto"))
10971         protocol = 1;
10972
10973 #define _(a) else if (unformat (input, #a)) a=1;
10974       foreach_ip4_proto_field
10975 #undef _
10976         else
10977         break;
10978     }
10979
10980 #define _(a) found_something += a;
10981   foreach_ip4_proto_field;
10982 #undef _
10983
10984   if (found_something == 0)
10985     return 0;
10986
10987   vec_validate (mask, sizeof (*ip) - 1);
10988
10989   ip = (ip4_header_t *) mask;
10990
10991 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10992   foreach_ip4_proto_field;
10993 #undef _
10994
10995   ip->ip_version_and_header_length = 0;
10996
10997   if (version)
10998     ip->ip_version_and_header_length |= 0xF0;
10999
11000   if (hdr_length)
11001     ip->ip_version_and_header_length |= 0x0F;
11002
11003   *maskp = mask;
11004   return 1;
11005 }
11006
11007 #define foreach_ip6_proto_field                 \
11008 _(src_address)                                  \
11009 _(dst_address)                                  \
11010 _(payload_length)                               \
11011 _(hop_limit)                                    \
11012 _(protocol)
11013
11014 uword
11015 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11016 {
11017   u8 **maskp = va_arg (*args, u8 **);
11018   u8 *mask = 0;
11019   u8 found_something = 0;
11020   ip6_header_t *ip;
11021   u32 ip_version_traffic_class_and_flow_label;
11022
11023 #define _(a) u8 a=0;
11024   foreach_ip6_proto_field;
11025 #undef _
11026   u8 version = 0;
11027   u8 traffic_class = 0;
11028   u8 flow_label = 0;
11029
11030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11031     {
11032       if (unformat (input, "version"))
11033         version = 1;
11034       else if (unformat (input, "traffic-class"))
11035         traffic_class = 1;
11036       else if (unformat (input, "flow-label"))
11037         flow_label = 1;
11038       else if (unformat (input, "src"))
11039         src_address = 1;
11040       else if (unformat (input, "dst"))
11041         dst_address = 1;
11042       else if (unformat (input, "proto"))
11043         protocol = 1;
11044
11045 #define _(a) else if (unformat (input, #a)) a=1;
11046       foreach_ip6_proto_field
11047 #undef _
11048         else
11049         break;
11050     }
11051
11052 #define _(a) found_something += a;
11053   foreach_ip6_proto_field;
11054 #undef _
11055
11056   if (found_something == 0)
11057     return 0;
11058
11059   vec_validate (mask, sizeof (*ip) - 1);
11060
11061   ip = (ip6_header_t *) mask;
11062
11063 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11064   foreach_ip6_proto_field;
11065 #undef _
11066
11067   ip_version_traffic_class_and_flow_label = 0;
11068
11069   if (version)
11070     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11071
11072   if (traffic_class)
11073     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11074
11075   if (flow_label)
11076     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11077
11078   ip->ip_version_traffic_class_and_flow_label =
11079     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11080
11081   *maskp = mask;
11082   return 1;
11083 }
11084
11085 uword
11086 unformat_l3_mask (unformat_input_t * input, va_list * args)
11087 {
11088   u8 **maskp = va_arg (*args, u8 **);
11089
11090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11091     {
11092       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11093         return 1;
11094       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11095         return 1;
11096       else
11097         break;
11098     }
11099   return 0;
11100 }
11101
11102 uword
11103 unformat_l2_mask (unformat_input_t * input, va_list * args)
11104 {
11105   u8 **maskp = va_arg (*args, u8 **);
11106   u8 *mask = 0;
11107   u8 src = 0;
11108   u8 dst = 0;
11109   u8 proto = 0;
11110   u8 tag1 = 0;
11111   u8 tag2 = 0;
11112   u8 ignore_tag1 = 0;
11113   u8 ignore_tag2 = 0;
11114   u8 cos1 = 0;
11115   u8 cos2 = 0;
11116   u8 dot1q = 0;
11117   u8 dot1ad = 0;
11118   int len = 14;
11119
11120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11121     {
11122       if (unformat (input, "src"))
11123         src = 1;
11124       else if (unformat (input, "dst"))
11125         dst = 1;
11126       else if (unformat (input, "proto"))
11127         proto = 1;
11128       else if (unformat (input, "tag1"))
11129         tag1 = 1;
11130       else if (unformat (input, "tag2"))
11131         tag2 = 1;
11132       else if (unformat (input, "ignore-tag1"))
11133         ignore_tag1 = 1;
11134       else if (unformat (input, "ignore-tag2"))
11135         ignore_tag2 = 1;
11136       else if (unformat (input, "cos1"))
11137         cos1 = 1;
11138       else if (unformat (input, "cos2"))
11139         cos2 = 1;
11140       else if (unformat (input, "dot1q"))
11141         dot1q = 1;
11142       else if (unformat (input, "dot1ad"))
11143         dot1ad = 1;
11144       else
11145         break;
11146     }
11147   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11148        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11149     return 0;
11150
11151   if (tag1 || ignore_tag1 || cos1 || dot1q)
11152     len = 18;
11153   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11154     len = 22;
11155
11156   vec_validate (mask, len - 1);
11157
11158   if (dst)
11159     memset (mask, 0xff, 6);
11160
11161   if (src)
11162     memset (mask + 6, 0xff, 6);
11163
11164   if (tag2 || dot1ad)
11165     {
11166       /* inner vlan tag */
11167       if (tag2)
11168         {
11169           mask[19] = 0xff;
11170           mask[18] = 0x0f;
11171         }
11172       if (cos2)
11173         mask[18] |= 0xe0;
11174       if (proto)
11175         mask[21] = mask[20] = 0xff;
11176       if (tag1)
11177         {
11178           mask[15] = 0xff;
11179           mask[14] = 0x0f;
11180         }
11181       if (cos1)
11182         mask[14] |= 0xe0;
11183       *maskp = mask;
11184       return 1;
11185     }
11186   if (tag1 | dot1q)
11187     {
11188       if (tag1)
11189         {
11190           mask[15] = 0xff;
11191           mask[14] = 0x0f;
11192         }
11193       if (cos1)
11194         mask[14] |= 0xe0;
11195       if (proto)
11196         mask[16] = mask[17] = 0xff;
11197
11198       *maskp = mask;
11199       return 1;
11200     }
11201   if (cos2)
11202     mask[18] |= 0xe0;
11203   if (cos1)
11204     mask[14] |= 0xe0;
11205   if (proto)
11206     mask[12] = mask[13] = 0xff;
11207
11208   *maskp = mask;
11209   return 1;
11210 }
11211
11212 uword
11213 unformat_classify_mask (unformat_input_t * input, va_list * args)
11214 {
11215   u8 **maskp = va_arg (*args, u8 **);
11216   u32 *skipp = va_arg (*args, u32 *);
11217   u32 *matchp = va_arg (*args, u32 *);
11218   u32 match;
11219   u8 *mask = 0;
11220   u8 *l2 = 0;
11221   u8 *l3 = 0;
11222   u8 *l4 = 0;
11223   int i;
11224
11225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11226     {
11227       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11228         ;
11229       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11230         ;
11231       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11232         ;
11233       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11234         ;
11235       else
11236         break;
11237     }
11238
11239   if (l4 && !l3)
11240     {
11241       vec_free (mask);
11242       vec_free (l2);
11243       vec_free (l4);
11244       return 0;
11245     }
11246
11247   if (mask || l2 || l3 || l4)
11248     {
11249       if (l2 || l3 || l4)
11250         {
11251           /* "With a free Ethernet header in every package" */
11252           if (l2 == 0)
11253             vec_validate (l2, 13);
11254           mask = l2;
11255           if (vec_len (l3))
11256             {
11257               vec_append (mask, l3);
11258               vec_free (l3);
11259             }
11260           if (vec_len (l4))
11261             {
11262               vec_append (mask, l4);
11263               vec_free (l4);
11264             }
11265         }
11266
11267       /* Scan forward looking for the first significant mask octet */
11268       for (i = 0; i < vec_len (mask); i++)
11269         if (mask[i])
11270           break;
11271
11272       /* compute (skip, match) params */
11273       *skipp = i / sizeof (u32x4);
11274       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11275
11276       /* Pad mask to an even multiple of the vector size */
11277       while (vec_len (mask) % sizeof (u32x4))
11278         vec_add1 (mask, 0);
11279
11280       match = vec_len (mask) / sizeof (u32x4);
11281
11282       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11283         {
11284           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11285           if (*tmp || *(tmp + 1))
11286             break;
11287           match--;
11288         }
11289       if (match == 0)
11290         clib_warning ("BUG: match 0");
11291
11292       _vec_len (mask) = match * sizeof (u32x4);
11293
11294       *matchp = match;
11295       *maskp = mask;
11296
11297       return 1;
11298     }
11299
11300   return 0;
11301 }
11302 #endif /* VPP_API_TEST_BUILTIN */
11303
11304 #define foreach_l2_next                         \
11305 _(drop, DROP)                                   \
11306 _(ethernet, ETHERNET_INPUT)                     \
11307 _(ip4, IP4_INPUT)                               \
11308 _(ip6, IP6_INPUT)
11309
11310 uword
11311 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11312 {
11313   u32 *miss_next_indexp = va_arg (*args, u32 *);
11314   u32 next_index = 0;
11315   u32 tmp;
11316
11317 #define _(n,N) \
11318   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11319   foreach_l2_next;
11320 #undef _
11321
11322   if (unformat (input, "%d", &tmp))
11323     {
11324       next_index = tmp;
11325       goto out;
11326     }
11327
11328   return 0;
11329
11330 out:
11331   *miss_next_indexp = next_index;
11332   return 1;
11333 }
11334
11335 #define foreach_ip_next                         \
11336 _(drop, DROP)                                   \
11337 _(local, LOCAL)                                 \
11338 _(rewrite, REWRITE)
11339
11340 uword
11341 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11342 {
11343   u32 *miss_next_indexp = va_arg (*args, u32 *);
11344   u32 next_index = 0;
11345   u32 tmp;
11346
11347 #define _(n,N) \
11348   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11349   foreach_ip_next;
11350 #undef _
11351
11352   if (unformat (input, "%d", &tmp))
11353     {
11354       next_index = tmp;
11355       goto out;
11356     }
11357
11358   return 0;
11359
11360 out:
11361   *miss_next_indexp = next_index;
11362   return 1;
11363 }
11364
11365 #define foreach_acl_next                        \
11366 _(deny, DENY)
11367
11368 uword
11369 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11370 {
11371   u32 *miss_next_indexp = va_arg (*args, u32 *);
11372   u32 next_index = 0;
11373   u32 tmp;
11374
11375 #define _(n,N) \
11376   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11377   foreach_acl_next;
11378 #undef _
11379
11380   if (unformat (input, "permit"))
11381     {
11382       next_index = ~0;
11383       goto out;
11384     }
11385   else if (unformat (input, "%d", &tmp))
11386     {
11387       next_index = tmp;
11388       goto out;
11389     }
11390
11391   return 0;
11392
11393 out:
11394   *miss_next_indexp = next_index;
11395   return 1;
11396 }
11397
11398 uword
11399 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11400 {
11401   u32 *r = va_arg (*args, u32 *);
11402
11403   if (unformat (input, "conform-color"))
11404     *r = POLICE_CONFORM;
11405   else if (unformat (input, "exceed-color"))
11406     *r = POLICE_EXCEED;
11407   else
11408     return 0;
11409
11410   return 1;
11411 }
11412
11413 static int
11414 api_classify_add_del_table (vat_main_t * vam)
11415 {
11416   unformat_input_t *i = vam->input;
11417   vl_api_classify_add_del_table_t *mp;
11418
11419   u32 nbuckets = 2;
11420   u32 skip = ~0;
11421   u32 match = ~0;
11422   int is_add = 1;
11423   int del_chain = 0;
11424   u32 table_index = ~0;
11425   u32 next_table_index = ~0;
11426   u32 miss_next_index = ~0;
11427   u32 memory_size = 32 << 20;
11428   u8 *mask = 0;
11429   u32 current_data_flag = 0;
11430   int current_data_offset = 0;
11431   int ret;
11432
11433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11434     {
11435       if (unformat (i, "del"))
11436         is_add = 0;
11437       else if (unformat (i, "del-chain"))
11438         {
11439           is_add = 0;
11440           del_chain = 1;
11441         }
11442       else if (unformat (i, "buckets %d", &nbuckets))
11443         ;
11444       else if (unformat (i, "memory_size %d", &memory_size))
11445         ;
11446       else if (unformat (i, "skip %d", &skip))
11447         ;
11448       else if (unformat (i, "match %d", &match))
11449         ;
11450       else if (unformat (i, "table %d", &table_index))
11451         ;
11452       else if (unformat (i, "mask %U", unformat_classify_mask,
11453                          &mask, &skip, &match))
11454         ;
11455       else if (unformat (i, "next-table %d", &next_table_index))
11456         ;
11457       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11458                          &miss_next_index))
11459         ;
11460       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11461                          &miss_next_index))
11462         ;
11463       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11464                          &miss_next_index))
11465         ;
11466       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11467         ;
11468       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11469         ;
11470       else
11471         break;
11472     }
11473
11474   if (is_add && mask == 0)
11475     {
11476       errmsg ("Mask required");
11477       return -99;
11478     }
11479
11480   if (is_add && skip == ~0)
11481     {
11482       errmsg ("skip count required");
11483       return -99;
11484     }
11485
11486   if (is_add && match == ~0)
11487     {
11488       errmsg ("match count required");
11489       return -99;
11490     }
11491
11492   if (!is_add && table_index == ~0)
11493     {
11494       errmsg ("table index required for delete");
11495       return -99;
11496     }
11497
11498   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11499
11500   mp->is_add = is_add;
11501   mp->del_chain = del_chain;
11502   mp->table_index = ntohl (table_index);
11503   mp->nbuckets = ntohl (nbuckets);
11504   mp->memory_size = ntohl (memory_size);
11505   mp->skip_n_vectors = ntohl (skip);
11506   mp->match_n_vectors = ntohl (match);
11507   mp->next_table_index = ntohl (next_table_index);
11508   mp->miss_next_index = ntohl (miss_next_index);
11509   mp->current_data_flag = ntohl (current_data_flag);
11510   mp->current_data_offset = ntohl (current_data_offset);
11511   clib_memcpy (mp->mask, mask, vec_len (mask));
11512
11513   vec_free (mask);
11514
11515   S (mp);
11516   W (ret);
11517   return ret;
11518 }
11519
11520 #if VPP_API_TEST_BUILTIN == 0
11521 uword
11522 unformat_l4_match (unformat_input_t * input, va_list * args)
11523 {
11524   u8 **matchp = va_arg (*args, u8 **);
11525
11526   u8 *proto_header = 0;
11527   int src_port = 0;
11528   int dst_port = 0;
11529
11530   tcpudp_header_t h;
11531
11532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11533     {
11534       if (unformat (input, "src_port %d", &src_port))
11535         ;
11536       else if (unformat (input, "dst_port %d", &dst_port))
11537         ;
11538       else
11539         return 0;
11540     }
11541
11542   h.src_port = clib_host_to_net_u16 (src_port);
11543   h.dst_port = clib_host_to_net_u16 (dst_port);
11544   vec_validate (proto_header, sizeof (h) - 1);
11545   memcpy (proto_header, &h, sizeof (h));
11546
11547   *matchp = proto_header;
11548
11549   return 1;
11550 }
11551
11552 uword
11553 unformat_ip4_match (unformat_input_t * input, va_list * args)
11554 {
11555   u8 **matchp = va_arg (*args, u8 **);
11556   u8 *match = 0;
11557   ip4_header_t *ip;
11558   int version = 0;
11559   u32 version_val;
11560   int hdr_length = 0;
11561   u32 hdr_length_val;
11562   int src = 0, dst = 0;
11563   ip4_address_t src_val, dst_val;
11564   int proto = 0;
11565   u32 proto_val;
11566   int tos = 0;
11567   u32 tos_val;
11568   int length = 0;
11569   u32 length_val;
11570   int fragment_id = 0;
11571   u32 fragment_id_val;
11572   int ttl = 0;
11573   int ttl_val;
11574   int checksum = 0;
11575   u32 checksum_val;
11576
11577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11578     {
11579       if (unformat (input, "version %d", &version_val))
11580         version = 1;
11581       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11582         hdr_length = 1;
11583       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11584         src = 1;
11585       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11586         dst = 1;
11587       else if (unformat (input, "proto %d", &proto_val))
11588         proto = 1;
11589       else if (unformat (input, "tos %d", &tos_val))
11590         tos = 1;
11591       else if (unformat (input, "length %d", &length_val))
11592         length = 1;
11593       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11594         fragment_id = 1;
11595       else if (unformat (input, "ttl %d", &ttl_val))
11596         ttl = 1;
11597       else if (unformat (input, "checksum %d", &checksum_val))
11598         checksum = 1;
11599       else
11600         break;
11601     }
11602
11603   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11604       + ttl + checksum == 0)
11605     return 0;
11606
11607   /*
11608    * Aligned because we use the real comparison functions
11609    */
11610   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11611
11612   ip = (ip4_header_t *) match;
11613
11614   /* These are realistically matched in practice */
11615   if (src)
11616     ip->src_address.as_u32 = src_val.as_u32;
11617
11618   if (dst)
11619     ip->dst_address.as_u32 = dst_val.as_u32;
11620
11621   if (proto)
11622     ip->protocol = proto_val;
11623
11624
11625   /* These are not, but they're included for completeness */
11626   if (version)
11627     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11628
11629   if (hdr_length)
11630     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11631
11632   if (tos)
11633     ip->tos = tos_val;
11634
11635   if (length)
11636     ip->length = clib_host_to_net_u16 (length_val);
11637
11638   if (ttl)
11639     ip->ttl = ttl_val;
11640
11641   if (checksum)
11642     ip->checksum = clib_host_to_net_u16 (checksum_val);
11643
11644   *matchp = match;
11645   return 1;
11646 }
11647
11648 uword
11649 unformat_ip6_match (unformat_input_t * input, va_list * args)
11650 {
11651   u8 **matchp = va_arg (*args, u8 **);
11652   u8 *match = 0;
11653   ip6_header_t *ip;
11654   int version = 0;
11655   u32 version_val;
11656   u8 traffic_class = 0;
11657   u32 traffic_class_val = 0;
11658   u8 flow_label = 0;
11659   u8 flow_label_val;
11660   int src = 0, dst = 0;
11661   ip6_address_t src_val, dst_val;
11662   int proto = 0;
11663   u32 proto_val;
11664   int payload_length = 0;
11665   u32 payload_length_val;
11666   int hop_limit = 0;
11667   int hop_limit_val;
11668   u32 ip_version_traffic_class_and_flow_label;
11669
11670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11671     {
11672       if (unformat (input, "version %d", &version_val))
11673         version = 1;
11674       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11675         traffic_class = 1;
11676       else if (unformat (input, "flow_label %d", &flow_label_val))
11677         flow_label = 1;
11678       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11679         src = 1;
11680       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11681         dst = 1;
11682       else if (unformat (input, "proto %d", &proto_val))
11683         proto = 1;
11684       else if (unformat (input, "payload_length %d", &payload_length_val))
11685         payload_length = 1;
11686       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11687         hop_limit = 1;
11688       else
11689         break;
11690     }
11691
11692   if (version + traffic_class + flow_label + src + dst + proto +
11693       payload_length + hop_limit == 0)
11694     return 0;
11695
11696   /*
11697    * Aligned because we use the real comparison functions
11698    */
11699   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11700
11701   ip = (ip6_header_t *) match;
11702
11703   if (src)
11704     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11705
11706   if (dst)
11707     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11708
11709   if (proto)
11710     ip->protocol = proto_val;
11711
11712   ip_version_traffic_class_and_flow_label = 0;
11713
11714   if (version)
11715     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11716
11717   if (traffic_class)
11718     ip_version_traffic_class_and_flow_label |=
11719       (traffic_class_val & 0xFF) << 20;
11720
11721   if (flow_label)
11722     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11723
11724   ip->ip_version_traffic_class_and_flow_label =
11725     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11726
11727   if (payload_length)
11728     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11729
11730   if (hop_limit)
11731     ip->hop_limit = hop_limit_val;
11732
11733   *matchp = match;
11734   return 1;
11735 }
11736
11737 uword
11738 unformat_l3_match (unformat_input_t * input, va_list * args)
11739 {
11740   u8 **matchp = va_arg (*args, u8 **);
11741
11742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11743     {
11744       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11745         return 1;
11746       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11747         return 1;
11748       else
11749         break;
11750     }
11751   return 0;
11752 }
11753
11754 uword
11755 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11756 {
11757   u8 *tagp = va_arg (*args, u8 *);
11758   u32 tag;
11759
11760   if (unformat (input, "%d", &tag))
11761     {
11762       tagp[0] = (tag >> 8) & 0x0F;
11763       tagp[1] = tag & 0xFF;
11764       return 1;
11765     }
11766
11767   return 0;
11768 }
11769
11770 uword
11771 unformat_l2_match (unformat_input_t * input, va_list * args)
11772 {
11773   u8 **matchp = va_arg (*args, u8 **);
11774   u8 *match = 0;
11775   u8 src = 0;
11776   u8 src_val[6];
11777   u8 dst = 0;
11778   u8 dst_val[6];
11779   u8 proto = 0;
11780   u16 proto_val;
11781   u8 tag1 = 0;
11782   u8 tag1_val[2];
11783   u8 tag2 = 0;
11784   u8 tag2_val[2];
11785   int len = 14;
11786   u8 ignore_tag1 = 0;
11787   u8 ignore_tag2 = 0;
11788   u8 cos1 = 0;
11789   u8 cos2 = 0;
11790   u32 cos1_val = 0;
11791   u32 cos2_val = 0;
11792
11793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11794     {
11795       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11796         src = 1;
11797       else
11798         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11799         dst = 1;
11800       else if (unformat (input, "proto %U",
11801                          unformat_ethernet_type_host_byte_order, &proto_val))
11802         proto = 1;
11803       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11804         tag1 = 1;
11805       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11806         tag2 = 1;
11807       else if (unformat (input, "ignore-tag1"))
11808         ignore_tag1 = 1;
11809       else if (unformat (input, "ignore-tag2"))
11810         ignore_tag2 = 1;
11811       else if (unformat (input, "cos1 %d", &cos1_val))
11812         cos1 = 1;
11813       else if (unformat (input, "cos2 %d", &cos2_val))
11814         cos2 = 1;
11815       else
11816         break;
11817     }
11818   if ((src + dst + proto + tag1 + tag2 +
11819        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11820     return 0;
11821
11822   if (tag1 || ignore_tag1 || cos1)
11823     len = 18;
11824   if (tag2 || ignore_tag2 || cos2)
11825     len = 22;
11826
11827   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11828
11829   if (dst)
11830     clib_memcpy (match, dst_val, 6);
11831
11832   if (src)
11833     clib_memcpy (match + 6, src_val, 6);
11834
11835   if (tag2)
11836     {
11837       /* inner vlan tag */
11838       match[19] = tag2_val[1];
11839       match[18] = tag2_val[0];
11840       if (cos2)
11841         match[18] |= (cos2_val & 0x7) << 5;
11842       if (proto)
11843         {
11844           match[21] = proto_val & 0xff;
11845           match[20] = proto_val >> 8;
11846         }
11847       if (tag1)
11848         {
11849           match[15] = tag1_val[1];
11850           match[14] = tag1_val[0];
11851         }
11852       if (cos1)
11853         match[14] |= (cos1_val & 0x7) << 5;
11854       *matchp = match;
11855       return 1;
11856     }
11857   if (tag1)
11858     {
11859       match[15] = tag1_val[1];
11860       match[14] = tag1_val[0];
11861       if (proto)
11862         {
11863           match[17] = proto_val & 0xff;
11864           match[16] = proto_val >> 8;
11865         }
11866       if (cos1)
11867         match[14] |= (cos1_val & 0x7) << 5;
11868
11869       *matchp = match;
11870       return 1;
11871     }
11872   if (cos2)
11873     match[18] |= (cos2_val & 0x7) << 5;
11874   if (cos1)
11875     match[14] |= (cos1_val & 0x7) << 5;
11876   if (proto)
11877     {
11878       match[13] = proto_val & 0xff;
11879       match[12] = proto_val >> 8;
11880     }
11881
11882   *matchp = match;
11883   return 1;
11884 }
11885
11886 uword
11887 unformat_qos_source (unformat_input_t * input, va_list * args)
11888 {
11889   int *qs = va_arg (*args, int *);
11890
11891   if (unformat (input, "ip"))
11892     *qs = QOS_SOURCE_IP;
11893   else if (unformat (input, "mpls"))
11894     *qs = QOS_SOURCE_MPLS;
11895   else if (unformat (input, "ext"))
11896     *qs = QOS_SOURCE_EXT;
11897   else if (unformat (input, "vlan"))
11898     *qs = QOS_SOURCE_VLAN;
11899   else
11900     return 0;
11901
11902   return 1;
11903 }
11904 #endif
11905
11906 uword
11907 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11908 {
11909   u8 **matchp = va_arg (*args, u8 **);
11910   u32 skip_n_vectors = va_arg (*args, u32);
11911   u32 match_n_vectors = va_arg (*args, u32);
11912
11913   u8 *match = 0;
11914   u8 *l2 = 0;
11915   u8 *l3 = 0;
11916   u8 *l4 = 0;
11917
11918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11919     {
11920       if (unformat (input, "hex %U", unformat_hex_string, &match))
11921         ;
11922       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11923         ;
11924       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11925         ;
11926       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11927         ;
11928       else
11929         break;
11930     }
11931
11932   if (l4 && !l3)
11933     {
11934       vec_free (match);
11935       vec_free (l2);
11936       vec_free (l4);
11937       return 0;
11938     }
11939
11940   if (match || l2 || l3 || l4)
11941     {
11942       if (l2 || l3 || l4)
11943         {
11944           /* "Win a free Ethernet header in every packet" */
11945           if (l2 == 0)
11946             vec_validate_aligned (l2, 13, sizeof (u32x4));
11947           match = l2;
11948           if (vec_len (l3))
11949             {
11950               vec_append_aligned (match, l3, sizeof (u32x4));
11951               vec_free (l3);
11952             }
11953           if (vec_len (l4))
11954             {
11955               vec_append_aligned (match, l4, sizeof (u32x4));
11956               vec_free (l4);
11957             }
11958         }
11959
11960       /* Make sure the vector is big enough even if key is all 0's */
11961       vec_validate_aligned
11962         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11963          sizeof (u32x4));
11964
11965       /* Set size, include skipped vectors */
11966       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11967
11968       *matchp = match;
11969
11970       return 1;
11971     }
11972
11973   return 0;
11974 }
11975
11976 static int
11977 api_classify_add_del_session (vat_main_t * vam)
11978 {
11979   unformat_input_t *i = vam->input;
11980   vl_api_classify_add_del_session_t *mp;
11981   int is_add = 1;
11982   u32 table_index = ~0;
11983   u32 hit_next_index = ~0;
11984   u32 opaque_index = ~0;
11985   u8 *match = 0;
11986   i32 advance = 0;
11987   u32 skip_n_vectors = 0;
11988   u32 match_n_vectors = 0;
11989   u32 action = 0;
11990   u32 metadata = 0;
11991   int ret;
11992
11993   /*
11994    * Warning: you have to supply skip_n and match_n
11995    * because the API client cant simply look at the classify
11996    * table object.
11997    */
11998
11999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12000     {
12001       if (unformat (i, "del"))
12002         is_add = 0;
12003       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12004                          &hit_next_index))
12005         ;
12006       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12007                          &hit_next_index))
12008         ;
12009       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12010                          &hit_next_index))
12011         ;
12012       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12013         ;
12014       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12015         ;
12016       else if (unformat (i, "opaque-index %d", &opaque_index))
12017         ;
12018       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12019         ;
12020       else if (unformat (i, "match_n %d", &match_n_vectors))
12021         ;
12022       else if (unformat (i, "match %U", api_unformat_classify_match,
12023                          &match, skip_n_vectors, match_n_vectors))
12024         ;
12025       else if (unformat (i, "advance %d", &advance))
12026         ;
12027       else if (unformat (i, "table-index %d", &table_index))
12028         ;
12029       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12030         action = 1;
12031       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12032         action = 2;
12033       else if (unformat (i, "action %d", &action))
12034         ;
12035       else if (unformat (i, "metadata %d", &metadata))
12036         ;
12037       else
12038         break;
12039     }
12040
12041   if (table_index == ~0)
12042     {
12043       errmsg ("Table index required");
12044       return -99;
12045     }
12046
12047   if (is_add && match == 0)
12048     {
12049       errmsg ("Match value required");
12050       return -99;
12051     }
12052
12053   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12054
12055   mp->is_add = is_add;
12056   mp->table_index = ntohl (table_index);
12057   mp->hit_next_index = ntohl (hit_next_index);
12058   mp->opaque_index = ntohl (opaque_index);
12059   mp->advance = ntohl (advance);
12060   mp->action = action;
12061   mp->metadata = ntohl (metadata);
12062   clib_memcpy (mp->match, match, vec_len (match));
12063   vec_free (match);
12064
12065   S (mp);
12066   W (ret);
12067   return ret;
12068 }
12069
12070 static int
12071 api_classify_set_interface_ip_table (vat_main_t * vam)
12072 {
12073   unformat_input_t *i = vam->input;
12074   vl_api_classify_set_interface_ip_table_t *mp;
12075   u32 sw_if_index;
12076   int sw_if_index_set;
12077   u32 table_index = ~0;
12078   u8 is_ipv6 = 0;
12079   int ret;
12080
12081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12082     {
12083       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12084         sw_if_index_set = 1;
12085       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12086         sw_if_index_set = 1;
12087       else if (unformat (i, "table %d", &table_index))
12088         ;
12089       else
12090         {
12091           clib_warning ("parse error '%U'", format_unformat_error, i);
12092           return -99;
12093         }
12094     }
12095
12096   if (sw_if_index_set == 0)
12097     {
12098       errmsg ("missing interface name or sw_if_index");
12099       return -99;
12100     }
12101
12102
12103   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12104
12105   mp->sw_if_index = ntohl (sw_if_index);
12106   mp->table_index = ntohl (table_index);
12107   mp->is_ipv6 = is_ipv6;
12108
12109   S (mp);
12110   W (ret);
12111   return ret;
12112 }
12113
12114 static int
12115 api_classify_set_interface_l2_tables (vat_main_t * vam)
12116 {
12117   unformat_input_t *i = vam->input;
12118   vl_api_classify_set_interface_l2_tables_t *mp;
12119   u32 sw_if_index;
12120   int sw_if_index_set;
12121   u32 ip4_table_index = ~0;
12122   u32 ip6_table_index = ~0;
12123   u32 other_table_index = ~0;
12124   u32 is_input = 1;
12125   int ret;
12126
12127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12128     {
12129       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12130         sw_if_index_set = 1;
12131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12132         sw_if_index_set = 1;
12133       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12134         ;
12135       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12136         ;
12137       else if (unformat (i, "other-table %d", &other_table_index))
12138         ;
12139       else if (unformat (i, "is-input %d", &is_input))
12140         ;
12141       else
12142         {
12143           clib_warning ("parse error '%U'", format_unformat_error, i);
12144           return -99;
12145         }
12146     }
12147
12148   if (sw_if_index_set == 0)
12149     {
12150       errmsg ("missing interface name or sw_if_index");
12151       return -99;
12152     }
12153
12154
12155   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12156
12157   mp->sw_if_index = ntohl (sw_if_index);
12158   mp->ip4_table_index = ntohl (ip4_table_index);
12159   mp->ip6_table_index = ntohl (ip6_table_index);
12160   mp->other_table_index = ntohl (other_table_index);
12161   mp->is_input = (u8) is_input;
12162
12163   S (mp);
12164   W (ret);
12165   return ret;
12166 }
12167
12168 static int
12169 api_set_ipfix_exporter (vat_main_t * vam)
12170 {
12171   unformat_input_t *i = vam->input;
12172   vl_api_set_ipfix_exporter_t *mp;
12173   ip4_address_t collector_address;
12174   u8 collector_address_set = 0;
12175   u32 collector_port = ~0;
12176   ip4_address_t src_address;
12177   u8 src_address_set = 0;
12178   u32 vrf_id = ~0;
12179   u32 path_mtu = ~0;
12180   u32 template_interval = ~0;
12181   u8 udp_checksum = 0;
12182   int ret;
12183
12184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12185     {
12186       if (unformat (i, "collector_address %U", unformat_ip4_address,
12187                     &collector_address))
12188         collector_address_set = 1;
12189       else if (unformat (i, "collector_port %d", &collector_port))
12190         ;
12191       else if (unformat (i, "src_address %U", unformat_ip4_address,
12192                          &src_address))
12193         src_address_set = 1;
12194       else if (unformat (i, "vrf_id %d", &vrf_id))
12195         ;
12196       else if (unformat (i, "path_mtu %d", &path_mtu))
12197         ;
12198       else if (unformat (i, "template_interval %d", &template_interval))
12199         ;
12200       else if (unformat (i, "udp_checksum"))
12201         udp_checksum = 1;
12202       else
12203         break;
12204     }
12205
12206   if (collector_address_set == 0)
12207     {
12208       errmsg ("collector_address required");
12209       return -99;
12210     }
12211
12212   if (src_address_set == 0)
12213     {
12214       errmsg ("src_address required");
12215       return -99;
12216     }
12217
12218   M (SET_IPFIX_EXPORTER, mp);
12219
12220   memcpy (mp->collector_address, collector_address.data,
12221           sizeof (collector_address.data));
12222   mp->collector_port = htons ((u16) collector_port);
12223   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12224   mp->vrf_id = htonl (vrf_id);
12225   mp->path_mtu = htonl (path_mtu);
12226   mp->template_interval = htonl (template_interval);
12227   mp->udp_checksum = udp_checksum;
12228
12229   S (mp);
12230   W (ret);
12231   return ret;
12232 }
12233
12234 static int
12235 api_set_ipfix_classify_stream (vat_main_t * vam)
12236 {
12237   unformat_input_t *i = vam->input;
12238   vl_api_set_ipfix_classify_stream_t *mp;
12239   u32 domain_id = 0;
12240   u32 src_port = UDP_DST_PORT_ipfix;
12241   int ret;
12242
12243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12244     {
12245       if (unformat (i, "domain %d", &domain_id))
12246         ;
12247       else if (unformat (i, "src_port %d", &src_port))
12248         ;
12249       else
12250         {
12251           errmsg ("unknown input `%U'", format_unformat_error, i);
12252           return -99;
12253         }
12254     }
12255
12256   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12257
12258   mp->domain_id = htonl (domain_id);
12259   mp->src_port = htons ((u16) src_port);
12260
12261   S (mp);
12262   W (ret);
12263   return ret;
12264 }
12265
12266 static int
12267 api_ipfix_classify_table_add_del (vat_main_t * vam)
12268 {
12269   unformat_input_t *i = vam->input;
12270   vl_api_ipfix_classify_table_add_del_t *mp;
12271   int is_add = -1;
12272   u32 classify_table_index = ~0;
12273   u8 ip_version = 0;
12274   u8 transport_protocol = 255;
12275   int ret;
12276
12277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12278     {
12279       if (unformat (i, "add"))
12280         is_add = 1;
12281       else if (unformat (i, "del"))
12282         is_add = 0;
12283       else if (unformat (i, "table %d", &classify_table_index))
12284         ;
12285       else if (unformat (i, "ip4"))
12286         ip_version = 4;
12287       else if (unformat (i, "ip6"))
12288         ip_version = 6;
12289       else if (unformat (i, "tcp"))
12290         transport_protocol = 6;
12291       else if (unformat (i, "udp"))
12292         transport_protocol = 17;
12293       else
12294         {
12295           errmsg ("unknown input `%U'", format_unformat_error, i);
12296           return -99;
12297         }
12298     }
12299
12300   if (is_add == -1)
12301     {
12302       errmsg ("expecting: add|del");
12303       return -99;
12304     }
12305   if (classify_table_index == ~0)
12306     {
12307       errmsg ("classifier table not specified");
12308       return -99;
12309     }
12310   if (ip_version == 0)
12311     {
12312       errmsg ("IP version not specified");
12313       return -99;
12314     }
12315
12316   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12317
12318   mp->is_add = is_add;
12319   mp->table_id = htonl (classify_table_index);
12320   mp->ip_version = ip_version;
12321   mp->transport_protocol = transport_protocol;
12322
12323   S (mp);
12324   W (ret);
12325   return ret;
12326 }
12327
12328 static int
12329 api_get_node_index (vat_main_t * vam)
12330 {
12331   unformat_input_t *i = vam->input;
12332   vl_api_get_node_index_t *mp;
12333   u8 *name = 0;
12334   int ret;
12335
12336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12337     {
12338       if (unformat (i, "node %s", &name))
12339         ;
12340       else
12341         break;
12342     }
12343   if (name == 0)
12344     {
12345       errmsg ("node name required");
12346       return -99;
12347     }
12348   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12349     {
12350       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12351       return -99;
12352     }
12353
12354   M (GET_NODE_INDEX, mp);
12355   clib_memcpy (mp->node_name, name, vec_len (name));
12356   vec_free (name);
12357
12358   S (mp);
12359   W (ret);
12360   return ret;
12361 }
12362
12363 static int
12364 api_get_next_index (vat_main_t * vam)
12365 {
12366   unformat_input_t *i = vam->input;
12367   vl_api_get_next_index_t *mp;
12368   u8 *node_name = 0, *next_node_name = 0;
12369   int ret;
12370
12371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12372     {
12373       if (unformat (i, "node-name %s", &node_name))
12374         ;
12375       else if (unformat (i, "next-node-name %s", &next_node_name))
12376         break;
12377     }
12378
12379   if (node_name == 0)
12380     {
12381       errmsg ("node name required");
12382       return -99;
12383     }
12384   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12385     {
12386       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12387       return -99;
12388     }
12389
12390   if (next_node_name == 0)
12391     {
12392       errmsg ("next node name required");
12393       return -99;
12394     }
12395   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12396     {
12397       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12398       return -99;
12399     }
12400
12401   M (GET_NEXT_INDEX, mp);
12402   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12403   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12404   vec_free (node_name);
12405   vec_free (next_node_name);
12406
12407   S (mp);
12408   W (ret);
12409   return ret;
12410 }
12411
12412 static int
12413 api_add_node_next (vat_main_t * vam)
12414 {
12415   unformat_input_t *i = vam->input;
12416   vl_api_add_node_next_t *mp;
12417   u8 *name = 0;
12418   u8 *next = 0;
12419   int ret;
12420
12421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12422     {
12423       if (unformat (i, "node %s", &name))
12424         ;
12425       else if (unformat (i, "next %s", &next))
12426         ;
12427       else
12428         break;
12429     }
12430   if (name == 0)
12431     {
12432       errmsg ("node name required");
12433       return -99;
12434     }
12435   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12436     {
12437       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12438       return -99;
12439     }
12440   if (next == 0)
12441     {
12442       errmsg ("next node required");
12443       return -99;
12444     }
12445   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12446     {
12447       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12448       return -99;
12449     }
12450
12451   M (ADD_NODE_NEXT, mp);
12452   clib_memcpy (mp->node_name, name, vec_len (name));
12453   clib_memcpy (mp->next_name, next, vec_len (next));
12454   vec_free (name);
12455   vec_free (next);
12456
12457   S (mp);
12458   W (ret);
12459   return ret;
12460 }
12461
12462 static int
12463 api_l2tpv3_create_tunnel (vat_main_t * vam)
12464 {
12465   unformat_input_t *i = vam->input;
12466   ip6_address_t client_address, our_address;
12467   int client_address_set = 0;
12468   int our_address_set = 0;
12469   u32 local_session_id = 0;
12470   u32 remote_session_id = 0;
12471   u64 local_cookie = 0;
12472   u64 remote_cookie = 0;
12473   u8 l2_sublayer_present = 0;
12474   vl_api_l2tpv3_create_tunnel_t *mp;
12475   int ret;
12476
12477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12478     {
12479       if (unformat (i, "client_address %U", unformat_ip6_address,
12480                     &client_address))
12481         client_address_set = 1;
12482       else if (unformat (i, "our_address %U", unformat_ip6_address,
12483                          &our_address))
12484         our_address_set = 1;
12485       else if (unformat (i, "local_session_id %d", &local_session_id))
12486         ;
12487       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12488         ;
12489       else if (unformat (i, "local_cookie %lld", &local_cookie))
12490         ;
12491       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12492         ;
12493       else if (unformat (i, "l2-sublayer-present"))
12494         l2_sublayer_present = 1;
12495       else
12496         break;
12497     }
12498
12499   if (client_address_set == 0)
12500     {
12501       errmsg ("client_address required");
12502       return -99;
12503     }
12504
12505   if (our_address_set == 0)
12506     {
12507       errmsg ("our_address required");
12508       return -99;
12509     }
12510
12511   M (L2TPV3_CREATE_TUNNEL, mp);
12512
12513   clib_memcpy (mp->client_address, client_address.as_u8,
12514                sizeof (mp->client_address));
12515
12516   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12517
12518   mp->local_session_id = ntohl (local_session_id);
12519   mp->remote_session_id = ntohl (remote_session_id);
12520   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12521   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12522   mp->l2_sublayer_present = l2_sublayer_present;
12523   mp->is_ipv6 = 1;
12524
12525   S (mp);
12526   W (ret);
12527   return ret;
12528 }
12529
12530 static int
12531 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12532 {
12533   unformat_input_t *i = vam->input;
12534   u32 sw_if_index;
12535   u8 sw_if_index_set = 0;
12536   u64 new_local_cookie = 0;
12537   u64 new_remote_cookie = 0;
12538   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12539   int ret;
12540
12541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12542     {
12543       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12544         sw_if_index_set = 1;
12545       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12546         sw_if_index_set = 1;
12547       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12548         ;
12549       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12550         ;
12551       else
12552         break;
12553     }
12554
12555   if (sw_if_index_set == 0)
12556     {
12557       errmsg ("missing interface name or sw_if_index");
12558       return -99;
12559     }
12560
12561   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12562
12563   mp->sw_if_index = ntohl (sw_if_index);
12564   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12565   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12566
12567   S (mp);
12568   W (ret);
12569   return ret;
12570 }
12571
12572 static int
12573 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12574 {
12575   unformat_input_t *i = vam->input;
12576   vl_api_l2tpv3_interface_enable_disable_t *mp;
12577   u32 sw_if_index;
12578   u8 sw_if_index_set = 0;
12579   u8 enable_disable = 1;
12580   int ret;
12581
12582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12583     {
12584       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12585         sw_if_index_set = 1;
12586       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12587         sw_if_index_set = 1;
12588       else if (unformat (i, "enable"))
12589         enable_disable = 1;
12590       else if (unformat (i, "disable"))
12591         enable_disable = 0;
12592       else
12593         break;
12594     }
12595
12596   if (sw_if_index_set == 0)
12597     {
12598       errmsg ("missing interface name or sw_if_index");
12599       return -99;
12600     }
12601
12602   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12603
12604   mp->sw_if_index = ntohl (sw_if_index);
12605   mp->enable_disable = enable_disable;
12606
12607   S (mp);
12608   W (ret);
12609   return ret;
12610 }
12611
12612 static int
12613 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12614 {
12615   unformat_input_t *i = vam->input;
12616   vl_api_l2tpv3_set_lookup_key_t *mp;
12617   u8 key = ~0;
12618   int ret;
12619
12620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12621     {
12622       if (unformat (i, "lookup_v6_src"))
12623         key = L2T_LOOKUP_SRC_ADDRESS;
12624       else if (unformat (i, "lookup_v6_dst"))
12625         key = L2T_LOOKUP_DST_ADDRESS;
12626       else if (unformat (i, "lookup_session_id"))
12627         key = L2T_LOOKUP_SESSION_ID;
12628       else
12629         break;
12630     }
12631
12632   if (key == (u8) ~ 0)
12633     {
12634       errmsg ("l2tp session lookup key unset");
12635       return -99;
12636     }
12637
12638   M (L2TPV3_SET_LOOKUP_KEY, mp);
12639
12640   mp->key = key;
12641
12642   S (mp);
12643   W (ret);
12644   return ret;
12645 }
12646
12647 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12648   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12649 {
12650   vat_main_t *vam = &vat_main;
12651
12652   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12653          format_ip6_address, mp->our_address,
12654          format_ip6_address, mp->client_address,
12655          clib_net_to_host_u32 (mp->sw_if_index));
12656
12657   print (vam->ofp,
12658          "   local cookies %016llx %016llx remote cookie %016llx",
12659          clib_net_to_host_u64 (mp->local_cookie[0]),
12660          clib_net_to_host_u64 (mp->local_cookie[1]),
12661          clib_net_to_host_u64 (mp->remote_cookie));
12662
12663   print (vam->ofp, "   local session-id %d remote session-id %d",
12664          clib_net_to_host_u32 (mp->local_session_id),
12665          clib_net_to_host_u32 (mp->remote_session_id));
12666
12667   print (vam->ofp, "   l2 specific sublayer %s\n",
12668          mp->l2_sublayer_present ? "preset" : "absent");
12669
12670 }
12671
12672 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12673   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12674 {
12675   vat_main_t *vam = &vat_main;
12676   vat_json_node_t *node = NULL;
12677   struct in6_addr addr;
12678
12679   if (VAT_JSON_ARRAY != vam->json_tree.type)
12680     {
12681       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12682       vat_json_init_array (&vam->json_tree);
12683     }
12684   node = vat_json_array_add (&vam->json_tree);
12685
12686   vat_json_init_object (node);
12687
12688   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12689   vat_json_object_add_ip6 (node, "our_address", addr);
12690   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12691   vat_json_object_add_ip6 (node, "client_address", addr);
12692
12693   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12694   vat_json_init_array (lc);
12695   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12696   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12697   vat_json_object_add_uint (node, "remote_cookie",
12698                             clib_net_to_host_u64 (mp->remote_cookie));
12699
12700   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12701   vat_json_object_add_uint (node, "local_session_id",
12702                             clib_net_to_host_u32 (mp->local_session_id));
12703   vat_json_object_add_uint (node, "remote_session_id",
12704                             clib_net_to_host_u32 (mp->remote_session_id));
12705   vat_json_object_add_string_copy (node, "l2_sublayer",
12706                                    mp->l2_sublayer_present ? (u8 *) "present"
12707                                    : (u8 *) "absent");
12708 }
12709
12710 static int
12711 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12712 {
12713   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12714   vl_api_control_ping_t *mp_ping;
12715   int ret;
12716
12717   /* Get list of l2tpv3-tunnel interfaces */
12718   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12719   S (mp);
12720
12721   /* Use a control ping for synchronization */
12722   MPING (CONTROL_PING, mp_ping);
12723   S (mp_ping);
12724
12725   W (ret);
12726   return ret;
12727 }
12728
12729
12730 static void vl_api_sw_interface_tap_details_t_handler
12731   (vl_api_sw_interface_tap_details_t * mp)
12732 {
12733   vat_main_t *vam = &vat_main;
12734
12735   print (vam->ofp, "%-16s %d",
12736          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12737 }
12738
12739 static void vl_api_sw_interface_tap_details_t_handler_json
12740   (vl_api_sw_interface_tap_details_t * mp)
12741 {
12742   vat_main_t *vam = &vat_main;
12743   vat_json_node_t *node = NULL;
12744
12745   if (VAT_JSON_ARRAY != vam->json_tree.type)
12746     {
12747       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12748       vat_json_init_array (&vam->json_tree);
12749     }
12750   node = vat_json_array_add (&vam->json_tree);
12751
12752   vat_json_init_object (node);
12753   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12754   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12755 }
12756
12757 static int
12758 api_sw_interface_tap_dump (vat_main_t * vam)
12759 {
12760   vl_api_sw_interface_tap_dump_t *mp;
12761   vl_api_control_ping_t *mp_ping;
12762   int ret;
12763
12764   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12765   /* Get list of tap interfaces */
12766   M (SW_INTERFACE_TAP_DUMP, mp);
12767   S (mp);
12768
12769   /* Use a control ping for synchronization */
12770   MPING (CONTROL_PING, mp_ping);
12771   S (mp_ping);
12772
12773   W (ret);
12774   return ret;
12775 }
12776
12777 static void vl_api_sw_interface_tap_v2_details_t_handler
12778   (vl_api_sw_interface_tap_v2_details_t * mp)
12779 {
12780   vat_main_t *vam = &vat_main;
12781
12782   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12783                     mp->host_ip4_prefix_len);
12784   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12785                     mp->host_ip6_prefix_len);
12786
12787   print (vam->ofp,
12788          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12789          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12790          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12791          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12792          mp->host_bridge, ip4, ip6);
12793
12794   vec_free (ip4);
12795   vec_free (ip6);
12796 }
12797
12798 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12799   (vl_api_sw_interface_tap_v2_details_t * mp)
12800 {
12801   vat_main_t *vam = &vat_main;
12802   vat_json_node_t *node = NULL;
12803
12804   if (VAT_JSON_ARRAY != vam->json_tree.type)
12805     {
12806       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12807       vat_json_init_array (&vam->json_tree);
12808     }
12809   node = vat_json_array_add (&vam->json_tree);
12810
12811   vat_json_init_object (node);
12812   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12813   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12814   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12815   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12816   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12817   vat_json_object_add_string_copy (node, "host_mac_addr",
12818                                    format (0, "%U", format_ethernet_address,
12819                                            &mp->host_mac_addr));
12820   vat_json_object_add_string_copy (node, "host_namespace",
12821                                    mp->host_namespace);
12822   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12823   vat_json_object_add_string_copy (node, "host_ip4_addr",
12824                                    format (0, "%U/%d", format_ip4_address,
12825                                            mp->host_ip4_addr,
12826                                            mp->host_ip4_prefix_len));
12827   vat_json_object_add_string_copy (node, "host_ip6_addr",
12828                                    format (0, "%U/%d", format_ip6_address,
12829                                            mp->host_ip6_addr,
12830                                            mp->host_ip6_prefix_len));
12831
12832 }
12833
12834 static int
12835 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12836 {
12837   vl_api_sw_interface_tap_v2_dump_t *mp;
12838   vl_api_control_ping_t *mp_ping;
12839   int ret;
12840
12841   print (vam->ofp,
12842          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12843          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12844          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12845          "host_ip6_addr");
12846
12847   /* Get list of tap interfaces */
12848   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12849   S (mp);
12850
12851   /* Use a control ping for synchronization */
12852   MPING (CONTROL_PING, mp_ping);
12853   S (mp_ping);
12854
12855   W (ret);
12856   return ret;
12857 }
12858
12859 static uword unformat_vxlan_decap_next
12860   (unformat_input_t * input, va_list * args)
12861 {
12862   u32 *result = va_arg (*args, u32 *);
12863   u32 tmp;
12864
12865   if (unformat (input, "l2"))
12866     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12867   else if (unformat (input, "%d", &tmp))
12868     *result = tmp;
12869   else
12870     return 0;
12871   return 1;
12872 }
12873
12874 static int
12875 api_vxlan_add_del_tunnel (vat_main_t * vam)
12876 {
12877   unformat_input_t *line_input = vam->input;
12878   vl_api_vxlan_add_del_tunnel_t *mp;
12879   ip46_address_t src, dst;
12880   u8 is_add = 1;
12881   u8 ipv4_set = 0, ipv6_set = 0;
12882   u8 src_set = 0;
12883   u8 dst_set = 0;
12884   u8 grp_set = 0;
12885   u32 instance = ~0;
12886   u32 mcast_sw_if_index = ~0;
12887   u32 encap_vrf_id = 0;
12888   u32 decap_next_index = ~0;
12889   u32 vni = 0;
12890   int ret;
12891
12892   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12893   memset (&src, 0, sizeof src);
12894   memset (&dst, 0, sizeof dst);
12895
12896   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12897     {
12898       if (unformat (line_input, "del"))
12899         is_add = 0;
12900       else if (unformat (line_input, "instance %d", &instance))
12901         ;
12902       else
12903         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12904         {
12905           ipv4_set = 1;
12906           src_set = 1;
12907         }
12908       else
12909         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12910         {
12911           ipv4_set = 1;
12912           dst_set = 1;
12913         }
12914       else
12915         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12916         {
12917           ipv6_set = 1;
12918           src_set = 1;
12919         }
12920       else
12921         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12922         {
12923           ipv6_set = 1;
12924           dst_set = 1;
12925         }
12926       else if (unformat (line_input, "group %U %U",
12927                          unformat_ip4_address, &dst.ip4,
12928                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12929         {
12930           grp_set = dst_set = 1;
12931           ipv4_set = 1;
12932         }
12933       else if (unformat (line_input, "group %U",
12934                          unformat_ip4_address, &dst.ip4))
12935         {
12936           grp_set = dst_set = 1;
12937           ipv4_set = 1;
12938         }
12939       else if (unformat (line_input, "group %U %U",
12940                          unformat_ip6_address, &dst.ip6,
12941                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12942         {
12943           grp_set = dst_set = 1;
12944           ipv6_set = 1;
12945         }
12946       else if (unformat (line_input, "group %U",
12947                          unformat_ip6_address, &dst.ip6))
12948         {
12949           grp_set = dst_set = 1;
12950           ipv6_set = 1;
12951         }
12952       else
12953         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12954         ;
12955       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12956         ;
12957       else if (unformat (line_input, "decap-next %U",
12958                          unformat_vxlan_decap_next, &decap_next_index))
12959         ;
12960       else if (unformat (line_input, "vni %d", &vni))
12961         ;
12962       else
12963         {
12964           errmsg ("parse error '%U'", format_unformat_error, line_input);
12965           return -99;
12966         }
12967     }
12968
12969   if (src_set == 0)
12970     {
12971       errmsg ("tunnel src address not specified");
12972       return -99;
12973     }
12974   if (dst_set == 0)
12975     {
12976       errmsg ("tunnel dst address not specified");
12977       return -99;
12978     }
12979
12980   if (grp_set && !ip46_address_is_multicast (&dst))
12981     {
12982       errmsg ("tunnel group address not multicast");
12983       return -99;
12984     }
12985   if (grp_set && mcast_sw_if_index == ~0)
12986     {
12987       errmsg ("tunnel nonexistent multicast device");
12988       return -99;
12989     }
12990   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12991     {
12992       errmsg ("tunnel dst address must be unicast");
12993       return -99;
12994     }
12995
12996
12997   if (ipv4_set && ipv6_set)
12998     {
12999       errmsg ("both IPv4 and IPv6 addresses specified");
13000       return -99;
13001     }
13002
13003   if ((vni == 0) || (vni >> 24))
13004     {
13005       errmsg ("vni not specified or out of range");
13006       return -99;
13007     }
13008
13009   M (VXLAN_ADD_DEL_TUNNEL, mp);
13010
13011   if (ipv6_set)
13012     {
13013       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13014       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13015     }
13016   else
13017     {
13018       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13019       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13020     }
13021
13022   mp->instance = htonl (instance);
13023   mp->encap_vrf_id = ntohl (encap_vrf_id);
13024   mp->decap_next_index = ntohl (decap_next_index);
13025   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13026   mp->vni = ntohl (vni);
13027   mp->is_add = is_add;
13028   mp->is_ipv6 = ipv6_set;
13029
13030   S (mp);
13031   W (ret);
13032   return ret;
13033 }
13034
13035 static void vl_api_vxlan_tunnel_details_t_handler
13036   (vl_api_vxlan_tunnel_details_t * mp)
13037 {
13038   vat_main_t *vam = &vat_main;
13039   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13040   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13041
13042   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13043          ntohl (mp->sw_if_index),
13044          ntohl (mp->instance),
13045          format_ip46_address, &src, IP46_TYPE_ANY,
13046          format_ip46_address, &dst, IP46_TYPE_ANY,
13047          ntohl (mp->encap_vrf_id),
13048          ntohl (mp->decap_next_index), ntohl (mp->vni),
13049          ntohl (mp->mcast_sw_if_index));
13050 }
13051
13052 static void vl_api_vxlan_tunnel_details_t_handler_json
13053   (vl_api_vxlan_tunnel_details_t * mp)
13054 {
13055   vat_main_t *vam = &vat_main;
13056   vat_json_node_t *node = NULL;
13057
13058   if (VAT_JSON_ARRAY != vam->json_tree.type)
13059     {
13060       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13061       vat_json_init_array (&vam->json_tree);
13062     }
13063   node = vat_json_array_add (&vam->json_tree);
13064
13065   vat_json_init_object (node);
13066   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13067
13068   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13069
13070   if (mp->is_ipv6)
13071     {
13072       struct in6_addr ip6;
13073
13074       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13075       vat_json_object_add_ip6 (node, "src_address", ip6);
13076       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13077       vat_json_object_add_ip6 (node, "dst_address", ip6);
13078     }
13079   else
13080     {
13081       struct in_addr ip4;
13082
13083       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13084       vat_json_object_add_ip4 (node, "src_address", ip4);
13085       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13086       vat_json_object_add_ip4 (node, "dst_address", ip4);
13087     }
13088   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13089   vat_json_object_add_uint (node, "decap_next_index",
13090                             ntohl (mp->decap_next_index));
13091   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13092   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13093   vat_json_object_add_uint (node, "mcast_sw_if_index",
13094                             ntohl (mp->mcast_sw_if_index));
13095 }
13096
13097 static int
13098 api_vxlan_tunnel_dump (vat_main_t * vam)
13099 {
13100   unformat_input_t *i = vam->input;
13101   vl_api_vxlan_tunnel_dump_t *mp;
13102   vl_api_control_ping_t *mp_ping;
13103   u32 sw_if_index;
13104   u8 sw_if_index_set = 0;
13105   int ret;
13106
13107   /* Parse args required to build the message */
13108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13109     {
13110       if (unformat (i, "sw_if_index %d", &sw_if_index))
13111         sw_if_index_set = 1;
13112       else
13113         break;
13114     }
13115
13116   if (sw_if_index_set == 0)
13117     {
13118       sw_if_index = ~0;
13119     }
13120
13121   if (!vam->json_output)
13122     {
13123       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13124              "sw_if_index", "instance", "src_address", "dst_address",
13125              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13126     }
13127
13128   /* Get list of vxlan-tunnel interfaces */
13129   M (VXLAN_TUNNEL_DUMP, mp);
13130
13131   mp->sw_if_index = htonl (sw_if_index);
13132
13133   S (mp);
13134
13135   /* Use a control ping for synchronization */
13136   MPING (CONTROL_PING, mp_ping);
13137   S (mp_ping);
13138
13139   W (ret);
13140   return ret;
13141 }
13142
13143 static uword unformat_geneve_decap_next
13144   (unformat_input_t * input, va_list * args)
13145 {
13146   u32 *result = va_arg (*args, u32 *);
13147   u32 tmp;
13148
13149   if (unformat (input, "l2"))
13150     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13151   else if (unformat (input, "%d", &tmp))
13152     *result = tmp;
13153   else
13154     return 0;
13155   return 1;
13156 }
13157
13158 static int
13159 api_geneve_add_del_tunnel (vat_main_t * vam)
13160 {
13161   unformat_input_t *line_input = vam->input;
13162   vl_api_geneve_add_del_tunnel_t *mp;
13163   ip46_address_t src, dst;
13164   u8 is_add = 1;
13165   u8 ipv4_set = 0, ipv6_set = 0;
13166   u8 src_set = 0;
13167   u8 dst_set = 0;
13168   u8 grp_set = 0;
13169   u32 mcast_sw_if_index = ~0;
13170   u32 encap_vrf_id = 0;
13171   u32 decap_next_index = ~0;
13172   u32 vni = 0;
13173   int ret;
13174
13175   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13176   memset (&src, 0, sizeof src);
13177   memset (&dst, 0, sizeof dst);
13178
13179   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13180     {
13181       if (unformat (line_input, "del"))
13182         is_add = 0;
13183       else
13184         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13185         {
13186           ipv4_set = 1;
13187           src_set = 1;
13188         }
13189       else
13190         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13191         {
13192           ipv4_set = 1;
13193           dst_set = 1;
13194         }
13195       else
13196         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13197         {
13198           ipv6_set = 1;
13199           src_set = 1;
13200         }
13201       else
13202         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13203         {
13204           ipv6_set = 1;
13205           dst_set = 1;
13206         }
13207       else if (unformat (line_input, "group %U %U",
13208                          unformat_ip4_address, &dst.ip4,
13209                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13210         {
13211           grp_set = dst_set = 1;
13212           ipv4_set = 1;
13213         }
13214       else if (unformat (line_input, "group %U",
13215                          unformat_ip4_address, &dst.ip4))
13216         {
13217           grp_set = dst_set = 1;
13218           ipv4_set = 1;
13219         }
13220       else if (unformat (line_input, "group %U %U",
13221                          unformat_ip6_address, &dst.ip6,
13222                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13223         {
13224           grp_set = dst_set = 1;
13225           ipv6_set = 1;
13226         }
13227       else if (unformat (line_input, "group %U",
13228                          unformat_ip6_address, &dst.ip6))
13229         {
13230           grp_set = dst_set = 1;
13231           ipv6_set = 1;
13232         }
13233       else
13234         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13235         ;
13236       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13237         ;
13238       else if (unformat (line_input, "decap-next %U",
13239                          unformat_geneve_decap_next, &decap_next_index))
13240         ;
13241       else if (unformat (line_input, "vni %d", &vni))
13242         ;
13243       else
13244         {
13245           errmsg ("parse error '%U'", format_unformat_error, line_input);
13246           return -99;
13247         }
13248     }
13249
13250   if (src_set == 0)
13251     {
13252       errmsg ("tunnel src address not specified");
13253       return -99;
13254     }
13255   if (dst_set == 0)
13256     {
13257       errmsg ("tunnel dst address not specified");
13258       return -99;
13259     }
13260
13261   if (grp_set && !ip46_address_is_multicast (&dst))
13262     {
13263       errmsg ("tunnel group address not multicast");
13264       return -99;
13265     }
13266   if (grp_set && mcast_sw_if_index == ~0)
13267     {
13268       errmsg ("tunnel nonexistent multicast device");
13269       return -99;
13270     }
13271   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13272     {
13273       errmsg ("tunnel dst address must be unicast");
13274       return -99;
13275     }
13276
13277
13278   if (ipv4_set && ipv6_set)
13279     {
13280       errmsg ("both IPv4 and IPv6 addresses specified");
13281       return -99;
13282     }
13283
13284   if ((vni == 0) || (vni >> 24))
13285     {
13286       errmsg ("vni not specified or out of range");
13287       return -99;
13288     }
13289
13290   M (GENEVE_ADD_DEL_TUNNEL, mp);
13291
13292   if (ipv6_set)
13293     {
13294       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13295       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13296     }
13297   else
13298     {
13299       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13300       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13301     }
13302   mp->encap_vrf_id = ntohl (encap_vrf_id);
13303   mp->decap_next_index = ntohl (decap_next_index);
13304   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13305   mp->vni = ntohl (vni);
13306   mp->is_add = is_add;
13307   mp->is_ipv6 = ipv6_set;
13308
13309   S (mp);
13310   W (ret);
13311   return ret;
13312 }
13313
13314 static void vl_api_geneve_tunnel_details_t_handler
13315   (vl_api_geneve_tunnel_details_t * mp)
13316 {
13317   vat_main_t *vam = &vat_main;
13318   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13319   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13320
13321   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13322          ntohl (mp->sw_if_index),
13323          format_ip46_address, &src, IP46_TYPE_ANY,
13324          format_ip46_address, &dst, IP46_TYPE_ANY,
13325          ntohl (mp->encap_vrf_id),
13326          ntohl (mp->decap_next_index), ntohl (mp->vni),
13327          ntohl (mp->mcast_sw_if_index));
13328 }
13329
13330 static void vl_api_geneve_tunnel_details_t_handler_json
13331   (vl_api_geneve_tunnel_details_t * mp)
13332 {
13333   vat_main_t *vam = &vat_main;
13334   vat_json_node_t *node = NULL;
13335
13336   if (VAT_JSON_ARRAY != vam->json_tree.type)
13337     {
13338       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13339       vat_json_init_array (&vam->json_tree);
13340     }
13341   node = vat_json_array_add (&vam->json_tree);
13342
13343   vat_json_init_object (node);
13344   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13345   if (mp->is_ipv6)
13346     {
13347       struct in6_addr ip6;
13348
13349       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13350       vat_json_object_add_ip6 (node, "src_address", ip6);
13351       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13352       vat_json_object_add_ip6 (node, "dst_address", ip6);
13353     }
13354   else
13355     {
13356       struct in_addr ip4;
13357
13358       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13359       vat_json_object_add_ip4 (node, "src_address", ip4);
13360       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13361       vat_json_object_add_ip4 (node, "dst_address", ip4);
13362     }
13363   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13364   vat_json_object_add_uint (node, "decap_next_index",
13365                             ntohl (mp->decap_next_index));
13366   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13367   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13368   vat_json_object_add_uint (node, "mcast_sw_if_index",
13369                             ntohl (mp->mcast_sw_if_index));
13370 }
13371
13372 static int
13373 api_geneve_tunnel_dump (vat_main_t * vam)
13374 {
13375   unformat_input_t *i = vam->input;
13376   vl_api_geneve_tunnel_dump_t *mp;
13377   vl_api_control_ping_t *mp_ping;
13378   u32 sw_if_index;
13379   u8 sw_if_index_set = 0;
13380   int ret;
13381
13382   /* Parse args required to build the message */
13383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13384     {
13385       if (unformat (i, "sw_if_index %d", &sw_if_index))
13386         sw_if_index_set = 1;
13387       else
13388         break;
13389     }
13390
13391   if (sw_if_index_set == 0)
13392     {
13393       sw_if_index = ~0;
13394     }
13395
13396   if (!vam->json_output)
13397     {
13398       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13399              "sw_if_index", "local_address", "remote_address",
13400              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13401     }
13402
13403   /* Get list of geneve-tunnel interfaces */
13404   M (GENEVE_TUNNEL_DUMP, mp);
13405
13406   mp->sw_if_index = htonl (sw_if_index);
13407
13408   S (mp);
13409
13410   /* Use a control ping for synchronization */
13411   M (CONTROL_PING, mp_ping);
13412   S (mp_ping);
13413
13414   W (ret);
13415   return ret;
13416 }
13417
13418 static int
13419 api_gre_add_del_tunnel (vat_main_t * vam)
13420 {
13421   unformat_input_t *line_input = vam->input;
13422   vl_api_gre_add_del_tunnel_t *mp;
13423   ip4_address_t src4, dst4;
13424   ip6_address_t src6, dst6;
13425   u8 is_add = 1;
13426   u8 ipv4_set = 0;
13427   u8 ipv6_set = 0;
13428   u8 t_type = GRE_TUNNEL_TYPE_L3;
13429   u8 src_set = 0;
13430   u8 dst_set = 0;
13431   u32 outer_fib_id = 0;
13432   u32 session_id = 0;
13433   u32 instance = ~0;
13434   int ret;
13435
13436   memset (&src4, 0, sizeof src4);
13437   memset (&dst4, 0, sizeof dst4);
13438   memset (&src6, 0, sizeof src6);
13439   memset (&dst6, 0, sizeof dst6);
13440
13441   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13442     {
13443       if (unformat (line_input, "del"))
13444         is_add = 0;
13445       else if (unformat (line_input, "instance %d", &instance))
13446         ;
13447       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13448         {
13449           src_set = 1;
13450           ipv4_set = 1;
13451         }
13452       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13453         {
13454           dst_set = 1;
13455           ipv4_set = 1;
13456         }
13457       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13458         {
13459           src_set = 1;
13460           ipv6_set = 1;
13461         }
13462       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13463         {
13464           dst_set = 1;
13465           ipv6_set = 1;
13466         }
13467       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13468         ;
13469       else if (unformat (line_input, "teb"))
13470         t_type = GRE_TUNNEL_TYPE_TEB;
13471       else if (unformat (line_input, "erspan %d", &session_id))
13472         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13473       else
13474         {
13475           errmsg ("parse error '%U'", format_unformat_error, line_input);
13476           return -99;
13477         }
13478     }
13479
13480   if (src_set == 0)
13481     {
13482       errmsg ("tunnel src address not specified");
13483       return -99;
13484     }
13485   if (dst_set == 0)
13486     {
13487       errmsg ("tunnel dst address not specified");
13488       return -99;
13489     }
13490   if (ipv4_set && ipv6_set)
13491     {
13492       errmsg ("both IPv4 and IPv6 addresses specified");
13493       return -99;
13494     }
13495
13496
13497   M (GRE_ADD_DEL_TUNNEL, mp);
13498
13499   if (ipv4_set)
13500     {
13501       clib_memcpy (&mp->src_address, &src4, 4);
13502       clib_memcpy (&mp->dst_address, &dst4, 4);
13503     }
13504   else
13505     {
13506       clib_memcpy (&mp->src_address, &src6, 16);
13507       clib_memcpy (&mp->dst_address, &dst6, 16);
13508     }
13509   mp->instance = htonl (instance);
13510   mp->outer_fib_id = htonl (outer_fib_id);
13511   mp->is_add = is_add;
13512   mp->session_id = htons ((u16) session_id);
13513   mp->tunnel_type = t_type;
13514   mp->is_ipv6 = ipv6_set;
13515
13516   S (mp);
13517   W (ret);
13518   return ret;
13519 }
13520
13521 static void vl_api_gre_tunnel_details_t_handler
13522   (vl_api_gre_tunnel_details_t * mp)
13523 {
13524   vat_main_t *vam = &vat_main;
13525   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13526   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13527
13528   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13529          ntohl (mp->sw_if_index),
13530          ntohl (mp->instance),
13531          format_ip46_address, &src, IP46_TYPE_ANY,
13532          format_ip46_address, &dst, IP46_TYPE_ANY,
13533          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13534 }
13535
13536 static void vl_api_gre_tunnel_details_t_handler_json
13537   (vl_api_gre_tunnel_details_t * mp)
13538 {
13539   vat_main_t *vam = &vat_main;
13540   vat_json_node_t *node = NULL;
13541   struct in_addr ip4;
13542   struct in6_addr ip6;
13543
13544   if (VAT_JSON_ARRAY != vam->json_tree.type)
13545     {
13546       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13547       vat_json_init_array (&vam->json_tree);
13548     }
13549   node = vat_json_array_add (&vam->json_tree);
13550
13551   vat_json_init_object (node);
13552   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13553   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13554   if (!mp->is_ipv6)
13555     {
13556       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13557       vat_json_object_add_ip4 (node, "src_address", ip4);
13558       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13559       vat_json_object_add_ip4 (node, "dst_address", ip4);
13560     }
13561   else
13562     {
13563       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13564       vat_json_object_add_ip6 (node, "src_address", ip6);
13565       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13566       vat_json_object_add_ip6 (node, "dst_address", ip6);
13567     }
13568   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13569   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13570   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13571   vat_json_object_add_uint (node, "session_id", mp->session_id);
13572 }
13573
13574 static int
13575 api_gre_tunnel_dump (vat_main_t * vam)
13576 {
13577   unformat_input_t *i = vam->input;
13578   vl_api_gre_tunnel_dump_t *mp;
13579   vl_api_control_ping_t *mp_ping;
13580   u32 sw_if_index;
13581   u8 sw_if_index_set = 0;
13582   int ret;
13583
13584   /* Parse args required to build the message */
13585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13586     {
13587       if (unformat (i, "sw_if_index %d", &sw_if_index))
13588         sw_if_index_set = 1;
13589       else
13590         break;
13591     }
13592
13593   if (sw_if_index_set == 0)
13594     {
13595       sw_if_index = ~0;
13596     }
13597
13598   if (!vam->json_output)
13599     {
13600       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13601              "sw_if_index", "instance", "src_address", "dst_address",
13602              "tunnel_type", "outer_fib_id", "session_id");
13603     }
13604
13605   /* Get list of gre-tunnel interfaces */
13606   M (GRE_TUNNEL_DUMP, mp);
13607
13608   mp->sw_if_index = htonl (sw_if_index);
13609
13610   S (mp);
13611
13612   /* Use a control ping for synchronization */
13613   MPING (CONTROL_PING, mp_ping);
13614   S (mp_ping);
13615
13616   W (ret);
13617   return ret;
13618 }
13619
13620 static int
13621 api_l2_fib_clear_table (vat_main_t * vam)
13622 {
13623 //  unformat_input_t * i = vam->input;
13624   vl_api_l2_fib_clear_table_t *mp;
13625   int ret;
13626
13627   M (L2_FIB_CLEAR_TABLE, mp);
13628
13629   S (mp);
13630   W (ret);
13631   return ret;
13632 }
13633
13634 static int
13635 api_l2_interface_efp_filter (vat_main_t * vam)
13636 {
13637   unformat_input_t *i = vam->input;
13638   vl_api_l2_interface_efp_filter_t *mp;
13639   u32 sw_if_index;
13640   u8 enable = 1;
13641   u8 sw_if_index_set = 0;
13642   int ret;
13643
13644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13645     {
13646       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13647         sw_if_index_set = 1;
13648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13649         sw_if_index_set = 1;
13650       else if (unformat (i, "enable"))
13651         enable = 1;
13652       else if (unformat (i, "disable"))
13653         enable = 0;
13654       else
13655         {
13656           clib_warning ("parse error '%U'", format_unformat_error, i);
13657           return -99;
13658         }
13659     }
13660
13661   if (sw_if_index_set == 0)
13662     {
13663       errmsg ("missing sw_if_index");
13664       return -99;
13665     }
13666
13667   M (L2_INTERFACE_EFP_FILTER, mp);
13668
13669   mp->sw_if_index = ntohl (sw_if_index);
13670   mp->enable_disable = enable;
13671
13672   S (mp);
13673   W (ret);
13674   return ret;
13675 }
13676
13677 #define foreach_vtr_op                          \
13678 _("disable",  L2_VTR_DISABLED)                  \
13679 _("push-1",  L2_VTR_PUSH_1)                     \
13680 _("push-2",  L2_VTR_PUSH_2)                     \
13681 _("pop-1",  L2_VTR_POP_1)                       \
13682 _("pop-2",  L2_VTR_POP_2)                       \
13683 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13684 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13685 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13686 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13687
13688 static int
13689 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13690 {
13691   unformat_input_t *i = vam->input;
13692   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13693   u32 sw_if_index;
13694   u8 sw_if_index_set = 0;
13695   u8 vtr_op_set = 0;
13696   u32 vtr_op = 0;
13697   u32 push_dot1q = 1;
13698   u32 tag1 = ~0;
13699   u32 tag2 = ~0;
13700   int ret;
13701
13702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13703     {
13704       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13705         sw_if_index_set = 1;
13706       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13707         sw_if_index_set = 1;
13708       else if (unformat (i, "vtr_op %d", &vtr_op))
13709         vtr_op_set = 1;
13710 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13711       foreach_vtr_op
13712 #undef _
13713         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13714         ;
13715       else if (unformat (i, "tag1 %d", &tag1))
13716         ;
13717       else if (unformat (i, "tag2 %d", &tag2))
13718         ;
13719       else
13720         {
13721           clib_warning ("parse error '%U'", format_unformat_error, i);
13722           return -99;
13723         }
13724     }
13725
13726   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13727     {
13728       errmsg ("missing vtr operation or sw_if_index");
13729       return -99;
13730     }
13731
13732   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13733   mp->sw_if_index = ntohl (sw_if_index);
13734   mp->vtr_op = ntohl (vtr_op);
13735   mp->push_dot1q = ntohl (push_dot1q);
13736   mp->tag1 = ntohl (tag1);
13737   mp->tag2 = ntohl (tag2);
13738
13739   S (mp);
13740   W (ret);
13741   return ret;
13742 }
13743
13744 static int
13745 api_create_vhost_user_if (vat_main_t * vam)
13746 {
13747   unformat_input_t *i = vam->input;
13748   vl_api_create_vhost_user_if_t *mp;
13749   u8 *file_name;
13750   u8 is_server = 0;
13751   u8 file_name_set = 0;
13752   u32 custom_dev_instance = ~0;
13753   u8 hwaddr[6];
13754   u8 use_custom_mac = 0;
13755   u8 *tag = 0;
13756   int ret;
13757
13758   /* Shut up coverity */
13759   memset (hwaddr, 0, sizeof (hwaddr));
13760
13761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13762     {
13763       if (unformat (i, "socket %s", &file_name))
13764         {
13765           file_name_set = 1;
13766         }
13767       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13768         ;
13769       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13770         use_custom_mac = 1;
13771       else if (unformat (i, "server"))
13772         is_server = 1;
13773       else if (unformat (i, "tag %s", &tag))
13774         ;
13775       else
13776         break;
13777     }
13778
13779   if (file_name_set == 0)
13780     {
13781       errmsg ("missing socket file name");
13782       return -99;
13783     }
13784
13785   if (vec_len (file_name) > 255)
13786     {
13787       errmsg ("socket file name too long");
13788       return -99;
13789     }
13790   vec_add1 (file_name, 0);
13791
13792   M (CREATE_VHOST_USER_IF, mp);
13793
13794   mp->is_server = is_server;
13795   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13796   vec_free (file_name);
13797   if (custom_dev_instance != ~0)
13798     {
13799       mp->renumber = 1;
13800       mp->custom_dev_instance = ntohl (custom_dev_instance);
13801     }
13802   mp->use_custom_mac = use_custom_mac;
13803   clib_memcpy (mp->mac_address, hwaddr, 6);
13804   if (tag)
13805     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13806   vec_free (tag);
13807
13808   S (mp);
13809   W (ret);
13810   return ret;
13811 }
13812
13813 static int
13814 api_modify_vhost_user_if (vat_main_t * vam)
13815 {
13816   unformat_input_t *i = vam->input;
13817   vl_api_modify_vhost_user_if_t *mp;
13818   u8 *file_name;
13819   u8 is_server = 0;
13820   u8 file_name_set = 0;
13821   u32 custom_dev_instance = ~0;
13822   u8 sw_if_index_set = 0;
13823   u32 sw_if_index = (u32) ~ 0;
13824   int ret;
13825
13826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13827     {
13828       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13829         sw_if_index_set = 1;
13830       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13831         sw_if_index_set = 1;
13832       else if (unformat (i, "socket %s", &file_name))
13833         {
13834           file_name_set = 1;
13835         }
13836       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13837         ;
13838       else if (unformat (i, "server"))
13839         is_server = 1;
13840       else
13841         break;
13842     }
13843
13844   if (sw_if_index_set == 0)
13845     {
13846       errmsg ("missing sw_if_index or interface name");
13847       return -99;
13848     }
13849
13850   if (file_name_set == 0)
13851     {
13852       errmsg ("missing socket file name");
13853       return -99;
13854     }
13855
13856   if (vec_len (file_name) > 255)
13857     {
13858       errmsg ("socket file name too long");
13859       return -99;
13860     }
13861   vec_add1 (file_name, 0);
13862
13863   M (MODIFY_VHOST_USER_IF, mp);
13864
13865   mp->sw_if_index = ntohl (sw_if_index);
13866   mp->is_server = is_server;
13867   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13868   vec_free (file_name);
13869   if (custom_dev_instance != ~0)
13870     {
13871       mp->renumber = 1;
13872       mp->custom_dev_instance = ntohl (custom_dev_instance);
13873     }
13874
13875   S (mp);
13876   W (ret);
13877   return ret;
13878 }
13879
13880 static int
13881 api_delete_vhost_user_if (vat_main_t * vam)
13882 {
13883   unformat_input_t *i = vam->input;
13884   vl_api_delete_vhost_user_if_t *mp;
13885   u32 sw_if_index = ~0;
13886   u8 sw_if_index_set = 0;
13887   int ret;
13888
13889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13890     {
13891       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13892         sw_if_index_set = 1;
13893       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13894         sw_if_index_set = 1;
13895       else
13896         break;
13897     }
13898
13899   if (sw_if_index_set == 0)
13900     {
13901       errmsg ("missing sw_if_index or interface name");
13902       return -99;
13903     }
13904
13905
13906   M (DELETE_VHOST_USER_IF, mp);
13907
13908   mp->sw_if_index = ntohl (sw_if_index);
13909
13910   S (mp);
13911   W (ret);
13912   return ret;
13913 }
13914
13915 static void vl_api_sw_interface_vhost_user_details_t_handler
13916   (vl_api_sw_interface_vhost_user_details_t * mp)
13917 {
13918   vat_main_t *vam = &vat_main;
13919
13920   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13921          (char *) mp->interface_name,
13922          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13923          clib_net_to_host_u64 (mp->features), mp->is_server,
13924          ntohl (mp->num_regions), (char *) mp->sock_filename);
13925   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13926 }
13927
13928 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13929   (vl_api_sw_interface_vhost_user_details_t * mp)
13930 {
13931   vat_main_t *vam = &vat_main;
13932   vat_json_node_t *node = NULL;
13933
13934   if (VAT_JSON_ARRAY != vam->json_tree.type)
13935     {
13936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13937       vat_json_init_array (&vam->json_tree);
13938     }
13939   node = vat_json_array_add (&vam->json_tree);
13940
13941   vat_json_init_object (node);
13942   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13943   vat_json_object_add_string_copy (node, "interface_name",
13944                                    mp->interface_name);
13945   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13946                             ntohl (mp->virtio_net_hdr_sz));
13947   vat_json_object_add_uint (node, "features",
13948                             clib_net_to_host_u64 (mp->features));
13949   vat_json_object_add_uint (node, "is_server", mp->is_server);
13950   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13951   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13952   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13953 }
13954
13955 static int
13956 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13957 {
13958   vl_api_sw_interface_vhost_user_dump_t *mp;
13959   vl_api_control_ping_t *mp_ping;
13960   int ret;
13961   print (vam->ofp,
13962          "Interface name            idx hdr_sz features server regions filename");
13963
13964   /* Get list of vhost-user interfaces */
13965   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13966   S (mp);
13967
13968   /* Use a control ping for synchronization */
13969   MPING (CONTROL_PING, mp_ping);
13970   S (mp_ping);
13971
13972   W (ret);
13973   return ret;
13974 }
13975
13976 static int
13977 api_show_version (vat_main_t * vam)
13978 {
13979   vl_api_show_version_t *mp;
13980   int ret;
13981
13982   M (SHOW_VERSION, mp);
13983
13984   S (mp);
13985   W (ret);
13986   return ret;
13987 }
13988
13989
13990 static int
13991 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13992 {
13993   unformat_input_t *line_input = vam->input;
13994   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13995   ip4_address_t local4, remote4;
13996   ip6_address_t local6, remote6;
13997   u8 is_add = 1;
13998   u8 ipv4_set = 0, ipv6_set = 0;
13999   u8 local_set = 0;
14000   u8 remote_set = 0;
14001   u8 grp_set = 0;
14002   u32 mcast_sw_if_index = ~0;
14003   u32 encap_vrf_id = 0;
14004   u32 decap_vrf_id = 0;
14005   u8 protocol = ~0;
14006   u32 vni;
14007   u8 vni_set = 0;
14008   int ret;
14009
14010   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14011   memset (&local4, 0, sizeof local4);
14012   memset (&remote4, 0, sizeof remote4);
14013   memset (&local6, 0, sizeof local6);
14014   memset (&remote6, 0, sizeof remote6);
14015
14016   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14017     {
14018       if (unformat (line_input, "del"))
14019         is_add = 0;
14020       else if (unformat (line_input, "local %U",
14021                          unformat_ip4_address, &local4))
14022         {
14023           local_set = 1;
14024           ipv4_set = 1;
14025         }
14026       else if (unformat (line_input, "remote %U",
14027                          unformat_ip4_address, &remote4))
14028         {
14029           remote_set = 1;
14030           ipv4_set = 1;
14031         }
14032       else if (unformat (line_input, "local %U",
14033                          unformat_ip6_address, &local6))
14034         {
14035           local_set = 1;
14036           ipv6_set = 1;
14037         }
14038       else if (unformat (line_input, "remote %U",
14039                          unformat_ip6_address, &remote6))
14040         {
14041           remote_set = 1;
14042           ipv6_set = 1;
14043         }
14044       else if (unformat (line_input, "group %U %U",
14045                          unformat_ip4_address, &remote4,
14046                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14047         {
14048           grp_set = remote_set = 1;
14049           ipv4_set = 1;
14050         }
14051       else if (unformat (line_input, "group %U",
14052                          unformat_ip4_address, &remote4))
14053         {
14054           grp_set = remote_set = 1;
14055           ipv4_set = 1;
14056         }
14057       else if (unformat (line_input, "group %U %U",
14058                          unformat_ip6_address, &remote6,
14059                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14060         {
14061           grp_set = remote_set = 1;
14062           ipv6_set = 1;
14063         }
14064       else if (unformat (line_input, "group %U",
14065                          unformat_ip6_address, &remote6))
14066         {
14067           grp_set = remote_set = 1;
14068           ipv6_set = 1;
14069         }
14070       else
14071         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14072         ;
14073       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14074         ;
14075       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14076         ;
14077       else if (unformat (line_input, "vni %d", &vni))
14078         vni_set = 1;
14079       else if (unformat (line_input, "next-ip4"))
14080         protocol = 1;
14081       else if (unformat (line_input, "next-ip6"))
14082         protocol = 2;
14083       else if (unformat (line_input, "next-ethernet"))
14084         protocol = 3;
14085       else if (unformat (line_input, "next-nsh"))
14086         protocol = 4;
14087       else
14088         {
14089           errmsg ("parse error '%U'", format_unformat_error, line_input);
14090           return -99;
14091         }
14092     }
14093
14094   if (local_set == 0)
14095     {
14096       errmsg ("tunnel local address not specified");
14097       return -99;
14098     }
14099   if (remote_set == 0)
14100     {
14101       errmsg ("tunnel remote address not specified");
14102       return -99;
14103     }
14104   if (grp_set && mcast_sw_if_index == ~0)
14105     {
14106       errmsg ("tunnel nonexistent multicast device");
14107       return -99;
14108     }
14109   if (ipv4_set && ipv6_set)
14110     {
14111       errmsg ("both IPv4 and IPv6 addresses specified");
14112       return -99;
14113     }
14114
14115   if (vni_set == 0)
14116     {
14117       errmsg ("vni not specified");
14118       return -99;
14119     }
14120
14121   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14122
14123
14124   if (ipv6_set)
14125     {
14126       clib_memcpy (&mp->local, &local6, sizeof (local6));
14127       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14128     }
14129   else
14130     {
14131       clib_memcpy (&mp->local, &local4, sizeof (local4));
14132       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14133     }
14134
14135   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14136   mp->encap_vrf_id = ntohl (encap_vrf_id);
14137   mp->decap_vrf_id = ntohl (decap_vrf_id);
14138   mp->protocol = protocol;
14139   mp->vni = ntohl (vni);
14140   mp->is_add = is_add;
14141   mp->is_ipv6 = ipv6_set;
14142
14143   S (mp);
14144   W (ret);
14145   return ret;
14146 }
14147
14148 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14149   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14150 {
14151   vat_main_t *vam = &vat_main;
14152   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14153   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14154
14155   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14156          ntohl (mp->sw_if_index),
14157          format_ip46_address, &local, IP46_TYPE_ANY,
14158          format_ip46_address, &remote, IP46_TYPE_ANY,
14159          ntohl (mp->vni), mp->protocol,
14160          ntohl (mp->mcast_sw_if_index),
14161          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14162 }
14163
14164
14165 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14166   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14167 {
14168   vat_main_t *vam = &vat_main;
14169   vat_json_node_t *node = NULL;
14170   struct in_addr ip4;
14171   struct in6_addr ip6;
14172
14173   if (VAT_JSON_ARRAY != vam->json_tree.type)
14174     {
14175       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14176       vat_json_init_array (&vam->json_tree);
14177     }
14178   node = vat_json_array_add (&vam->json_tree);
14179
14180   vat_json_init_object (node);
14181   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14182   if (mp->is_ipv6)
14183     {
14184       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14185       vat_json_object_add_ip6 (node, "local", ip6);
14186       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14187       vat_json_object_add_ip6 (node, "remote", ip6);
14188     }
14189   else
14190     {
14191       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14192       vat_json_object_add_ip4 (node, "local", ip4);
14193       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14194       vat_json_object_add_ip4 (node, "remote", ip4);
14195     }
14196   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14197   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14198   vat_json_object_add_uint (node, "mcast_sw_if_index",
14199                             ntohl (mp->mcast_sw_if_index));
14200   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14201   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14202   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14203 }
14204
14205 static int
14206 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14207 {
14208   unformat_input_t *i = vam->input;
14209   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14210   vl_api_control_ping_t *mp_ping;
14211   u32 sw_if_index;
14212   u8 sw_if_index_set = 0;
14213   int ret;
14214
14215   /* Parse args required to build the message */
14216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14217     {
14218       if (unformat (i, "sw_if_index %d", &sw_if_index))
14219         sw_if_index_set = 1;
14220       else
14221         break;
14222     }
14223
14224   if (sw_if_index_set == 0)
14225     {
14226       sw_if_index = ~0;
14227     }
14228
14229   if (!vam->json_output)
14230     {
14231       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14232              "sw_if_index", "local", "remote", "vni",
14233              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14234     }
14235
14236   /* Get list of vxlan-tunnel interfaces */
14237   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14238
14239   mp->sw_if_index = htonl (sw_if_index);
14240
14241   S (mp);
14242
14243   /* Use a control ping for synchronization */
14244   MPING (CONTROL_PING, mp_ping);
14245   S (mp_ping);
14246
14247   W (ret);
14248   return ret;
14249 }
14250
14251 static void vl_api_l2_fib_table_details_t_handler
14252   (vl_api_l2_fib_table_details_t * mp)
14253 {
14254   vat_main_t *vam = &vat_main;
14255
14256   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14257          "       %d       %d     %d",
14258          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14259          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14260          mp->bvi_mac);
14261 }
14262
14263 static void vl_api_l2_fib_table_details_t_handler_json
14264   (vl_api_l2_fib_table_details_t * mp)
14265 {
14266   vat_main_t *vam = &vat_main;
14267   vat_json_node_t *node = NULL;
14268
14269   if (VAT_JSON_ARRAY != vam->json_tree.type)
14270     {
14271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14272       vat_json_init_array (&vam->json_tree);
14273     }
14274   node = vat_json_array_add (&vam->json_tree);
14275
14276   vat_json_init_object (node);
14277   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14278   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14279   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14280   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14281   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14282   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14283 }
14284
14285 static int
14286 api_l2_fib_table_dump (vat_main_t * vam)
14287 {
14288   unformat_input_t *i = vam->input;
14289   vl_api_l2_fib_table_dump_t *mp;
14290   vl_api_control_ping_t *mp_ping;
14291   u32 bd_id;
14292   u8 bd_id_set = 0;
14293   int ret;
14294
14295   /* Parse args required to build the message */
14296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14297     {
14298       if (unformat (i, "bd_id %d", &bd_id))
14299         bd_id_set = 1;
14300       else
14301         break;
14302     }
14303
14304   if (bd_id_set == 0)
14305     {
14306       errmsg ("missing bridge domain");
14307       return -99;
14308     }
14309
14310   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14311
14312   /* Get list of l2 fib entries */
14313   M (L2_FIB_TABLE_DUMP, mp);
14314
14315   mp->bd_id = ntohl (bd_id);
14316   S (mp);
14317
14318   /* Use a control ping for synchronization */
14319   MPING (CONTROL_PING, mp_ping);
14320   S (mp_ping);
14321
14322   W (ret);
14323   return ret;
14324 }
14325
14326
14327 static int
14328 api_interface_name_renumber (vat_main_t * vam)
14329 {
14330   unformat_input_t *line_input = vam->input;
14331   vl_api_interface_name_renumber_t *mp;
14332   u32 sw_if_index = ~0;
14333   u32 new_show_dev_instance = ~0;
14334   int ret;
14335
14336   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14337     {
14338       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14339                     &sw_if_index))
14340         ;
14341       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14342         ;
14343       else if (unformat (line_input, "new_show_dev_instance %d",
14344                          &new_show_dev_instance))
14345         ;
14346       else
14347         break;
14348     }
14349
14350   if (sw_if_index == ~0)
14351     {
14352       errmsg ("missing interface name or sw_if_index");
14353       return -99;
14354     }
14355
14356   if (new_show_dev_instance == ~0)
14357     {
14358       errmsg ("missing new_show_dev_instance");
14359       return -99;
14360     }
14361
14362   M (INTERFACE_NAME_RENUMBER, mp);
14363
14364   mp->sw_if_index = ntohl (sw_if_index);
14365   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14366
14367   S (mp);
14368   W (ret);
14369   return ret;
14370 }
14371
14372 static int
14373 api_ip_probe_neighbor (vat_main_t * vam)
14374 {
14375   unformat_input_t *i = vam->input;
14376   vl_api_ip_probe_neighbor_t *mp;
14377   u8 int_set = 0;
14378   u8 adr_set = 0;
14379   u8 is_ipv6 = 0;
14380   u8 dst_adr[16];
14381   u32 sw_if_index;
14382   int ret;
14383
14384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14385     {
14386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14387         int_set = 1;
14388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14389         int_set = 1;
14390       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14391         adr_set = 1;
14392       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14393         {
14394           adr_set = 1;
14395           is_ipv6 = 1;
14396         }
14397       else
14398         break;
14399     }
14400
14401   if (int_set == 0)
14402     {
14403       errmsg ("missing interface");
14404       return -99;
14405     }
14406
14407   if (adr_set == 0)
14408     {
14409       errmsg ("missing addresses");
14410       return -99;
14411     }
14412
14413   M (IP_PROBE_NEIGHBOR, mp);
14414
14415   mp->sw_if_index = ntohl (sw_if_index);
14416   mp->is_ipv6 = is_ipv6;
14417   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14418
14419   S (mp);
14420   W (ret);
14421   return ret;
14422 }
14423
14424 static int
14425 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14426 {
14427   unformat_input_t *i = vam->input;
14428   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14429   u8 mode = IP_SCAN_V46_NEIGHBORS;
14430   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14431   int ret;
14432
14433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14434     {
14435       if (unformat (i, "ip4"))
14436         mode = IP_SCAN_V4_NEIGHBORS;
14437       else if (unformat (i, "ip6"))
14438         mode = IP_SCAN_V6_NEIGHBORS;
14439       if (unformat (i, "both"))
14440         mode = IP_SCAN_V46_NEIGHBORS;
14441       else if (unformat (i, "disable"))
14442         mode = IP_SCAN_DISABLED;
14443       else if (unformat (i, "interval %d", &interval))
14444         ;
14445       else if (unformat (i, "max-time %d", &time))
14446         ;
14447       else if (unformat (i, "max-update %d", &update))
14448         ;
14449       else if (unformat (i, "delay %d", &delay))
14450         ;
14451       else if (unformat (i, "stale %d", &stale))
14452         ;
14453       else
14454         break;
14455     }
14456
14457   if (interval > 255)
14458     {
14459       errmsg ("interval cannot exceed 255 minutes.");
14460       return -99;
14461     }
14462   if (time > 255)
14463     {
14464       errmsg ("max-time cannot exceed 255 usec.");
14465       return -99;
14466     }
14467   if (update > 255)
14468     {
14469       errmsg ("max-update cannot exceed 255.");
14470       return -99;
14471     }
14472   if (delay > 255)
14473     {
14474       errmsg ("delay cannot exceed 255 msec.");
14475       return -99;
14476     }
14477   if (stale > 255)
14478     {
14479       errmsg ("stale cannot exceed 255 minutes.");
14480       return -99;
14481     }
14482
14483   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14484   mp->mode = mode;
14485   mp->scan_interval = interval;
14486   mp->max_proc_time = time;
14487   mp->max_update = update;
14488   mp->scan_int_delay = delay;
14489   mp->stale_threshold = stale;
14490
14491   S (mp);
14492   W (ret);
14493   return ret;
14494 }
14495
14496 static int
14497 api_want_ip4_arp_events (vat_main_t * vam)
14498 {
14499   unformat_input_t *line_input = vam->input;
14500   vl_api_want_ip4_arp_events_t *mp;
14501   ip4_address_t address;
14502   int address_set = 0;
14503   u32 enable_disable = 1;
14504   int ret;
14505
14506   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14507     {
14508       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14509         address_set = 1;
14510       else if (unformat (line_input, "del"))
14511         enable_disable = 0;
14512       else
14513         break;
14514     }
14515
14516   if (address_set == 0)
14517     {
14518       errmsg ("missing addresses");
14519       return -99;
14520     }
14521
14522   M (WANT_IP4_ARP_EVENTS, mp);
14523   mp->enable_disable = enable_disable;
14524   mp->pid = htonl (getpid ());
14525   mp->address = address.as_u32;
14526
14527   S (mp);
14528   W (ret);
14529   return ret;
14530 }
14531
14532 static int
14533 api_want_ip6_nd_events (vat_main_t * vam)
14534 {
14535   unformat_input_t *line_input = vam->input;
14536   vl_api_want_ip6_nd_events_t *mp;
14537   ip6_address_t address;
14538   int address_set = 0;
14539   u32 enable_disable = 1;
14540   int ret;
14541
14542   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14543     {
14544       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14545         address_set = 1;
14546       else if (unformat (line_input, "del"))
14547         enable_disable = 0;
14548       else
14549         break;
14550     }
14551
14552   if (address_set == 0)
14553     {
14554       errmsg ("missing addresses");
14555       return -99;
14556     }
14557
14558   M (WANT_IP6_ND_EVENTS, mp);
14559   mp->enable_disable = enable_disable;
14560   mp->pid = htonl (getpid ());
14561   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14562
14563   S (mp);
14564   W (ret);
14565   return ret;
14566 }
14567
14568 static int
14569 api_want_l2_macs_events (vat_main_t * vam)
14570 {
14571   unformat_input_t *line_input = vam->input;
14572   vl_api_want_l2_macs_events_t *mp;
14573   u8 enable_disable = 1;
14574   u32 scan_delay = 0;
14575   u32 max_macs_in_event = 0;
14576   u32 learn_limit = 0;
14577   int ret;
14578
14579   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14580     {
14581       if (unformat (line_input, "learn-limit %d", &learn_limit))
14582         ;
14583       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14584         ;
14585       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14586         ;
14587       else if (unformat (line_input, "disable"))
14588         enable_disable = 0;
14589       else
14590         break;
14591     }
14592
14593   M (WANT_L2_MACS_EVENTS, mp);
14594   mp->enable_disable = enable_disable;
14595   mp->pid = htonl (getpid ());
14596   mp->learn_limit = htonl (learn_limit);
14597   mp->scan_delay = (u8) scan_delay;
14598   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14599   S (mp);
14600   W (ret);
14601   return ret;
14602 }
14603
14604 static int
14605 api_input_acl_set_interface (vat_main_t * vam)
14606 {
14607   unformat_input_t *i = vam->input;
14608   vl_api_input_acl_set_interface_t *mp;
14609   u32 sw_if_index;
14610   int sw_if_index_set;
14611   u32 ip4_table_index = ~0;
14612   u32 ip6_table_index = ~0;
14613   u32 l2_table_index = ~0;
14614   u8 is_add = 1;
14615   int ret;
14616
14617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14618     {
14619       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14620         sw_if_index_set = 1;
14621       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14622         sw_if_index_set = 1;
14623       else if (unformat (i, "del"))
14624         is_add = 0;
14625       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14626         ;
14627       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14628         ;
14629       else if (unformat (i, "l2-table %d", &l2_table_index))
14630         ;
14631       else
14632         {
14633           clib_warning ("parse error '%U'", format_unformat_error, i);
14634           return -99;
14635         }
14636     }
14637
14638   if (sw_if_index_set == 0)
14639     {
14640       errmsg ("missing interface name or sw_if_index");
14641       return -99;
14642     }
14643
14644   M (INPUT_ACL_SET_INTERFACE, mp);
14645
14646   mp->sw_if_index = ntohl (sw_if_index);
14647   mp->ip4_table_index = ntohl (ip4_table_index);
14648   mp->ip6_table_index = ntohl (ip6_table_index);
14649   mp->l2_table_index = ntohl (l2_table_index);
14650   mp->is_add = is_add;
14651
14652   S (mp);
14653   W (ret);
14654   return ret;
14655 }
14656
14657 static int
14658 api_output_acl_set_interface (vat_main_t * vam)
14659 {
14660   unformat_input_t *i = vam->input;
14661   vl_api_output_acl_set_interface_t *mp;
14662   u32 sw_if_index;
14663   int sw_if_index_set;
14664   u32 ip4_table_index = ~0;
14665   u32 ip6_table_index = ~0;
14666   u32 l2_table_index = ~0;
14667   u8 is_add = 1;
14668   int ret;
14669
14670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14671     {
14672       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14673         sw_if_index_set = 1;
14674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14675         sw_if_index_set = 1;
14676       else if (unformat (i, "del"))
14677         is_add = 0;
14678       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14679         ;
14680       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14681         ;
14682       else if (unformat (i, "l2-table %d", &l2_table_index))
14683         ;
14684       else
14685         {
14686           clib_warning ("parse error '%U'", format_unformat_error, i);
14687           return -99;
14688         }
14689     }
14690
14691   if (sw_if_index_set == 0)
14692     {
14693       errmsg ("missing interface name or sw_if_index");
14694       return -99;
14695     }
14696
14697   M (OUTPUT_ACL_SET_INTERFACE, mp);
14698
14699   mp->sw_if_index = ntohl (sw_if_index);
14700   mp->ip4_table_index = ntohl (ip4_table_index);
14701   mp->ip6_table_index = ntohl (ip6_table_index);
14702   mp->l2_table_index = ntohl (l2_table_index);
14703   mp->is_add = is_add;
14704
14705   S (mp);
14706   W (ret);
14707   return ret;
14708 }
14709
14710 static int
14711 api_ip_address_dump (vat_main_t * vam)
14712 {
14713   unformat_input_t *i = vam->input;
14714   vl_api_ip_address_dump_t *mp;
14715   vl_api_control_ping_t *mp_ping;
14716   u32 sw_if_index = ~0;
14717   u8 sw_if_index_set = 0;
14718   u8 ipv4_set = 0;
14719   u8 ipv6_set = 0;
14720   int ret;
14721
14722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14723     {
14724       if (unformat (i, "sw_if_index %d", &sw_if_index))
14725         sw_if_index_set = 1;
14726       else
14727         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14728         sw_if_index_set = 1;
14729       else if (unformat (i, "ipv4"))
14730         ipv4_set = 1;
14731       else if (unformat (i, "ipv6"))
14732         ipv6_set = 1;
14733       else
14734         break;
14735     }
14736
14737   if (ipv4_set && ipv6_set)
14738     {
14739       errmsg ("ipv4 and ipv6 flags cannot be both set");
14740       return -99;
14741     }
14742
14743   if ((!ipv4_set) && (!ipv6_set))
14744     {
14745       errmsg ("no ipv4 nor ipv6 flag set");
14746       return -99;
14747     }
14748
14749   if (sw_if_index_set == 0)
14750     {
14751       errmsg ("missing interface name or sw_if_index");
14752       return -99;
14753     }
14754
14755   vam->current_sw_if_index = sw_if_index;
14756   vam->is_ipv6 = ipv6_set;
14757
14758   M (IP_ADDRESS_DUMP, mp);
14759   mp->sw_if_index = ntohl (sw_if_index);
14760   mp->is_ipv6 = ipv6_set;
14761   S (mp);
14762
14763   /* Use a control ping for synchronization */
14764   MPING (CONTROL_PING, mp_ping);
14765   S (mp_ping);
14766
14767   W (ret);
14768   return ret;
14769 }
14770
14771 static int
14772 api_ip_dump (vat_main_t * vam)
14773 {
14774   vl_api_ip_dump_t *mp;
14775   vl_api_control_ping_t *mp_ping;
14776   unformat_input_t *in = vam->input;
14777   int ipv4_set = 0;
14778   int ipv6_set = 0;
14779   int is_ipv6;
14780   int i;
14781   int ret;
14782
14783   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14784     {
14785       if (unformat (in, "ipv4"))
14786         ipv4_set = 1;
14787       else if (unformat (in, "ipv6"))
14788         ipv6_set = 1;
14789       else
14790         break;
14791     }
14792
14793   if (ipv4_set && ipv6_set)
14794     {
14795       errmsg ("ipv4 and ipv6 flags cannot be both set");
14796       return -99;
14797     }
14798
14799   if ((!ipv4_set) && (!ipv6_set))
14800     {
14801       errmsg ("no ipv4 nor ipv6 flag set");
14802       return -99;
14803     }
14804
14805   is_ipv6 = ipv6_set;
14806   vam->is_ipv6 = is_ipv6;
14807
14808   /* free old data */
14809   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14810     {
14811       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14812     }
14813   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14814
14815   M (IP_DUMP, mp);
14816   mp->is_ipv6 = ipv6_set;
14817   S (mp);
14818
14819   /* Use a control ping for synchronization */
14820   MPING (CONTROL_PING, mp_ping);
14821   S (mp_ping);
14822
14823   W (ret);
14824   return ret;
14825 }
14826
14827 static int
14828 api_ipsec_spd_add_del (vat_main_t * vam)
14829 {
14830   unformat_input_t *i = vam->input;
14831   vl_api_ipsec_spd_add_del_t *mp;
14832   u32 spd_id = ~0;
14833   u8 is_add = 1;
14834   int ret;
14835
14836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14837     {
14838       if (unformat (i, "spd_id %d", &spd_id))
14839         ;
14840       else if (unformat (i, "del"))
14841         is_add = 0;
14842       else
14843         {
14844           clib_warning ("parse error '%U'", format_unformat_error, i);
14845           return -99;
14846         }
14847     }
14848   if (spd_id == ~0)
14849     {
14850       errmsg ("spd_id must be set");
14851       return -99;
14852     }
14853
14854   M (IPSEC_SPD_ADD_DEL, mp);
14855
14856   mp->spd_id = ntohl (spd_id);
14857   mp->is_add = is_add;
14858
14859   S (mp);
14860   W (ret);
14861   return ret;
14862 }
14863
14864 static int
14865 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14866 {
14867   unformat_input_t *i = vam->input;
14868   vl_api_ipsec_interface_add_del_spd_t *mp;
14869   u32 sw_if_index;
14870   u8 sw_if_index_set = 0;
14871   u32 spd_id = (u32) ~ 0;
14872   u8 is_add = 1;
14873   int ret;
14874
14875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14876     {
14877       if (unformat (i, "del"))
14878         is_add = 0;
14879       else if (unformat (i, "spd_id %d", &spd_id))
14880         ;
14881       else
14882         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14883         sw_if_index_set = 1;
14884       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14885         sw_if_index_set = 1;
14886       else
14887         {
14888           clib_warning ("parse error '%U'", format_unformat_error, i);
14889           return -99;
14890         }
14891
14892     }
14893
14894   if (spd_id == (u32) ~ 0)
14895     {
14896       errmsg ("spd_id must be set");
14897       return -99;
14898     }
14899
14900   if (sw_if_index_set == 0)
14901     {
14902       errmsg ("missing interface name or sw_if_index");
14903       return -99;
14904     }
14905
14906   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14907
14908   mp->spd_id = ntohl (spd_id);
14909   mp->sw_if_index = ntohl (sw_if_index);
14910   mp->is_add = is_add;
14911
14912   S (mp);
14913   W (ret);
14914   return ret;
14915 }
14916
14917 static int
14918 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14919 {
14920   unformat_input_t *i = vam->input;
14921   vl_api_ipsec_spd_add_del_entry_t *mp;
14922   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14923   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14924   i32 priority = 0;
14925   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14926   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14927   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14928   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14929   int ret;
14930
14931   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14932   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14933   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14934   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14935   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14936   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14937
14938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14939     {
14940       if (unformat (i, "del"))
14941         is_add = 0;
14942       if (unformat (i, "outbound"))
14943         is_outbound = 1;
14944       if (unformat (i, "inbound"))
14945         is_outbound = 0;
14946       else if (unformat (i, "spd_id %d", &spd_id))
14947         ;
14948       else if (unformat (i, "sa_id %d", &sa_id))
14949         ;
14950       else if (unformat (i, "priority %d", &priority))
14951         ;
14952       else if (unformat (i, "protocol %d", &protocol))
14953         ;
14954       else if (unformat (i, "lport_start %d", &lport_start))
14955         ;
14956       else if (unformat (i, "lport_stop %d", &lport_stop))
14957         ;
14958       else if (unformat (i, "rport_start %d", &rport_start))
14959         ;
14960       else if (unformat (i, "rport_stop %d", &rport_stop))
14961         ;
14962       else
14963         if (unformat
14964             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14965         {
14966           is_ipv6 = 0;
14967           is_ip_any = 0;
14968         }
14969       else
14970         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14971         {
14972           is_ipv6 = 0;
14973           is_ip_any = 0;
14974         }
14975       else
14976         if (unformat
14977             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14978         {
14979           is_ipv6 = 0;
14980           is_ip_any = 0;
14981         }
14982       else
14983         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14984         {
14985           is_ipv6 = 0;
14986           is_ip_any = 0;
14987         }
14988       else
14989         if (unformat
14990             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14991         {
14992           is_ipv6 = 1;
14993           is_ip_any = 0;
14994         }
14995       else
14996         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14997         {
14998           is_ipv6 = 1;
14999           is_ip_any = 0;
15000         }
15001       else
15002         if (unformat
15003             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15004         {
15005           is_ipv6 = 1;
15006           is_ip_any = 0;
15007         }
15008       else
15009         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15010         {
15011           is_ipv6 = 1;
15012           is_ip_any = 0;
15013         }
15014       else
15015         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15016         {
15017           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15018             {
15019               clib_warning ("unsupported action: 'resolve'");
15020               return -99;
15021             }
15022         }
15023       else
15024         {
15025           clib_warning ("parse error '%U'", format_unformat_error, i);
15026           return -99;
15027         }
15028
15029     }
15030
15031   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15032
15033   mp->spd_id = ntohl (spd_id);
15034   mp->priority = ntohl (priority);
15035   mp->is_outbound = is_outbound;
15036
15037   mp->is_ipv6 = is_ipv6;
15038   if (is_ipv6 || is_ip_any)
15039     {
15040       clib_memcpy (mp->remote_address_start, &raddr6_start,
15041                    sizeof (ip6_address_t));
15042       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15043                    sizeof (ip6_address_t));
15044       clib_memcpy (mp->local_address_start, &laddr6_start,
15045                    sizeof (ip6_address_t));
15046       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15047                    sizeof (ip6_address_t));
15048     }
15049   else
15050     {
15051       clib_memcpy (mp->remote_address_start, &raddr4_start,
15052                    sizeof (ip4_address_t));
15053       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15054                    sizeof (ip4_address_t));
15055       clib_memcpy (mp->local_address_start, &laddr4_start,
15056                    sizeof (ip4_address_t));
15057       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15058                    sizeof (ip4_address_t));
15059     }
15060   mp->protocol = (u8) protocol;
15061   mp->local_port_start = ntohs ((u16) lport_start);
15062   mp->local_port_stop = ntohs ((u16) lport_stop);
15063   mp->remote_port_start = ntohs ((u16) rport_start);
15064   mp->remote_port_stop = ntohs ((u16) rport_stop);
15065   mp->policy = (u8) policy;
15066   mp->sa_id = ntohl (sa_id);
15067   mp->is_add = is_add;
15068   mp->is_ip_any = is_ip_any;
15069   S (mp);
15070   W (ret);
15071   return ret;
15072 }
15073
15074 static int
15075 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15076 {
15077   unformat_input_t *i = vam->input;
15078   vl_api_ipsec_sad_add_del_entry_t *mp;
15079   u32 sad_id = 0, spi = 0;
15080   u8 *ck = 0, *ik = 0;
15081   u8 is_add = 1;
15082
15083   u8 protocol = IPSEC_PROTOCOL_AH;
15084   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15085   u32 crypto_alg = 0, integ_alg = 0;
15086   ip4_address_t tun_src4;
15087   ip4_address_t tun_dst4;
15088   ip6_address_t tun_src6;
15089   ip6_address_t tun_dst6;
15090   int ret;
15091
15092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15093     {
15094       if (unformat (i, "del"))
15095         is_add = 0;
15096       else if (unformat (i, "sad_id %d", &sad_id))
15097         ;
15098       else if (unformat (i, "spi %d", &spi))
15099         ;
15100       else if (unformat (i, "esp"))
15101         protocol = IPSEC_PROTOCOL_ESP;
15102       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15103         {
15104           is_tunnel = 1;
15105           is_tunnel_ipv6 = 0;
15106         }
15107       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15108         {
15109           is_tunnel = 1;
15110           is_tunnel_ipv6 = 0;
15111         }
15112       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15113         {
15114           is_tunnel = 1;
15115           is_tunnel_ipv6 = 1;
15116         }
15117       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15118         {
15119           is_tunnel = 1;
15120           is_tunnel_ipv6 = 1;
15121         }
15122       else
15123         if (unformat
15124             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15125         {
15126           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15127               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15128             {
15129               clib_warning ("unsupported crypto-alg: '%U'",
15130                             format_ipsec_crypto_alg, crypto_alg);
15131               return -99;
15132             }
15133         }
15134       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15135         ;
15136       else
15137         if (unformat
15138             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15139         {
15140           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15141               integ_alg >= IPSEC_INTEG_N_ALG)
15142             {
15143               clib_warning ("unsupported integ-alg: '%U'",
15144                             format_ipsec_integ_alg, integ_alg);
15145               return -99;
15146             }
15147         }
15148       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15149         ;
15150       else
15151         {
15152           clib_warning ("parse error '%U'", format_unformat_error, i);
15153           return -99;
15154         }
15155
15156     }
15157
15158   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15159
15160   mp->sad_id = ntohl (sad_id);
15161   mp->is_add = is_add;
15162   mp->protocol = protocol;
15163   mp->spi = ntohl (spi);
15164   mp->is_tunnel = is_tunnel;
15165   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15166   mp->crypto_algorithm = crypto_alg;
15167   mp->integrity_algorithm = integ_alg;
15168   mp->crypto_key_length = vec_len (ck);
15169   mp->integrity_key_length = vec_len (ik);
15170
15171   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15172     mp->crypto_key_length = sizeof (mp->crypto_key);
15173
15174   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15175     mp->integrity_key_length = sizeof (mp->integrity_key);
15176
15177   if (ck)
15178     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15179   if (ik)
15180     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15181
15182   if (is_tunnel)
15183     {
15184       if (is_tunnel_ipv6)
15185         {
15186           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15187                        sizeof (ip6_address_t));
15188           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15189                        sizeof (ip6_address_t));
15190         }
15191       else
15192         {
15193           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15194                        sizeof (ip4_address_t));
15195           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15196                        sizeof (ip4_address_t));
15197         }
15198     }
15199
15200   S (mp);
15201   W (ret);
15202   return ret;
15203 }
15204
15205 static int
15206 api_ipsec_sa_set_key (vat_main_t * vam)
15207 {
15208   unformat_input_t *i = vam->input;
15209   vl_api_ipsec_sa_set_key_t *mp;
15210   u32 sa_id;
15211   u8 *ck = 0, *ik = 0;
15212   int ret;
15213
15214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15215     {
15216       if (unformat (i, "sa_id %d", &sa_id))
15217         ;
15218       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15219         ;
15220       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15221         ;
15222       else
15223         {
15224           clib_warning ("parse error '%U'", format_unformat_error, i);
15225           return -99;
15226         }
15227     }
15228
15229   M (IPSEC_SA_SET_KEY, mp);
15230
15231   mp->sa_id = ntohl (sa_id);
15232   mp->crypto_key_length = vec_len (ck);
15233   mp->integrity_key_length = vec_len (ik);
15234
15235   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15236     mp->crypto_key_length = sizeof (mp->crypto_key);
15237
15238   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15239     mp->integrity_key_length = sizeof (mp->integrity_key);
15240
15241   if (ck)
15242     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15243   if (ik)
15244     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15245
15246   S (mp);
15247   W (ret);
15248   return ret;
15249 }
15250
15251 static int
15252 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15253 {
15254   unformat_input_t *i = vam->input;
15255   vl_api_ipsec_tunnel_if_add_del_t *mp;
15256   u32 local_spi = 0, remote_spi = 0;
15257   u32 crypto_alg = 0, integ_alg = 0;
15258   u8 *lck = NULL, *rck = NULL;
15259   u8 *lik = NULL, *rik = NULL;
15260   ip4_address_t local_ip = { {0} };
15261   ip4_address_t remote_ip = { {0} };
15262   u8 is_add = 1;
15263   u8 esn = 0;
15264   u8 anti_replay = 0;
15265   u8 renumber = 0;
15266   u32 instance = ~0;
15267   int ret;
15268
15269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15270     {
15271       if (unformat (i, "del"))
15272         is_add = 0;
15273       else if (unformat (i, "esn"))
15274         esn = 1;
15275       else if (unformat (i, "anti_replay"))
15276         anti_replay = 1;
15277       else if (unformat (i, "local_spi %d", &local_spi))
15278         ;
15279       else if (unformat (i, "remote_spi %d", &remote_spi))
15280         ;
15281       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15282         ;
15283       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15284         ;
15285       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15286         ;
15287       else
15288         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15289         ;
15290       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15291         ;
15292       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15293         ;
15294       else
15295         if (unformat
15296             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15297         {
15298           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15299               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15300             {
15301               errmsg ("unsupported crypto-alg: '%U'\n",
15302                       format_ipsec_crypto_alg, crypto_alg);
15303               return -99;
15304             }
15305         }
15306       else
15307         if (unformat
15308             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15309         {
15310           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15311               integ_alg >= IPSEC_INTEG_N_ALG)
15312             {
15313               errmsg ("unsupported integ-alg: '%U'\n",
15314                       format_ipsec_integ_alg, integ_alg);
15315               return -99;
15316             }
15317         }
15318       else if (unformat (i, "instance %u", &instance))
15319         renumber = 1;
15320       else
15321         {
15322           errmsg ("parse error '%U'\n", format_unformat_error, i);
15323           return -99;
15324         }
15325     }
15326
15327   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15328
15329   mp->is_add = is_add;
15330   mp->esn = esn;
15331   mp->anti_replay = anti_replay;
15332
15333   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15334   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15335
15336   mp->local_spi = htonl (local_spi);
15337   mp->remote_spi = htonl (remote_spi);
15338   mp->crypto_alg = (u8) crypto_alg;
15339
15340   mp->local_crypto_key_len = 0;
15341   if (lck)
15342     {
15343       mp->local_crypto_key_len = vec_len (lck);
15344       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15345         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15346       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15347     }
15348
15349   mp->remote_crypto_key_len = 0;
15350   if (rck)
15351     {
15352       mp->remote_crypto_key_len = vec_len (rck);
15353       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15354         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15355       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15356     }
15357
15358   mp->integ_alg = (u8) integ_alg;
15359
15360   mp->local_integ_key_len = 0;
15361   if (lik)
15362     {
15363       mp->local_integ_key_len = vec_len (lik);
15364       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15365         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15366       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15367     }
15368
15369   mp->remote_integ_key_len = 0;
15370   if (rik)
15371     {
15372       mp->remote_integ_key_len = vec_len (rik);
15373       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15374         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15375       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15376     }
15377
15378   if (renumber)
15379     {
15380       mp->renumber = renumber;
15381       mp->show_instance = ntohl (instance);
15382     }
15383
15384   S (mp);
15385   W (ret);
15386   return ret;
15387 }
15388
15389 static void
15390 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15391 {
15392   vat_main_t *vam = &vat_main;
15393
15394   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15395          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15396          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15397          "tunnel_src_addr %U tunnel_dst_addr %U "
15398          "salt %u seq_outbound %lu last_seq_inbound %lu "
15399          "replay_window %lu total_data_size %lu\n",
15400          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15401          mp->protocol,
15402          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15403          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15404          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15405          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15406          mp->tunnel_src_addr,
15407          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15408          mp->tunnel_dst_addr,
15409          ntohl (mp->salt),
15410          clib_net_to_host_u64 (mp->seq_outbound),
15411          clib_net_to_host_u64 (mp->last_seq_inbound),
15412          clib_net_to_host_u64 (mp->replay_window),
15413          clib_net_to_host_u64 (mp->total_data_size));
15414 }
15415
15416 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15417 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15418
15419 static void vl_api_ipsec_sa_details_t_handler_json
15420   (vl_api_ipsec_sa_details_t * mp)
15421 {
15422   vat_main_t *vam = &vat_main;
15423   vat_json_node_t *node = NULL;
15424   struct in_addr src_ip4, dst_ip4;
15425   struct in6_addr src_ip6, dst_ip6;
15426
15427   if (VAT_JSON_ARRAY != vam->json_tree.type)
15428     {
15429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15430       vat_json_init_array (&vam->json_tree);
15431     }
15432   node = vat_json_array_add (&vam->json_tree);
15433
15434   vat_json_init_object (node);
15435   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15436   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15437   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15438   vat_json_object_add_uint (node, "proto", mp->protocol);
15439   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15440   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15441   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15442   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15443   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15444   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15445   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15446                              mp->crypto_key_len);
15447   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15448                              mp->integ_key_len);
15449   if (mp->is_tunnel_ip6)
15450     {
15451       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15452       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15453       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15454       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15455     }
15456   else
15457     {
15458       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15459       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15460       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15461       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15462     }
15463   vat_json_object_add_uint (node, "replay_window",
15464                             clib_net_to_host_u64 (mp->replay_window));
15465   vat_json_object_add_uint (node, "total_data_size",
15466                             clib_net_to_host_u64 (mp->total_data_size));
15467
15468 }
15469
15470 static int
15471 api_ipsec_sa_dump (vat_main_t * vam)
15472 {
15473   unformat_input_t *i = vam->input;
15474   vl_api_ipsec_sa_dump_t *mp;
15475   vl_api_control_ping_t *mp_ping;
15476   u32 sa_id = ~0;
15477   int ret;
15478
15479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15480     {
15481       if (unformat (i, "sa_id %d", &sa_id))
15482         ;
15483       else
15484         {
15485           clib_warning ("parse error '%U'", format_unformat_error, i);
15486           return -99;
15487         }
15488     }
15489
15490   M (IPSEC_SA_DUMP, mp);
15491
15492   mp->sa_id = ntohl (sa_id);
15493
15494   S (mp);
15495
15496   /* Use a control ping for synchronization */
15497   M (CONTROL_PING, mp_ping);
15498   S (mp_ping);
15499
15500   W (ret);
15501   return ret;
15502 }
15503
15504 static int
15505 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15506 {
15507   unformat_input_t *i = vam->input;
15508   vl_api_ipsec_tunnel_if_set_key_t *mp;
15509   u32 sw_if_index = ~0;
15510   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15511   u8 *key = 0;
15512   u32 alg = ~0;
15513   int ret;
15514
15515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15516     {
15517       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15518         ;
15519       else
15520         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15521         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15522       else
15523         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15524         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15525       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15526         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15527       else
15528         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15529         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15530       else if (unformat (i, "%U", unformat_hex_string, &key))
15531         ;
15532       else
15533         {
15534           clib_warning ("parse error '%U'", format_unformat_error, i);
15535           return -99;
15536         }
15537     }
15538
15539   if (sw_if_index == ~0)
15540     {
15541       errmsg ("interface must be specified");
15542       return -99;
15543     }
15544
15545   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15546     {
15547       errmsg ("key type must be specified");
15548       return -99;
15549     }
15550
15551   if (alg == ~0)
15552     {
15553       errmsg ("algorithm must be specified");
15554       return -99;
15555     }
15556
15557   if (vec_len (key) == 0)
15558     {
15559       errmsg ("key must be specified");
15560       return -99;
15561     }
15562
15563   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15564
15565   mp->sw_if_index = htonl (sw_if_index);
15566   mp->alg = alg;
15567   mp->key_type = key_type;
15568   mp->key_len = vec_len (key);
15569   clib_memcpy (mp->key, key, vec_len (key));
15570
15571   S (mp);
15572   W (ret);
15573
15574   return ret;
15575 }
15576
15577 static int
15578 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15579 {
15580   unformat_input_t *i = vam->input;
15581   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15582   u32 sw_if_index = ~0;
15583   u32 sa_id = ~0;
15584   u8 is_outbound = (u8) ~ 0;
15585   int ret;
15586
15587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15588     {
15589       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15590         ;
15591       else if (unformat (i, "sa_id %d", &sa_id))
15592         ;
15593       else if (unformat (i, "outbound"))
15594         is_outbound = 1;
15595       else if (unformat (i, "inbound"))
15596         is_outbound = 0;
15597       else
15598         {
15599           clib_warning ("parse error '%U'", format_unformat_error, i);
15600           return -99;
15601         }
15602     }
15603
15604   if (sw_if_index == ~0)
15605     {
15606       errmsg ("interface must be specified");
15607       return -99;
15608     }
15609
15610   if (sa_id == ~0)
15611     {
15612       errmsg ("SA ID must be specified");
15613       return -99;
15614     }
15615
15616   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15617
15618   mp->sw_if_index = htonl (sw_if_index);
15619   mp->sa_id = htonl (sa_id);
15620   mp->is_outbound = is_outbound;
15621
15622   S (mp);
15623   W (ret);
15624
15625   return ret;
15626 }
15627
15628 static int
15629 api_ikev2_profile_add_del (vat_main_t * vam)
15630 {
15631   unformat_input_t *i = vam->input;
15632   vl_api_ikev2_profile_add_del_t *mp;
15633   u8 is_add = 1;
15634   u8 *name = 0;
15635   int ret;
15636
15637   const char *valid_chars = "a-zA-Z0-9_";
15638
15639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15640     {
15641       if (unformat (i, "del"))
15642         is_add = 0;
15643       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15644         vec_add1 (name, 0);
15645       else
15646         {
15647           errmsg ("parse error '%U'", format_unformat_error, i);
15648           return -99;
15649         }
15650     }
15651
15652   if (!vec_len (name))
15653     {
15654       errmsg ("profile name must be specified");
15655       return -99;
15656     }
15657
15658   if (vec_len (name) > 64)
15659     {
15660       errmsg ("profile name too long");
15661       return -99;
15662     }
15663
15664   M (IKEV2_PROFILE_ADD_DEL, mp);
15665
15666   clib_memcpy (mp->name, name, vec_len (name));
15667   mp->is_add = is_add;
15668   vec_free (name);
15669
15670   S (mp);
15671   W (ret);
15672   return ret;
15673 }
15674
15675 static int
15676 api_ikev2_profile_set_auth (vat_main_t * vam)
15677 {
15678   unformat_input_t *i = vam->input;
15679   vl_api_ikev2_profile_set_auth_t *mp;
15680   u8 *name = 0;
15681   u8 *data = 0;
15682   u32 auth_method = 0;
15683   u8 is_hex = 0;
15684   int ret;
15685
15686   const char *valid_chars = "a-zA-Z0-9_";
15687
15688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15689     {
15690       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15691         vec_add1 (name, 0);
15692       else if (unformat (i, "auth_method %U",
15693                          unformat_ikev2_auth_method, &auth_method))
15694         ;
15695       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15696         is_hex = 1;
15697       else if (unformat (i, "auth_data %v", &data))
15698         ;
15699       else
15700         {
15701           errmsg ("parse error '%U'", format_unformat_error, i);
15702           return -99;
15703         }
15704     }
15705
15706   if (!vec_len (name))
15707     {
15708       errmsg ("profile name must be specified");
15709       return -99;
15710     }
15711
15712   if (vec_len (name) > 64)
15713     {
15714       errmsg ("profile name too long");
15715       return -99;
15716     }
15717
15718   if (!vec_len (data))
15719     {
15720       errmsg ("auth_data must be specified");
15721       return -99;
15722     }
15723
15724   if (!auth_method)
15725     {
15726       errmsg ("auth_method must be specified");
15727       return -99;
15728     }
15729
15730   M (IKEV2_PROFILE_SET_AUTH, mp);
15731
15732   mp->is_hex = is_hex;
15733   mp->auth_method = (u8) auth_method;
15734   mp->data_len = vec_len (data);
15735   clib_memcpy (mp->name, name, vec_len (name));
15736   clib_memcpy (mp->data, data, vec_len (data));
15737   vec_free (name);
15738   vec_free (data);
15739
15740   S (mp);
15741   W (ret);
15742   return ret;
15743 }
15744
15745 static int
15746 api_ikev2_profile_set_id (vat_main_t * vam)
15747 {
15748   unformat_input_t *i = vam->input;
15749   vl_api_ikev2_profile_set_id_t *mp;
15750   u8 *name = 0;
15751   u8 *data = 0;
15752   u8 is_local = 0;
15753   u32 id_type = 0;
15754   ip4_address_t ip4;
15755   int ret;
15756
15757   const char *valid_chars = "a-zA-Z0-9_";
15758
15759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15760     {
15761       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15762         vec_add1 (name, 0);
15763       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15764         ;
15765       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15766         {
15767           data = vec_new (u8, 4);
15768           clib_memcpy (data, ip4.as_u8, 4);
15769         }
15770       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15771         ;
15772       else if (unformat (i, "id_data %v", &data))
15773         ;
15774       else if (unformat (i, "local"))
15775         is_local = 1;
15776       else if (unformat (i, "remote"))
15777         is_local = 0;
15778       else
15779         {
15780           errmsg ("parse error '%U'", format_unformat_error, i);
15781           return -99;
15782         }
15783     }
15784
15785   if (!vec_len (name))
15786     {
15787       errmsg ("profile name must be specified");
15788       return -99;
15789     }
15790
15791   if (vec_len (name) > 64)
15792     {
15793       errmsg ("profile name too long");
15794       return -99;
15795     }
15796
15797   if (!vec_len (data))
15798     {
15799       errmsg ("id_data must be specified");
15800       return -99;
15801     }
15802
15803   if (!id_type)
15804     {
15805       errmsg ("id_type must be specified");
15806       return -99;
15807     }
15808
15809   M (IKEV2_PROFILE_SET_ID, mp);
15810
15811   mp->is_local = is_local;
15812   mp->id_type = (u8) id_type;
15813   mp->data_len = vec_len (data);
15814   clib_memcpy (mp->name, name, vec_len (name));
15815   clib_memcpy (mp->data, data, vec_len (data));
15816   vec_free (name);
15817   vec_free (data);
15818
15819   S (mp);
15820   W (ret);
15821   return ret;
15822 }
15823
15824 static int
15825 api_ikev2_profile_set_ts (vat_main_t * vam)
15826 {
15827   unformat_input_t *i = vam->input;
15828   vl_api_ikev2_profile_set_ts_t *mp;
15829   u8 *name = 0;
15830   u8 is_local = 0;
15831   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15832   ip4_address_t start_addr, end_addr;
15833
15834   const char *valid_chars = "a-zA-Z0-9_";
15835   int ret;
15836
15837   start_addr.as_u32 = 0;
15838   end_addr.as_u32 = (u32) ~ 0;
15839
15840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15841     {
15842       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15843         vec_add1 (name, 0);
15844       else if (unformat (i, "protocol %d", &proto))
15845         ;
15846       else if (unformat (i, "start_port %d", &start_port))
15847         ;
15848       else if (unformat (i, "end_port %d", &end_port))
15849         ;
15850       else
15851         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15852         ;
15853       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15854         ;
15855       else if (unformat (i, "local"))
15856         is_local = 1;
15857       else if (unformat (i, "remote"))
15858         is_local = 0;
15859       else
15860         {
15861           errmsg ("parse error '%U'", format_unformat_error, i);
15862           return -99;
15863         }
15864     }
15865
15866   if (!vec_len (name))
15867     {
15868       errmsg ("profile name must be specified");
15869       return -99;
15870     }
15871
15872   if (vec_len (name) > 64)
15873     {
15874       errmsg ("profile name too long");
15875       return -99;
15876     }
15877
15878   M (IKEV2_PROFILE_SET_TS, mp);
15879
15880   mp->is_local = is_local;
15881   mp->proto = (u8) proto;
15882   mp->start_port = (u16) start_port;
15883   mp->end_port = (u16) end_port;
15884   mp->start_addr = start_addr.as_u32;
15885   mp->end_addr = end_addr.as_u32;
15886   clib_memcpy (mp->name, name, vec_len (name));
15887   vec_free (name);
15888
15889   S (mp);
15890   W (ret);
15891   return ret;
15892 }
15893
15894 static int
15895 api_ikev2_set_local_key (vat_main_t * vam)
15896 {
15897   unformat_input_t *i = vam->input;
15898   vl_api_ikev2_set_local_key_t *mp;
15899   u8 *file = 0;
15900   int ret;
15901
15902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15903     {
15904       if (unformat (i, "file %v", &file))
15905         vec_add1 (file, 0);
15906       else
15907         {
15908           errmsg ("parse error '%U'", format_unformat_error, i);
15909           return -99;
15910         }
15911     }
15912
15913   if (!vec_len (file))
15914     {
15915       errmsg ("RSA key file must be specified");
15916       return -99;
15917     }
15918
15919   if (vec_len (file) > 256)
15920     {
15921       errmsg ("file name too long");
15922       return -99;
15923     }
15924
15925   M (IKEV2_SET_LOCAL_KEY, mp);
15926
15927   clib_memcpy (mp->key_file, file, vec_len (file));
15928   vec_free (file);
15929
15930   S (mp);
15931   W (ret);
15932   return ret;
15933 }
15934
15935 static int
15936 api_ikev2_set_responder (vat_main_t * vam)
15937 {
15938   unformat_input_t *i = vam->input;
15939   vl_api_ikev2_set_responder_t *mp;
15940   int ret;
15941   u8 *name = 0;
15942   u32 sw_if_index = ~0;
15943   ip4_address_t address;
15944
15945   const char *valid_chars = "a-zA-Z0-9_";
15946
15947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15948     {
15949       if (unformat
15950           (i, "%U interface %d address %U", unformat_token, valid_chars,
15951            &name, &sw_if_index, unformat_ip4_address, &address))
15952         vec_add1 (name, 0);
15953       else
15954         {
15955           errmsg ("parse error '%U'", format_unformat_error, i);
15956           return -99;
15957         }
15958     }
15959
15960   if (!vec_len (name))
15961     {
15962       errmsg ("profile name must be specified");
15963       return -99;
15964     }
15965
15966   if (vec_len (name) > 64)
15967     {
15968       errmsg ("profile name too long");
15969       return -99;
15970     }
15971
15972   M (IKEV2_SET_RESPONDER, mp);
15973
15974   clib_memcpy (mp->name, name, vec_len (name));
15975   vec_free (name);
15976
15977   mp->sw_if_index = sw_if_index;
15978   clib_memcpy (mp->address, &address, sizeof (address));
15979
15980   S (mp);
15981   W (ret);
15982   return ret;
15983 }
15984
15985 static int
15986 api_ikev2_set_ike_transforms (vat_main_t * vam)
15987 {
15988   unformat_input_t *i = vam->input;
15989   vl_api_ikev2_set_ike_transforms_t *mp;
15990   int ret;
15991   u8 *name = 0;
15992   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15993
15994   const char *valid_chars = "a-zA-Z0-9_";
15995
15996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15997     {
15998       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15999                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16000         vec_add1 (name, 0);
16001       else
16002         {
16003           errmsg ("parse error '%U'", format_unformat_error, i);
16004           return -99;
16005         }
16006     }
16007
16008   if (!vec_len (name))
16009     {
16010       errmsg ("profile name must be specified");
16011       return -99;
16012     }
16013
16014   if (vec_len (name) > 64)
16015     {
16016       errmsg ("profile name too long");
16017       return -99;
16018     }
16019
16020   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16021
16022   clib_memcpy (mp->name, name, vec_len (name));
16023   vec_free (name);
16024   mp->crypto_alg = crypto_alg;
16025   mp->crypto_key_size = crypto_key_size;
16026   mp->integ_alg = integ_alg;
16027   mp->dh_group = dh_group;
16028
16029   S (mp);
16030   W (ret);
16031   return ret;
16032 }
16033
16034
16035 static int
16036 api_ikev2_set_esp_transforms (vat_main_t * vam)
16037 {
16038   unformat_input_t *i = vam->input;
16039   vl_api_ikev2_set_esp_transforms_t *mp;
16040   int ret;
16041   u8 *name = 0;
16042   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16043
16044   const char *valid_chars = "a-zA-Z0-9_";
16045
16046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16047     {
16048       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16049                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16050         vec_add1 (name, 0);
16051       else
16052         {
16053           errmsg ("parse error '%U'", format_unformat_error, i);
16054           return -99;
16055         }
16056     }
16057
16058   if (!vec_len (name))
16059     {
16060       errmsg ("profile name must be specified");
16061       return -99;
16062     }
16063
16064   if (vec_len (name) > 64)
16065     {
16066       errmsg ("profile name too long");
16067       return -99;
16068     }
16069
16070   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16071
16072   clib_memcpy (mp->name, name, vec_len (name));
16073   vec_free (name);
16074   mp->crypto_alg = crypto_alg;
16075   mp->crypto_key_size = crypto_key_size;
16076   mp->integ_alg = integ_alg;
16077   mp->dh_group = dh_group;
16078
16079   S (mp);
16080   W (ret);
16081   return ret;
16082 }
16083
16084 static int
16085 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16086 {
16087   unformat_input_t *i = vam->input;
16088   vl_api_ikev2_set_sa_lifetime_t *mp;
16089   int ret;
16090   u8 *name = 0;
16091   u64 lifetime, lifetime_maxdata;
16092   u32 lifetime_jitter, handover;
16093
16094   const char *valid_chars = "a-zA-Z0-9_";
16095
16096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16097     {
16098       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16099                     &lifetime, &lifetime_jitter, &handover,
16100                     &lifetime_maxdata))
16101         vec_add1 (name, 0);
16102       else
16103         {
16104           errmsg ("parse error '%U'", format_unformat_error, i);
16105           return -99;
16106         }
16107     }
16108
16109   if (!vec_len (name))
16110     {
16111       errmsg ("profile name must be specified");
16112       return -99;
16113     }
16114
16115   if (vec_len (name) > 64)
16116     {
16117       errmsg ("profile name too long");
16118       return -99;
16119     }
16120
16121   M (IKEV2_SET_SA_LIFETIME, mp);
16122
16123   clib_memcpy (mp->name, name, vec_len (name));
16124   vec_free (name);
16125   mp->lifetime = lifetime;
16126   mp->lifetime_jitter = lifetime_jitter;
16127   mp->handover = handover;
16128   mp->lifetime_maxdata = lifetime_maxdata;
16129
16130   S (mp);
16131   W (ret);
16132   return ret;
16133 }
16134
16135 static int
16136 api_ikev2_initiate_sa_init (vat_main_t * vam)
16137 {
16138   unformat_input_t *i = vam->input;
16139   vl_api_ikev2_initiate_sa_init_t *mp;
16140   int ret;
16141   u8 *name = 0;
16142
16143   const char *valid_chars = "a-zA-Z0-9_";
16144
16145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16146     {
16147       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16148         vec_add1 (name, 0);
16149       else
16150         {
16151           errmsg ("parse error '%U'", format_unformat_error, i);
16152           return -99;
16153         }
16154     }
16155
16156   if (!vec_len (name))
16157     {
16158       errmsg ("profile name must be specified");
16159       return -99;
16160     }
16161
16162   if (vec_len (name) > 64)
16163     {
16164       errmsg ("profile name too long");
16165       return -99;
16166     }
16167
16168   M (IKEV2_INITIATE_SA_INIT, mp);
16169
16170   clib_memcpy (mp->name, name, vec_len (name));
16171   vec_free (name);
16172
16173   S (mp);
16174   W (ret);
16175   return ret;
16176 }
16177
16178 static int
16179 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16180 {
16181   unformat_input_t *i = vam->input;
16182   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16183   int ret;
16184   u64 ispi;
16185
16186
16187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16188     {
16189       if (unformat (i, "%lx", &ispi))
16190         ;
16191       else
16192         {
16193           errmsg ("parse error '%U'", format_unformat_error, i);
16194           return -99;
16195         }
16196     }
16197
16198   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16199
16200   mp->ispi = ispi;
16201
16202   S (mp);
16203   W (ret);
16204   return ret;
16205 }
16206
16207 static int
16208 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16209 {
16210   unformat_input_t *i = vam->input;
16211   vl_api_ikev2_initiate_del_child_sa_t *mp;
16212   int ret;
16213   u32 ispi;
16214
16215
16216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16217     {
16218       if (unformat (i, "%x", &ispi))
16219         ;
16220       else
16221         {
16222           errmsg ("parse error '%U'", format_unformat_error, i);
16223           return -99;
16224         }
16225     }
16226
16227   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16228
16229   mp->ispi = ispi;
16230
16231   S (mp);
16232   W (ret);
16233   return ret;
16234 }
16235
16236 static int
16237 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16238 {
16239   unformat_input_t *i = vam->input;
16240   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16241   int ret;
16242   u32 ispi;
16243
16244
16245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16246     {
16247       if (unformat (i, "%x", &ispi))
16248         ;
16249       else
16250         {
16251           errmsg ("parse error '%U'", format_unformat_error, i);
16252           return -99;
16253         }
16254     }
16255
16256   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16257
16258   mp->ispi = ispi;
16259
16260   S (mp);
16261   W (ret);
16262   return ret;
16263 }
16264
16265 /*
16266  * MAP
16267  */
16268 static int
16269 api_map_add_domain (vat_main_t * vam)
16270 {
16271   unformat_input_t *i = vam->input;
16272   vl_api_map_add_domain_t *mp;
16273
16274   ip4_address_t ip4_prefix;
16275   ip6_address_t ip6_prefix;
16276   ip6_address_t ip6_src;
16277   u32 num_m_args = 0;
16278   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16279     0, psid_length = 0;
16280   u8 is_translation = 0;
16281   u32 mtu = 0;
16282   u32 ip6_src_len = 128;
16283   int ret;
16284
16285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16286     {
16287       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16288                     &ip4_prefix, &ip4_prefix_len))
16289         num_m_args++;
16290       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16291                          &ip6_prefix, &ip6_prefix_len))
16292         num_m_args++;
16293       else
16294         if (unformat
16295             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16296              &ip6_src_len))
16297         num_m_args++;
16298       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16299         num_m_args++;
16300       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16301         num_m_args++;
16302       else if (unformat (i, "psid-offset %d", &psid_offset))
16303         num_m_args++;
16304       else if (unformat (i, "psid-len %d", &psid_length))
16305         num_m_args++;
16306       else if (unformat (i, "mtu %d", &mtu))
16307         num_m_args++;
16308       else if (unformat (i, "map-t"))
16309         is_translation = 1;
16310       else
16311         {
16312           clib_warning ("parse error '%U'", format_unformat_error, i);
16313           return -99;
16314         }
16315     }
16316
16317   if (num_m_args < 3)
16318     {
16319       errmsg ("mandatory argument(s) missing");
16320       return -99;
16321     }
16322
16323   /* Construct the API message */
16324   M (MAP_ADD_DOMAIN, mp);
16325
16326   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16327   mp->ip4_prefix_len = ip4_prefix_len;
16328
16329   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16330   mp->ip6_prefix_len = ip6_prefix_len;
16331
16332   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16333   mp->ip6_src_prefix_len = ip6_src_len;
16334
16335   mp->ea_bits_len = ea_bits_len;
16336   mp->psid_offset = psid_offset;
16337   mp->psid_length = psid_length;
16338   mp->is_translation = is_translation;
16339   mp->mtu = htons (mtu);
16340
16341   /* send it... */
16342   S (mp);
16343
16344   /* Wait for a reply, return good/bad news  */
16345   W (ret);
16346   return ret;
16347 }
16348
16349 static int
16350 api_map_del_domain (vat_main_t * vam)
16351 {
16352   unformat_input_t *i = vam->input;
16353   vl_api_map_del_domain_t *mp;
16354
16355   u32 num_m_args = 0;
16356   u32 index;
16357   int ret;
16358
16359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16360     {
16361       if (unformat (i, "index %d", &index))
16362         num_m_args++;
16363       else
16364         {
16365           clib_warning ("parse error '%U'", format_unformat_error, i);
16366           return -99;
16367         }
16368     }
16369
16370   if (num_m_args != 1)
16371     {
16372       errmsg ("mandatory argument(s) missing");
16373       return -99;
16374     }
16375
16376   /* Construct the API message */
16377   M (MAP_DEL_DOMAIN, mp);
16378
16379   mp->index = ntohl (index);
16380
16381   /* send it... */
16382   S (mp);
16383
16384   /* Wait for a reply, return good/bad news  */
16385   W (ret);
16386   return ret;
16387 }
16388
16389 static int
16390 api_map_add_del_rule (vat_main_t * vam)
16391 {
16392   unformat_input_t *i = vam->input;
16393   vl_api_map_add_del_rule_t *mp;
16394   u8 is_add = 1;
16395   ip6_address_t ip6_dst;
16396   u32 num_m_args = 0, index, psid = 0;
16397   int ret;
16398
16399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16400     {
16401       if (unformat (i, "index %d", &index))
16402         num_m_args++;
16403       else if (unformat (i, "psid %d", &psid))
16404         num_m_args++;
16405       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16406         num_m_args++;
16407       else if (unformat (i, "del"))
16408         {
16409           is_add = 0;
16410         }
16411       else
16412         {
16413           clib_warning ("parse error '%U'", format_unformat_error, i);
16414           return -99;
16415         }
16416     }
16417
16418   /* Construct the API message */
16419   M (MAP_ADD_DEL_RULE, mp);
16420
16421   mp->index = ntohl (index);
16422   mp->is_add = is_add;
16423   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16424   mp->psid = ntohs (psid);
16425
16426   /* send it... */
16427   S (mp);
16428
16429   /* Wait for a reply, return good/bad news  */
16430   W (ret);
16431   return ret;
16432 }
16433
16434 static int
16435 api_map_domain_dump (vat_main_t * vam)
16436 {
16437   vl_api_map_domain_dump_t *mp;
16438   vl_api_control_ping_t *mp_ping;
16439   int ret;
16440
16441   /* Construct the API message */
16442   M (MAP_DOMAIN_DUMP, mp);
16443
16444   /* send it... */
16445   S (mp);
16446
16447   /* Use a control ping for synchronization */
16448   MPING (CONTROL_PING, mp_ping);
16449   S (mp_ping);
16450
16451   W (ret);
16452   return ret;
16453 }
16454
16455 static int
16456 api_map_rule_dump (vat_main_t * vam)
16457 {
16458   unformat_input_t *i = vam->input;
16459   vl_api_map_rule_dump_t *mp;
16460   vl_api_control_ping_t *mp_ping;
16461   u32 domain_index = ~0;
16462   int ret;
16463
16464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16465     {
16466       if (unformat (i, "index %u", &domain_index))
16467         ;
16468       else
16469         break;
16470     }
16471
16472   if (domain_index == ~0)
16473     {
16474       clib_warning ("parse error: domain index expected");
16475       return -99;
16476     }
16477
16478   /* Construct the API message */
16479   M (MAP_RULE_DUMP, mp);
16480
16481   mp->domain_index = htonl (domain_index);
16482
16483   /* send it... */
16484   S (mp);
16485
16486   /* Use a control ping for synchronization */
16487   MPING (CONTROL_PING, mp_ping);
16488   S (mp_ping);
16489
16490   W (ret);
16491   return ret;
16492 }
16493
16494 static void vl_api_map_add_domain_reply_t_handler
16495   (vl_api_map_add_domain_reply_t * mp)
16496 {
16497   vat_main_t *vam = &vat_main;
16498   i32 retval = ntohl (mp->retval);
16499
16500   if (vam->async_mode)
16501     {
16502       vam->async_errors += (retval < 0);
16503     }
16504   else
16505     {
16506       vam->retval = retval;
16507       vam->result_ready = 1;
16508     }
16509 }
16510
16511 static void vl_api_map_add_domain_reply_t_handler_json
16512   (vl_api_map_add_domain_reply_t * mp)
16513 {
16514   vat_main_t *vam = &vat_main;
16515   vat_json_node_t node;
16516
16517   vat_json_init_object (&node);
16518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16519   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16520
16521   vat_json_print (vam->ofp, &node);
16522   vat_json_free (&node);
16523
16524   vam->retval = ntohl (mp->retval);
16525   vam->result_ready = 1;
16526 }
16527
16528 static int
16529 api_get_first_msg_id (vat_main_t * vam)
16530 {
16531   vl_api_get_first_msg_id_t *mp;
16532   unformat_input_t *i = vam->input;
16533   u8 *name;
16534   u8 name_set = 0;
16535   int ret;
16536
16537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16538     {
16539       if (unformat (i, "client %s", &name))
16540         name_set = 1;
16541       else
16542         break;
16543     }
16544
16545   if (name_set == 0)
16546     {
16547       errmsg ("missing client name");
16548       return -99;
16549     }
16550   vec_add1 (name, 0);
16551
16552   if (vec_len (name) > 63)
16553     {
16554       errmsg ("client name too long");
16555       return -99;
16556     }
16557
16558   M (GET_FIRST_MSG_ID, mp);
16559   clib_memcpy (mp->name, name, vec_len (name));
16560   S (mp);
16561   W (ret);
16562   return ret;
16563 }
16564
16565 static int
16566 api_cop_interface_enable_disable (vat_main_t * vam)
16567 {
16568   unformat_input_t *line_input = vam->input;
16569   vl_api_cop_interface_enable_disable_t *mp;
16570   u32 sw_if_index = ~0;
16571   u8 enable_disable = 1;
16572   int ret;
16573
16574   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16575     {
16576       if (unformat (line_input, "disable"))
16577         enable_disable = 0;
16578       if (unformat (line_input, "enable"))
16579         enable_disable = 1;
16580       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16581                          vam, &sw_if_index))
16582         ;
16583       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16584         ;
16585       else
16586         break;
16587     }
16588
16589   if (sw_if_index == ~0)
16590     {
16591       errmsg ("missing interface name or sw_if_index");
16592       return -99;
16593     }
16594
16595   /* Construct the API message */
16596   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16597   mp->sw_if_index = ntohl (sw_if_index);
16598   mp->enable_disable = enable_disable;
16599
16600   /* send it... */
16601   S (mp);
16602   /* Wait for the reply */
16603   W (ret);
16604   return ret;
16605 }
16606
16607 static int
16608 api_cop_whitelist_enable_disable (vat_main_t * vam)
16609 {
16610   unformat_input_t *line_input = vam->input;
16611   vl_api_cop_whitelist_enable_disable_t *mp;
16612   u32 sw_if_index = ~0;
16613   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16614   u32 fib_id = 0;
16615   int ret;
16616
16617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16618     {
16619       if (unformat (line_input, "ip4"))
16620         ip4 = 1;
16621       else if (unformat (line_input, "ip6"))
16622         ip6 = 1;
16623       else if (unformat (line_input, "default"))
16624         default_cop = 1;
16625       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16626                          vam, &sw_if_index))
16627         ;
16628       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16629         ;
16630       else if (unformat (line_input, "fib-id %d", &fib_id))
16631         ;
16632       else
16633         break;
16634     }
16635
16636   if (sw_if_index == ~0)
16637     {
16638       errmsg ("missing interface name or sw_if_index");
16639       return -99;
16640     }
16641
16642   /* Construct the API message */
16643   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16644   mp->sw_if_index = ntohl (sw_if_index);
16645   mp->fib_id = ntohl (fib_id);
16646   mp->ip4 = ip4;
16647   mp->ip6 = ip6;
16648   mp->default_cop = default_cop;
16649
16650   /* send it... */
16651   S (mp);
16652   /* Wait for the reply */
16653   W (ret);
16654   return ret;
16655 }
16656
16657 static int
16658 api_get_node_graph (vat_main_t * vam)
16659 {
16660   vl_api_get_node_graph_t *mp;
16661   int ret;
16662
16663   M (GET_NODE_GRAPH, mp);
16664
16665   /* send it... */
16666   S (mp);
16667   /* Wait for the reply */
16668   W (ret);
16669   return ret;
16670 }
16671
16672 /* *INDENT-OFF* */
16673 /** Used for parsing LISP eids */
16674 typedef CLIB_PACKED(struct{
16675   u8 addr[16];   /**< eid address */
16676   u32 len;       /**< prefix length if IP */
16677   u8 type;      /**< type of eid */
16678 }) lisp_eid_vat_t;
16679 /* *INDENT-ON* */
16680
16681 static uword
16682 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16683 {
16684   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16685
16686   memset (a, 0, sizeof (a[0]));
16687
16688   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16689     {
16690       a->type = 0;              /* ipv4 type */
16691     }
16692   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16693     {
16694       a->type = 1;              /* ipv6 type */
16695     }
16696   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16697     {
16698       a->type = 2;              /* mac type */
16699     }
16700   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16701     {
16702       a->type = 3;              /* NSH type */
16703       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16704       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16705     }
16706   else
16707     {
16708       return 0;
16709     }
16710
16711   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16712     {
16713       return 0;
16714     }
16715
16716   return 1;
16717 }
16718
16719 static int
16720 lisp_eid_size_vat (u8 type)
16721 {
16722   switch (type)
16723     {
16724     case 0:
16725       return 4;
16726     case 1:
16727       return 16;
16728     case 2:
16729       return 6;
16730     case 3:
16731       return 5;
16732     }
16733   return 0;
16734 }
16735
16736 static void
16737 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16738 {
16739   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16740 }
16741
16742 static int
16743 api_one_add_del_locator_set (vat_main_t * vam)
16744 {
16745   unformat_input_t *input = vam->input;
16746   vl_api_one_add_del_locator_set_t *mp;
16747   u8 is_add = 1;
16748   u8 *locator_set_name = NULL;
16749   u8 locator_set_name_set = 0;
16750   vl_api_local_locator_t locator, *locators = 0;
16751   u32 sw_if_index, priority, weight;
16752   u32 data_len = 0;
16753
16754   int ret;
16755   /* Parse args required to build the message */
16756   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16757     {
16758       if (unformat (input, "del"))
16759         {
16760           is_add = 0;
16761         }
16762       else if (unformat (input, "locator-set %s", &locator_set_name))
16763         {
16764           locator_set_name_set = 1;
16765         }
16766       else if (unformat (input, "sw_if_index %u p %u w %u",
16767                          &sw_if_index, &priority, &weight))
16768         {
16769           locator.sw_if_index = htonl (sw_if_index);
16770           locator.priority = priority;
16771           locator.weight = weight;
16772           vec_add1 (locators, locator);
16773         }
16774       else
16775         if (unformat
16776             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16777              &sw_if_index, &priority, &weight))
16778         {
16779           locator.sw_if_index = htonl (sw_if_index);
16780           locator.priority = priority;
16781           locator.weight = weight;
16782           vec_add1 (locators, locator);
16783         }
16784       else
16785         break;
16786     }
16787
16788   if (locator_set_name_set == 0)
16789     {
16790       errmsg ("missing locator-set name");
16791       vec_free (locators);
16792       return -99;
16793     }
16794
16795   if (vec_len (locator_set_name) > 64)
16796     {
16797       errmsg ("locator-set name too long");
16798       vec_free (locator_set_name);
16799       vec_free (locators);
16800       return -99;
16801     }
16802   vec_add1 (locator_set_name, 0);
16803
16804   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16805
16806   /* Construct the API message */
16807   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16808
16809   mp->is_add = is_add;
16810   clib_memcpy (mp->locator_set_name, locator_set_name,
16811                vec_len (locator_set_name));
16812   vec_free (locator_set_name);
16813
16814   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16815   if (locators)
16816     clib_memcpy (mp->locators, locators, data_len);
16817   vec_free (locators);
16818
16819   /* send it... */
16820   S (mp);
16821
16822   /* Wait for a reply... */
16823   W (ret);
16824   return ret;
16825 }
16826
16827 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16828
16829 static int
16830 api_one_add_del_locator (vat_main_t * vam)
16831 {
16832   unformat_input_t *input = vam->input;
16833   vl_api_one_add_del_locator_t *mp;
16834   u32 tmp_if_index = ~0;
16835   u32 sw_if_index = ~0;
16836   u8 sw_if_index_set = 0;
16837   u8 sw_if_index_if_name_set = 0;
16838   u32 priority = ~0;
16839   u8 priority_set = 0;
16840   u32 weight = ~0;
16841   u8 weight_set = 0;
16842   u8 is_add = 1;
16843   u8 *locator_set_name = NULL;
16844   u8 locator_set_name_set = 0;
16845   int ret;
16846
16847   /* Parse args required to build the message */
16848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16849     {
16850       if (unformat (input, "del"))
16851         {
16852           is_add = 0;
16853         }
16854       else if (unformat (input, "locator-set %s", &locator_set_name))
16855         {
16856           locator_set_name_set = 1;
16857         }
16858       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16859                          &tmp_if_index))
16860         {
16861           sw_if_index_if_name_set = 1;
16862           sw_if_index = tmp_if_index;
16863         }
16864       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16865         {
16866           sw_if_index_set = 1;
16867           sw_if_index = tmp_if_index;
16868         }
16869       else if (unformat (input, "p %d", &priority))
16870         {
16871           priority_set = 1;
16872         }
16873       else if (unformat (input, "w %d", &weight))
16874         {
16875           weight_set = 1;
16876         }
16877       else
16878         break;
16879     }
16880
16881   if (locator_set_name_set == 0)
16882     {
16883       errmsg ("missing locator-set name");
16884       return -99;
16885     }
16886
16887   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16888     {
16889       errmsg ("missing sw_if_index");
16890       vec_free (locator_set_name);
16891       return -99;
16892     }
16893
16894   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16895     {
16896       errmsg ("cannot use both params interface name and sw_if_index");
16897       vec_free (locator_set_name);
16898       return -99;
16899     }
16900
16901   if (priority_set == 0)
16902     {
16903       errmsg ("missing locator-set priority");
16904       vec_free (locator_set_name);
16905       return -99;
16906     }
16907
16908   if (weight_set == 0)
16909     {
16910       errmsg ("missing locator-set weight");
16911       vec_free (locator_set_name);
16912       return -99;
16913     }
16914
16915   if (vec_len (locator_set_name) > 64)
16916     {
16917       errmsg ("locator-set name too long");
16918       vec_free (locator_set_name);
16919       return -99;
16920     }
16921   vec_add1 (locator_set_name, 0);
16922
16923   /* Construct the API message */
16924   M (ONE_ADD_DEL_LOCATOR, mp);
16925
16926   mp->is_add = is_add;
16927   mp->sw_if_index = ntohl (sw_if_index);
16928   mp->priority = priority;
16929   mp->weight = weight;
16930   clib_memcpy (mp->locator_set_name, locator_set_name,
16931                vec_len (locator_set_name));
16932   vec_free (locator_set_name);
16933
16934   /* send it... */
16935   S (mp);
16936
16937   /* Wait for a reply... */
16938   W (ret);
16939   return ret;
16940 }
16941
16942 #define api_lisp_add_del_locator api_one_add_del_locator
16943
16944 uword
16945 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16946 {
16947   u32 *key_id = va_arg (*args, u32 *);
16948   u8 *s = 0;
16949
16950   if (unformat (input, "%s", &s))
16951     {
16952       if (!strcmp ((char *) s, "sha1"))
16953         key_id[0] = HMAC_SHA_1_96;
16954       else if (!strcmp ((char *) s, "sha256"))
16955         key_id[0] = HMAC_SHA_256_128;
16956       else
16957         {
16958           clib_warning ("invalid key_id: '%s'", s);
16959           key_id[0] = HMAC_NO_KEY;
16960         }
16961     }
16962   else
16963     return 0;
16964
16965   vec_free (s);
16966   return 1;
16967 }
16968
16969 static int
16970 api_one_add_del_local_eid (vat_main_t * vam)
16971 {
16972   unformat_input_t *input = vam->input;
16973   vl_api_one_add_del_local_eid_t *mp;
16974   u8 is_add = 1;
16975   u8 eid_set = 0;
16976   lisp_eid_vat_t _eid, *eid = &_eid;
16977   u8 *locator_set_name = 0;
16978   u8 locator_set_name_set = 0;
16979   u32 vni = 0;
16980   u16 key_id = 0;
16981   u8 *key = 0;
16982   int ret;
16983
16984   /* Parse args required to build the message */
16985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16986     {
16987       if (unformat (input, "del"))
16988         {
16989           is_add = 0;
16990         }
16991       else if (unformat (input, "vni %d", &vni))
16992         {
16993           ;
16994         }
16995       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16996         {
16997           eid_set = 1;
16998         }
16999       else if (unformat (input, "locator-set %s", &locator_set_name))
17000         {
17001           locator_set_name_set = 1;
17002         }
17003       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17004         ;
17005       else if (unformat (input, "secret-key %_%v%_", &key))
17006         ;
17007       else
17008         break;
17009     }
17010
17011   if (locator_set_name_set == 0)
17012     {
17013       errmsg ("missing locator-set name");
17014       return -99;
17015     }
17016
17017   if (0 == eid_set)
17018     {
17019       errmsg ("EID address not set!");
17020       vec_free (locator_set_name);
17021       return -99;
17022     }
17023
17024   if (key && (0 == key_id))
17025     {
17026       errmsg ("invalid key_id!");
17027       return -99;
17028     }
17029
17030   if (vec_len (key) > 64)
17031     {
17032       errmsg ("key too long");
17033       vec_free (key);
17034       return -99;
17035     }
17036
17037   if (vec_len (locator_set_name) > 64)
17038     {
17039       errmsg ("locator-set name too long");
17040       vec_free (locator_set_name);
17041       return -99;
17042     }
17043   vec_add1 (locator_set_name, 0);
17044
17045   /* Construct the API message */
17046   M (ONE_ADD_DEL_LOCAL_EID, mp);
17047
17048   mp->is_add = is_add;
17049   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17050   mp->eid_type = eid->type;
17051   mp->prefix_len = eid->len;
17052   mp->vni = clib_host_to_net_u32 (vni);
17053   mp->key_id = clib_host_to_net_u16 (key_id);
17054   clib_memcpy (mp->locator_set_name, locator_set_name,
17055                vec_len (locator_set_name));
17056   clib_memcpy (mp->key, key, vec_len (key));
17057
17058   vec_free (locator_set_name);
17059   vec_free (key);
17060
17061   /* send it... */
17062   S (mp);
17063
17064   /* Wait for a reply... */
17065   W (ret);
17066   return ret;
17067 }
17068
17069 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17070
17071 static int
17072 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17073 {
17074   u32 dp_table = 0, vni = 0;;
17075   unformat_input_t *input = vam->input;
17076   vl_api_gpe_add_del_fwd_entry_t *mp;
17077   u8 is_add = 1;
17078   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17079   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17080   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17081   u32 action = ~0, w;
17082   ip4_address_t rmt_rloc4, lcl_rloc4;
17083   ip6_address_t rmt_rloc6, lcl_rloc6;
17084   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17085   int ret;
17086
17087   memset (&rloc, 0, sizeof (rloc));
17088
17089   /* Parse args required to build the message */
17090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17091     {
17092       if (unformat (input, "del"))
17093         is_add = 0;
17094       else if (unformat (input, "add"))
17095         is_add = 1;
17096       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17097         {
17098           rmt_eid_set = 1;
17099         }
17100       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17101         {
17102           lcl_eid_set = 1;
17103         }
17104       else if (unformat (input, "vrf %d", &dp_table))
17105         ;
17106       else if (unformat (input, "bd %d", &dp_table))
17107         ;
17108       else if (unformat (input, "vni %d", &vni))
17109         ;
17110       else if (unformat (input, "w %d", &w))
17111         {
17112           if (!curr_rloc)
17113             {
17114               errmsg ("No RLOC configured for setting priority/weight!");
17115               return -99;
17116             }
17117           curr_rloc->weight = w;
17118         }
17119       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17120                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17121         {
17122           rloc.is_ip4 = 1;
17123
17124           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17125           rloc.weight = 0;
17126           vec_add1 (lcl_locs, rloc);
17127
17128           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17129           vec_add1 (rmt_locs, rloc);
17130           /* weight saved in rmt loc */
17131           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17132         }
17133       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17134                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17135         {
17136           rloc.is_ip4 = 0;
17137           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17138           rloc.weight = 0;
17139           vec_add1 (lcl_locs, rloc);
17140
17141           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17142           vec_add1 (rmt_locs, rloc);
17143           /* weight saved in rmt loc */
17144           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17145         }
17146       else if (unformat (input, "action %d", &action))
17147         {
17148           ;
17149         }
17150       else
17151         {
17152           clib_warning ("parse error '%U'", format_unformat_error, input);
17153           return -99;
17154         }
17155     }
17156
17157   if (!rmt_eid_set)
17158     {
17159       errmsg ("remote eid addresses not set");
17160       return -99;
17161     }
17162
17163   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17164     {
17165       errmsg ("eid types don't match");
17166       return -99;
17167     }
17168
17169   if (0 == rmt_locs && (u32) ~ 0 == action)
17170     {
17171       errmsg ("action not set for negative mapping");
17172       return -99;
17173     }
17174
17175   /* Construct the API message */
17176   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17177       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17178
17179   mp->is_add = is_add;
17180   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17181   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17182   mp->eid_type = rmt_eid->type;
17183   mp->dp_table = clib_host_to_net_u32 (dp_table);
17184   mp->vni = clib_host_to_net_u32 (vni);
17185   mp->rmt_len = rmt_eid->len;
17186   mp->lcl_len = lcl_eid->len;
17187   mp->action = action;
17188
17189   if (0 != rmt_locs && 0 != lcl_locs)
17190     {
17191       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17192       clib_memcpy (mp->locs, lcl_locs,
17193                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17194
17195       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17196       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17197                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17198     }
17199   vec_free (lcl_locs);
17200   vec_free (rmt_locs);
17201
17202   /* send it... */
17203   S (mp);
17204
17205   /* Wait for a reply... */
17206   W (ret);
17207   return ret;
17208 }
17209
17210 static int
17211 api_one_add_del_map_server (vat_main_t * vam)
17212 {
17213   unformat_input_t *input = vam->input;
17214   vl_api_one_add_del_map_server_t *mp;
17215   u8 is_add = 1;
17216   u8 ipv4_set = 0;
17217   u8 ipv6_set = 0;
17218   ip4_address_t ipv4;
17219   ip6_address_t ipv6;
17220   int ret;
17221
17222   /* Parse args required to build the message */
17223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17224     {
17225       if (unformat (input, "del"))
17226         {
17227           is_add = 0;
17228         }
17229       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17230         {
17231           ipv4_set = 1;
17232         }
17233       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17234         {
17235           ipv6_set = 1;
17236         }
17237       else
17238         break;
17239     }
17240
17241   if (ipv4_set && ipv6_set)
17242     {
17243       errmsg ("both eid v4 and v6 addresses set");
17244       return -99;
17245     }
17246
17247   if (!ipv4_set && !ipv6_set)
17248     {
17249       errmsg ("eid addresses not set");
17250       return -99;
17251     }
17252
17253   /* Construct the API message */
17254   M (ONE_ADD_DEL_MAP_SERVER, mp);
17255
17256   mp->is_add = is_add;
17257   if (ipv6_set)
17258     {
17259       mp->is_ipv6 = 1;
17260       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17261     }
17262   else
17263     {
17264       mp->is_ipv6 = 0;
17265       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17266     }
17267
17268   /* send it... */
17269   S (mp);
17270
17271   /* Wait for a reply... */
17272   W (ret);
17273   return ret;
17274 }
17275
17276 #define api_lisp_add_del_map_server api_one_add_del_map_server
17277
17278 static int
17279 api_one_add_del_map_resolver (vat_main_t * vam)
17280 {
17281   unformat_input_t *input = vam->input;
17282   vl_api_one_add_del_map_resolver_t *mp;
17283   u8 is_add = 1;
17284   u8 ipv4_set = 0;
17285   u8 ipv6_set = 0;
17286   ip4_address_t ipv4;
17287   ip6_address_t ipv6;
17288   int ret;
17289
17290   /* Parse args required to build the message */
17291   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17292     {
17293       if (unformat (input, "del"))
17294         {
17295           is_add = 0;
17296         }
17297       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17298         {
17299           ipv4_set = 1;
17300         }
17301       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17302         {
17303           ipv6_set = 1;
17304         }
17305       else
17306         break;
17307     }
17308
17309   if (ipv4_set && ipv6_set)
17310     {
17311       errmsg ("both eid v4 and v6 addresses set");
17312       return -99;
17313     }
17314
17315   if (!ipv4_set && !ipv6_set)
17316     {
17317       errmsg ("eid addresses not set");
17318       return -99;
17319     }
17320
17321   /* Construct the API message */
17322   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17323
17324   mp->is_add = is_add;
17325   if (ipv6_set)
17326     {
17327       mp->is_ipv6 = 1;
17328       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17329     }
17330   else
17331     {
17332       mp->is_ipv6 = 0;
17333       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17334     }
17335
17336   /* send it... */
17337   S (mp);
17338
17339   /* Wait for a reply... */
17340   W (ret);
17341   return ret;
17342 }
17343
17344 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17345
17346 static int
17347 api_lisp_gpe_enable_disable (vat_main_t * vam)
17348 {
17349   unformat_input_t *input = vam->input;
17350   vl_api_gpe_enable_disable_t *mp;
17351   u8 is_set = 0;
17352   u8 is_en = 1;
17353   int ret;
17354
17355   /* Parse args required to build the message */
17356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17357     {
17358       if (unformat (input, "enable"))
17359         {
17360           is_set = 1;
17361           is_en = 1;
17362         }
17363       else if (unformat (input, "disable"))
17364         {
17365           is_set = 1;
17366           is_en = 0;
17367         }
17368       else
17369         break;
17370     }
17371
17372   if (is_set == 0)
17373     {
17374       errmsg ("Value not set");
17375       return -99;
17376     }
17377
17378   /* Construct the API message */
17379   M (GPE_ENABLE_DISABLE, mp);
17380
17381   mp->is_en = is_en;
17382
17383   /* send it... */
17384   S (mp);
17385
17386   /* Wait for a reply... */
17387   W (ret);
17388   return ret;
17389 }
17390
17391 static int
17392 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17393 {
17394   unformat_input_t *input = vam->input;
17395   vl_api_one_rloc_probe_enable_disable_t *mp;
17396   u8 is_set = 0;
17397   u8 is_en = 0;
17398   int ret;
17399
17400   /* Parse args required to build the message */
17401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17402     {
17403       if (unformat (input, "enable"))
17404         {
17405           is_set = 1;
17406           is_en = 1;
17407         }
17408       else if (unformat (input, "disable"))
17409         is_set = 1;
17410       else
17411         break;
17412     }
17413
17414   if (!is_set)
17415     {
17416       errmsg ("Value not set");
17417       return -99;
17418     }
17419
17420   /* Construct the API message */
17421   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17422
17423   mp->is_enabled = is_en;
17424
17425   /* send it... */
17426   S (mp);
17427
17428   /* Wait for a reply... */
17429   W (ret);
17430   return ret;
17431 }
17432
17433 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17434
17435 static int
17436 api_one_map_register_enable_disable (vat_main_t * vam)
17437 {
17438   unformat_input_t *input = vam->input;
17439   vl_api_one_map_register_enable_disable_t *mp;
17440   u8 is_set = 0;
17441   u8 is_en = 0;
17442   int ret;
17443
17444   /* Parse args required to build the message */
17445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17446     {
17447       if (unformat (input, "enable"))
17448         {
17449           is_set = 1;
17450           is_en = 1;
17451         }
17452       else if (unformat (input, "disable"))
17453         is_set = 1;
17454       else
17455         break;
17456     }
17457
17458   if (!is_set)
17459     {
17460       errmsg ("Value not set");
17461       return -99;
17462     }
17463
17464   /* Construct the API message */
17465   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17466
17467   mp->is_enabled = is_en;
17468
17469   /* send it... */
17470   S (mp);
17471
17472   /* Wait for a reply... */
17473   W (ret);
17474   return ret;
17475 }
17476
17477 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17478
17479 static int
17480 api_one_enable_disable (vat_main_t * vam)
17481 {
17482   unformat_input_t *input = vam->input;
17483   vl_api_one_enable_disable_t *mp;
17484   u8 is_set = 0;
17485   u8 is_en = 0;
17486   int ret;
17487
17488   /* Parse args required to build the message */
17489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17490     {
17491       if (unformat (input, "enable"))
17492         {
17493           is_set = 1;
17494           is_en = 1;
17495         }
17496       else if (unformat (input, "disable"))
17497         {
17498           is_set = 1;
17499         }
17500       else
17501         break;
17502     }
17503
17504   if (!is_set)
17505     {
17506       errmsg ("Value not set");
17507       return -99;
17508     }
17509
17510   /* Construct the API message */
17511   M (ONE_ENABLE_DISABLE, mp);
17512
17513   mp->is_en = is_en;
17514
17515   /* send it... */
17516   S (mp);
17517
17518   /* Wait for a reply... */
17519   W (ret);
17520   return ret;
17521 }
17522
17523 #define api_lisp_enable_disable api_one_enable_disable
17524
17525 static int
17526 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17527 {
17528   unformat_input_t *input = vam->input;
17529   vl_api_one_enable_disable_xtr_mode_t *mp;
17530   u8 is_set = 0;
17531   u8 is_en = 0;
17532   int ret;
17533
17534   /* Parse args required to build the message */
17535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17536     {
17537       if (unformat (input, "enable"))
17538         {
17539           is_set = 1;
17540           is_en = 1;
17541         }
17542       else if (unformat (input, "disable"))
17543         {
17544           is_set = 1;
17545         }
17546       else
17547         break;
17548     }
17549
17550   if (!is_set)
17551     {
17552       errmsg ("Value not set");
17553       return -99;
17554     }
17555
17556   /* Construct the API message */
17557   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17558
17559   mp->is_en = is_en;
17560
17561   /* send it... */
17562   S (mp);
17563
17564   /* Wait for a reply... */
17565   W (ret);
17566   return ret;
17567 }
17568
17569 static int
17570 api_one_show_xtr_mode (vat_main_t * vam)
17571 {
17572   vl_api_one_show_xtr_mode_t *mp;
17573   int ret;
17574
17575   /* Construct the API message */
17576   M (ONE_SHOW_XTR_MODE, mp);
17577
17578   /* send it... */
17579   S (mp);
17580
17581   /* Wait for a reply... */
17582   W (ret);
17583   return ret;
17584 }
17585
17586 static int
17587 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17588 {
17589   unformat_input_t *input = vam->input;
17590   vl_api_one_enable_disable_pitr_mode_t *mp;
17591   u8 is_set = 0;
17592   u8 is_en = 0;
17593   int ret;
17594
17595   /* Parse args required to build the message */
17596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17597     {
17598       if (unformat (input, "enable"))
17599         {
17600           is_set = 1;
17601           is_en = 1;
17602         }
17603       else if (unformat (input, "disable"))
17604         {
17605           is_set = 1;
17606         }
17607       else
17608         break;
17609     }
17610
17611   if (!is_set)
17612     {
17613       errmsg ("Value not set");
17614       return -99;
17615     }
17616
17617   /* Construct the API message */
17618   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17619
17620   mp->is_en = is_en;
17621
17622   /* send it... */
17623   S (mp);
17624
17625   /* Wait for a reply... */
17626   W (ret);
17627   return ret;
17628 }
17629
17630 static int
17631 api_one_show_pitr_mode (vat_main_t * vam)
17632 {
17633   vl_api_one_show_pitr_mode_t *mp;
17634   int ret;
17635
17636   /* Construct the API message */
17637   M (ONE_SHOW_PITR_MODE, mp);
17638
17639   /* send it... */
17640   S (mp);
17641
17642   /* Wait for a reply... */
17643   W (ret);
17644   return ret;
17645 }
17646
17647 static int
17648 api_one_enable_disable_petr_mode (vat_main_t * vam)
17649 {
17650   unformat_input_t *input = vam->input;
17651   vl_api_one_enable_disable_petr_mode_t *mp;
17652   u8 is_set = 0;
17653   u8 is_en = 0;
17654   int ret;
17655
17656   /* Parse args required to build the message */
17657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17658     {
17659       if (unformat (input, "enable"))
17660         {
17661           is_set = 1;
17662           is_en = 1;
17663         }
17664       else if (unformat (input, "disable"))
17665         {
17666           is_set = 1;
17667         }
17668       else
17669         break;
17670     }
17671
17672   if (!is_set)
17673     {
17674       errmsg ("Value not set");
17675       return -99;
17676     }
17677
17678   /* Construct the API message */
17679   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17680
17681   mp->is_en = is_en;
17682
17683   /* send it... */
17684   S (mp);
17685
17686   /* Wait for a reply... */
17687   W (ret);
17688   return ret;
17689 }
17690
17691 static int
17692 api_one_show_petr_mode (vat_main_t * vam)
17693 {
17694   vl_api_one_show_petr_mode_t *mp;
17695   int ret;
17696
17697   /* Construct the API message */
17698   M (ONE_SHOW_PETR_MODE, mp);
17699
17700   /* send it... */
17701   S (mp);
17702
17703   /* Wait for a reply... */
17704   W (ret);
17705   return ret;
17706 }
17707
17708 static int
17709 api_show_one_map_register_state (vat_main_t * vam)
17710 {
17711   vl_api_show_one_map_register_state_t *mp;
17712   int ret;
17713
17714   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17715
17716   /* send */
17717   S (mp);
17718
17719   /* wait for reply */
17720   W (ret);
17721   return ret;
17722 }
17723
17724 #define api_show_lisp_map_register_state api_show_one_map_register_state
17725
17726 static int
17727 api_show_one_rloc_probe_state (vat_main_t * vam)
17728 {
17729   vl_api_show_one_rloc_probe_state_t *mp;
17730   int ret;
17731
17732   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17733
17734   /* send */
17735   S (mp);
17736
17737   /* wait for reply */
17738   W (ret);
17739   return ret;
17740 }
17741
17742 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17743
17744 static int
17745 api_one_add_del_ndp_entry (vat_main_t * vam)
17746 {
17747   vl_api_one_add_del_ndp_entry_t *mp;
17748   unformat_input_t *input = vam->input;
17749   u8 is_add = 1;
17750   u8 mac_set = 0;
17751   u8 bd_set = 0;
17752   u8 ip_set = 0;
17753   u8 mac[6] = { 0, };
17754   u8 ip6[16] = { 0, };
17755   u32 bd = ~0;
17756   int ret;
17757
17758   /* Parse args required to build the message */
17759   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17760     {
17761       if (unformat (input, "del"))
17762         is_add = 0;
17763       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17764         mac_set = 1;
17765       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17766         ip_set = 1;
17767       else if (unformat (input, "bd %d", &bd))
17768         bd_set = 1;
17769       else
17770         {
17771           errmsg ("parse error '%U'", format_unformat_error, input);
17772           return -99;
17773         }
17774     }
17775
17776   if (!bd_set || !ip_set || (!mac_set && is_add))
17777     {
17778       errmsg ("Missing BD, IP or MAC!");
17779       return -99;
17780     }
17781
17782   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17783   mp->is_add = is_add;
17784   clib_memcpy (mp->mac, mac, 6);
17785   mp->bd = clib_host_to_net_u32 (bd);
17786   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17787
17788   /* send */
17789   S (mp);
17790
17791   /* wait for reply */
17792   W (ret);
17793   return ret;
17794 }
17795
17796 static int
17797 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17798 {
17799   vl_api_one_add_del_l2_arp_entry_t *mp;
17800   unformat_input_t *input = vam->input;
17801   u8 is_add = 1;
17802   u8 mac_set = 0;
17803   u8 bd_set = 0;
17804   u8 ip_set = 0;
17805   u8 mac[6] = { 0, };
17806   u32 ip4 = 0, bd = ~0;
17807   int ret;
17808
17809   /* Parse args required to build the message */
17810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17811     {
17812       if (unformat (input, "del"))
17813         is_add = 0;
17814       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17815         mac_set = 1;
17816       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17817         ip_set = 1;
17818       else if (unformat (input, "bd %d", &bd))
17819         bd_set = 1;
17820       else
17821         {
17822           errmsg ("parse error '%U'", format_unformat_error, input);
17823           return -99;
17824         }
17825     }
17826
17827   if (!bd_set || !ip_set || (!mac_set && is_add))
17828     {
17829       errmsg ("Missing BD, IP or MAC!");
17830       return -99;
17831     }
17832
17833   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17834   mp->is_add = is_add;
17835   clib_memcpy (mp->mac, mac, 6);
17836   mp->bd = clib_host_to_net_u32 (bd);
17837   mp->ip4 = ip4;
17838
17839   /* send */
17840   S (mp);
17841
17842   /* wait for reply */
17843   W (ret);
17844   return ret;
17845 }
17846
17847 static int
17848 api_one_ndp_bd_get (vat_main_t * vam)
17849 {
17850   vl_api_one_ndp_bd_get_t *mp;
17851   int ret;
17852
17853   M (ONE_NDP_BD_GET, mp);
17854
17855   /* send */
17856   S (mp);
17857
17858   /* wait for reply */
17859   W (ret);
17860   return ret;
17861 }
17862
17863 static int
17864 api_one_ndp_entries_get (vat_main_t * vam)
17865 {
17866   vl_api_one_ndp_entries_get_t *mp;
17867   unformat_input_t *input = vam->input;
17868   u8 bd_set = 0;
17869   u32 bd = ~0;
17870   int ret;
17871
17872   /* Parse args required to build the message */
17873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17874     {
17875       if (unformat (input, "bd %d", &bd))
17876         bd_set = 1;
17877       else
17878         {
17879           errmsg ("parse error '%U'", format_unformat_error, input);
17880           return -99;
17881         }
17882     }
17883
17884   if (!bd_set)
17885     {
17886       errmsg ("Expected bridge domain!");
17887       return -99;
17888     }
17889
17890   M (ONE_NDP_ENTRIES_GET, mp);
17891   mp->bd = clib_host_to_net_u32 (bd);
17892
17893   /* send */
17894   S (mp);
17895
17896   /* wait for reply */
17897   W (ret);
17898   return ret;
17899 }
17900
17901 static int
17902 api_one_l2_arp_bd_get (vat_main_t * vam)
17903 {
17904   vl_api_one_l2_arp_bd_get_t *mp;
17905   int ret;
17906
17907   M (ONE_L2_ARP_BD_GET, mp);
17908
17909   /* send */
17910   S (mp);
17911
17912   /* wait for reply */
17913   W (ret);
17914   return ret;
17915 }
17916
17917 static int
17918 api_one_l2_arp_entries_get (vat_main_t * vam)
17919 {
17920   vl_api_one_l2_arp_entries_get_t *mp;
17921   unformat_input_t *input = vam->input;
17922   u8 bd_set = 0;
17923   u32 bd = ~0;
17924   int ret;
17925
17926   /* Parse args required to build the message */
17927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17928     {
17929       if (unformat (input, "bd %d", &bd))
17930         bd_set = 1;
17931       else
17932         {
17933           errmsg ("parse error '%U'", format_unformat_error, input);
17934           return -99;
17935         }
17936     }
17937
17938   if (!bd_set)
17939     {
17940       errmsg ("Expected bridge domain!");
17941       return -99;
17942     }
17943
17944   M (ONE_L2_ARP_ENTRIES_GET, mp);
17945   mp->bd = clib_host_to_net_u32 (bd);
17946
17947   /* send */
17948   S (mp);
17949
17950   /* wait for reply */
17951   W (ret);
17952   return ret;
17953 }
17954
17955 static int
17956 api_one_stats_enable_disable (vat_main_t * vam)
17957 {
17958   vl_api_one_stats_enable_disable_t *mp;
17959   unformat_input_t *input = vam->input;
17960   u8 is_set = 0;
17961   u8 is_en = 0;
17962   int ret;
17963
17964   /* Parse args required to build the message */
17965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17966     {
17967       if (unformat (input, "enable"))
17968         {
17969           is_set = 1;
17970           is_en = 1;
17971         }
17972       else if (unformat (input, "disable"))
17973         {
17974           is_set = 1;
17975         }
17976       else
17977         break;
17978     }
17979
17980   if (!is_set)
17981     {
17982       errmsg ("Value not set");
17983       return -99;
17984     }
17985
17986   M (ONE_STATS_ENABLE_DISABLE, mp);
17987   mp->is_en = is_en;
17988
17989   /* send */
17990   S (mp);
17991
17992   /* wait for reply */
17993   W (ret);
17994   return ret;
17995 }
17996
17997 static int
17998 api_show_one_stats_enable_disable (vat_main_t * vam)
17999 {
18000   vl_api_show_one_stats_enable_disable_t *mp;
18001   int ret;
18002
18003   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18004
18005   /* send */
18006   S (mp);
18007
18008   /* wait for reply */
18009   W (ret);
18010   return ret;
18011 }
18012
18013 static int
18014 api_show_one_map_request_mode (vat_main_t * vam)
18015 {
18016   vl_api_show_one_map_request_mode_t *mp;
18017   int ret;
18018
18019   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18020
18021   /* send */
18022   S (mp);
18023
18024   /* wait for reply */
18025   W (ret);
18026   return ret;
18027 }
18028
18029 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18030
18031 static int
18032 api_one_map_request_mode (vat_main_t * vam)
18033 {
18034   unformat_input_t *input = vam->input;
18035   vl_api_one_map_request_mode_t *mp;
18036   u8 mode = 0;
18037   int ret;
18038
18039   /* Parse args required to build the message */
18040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18041     {
18042       if (unformat (input, "dst-only"))
18043         mode = 0;
18044       else if (unformat (input, "src-dst"))
18045         mode = 1;
18046       else
18047         {
18048           errmsg ("parse error '%U'", format_unformat_error, input);
18049           return -99;
18050         }
18051     }
18052
18053   M (ONE_MAP_REQUEST_MODE, mp);
18054
18055   mp->mode = mode;
18056
18057   /* send */
18058   S (mp);
18059
18060   /* wait for reply */
18061   W (ret);
18062   return ret;
18063 }
18064
18065 #define api_lisp_map_request_mode api_one_map_request_mode
18066
18067 /**
18068  * Enable/disable ONE proxy ITR.
18069  *
18070  * @param vam vpp API test context
18071  * @return return code
18072  */
18073 static int
18074 api_one_pitr_set_locator_set (vat_main_t * vam)
18075 {
18076   u8 ls_name_set = 0;
18077   unformat_input_t *input = vam->input;
18078   vl_api_one_pitr_set_locator_set_t *mp;
18079   u8 is_add = 1;
18080   u8 *ls_name = 0;
18081   int ret;
18082
18083   /* Parse args required to build the message */
18084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18085     {
18086       if (unformat (input, "del"))
18087         is_add = 0;
18088       else if (unformat (input, "locator-set %s", &ls_name))
18089         ls_name_set = 1;
18090       else
18091         {
18092           errmsg ("parse error '%U'", format_unformat_error, input);
18093           return -99;
18094         }
18095     }
18096
18097   if (!ls_name_set)
18098     {
18099       errmsg ("locator-set name not set!");
18100       return -99;
18101     }
18102
18103   M (ONE_PITR_SET_LOCATOR_SET, mp);
18104
18105   mp->is_add = is_add;
18106   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18107   vec_free (ls_name);
18108
18109   /* send */
18110   S (mp);
18111
18112   /* wait for reply */
18113   W (ret);
18114   return ret;
18115 }
18116
18117 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18118
18119 static int
18120 api_one_nsh_set_locator_set (vat_main_t * vam)
18121 {
18122   u8 ls_name_set = 0;
18123   unformat_input_t *input = vam->input;
18124   vl_api_one_nsh_set_locator_set_t *mp;
18125   u8 is_add = 1;
18126   u8 *ls_name = 0;
18127   int ret;
18128
18129   /* Parse args required to build the message */
18130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18131     {
18132       if (unformat (input, "del"))
18133         is_add = 0;
18134       else if (unformat (input, "ls %s", &ls_name))
18135         ls_name_set = 1;
18136       else
18137         {
18138           errmsg ("parse error '%U'", format_unformat_error, input);
18139           return -99;
18140         }
18141     }
18142
18143   if (!ls_name_set && is_add)
18144     {
18145       errmsg ("locator-set name not set!");
18146       return -99;
18147     }
18148
18149   M (ONE_NSH_SET_LOCATOR_SET, mp);
18150
18151   mp->is_add = is_add;
18152   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18153   vec_free (ls_name);
18154
18155   /* send */
18156   S (mp);
18157
18158   /* wait for reply */
18159   W (ret);
18160   return ret;
18161 }
18162
18163 static int
18164 api_show_one_pitr (vat_main_t * vam)
18165 {
18166   vl_api_show_one_pitr_t *mp;
18167   int ret;
18168
18169   if (!vam->json_output)
18170     {
18171       print (vam->ofp, "%=20s", "lisp status:");
18172     }
18173
18174   M (SHOW_ONE_PITR, mp);
18175   /* send it... */
18176   S (mp);
18177
18178   /* Wait for a reply... */
18179   W (ret);
18180   return ret;
18181 }
18182
18183 #define api_show_lisp_pitr api_show_one_pitr
18184
18185 static int
18186 api_one_use_petr (vat_main_t * vam)
18187 {
18188   unformat_input_t *input = vam->input;
18189   vl_api_one_use_petr_t *mp;
18190   u8 is_add = 0;
18191   ip_address_t ip;
18192   int ret;
18193
18194   memset (&ip, 0, sizeof (ip));
18195
18196   /* Parse args required to build the message */
18197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18198     {
18199       if (unformat (input, "disable"))
18200         is_add = 0;
18201       else
18202         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18203         {
18204           is_add = 1;
18205           ip_addr_version (&ip) = IP4;
18206         }
18207       else
18208         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18209         {
18210           is_add = 1;
18211           ip_addr_version (&ip) = IP6;
18212         }
18213       else
18214         {
18215           errmsg ("parse error '%U'", format_unformat_error, input);
18216           return -99;
18217         }
18218     }
18219
18220   M (ONE_USE_PETR, mp);
18221
18222   mp->is_add = is_add;
18223   if (is_add)
18224     {
18225       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18226       if (mp->is_ip4)
18227         clib_memcpy (mp->address, &ip, 4);
18228       else
18229         clib_memcpy (mp->address, &ip, 16);
18230     }
18231
18232   /* send */
18233   S (mp);
18234
18235   /* wait for reply */
18236   W (ret);
18237   return ret;
18238 }
18239
18240 #define api_lisp_use_petr api_one_use_petr
18241
18242 static int
18243 api_show_one_nsh_mapping (vat_main_t * vam)
18244 {
18245   vl_api_show_one_use_petr_t *mp;
18246   int ret;
18247
18248   if (!vam->json_output)
18249     {
18250       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18251     }
18252
18253   M (SHOW_ONE_NSH_MAPPING, mp);
18254   /* send it... */
18255   S (mp);
18256
18257   /* Wait for a reply... */
18258   W (ret);
18259   return ret;
18260 }
18261
18262 static int
18263 api_show_one_use_petr (vat_main_t * vam)
18264 {
18265   vl_api_show_one_use_petr_t *mp;
18266   int ret;
18267
18268   if (!vam->json_output)
18269     {
18270       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18271     }
18272
18273   M (SHOW_ONE_USE_PETR, mp);
18274   /* send it... */
18275   S (mp);
18276
18277   /* Wait for a reply... */
18278   W (ret);
18279   return ret;
18280 }
18281
18282 #define api_show_lisp_use_petr api_show_one_use_petr
18283
18284 /**
18285  * Add/delete mapping between vni and vrf
18286  */
18287 static int
18288 api_one_eid_table_add_del_map (vat_main_t * vam)
18289 {
18290   unformat_input_t *input = vam->input;
18291   vl_api_one_eid_table_add_del_map_t *mp;
18292   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18293   u32 vni, vrf, bd_index;
18294   int ret;
18295
18296   /* Parse args required to build the message */
18297   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18298     {
18299       if (unformat (input, "del"))
18300         is_add = 0;
18301       else if (unformat (input, "vrf %d", &vrf))
18302         vrf_set = 1;
18303       else if (unformat (input, "bd_index %d", &bd_index))
18304         bd_index_set = 1;
18305       else if (unformat (input, "vni %d", &vni))
18306         vni_set = 1;
18307       else
18308         break;
18309     }
18310
18311   if (!vni_set || (!vrf_set && !bd_index_set))
18312     {
18313       errmsg ("missing arguments!");
18314       return -99;
18315     }
18316
18317   if (vrf_set && bd_index_set)
18318     {
18319       errmsg ("error: both vrf and bd entered!");
18320       return -99;
18321     }
18322
18323   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18324
18325   mp->is_add = is_add;
18326   mp->vni = htonl (vni);
18327   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18328   mp->is_l2 = bd_index_set;
18329
18330   /* send */
18331   S (mp);
18332
18333   /* wait for reply */
18334   W (ret);
18335   return ret;
18336 }
18337
18338 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18339
18340 uword
18341 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18342 {
18343   u32 *action = va_arg (*args, u32 *);
18344   u8 *s = 0;
18345
18346   if (unformat (input, "%s", &s))
18347     {
18348       if (!strcmp ((char *) s, "no-action"))
18349         action[0] = 0;
18350       else if (!strcmp ((char *) s, "natively-forward"))
18351         action[0] = 1;
18352       else if (!strcmp ((char *) s, "send-map-request"))
18353         action[0] = 2;
18354       else if (!strcmp ((char *) s, "drop"))
18355         action[0] = 3;
18356       else
18357         {
18358           clib_warning ("invalid action: '%s'", s);
18359           action[0] = 3;
18360         }
18361     }
18362   else
18363     return 0;
18364
18365   vec_free (s);
18366   return 1;
18367 }
18368
18369 /**
18370  * Add/del remote mapping to/from ONE control plane
18371  *
18372  * @param vam vpp API test context
18373  * @return return code
18374  */
18375 static int
18376 api_one_add_del_remote_mapping (vat_main_t * vam)
18377 {
18378   unformat_input_t *input = vam->input;
18379   vl_api_one_add_del_remote_mapping_t *mp;
18380   u32 vni = 0;
18381   lisp_eid_vat_t _eid, *eid = &_eid;
18382   lisp_eid_vat_t _seid, *seid = &_seid;
18383   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18384   u32 action = ~0, p, w, data_len;
18385   ip4_address_t rloc4;
18386   ip6_address_t rloc6;
18387   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18388   int ret;
18389
18390   memset (&rloc, 0, sizeof (rloc));
18391
18392   /* Parse args required to build the message */
18393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18394     {
18395       if (unformat (input, "del-all"))
18396         {
18397           del_all = 1;
18398         }
18399       else if (unformat (input, "del"))
18400         {
18401           is_add = 0;
18402         }
18403       else if (unformat (input, "add"))
18404         {
18405           is_add = 1;
18406         }
18407       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18408         {
18409           eid_set = 1;
18410         }
18411       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18412         {
18413           seid_set = 1;
18414         }
18415       else if (unformat (input, "vni %d", &vni))
18416         {
18417           ;
18418         }
18419       else if (unformat (input, "p %d w %d", &p, &w))
18420         {
18421           if (!curr_rloc)
18422             {
18423               errmsg ("No RLOC configured for setting priority/weight!");
18424               return -99;
18425             }
18426           curr_rloc->priority = p;
18427           curr_rloc->weight = w;
18428         }
18429       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18430         {
18431           rloc.is_ip4 = 1;
18432           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18433           vec_add1 (rlocs, rloc);
18434           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18435         }
18436       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18437         {
18438           rloc.is_ip4 = 0;
18439           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18440           vec_add1 (rlocs, rloc);
18441           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18442         }
18443       else if (unformat (input, "action %U",
18444                          unformat_negative_mapping_action, &action))
18445         {
18446           ;
18447         }
18448       else
18449         {
18450           clib_warning ("parse error '%U'", format_unformat_error, input);
18451           return -99;
18452         }
18453     }
18454
18455   if (0 == eid_set)
18456     {
18457       errmsg ("missing params!");
18458       return -99;
18459     }
18460
18461   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18462     {
18463       errmsg ("no action set for negative map-reply!");
18464       return -99;
18465     }
18466
18467   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18468
18469   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18470   mp->is_add = is_add;
18471   mp->vni = htonl (vni);
18472   mp->action = (u8) action;
18473   mp->is_src_dst = seid_set;
18474   mp->eid_len = eid->len;
18475   mp->seid_len = seid->len;
18476   mp->del_all = del_all;
18477   mp->eid_type = eid->type;
18478   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18479   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18480
18481   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18482   clib_memcpy (mp->rlocs, rlocs, data_len);
18483   vec_free (rlocs);
18484
18485   /* send it... */
18486   S (mp);
18487
18488   /* Wait for a reply... */
18489   W (ret);
18490   return ret;
18491 }
18492
18493 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18494
18495 /**
18496  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18497  * forwarding entries in data-plane accordingly.
18498  *
18499  * @param vam vpp API test context
18500  * @return return code
18501  */
18502 static int
18503 api_one_add_del_adjacency (vat_main_t * vam)
18504 {
18505   unformat_input_t *input = vam->input;
18506   vl_api_one_add_del_adjacency_t *mp;
18507   u32 vni = 0;
18508   ip4_address_t leid4, reid4;
18509   ip6_address_t leid6, reid6;
18510   u8 reid_mac[6] = { 0 };
18511   u8 leid_mac[6] = { 0 };
18512   u8 reid_type, leid_type;
18513   u32 leid_len = 0, reid_len = 0, len;
18514   u8 is_add = 1;
18515   int ret;
18516
18517   leid_type = reid_type = (u8) ~ 0;
18518
18519   /* Parse args required to build the message */
18520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18521     {
18522       if (unformat (input, "del"))
18523         {
18524           is_add = 0;
18525         }
18526       else if (unformat (input, "add"))
18527         {
18528           is_add = 1;
18529         }
18530       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18531                          &reid4, &len))
18532         {
18533           reid_type = 0;        /* ipv4 */
18534           reid_len = len;
18535         }
18536       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18537                          &reid6, &len))
18538         {
18539           reid_type = 1;        /* ipv6 */
18540           reid_len = len;
18541         }
18542       else if (unformat (input, "reid %U", unformat_ethernet_address,
18543                          reid_mac))
18544         {
18545           reid_type = 2;        /* mac */
18546         }
18547       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18548                          &leid4, &len))
18549         {
18550           leid_type = 0;        /* ipv4 */
18551           leid_len = len;
18552         }
18553       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18554                          &leid6, &len))
18555         {
18556           leid_type = 1;        /* ipv6 */
18557           leid_len = len;
18558         }
18559       else if (unformat (input, "leid %U", unformat_ethernet_address,
18560                          leid_mac))
18561         {
18562           leid_type = 2;        /* mac */
18563         }
18564       else if (unformat (input, "vni %d", &vni))
18565         {
18566           ;
18567         }
18568       else
18569         {
18570           errmsg ("parse error '%U'", format_unformat_error, input);
18571           return -99;
18572         }
18573     }
18574
18575   if ((u8) ~ 0 == reid_type)
18576     {
18577       errmsg ("missing params!");
18578       return -99;
18579     }
18580
18581   if (leid_type != reid_type)
18582     {
18583       errmsg ("remote and local EIDs are of different types!");
18584       return -99;
18585     }
18586
18587   M (ONE_ADD_DEL_ADJACENCY, mp);
18588   mp->is_add = is_add;
18589   mp->vni = htonl (vni);
18590   mp->leid_len = leid_len;
18591   mp->reid_len = reid_len;
18592   mp->eid_type = reid_type;
18593
18594   switch (mp->eid_type)
18595     {
18596     case 0:
18597       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18598       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18599       break;
18600     case 1:
18601       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18602       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18603       break;
18604     case 2:
18605       clib_memcpy (mp->leid, leid_mac, 6);
18606       clib_memcpy (mp->reid, reid_mac, 6);
18607       break;
18608     default:
18609       errmsg ("unknown EID type %d!", mp->eid_type);
18610       return 0;
18611     }
18612
18613   /* send it... */
18614   S (mp);
18615
18616   /* Wait for a reply... */
18617   W (ret);
18618   return ret;
18619 }
18620
18621 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18622
18623 uword
18624 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18625 {
18626   u32 *mode = va_arg (*args, u32 *);
18627
18628   if (unformat (input, "lisp"))
18629     *mode = 0;
18630   else if (unformat (input, "vxlan"))
18631     *mode = 1;
18632   else
18633     return 0;
18634
18635   return 1;
18636 }
18637
18638 static int
18639 api_gpe_get_encap_mode (vat_main_t * vam)
18640 {
18641   vl_api_gpe_get_encap_mode_t *mp;
18642   int ret;
18643
18644   /* Construct the API message */
18645   M (GPE_GET_ENCAP_MODE, mp);
18646
18647   /* send it... */
18648   S (mp);
18649
18650   /* Wait for a reply... */
18651   W (ret);
18652   return ret;
18653 }
18654
18655 static int
18656 api_gpe_set_encap_mode (vat_main_t * vam)
18657 {
18658   unformat_input_t *input = vam->input;
18659   vl_api_gpe_set_encap_mode_t *mp;
18660   int ret;
18661   u32 mode = 0;
18662
18663   /* Parse args required to build the message */
18664   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18665     {
18666       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18667         ;
18668       else
18669         break;
18670     }
18671
18672   /* Construct the API message */
18673   M (GPE_SET_ENCAP_MODE, mp);
18674
18675   mp->mode = mode;
18676
18677   /* send it... */
18678   S (mp);
18679
18680   /* Wait for a reply... */
18681   W (ret);
18682   return ret;
18683 }
18684
18685 static int
18686 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18687 {
18688   unformat_input_t *input = vam->input;
18689   vl_api_gpe_add_del_iface_t *mp;
18690   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18691   u32 dp_table = 0, vni = 0;
18692   int ret;
18693
18694   /* Parse args required to build the message */
18695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18696     {
18697       if (unformat (input, "up"))
18698         {
18699           action_set = 1;
18700           is_add = 1;
18701         }
18702       else if (unformat (input, "down"))
18703         {
18704           action_set = 1;
18705           is_add = 0;
18706         }
18707       else if (unformat (input, "table_id %d", &dp_table))
18708         {
18709           dp_table_set = 1;
18710         }
18711       else if (unformat (input, "bd_id %d", &dp_table))
18712         {
18713           dp_table_set = 1;
18714           is_l2 = 1;
18715         }
18716       else if (unformat (input, "vni %d", &vni))
18717         {
18718           vni_set = 1;
18719         }
18720       else
18721         break;
18722     }
18723
18724   if (action_set == 0)
18725     {
18726       errmsg ("Action not set");
18727       return -99;
18728     }
18729   if (dp_table_set == 0 || vni_set == 0)
18730     {
18731       errmsg ("vni and dp_table must be set");
18732       return -99;
18733     }
18734
18735   /* Construct the API message */
18736   M (GPE_ADD_DEL_IFACE, mp);
18737
18738   mp->is_add = is_add;
18739   mp->dp_table = clib_host_to_net_u32 (dp_table);
18740   mp->is_l2 = is_l2;
18741   mp->vni = clib_host_to_net_u32 (vni);
18742
18743   /* send it... */
18744   S (mp);
18745
18746   /* Wait for a reply... */
18747   W (ret);
18748   return ret;
18749 }
18750
18751 static int
18752 api_one_map_register_fallback_threshold (vat_main_t * vam)
18753 {
18754   unformat_input_t *input = vam->input;
18755   vl_api_one_map_register_fallback_threshold_t *mp;
18756   u32 value = 0;
18757   u8 is_set = 0;
18758   int ret;
18759
18760   /* Parse args required to build the message */
18761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18762     {
18763       if (unformat (input, "%u", &value))
18764         is_set = 1;
18765       else
18766         {
18767           clib_warning ("parse error '%U'", format_unformat_error, input);
18768           return -99;
18769         }
18770     }
18771
18772   if (!is_set)
18773     {
18774       errmsg ("fallback threshold value is missing!");
18775       return -99;
18776     }
18777
18778   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18779   mp->value = clib_host_to_net_u32 (value);
18780
18781   /* send it... */
18782   S (mp);
18783
18784   /* Wait for a reply... */
18785   W (ret);
18786   return ret;
18787 }
18788
18789 static int
18790 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18791 {
18792   vl_api_show_one_map_register_fallback_threshold_t *mp;
18793   int ret;
18794
18795   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18796
18797   /* send it... */
18798   S (mp);
18799
18800   /* Wait for a reply... */
18801   W (ret);
18802   return ret;
18803 }
18804
18805 uword
18806 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18807 {
18808   u32 *proto = va_arg (*args, u32 *);
18809
18810   if (unformat (input, "udp"))
18811     *proto = 1;
18812   else if (unformat (input, "api"))
18813     *proto = 2;
18814   else
18815     return 0;
18816
18817   return 1;
18818 }
18819
18820 static int
18821 api_one_set_transport_protocol (vat_main_t * vam)
18822 {
18823   unformat_input_t *input = vam->input;
18824   vl_api_one_set_transport_protocol_t *mp;
18825   u8 is_set = 0;
18826   u32 protocol = 0;
18827   int ret;
18828
18829   /* Parse args required to build the message */
18830   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18831     {
18832       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18833         is_set = 1;
18834       else
18835         {
18836           clib_warning ("parse error '%U'", format_unformat_error, input);
18837           return -99;
18838         }
18839     }
18840
18841   if (!is_set)
18842     {
18843       errmsg ("Transport protocol missing!");
18844       return -99;
18845     }
18846
18847   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18848   mp->protocol = (u8) protocol;
18849
18850   /* send it... */
18851   S (mp);
18852
18853   /* Wait for a reply... */
18854   W (ret);
18855   return ret;
18856 }
18857
18858 static int
18859 api_one_get_transport_protocol (vat_main_t * vam)
18860 {
18861   vl_api_one_get_transport_protocol_t *mp;
18862   int ret;
18863
18864   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18865
18866   /* send it... */
18867   S (mp);
18868
18869   /* Wait for a reply... */
18870   W (ret);
18871   return ret;
18872 }
18873
18874 static int
18875 api_one_map_register_set_ttl (vat_main_t * vam)
18876 {
18877   unformat_input_t *input = vam->input;
18878   vl_api_one_map_register_set_ttl_t *mp;
18879   u32 ttl = 0;
18880   u8 is_set = 0;
18881   int ret;
18882
18883   /* Parse args required to build the message */
18884   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18885     {
18886       if (unformat (input, "%u", &ttl))
18887         is_set = 1;
18888       else
18889         {
18890           clib_warning ("parse error '%U'", format_unformat_error, input);
18891           return -99;
18892         }
18893     }
18894
18895   if (!is_set)
18896     {
18897       errmsg ("TTL value missing!");
18898       return -99;
18899     }
18900
18901   M (ONE_MAP_REGISTER_SET_TTL, mp);
18902   mp->ttl = clib_host_to_net_u32 (ttl);
18903
18904   /* send it... */
18905   S (mp);
18906
18907   /* Wait for a reply... */
18908   W (ret);
18909   return ret;
18910 }
18911
18912 static int
18913 api_show_one_map_register_ttl (vat_main_t * vam)
18914 {
18915   vl_api_show_one_map_register_ttl_t *mp;
18916   int ret;
18917
18918   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18919
18920   /* send it... */
18921   S (mp);
18922
18923   /* Wait for a reply... */
18924   W (ret);
18925   return ret;
18926 }
18927
18928 /**
18929  * Add/del map request itr rlocs from ONE control plane and updates
18930  *
18931  * @param vam vpp API test context
18932  * @return return code
18933  */
18934 static int
18935 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18936 {
18937   unformat_input_t *input = vam->input;
18938   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18939   u8 *locator_set_name = 0;
18940   u8 locator_set_name_set = 0;
18941   u8 is_add = 1;
18942   int ret;
18943
18944   /* Parse args required to build the message */
18945   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18946     {
18947       if (unformat (input, "del"))
18948         {
18949           is_add = 0;
18950         }
18951       else if (unformat (input, "%_%v%_", &locator_set_name))
18952         {
18953           locator_set_name_set = 1;
18954         }
18955       else
18956         {
18957           clib_warning ("parse error '%U'", format_unformat_error, input);
18958           return -99;
18959         }
18960     }
18961
18962   if (is_add && !locator_set_name_set)
18963     {
18964       errmsg ("itr-rloc is not set!");
18965       return -99;
18966     }
18967
18968   if (is_add && vec_len (locator_set_name) > 64)
18969     {
18970       errmsg ("itr-rloc locator-set name too long");
18971       vec_free (locator_set_name);
18972       return -99;
18973     }
18974
18975   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18976   mp->is_add = is_add;
18977   if (is_add)
18978     {
18979       clib_memcpy (mp->locator_set_name, locator_set_name,
18980                    vec_len (locator_set_name));
18981     }
18982   else
18983     {
18984       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18985     }
18986   vec_free (locator_set_name);
18987
18988   /* send it... */
18989   S (mp);
18990
18991   /* Wait for a reply... */
18992   W (ret);
18993   return ret;
18994 }
18995
18996 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18997
18998 static int
18999 api_one_locator_dump (vat_main_t * vam)
19000 {
19001   unformat_input_t *input = vam->input;
19002   vl_api_one_locator_dump_t *mp;
19003   vl_api_control_ping_t *mp_ping;
19004   u8 is_index_set = 0, is_name_set = 0;
19005   u8 *ls_name = 0;
19006   u32 ls_index = ~0;
19007   int ret;
19008
19009   /* Parse args required to build the message */
19010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19011     {
19012       if (unformat (input, "ls_name %_%v%_", &ls_name))
19013         {
19014           is_name_set = 1;
19015         }
19016       else if (unformat (input, "ls_index %d", &ls_index))
19017         {
19018           is_index_set = 1;
19019         }
19020       else
19021         {
19022           errmsg ("parse error '%U'", format_unformat_error, input);
19023           return -99;
19024         }
19025     }
19026
19027   if (!is_index_set && !is_name_set)
19028     {
19029       errmsg ("error: expected one of index or name!");
19030       return -99;
19031     }
19032
19033   if (is_index_set && is_name_set)
19034     {
19035       errmsg ("error: only one param expected!");
19036       return -99;
19037     }
19038
19039   if (vec_len (ls_name) > 62)
19040     {
19041       errmsg ("error: locator set name too long!");
19042       return -99;
19043     }
19044
19045   if (!vam->json_output)
19046     {
19047       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19048     }
19049
19050   M (ONE_LOCATOR_DUMP, mp);
19051   mp->is_index_set = is_index_set;
19052
19053   if (is_index_set)
19054     mp->ls_index = clib_host_to_net_u32 (ls_index);
19055   else
19056     {
19057       vec_add1 (ls_name, 0);
19058       strncpy ((char *) mp->ls_name, (char *) ls_name,
19059                sizeof (mp->ls_name) - 1);
19060     }
19061
19062   /* send it... */
19063   S (mp);
19064
19065   /* Use a control ping for synchronization */
19066   MPING (CONTROL_PING, mp_ping);
19067   S (mp_ping);
19068
19069   /* Wait for a reply... */
19070   W (ret);
19071   return ret;
19072 }
19073
19074 #define api_lisp_locator_dump api_one_locator_dump
19075
19076 static int
19077 api_one_locator_set_dump (vat_main_t * vam)
19078 {
19079   vl_api_one_locator_set_dump_t *mp;
19080   vl_api_control_ping_t *mp_ping;
19081   unformat_input_t *input = vam->input;
19082   u8 filter = 0;
19083   int ret;
19084
19085   /* Parse args required to build the message */
19086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19087     {
19088       if (unformat (input, "local"))
19089         {
19090           filter = 1;
19091         }
19092       else if (unformat (input, "remote"))
19093         {
19094           filter = 2;
19095         }
19096       else
19097         {
19098           errmsg ("parse error '%U'", format_unformat_error, input);
19099           return -99;
19100         }
19101     }
19102
19103   if (!vam->json_output)
19104     {
19105       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19106     }
19107
19108   M (ONE_LOCATOR_SET_DUMP, mp);
19109
19110   mp->filter = filter;
19111
19112   /* send it... */
19113   S (mp);
19114
19115   /* Use a control ping for synchronization */
19116   MPING (CONTROL_PING, mp_ping);
19117   S (mp_ping);
19118
19119   /* Wait for a reply... */
19120   W (ret);
19121   return ret;
19122 }
19123
19124 #define api_lisp_locator_set_dump api_one_locator_set_dump
19125
19126 static int
19127 api_one_eid_table_map_dump (vat_main_t * vam)
19128 {
19129   u8 is_l2 = 0;
19130   u8 mode_set = 0;
19131   unformat_input_t *input = vam->input;
19132   vl_api_one_eid_table_map_dump_t *mp;
19133   vl_api_control_ping_t *mp_ping;
19134   int ret;
19135
19136   /* Parse args required to build the message */
19137   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19138     {
19139       if (unformat (input, "l2"))
19140         {
19141           is_l2 = 1;
19142           mode_set = 1;
19143         }
19144       else if (unformat (input, "l3"))
19145         {
19146           is_l2 = 0;
19147           mode_set = 1;
19148         }
19149       else
19150         {
19151           errmsg ("parse error '%U'", format_unformat_error, input);
19152           return -99;
19153         }
19154     }
19155
19156   if (!mode_set)
19157     {
19158       errmsg ("expected one of 'l2' or 'l3' parameter!");
19159       return -99;
19160     }
19161
19162   if (!vam->json_output)
19163     {
19164       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19165     }
19166
19167   M (ONE_EID_TABLE_MAP_DUMP, mp);
19168   mp->is_l2 = is_l2;
19169
19170   /* send it... */
19171   S (mp);
19172
19173   /* Use a control ping for synchronization */
19174   MPING (CONTROL_PING, mp_ping);
19175   S (mp_ping);
19176
19177   /* Wait for a reply... */
19178   W (ret);
19179   return ret;
19180 }
19181
19182 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19183
19184 static int
19185 api_one_eid_table_vni_dump (vat_main_t * vam)
19186 {
19187   vl_api_one_eid_table_vni_dump_t *mp;
19188   vl_api_control_ping_t *mp_ping;
19189   int ret;
19190
19191   if (!vam->json_output)
19192     {
19193       print (vam->ofp, "VNI");
19194     }
19195
19196   M (ONE_EID_TABLE_VNI_DUMP, mp);
19197
19198   /* send it... */
19199   S (mp);
19200
19201   /* Use a control ping for synchronization */
19202   MPING (CONTROL_PING, mp_ping);
19203   S (mp_ping);
19204
19205   /* Wait for a reply... */
19206   W (ret);
19207   return ret;
19208 }
19209
19210 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19211
19212 static int
19213 api_one_eid_table_dump (vat_main_t * vam)
19214 {
19215   unformat_input_t *i = vam->input;
19216   vl_api_one_eid_table_dump_t *mp;
19217   vl_api_control_ping_t *mp_ping;
19218   struct in_addr ip4;
19219   struct in6_addr ip6;
19220   u8 mac[6];
19221   u8 eid_type = ~0, eid_set = 0;
19222   u32 prefix_length = ~0, t, vni = 0;
19223   u8 filter = 0;
19224   int ret;
19225   lisp_nsh_api_t nsh;
19226
19227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19228     {
19229       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19230         {
19231           eid_set = 1;
19232           eid_type = 0;
19233           prefix_length = t;
19234         }
19235       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19236         {
19237           eid_set = 1;
19238           eid_type = 1;
19239           prefix_length = t;
19240         }
19241       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19242         {
19243           eid_set = 1;
19244           eid_type = 2;
19245         }
19246       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19247         {
19248           eid_set = 1;
19249           eid_type = 3;
19250         }
19251       else if (unformat (i, "vni %d", &t))
19252         {
19253           vni = t;
19254         }
19255       else if (unformat (i, "local"))
19256         {
19257           filter = 1;
19258         }
19259       else if (unformat (i, "remote"))
19260         {
19261           filter = 2;
19262         }
19263       else
19264         {
19265           errmsg ("parse error '%U'", format_unformat_error, i);
19266           return -99;
19267         }
19268     }
19269
19270   if (!vam->json_output)
19271     {
19272       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19273              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19274     }
19275
19276   M (ONE_EID_TABLE_DUMP, mp);
19277
19278   mp->filter = filter;
19279   if (eid_set)
19280     {
19281       mp->eid_set = 1;
19282       mp->vni = htonl (vni);
19283       mp->eid_type = eid_type;
19284       switch (eid_type)
19285         {
19286         case 0:
19287           mp->prefix_length = prefix_length;
19288           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19289           break;
19290         case 1:
19291           mp->prefix_length = prefix_length;
19292           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19293           break;
19294         case 2:
19295           clib_memcpy (mp->eid, mac, sizeof (mac));
19296           break;
19297         case 3:
19298           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19299           break;
19300         default:
19301           errmsg ("unknown EID type %d!", eid_type);
19302           return -99;
19303         }
19304     }
19305
19306   /* send it... */
19307   S (mp);
19308
19309   /* Use a control ping for synchronization */
19310   MPING (CONTROL_PING, mp_ping);
19311   S (mp_ping);
19312
19313   /* Wait for a reply... */
19314   W (ret);
19315   return ret;
19316 }
19317
19318 #define api_lisp_eid_table_dump api_one_eid_table_dump
19319
19320 static int
19321 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19322 {
19323   unformat_input_t *i = vam->input;
19324   vl_api_gpe_fwd_entries_get_t *mp;
19325   u8 vni_set = 0;
19326   u32 vni = ~0;
19327   int ret;
19328
19329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19330     {
19331       if (unformat (i, "vni %d", &vni))
19332         {
19333           vni_set = 1;
19334         }
19335       else
19336         {
19337           errmsg ("parse error '%U'", format_unformat_error, i);
19338           return -99;
19339         }
19340     }
19341
19342   if (!vni_set)
19343     {
19344       errmsg ("vni not set!");
19345       return -99;
19346     }
19347
19348   if (!vam->json_output)
19349     {
19350       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19351              "leid", "reid");
19352     }
19353
19354   M (GPE_FWD_ENTRIES_GET, mp);
19355   mp->vni = clib_host_to_net_u32 (vni);
19356
19357   /* send it... */
19358   S (mp);
19359
19360   /* Wait for a reply... */
19361   W (ret);
19362   return ret;
19363 }
19364
19365 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19366 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19367 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19368 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19369 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19370 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19371 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19372 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19373
19374 static int
19375 api_one_adjacencies_get (vat_main_t * vam)
19376 {
19377   unformat_input_t *i = vam->input;
19378   vl_api_one_adjacencies_get_t *mp;
19379   u8 vni_set = 0;
19380   u32 vni = ~0;
19381   int ret;
19382
19383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19384     {
19385       if (unformat (i, "vni %d", &vni))
19386         {
19387           vni_set = 1;
19388         }
19389       else
19390         {
19391           errmsg ("parse error '%U'", format_unformat_error, i);
19392           return -99;
19393         }
19394     }
19395
19396   if (!vni_set)
19397     {
19398       errmsg ("vni not set!");
19399       return -99;
19400     }
19401
19402   if (!vam->json_output)
19403     {
19404       print (vam->ofp, "%s %40s", "leid", "reid");
19405     }
19406
19407   M (ONE_ADJACENCIES_GET, mp);
19408   mp->vni = clib_host_to_net_u32 (vni);
19409
19410   /* send it... */
19411   S (mp);
19412
19413   /* Wait for a reply... */
19414   W (ret);
19415   return ret;
19416 }
19417
19418 #define api_lisp_adjacencies_get api_one_adjacencies_get
19419
19420 static int
19421 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19422 {
19423   unformat_input_t *i = vam->input;
19424   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19425   int ret;
19426   u8 ip_family_set = 0, is_ip4 = 1;
19427
19428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19429     {
19430       if (unformat (i, "ip4"))
19431         {
19432           ip_family_set = 1;
19433           is_ip4 = 1;
19434         }
19435       else if (unformat (i, "ip6"))
19436         {
19437           ip_family_set = 1;
19438           is_ip4 = 0;
19439         }
19440       else
19441         {
19442           errmsg ("parse error '%U'", format_unformat_error, i);
19443           return -99;
19444         }
19445     }
19446
19447   if (!ip_family_set)
19448     {
19449       errmsg ("ip family not set!");
19450       return -99;
19451     }
19452
19453   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19454   mp->is_ip4 = is_ip4;
19455
19456   /* send it... */
19457   S (mp);
19458
19459   /* Wait for a reply... */
19460   W (ret);
19461   return ret;
19462 }
19463
19464 static int
19465 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19466 {
19467   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19468   int ret;
19469
19470   if (!vam->json_output)
19471     {
19472       print (vam->ofp, "VNIs");
19473     }
19474
19475   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19476
19477   /* send it... */
19478   S (mp);
19479
19480   /* Wait for a reply... */
19481   W (ret);
19482   return ret;
19483 }
19484
19485 static int
19486 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19487 {
19488   unformat_input_t *i = vam->input;
19489   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19490   int ret = 0;
19491   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19492   struct in_addr ip4;
19493   struct in6_addr ip6;
19494   u32 table_id = 0, nh_sw_if_index = ~0;
19495
19496   memset (&ip4, 0, sizeof (ip4));
19497   memset (&ip6, 0, sizeof (ip6));
19498
19499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19500     {
19501       if (unformat (i, "del"))
19502         is_add = 0;
19503       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19504                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19505         {
19506           ip_set = 1;
19507           is_ip4 = 1;
19508         }
19509       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19510                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19511         {
19512           ip_set = 1;
19513           is_ip4 = 0;
19514         }
19515       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19516         {
19517           ip_set = 1;
19518           is_ip4 = 1;
19519           nh_sw_if_index = ~0;
19520         }
19521       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19522         {
19523           ip_set = 1;
19524           is_ip4 = 0;
19525           nh_sw_if_index = ~0;
19526         }
19527       else if (unformat (i, "table %d", &table_id))
19528         ;
19529       else
19530         {
19531           errmsg ("parse error '%U'", format_unformat_error, i);
19532           return -99;
19533         }
19534     }
19535
19536   if (!ip_set)
19537     {
19538       errmsg ("nh addr not set!");
19539       return -99;
19540     }
19541
19542   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19543   mp->is_add = is_add;
19544   mp->table_id = clib_host_to_net_u32 (table_id);
19545   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19546   mp->is_ip4 = is_ip4;
19547   if (is_ip4)
19548     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19549   else
19550     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19551
19552   /* send it... */
19553   S (mp);
19554
19555   /* Wait for a reply... */
19556   W (ret);
19557   return ret;
19558 }
19559
19560 static int
19561 api_one_map_server_dump (vat_main_t * vam)
19562 {
19563   vl_api_one_map_server_dump_t *mp;
19564   vl_api_control_ping_t *mp_ping;
19565   int ret;
19566
19567   if (!vam->json_output)
19568     {
19569       print (vam->ofp, "%=20s", "Map server");
19570     }
19571
19572   M (ONE_MAP_SERVER_DUMP, mp);
19573   /* send it... */
19574   S (mp);
19575
19576   /* Use a control ping for synchronization */
19577   MPING (CONTROL_PING, mp_ping);
19578   S (mp_ping);
19579
19580   /* Wait for a reply... */
19581   W (ret);
19582   return ret;
19583 }
19584
19585 #define api_lisp_map_server_dump api_one_map_server_dump
19586
19587 static int
19588 api_one_map_resolver_dump (vat_main_t * vam)
19589 {
19590   vl_api_one_map_resolver_dump_t *mp;
19591   vl_api_control_ping_t *mp_ping;
19592   int ret;
19593
19594   if (!vam->json_output)
19595     {
19596       print (vam->ofp, "%=20s", "Map resolver");
19597     }
19598
19599   M (ONE_MAP_RESOLVER_DUMP, mp);
19600   /* send it... */
19601   S (mp);
19602
19603   /* Use a control ping for synchronization */
19604   MPING (CONTROL_PING, mp_ping);
19605   S (mp_ping);
19606
19607   /* Wait for a reply... */
19608   W (ret);
19609   return ret;
19610 }
19611
19612 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19613
19614 static int
19615 api_one_stats_flush (vat_main_t * vam)
19616 {
19617   vl_api_one_stats_flush_t *mp;
19618   int ret = 0;
19619
19620   M (ONE_STATS_FLUSH, mp);
19621   S (mp);
19622   W (ret);
19623   return ret;
19624 }
19625
19626 static int
19627 api_one_stats_dump (vat_main_t * vam)
19628 {
19629   vl_api_one_stats_dump_t *mp;
19630   vl_api_control_ping_t *mp_ping;
19631   int ret;
19632
19633   M (ONE_STATS_DUMP, mp);
19634   /* send it... */
19635   S (mp);
19636
19637   /* Use a control ping for synchronization */
19638   MPING (CONTROL_PING, mp_ping);
19639   S (mp_ping);
19640
19641   /* Wait for a reply... */
19642   W (ret);
19643   return ret;
19644 }
19645
19646 static int
19647 api_show_one_status (vat_main_t * vam)
19648 {
19649   vl_api_show_one_status_t *mp;
19650   int ret;
19651
19652   if (!vam->json_output)
19653     {
19654       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19655     }
19656
19657   M (SHOW_ONE_STATUS, mp);
19658   /* send it... */
19659   S (mp);
19660   /* Wait for a reply... */
19661   W (ret);
19662   return ret;
19663 }
19664
19665 #define api_show_lisp_status api_show_one_status
19666
19667 static int
19668 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19669 {
19670   vl_api_gpe_fwd_entry_path_dump_t *mp;
19671   vl_api_control_ping_t *mp_ping;
19672   unformat_input_t *i = vam->input;
19673   u32 fwd_entry_index = ~0;
19674   int ret;
19675
19676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19677     {
19678       if (unformat (i, "index %d", &fwd_entry_index))
19679         ;
19680       else
19681         break;
19682     }
19683
19684   if (~0 == fwd_entry_index)
19685     {
19686       errmsg ("no index specified!");
19687       return -99;
19688     }
19689
19690   if (!vam->json_output)
19691     {
19692       print (vam->ofp, "first line");
19693     }
19694
19695   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19696
19697   /* send it... */
19698   S (mp);
19699   /* Use a control ping for synchronization */
19700   MPING (CONTROL_PING, mp_ping);
19701   S (mp_ping);
19702
19703   /* Wait for a reply... */
19704   W (ret);
19705   return ret;
19706 }
19707
19708 static int
19709 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19710 {
19711   vl_api_one_get_map_request_itr_rlocs_t *mp;
19712   int ret;
19713
19714   if (!vam->json_output)
19715     {
19716       print (vam->ofp, "%=20s", "itr-rlocs:");
19717     }
19718
19719   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19720   /* send it... */
19721   S (mp);
19722   /* Wait for a reply... */
19723   W (ret);
19724   return ret;
19725 }
19726
19727 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19728
19729 static int
19730 api_af_packet_create (vat_main_t * vam)
19731 {
19732   unformat_input_t *i = vam->input;
19733   vl_api_af_packet_create_t *mp;
19734   u8 *host_if_name = 0;
19735   u8 hw_addr[6];
19736   u8 random_hw_addr = 1;
19737   int ret;
19738
19739   memset (hw_addr, 0, sizeof (hw_addr));
19740
19741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19742     {
19743       if (unformat (i, "name %s", &host_if_name))
19744         vec_add1 (host_if_name, 0);
19745       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19746         random_hw_addr = 0;
19747       else
19748         break;
19749     }
19750
19751   if (!vec_len (host_if_name))
19752     {
19753       errmsg ("host-interface name must be specified");
19754       return -99;
19755     }
19756
19757   if (vec_len (host_if_name) > 64)
19758     {
19759       errmsg ("host-interface name too long");
19760       return -99;
19761     }
19762
19763   M (AF_PACKET_CREATE, mp);
19764
19765   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19766   clib_memcpy (mp->hw_addr, hw_addr, 6);
19767   mp->use_random_hw_addr = random_hw_addr;
19768   vec_free (host_if_name);
19769
19770   S (mp);
19771
19772   /* *INDENT-OFF* */
19773   W2 (ret,
19774       ({
19775         if (ret == 0)
19776           fprintf (vam->ofp ? vam->ofp : stderr,
19777                    " new sw_if_index = %d\n", vam->sw_if_index);
19778       }));
19779   /* *INDENT-ON* */
19780   return ret;
19781 }
19782
19783 static int
19784 api_af_packet_delete (vat_main_t * vam)
19785 {
19786   unformat_input_t *i = vam->input;
19787   vl_api_af_packet_delete_t *mp;
19788   u8 *host_if_name = 0;
19789   int ret;
19790
19791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19792     {
19793       if (unformat (i, "name %s", &host_if_name))
19794         vec_add1 (host_if_name, 0);
19795       else
19796         break;
19797     }
19798
19799   if (!vec_len (host_if_name))
19800     {
19801       errmsg ("host-interface name must be specified");
19802       return -99;
19803     }
19804
19805   if (vec_len (host_if_name) > 64)
19806     {
19807       errmsg ("host-interface name too long");
19808       return -99;
19809     }
19810
19811   M (AF_PACKET_DELETE, mp);
19812
19813   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19814   vec_free (host_if_name);
19815
19816   S (mp);
19817   W (ret);
19818   return ret;
19819 }
19820
19821 static void vl_api_af_packet_details_t_handler
19822   (vl_api_af_packet_details_t * mp)
19823 {
19824   vat_main_t *vam = &vat_main;
19825
19826   print (vam->ofp, "%-16s %d",
19827          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19828 }
19829
19830 static void vl_api_af_packet_details_t_handler_json
19831   (vl_api_af_packet_details_t * mp)
19832 {
19833   vat_main_t *vam = &vat_main;
19834   vat_json_node_t *node = NULL;
19835
19836   if (VAT_JSON_ARRAY != vam->json_tree.type)
19837     {
19838       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19839       vat_json_init_array (&vam->json_tree);
19840     }
19841   node = vat_json_array_add (&vam->json_tree);
19842
19843   vat_json_init_object (node);
19844   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19845   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19846 }
19847
19848 static int
19849 api_af_packet_dump (vat_main_t * vam)
19850 {
19851   vl_api_af_packet_dump_t *mp;
19852   vl_api_control_ping_t *mp_ping;
19853   int ret;
19854
19855   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19856   /* Get list of tap interfaces */
19857   M (AF_PACKET_DUMP, mp);
19858   S (mp);
19859
19860   /* Use a control ping for synchronization */
19861   MPING (CONTROL_PING, mp_ping);
19862   S (mp_ping);
19863
19864   W (ret);
19865   return ret;
19866 }
19867
19868 static int
19869 api_policer_add_del (vat_main_t * vam)
19870 {
19871   unformat_input_t *i = vam->input;
19872   vl_api_policer_add_del_t *mp;
19873   u8 is_add = 1;
19874   u8 *name = 0;
19875   u32 cir = 0;
19876   u32 eir = 0;
19877   u64 cb = 0;
19878   u64 eb = 0;
19879   u8 rate_type = 0;
19880   u8 round_type = 0;
19881   u8 type = 0;
19882   u8 color_aware = 0;
19883   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19884   int ret;
19885
19886   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19887   conform_action.dscp = 0;
19888   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19889   exceed_action.dscp = 0;
19890   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19891   violate_action.dscp = 0;
19892
19893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19894     {
19895       if (unformat (i, "del"))
19896         is_add = 0;
19897       else if (unformat (i, "name %s", &name))
19898         vec_add1 (name, 0);
19899       else if (unformat (i, "cir %u", &cir))
19900         ;
19901       else if (unformat (i, "eir %u", &eir))
19902         ;
19903       else if (unformat (i, "cb %u", &cb))
19904         ;
19905       else if (unformat (i, "eb %u", &eb))
19906         ;
19907       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19908                          &rate_type))
19909         ;
19910       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19911                          &round_type))
19912         ;
19913       else if (unformat (i, "type %U", unformat_policer_type, &type))
19914         ;
19915       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19916                          &conform_action))
19917         ;
19918       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19919                          &exceed_action))
19920         ;
19921       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19922                          &violate_action))
19923         ;
19924       else if (unformat (i, "color-aware"))
19925         color_aware = 1;
19926       else
19927         break;
19928     }
19929
19930   if (!vec_len (name))
19931     {
19932       errmsg ("policer name must be specified");
19933       return -99;
19934     }
19935
19936   if (vec_len (name) > 64)
19937     {
19938       errmsg ("policer name too long");
19939       return -99;
19940     }
19941
19942   M (POLICER_ADD_DEL, mp);
19943
19944   clib_memcpy (mp->name, name, vec_len (name));
19945   vec_free (name);
19946   mp->is_add = is_add;
19947   mp->cir = ntohl (cir);
19948   mp->eir = ntohl (eir);
19949   mp->cb = clib_net_to_host_u64 (cb);
19950   mp->eb = clib_net_to_host_u64 (eb);
19951   mp->rate_type = rate_type;
19952   mp->round_type = round_type;
19953   mp->type = type;
19954   mp->conform_action_type = conform_action.action_type;
19955   mp->conform_dscp = conform_action.dscp;
19956   mp->exceed_action_type = exceed_action.action_type;
19957   mp->exceed_dscp = exceed_action.dscp;
19958   mp->violate_action_type = violate_action.action_type;
19959   mp->violate_dscp = violate_action.dscp;
19960   mp->color_aware = color_aware;
19961
19962   S (mp);
19963   W (ret);
19964   return ret;
19965 }
19966
19967 static int
19968 api_policer_dump (vat_main_t * vam)
19969 {
19970   unformat_input_t *i = vam->input;
19971   vl_api_policer_dump_t *mp;
19972   vl_api_control_ping_t *mp_ping;
19973   u8 *match_name = 0;
19974   u8 match_name_valid = 0;
19975   int ret;
19976
19977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19978     {
19979       if (unformat (i, "name %s", &match_name))
19980         {
19981           vec_add1 (match_name, 0);
19982           match_name_valid = 1;
19983         }
19984       else
19985         break;
19986     }
19987
19988   M (POLICER_DUMP, mp);
19989   mp->match_name_valid = match_name_valid;
19990   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19991   vec_free (match_name);
19992   /* send it... */
19993   S (mp);
19994
19995   /* Use a control ping for synchronization */
19996   MPING (CONTROL_PING, mp_ping);
19997   S (mp_ping);
19998
19999   /* Wait for a reply... */
20000   W (ret);
20001   return ret;
20002 }
20003
20004 static int
20005 api_policer_classify_set_interface (vat_main_t * vam)
20006 {
20007   unformat_input_t *i = vam->input;
20008   vl_api_policer_classify_set_interface_t *mp;
20009   u32 sw_if_index;
20010   int sw_if_index_set;
20011   u32 ip4_table_index = ~0;
20012   u32 ip6_table_index = ~0;
20013   u32 l2_table_index = ~0;
20014   u8 is_add = 1;
20015   int ret;
20016
20017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20018     {
20019       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20020         sw_if_index_set = 1;
20021       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20022         sw_if_index_set = 1;
20023       else if (unformat (i, "del"))
20024         is_add = 0;
20025       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20026         ;
20027       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20028         ;
20029       else if (unformat (i, "l2-table %d", &l2_table_index))
20030         ;
20031       else
20032         {
20033           clib_warning ("parse error '%U'", format_unformat_error, i);
20034           return -99;
20035         }
20036     }
20037
20038   if (sw_if_index_set == 0)
20039     {
20040       errmsg ("missing interface name or sw_if_index");
20041       return -99;
20042     }
20043
20044   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20045
20046   mp->sw_if_index = ntohl (sw_if_index);
20047   mp->ip4_table_index = ntohl (ip4_table_index);
20048   mp->ip6_table_index = ntohl (ip6_table_index);
20049   mp->l2_table_index = ntohl (l2_table_index);
20050   mp->is_add = is_add;
20051
20052   S (mp);
20053   W (ret);
20054   return ret;
20055 }
20056
20057 static int
20058 api_policer_classify_dump (vat_main_t * vam)
20059 {
20060   unformat_input_t *i = vam->input;
20061   vl_api_policer_classify_dump_t *mp;
20062   vl_api_control_ping_t *mp_ping;
20063   u8 type = POLICER_CLASSIFY_N_TABLES;
20064   int ret;
20065
20066   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20067     ;
20068   else
20069     {
20070       errmsg ("classify table type must be specified");
20071       return -99;
20072     }
20073
20074   if (!vam->json_output)
20075     {
20076       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20077     }
20078
20079   M (POLICER_CLASSIFY_DUMP, mp);
20080   mp->type = type;
20081   /* send it... */
20082   S (mp);
20083
20084   /* Use a control ping for synchronization */
20085   MPING (CONTROL_PING, mp_ping);
20086   S (mp_ping);
20087
20088   /* Wait for a reply... */
20089   W (ret);
20090   return ret;
20091 }
20092
20093 static int
20094 api_netmap_create (vat_main_t * vam)
20095 {
20096   unformat_input_t *i = vam->input;
20097   vl_api_netmap_create_t *mp;
20098   u8 *if_name = 0;
20099   u8 hw_addr[6];
20100   u8 random_hw_addr = 1;
20101   u8 is_pipe = 0;
20102   u8 is_master = 0;
20103   int ret;
20104
20105   memset (hw_addr, 0, sizeof (hw_addr));
20106
20107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20108     {
20109       if (unformat (i, "name %s", &if_name))
20110         vec_add1 (if_name, 0);
20111       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20112         random_hw_addr = 0;
20113       else if (unformat (i, "pipe"))
20114         is_pipe = 1;
20115       else if (unformat (i, "master"))
20116         is_master = 1;
20117       else if (unformat (i, "slave"))
20118         is_master = 0;
20119       else
20120         break;
20121     }
20122
20123   if (!vec_len (if_name))
20124     {
20125       errmsg ("interface name must be specified");
20126       return -99;
20127     }
20128
20129   if (vec_len (if_name) > 64)
20130     {
20131       errmsg ("interface name too long");
20132       return -99;
20133     }
20134
20135   M (NETMAP_CREATE, mp);
20136
20137   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20138   clib_memcpy (mp->hw_addr, hw_addr, 6);
20139   mp->use_random_hw_addr = random_hw_addr;
20140   mp->is_pipe = is_pipe;
20141   mp->is_master = is_master;
20142   vec_free (if_name);
20143
20144   S (mp);
20145   W (ret);
20146   return ret;
20147 }
20148
20149 static int
20150 api_netmap_delete (vat_main_t * vam)
20151 {
20152   unformat_input_t *i = vam->input;
20153   vl_api_netmap_delete_t *mp;
20154   u8 *if_name = 0;
20155   int ret;
20156
20157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20158     {
20159       if (unformat (i, "name %s", &if_name))
20160         vec_add1 (if_name, 0);
20161       else
20162         break;
20163     }
20164
20165   if (!vec_len (if_name))
20166     {
20167       errmsg ("interface name must be specified");
20168       return -99;
20169     }
20170
20171   if (vec_len (if_name) > 64)
20172     {
20173       errmsg ("interface name too long");
20174       return -99;
20175     }
20176
20177   M (NETMAP_DELETE, mp);
20178
20179   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20180   vec_free (if_name);
20181
20182   S (mp);
20183   W (ret);
20184   return ret;
20185 }
20186
20187 static void
20188 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20189 {
20190   if (fp->afi == IP46_TYPE_IP6)
20191     print (vam->ofp,
20192            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20193            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20194            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20195            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20196            format_ip6_address, fp->next_hop);
20197   else if (fp->afi == IP46_TYPE_IP4)
20198     print (vam->ofp,
20199            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20200            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20201            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20202            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20203            format_ip4_address, fp->next_hop);
20204 }
20205
20206 static void
20207 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20208                                  vl_api_fib_path_t * fp)
20209 {
20210   struct in_addr ip4;
20211   struct in6_addr ip6;
20212
20213   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20214   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20215   vat_json_object_add_uint (node, "is_local", fp->is_local);
20216   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20217   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20218   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20219   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20220   if (fp->afi == IP46_TYPE_IP4)
20221     {
20222       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20223       vat_json_object_add_ip4 (node, "next_hop", ip4);
20224     }
20225   else if (fp->afi == IP46_TYPE_IP6)
20226     {
20227       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20228       vat_json_object_add_ip6 (node, "next_hop", ip6);
20229     }
20230 }
20231
20232 static void
20233 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20234 {
20235   vat_main_t *vam = &vat_main;
20236   int count = ntohl (mp->mt_count);
20237   vl_api_fib_path_t *fp;
20238   i32 i;
20239
20240   print (vam->ofp, "[%d]: sw_if_index %d via:",
20241          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20242   fp = mp->mt_paths;
20243   for (i = 0; i < count; i++)
20244     {
20245       vl_api_mpls_fib_path_print (vam, fp);
20246       fp++;
20247     }
20248
20249   print (vam->ofp, "");
20250 }
20251
20252 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20253 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20254
20255 static void
20256 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20257 {
20258   vat_main_t *vam = &vat_main;
20259   vat_json_node_t *node = NULL;
20260   int count = ntohl (mp->mt_count);
20261   vl_api_fib_path_t *fp;
20262   i32 i;
20263
20264   if (VAT_JSON_ARRAY != vam->json_tree.type)
20265     {
20266       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20267       vat_json_init_array (&vam->json_tree);
20268     }
20269   node = vat_json_array_add (&vam->json_tree);
20270
20271   vat_json_init_object (node);
20272   vat_json_object_add_uint (node, "tunnel_index",
20273                             ntohl (mp->mt_tunnel_index));
20274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20275
20276   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20277
20278   fp = mp->mt_paths;
20279   for (i = 0; i < count; i++)
20280     {
20281       vl_api_mpls_fib_path_json_print (node, fp);
20282       fp++;
20283     }
20284 }
20285
20286 static int
20287 api_mpls_tunnel_dump (vat_main_t * vam)
20288 {
20289   vl_api_mpls_tunnel_dump_t *mp;
20290   vl_api_control_ping_t *mp_ping;
20291   i32 index = -1;
20292   int ret;
20293
20294   /* Parse args required to build the message */
20295   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20296     {
20297       if (!unformat (vam->input, "tunnel_index %d", &index))
20298         {
20299           index = -1;
20300           break;
20301         }
20302     }
20303
20304   print (vam->ofp, "  tunnel_index %d", index);
20305
20306   M (MPLS_TUNNEL_DUMP, mp);
20307   mp->tunnel_index = htonl (index);
20308   S (mp);
20309
20310   /* Use a control ping for synchronization */
20311   MPING (CONTROL_PING, mp_ping);
20312   S (mp_ping);
20313
20314   W (ret);
20315   return ret;
20316 }
20317
20318 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20319 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20320
20321
20322 static void
20323 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20324 {
20325   vat_main_t *vam = &vat_main;
20326   int count = ntohl (mp->count);
20327   vl_api_fib_path_t *fp;
20328   int i;
20329
20330   print (vam->ofp,
20331          "table-id %d, label %u, ess_bit %u",
20332          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20333   fp = mp->path;
20334   for (i = 0; i < count; i++)
20335     {
20336       vl_api_mpls_fib_path_print (vam, fp);
20337       fp++;
20338     }
20339 }
20340
20341 static void vl_api_mpls_fib_details_t_handler_json
20342   (vl_api_mpls_fib_details_t * mp)
20343 {
20344   vat_main_t *vam = &vat_main;
20345   int count = ntohl (mp->count);
20346   vat_json_node_t *node = NULL;
20347   vl_api_fib_path_t *fp;
20348   int i;
20349
20350   if (VAT_JSON_ARRAY != vam->json_tree.type)
20351     {
20352       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20353       vat_json_init_array (&vam->json_tree);
20354     }
20355   node = vat_json_array_add (&vam->json_tree);
20356
20357   vat_json_init_object (node);
20358   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20359   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20360   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20361   vat_json_object_add_uint (node, "path_count", count);
20362   fp = mp->path;
20363   for (i = 0; i < count; i++)
20364     {
20365       vl_api_mpls_fib_path_json_print (node, fp);
20366       fp++;
20367     }
20368 }
20369
20370 static int
20371 api_mpls_fib_dump (vat_main_t * vam)
20372 {
20373   vl_api_mpls_fib_dump_t *mp;
20374   vl_api_control_ping_t *mp_ping;
20375   int ret;
20376
20377   M (MPLS_FIB_DUMP, mp);
20378   S (mp);
20379
20380   /* Use a control ping for synchronization */
20381   MPING (CONTROL_PING, mp_ping);
20382   S (mp_ping);
20383
20384   W (ret);
20385   return ret;
20386 }
20387
20388 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20389 #define vl_api_ip_fib_details_t_print vl_noop_handler
20390
20391 static void
20392 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20393 {
20394   vat_main_t *vam = &vat_main;
20395   int count = ntohl (mp->count);
20396   vl_api_fib_path_t *fp;
20397   int i;
20398
20399   print (vam->ofp,
20400          "table-id %d, prefix %U/%d",
20401          ntohl (mp->table_id), format_ip4_address, mp->address,
20402          mp->address_length);
20403   fp = mp->path;
20404   for (i = 0; i < count; i++)
20405     {
20406       if (fp->afi == IP46_TYPE_IP6)
20407         print (vam->ofp,
20408                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20409                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20410                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20411                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20412                format_ip6_address, fp->next_hop);
20413       else if (fp->afi == IP46_TYPE_IP4)
20414         print (vam->ofp,
20415                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20416                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20417                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20418                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20419                format_ip4_address, fp->next_hop);
20420       fp++;
20421     }
20422 }
20423
20424 static void vl_api_ip_fib_details_t_handler_json
20425   (vl_api_ip_fib_details_t * mp)
20426 {
20427   vat_main_t *vam = &vat_main;
20428   int count = ntohl (mp->count);
20429   vat_json_node_t *node = NULL;
20430   struct in_addr ip4;
20431   struct in6_addr ip6;
20432   vl_api_fib_path_t *fp;
20433   int i;
20434
20435   if (VAT_JSON_ARRAY != vam->json_tree.type)
20436     {
20437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20438       vat_json_init_array (&vam->json_tree);
20439     }
20440   node = vat_json_array_add (&vam->json_tree);
20441
20442   vat_json_init_object (node);
20443   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20444   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20445   vat_json_object_add_ip4 (node, "prefix", ip4);
20446   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20447   vat_json_object_add_uint (node, "path_count", count);
20448   fp = mp->path;
20449   for (i = 0; i < count; i++)
20450     {
20451       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20452       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20453       vat_json_object_add_uint (node, "is_local", fp->is_local);
20454       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20455       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20456       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20457       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20458       if (fp->afi == IP46_TYPE_IP4)
20459         {
20460           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20461           vat_json_object_add_ip4 (node, "next_hop", ip4);
20462         }
20463       else if (fp->afi == IP46_TYPE_IP6)
20464         {
20465           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20466           vat_json_object_add_ip6 (node, "next_hop", ip6);
20467         }
20468     }
20469 }
20470
20471 static int
20472 api_ip_fib_dump (vat_main_t * vam)
20473 {
20474   vl_api_ip_fib_dump_t *mp;
20475   vl_api_control_ping_t *mp_ping;
20476   int ret;
20477
20478   M (IP_FIB_DUMP, mp);
20479   S (mp);
20480
20481   /* Use a control ping for synchronization */
20482   MPING (CONTROL_PING, mp_ping);
20483   S (mp_ping);
20484
20485   W (ret);
20486   return ret;
20487 }
20488
20489 static int
20490 api_ip_mfib_dump (vat_main_t * vam)
20491 {
20492   vl_api_ip_mfib_dump_t *mp;
20493   vl_api_control_ping_t *mp_ping;
20494   int ret;
20495
20496   M (IP_MFIB_DUMP, mp);
20497   S (mp);
20498
20499   /* Use a control ping for synchronization */
20500   MPING (CONTROL_PING, mp_ping);
20501   S (mp_ping);
20502
20503   W (ret);
20504   return ret;
20505 }
20506
20507 static void vl_api_ip_neighbor_details_t_handler
20508   (vl_api_ip_neighbor_details_t * mp)
20509 {
20510   vat_main_t *vam = &vat_main;
20511
20512   print (vam->ofp, "%c %U %U",
20513          (mp->is_static) ? 'S' : 'D',
20514          format_ethernet_address, &mp->mac_address,
20515          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20516          &mp->ip_address);
20517 }
20518
20519 static void vl_api_ip_neighbor_details_t_handler_json
20520   (vl_api_ip_neighbor_details_t * mp)
20521 {
20522
20523   vat_main_t *vam = &vat_main;
20524   vat_json_node_t *node;
20525   struct in_addr ip4;
20526   struct in6_addr ip6;
20527
20528   if (VAT_JSON_ARRAY != vam->json_tree.type)
20529     {
20530       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20531       vat_json_init_array (&vam->json_tree);
20532     }
20533   node = vat_json_array_add (&vam->json_tree);
20534
20535   vat_json_init_object (node);
20536   vat_json_object_add_string_copy (node, "flag",
20537                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20538                                    "dynamic");
20539
20540   vat_json_object_add_string_copy (node, "link_layer",
20541                                    format (0, "%U", format_ethernet_address,
20542                                            &mp->mac_address));
20543
20544   if (mp->is_ipv6)
20545     {
20546       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20547       vat_json_object_add_ip6 (node, "ip_address", ip6);
20548     }
20549   else
20550     {
20551       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20552       vat_json_object_add_ip4 (node, "ip_address", ip4);
20553     }
20554 }
20555
20556 static int
20557 api_ip_neighbor_dump (vat_main_t * vam)
20558 {
20559   unformat_input_t *i = vam->input;
20560   vl_api_ip_neighbor_dump_t *mp;
20561   vl_api_control_ping_t *mp_ping;
20562   u8 is_ipv6 = 0;
20563   u32 sw_if_index = ~0;
20564   int ret;
20565
20566   /* Parse args required to build the message */
20567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20568     {
20569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20570         ;
20571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20572         ;
20573       else if (unformat (i, "ip6"))
20574         is_ipv6 = 1;
20575       else
20576         break;
20577     }
20578
20579   if (sw_if_index == ~0)
20580     {
20581       errmsg ("missing interface name or sw_if_index");
20582       return -99;
20583     }
20584
20585   M (IP_NEIGHBOR_DUMP, mp);
20586   mp->is_ipv6 = (u8) is_ipv6;
20587   mp->sw_if_index = ntohl (sw_if_index);
20588   S (mp);
20589
20590   /* Use a control ping for synchronization */
20591   MPING (CONTROL_PING, mp_ping);
20592   S (mp_ping);
20593
20594   W (ret);
20595   return ret;
20596 }
20597
20598 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20599 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20600
20601 static void
20602 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20603 {
20604   vat_main_t *vam = &vat_main;
20605   int count = ntohl (mp->count);
20606   vl_api_fib_path_t *fp;
20607   int i;
20608
20609   print (vam->ofp,
20610          "table-id %d, prefix %U/%d",
20611          ntohl (mp->table_id), format_ip6_address, mp->address,
20612          mp->address_length);
20613   fp = mp->path;
20614   for (i = 0; i < count; i++)
20615     {
20616       if (fp->afi == IP46_TYPE_IP6)
20617         print (vam->ofp,
20618                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20619                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20620                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20621                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20622                format_ip6_address, fp->next_hop);
20623       else if (fp->afi == IP46_TYPE_IP4)
20624         print (vam->ofp,
20625                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20626                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20627                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20628                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20629                format_ip4_address, fp->next_hop);
20630       fp++;
20631     }
20632 }
20633
20634 static void vl_api_ip6_fib_details_t_handler_json
20635   (vl_api_ip6_fib_details_t * mp)
20636 {
20637   vat_main_t *vam = &vat_main;
20638   int count = ntohl (mp->count);
20639   vat_json_node_t *node = NULL;
20640   struct in_addr ip4;
20641   struct in6_addr ip6;
20642   vl_api_fib_path_t *fp;
20643   int i;
20644
20645   if (VAT_JSON_ARRAY != vam->json_tree.type)
20646     {
20647       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20648       vat_json_init_array (&vam->json_tree);
20649     }
20650   node = vat_json_array_add (&vam->json_tree);
20651
20652   vat_json_init_object (node);
20653   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20654   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20655   vat_json_object_add_ip6 (node, "prefix", ip6);
20656   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20657   vat_json_object_add_uint (node, "path_count", count);
20658   fp = mp->path;
20659   for (i = 0; i < count; i++)
20660     {
20661       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20662       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20663       vat_json_object_add_uint (node, "is_local", fp->is_local);
20664       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20665       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20666       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20667       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20668       if (fp->afi == IP46_TYPE_IP4)
20669         {
20670           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20671           vat_json_object_add_ip4 (node, "next_hop", ip4);
20672         }
20673       else if (fp->afi == IP46_TYPE_IP6)
20674         {
20675           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20676           vat_json_object_add_ip6 (node, "next_hop", ip6);
20677         }
20678     }
20679 }
20680
20681 static int
20682 api_ip6_fib_dump (vat_main_t * vam)
20683 {
20684   vl_api_ip6_fib_dump_t *mp;
20685   vl_api_control_ping_t *mp_ping;
20686   int ret;
20687
20688   M (IP6_FIB_DUMP, mp);
20689   S (mp);
20690
20691   /* Use a control ping for synchronization */
20692   MPING (CONTROL_PING, mp_ping);
20693   S (mp_ping);
20694
20695   W (ret);
20696   return ret;
20697 }
20698
20699 static int
20700 api_ip6_mfib_dump (vat_main_t * vam)
20701 {
20702   vl_api_ip6_mfib_dump_t *mp;
20703   vl_api_control_ping_t *mp_ping;
20704   int ret;
20705
20706   M (IP6_MFIB_DUMP, mp);
20707   S (mp);
20708
20709   /* Use a control ping for synchronization */
20710   MPING (CONTROL_PING, mp_ping);
20711   S (mp_ping);
20712
20713   W (ret);
20714   return ret;
20715 }
20716
20717 int
20718 api_classify_table_ids (vat_main_t * vam)
20719 {
20720   vl_api_classify_table_ids_t *mp;
20721   int ret;
20722
20723   /* Construct the API message */
20724   M (CLASSIFY_TABLE_IDS, mp);
20725   mp->context = 0;
20726
20727   S (mp);
20728   W (ret);
20729   return ret;
20730 }
20731
20732 int
20733 api_classify_table_by_interface (vat_main_t * vam)
20734 {
20735   unformat_input_t *input = vam->input;
20736   vl_api_classify_table_by_interface_t *mp;
20737
20738   u32 sw_if_index = ~0;
20739   int ret;
20740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20741     {
20742       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20743         ;
20744       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20745         ;
20746       else
20747         break;
20748     }
20749   if (sw_if_index == ~0)
20750     {
20751       errmsg ("missing interface name or sw_if_index");
20752       return -99;
20753     }
20754
20755   /* Construct the API message */
20756   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20757   mp->context = 0;
20758   mp->sw_if_index = ntohl (sw_if_index);
20759
20760   S (mp);
20761   W (ret);
20762   return ret;
20763 }
20764
20765 int
20766 api_classify_table_info (vat_main_t * vam)
20767 {
20768   unformat_input_t *input = vam->input;
20769   vl_api_classify_table_info_t *mp;
20770
20771   u32 table_id = ~0;
20772   int ret;
20773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20774     {
20775       if (unformat (input, "table_id %d", &table_id))
20776         ;
20777       else
20778         break;
20779     }
20780   if (table_id == ~0)
20781     {
20782       errmsg ("missing table id");
20783       return -99;
20784     }
20785
20786   /* Construct the API message */
20787   M (CLASSIFY_TABLE_INFO, mp);
20788   mp->context = 0;
20789   mp->table_id = ntohl (table_id);
20790
20791   S (mp);
20792   W (ret);
20793   return ret;
20794 }
20795
20796 int
20797 api_classify_session_dump (vat_main_t * vam)
20798 {
20799   unformat_input_t *input = vam->input;
20800   vl_api_classify_session_dump_t *mp;
20801   vl_api_control_ping_t *mp_ping;
20802
20803   u32 table_id = ~0;
20804   int ret;
20805   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20806     {
20807       if (unformat (input, "table_id %d", &table_id))
20808         ;
20809       else
20810         break;
20811     }
20812   if (table_id == ~0)
20813     {
20814       errmsg ("missing table id");
20815       return -99;
20816     }
20817
20818   /* Construct the API message */
20819   M (CLASSIFY_SESSION_DUMP, mp);
20820   mp->context = 0;
20821   mp->table_id = ntohl (table_id);
20822   S (mp);
20823
20824   /* Use a control ping for synchronization */
20825   MPING (CONTROL_PING, mp_ping);
20826   S (mp_ping);
20827
20828   W (ret);
20829   return ret;
20830 }
20831
20832 static void
20833 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20834 {
20835   vat_main_t *vam = &vat_main;
20836
20837   print (vam->ofp, "collector_address %U, collector_port %d, "
20838          "src_address %U, vrf_id %d, path_mtu %u, "
20839          "template_interval %u, udp_checksum %d",
20840          format_ip4_address, mp->collector_address,
20841          ntohs (mp->collector_port),
20842          format_ip4_address, mp->src_address,
20843          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20844          ntohl (mp->template_interval), mp->udp_checksum);
20845
20846   vam->retval = 0;
20847   vam->result_ready = 1;
20848 }
20849
20850 static void
20851   vl_api_ipfix_exporter_details_t_handler_json
20852   (vl_api_ipfix_exporter_details_t * mp)
20853 {
20854   vat_main_t *vam = &vat_main;
20855   vat_json_node_t node;
20856   struct in_addr collector_address;
20857   struct in_addr src_address;
20858
20859   vat_json_init_object (&node);
20860   clib_memcpy (&collector_address, &mp->collector_address,
20861                sizeof (collector_address));
20862   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20863   vat_json_object_add_uint (&node, "collector_port",
20864                             ntohs (mp->collector_port));
20865   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20866   vat_json_object_add_ip4 (&node, "src_address", src_address);
20867   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20868   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20869   vat_json_object_add_uint (&node, "template_interval",
20870                             ntohl (mp->template_interval));
20871   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20872
20873   vat_json_print (vam->ofp, &node);
20874   vat_json_free (&node);
20875   vam->retval = 0;
20876   vam->result_ready = 1;
20877 }
20878
20879 int
20880 api_ipfix_exporter_dump (vat_main_t * vam)
20881 {
20882   vl_api_ipfix_exporter_dump_t *mp;
20883   int ret;
20884
20885   /* Construct the API message */
20886   M (IPFIX_EXPORTER_DUMP, mp);
20887   mp->context = 0;
20888
20889   S (mp);
20890   W (ret);
20891   return ret;
20892 }
20893
20894 static int
20895 api_ipfix_classify_stream_dump (vat_main_t * vam)
20896 {
20897   vl_api_ipfix_classify_stream_dump_t *mp;
20898   int ret;
20899
20900   /* Construct the API message */
20901   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20902   mp->context = 0;
20903
20904   S (mp);
20905   W (ret);
20906   return ret;
20907   /* NOTREACHED */
20908   return 0;
20909 }
20910
20911 static void
20912   vl_api_ipfix_classify_stream_details_t_handler
20913   (vl_api_ipfix_classify_stream_details_t * mp)
20914 {
20915   vat_main_t *vam = &vat_main;
20916   print (vam->ofp, "domain_id %d, src_port %d",
20917          ntohl (mp->domain_id), ntohs (mp->src_port));
20918   vam->retval = 0;
20919   vam->result_ready = 1;
20920 }
20921
20922 static void
20923   vl_api_ipfix_classify_stream_details_t_handler_json
20924   (vl_api_ipfix_classify_stream_details_t * mp)
20925 {
20926   vat_main_t *vam = &vat_main;
20927   vat_json_node_t node;
20928
20929   vat_json_init_object (&node);
20930   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20931   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20932
20933   vat_json_print (vam->ofp, &node);
20934   vat_json_free (&node);
20935   vam->retval = 0;
20936   vam->result_ready = 1;
20937 }
20938
20939 static int
20940 api_ipfix_classify_table_dump (vat_main_t * vam)
20941 {
20942   vl_api_ipfix_classify_table_dump_t *mp;
20943   vl_api_control_ping_t *mp_ping;
20944   int ret;
20945
20946   if (!vam->json_output)
20947     {
20948       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20949              "transport_protocol");
20950     }
20951
20952   /* Construct the API message */
20953   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20954
20955   /* send it... */
20956   S (mp);
20957
20958   /* Use a control ping for synchronization */
20959   MPING (CONTROL_PING, mp_ping);
20960   S (mp_ping);
20961
20962   W (ret);
20963   return ret;
20964 }
20965
20966 static void
20967   vl_api_ipfix_classify_table_details_t_handler
20968   (vl_api_ipfix_classify_table_details_t * mp)
20969 {
20970   vat_main_t *vam = &vat_main;
20971   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20972          mp->transport_protocol);
20973 }
20974
20975 static void
20976   vl_api_ipfix_classify_table_details_t_handler_json
20977   (vl_api_ipfix_classify_table_details_t * mp)
20978 {
20979   vat_json_node_t *node = NULL;
20980   vat_main_t *vam = &vat_main;
20981
20982   if (VAT_JSON_ARRAY != vam->json_tree.type)
20983     {
20984       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20985       vat_json_init_array (&vam->json_tree);
20986     }
20987
20988   node = vat_json_array_add (&vam->json_tree);
20989   vat_json_init_object (node);
20990
20991   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20992   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20993   vat_json_object_add_uint (node, "transport_protocol",
20994                             mp->transport_protocol);
20995 }
20996
20997 static int
20998 api_sw_interface_span_enable_disable (vat_main_t * vam)
20999 {
21000   unformat_input_t *i = vam->input;
21001   vl_api_sw_interface_span_enable_disable_t *mp;
21002   u32 src_sw_if_index = ~0;
21003   u32 dst_sw_if_index = ~0;
21004   u8 state = 3;
21005   int ret;
21006   u8 is_l2 = 0;
21007
21008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21009     {
21010       if (unformat
21011           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21012         ;
21013       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21014         ;
21015       else
21016         if (unformat
21017             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21018         ;
21019       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21020         ;
21021       else if (unformat (i, "disable"))
21022         state = 0;
21023       else if (unformat (i, "rx"))
21024         state = 1;
21025       else if (unformat (i, "tx"))
21026         state = 2;
21027       else if (unformat (i, "both"))
21028         state = 3;
21029       else if (unformat (i, "l2"))
21030         is_l2 = 1;
21031       else
21032         break;
21033     }
21034
21035   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21036
21037   mp->sw_if_index_from = htonl (src_sw_if_index);
21038   mp->sw_if_index_to = htonl (dst_sw_if_index);
21039   mp->state = state;
21040   mp->is_l2 = is_l2;
21041
21042   S (mp);
21043   W (ret);
21044   return ret;
21045 }
21046
21047 static void
21048 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21049                                             * mp)
21050 {
21051   vat_main_t *vam = &vat_main;
21052   u8 *sw_if_from_name = 0;
21053   u8 *sw_if_to_name = 0;
21054   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21055   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21056   char *states[] = { "none", "rx", "tx", "both" };
21057   hash_pair_t *p;
21058
21059   /* *INDENT-OFF* */
21060   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21061   ({
21062     if ((u32) p->value[0] == sw_if_index_from)
21063       {
21064         sw_if_from_name = (u8 *)(p->key);
21065         if (sw_if_to_name)
21066           break;
21067       }
21068     if ((u32) p->value[0] == sw_if_index_to)
21069       {
21070         sw_if_to_name = (u8 *)(p->key);
21071         if (sw_if_from_name)
21072           break;
21073       }
21074   }));
21075   /* *INDENT-ON* */
21076   print (vam->ofp, "%20s => %20s (%s) %s",
21077          sw_if_from_name, sw_if_to_name, states[mp->state],
21078          mp->is_l2 ? "l2" : "device");
21079 }
21080
21081 static void
21082   vl_api_sw_interface_span_details_t_handler_json
21083   (vl_api_sw_interface_span_details_t * mp)
21084 {
21085   vat_main_t *vam = &vat_main;
21086   vat_json_node_t *node = NULL;
21087   u8 *sw_if_from_name = 0;
21088   u8 *sw_if_to_name = 0;
21089   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21090   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21091   hash_pair_t *p;
21092
21093   /* *INDENT-OFF* */
21094   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21095   ({
21096     if ((u32) p->value[0] == sw_if_index_from)
21097       {
21098         sw_if_from_name = (u8 *)(p->key);
21099         if (sw_if_to_name)
21100           break;
21101       }
21102     if ((u32) p->value[0] == sw_if_index_to)
21103       {
21104         sw_if_to_name = (u8 *)(p->key);
21105         if (sw_if_from_name)
21106           break;
21107       }
21108   }));
21109   /* *INDENT-ON* */
21110
21111   if (VAT_JSON_ARRAY != vam->json_tree.type)
21112     {
21113       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21114       vat_json_init_array (&vam->json_tree);
21115     }
21116   node = vat_json_array_add (&vam->json_tree);
21117
21118   vat_json_init_object (node);
21119   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21120   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21121   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21122   if (0 != sw_if_to_name)
21123     {
21124       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21125     }
21126   vat_json_object_add_uint (node, "state", mp->state);
21127   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21128 }
21129
21130 static int
21131 api_sw_interface_span_dump (vat_main_t * vam)
21132 {
21133   unformat_input_t *input = vam->input;
21134   vl_api_sw_interface_span_dump_t *mp;
21135   vl_api_control_ping_t *mp_ping;
21136   u8 is_l2 = 0;
21137   int ret;
21138
21139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21140     {
21141       if (unformat (input, "l2"))
21142         is_l2 = 1;
21143       else
21144         break;
21145     }
21146
21147   M (SW_INTERFACE_SPAN_DUMP, mp);
21148   mp->is_l2 = is_l2;
21149   S (mp);
21150
21151   /* Use a control ping for synchronization */
21152   MPING (CONTROL_PING, mp_ping);
21153   S (mp_ping);
21154
21155   W (ret);
21156   return ret;
21157 }
21158
21159 int
21160 api_pg_create_interface (vat_main_t * vam)
21161 {
21162   unformat_input_t *input = vam->input;
21163   vl_api_pg_create_interface_t *mp;
21164
21165   u32 if_id = ~0;
21166   int ret;
21167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21168     {
21169       if (unformat (input, "if_id %d", &if_id))
21170         ;
21171       else
21172         break;
21173     }
21174   if (if_id == ~0)
21175     {
21176       errmsg ("missing pg interface index");
21177       return -99;
21178     }
21179
21180   /* Construct the API message */
21181   M (PG_CREATE_INTERFACE, mp);
21182   mp->context = 0;
21183   mp->interface_id = ntohl (if_id);
21184
21185   S (mp);
21186   W (ret);
21187   return ret;
21188 }
21189
21190 int
21191 api_pg_capture (vat_main_t * vam)
21192 {
21193   unformat_input_t *input = vam->input;
21194   vl_api_pg_capture_t *mp;
21195
21196   u32 if_id = ~0;
21197   u8 enable = 1;
21198   u32 count = 1;
21199   u8 pcap_file_set = 0;
21200   u8 *pcap_file = 0;
21201   int ret;
21202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21203     {
21204       if (unformat (input, "if_id %d", &if_id))
21205         ;
21206       else if (unformat (input, "pcap %s", &pcap_file))
21207         pcap_file_set = 1;
21208       else if (unformat (input, "count %d", &count))
21209         ;
21210       else if (unformat (input, "disable"))
21211         enable = 0;
21212       else
21213         break;
21214     }
21215   if (if_id == ~0)
21216     {
21217       errmsg ("missing pg interface index");
21218       return -99;
21219     }
21220   if (pcap_file_set > 0)
21221     {
21222       if (vec_len (pcap_file) > 255)
21223         {
21224           errmsg ("pcap file name is too long");
21225           return -99;
21226         }
21227     }
21228
21229   u32 name_len = vec_len (pcap_file);
21230   /* Construct the API message */
21231   M (PG_CAPTURE, mp);
21232   mp->context = 0;
21233   mp->interface_id = ntohl (if_id);
21234   mp->is_enabled = enable;
21235   mp->count = ntohl (count);
21236   mp->pcap_name_length = ntohl (name_len);
21237   if (pcap_file_set != 0)
21238     {
21239       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21240     }
21241   vec_free (pcap_file);
21242
21243   S (mp);
21244   W (ret);
21245   return ret;
21246 }
21247
21248 int
21249 api_pg_enable_disable (vat_main_t * vam)
21250 {
21251   unformat_input_t *input = vam->input;
21252   vl_api_pg_enable_disable_t *mp;
21253
21254   u8 enable = 1;
21255   u8 stream_name_set = 0;
21256   u8 *stream_name = 0;
21257   int ret;
21258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21259     {
21260       if (unformat (input, "stream %s", &stream_name))
21261         stream_name_set = 1;
21262       else if (unformat (input, "disable"))
21263         enable = 0;
21264       else
21265         break;
21266     }
21267
21268   if (stream_name_set > 0)
21269     {
21270       if (vec_len (stream_name) > 255)
21271         {
21272           errmsg ("stream name too long");
21273           return -99;
21274         }
21275     }
21276
21277   u32 name_len = vec_len (stream_name);
21278   /* Construct the API message */
21279   M (PG_ENABLE_DISABLE, mp);
21280   mp->context = 0;
21281   mp->is_enabled = enable;
21282   if (stream_name_set != 0)
21283     {
21284       mp->stream_name_length = ntohl (name_len);
21285       clib_memcpy (mp->stream_name, stream_name, name_len);
21286     }
21287   vec_free (stream_name);
21288
21289   S (mp);
21290   W (ret);
21291   return ret;
21292 }
21293
21294 int
21295 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21296 {
21297   unformat_input_t *input = vam->input;
21298   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21299
21300   u16 *low_ports = 0;
21301   u16 *high_ports = 0;
21302   u16 this_low;
21303   u16 this_hi;
21304   ip4_address_t ip4_addr;
21305   ip6_address_t ip6_addr;
21306   u32 length;
21307   u32 tmp, tmp2;
21308   u8 prefix_set = 0;
21309   u32 vrf_id = ~0;
21310   u8 is_add = 1;
21311   u8 is_ipv6 = 0;
21312   int ret;
21313
21314   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21315     {
21316       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21317         {
21318           prefix_set = 1;
21319         }
21320       else
21321         if (unformat
21322             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21323         {
21324           prefix_set = 1;
21325           is_ipv6 = 1;
21326         }
21327       else if (unformat (input, "vrf %d", &vrf_id))
21328         ;
21329       else if (unformat (input, "del"))
21330         is_add = 0;
21331       else if (unformat (input, "port %d", &tmp))
21332         {
21333           if (tmp == 0 || tmp > 65535)
21334             {
21335               errmsg ("port %d out of range", tmp);
21336               return -99;
21337             }
21338           this_low = tmp;
21339           this_hi = this_low + 1;
21340           vec_add1 (low_ports, this_low);
21341           vec_add1 (high_ports, this_hi);
21342         }
21343       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21344         {
21345           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21346             {
21347               errmsg ("incorrect range parameters");
21348               return -99;
21349             }
21350           this_low = tmp;
21351           /* Note: in debug CLI +1 is added to high before
21352              passing to real fn that does "the work"
21353              (ip_source_and_port_range_check_add_del).
21354              This fn is a wrapper around the binary API fn a
21355              control plane will call, which expects this increment
21356              to have occurred. Hence letting the binary API control
21357              plane fn do the increment for consistency between VAT
21358              and other control planes.
21359            */
21360           this_hi = tmp2;
21361           vec_add1 (low_ports, this_low);
21362           vec_add1 (high_ports, this_hi);
21363         }
21364       else
21365         break;
21366     }
21367
21368   if (prefix_set == 0)
21369     {
21370       errmsg ("<address>/<mask> not specified");
21371       return -99;
21372     }
21373
21374   if (vrf_id == ~0)
21375     {
21376       errmsg ("VRF ID required, not specified");
21377       return -99;
21378     }
21379
21380   if (vrf_id == 0)
21381     {
21382       errmsg
21383         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21384       return -99;
21385     }
21386
21387   if (vec_len (low_ports) == 0)
21388     {
21389       errmsg ("At least one port or port range required");
21390       return -99;
21391     }
21392
21393   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21394
21395   mp->is_add = is_add;
21396
21397   if (is_ipv6)
21398     {
21399       mp->is_ipv6 = 1;
21400       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21401     }
21402   else
21403     {
21404       mp->is_ipv6 = 0;
21405       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21406     }
21407
21408   mp->mask_length = length;
21409   mp->number_of_ranges = vec_len (low_ports);
21410
21411   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21412   vec_free (low_ports);
21413
21414   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21415   vec_free (high_ports);
21416
21417   mp->vrf_id = ntohl (vrf_id);
21418
21419   S (mp);
21420   W (ret);
21421   return ret;
21422 }
21423
21424 int
21425 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21426 {
21427   unformat_input_t *input = vam->input;
21428   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21429   u32 sw_if_index = ~0;
21430   int vrf_set = 0;
21431   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21432   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21433   u8 is_add = 1;
21434   int ret;
21435
21436   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21437     {
21438       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21439         ;
21440       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21441         ;
21442       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21443         vrf_set = 1;
21444       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21445         vrf_set = 1;
21446       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21447         vrf_set = 1;
21448       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21449         vrf_set = 1;
21450       else if (unformat (input, "del"))
21451         is_add = 0;
21452       else
21453         break;
21454     }
21455
21456   if (sw_if_index == ~0)
21457     {
21458       errmsg ("Interface required but not specified");
21459       return -99;
21460     }
21461
21462   if (vrf_set == 0)
21463     {
21464       errmsg ("VRF ID required but not specified");
21465       return -99;
21466     }
21467
21468   if (tcp_out_vrf_id == 0
21469       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21470     {
21471       errmsg
21472         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21473       return -99;
21474     }
21475
21476   /* Construct the API message */
21477   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21478
21479   mp->sw_if_index = ntohl (sw_if_index);
21480   mp->is_add = is_add;
21481   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21482   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21483   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21484   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21485
21486   /* send it... */
21487   S (mp);
21488
21489   /* Wait for a reply... */
21490   W (ret);
21491   return ret;
21492 }
21493
21494 static int
21495 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21496 {
21497   unformat_input_t *i = vam->input;
21498   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21499   u32 local_sa_id = 0;
21500   u32 remote_sa_id = 0;
21501   ip4_address_t src_address;
21502   ip4_address_t dst_address;
21503   u8 is_add = 1;
21504   int ret;
21505
21506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21507     {
21508       if (unformat (i, "local_sa %d", &local_sa_id))
21509         ;
21510       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21511         ;
21512       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21513         ;
21514       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21515         ;
21516       else if (unformat (i, "del"))
21517         is_add = 0;
21518       else
21519         {
21520           clib_warning ("parse error '%U'", format_unformat_error, i);
21521           return -99;
21522         }
21523     }
21524
21525   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21526
21527   mp->local_sa_id = ntohl (local_sa_id);
21528   mp->remote_sa_id = ntohl (remote_sa_id);
21529   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21530   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21531   mp->is_add = is_add;
21532
21533   S (mp);
21534   W (ret);
21535   return ret;
21536 }
21537
21538 static int
21539 api_punt (vat_main_t * vam)
21540 {
21541   unformat_input_t *i = vam->input;
21542   vl_api_punt_t *mp;
21543   u32 ipv = ~0;
21544   u32 protocol = ~0;
21545   u32 port = ~0;
21546   int is_add = 1;
21547   int ret;
21548
21549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21550     {
21551       if (unformat (i, "ip %d", &ipv))
21552         ;
21553       else if (unformat (i, "protocol %d", &protocol))
21554         ;
21555       else if (unformat (i, "port %d", &port))
21556         ;
21557       else if (unformat (i, "del"))
21558         is_add = 0;
21559       else
21560         {
21561           clib_warning ("parse error '%U'", format_unformat_error, i);
21562           return -99;
21563         }
21564     }
21565
21566   M (PUNT, mp);
21567
21568   mp->is_add = (u8) is_add;
21569   mp->ipv = (u8) ipv;
21570   mp->l4_protocol = (u8) protocol;
21571   mp->l4_port = htons ((u16) port);
21572
21573   S (mp);
21574   W (ret);
21575   return ret;
21576 }
21577
21578 static void vl_api_ipsec_gre_tunnel_details_t_handler
21579   (vl_api_ipsec_gre_tunnel_details_t * mp)
21580 {
21581   vat_main_t *vam = &vat_main;
21582
21583   print (vam->ofp, "%11d%15U%15U%14d%14d",
21584          ntohl (mp->sw_if_index),
21585          format_ip4_address, &mp->src_address,
21586          format_ip4_address, &mp->dst_address,
21587          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21588 }
21589
21590 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21591   (vl_api_ipsec_gre_tunnel_details_t * mp)
21592 {
21593   vat_main_t *vam = &vat_main;
21594   vat_json_node_t *node = NULL;
21595   struct in_addr ip4;
21596
21597   if (VAT_JSON_ARRAY != vam->json_tree.type)
21598     {
21599       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21600       vat_json_init_array (&vam->json_tree);
21601     }
21602   node = vat_json_array_add (&vam->json_tree);
21603
21604   vat_json_init_object (node);
21605   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21606   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21607   vat_json_object_add_ip4 (node, "src_address", ip4);
21608   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21609   vat_json_object_add_ip4 (node, "dst_address", ip4);
21610   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21611   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21612 }
21613
21614 static int
21615 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21616 {
21617   unformat_input_t *i = vam->input;
21618   vl_api_ipsec_gre_tunnel_dump_t *mp;
21619   vl_api_control_ping_t *mp_ping;
21620   u32 sw_if_index;
21621   u8 sw_if_index_set = 0;
21622   int ret;
21623
21624   /* Parse args required to build the message */
21625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21626     {
21627       if (unformat (i, "sw_if_index %d", &sw_if_index))
21628         sw_if_index_set = 1;
21629       else
21630         break;
21631     }
21632
21633   if (sw_if_index_set == 0)
21634     {
21635       sw_if_index = ~0;
21636     }
21637
21638   if (!vam->json_output)
21639     {
21640       print (vam->ofp, "%11s%15s%15s%14s%14s",
21641              "sw_if_index", "src_address", "dst_address",
21642              "local_sa_id", "remote_sa_id");
21643     }
21644
21645   /* Get list of gre-tunnel interfaces */
21646   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21647
21648   mp->sw_if_index = htonl (sw_if_index);
21649
21650   S (mp);
21651
21652   /* Use a control ping for synchronization */
21653   MPING (CONTROL_PING, mp_ping);
21654   S (mp_ping);
21655
21656   W (ret);
21657   return ret;
21658 }
21659
21660 static int
21661 api_delete_subif (vat_main_t * vam)
21662 {
21663   unformat_input_t *i = vam->input;
21664   vl_api_delete_subif_t *mp;
21665   u32 sw_if_index = ~0;
21666   int ret;
21667
21668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21669     {
21670       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21671         ;
21672       if (unformat (i, "sw_if_index %d", &sw_if_index))
21673         ;
21674       else
21675         break;
21676     }
21677
21678   if (sw_if_index == ~0)
21679     {
21680       errmsg ("missing sw_if_index");
21681       return -99;
21682     }
21683
21684   /* Construct the API message */
21685   M (DELETE_SUBIF, mp);
21686   mp->sw_if_index = ntohl (sw_if_index);
21687
21688   S (mp);
21689   W (ret);
21690   return ret;
21691 }
21692
21693 #define foreach_pbb_vtr_op      \
21694 _("disable",  L2_VTR_DISABLED)  \
21695 _("pop",  L2_VTR_POP_2)         \
21696 _("push",  L2_VTR_PUSH_2)
21697
21698 static int
21699 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21700 {
21701   unformat_input_t *i = vam->input;
21702   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21703   u32 sw_if_index = ~0, vtr_op = ~0;
21704   u16 outer_tag = ~0;
21705   u8 dmac[6], smac[6];
21706   u8 dmac_set = 0, smac_set = 0;
21707   u16 vlanid = 0;
21708   u32 sid = ~0;
21709   u32 tmp;
21710   int ret;
21711
21712   /* Shut up coverity */
21713   memset (dmac, 0, sizeof (dmac));
21714   memset (smac, 0, sizeof (smac));
21715
21716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21717     {
21718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21719         ;
21720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21721         ;
21722       else if (unformat (i, "vtr_op %d", &vtr_op))
21723         ;
21724 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21725       foreach_pbb_vtr_op
21726 #undef _
21727         else if (unformat (i, "translate_pbb_stag"))
21728         {
21729           if (unformat (i, "%d", &tmp))
21730             {
21731               vtr_op = L2_VTR_TRANSLATE_2_1;
21732               outer_tag = tmp;
21733             }
21734           else
21735             {
21736               errmsg
21737                 ("translate_pbb_stag operation requires outer tag definition");
21738               return -99;
21739             }
21740         }
21741       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21742         dmac_set++;
21743       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21744         smac_set++;
21745       else if (unformat (i, "sid %d", &sid))
21746         ;
21747       else if (unformat (i, "vlanid %d", &tmp))
21748         vlanid = tmp;
21749       else
21750         {
21751           clib_warning ("parse error '%U'", format_unformat_error, i);
21752           return -99;
21753         }
21754     }
21755
21756   if ((sw_if_index == ~0) || (vtr_op == ~0))
21757     {
21758       errmsg ("missing sw_if_index or vtr operation");
21759       return -99;
21760     }
21761   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21762       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21763     {
21764       errmsg
21765         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21766       return -99;
21767     }
21768
21769   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21770   mp->sw_if_index = ntohl (sw_if_index);
21771   mp->vtr_op = ntohl (vtr_op);
21772   mp->outer_tag = ntohs (outer_tag);
21773   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21774   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21775   mp->b_vlanid = ntohs (vlanid);
21776   mp->i_sid = ntohl (sid);
21777
21778   S (mp);
21779   W (ret);
21780   return ret;
21781 }
21782
21783 static int
21784 api_flow_classify_set_interface (vat_main_t * vam)
21785 {
21786   unformat_input_t *i = vam->input;
21787   vl_api_flow_classify_set_interface_t *mp;
21788   u32 sw_if_index;
21789   int sw_if_index_set;
21790   u32 ip4_table_index = ~0;
21791   u32 ip6_table_index = ~0;
21792   u8 is_add = 1;
21793   int ret;
21794
21795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21796     {
21797       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21798         sw_if_index_set = 1;
21799       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21800         sw_if_index_set = 1;
21801       else if (unformat (i, "del"))
21802         is_add = 0;
21803       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21804         ;
21805       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21806         ;
21807       else
21808         {
21809           clib_warning ("parse error '%U'", format_unformat_error, i);
21810           return -99;
21811         }
21812     }
21813
21814   if (sw_if_index_set == 0)
21815     {
21816       errmsg ("missing interface name or sw_if_index");
21817       return -99;
21818     }
21819
21820   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21821
21822   mp->sw_if_index = ntohl (sw_if_index);
21823   mp->ip4_table_index = ntohl (ip4_table_index);
21824   mp->ip6_table_index = ntohl (ip6_table_index);
21825   mp->is_add = is_add;
21826
21827   S (mp);
21828   W (ret);
21829   return ret;
21830 }
21831
21832 static int
21833 api_flow_classify_dump (vat_main_t * vam)
21834 {
21835   unformat_input_t *i = vam->input;
21836   vl_api_flow_classify_dump_t *mp;
21837   vl_api_control_ping_t *mp_ping;
21838   u8 type = FLOW_CLASSIFY_N_TABLES;
21839   int ret;
21840
21841   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21842     ;
21843   else
21844     {
21845       errmsg ("classify table type must be specified");
21846       return -99;
21847     }
21848
21849   if (!vam->json_output)
21850     {
21851       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21852     }
21853
21854   M (FLOW_CLASSIFY_DUMP, mp);
21855   mp->type = type;
21856   /* send it... */
21857   S (mp);
21858
21859   /* Use a control ping for synchronization */
21860   MPING (CONTROL_PING, mp_ping);
21861   S (mp_ping);
21862
21863   /* Wait for a reply... */
21864   W (ret);
21865   return ret;
21866 }
21867
21868 static int
21869 api_feature_enable_disable (vat_main_t * vam)
21870 {
21871   unformat_input_t *i = vam->input;
21872   vl_api_feature_enable_disable_t *mp;
21873   u8 *arc_name = 0;
21874   u8 *feature_name = 0;
21875   u32 sw_if_index = ~0;
21876   u8 enable = 1;
21877   int ret;
21878
21879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21880     {
21881       if (unformat (i, "arc_name %s", &arc_name))
21882         ;
21883       else if (unformat (i, "feature_name %s", &feature_name))
21884         ;
21885       else
21886         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21887         ;
21888       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21889         ;
21890       else if (unformat (i, "disable"))
21891         enable = 0;
21892       else
21893         break;
21894     }
21895
21896   if (arc_name == 0)
21897     {
21898       errmsg ("missing arc name");
21899       return -99;
21900     }
21901   if (vec_len (arc_name) > 63)
21902     {
21903       errmsg ("arc name too long");
21904     }
21905
21906   if (feature_name == 0)
21907     {
21908       errmsg ("missing feature name");
21909       return -99;
21910     }
21911   if (vec_len (feature_name) > 63)
21912     {
21913       errmsg ("feature name too long");
21914     }
21915
21916   if (sw_if_index == ~0)
21917     {
21918       errmsg ("missing interface name or sw_if_index");
21919       return -99;
21920     }
21921
21922   /* Construct the API message */
21923   M (FEATURE_ENABLE_DISABLE, mp);
21924   mp->sw_if_index = ntohl (sw_if_index);
21925   mp->enable = enable;
21926   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21927   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21928   vec_free (arc_name);
21929   vec_free (feature_name);
21930
21931   S (mp);
21932   W (ret);
21933   return ret;
21934 }
21935
21936 static int
21937 api_sw_interface_tag_add_del (vat_main_t * vam)
21938 {
21939   unformat_input_t *i = vam->input;
21940   vl_api_sw_interface_tag_add_del_t *mp;
21941   u32 sw_if_index = ~0;
21942   u8 *tag = 0;
21943   u8 enable = 1;
21944   int ret;
21945
21946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21947     {
21948       if (unformat (i, "tag %s", &tag))
21949         ;
21950       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21951         ;
21952       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21953         ;
21954       else if (unformat (i, "del"))
21955         enable = 0;
21956       else
21957         break;
21958     }
21959
21960   if (sw_if_index == ~0)
21961     {
21962       errmsg ("missing interface name or sw_if_index");
21963       return -99;
21964     }
21965
21966   if (enable && (tag == 0))
21967     {
21968       errmsg ("no tag specified");
21969       return -99;
21970     }
21971
21972   /* Construct the API message */
21973   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21974   mp->sw_if_index = ntohl (sw_if_index);
21975   mp->is_add = enable;
21976   if (enable)
21977     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21978   vec_free (tag);
21979
21980   S (mp);
21981   W (ret);
21982   return ret;
21983 }
21984
21985 static void vl_api_l2_xconnect_details_t_handler
21986   (vl_api_l2_xconnect_details_t * mp)
21987 {
21988   vat_main_t *vam = &vat_main;
21989
21990   print (vam->ofp, "%15d%15d",
21991          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21992 }
21993
21994 static void vl_api_l2_xconnect_details_t_handler_json
21995   (vl_api_l2_xconnect_details_t * mp)
21996 {
21997   vat_main_t *vam = &vat_main;
21998   vat_json_node_t *node = NULL;
21999
22000   if (VAT_JSON_ARRAY != vam->json_tree.type)
22001     {
22002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22003       vat_json_init_array (&vam->json_tree);
22004     }
22005   node = vat_json_array_add (&vam->json_tree);
22006
22007   vat_json_init_object (node);
22008   vat_json_object_add_uint (node, "rx_sw_if_index",
22009                             ntohl (mp->rx_sw_if_index));
22010   vat_json_object_add_uint (node, "tx_sw_if_index",
22011                             ntohl (mp->tx_sw_if_index));
22012 }
22013
22014 static int
22015 api_l2_xconnect_dump (vat_main_t * vam)
22016 {
22017   vl_api_l2_xconnect_dump_t *mp;
22018   vl_api_control_ping_t *mp_ping;
22019   int ret;
22020
22021   if (!vam->json_output)
22022     {
22023       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22024     }
22025
22026   M (L2_XCONNECT_DUMP, mp);
22027
22028   S (mp);
22029
22030   /* Use a control ping for synchronization */
22031   MPING (CONTROL_PING, mp_ping);
22032   S (mp_ping);
22033
22034   W (ret);
22035   return ret;
22036 }
22037
22038 static int
22039 api_sw_interface_set_mtu (vat_main_t * vam)
22040 {
22041   unformat_input_t *i = vam->input;
22042   vl_api_sw_interface_set_mtu_t *mp;
22043   u32 sw_if_index = ~0;
22044   u32 mtu = 0;
22045   int ret;
22046
22047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22048     {
22049       if (unformat (i, "mtu %d", &mtu))
22050         ;
22051       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22052         ;
22053       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22054         ;
22055       else
22056         break;
22057     }
22058
22059   if (sw_if_index == ~0)
22060     {
22061       errmsg ("missing interface name or sw_if_index");
22062       return -99;
22063     }
22064
22065   if (mtu == 0)
22066     {
22067       errmsg ("no mtu specified");
22068       return -99;
22069     }
22070
22071   /* Construct the API message */
22072   M (SW_INTERFACE_SET_MTU, mp);
22073   mp->sw_if_index = ntohl (sw_if_index);
22074   mp->mtu = ntohs ((u16) mtu);
22075
22076   S (mp);
22077   W (ret);
22078   return ret;
22079 }
22080
22081 static int
22082 api_p2p_ethernet_add (vat_main_t * vam)
22083 {
22084   unformat_input_t *i = vam->input;
22085   vl_api_p2p_ethernet_add_t *mp;
22086   u32 parent_if_index = ~0;
22087   u32 sub_id = ~0;
22088   u8 remote_mac[6];
22089   u8 mac_set = 0;
22090   int ret;
22091
22092   memset (remote_mac, 0, sizeof (remote_mac));
22093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22094     {
22095       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22096         ;
22097       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22098         ;
22099       else
22100         if (unformat
22101             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22102         mac_set++;
22103       else if (unformat (i, "sub_id %d", &sub_id))
22104         ;
22105       else
22106         {
22107           clib_warning ("parse error '%U'", format_unformat_error, i);
22108           return -99;
22109         }
22110     }
22111
22112   if (parent_if_index == ~0)
22113     {
22114       errmsg ("missing interface name or sw_if_index");
22115       return -99;
22116     }
22117   if (mac_set == 0)
22118     {
22119       errmsg ("missing remote mac address");
22120       return -99;
22121     }
22122   if (sub_id == ~0)
22123     {
22124       errmsg ("missing sub-interface id");
22125       return -99;
22126     }
22127
22128   M (P2P_ETHERNET_ADD, mp);
22129   mp->parent_if_index = ntohl (parent_if_index);
22130   mp->subif_id = ntohl (sub_id);
22131   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22132
22133   S (mp);
22134   W (ret);
22135   return ret;
22136 }
22137
22138 static int
22139 api_p2p_ethernet_del (vat_main_t * vam)
22140 {
22141   unformat_input_t *i = vam->input;
22142   vl_api_p2p_ethernet_del_t *mp;
22143   u32 parent_if_index = ~0;
22144   u8 remote_mac[6];
22145   u8 mac_set = 0;
22146   int ret;
22147
22148   memset (remote_mac, 0, sizeof (remote_mac));
22149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22150     {
22151       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22152         ;
22153       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22154         ;
22155       else
22156         if (unformat
22157             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22158         mac_set++;
22159       else
22160         {
22161           clib_warning ("parse error '%U'", format_unformat_error, i);
22162           return -99;
22163         }
22164     }
22165
22166   if (parent_if_index == ~0)
22167     {
22168       errmsg ("missing interface name or sw_if_index");
22169       return -99;
22170     }
22171   if (mac_set == 0)
22172     {
22173       errmsg ("missing remote mac address");
22174       return -99;
22175     }
22176
22177   M (P2P_ETHERNET_DEL, mp);
22178   mp->parent_if_index = ntohl (parent_if_index);
22179   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22180
22181   S (mp);
22182   W (ret);
22183   return ret;
22184 }
22185
22186 static int
22187 api_lldp_config (vat_main_t * vam)
22188 {
22189   unformat_input_t *i = vam->input;
22190   vl_api_lldp_config_t *mp;
22191   int tx_hold = 0;
22192   int tx_interval = 0;
22193   u8 *sys_name = NULL;
22194   int ret;
22195
22196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22197     {
22198       if (unformat (i, "system-name %s", &sys_name))
22199         ;
22200       else if (unformat (i, "tx-hold %d", &tx_hold))
22201         ;
22202       else if (unformat (i, "tx-interval %d", &tx_interval))
22203         ;
22204       else
22205         {
22206           clib_warning ("parse error '%U'", format_unformat_error, i);
22207           return -99;
22208         }
22209     }
22210
22211   vec_add1 (sys_name, 0);
22212
22213   M (LLDP_CONFIG, mp);
22214   mp->tx_hold = htonl (tx_hold);
22215   mp->tx_interval = htonl (tx_interval);
22216   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22217   vec_free (sys_name);
22218
22219   S (mp);
22220   W (ret);
22221   return ret;
22222 }
22223
22224 static int
22225 api_sw_interface_set_lldp (vat_main_t * vam)
22226 {
22227   unformat_input_t *i = vam->input;
22228   vl_api_sw_interface_set_lldp_t *mp;
22229   u32 sw_if_index = ~0;
22230   u32 enable = 1;
22231   u8 *port_desc = NULL, *mgmt_oid = NULL;
22232   ip4_address_t ip4_addr;
22233   ip6_address_t ip6_addr;
22234   int ret;
22235
22236   memset (&ip4_addr, 0, sizeof (ip4_addr));
22237   memset (&ip6_addr, 0, sizeof (ip6_addr));
22238
22239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22240     {
22241       if (unformat (i, "disable"))
22242         enable = 0;
22243       else
22244         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22245         ;
22246       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22247         ;
22248       else if (unformat (i, "port-desc %s", &port_desc))
22249         ;
22250       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22251         ;
22252       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22253         ;
22254       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22255         ;
22256       else
22257         break;
22258     }
22259
22260   if (sw_if_index == ~0)
22261     {
22262       errmsg ("missing interface name or sw_if_index");
22263       return -99;
22264     }
22265
22266   /* Construct the API message */
22267   vec_add1 (port_desc, 0);
22268   vec_add1 (mgmt_oid, 0);
22269   M (SW_INTERFACE_SET_LLDP, mp);
22270   mp->sw_if_index = ntohl (sw_if_index);
22271   mp->enable = enable;
22272   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22273   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22274   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22275   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22276   vec_free (port_desc);
22277   vec_free (mgmt_oid);
22278
22279   S (mp);
22280   W (ret);
22281   return ret;
22282 }
22283
22284 static int
22285 api_tcp_configure_src_addresses (vat_main_t * vam)
22286 {
22287   vl_api_tcp_configure_src_addresses_t *mp;
22288   unformat_input_t *i = vam->input;
22289   ip4_address_t v4first, v4last;
22290   ip6_address_t v6first, v6last;
22291   u8 range_set = 0;
22292   u32 vrf_id = 0;
22293   int ret;
22294
22295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22296     {
22297       if (unformat (i, "%U - %U",
22298                     unformat_ip4_address, &v4first,
22299                     unformat_ip4_address, &v4last))
22300         {
22301           if (range_set)
22302             {
22303               errmsg ("one range per message (range already set)");
22304               return -99;
22305             }
22306           range_set = 1;
22307         }
22308       else if (unformat (i, "%U - %U",
22309                          unformat_ip6_address, &v6first,
22310                          unformat_ip6_address, &v6last))
22311         {
22312           if (range_set)
22313             {
22314               errmsg ("one range per message (range already set)");
22315               return -99;
22316             }
22317           range_set = 2;
22318         }
22319       else if (unformat (i, "vrf %d", &vrf_id))
22320         ;
22321       else
22322         break;
22323     }
22324
22325   if (range_set == 0)
22326     {
22327       errmsg ("address range not set");
22328       return -99;
22329     }
22330
22331   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22332   mp->vrf_id = ntohl (vrf_id);
22333   /* ipv6? */
22334   if (range_set == 2)
22335     {
22336       mp->is_ipv6 = 1;
22337       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22338       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22339     }
22340   else
22341     {
22342       mp->is_ipv6 = 0;
22343       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22344       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22345     }
22346   S (mp);
22347   W (ret);
22348   return ret;
22349 }
22350
22351 static void vl_api_app_namespace_add_del_reply_t_handler
22352   (vl_api_app_namespace_add_del_reply_t * mp)
22353 {
22354   vat_main_t *vam = &vat_main;
22355   i32 retval = ntohl (mp->retval);
22356   if (vam->async_mode)
22357     {
22358       vam->async_errors += (retval < 0);
22359     }
22360   else
22361     {
22362       vam->retval = retval;
22363       if (retval == 0)
22364         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22365       vam->result_ready = 1;
22366     }
22367 }
22368
22369 static void vl_api_app_namespace_add_del_reply_t_handler_json
22370   (vl_api_app_namespace_add_del_reply_t * mp)
22371 {
22372   vat_main_t *vam = &vat_main;
22373   vat_json_node_t node;
22374
22375   vat_json_init_object (&node);
22376   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22377   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22378
22379   vat_json_print (vam->ofp, &node);
22380   vat_json_free (&node);
22381
22382   vam->retval = ntohl (mp->retval);
22383   vam->result_ready = 1;
22384 }
22385
22386 static int
22387 api_app_namespace_add_del (vat_main_t * vam)
22388 {
22389   vl_api_app_namespace_add_del_t *mp;
22390   unformat_input_t *i = vam->input;
22391   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22392   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22393   u64 secret;
22394   int ret;
22395
22396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22397     {
22398       if (unformat (i, "id %_%v%_", &ns_id))
22399         ;
22400       else if (unformat (i, "secret %lu", &secret))
22401         secret_set = 1;
22402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22403         sw_if_index_set = 1;
22404       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22405         ;
22406       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22407         ;
22408       else
22409         break;
22410     }
22411   if (!ns_id || !secret_set || !sw_if_index_set)
22412     {
22413       errmsg ("namespace id, secret and sw_if_index must be set");
22414       return -99;
22415     }
22416   if (vec_len (ns_id) > 64)
22417     {
22418       errmsg ("namespace id too long");
22419       return -99;
22420     }
22421   M (APP_NAMESPACE_ADD_DEL, mp);
22422
22423   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22424   mp->namespace_id_len = vec_len (ns_id);
22425   mp->secret = clib_host_to_net_u64 (secret);
22426   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22427   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22428   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22429   vec_free (ns_id);
22430   S (mp);
22431   W (ret);
22432   return ret;
22433 }
22434
22435 static void vl_api_map_stats_segment_reply_t_handler
22436   (vl_api_map_stats_segment_reply_t * mp)
22437 {
22438 #if VPP_API_TEST_BUILTIN == 0
22439   vat_main_t *vam = &vat_main;
22440   ssvm_private_t *ssvmp = &vam->stat_segment;
22441   ssvm_shared_header_t *shared_header;
22442   socket_client_main_t *scm = vam->socket_client_main;
22443   int rv = ntohl (mp->retval);
22444   int my_fd, retval;
22445   clib_error_t *error;
22446
22447   vam->retval = rv;
22448
22449   if (rv != 0)
22450     {
22451       vam->result_ready = 1;
22452       return;
22453     }
22454
22455   /*
22456    * Check the socket for the magic fd
22457    */
22458   error = vl_sock_api_recv_fd_msg (scm->socket_fd, &my_fd, 5);
22459   if (error)
22460     {
22461       clib_error_report (error);
22462       vam->retval = -99;
22463       vam->result_ready = 1;
22464       return;
22465     }
22466
22467   memset (ssvmp, 0, sizeof (*ssvmp));
22468   ssvmp->fd = my_fd;
22469
22470   /* Note: this closes memfd.fd */
22471   retval = ssvm_slave_init_memfd (ssvmp);
22472   if (retval)
22473     {
22474       clib_warning ("WARNING: segment map returned %d", retval);
22475       vam->retval = -99;
22476       vam->result_ready = 1;
22477       return;
22478     }
22479   else
22480     errmsg ("stat segment mapped OK...");
22481
22482   ASSERT (ssvmp && ssvmp->sh);
22483
22484   /* Pick up the segment lock from the shared memory header */
22485   shared_header = ssvmp->sh;
22486   vam->stat_segment_lockp = (clib_spinlock_t *) (shared_header->opaque[0]);
22487   vam->retval = 0;
22488   vam->result_ready = 1;
22489 #endif
22490 }
22491
22492 static void vl_api_map_stats_segment_reply_t_handler_json
22493   (vl_api_map_stats_segment_reply_t * mp)
22494 {
22495 #if VPP_API_TEST_BUILTIN == 0
22496   vat_main_t *vam = &vat_main;
22497   clib_warning ("not implemented");
22498   vam->retval = -99;
22499   vam->result_ready = 1;
22500 #endif
22501 }
22502
22503 static int
22504 api_map_stats_segment (vat_main_t * vam)
22505 {
22506 #if VPP_API_TEST_BUILTIN == 0
22507   vl_api_map_stats_segment_t *mp;
22508   int ret;
22509
22510   M (MAP_STATS_SEGMENT, mp);
22511   S (mp);
22512   W (ret);
22513
22514   return ret;
22515 #else
22516   errmsg ("api unavailable");
22517   return -99;
22518 #endif
22519 }
22520
22521 static int
22522 api_sock_init_shm (vat_main_t * vam)
22523 {
22524 #if VPP_API_TEST_BUILTIN == 0
22525   unformat_input_t *i = vam->input;
22526   vl_api_shm_elem_config_t *config = 0;
22527   u64 size = 64 << 20;
22528   int rv;
22529
22530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22531     {
22532       if (unformat (i, "size %U", unformat_memory_size, &size))
22533         ;
22534       else
22535         break;
22536     }
22537
22538   /*
22539    * Canned custom ring allocator config.
22540    * Should probably parse all of this
22541    */
22542   vec_validate (config, 6);
22543   config[0].type = VL_API_VLIB_RING;
22544   config[0].size = 256;
22545   config[0].count = 32;
22546
22547   config[1].type = VL_API_VLIB_RING;
22548   config[1].size = 1024;
22549   config[1].count = 16;
22550
22551   config[2].type = VL_API_VLIB_RING;
22552   config[2].size = 4096;
22553   config[2].count = 2;
22554
22555   config[3].type = VL_API_CLIENT_RING;
22556   config[3].size = 256;
22557   config[3].count = 32;
22558
22559   config[4].type = VL_API_CLIENT_RING;
22560   config[4].size = 1024;
22561   config[4].count = 16;
22562
22563   config[5].type = VL_API_CLIENT_RING;
22564   config[5].size = 4096;
22565   config[5].count = 2;
22566
22567   config[6].type = VL_API_QUEUE;
22568   config[6].count = 128;
22569   config[6].size = sizeof (uword);
22570
22571   rv = vl_socket_client_init_shm (config);
22572   if (!rv)
22573     vam->client_index_invalid = 1;
22574   return rv;
22575 #else
22576   return -99;
22577 #endif
22578 }
22579
22580 static int
22581 api_dns_enable_disable (vat_main_t * vam)
22582 {
22583   unformat_input_t *line_input = vam->input;
22584   vl_api_dns_enable_disable_t *mp;
22585   u8 enable_disable = 1;
22586   int ret;
22587
22588   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22589     {
22590       if (unformat (line_input, "disable"))
22591         enable_disable = 0;
22592       if (unformat (line_input, "enable"))
22593         enable_disable = 1;
22594       else
22595         break;
22596     }
22597
22598   /* Construct the API message */
22599   M (DNS_ENABLE_DISABLE, mp);
22600   mp->enable = enable_disable;
22601
22602   /* send it... */
22603   S (mp);
22604   /* Wait for the reply */
22605   W (ret);
22606   return ret;
22607 }
22608
22609 static int
22610 api_dns_resolve_name (vat_main_t * vam)
22611 {
22612   unformat_input_t *line_input = vam->input;
22613   vl_api_dns_resolve_name_t *mp;
22614   u8 *name = 0;
22615   int ret;
22616
22617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22618     {
22619       if (unformat (line_input, "%s", &name))
22620         ;
22621       else
22622         break;
22623     }
22624
22625   if (vec_len (name) > 127)
22626     {
22627       errmsg ("name too long");
22628       return -99;
22629     }
22630
22631   /* Construct the API message */
22632   M (DNS_RESOLVE_NAME, mp);
22633   memcpy (mp->name, name, vec_len (name));
22634   vec_free (name);
22635
22636   /* send it... */
22637   S (mp);
22638   /* Wait for the reply */
22639   W (ret);
22640   return ret;
22641 }
22642
22643 static int
22644 api_dns_resolve_ip (vat_main_t * vam)
22645 {
22646   unformat_input_t *line_input = vam->input;
22647   vl_api_dns_resolve_ip_t *mp;
22648   int is_ip6 = -1;
22649   ip4_address_t addr4;
22650   ip6_address_t addr6;
22651   int ret;
22652
22653   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22654     {
22655       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22656         is_ip6 = 1;
22657       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22658         is_ip6 = 0;
22659       else
22660         break;
22661     }
22662
22663   if (is_ip6 == -1)
22664     {
22665       errmsg ("missing address");
22666       return -99;
22667     }
22668
22669   /* Construct the API message */
22670   M (DNS_RESOLVE_IP, mp);
22671   mp->is_ip6 = is_ip6;
22672   if (is_ip6)
22673     memcpy (mp->address, &addr6, sizeof (addr6));
22674   else
22675     memcpy (mp->address, &addr4, sizeof (addr4));
22676
22677   /* send it... */
22678   S (mp);
22679   /* Wait for the reply */
22680   W (ret);
22681   return ret;
22682 }
22683
22684 static int
22685 api_dns_name_server_add_del (vat_main_t * vam)
22686 {
22687   unformat_input_t *i = vam->input;
22688   vl_api_dns_name_server_add_del_t *mp;
22689   u8 is_add = 1;
22690   ip6_address_t ip6_server;
22691   ip4_address_t ip4_server;
22692   int ip6_set = 0;
22693   int ip4_set = 0;
22694   int ret = 0;
22695
22696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22697     {
22698       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22699         ip6_set = 1;
22700       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22701         ip4_set = 1;
22702       else if (unformat (i, "del"))
22703         is_add = 0;
22704       else
22705         {
22706           clib_warning ("parse error '%U'", format_unformat_error, i);
22707           return -99;
22708         }
22709     }
22710
22711   if (ip4_set && ip6_set)
22712     {
22713       errmsg ("Only one server address allowed per message");
22714       return -99;
22715     }
22716   if ((ip4_set + ip6_set) == 0)
22717     {
22718       errmsg ("Server address required");
22719       return -99;
22720     }
22721
22722   /* Construct the API message */
22723   M (DNS_NAME_SERVER_ADD_DEL, mp);
22724
22725   if (ip6_set)
22726     {
22727       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22728       mp->is_ip6 = 1;
22729     }
22730   else
22731     {
22732       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22733       mp->is_ip6 = 0;
22734     }
22735
22736   mp->is_add = is_add;
22737
22738   /* send it... */
22739   S (mp);
22740
22741   /* Wait for a reply, return good/bad news  */
22742   W (ret);
22743   return ret;
22744 }
22745
22746 static void
22747 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22748 {
22749   vat_main_t *vam = &vat_main;
22750
22751   if (mp->is_ip4)
22752     {
22753       print (vam->ofp,
22754              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22755              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22756              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22757              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22758              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22759              clib_net_to_host_u32 (mp->action_index), mp->tag);
22760     }
22761   else
22762     {
22763       print (vam->ofp,
22764              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22765              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22766              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22767              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22768              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22769              clib_net_to_host_u32 (mp->action_index), mp->tag);
22770     }
22771 }
22772
22773 static void
22774 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22775                                              mp)
22776 {
22777   vat_main_t *vam = &vat_main;
22778   vat_json_node_t *node = NULL;
22779   struct in6_addr ip6;
22780   struct in_addr ip4;
22781
22782   if (VAT_JSON_ARRAY != vam->json_tree.type)
22783     {
22784       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22785       vat_json_init_array (&vam->json_tree);
22786     }
22787   node = vat_json_array_add (&vam->json_tree);
22788   vat_json_init_object (node);
22789
22790   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22791   vat_json_object_add_uint (node, "appns_index",
22792                             clib_net_to_host_u32 (mp->appns_index));
22793   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22794   vat_json_object_add_uint (node, "scope", mp->scope);
22795   vat_json_object_add_uint (node, "action_index",
22796                             clib_net_to_host_u32 (mp->action_index));
22797   vat_json_object_add_uint (node, "lcl_port",
22798                             clib_net_to_host_u16 (mp->lcl_port));
22799   vat_json_object_add_uint (node, "rmt_port",
22800                             clib_net_to_host_u16 (mp->rmt_port));
22801   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22802   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22803   vat_json_object_add_string_copy (node, "tag", mp->tag);
22804   if (mp->is_ip4)
22805     {
22806       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22807       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22808       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22809       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22810     }
22811   else
22812     {
22813       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22814       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22815       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22816       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22817     }
22818 }
22819
22820 static int
22821 api_session_rule_add_del (vat_main_t * vam)
22822 {
22823   vl_api_session_rule_add_del_t *mp;
22824   unformat_input_t *i = vam->input;
22825   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22826   u32 appns_index = 0, scope = 0;
22827   ip4_address_t lcl_ip4, rmt_ip4;
22828   ip6_address_t lcl_ip6, rmt_ip6;
22829   u8 is_ip4 = 1, conn_set = 0;
22830   u8 is_add = 1, *tag = 0;
22831   int ret;
22832
22833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22834     {
22835       if (unformat (i, "del"))
22836         is_add = 0;
22837       else if (unformat (i, "add"))
22838         ;
22839       else if (unformat (i, "proto tcp"))
22840         proto = 0;
22841       else if (unformat (i, "proto udp"))
22842         proto = 1;
22843       else if (unformat (i, "appns %d", &appns_index))
22844         ;
22845       else if (unformat (i, "scope %d", &scope))
22846         ;
22847       else if (unformat (i, "tag %_%v%_", &tag))
22848         ;
22849       else
22850         if (unformat
22851             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22852              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22853              &rmt_port))
22854         {
22855           is_ip4 = 1;
22856           conn_set = 1;
22857         }
22858       else
22859         if (unformat
22860             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22861              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22862              &rmt_port))
22863         {
22864           is_ip4 = 0;
22865           conn_set = 1;
22866         }
22867       else if (unformat (i, "action %d", &action))
22868         ;
22869       else
22870         break;
22871     }
22872   if (proto == ~0 || !conn_set || action == ~0)
22873     {
22874       errmsg ("transport proto, connection and action must be set");
22875       return -99;
22876     }
22877
22878   if (scope > 3)
22879     {
22880       errmsg ("scope should be 0-3");
22881       return -99;
22882     }
22883
22884   M (SESSION_RULE_ADD_DEL, mp);
22885
22886   mp->is_ip4 = is_ip4;
22887   mp->transport_proto = proto;
22888   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22889   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22890   mp->lcl_plen = lcl_plen;
22891   mp->rmt_plen = rmt_plen;
22892   mp->action_index = clib_host_to_net_u32 (action);
22893   mp->appns_index = clib_host_to_net_u32 (appns_index);
22894   mp->scope = scope;
22895   mp->is_add = is_add;
22896   if (is_ip4)
22897     {
22898       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22899       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22900     }
22901   else
22902     {
22903       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22904       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22905     }
22906   if (tag)
22907     {
22908       clib_memcpy (mp->tag, tag, vec_len (tag));
22909       vec_free (tag);
22910     }
22911
22912   S (mp);
22913   W (ret);
22914   return ret;
22915 }
22916
22917 static int
22918 api_session_rules_dump (vat_main_t * vam)
22919 {
22920   vl_api_session_rules_dump_t *mp;
22921   vl_api_control_ping_t *mp_ping;
22922   int ret;
22923
22924   if (!vam->json_output)
22925     {
22926       print (vam->ofp, "%=20s", "Session Rules");
22927     }
22928
22929   M (SESSION_RULES_DUMP, mp);
22930   /* send it... */
22931   S (mp);
22932
22933   /* Use a control ping for synchronization */
22934   MPING (CONTROL_PING, mp_ping);
22935   S (mp_ping);
22936
22937   /* Wait for a reply... */
22938   W (ret);
22939   return ret;
22940 }
22941
22942 static int
22943 api_ip_container_proxy_add_del (vat_main_t * vam)
22944 {
22945   vl_api_ip_container_proxy_add_del_t *mp;
22946   unformat_input_t *i = vam->input;
22947   u32 plen = ~0, sw_if_index = ~0;
22948   ip4_address_t ip4;
22949   ip6_address_t ip6;
22950   u8 is_ip4 = 1;
22951   u8 is_add = 1;
22952   int ret;
22953
22954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22955     {
22956       if (unformat (i, "del"))
22957         is_add = 0;
22958       else if (unformat (i, "add"))
22959         ;
22960       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22961         {
22962           is_ip4 = 1;
22963           plen = 32;
22964         }
22965       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22966         {
22967           is_ip4 = 0;
22968           plen = 128;
22969         }
22970       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22971         ;
22972       else
22973         break;
22974     }
22975   if (sw_if_index == ~0 || plen == ~0)
22976     {
22977       errmsg ("address and sw_if_index must be set");
22978       return -99;
22979     }
22980
22981   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22982
22983   mp->is_ip4 = is_ip4;
22984   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22985   mp->plen = plen;
22986   mp->is_add = is_add;
22987   if (is_ip4)
22988     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22989   else
22990     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22991
22992   S (mp);
22993   W (ret);
22994   return ret;
22995 }
22996
22997 static int
22998 api_qos_record_enable_disable (vat_main_t * vam)
22999 {
23000   unformat_input_t *i = vam->input;
23001   vl_api_qos_record_enable_disable_t *mp;
23002   u32 sw_if_index, qs = 0xff;
23003   u8 sw_if_index_set = 0;
23004   u8 enable = 1;
23005   int ret;
23006
23007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23008     {
23009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23010         sw_if_index_set = 1;
23011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23012         sw_if_index_set = 1;
23013       else if (unformat (i, "%U", unformat_qos_source, &qs))
23014         ;
23015       else if (unformat (i, "disable"))
23016         enable = 0;
23017       else
23018         {
23019           clib_warning ("parse error '%U'", format_unformat_error, i);
23020           return -99;
23021         }
23022     }
23023
23024   if (sw_if_index_set == 0)
23025     {
23026       errmsg ("missing interface name or sw_if_index");
23027       return -99;
23028     }
23029   if (qs == 0xff)
23030     {
23031       errmsg ("input location must be specified");
23032       return -99;
23033     }
23034
23035   M (QOS_RECORD_ENABLE_DISABLE, mp);
23036
23037   mp->sw_if_index = ntohl (sw_if_index);
23038   mp->input_source = qs;
23039   mp->enable = enable;
23040
23041   S (mp);
23042   W (ret);
23043   return ret;
23044 }
23045
23046
23047 static int
23048 q_or_quit (vat_main_t * vam)
23049 {
23050 #if VPP_API_TEST_BUILTIN == 0
23051   longjmp (vam->jump_buf, 1);
23052 #endif
23053   return 0;                     /* not so much */
23054 }
23055
23056 static int
23057 q (vat_main_t * vam)
23058 {
23059   return q_or_quit (vam);
23060 }
23061
23062 static int
23063 quit (vat_main_t * vam)
23064 {
23065   return q_or_quit (vam);
23066 }
23067
23068 static int
23069 comment (vat_main_t * vam)
23070 {
23071   return 0;
23072 }
23073
23074 static int
23075 statseg (vat_main_t * vam)
23076 {
23077   ssvm_private_t *ssvmp = &vam->stat_segment;
23078   ssvm_shared_header_t *shared_header = ssvmp->sh;
23079   vlib_counter_t **counters;
23080   u64 thread0_index1_packets;
23081   u64 thread0_index1_bytes;
23082   f64 vector_rate, input_rate;
23083   uword *p;
23084
23085   uword *counter_vector_by_name;
23086   if (vam->stat_segment_lockp == 0)
23087     {
23088       errmsg ("Stat segment not mapped...");
23089       return -99;
23090     }
23091
23092   /* look up "/if/rx for sw_if_index 1 as a test */
23093
23094   clib_spinlock_lock (vam->stat_segment_lockp);
23095
23096   counter_vector_by_name = (uword *) shared_header->opaque[1];
23097
23098   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23099   if (p == 0)
23100     {
23101       clib_spinlock_unlock (vam->stat_segment_lockp);
23102       errmsg ("/if/tx not found?");
23103       return -99;
23104     }
23105
23106   /* Fish per-thread vector of combined counters from shared memory */
23107   counters = (vlib_counter_t **) p[0];
23108
23109   if (vec_len (counters[0]) < 2)
23110     {
23111       clib_spinlock_unlock (vam->stat_segment_lockp);
23112       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23113       return -99;
23114     }
23115
23116   /* Read thread 0 sw_if_index 1 counter */
23117   thread0_index1_packets = counters[0][1].packets;
23118   thread0_index1_bytes = counters[0][1].bytes;
23119
23120   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23121   if (p == 0)
23122     {
23123       clib_spinlock_unlock (vam->stat_segment_lockp);
23124       errmsg ("vector_rate not found?");
23125       return -99;
23126     }
23127
23128   vector_rate = *(f64 *) (p[0]);
23129   p = hash_get_mem (counter_vector_by_name, "input_rate");
23130   if (p == 0)
23131     {
23132       clib_spinlock_unlock (vam->stat_segment_lockp);
23133       errmsg ("input_rate not found?");
23134       return -99;
23135     }
23136   input_rate = *(f64 *) (p[0]);
23137
23138   clib_spinlock_unlock (vam->stat_segment_lockp);
23139
23140   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23141          vector_rate, input_rate);
23142   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23143          thread0_index1_packets, thread0_index1_bytes);
23144
23145   return 0;
23146 }
23147
23148 static int
23149 cmd_cmp (void *a1, void *a2)
23150 {
23151   u8 **c1 = a1;
23152   u8 **c2 = a2;
23153
23154   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23155 }
23156
23157 static int
23158 help (vat_main_t * vam)
23159 {
23160   u8 **cmds = 0;
23161   u8 *name = 0;
23162   hash_pair_t *p;
23163   unformat_input_t *i = vam->input;
23164   int j;
23165
23166   if (unformat (i, "%s", &name))
23167     {
23168       uword *hs;
23169
23170       vec_add1 (name, 0);
23171
23172       hs = hash_get_mem (vam->help_by_name, name);
23173       if (hs)
23174         print (vam->ofp, "usage: %s %s", name, hs[0]);
23175       else
23176         print (vam->ofp, "No such msg / command '%s'", name);
23177       vec_free (name);
23178       return 0;
23179     }
23180
23181   print (vam->ofp, "Help is available for the following:");
23182
23183     /* *INDENT-OFF* */
23184     hash_foreach_pair (p, vam->function_by_name,
23185     ({
23186       vec_add1 (cmds, (u8 *)(p->key));
23187     }));
23188     /* *INDENT-ON* */
23189
23190   vec_sort_with_function (cmds, cmd_cmp);
23191
23192   for (j = 0; j < vec_len (cmds); j++)
23193     print (vam->ofp, "%s", cmds[j]);
23194
23195   vec_free (cmds);
23196   return 0;
23197 }
23198
23199 static int
23200 set (vat_main_t * vam)
23201 {
23202   u8 *name = 0, *value = 0;
23203   unformat_input_t *i = vam->input;
23204
23205   if (unformat (i, "%s", &name))
23206     {
23207       /* The input buffer is a vector, not a string. */
23208       value = vec_dup (i->buffer);
23209       vec_delete (value, i->index, 0);
23210       /* Almost certainly has a trailing newline */
23211       if (value[vec_len (value) - 1] == '\n')
23212         value[vec_len (value) - 1] = 0;
23213       /* Make sure it's a proper string, one way or the other */
23214       vec_add1 (value, 0);
23215       (void) clib_macro_set_value (&vam->macro_main,
23216                                    (char *) name, (char *) value);
23217     }
23218   else
23219     errmsg ("usage: set <name> <value>");
23220
23221   vec_free (name);
23222   vec_free (value);
23223   return 0;
23224 }
23225
23226 static int
23227 unset (vat_main_t * vam)
23228 {
23229   u8 *name = 0;
23230
23231   if (unformat (vam->input, "%s", &name))
23232     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23233       errmsg ("unset: %s wasn't set", name);
23234   vec_free (name);
23235   return 0;
23236 }
23237
23238 typedef struct
23239 {
23240   u8 *name;
23241   u8 *value;
23242 } macro_sort_t;
23243
23244
23245 static int
23246 macro_sort_cmp (void *a1, void *a2)
23247 {
23248   macro_sort_t *s1 = a1;
23249   macro_sort_t *s2 = a2;
23250
23251   return strcmp ((char *) (s1->name), (char *) (s2->name));
23252 }
23253
23254 static int
23255 dump_macro_table (vat_main_t * vam)
23256 {
23257   macro_sort_t *sort_me = 0, *sm;
23258   int i;
23259   hash_pair_t *p;
23260
23261     /* *INDENT-OFF* */
23262     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23263     ({
23264       vec_add2 (sort_me, sm, 1);
23265       sm->name = (u8 *)(p->key);
23266       sm->value = (u8 *) (p->value[0]);
23267     }));
23268     /* *INDENT-ON* */
23269
23270   vec_sort_with_function (sort_me, macro_sort_cmp);
23271
23272   if (vec_len (sort_me))
23273     print (vam->ofp, "%-15s%s", "Name", "Value");
23274   else
23275     print (vam->ofp, "The macro table is empty...");
23276
23277   for (i = 0; i < vec_len (sort_me); i++)
23278     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23279   return 0;
23280 }
23281
23282 static int
23283 dump_node_table (vat_main_t * vam)
23284 {
23285   int i, j;
23286   vlib_node_t *node, *next_node;
23287
23288   if (vec_len (vam->graph_nodes) == 0)
23289     {
23290       print (vam->ofp, "Node table empty, issue get_node_graph...");
23291       return 0;
23292     }
23293
23294   for (i = 0; i < vec_len (vam->graph_nodes); i++)
23295     {
23296       node = vam->graph_nodes[i];
23297       print (vam->ofp, "[%d] %s", i, node->name);
23298       for (j = 0; j < vec_len (node->next_nodes); j++)
23299         {
23300           if (node->next_nodes[j] != ~0)
23301             {
23302               next_node = vam->graph_nodes[node->next_nodes[j]];
23303               print (vam->ofp, "  [%d] %s", j, next_node->name);
23304             }
23305         }
23306     }
23307   return 0;
23308 }
23309
23310 static int
23311 value_sort_cmp (void *a1, void *a2)
23312 {
23313   name_sort_t *n1 = a1;
23314   name_sort_t *n2 = a2;
23315
23316   if (n1->value < n2->value)
23317     return -1;
23318   if (n1->value > n2->value)
23319     return 1;
23320   return 0;
23321 }
23322
23323
23324 static int
23325 dump_msg_api_table (vat_main_t * vam)
23326 {
23327   api_main_t *am = &api_main;
23328   name_sort_t *nses = 0, *ns;
23329   hash_pair_t *hp;
23330   int i;
23331
23332   /* *INDENT-OFF* */
23333   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23334   ({
23335     vec_add2 (nses, ns, 1);
23336     ns->name = (u8 *)(hp->key);
23337     ns->value = (u32) hp->value[0];
23338   }));
23339   /* *INDENT-ON* */
23340
23341   vec_sort_with_function (nses, value_sort_cmp);
23342
23343   for (i = 0; i < vec_len (nses); i++)
23344     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23345   vec_free (nses);
23346   return 0;
23347 }
23348
23349 static int
23350 get_msg_id (vat_main_t * vam)
23351 {
23352   u8 *name_and_crc;
23353   u32 message_index;
23354
23355   if (unformat (vam->input, "%s", &name_and_crc))
23356     {
23357       message_index = vl_msg_api_get_msg_index (name_and_crc);
23358       if (message_index == ~0)
23359         {
23360           print (vam->ofp, " '%s' not found", name_and_crc);
23361           return 0;
23362         }
23363       print (vam->ofp, " '%s' has message index %d",
23364              name_and_crc, message_index);
23365       return 0;
23366     }
23367   errmsg ("name_and_crc required...");
23368   return 0;
23369 }
23370
23371 static int
23372 search_node_table (vat_main_t * vam)
23373 {
23374   unformat_input_t *line_input = vam->input;
23375   u8 *node_to_find;
23376   int j;
23377   vlib_node_t *node, *next_node;
23378   uword *p;
23379
23380   if (vam->graph_node_index_by_name == 0)
23381     {
23382       print (vam->ofp, "Node table empty, issue get_node_graph...");
23383       return 0;
23384     }
23385
23386   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23387     {
23388       if (unformat (line_input, "%s", &node_to_find))
23389         {
23390           vec_add1 (node_to_find, 0);
23391           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23392           if (p == 0)
23393             {
23394               print (vam->ofp, "%s not found...", node_to_find);
23395               goto out;
23396             }
23397           node = vam->graph_nodes[p[0]];
23398           print (vam->ofp, "[%d] %s", p[0], node->name);
23399           for (j = 0; j < vec_len (node->next_nodes); j++)
23400             {
23401               if (node->next_nodes[j] != ~0)
23402                 {
23403                   next_node = vam->graph_nodes[node->next_nodes[j]];
23404                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23405                 }
23406             }
23407         }
23408
23409       else
23410         {
23411           clib_warning ("parse error '%U'", format_unformat_error,
23412                         line_input);
23413           return -99;
23414         }
23415
23416     out:
23417       vec_free (node_to_find);
23418
23419     }
23420
23421   return 0;
23422 }
23423
23424
23425 static int
23426 script (vat_main_t * vam)
23427 {
23428 #if (VPP_API_TEST_BUILTIN==0)
23429   u8 *s = 0;
23430   char *save_current_file;
23431   unformat_input_t save_input;
23432   jmp_buf save_jump_buf;
23433   u32 save_line_number;
23434
23435   FILE *new_fp, *save_ifp;
23436
23437   if (unformat (vam->input, "%s", &s))
23438     {
23439       new_fp = fopen ((char *) s, "r");
23440       if (new_fp == 0)
23441         {
23442           errmsg ("Couldn't open script file %s", s);
23443           vec_free (s);
23444           return -99;
23445         }
23446     }
23447   else
23448     {
23449       errmsg ("Missing script name");
23450       return -99;
23451     }
23452
23453   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23454   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23455   save_ifp = vam->ifp;
23456   save_line_number = vam->input_line_number;
23457   save_current_file = (char *) vam->current_file;
23458
23459   vam->input_line_number = 0;
23460   vam->ifp = new_fp;
23461   vam->current_file = s;
23462   do_one_file (vam);
23463
23464   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23465   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23466   vam->ifp = save_ifp;
23467   vam->input_line_number = save_line_number;
23468   vam->current_file = (u8 *) save_current_file;
23469   vec_free (s);
23470
23471   return 0;
23472 #else
23473   clib_warning ("use the exec command...");
23474   return -99;
23475 #endif
23476 }
23477
23478 static int
23479 echo (vat_main_t * vam)
23480 {
23481   print (vam->ofp, "%v", vam->input->buffer);
23482   return 0;
23483 }
23484
23485 /* List of API message constructors, CLI names map to api_xxx */
23486 #define foreach_vpe_api_msg                                             \
23487 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23488 _(sw_interface_dump,"")                                                 \
23489 _(sw_interface_set_flags,                                               \
23490   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23491 _(sw_interface_add_del_address,                                         \
23492   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23493 _(sw_interface_set_rx_mode,                                             \
23494   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23495 _(sw_interface_set_table,                                               \
23496   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23497 _(sw_interface_set_mpls_enable,                                         \
23498   "<intfc> | sw_if_index [disable | dis]")                              \
23499 _(sw_interface_set_vpath,                                               \
23500   "<intfc> | sw_if_index <id> enable | disable")                        \
23501 _(sw_interface_set_vxlan_bypass,                                        \
23502   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23503 _(sw_interface_set_geneve_bypass,                                       \
23504   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23505 _(sw_interface_set_l2_xconnect,                                         \
23506   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23507   "enable | disable")                                                   \
23508 _(sw_interface_set_l2_bridge,                                           \
23509   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23510   "[shg <split-horizon-group>] [bvi]\n"                                 \
23511   "enable | disable")                                                   \
23512 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23513 _(bridge_domain_add_del,                                                \
23514   "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") \
23515 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23516 _(l2fib_add_del,                                                        \
23517   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23518 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23519 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23520 _(l2_flags,                                                             \
23521   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23522 _(bridge_flags,                                                         \
23523   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23524 _(tap_connect,                                                          \
23525   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23526 _(tap_modify,                                                           \
23527   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23528 _(tap_delete,                                                           \
23529   "<vpp-if-name> | sw_if_index <id>")                                   \
23530 _(sw_interface_tap_dump, "")                                            \
23531 _(tap_create_v2,                                                        \
23532   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23533 _(tap_delete_v2,                                                        \
23534   "<vpp-if-name> | sw_if_index <id>")                                   \
23535 _(sw_interface_tap_v2_dump, "")                                         \
23536 _(bond_create,                                                          \
23537   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23538   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23539 _(bond_delete,                                                          \
23540   "<vpp-if-name> | sw_if_index <id>")                                   \
23541 _(bond_enslave,                                                         \
23542   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23543 _(bond_detach_slave,                                                    \
23544   "sw_if_index <n>")                                                    \
23545 _(sw_interface_bond_dump, "")                                           \
23546 _(sw_interface_slave_dump,                                              \
23547   "<vpp-if-name> | sw_if_index <id>")                                   \
23548 _(ip_table_add_del,                                                     \
23549   "table-id <n> [ipv6]\n")                                              \
23550 _(ip_add_del_route,                                                     \
23551   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23552   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23553   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23554   "[multipath] [count <n>]")                                            \
23555 _(ip_mroute_add_del,                                                    \
23556   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23557   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23558 _(mpls_table_add_del,                                                   \
23559   "table-id <n>\n")                                                     \
23560 _(mpls_route_add_del,                                                   \
23561   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23562   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23563   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23564   "[multipath] [count <n>]")                                            \
23565 _(mpls_ip_bind_unbind,                                                  \
23566   "<label> <addr/len>")                                                 \
23567 _(mpls_tunnel_add_del,                                                  \
23568   " via <addr> [table-id <n>]\n"                                        \
23569   "sw_if_index <id>] [l2]  [del]")                                      \
23570 _(bier_table_add_del,                                                   \
23571   "<label> <sub-domain> <set> <bsl> [del]")                             \
23572 _(bier_route_add_del,                                                   \
23573   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23574   "[<intfc> | sw_if_index <id>]"                                        \
23575   "[weight <n>] [del] [multipath]")                                     \
23576 _(proxy_arp_add_del,                                                    \
23577   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23578 _(proxy_arp_intfc_enable_disable,                                       \
23579   "<intfc> | sw_if_index <id> enable | disable")                        \
23580 _(sw_interface_set_unnumbered,                                          \
23581   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23582 _(ip_neighbor_add_del,                                                  \
23583   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23584   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23585 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23586 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23587   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23588   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23589   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23590 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23591 _(reset_fib, "vrf <n> [ipv6]")                                          \
23592 _(dhcp_proxy_config,                                                    \
23593   "svr <v46-address> src <v46-address>\n"                               \
23594    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23595 _(dhcp_proxy_set_vss,                                                   \
23596   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23597 _(dhcp_proxy_dump, "ip6")                                               \
23598 _(dhcp_client_config,                                                   \
23599   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23600 _(set_ip_flow_hash,                                                     \
23601   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23602 _(sw_interface_ip6_enable_disable,                                      \
23603   "<intfc> | sw_if_index <id> enable | disable")                        \
23604 _(sw_interface_ip6_set_link_local_address,                              \
23605   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23606 _(ip6nd_proxy_add_del,                                                  \
23607   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23608 _(ip6nd_proxy_dump, "")                                                 \
23609 _(sw_interface_ip6nd_ra_prefix,                                         \
23610   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23611   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23612   "[nolink] [isno]")                                                    \
23613 _(sw_interface_ip6nd_ra_config,                                         \
23614   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23615   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23616   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23617 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23618 _(l2_patch_add_del,                                                     \
23619   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23620   "enable | disable")                                                   \
23621 _(sr_localsid_add_del,                                                  \
23622   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23623   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23624 _(classify_add_del_table,                                               \
23625   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23626   " [del] [del-chain] mask <mask-value>\n"                              \
23627   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23628   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23629 _(classify_add_del_session,                                             \
23630   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23631   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23632   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23633   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23634 _(classify_set_interface_ip_table,                                      \
23635   "<intfc> | sw_if_index <nn> table <nn>")                              \
23636 _(classify_set_interface_l2_tables,                                     \
23637   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23638   "  [other-table <nn>]")                                               \
23639 _(get_node_index, "node <node-name")                                    \
23640 _(add_node_next, "node <node-name> next <next-node-name>")              \
23641 _(l2tpv3_create_tunnel,                                                 \
23642   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23643   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23644   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23645 _(l2tpv3_set_tunnel_cookies,                                            \
23646   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23647   "[new_remote_cookie <nn>]\n")                                         \
23648 _(l2tpv3_interface_enable_disable,                                      \
23649   "<intfc> | sw_if_index <nn> enable | disable")                        \
23650 _(l2tpv3_set_lookup_key,                                                \
23651   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23652 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23653 _(vxlan_add_del_tunnel,                                                 \
23654   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23655   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23656   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23657 _(geneve_add_del_tunnel,                                                \
23658   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23659   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23660   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23661 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23662 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23663 _(gre_add_del_tunnel,                                                   \
23664   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23665   "[teb | erspan <session-id>] [del]")                                  \
23666 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23667 _(l2_fib_clear_table, "")                                               \
23668 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23669 _(l2_interface_vlan_tag_rewrite,                                        \
23670   "<intfc> | sw_if_index <nn> \n"                                       \
23671   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23672   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23673 _(create_vhost_user_if,                                                 \
23674         "socket <filename> [server] [renumber <dev_instance>] "         \
23675         "[mac <mac_address>]")                                          \
23676 _(modify_vhost_user_if,                                                 \
23677         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23678         "[server] [renumber <dev_instance>]")                           \
23679 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23680 _(sw_interface_vhost_user_dump, "")                                     \
23681 _(show_version, "")                                                     \
23682 _(vxlan_gpe_add_del_tunnel,                                             \
23683   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23684   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23685   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23686   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23687 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23688 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23689 _(interface_name_renumber,                                              \
23690   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23691 _(input_acl_set_interface,                                              \
23692   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23693   "  [l2-table <nn>] [del]")                                            \
23694 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23695 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23696   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23697 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23698 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23699 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23700 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23701 _(ip_dump, "ipv4 | ipv6")                                               \
23702 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23703 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23704   "  spid_id <n> ")                                                     \
23705 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23706   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23707   "  integ_alg <alg> integ_key <hex>")                                  \
23708 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23709   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23710   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23711   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23712 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23713 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23714   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23715   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23716   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23717   "  [instance <n>]")     \
23718 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23719 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23720   "  <alg> <hex>\n")                                                    \
23721 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23722 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23723 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23724   "(auth_data 0x<data> | auth_data <data>)")                            \
23725 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23726   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23727 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23728   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23729   "(local|remote)")                                                     \
23730 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23731 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23732 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23733 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23734 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23735 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23736 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23737 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23738 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23739 _(delete_loopback,"sw_if_index <nn>")                                   \
23740 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23741 _(map_add_domain,                                                       \
23742   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23743   "ip6-src <ip6addr> "                                                  \
23744   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23745 _(map_del_domain, "index <n>")                                          \
23746 _(map_add_del_rule,                                                     \
23747   "index <n> psid <n> dst <ip6addr> [del]")                             \
23748 _(map_domain_dump, "")                                                  \
23749 _(map_rule_dump, "index <map-domain>")                                  \
23750 _(want_interface_events,  "enable|disable")                             \
23751 _(want_stats,"enable|disable")                                          \
23752 _(get_first_msg_id, "client <name>")                                    \
23753 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23754 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23755   "fib-id <nn> [ip4][ip6][default]")                                    \
23756 _(get_node_graph, " ")                                                  \
23757 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23758 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23759 _(ioam_disable, "")                                                     \
23760 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23761                             " sw_if_index <sw_if_index> p <priority> "  \
23762                             "w <weight>] [del]")                        \
23763 _(one_add_del_locator, "locator-set <locator_name> "                    \
23764                         "iface <intf> | sw_if_index <sw_if_index> "     \
23765                         "p <priority> w <weight> [del]")                \
23766 _(one_add_del_local_eid,"vni <vni> eid "                                \
23767                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23768                          "locator-set <locator_name> [del]"             \
23769                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23770 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23771 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23772 _(one_enable_disable, "enable|disable")                                 \
23773 _(one_map_register_enable_disable, "enable|disable")                    \
23774 _(one_map_register_fallback_threshold, "<value>")                       \
23775 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23776 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23777                                "[seid <seid>] "                         \
23778                                "rloc <locator> p <prio> "               \
23779                                "w <weight> [rloc <loc> ... ] "          \
23780                                "action <action> [del-all]")             \
23781 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23782                           "<local-eid>")                                \
23783 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23784 _(one_use_petr, "ip-address> | disable")                                \
23785 _(one_map_request_mode, "src-dst|dst-only")                             \
23786 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23787 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23788 _(one_locator_set_dump, "[local | remote]")                             \
23789 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23790 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23791                        "[local] | [remote]")                            \
23792 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23793 _(one_ndp_bd_get, "")                                                   \
23794 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23795 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23796 _(one_l2_arp_bd_get, "")                                                \
23797 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23798 _(one_stats_enable_disable, "enable|disalbe")                           \
23799 _(show_one_stats_enable_disable, "")                                    \
23800 _(one_eid_table_vni_dump, "")                                           \
23801 _(one_eid_table_map_dump, "l2|l3")                                      \
23802 _(one_map_resolver_dump, "")                                            \
23803 _(one_map_server_dump, "")                                              \
23804 _(one_adjacencies_get, "vni <vni>")                                     \
23805 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23806 _(show_one_rloc_probe_state, "")                                        \
23807 _(show_one_map_register_state, "")                                      \
23808 _(show_one_status, "")                                                  \
23809 _(one_stats_dump, "")                                                   \
23810 _(one_stats_flush, "")                                                  \
23811 _(one_get_map_request_itr_rlocs, "")                                    \
23812 _(one_map_register_set_ttl, "<ttl>")                                    \
23813 _(one_set_transport_protocol, "udp|api")                                \
23814 _(one_get_transport_protocol, "")                                       \
23815 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23816 _(one_show_xtr_mode, "")                                                \
23817 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23818 _(one_show_pitr_mode, "")                                               \
23819 _(one_enable_disable_petr_mode, "enable|disable")                       \
23820 _(one_show_petr_mode, "")                                               \
23821 _(show_one_nsh_mapping, "")                                             \
23822 _(show_one_pitr, "")                                                    \
23823 _(show_one_use_petr, "")                                                \
23824 _(show_one_map_request_mode, "")                                        \
23825 _(show_one_map_register_ttl, "")                                        \
23826 _(show_one_map_register_fallback_threshold, "")                         \
23827 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23828                             " sw_if_index <sw_if_index> p <priority> "  \
23829                             "w <weight>] [del]")                        \
23830 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23831                         "iface <intf> | sw_if_index <sw_if_index> "     \
23832                         "p <priority> w <weight> [del]")                \
23833 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23834                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23835                          "locator-set <locator_name> [del]"             \
23836                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23837 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23838 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23839 _(lisp_enable_disable, "enable|disable")                                \
23840 _(lisp_map_register_enable_disable, "enable|disable")                   \
23841 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23842 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23843                                "[seid <seid>] "                         \
23844                                "rloc <locator> p <prio> "               \
23845                                "w <weight> [rloc <loc> ... ] "          \
23846                                "action <action> [del-all]")             \
23847 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23848                           "<local-eid>")                                \
23849 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23850 _(lisp_use_petr, "<ip-address> | disable")                              \
23851 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23852 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23853 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23854 _(lisp_locator_set_dump, "[local | remote]")                            \
23855 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23856 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23857                        "[local] | [remote]")                            \
23858 _(lisp_eid_table_vni_dump, "")                                          \
23859 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23860 _(lisp_map_resolver_dump, "")                                           \
23861 _(lisp_map_server_dump, "")                                             \
23862 _(lisp_adjacencies_get, "vni <vni>")                                    \
23863 _(gpe_fwd_entry_vnis_get, "")                                           \
23864 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23865 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23866                                 "[table <table-id>]")                   \
23867 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23868 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23869 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23870 _(gpe_get_encap_mode, "")                                               \
23871 _(lisp_gpe_add_del_iface, "up|down")                                    \
23872 _(lisp_gpe_enable_disable, "enable|disable")                            \
23873 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23874   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23875 _(show_lisp_rloc_probe_state, "")                                       \
23876 _(show_lisp_map_register_state, "")                                     \
23877 _(show_lisp_status, "")                                                 \
23878 _(lisp_get_map_request_itr_rlocs, "")                                   \
23879 _(show_lisp_pitr, "")                                                   \
23880 _(show_lisp_use_petr, "")                                               \
23881 _(show_lisp_map_request_mode, "")                                       \
23882 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23883 _(af_packet_delete, "name <host interface name>")                       \
23884 _(af_packet_dump, "")                                                   \
23885 _(policer_add_del, "name <policer name> <params> [del]")                \
23886 _(policer_dump, "[name <policer name>]")                                \
23887 _(policer_classify_set_interface,                                       \
23888   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23889   "  [l2-table <nn>] [del]")                                            \
23890 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23891 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23892     "[master|slave]")                                                   \
23893 _(netmap_delete, "name <interface name>")                               \
23894 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23895 _(mpls_fib_dump, "")                                                    \
23896 _(classify_table_ids, "")                                               \
23897 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23898 _(classify_table_info, "table_id <nn>")                                 \
23899 _(classify_session_dump, "table_id <nn>")                               \
23900 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23901     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23902     "[template_interval <nn>] [udp_checksum]")                          \
23903 _(ipfix_exporter_dump, "")                                              \
23904 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23905 _(ipfix_classify_stream_dump, "")                                       \
23906 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23907 _(ipfix_classify_table_dump, "")                                        \
23908 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23909 _(sw_interface_span_dump, "[l2]")                                           \
23910 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23911 _(pg_create_interface, "if_id <nn>")                                    \
23912 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23913 _(pg_enable_disable, "[stream <id>] disable")                           \
23914 _(ip_source_and_port_range_check_add_del,                               \
23915   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23916 _(ip_source_and_port_range_check_interface_add_del,                     \
23917   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23918   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23919 _(ipsec_gre_add_del_tunnel,                                             \
23920   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23921 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23922 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23923 _(l2_interface_pbb_tag_rewrite,                                         \
23924   "<intfc> | sw_if_index <nn> \n"                                       \
23925   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23926   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23927 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23928 _(flow_classify_set_interface,                                          \
23929   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23930 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23931 _(ip_fib_dump, "")                                                      \
23932 _(ip_mfib_dump, "")                                                     \
23933 _(ip6_fib_dump, "")                                                     \
23934 _(ip6_mfib_dump, "")                                                    \
23935 _(feature_enable_disable, "arc_name <arc_name> "                        \
23936   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23937 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23938 "[disable]")                                                            \
23939 _(l2_xconnect_dump, "")                                                 \
23940 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23941 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23942 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23943 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23944 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23945 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23946 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23947   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23948 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23949 _(sock_init_shm, "size <nnn>")                                          \
23950 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23951 _(dns_enable_disable, "[enable][disable]")                              \
23952 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23953 _(dns_resolve_name, "<hostname>")                                       \
23954 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23955 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23956 _(dns_resolve_name, "<hostname>")                                       \
23957 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23958   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23959 _(session_rules_dump, "")                                               \
23960 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23961 _(output_acl_set_interface,                                             \
23962   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23963   "  [l2-table <nn>] [del]")                                            \
23964 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]") \
23965 _(map_stats_segment, "<no-args>")
23966
23967 /* List of command functions, CLI names map directly to functions */
23968 #define foreach_cli_function                                    \
23969 _(comment, "usage: comment <ignore-rest-of-line>")              \
23970 _(dump_interface_table, "usage: dump_interface_table")          \
23971 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23972 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23973 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23974 _(dump_stats_table, "usage: dump_stats_table")                  \
23975 _(dump_macro_table, "usage: dump_macro_table ")                 \
23976 _(dump_node_table, "usage: dump_node_table")                    \
23977 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23978 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23979 _(echo, "usage: echo <message>")                                \
23980 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23981 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23982 _(help, "usage: help")                                          \
23983 _(q, "usage: quit")                                             \
23984 _(quit, "usage: quit")                                          \
23985 _(search_node_table, "usage: search_node_table <name>...")      \
23986 _(set, "usage: set <variable-name> <value>")                    \
23987 _(script, "usage: script <file-name>")                          \
23988 _(statseg, "usage: statseg");                                   \
23989 _(unset, "usage: unset <variable-name>")
23990
23991 #define _(N,n)                                  \
23992     static void vl_api_##n##_t_handler_uni      \
23993     (vl_api_##n##_t * mp)                       \
23994     {                                           \
23995         vat_main_t * vam = &vat_main;           \
23996         if (vam->json_output) {                 \
23997             vl_api_##n##_t_handler_json(mp);    \
23998         } else {                                \
23999             vl_api_##n##_t_handler(mp);         \
24000         }                                       \
24001     }
24002 foreach_vpe_api_reply_msg;
24003 #if VPP_API_TEST_BUILTIN == 0
24004 foreach_standalone_reply_msg;
24005 #endif
24006 #undef _
24007
24008 void
24009 vat_api_hookup (vat_main_t * vam)
24010 {
24011 #define _(N,n)                                                  \
24012     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24013                            vl_api_##n##_t_handler_uni,          \
24014                            vl_noop_handler,                     \
24015                            vl_api_##n##_t_endian,               \
24016                            vl_api_##n##_t_print,                \
24017                            sizeof(vl_api_##n##_t), 1);
24018   foreach_vpe_api_reply_msg;
24019 #if VPP_API_TEST_BUILTIN == 0
24020   foreach_standalone_reply_msg;
24021 #endif
24022 #undef _
24023
24024 #if (VPP_API_TEST_BUILTIN==0)
24025   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24026
24027   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24028
24029   vam->function_by_name = hash_create_string (0, sizeof (uword));
24030
24031   vam->help_by_name = hash_create_string (0, sizeof (uword));
24032 #endif
24033
24034   /* API messages we can send */
24035 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24036   foreach_vpe_api_msg;
24037 #undef _
24038
24039   /* Help strings */
24040 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24041   foreach_vpe_api_msg;
24042 #undef _
24043
24044   /* CLI functions */
24045 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24046   foreach_cli_function;
24047 #undef _
24048
24049   /* Help strings */
24050 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24051   foreach_cli_function;
24052 #undef _
24053 }
24054
24055 #if VPP_API_TEST_BUILTIN
24056 static clib_error_t *
24057 vat_api_hookup_shim (vlib_main_t * vm)
24058 {
24059   vat_api_hookup (&vat_main);
24060   return 0;
24061 }
24062
24063 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24064 #endif
24065
24066 /*
24067  * fd.io coding-style-patch-verification: ON
24068  *
24069  * Local Variables:
24070  * eval: (c-set-style "gnu")
24071  * End:
24072  */