Periodic scan and probe of IP neighbors to maintain neighbor pools
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/ip/ip_neighbor.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/in_out_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include "vat/json_format.h"
57
58 #include <inttypes.h>
59 #include <sys/stat.h>
60
61 #define vl_typedefs             /* define message structures */
62 #include <vpp/api/vpe_all_api_h.h>
63 #undef vl_typedefs
64
65 /* declare message handlers for each api */
66
67 #define vl_endianfun            /* define message structures */
68 #include <vpp/api/vpe_all_api_h.h>
69 #undef vl_endianfun
70
71 /* instantiate all the print functions we know about */
72 #define vl_print(handle, ...)
73 #define vl_printfun
74 #include <vpp/api/vpe_all_api_h.h>
75 #undef vl_printfun
76
77 #define __plugin_msg_base 0
78 #include <vlibapi/vat_helper_macros.h>
79
80 #if VPP_API_TEST_BUILTIN == 0
81 #include <netdb.h>
82
83 u32
84 vl (void *p)
85 {
86   return vec_len (p);
87 }
88
89 int
90 vat_socket_connect (vat_main_t * vam)
91 {
92   vam->socket_client_main = &socket_client_main;
93   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
94                                    0 /* default socket rx, tx buffer */ );
95 }
96 #else /* vpp built-in case, we don't do sockets... */
97 int
98 vat_socket_connect (vat_main_t * vam)
99 {
100   return 0;
101 }
102
103 int
104 vl_socket_client_read (int wait)
105 {
106   return -1;
107 };
108
109 int
110 vl_socket_client_write ()
111 {
112   return -1;
113 };
114
115 void *
116 vl_socket_client_msg_alloc (int nbytes)
117 {
118   return 0;
119 }
120 #endif
121
122
123 f64
124 vat_time_now (vat_main_t * vam)
125 {
126 #if VPP_API_TEST_BUILTIN
127   return vlib_time_now (vam->vlib_main);
128 #else
129   return clib_time_now (&vam->clib_time);
130 #endif
131 }
132
133 void
134 errmsg (char *fmt, ...)
135 {
136   vat_main_t *vam = &vat_main;
137   va_list va;
138   u8 *s;
139
140   va_start (va, fmt);
141   s = va_format (0, fmt, &va);
142   va_end (va);
143
144   vec_add1 (s, 0);
145
146 #if VPP_API_TEST_BUILTIN
147   vlib_cli_output (vam->vlib_main, (char *) s);
148 #else
149   {
150     if (vam->ifp != stdin)
151       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
152                vam->input_line_number);
153     fformat (vam->ofp, (char *) s);
154     fflush (vam->ofp);
155   }
156 #endif
157
158   vec_free (s);
159 }
160
161 #if VPP_API_TEST_BUILTIN == 0
162 static uword
163 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
164 {
165   vat_main_t *vam = va_arg (*args, vat_main_t *);
166   u32 *result = va_arg (*args, u32 *);
167   u8 *if_name;
168   uword *p;
169
170   if (!unformat (input, "%s", &if_name))
171     return 0;
172
173   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
174   if (p == 0)
175     return 0;
176   *result = p[0];
177   return 1;
178 }
179
180 /* Parse an IP4 address %d.%d.%d.%d. */
181 uword
182 unformat_ip4_address (unformat_input_t * input, va_list * args)
183 {
184   u8 *result = va_arg (*args, u8 *);
185   unsigned a[4];
186
187   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
188     return 0;
189
190   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
191     return 0;
192
193   result[0] = a[0];
194   result[1] = a[1];
195   result[2] = a[2];
196   result[3] = a[3];
197
198   return 1;
199 }
200
201 uword
202 unformat_ethernet_address (unformat_input_t * input, va_list * args)
203 {
204   u8 *result = va_arg (*args, u8 *);
205   u32 i, a[6];
206
207   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
208                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
209     return 0;
210
211   /* Check range. */
212   for (i = 0; i < 6; i++)
213     if (a[i] >= (1 << 8))
214       return 0;
215
216   for (i = 0; i < 6; i++)
217     result[i] = a[i];
218
219   return 1;
220 }
221
222 /* Returns ethernet type as an int in host byte order. */
223 uword
224 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
225                                         va_list * args)
226 {
227   u16 *result = va_arg (*args, u16 *);
228   int type;
229
230   /* Numeric type. */
231   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
232     {
233       if (type >= (1 << 16))
234         return 0;
235       *result = type;
236       return 1;
237     }
238   return 0;
239 }
240
241 /* Parse an IP6 address. */
242 uword
243 unformat_ip6_address (unformat_input_t * input, va_list * args)
244 {
245   ip6_address_t *result = va_arg (*args, ip6_address_t *);
246   u16 hex_quads[8];
247   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
248   uword c, n_colon, double_colon_index;
249
250   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
251   double_colon_index = ARRAY_LEN (hex_quads);
252   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
253     {
254       hex_digit = 16;
255       if (c >= '0' && c <= '9')
256         hex_digit = c - '0';
257       else if (c >= 'a' && c <= 'f')
258         hex_digit = c + 10 - 'a';
259       else if (c >= 'A' && c <= 'F')
260         hex_digit = c + 10 - 'A';
261       else if (c == ':' && n_colon < 2)
262         n_colon++;
263       else
264         {
265           unformat_put_input (input);
266           break;
267         }
268
269       /* Too many hex quads. */
270       if (n_hex_quads >= ARRAY_LEN (hex_quads))
271         return 0;
272
273       if (hex_digit < 16)
274         {
275           hex_quad = (hex_quad << 4) | hex_digit;
276
277           /* Hex quad must fit in 16 bits. */
278           if (n_hex_digits >= 4)
279             return 0;
280
281           n_colon = 0;
282           n_hex_digits++;
283         }
284
285       /* Save position of :: */
286       if (n_colon == 2)
287         {
288           /* More than one :: ? */
289           if (double_colon_index < ARRAY_LEN (hex_quads))
290             return 0;
291           double_colon_index = n_hex_quads;
292         }
293
294       if (n_colon > 0 && n_hex_digits > 0)
295         {
296           hex_quads[n_hex_quads++] = hex_quad;
297           hex_quad = 0;
298           n_hex_digits = 0;
299         }
300     }
301
302   if (n_hex_digits > 0)
303     hex_quads[n_hex_quads++] = hex_quad;
304
305   {
306     word i;
307
308     /* Expand :: to appropriate number of zero hex quads. */
309     if (double_colon_index < ARRAY_LEN (hex_quads))
310       {
311         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
312
313         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
314           hex_quads[n_zero + i] = hex_quads[i];
315
316         for (i = 0; i < n_zero; i++)
317           hex_quads[double_colon_index + i] = 0;
318
319         n_hex_quads = ARRAY_LEN (hex_quads);
320       }
321
322     /* Too few hex quads given. */
323     if (n_hex_quads < ARRAY_LEN (hex_quads))
324       return 0;
325
326     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
327       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
328
329     return 1;
330   }
331 }
332
333 uword
334 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
335 {
336   u32 *r = va_arg (*args, u32 *);
337
338   if (0);
339 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
340   foreach_ipsec_policy_action
341 #undef _
342     else
343     return 0;
344   return 1;
345 }
346
347 uword
348 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
349 {
350   u32 *r = va_arg (*args, u32 *);
351
352   if (0);
353 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
354   foreach_ipsec_crypto_alg
355 #undef _
356     else
357     return 0;
358   return 1;
359 }
360
361 u8 *
362 format_ipsec_crypto_alg (u8 * s, va_list * args)
363 {
364   u32 i = va_arg (*args, u32);
365   u8 *t = 0;
366
367   switch (i)
368     {
369 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
370       foreach_ipsec_crypto_alg
371 #undef _
372     default:
373       return format (s, "unknown");
374     }
375   return format (s, "%s", t);
376 }
377
378 uword
379 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
380 {
381   u32 *r = va_arg (*args, u32 *);
382
383   if (0);
384 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
385   foreach_ipsec_integ_alg
386 #undef _
387     else
388     return 0;
389   return 1;
390 }
391
392 u8 *
393 format_ipsec_integ_alg (u8 * s, va_list * args)
394 {
395   u32 i = va_arg (*args, u32);
396   u8 *t = 0;
397
398   switch (i)
399     {
400 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
401       foreach_ipsec_integ_alg
402 #undef _
403     default:
404       return format (s, "unknown");
405     }
406   return format (s, "%s", t);
407 }
408
409 uword
410 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
411 {
412   u32 *r = va_arg (*args, u32 *);
413
414   if (0);
415 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
416   foreach_ikev2_auth_method
417 #undef _
418     else
419     return 0;
420   return 1;
421 }
422
423 uword
424 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
425 {
426   u32 *r = va_arg (*args, u32 *);
427
428   if (0);
429 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
430   foreach_ikev2_id_type
431 #undef _
432     else
433     return 0;
434   return 1;
435 }
436 #else /* VPP_API_TEST_BUILTIN == 1 */
437 static uword
438 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
439 {
440   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
441   vnet_main_t *vnm = vnet_get_main ();
442   u32 *result = va_arg (*args, u32 *);
443   u32 sw_if_index;
444
445   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
446     return 0;
447
448   *result = sw_if_index;
449   return 1;
450 }
451 #endif /* VPP_API_TEST_BUILTIN */
452
453 static uword
454 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "kbps"))
459     *r = SSE2_QOS_RATE_KBPS;
460   else if (unformat (input, "pps"))
461     *r = SSE2_QOS_RATE_PPS;
462   else
463     return 0;
464   return 1;
465 }
466
467 static uword
468 unformat_policer_round_type (unformat_input_t * input, va_list * args)
469 {
470   u8 *r = va_arg (*args, u8 *);
471
472   if (unformat (input, "closest"))
473     *r = SSE2_QOS_ROUND_TO_CLOSEST;
474   else if (unformat (input, "up"))
475     *r = SSE2_QOS_ROUND_TO_UP;
476   else if (unformat (input, "down"))
477     *r = SSE2_QOS_ROUND_TO_DOWN;
478   else
479     return 0;
480   return 1;
481 }
482
483 static uword
484 unformat_policer_type (unformat_input_t * input, va_list * args)
485 {
486   u8 *r = va_arg (*args, u8 *);
487
488   if (unformat (input, "1r2c"))
489     *r = SSE2_QOS_POLICER_TYPE_1R2C;
490   else if (unformat (input, "1r3c"))
491     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
492   else if (unformat (input, "2r3c-2698"))
493     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
494   else if (unformat (input, "2r3c-4115"))
495     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
496   else if (unformat (input, "2r3c-mef5cf1"))
497     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
498   else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_dscp (unformat_input_t * input, va_list * va)
505 {
506   u8 *r = va_arg (*va, u8 *);
507
508   if (0);
509 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
510   foreach_vnet_dscp
511 #undef _
512     else
513     return 0;
514   return 1;
515 }
516
517 static uword
518 unformat_policer_action_type (unformat_input_t * input, va_list * va)
519 {
520   sse2_qos_pol_action_params_st *a
521     = va_arg (*va, sse2_qos_pol_action_params_st *);
522
523   if (unformat (input, "drop"))
524     a->action_type = SSE2_QOS_ACTION_DROP;
525   else if (unformat (input, "transmit"))
526     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
527   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
528     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
529   else
530     return 0;
531   return 1;
532 }
533
534 static uword
535 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
536 {
537   u32 *r = va_arg (*va, u32 *);
538   u32 tid;
539
540   if (unformat (input, "ip4"))
541     tid = POLICER_CLASSIFY_TABLE_IP4;
542   else if (unformat (input, "ip6"))
543     tid = POLICER_CLASSIFY_TABLE_IP6;
544   else if (unformat (input, "l2"))
545     tid = POLICER_CLASSIFY_TABLE_L2;
546   else
547     return 0;
548
549   *r = tid;
550   return 1;
551 }
552
553 static uword
554 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
555 {
556   u32 *r = va_arg (*va, u32 *);
557   u32 tid;
558
559   if (unformat (input, "ip4"))
560     tid = FLOW_CLASSIFY_TABLE_IP4;
561   else if (unformat (input, "ip6"))
562     tid = FLOW_CLASSIFY_TABLE_IP6;
563   else
564     return 0;
565
566   *r = tid;
567   return 1;
568 }
569
570 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
571 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
572 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
573 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
574
575 #if (VPP_API_TEST_BUILTIN==0)
576 uword
577 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
578 {
579   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
580   mfib_itf_attribute_t attr;
581
582   old = *iflags;
583   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
584   {
585     if (unformat (input, mfib_itf_flag_long_names[attr]))
586       *iflags |= (1 << attr);
587   }
588   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
589   {
590     if (unformat (input, mfib_itf_flag_names[attr]))
591       *iflags |= (1 << attr);
592   }
593
594   return (old == *iflags ? 0 : 1);
595 }
596
597 uword
598 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
599 {
600   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
601   mfib_entry_attribute_t attr;
602
603   old = *eflags;
604   FOR_EACH_MFIB_ATTRIBUTE (attr)
605   {
606     if (unformat (input, mfib_flag_long_names[attr]))
607       *eflags |= (1 << attr);
608   }
609   FOR_EACH_MFIB_ATTRIBUTE (attr)
610   {
611     if (unformat (input, mfib_flag_names[attr]))
612       *eflags |= (1 << attr);
613   }
614
615   return (old == *eflags ? 0 : 1);
616 }
617
618 u8 *
619 format_ip4_address (u8 * s, va_list * args)
620 {
621   u8 *a = va_arg (*args, u8 *);
622   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
623 }
624
625 u8 *
626 format_ip6_address (u8 * s, va_list * args)
627 {
628   ip6_address_t *a = va_arg (*args, ip6_address_t *);
629   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
630
631   i_max_n_zero = ARRAY_LEN (a->as_u16);
632   max_n_zeros = 0;
633   i_first_zero = i_max_n_zero;
634   n_zeros = 0;
635   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
636     {
637       u32 is_zero = a->as_u16[i] == 0;
638       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
639         {
640           i_first_zero = i;
641           n_zeros = 0;
642         }
643       n_zeros += is_zero;
644       if ((!is_zero && n_zeros > max_n_zeros)
645           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
646         {
647           i_max_n_zero = i_first_zero;
648           max_n_zeros = n_zeros;
649           i_first_zero = ARRAY_LEN (a->as_u16);
650           n_zeros = 0;
651         }
652     }
653
654   last_double_colon = 0;
655   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
656     {
657       if (i == i_max_n_zero && max_n_zeros > 1)
658         {
659           s = format (s, "::");
660           i += max_n_zeros - 1;
661           last_double_colon = 1;
662         }
663       else
664         {
665           s = format (s, "%s%x",
666                       (last_double_colon || i == 0) ? "" : ":",
667                       clib_net_to_host_u16 (a->as_u16[i]));
668           last_double_colon = 0;
669         }
670     }
671
672   return s;
673 }
674
675 /* Format an IP46 address. */
676 u8 *
677 format_ip46_address (u8 * s, va_list * args)
678 {
679   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
680   ip46_type_t type = va_arg (*args, ip46_type_t);
681   int is_ip4 = 1;
682
683   switch (type)
684     {
685     case IP46_TYPE_ANY:
686       is_ip4 = ip46_address_is_ip4 (ip46);
687       break;
688     case IP46_TYPE_IP4:
689       is_ip4 = 1;
690       break;
691     case IP46_TYPE_IP6:
692       is_ip4 = 0;
693       break;
694     }
695
696   return is_ip4 ?
697     format (s, "%U", format_ip4_address, &ip46->ip4) :
698     format (s, "%U", format_ip6_address, &ip46->ip6);
699 }
700
701 u8 *
702 format_ethernet_address (u8 * s, va_list * args)
703 {
704   u8 *a = va_arg (*args, u8 *);
705
706   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
707                  a[0], a[1], a[2], a[3], a[4], a[5]);
708 }
709 #endif
710
711 static void
712 increment_v4_address (ip4_address_t * a)
713 {
714   u32 v;
715
716   v = ntohl (a->as_u32) + 1;
717   a->as_u32 = ntohl (v);
718 }
719
720 static void
721 increment_v6_address (ip6_address_t * a)
722 {
723   u64 v0, v1;
724
725   v0 = clib_net_to_host_u64 (a->as_u64[0]);
726   v1 = clib_net_to_host_u64 (a->as_u64[1]);
727
728   v1 += 1;
729   if (v1 == 0)
730     v0 += 1;
731   a->as_u64[0] = clib_net_to_host_u64 (v0);
732   a->as_u64[1] = clib_net_to_host_u64 (v1);
733 }
734
735 static void
736 increment_mac_address (u8 * mac)
737 {
738   u64 tmp = *((u64 *) mac);
739   tmp = clib_net_to_host_u64 (tmp);
740   tmp += 1 << 16;               /* skip unused (least significant) octets */
741   tmp = clib_host_to_net_u64 (tmp);
742
743   clib_memcpy (mac, &tmp, 6);
744 }
745
746 static void vl_api_create_loopback_reply_t_handler
747   (vl_api_create_loopback_reply_t * mp)
748 {
749   vat_main_t *vam = &vat_main;
750   i32 retval = ntohl (mp->retval);
751
752   vam->retval = retval;
753   vam->regenerate_interface_table = 1;
754   vam->sw_if_index = ntohl (mp->sw_if_index);
755   vam->result_ready = 1;
756 }
757
758 static void vl_api_create_loopback_reply_t_handler_json
759   (vl_api_create_loopback_reply_t * mp)
760 {
761   vat_main_t *vam = &vat_main;
762   vat_json_node_t node;
763
764   vat_json_init_object (&node);
765   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
766   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
767
768   vat_json_print (vam->ofp, &node);
769   vat_json_free (&node);
770   vam->retval = ntohl (mp->retval);
771   vam->result_ready = 1;
772 }
773
774 static void vl_api_create_loopback_instance_reply_t_handler
775   (vl_api_create_loopback_instance_reply_t * mp)
776 {
777   vat_main_t *vam = &vat_main;
778   i32 retval = ntohl (mp->retval);
779
780   vam->retval = retval;
781   vam->regenerate_interface_table = 1;
782   vam->sw_if_index = ntohl (mp->sw_if_index);
783   vam->result_ready = 1;
784 }
785
786 static void vl_api_create_loopback_instance_reply_t_handler_json
787   (vl_api_create_loopback_instance_reply_t * mp)
788 {
789   vat_main_t *vam = &vat_main;
790   vat_json_node_t node;
791
792   vat_json_init_object (&node);
793   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
794   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
795
796   vat_json_print (vam->ofp, &node);
797   vat_json_free (&node);
798   vam->retval = ntohl (mp->retval);
799   vam->result_ready = 1;
800 }
801
802 static void vl_api_af_packet_create_reply_t_handler
803   (vl_api_af_packet_create_reply_t * mp)
804 {
805   vat_main_t *vam = &vat_main;
806   i32 retval = ntohl (mp->retval);
807
808   vam->retval = retval;
809   vam->regenerate_interface_table = 1;
810   vam->sw_if_index = ntohl (mp->sw_if_index);
811   vam->result_ready = 1;
812 }
813
814 static void vl_api_af_packet_create_reply_t_handler_json
815   (vl_api_af_packet_create_reply_t * mp)
816 {
817   vat_main_t *vam = &vat_main;
818   vat_json_node_t node;
819
820   vat_json_init_object (&node);
821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
822   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
823
824   vat_json_print (vam->ofp, &node);
825   vat_json_free (&node);
826
827   vam->retval = ntohl (mp->retval);
828   vam->result_ready = 1;
829 }
830
831 static void vl_api_create_vlan_subif_reply_t_handler
832   (vl_api_create_vlan_subif_reply_t * mp)
833 {
834   vat_main_t *vam = &vat_main;
835   i32 retval = ntohl (mp->retval);
836
837   vam->retval = retval;
838   vam->regenerate_interface_table = 1;
839   vam->sw_if_index = ntohl (mp->sw_if_index);
840   vam->result_ready = 1;
841 }
842
843 static void vl_api_create_vlan_subif_reply_t_handler_json
844   (vl_api_create_vlan_subif_reply_t * mp)
845 {
846   vat_main_t *vam = &vat_main;
847   vat_json_node_t node;
848
849   vat_json_init_object (&node);
850   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
851   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
852
853   vat_json_print (vam->ofp, &node);
854   vat_json_free (&node);
855
856   vam->retval = ntohl (mp->retval);
857   vam->result_ready = 1;
858 }
859
860 static void vl_api_create_subif_reply_t_handler
861   (vl_api_create_subif_reply_t * mp)
862 {
863   vat_main_t *vam = &vat_main;
864   i32 retval = ntohl (mp->retval);
865
866   vam->retval = retval;
867   vam->regenerate_interface_table = 1;
868   vam->sw_if_index = ntohl (mp->sw_if_index);
869   vam->result_ready = 1;
870 }
871
872 static void vl_api_create_subif_reply_t_handler_json
873   (vl_api_create_subif_reply_t * mp)
874 {
875   vat_main_t *vam = &vat_main;
876   vat_json_node_t node;
877
878   vat_json_init_object (&node);
879   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
880   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
881
882   vat_json_print (vam->ofp, &node);
883   vat_json_free (&node);
884
885   vam->retval = ntohl (mp->retval);
886   vam->result_ready = 1;
887 }
888
889 static void vl_api_interface_name_renumber_reply_t_handler
890   (vl_api_interface_name_renumber_reply_t * mp)
891 {
892   vat_main_t *vam = &vat_main;
893   i32 retval = ntohl (mp->retval);
894
895   vam->retval = retval;
896   vam->regenerate_interface_table = 1;
897   vam->result_ready = 1;
898 }
899
900 static void vl_api_interface_name_renumber_reply_t_handler_json
901   (vl_api_interface_name_renumber_reply_t * mp)
902 {
903   vat_main_t *vam = &vat_main;
904   vat_json_node_t node;
905
906   vat_json_init_object (&node);
907   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
908
909   vat_json_print (vam->ofp, &node);
910   vat_json_free (&node);
911
912   vam->retval = ntohl (mp->retval);
913   vam->result_ready = 1;
914 }
915
916 /*
917  * Special-case: build the interface table, maintain
918  * the next loopback sw_if_index vbl.
919  */
920 static void vl_api_sw_interface_details_t_handler
921   (vl_api_sw_interface_details_t * mp)
922 {
923   vat_main_t *vam = &vat_main;
924   u8 *s = format (0, "%s%c", mp->interface_name, 0);
925
926   hash_set_mem (vam->sw_if_index_by_interface_name, s,
927                 ntohl (mp->sw_if_index));
928
929   /* In sub interface case, fill the sub interface table entry */
930   if (mp->sw_if_index != mp->sup_sw_if_index)
931     {
932       sw_interface_subif_t *sub = NULL;
933
934       vec_add2 (vam->sw_if_subif_table, sub, 1);
935
936       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
937       strncpy ((char *) sub->interface_name, (char *) s,
938                vec_len (sub->interface_name));
939       sub->sw_if_index = ntohl (mp->sw_if_index);
940       sub->sub_id = ntohl (mp->sub_id);
941
942       sub->sub_dot1ad = mp->sub_dot1ad;
943       sub->sub_number_of_tags = mp->sub_number_of_tags;
944       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
945       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
946       sub->sub_exact_match = mp->sub_exact_match;
947       sub->sub_default = mp->sub_default;
948       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
949       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
950
951       /* vlan tag rewrite */
952       sub->vtr_op = ntohl (mp->vtr_op);
953       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
954       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
955       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
956     }
957 }
958
959 static void vl_api_sw_interface_details_t_handler_json
960   (vl_api_sw_interface_details_t * mp)
961 {
962   vat_main_t *vam = &vat_main;
963   vat_json_node_t *node = NULL;
964
965   if (VAT_JSON_ARRAY != vam->json_tree.type)
966     {
967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
968       vat_json_init_array (&vam->json_tree);
969     }
970   node = vat_json_array_add (&vam->json_tree);
971
972   vat_json_init_object (node);
973   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
974   vat_json_object_add_uint (node, "sup_sw_if_index",
975                             ntohl (mp->sup_sw_if_index));
976   vat_json_object_add_uint (node, "l2_address_length",
977                             ntohl (mp->l2_address_length));
978   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
979                              sizeof (mp->l2_address));
980   vat_json_object_add_string_copy (node, "interface_name",
981                                    mp->interface_name);
982   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
983   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
984   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
985   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
986   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
987   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
988   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
989   vat_json_object_add_uint (node, "sub_number_of_tags",
990                             mp->sub_number_of_tags);
991   vat_json_object_add_uint (node, "sub_outer_vlan_id",
992                             ntohs (mp->sub_outer_vlan_id));
993   vat_json_object_add_uint (node, "sub_inner_vlan_id",
994                             ntohs (mp->sub_inner_vlan_id));
995   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
996   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
997   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
998                             mp->sub_outer_vlan_id_any);
999   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1000                             mp->sub_inner_vlan_id_any);
1001   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1002   vat_json_object_add_uint (node, "vtr_push_dot1q",
1003                             ntohl (mp->vtr_push_dot1q));
1004   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1005   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1006   if (mp->sub_dot1ah)
1007     {
1008       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1009                                        format (0, "%U",
1010                                                format_ethernet_address,
1011                                                &mp->b_dmac));
1012       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1013                                        format (0, "%U",
1014                                                format_ethernet_address,
1015                                                &mp->b_smac));
1016       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1017       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1018     }
1019 }
1020
1021 #if VPP_API_TEST_BUILTIN == 0
1022 static void vl_api_sw_interface_event_t_handler
1023   (vl_api_sw_interface_event_t * mp)
1024 {
1025   vat_main_t *vam = &vat_main;
1026   if (vam->interface_event_display)
1027     errmsg ("interface flags: sw_if_index %d %s %s",
1028             ntohl (mp->sw_if_index),
1029             mp->admin_up_down ? "admin-up" : "admin-down",
1030             mp->link_up_down ? "link-up" : "link-down");
1031 }
1032 #endif
1033
1034 static void vl_api_sw_interface_event_t_handler_json
1035   (vl_api_sw_interface_event_t * mp)
1036 {
1037   /* JSON output not supported */
1038 }
1039
1040 static void
1041 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1042 {
1043   vat_main_t *vam = &vat_main;
1044   i32 retval = ntohl (mp->retval);
1045
1046   vam->retval = retval;
1047   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1048   vam->result_ready = 1;
1049 }
1050
1051 static void
1052 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1053 {
1054   vat_main_t *vam = &vat_main;
1055   vat_json_node_t node;
1056   api_main_t *am = &api_main;
1057   void *oldheap;
1058   u8 *reply;
1059
1060   vat_json_init_object (&node);
1061   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1062   vat_json_object_add_uint (&node, "reply_in_shmem",
1063                             ntohl (mp->reply_in_shmem));
1064   /* Toss the shared-memory original... */
1065   pthread_mutex_lock (&am->vlib_rp->mutex);
1066   oldheap = svm_push_data_heap (am->vlib_rp);
1067
1068   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1069   vec_free (reply);
1070
1071   svm_pop_heap (oldheap);
1072   pthread_mutex_unlock (&am->vlib_rp->mutex);
1073
1074   vat_json_print (vam->ofp, &node);
1075   vat_json_free (&node);
1076
1077   vam->retval = ntohl (mp->retval);
1078   vam->result_ready = 1;
1079 }
1080
1081 static void
1082 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1083 {
1084   vat_main_t *vam = &vat_main;
1085   i32 retval = ntohl (mp->retval);
1086   u32 length = ntohl (mp->length);
1087
1088   vec_reset_length (vam->cmd_reply);
1089
1090   vam->retval = retval;
1091   if (retval == 0)
1092     {
1093       vec_validate (vam->cmd_reply, length);
1094       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1095       vam->cmd_reply[length] = 0;
1096     }
1097   vam->result_ready = 1;
1098 }
1099
1100 static void
1101 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   vat_json_node_t node;
1105
1106   vec_reset_length (vam->cmd_reply);
1107
1108   vat_json_init_object (&node);
1109   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1110   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1111
1112   vat_json_print (vam->ofp, &node);
1113   vat_json_free (&node);
1114
1115   vam->retval = ntohl (mp->retval);
1116   vam->result_ready = 1;
1117 }
1118
1119 static void vl_api_classify_add_del_table_reply_t_handler
1120   (vl_api_classify_add_del_table_reply_t * mp)
1121 {
1122   vat_main_t *vam = &vat_main;
1123   i32 retval = ntohl (mp->retval);
1124   if (vam->async_mode)
1125     {
1126       vam->async_errors += (retval < 0);
1127     }
1128   else
1129     {
1130       vam->retval = retval;
1131       if (retval == 0 &&
1132           ((mp->new_table_index != 0xFFFFFFFF) ||
1133            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1134            (mp->match_n_vectors != 0xFFFFFFFF)))
1135         /*
1136          * Note: this is just barely thread-safe, depends on
1137          * the main thread spinning waiting for an answer...
1138          */
1139         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1140                 ntohl (mp->new_table_index),
1141                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1142       vam->result_ready = 1;
1143     }
1144 }
1145
1146 static void vl_api_classify_add_del_table_reply_t_handler_json
1147   (vl_api_classify_add_del_table_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   vat_json_node_t node;
1151
1152   vat_json_init_object (&node);
1153   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1154   vat_json_object_add_uint (&node, "new_table_index",
1155                             ntohl (mp->new_table_index));
1156   vat_json_object_add_uint (&node, "skip_n_vectors",
1157                             ntohl (mp->skip_n_vectors));
1158   vat_json_object_add_uint (&node, "match_n_vectors",
1159                             ntohl (mp->match_n_vectors));
1160
1161   vat_json_print (vam->ofp, &node);
1162   vat_json_free (&node);
1163
1164   vam->retval = ntohl (mp->retval);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void vl_api_get_node_index_reply_t_handler
1169   (vl_api_get_node_index_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   i32 retval = ntohl (mp->retval);
1173   if (vam->async_mode)
1174     {
1175       vam->async_errors += (retval < 0);
1176     }
1177   else
1178     {
1179       vam->retval = retval;
1180       if (retval == 0)
1181         errmsg ("node index %d", ntohl (mp->node_index));
1182       vam->result_ready = 1;
1183     }
1184 }
1185
1186 static void vl_api_get_node_index_reply_t_handler_json
1187   (vl_api_get_node_index_reply_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   vat_json_node_t node;
1191
1192   vat_json_init_object (&node);
1193   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1194   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1195
1196   vat_json_print (vam->ofp, &node);
1197   vat_json_free (&node);
1198
1199   vam->retval = ntohl (mp->retval);
1200   vam->result_ready = 1;
1201 }
1202
1203 static void vl_api_get_next_index_reply_t_handler
1204   (vl_api_get_next_index_reply_t * mp)
1205 {
1206   vat_main_t *vam = &vat_main;
1207   i32 retval = ntohl (mp->retval);
1208   if (vam->async_mode)
1209     {
1210       vam->async_errors += (retval < 0);
1211     }
1212   else
1213     {
1214       vam->retval = retval;
1215       if (retval == 0)
1216         errmsg ("next node index %d", ntohl (mp->next_index));
1217       vam->result_ready = 1;
1218     }
1219 }
1220
1221 static void vl_api_get_next_index_reply_t_handler_json
1222   (vl_api_get_next_index_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   vat_json_node_t node;
1226
1227   vat_json_init_object (&node);
1228   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1229   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1230
1231   vat_json_print (vam->ofp, &node);
1232   vat_json_free (&node);
1233
1234   vam->retval = ntohl (mp->retval);
1235   vam->result_ready = 1;
1236 }
1237
1238 static void vl_api_add_node_next_reply_t_handler
1239   (vl_api_add_node_next_reply_t * mp)
1240 {
1241   vat_main_t *vam = &vat_main;
1242   i32 retval = ntohl (mp->retval);
1243   if (vam->async_mode)
1244     {
1245       vam->async_errors += (retval < 0);
1246     }
1247   else
1248     {
1249       vam->retval = retval;
1250       if (retval == 0)
1251         errmsg ("next index %d", ntohl (mp->next_index));
1252       vam->result_ready = 1;
1253     }
1254 }
1255
1256 static void vl_api_add_node_next_reply_t_handler_json
1257   (vl_api_add_node_next_reply_t * mp)
1258 {
1259   vat_main_t *vam = &vat_main;
1260   vat_json_node_t node;
1261
1262   vat_json_init_object (&node);
1263   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1264   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1265
1266   vat_json_print (vam->ofp, &node);
1267   vat_json_free (&node);
1268
1269   vam->retval = ntohl (mp->retval);
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_show_version_reply_t_handler
1274   (vl_api_show_version_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278
1279   if (retval >= 0)
1280     {
1281       errmsg ("        program: %s", mp->program);
1282       errmsg ("        version: %s", mp->version);
1283       errmsg ("     build date: %s", mp->build_date);
1284       errmsg ("build directory: %s", mp->build_directory);
1285     }
1286   vam->retval = retval;
1287   vam->result_ready = 1;
1288 }
1289
1290 static void vl_api_show_version_reply_t_handler_json
1291   (vl_api_show_version_reply_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   vat_json_node_t node;
1295
1296   vat_json_init_object (&node);
1297   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1298   vat_json_object_add_string_copy (&node, "program", mp->program);
1299   vat_json_object_add_string_copy (&node, "version", mp->version);
1300   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1301   vat_json_object_add_string_copy (&node, "build_directory",
1302                                    mp->build_directory);
1303
1304   vat_json_print (vam->ofp, &node);
1305   vat_json_free (&node);
1306
1307   vam->retval = ntohl (mp->retval);
1308   vam->result_ready = 1;
1309 }
1310
1311 static void
1312 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1313 {
1314   u32 sw_if_index = ntohl (mp->sw_if_index);
1315   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1316           mp->mac_ip ? "mac/ip binding" : "address resolution",
1317           ntohl (mp->pid), format_ip4_address, &mp->address,
1318           format_ethernet_address, mp->new_mac, sw_if_index);
1319 }
1320
1321 static void
1322 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1323 {
1324   /* JSON output not supported */
1325 }
1326
1327 static void
1328 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1329 {
1330   u32 sw_if_index = ntohl (mp->sw_if_index);
1331   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1332           mp->mac_ip ? "mac/ip binding" : "address resolution",
1333           ntohl (mp->pid), format_ip6_address, mp->address,
1334           format_ethernet_address, mp->new_mac, sw_if_index);
1335 }
1336
1337 static void
1338 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1339 {
1340   /* JSON output not supported */
1341 }
1342
1343 static void
1344 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1345 {
1346   u32 n_macs = ntohl (mp->n_macs);
1347   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1348           ntohl (mp->pid), mp->client_index, n_macs);
1349   int i;
1350   for (i = 0; i < n_macs; i++)
1351     {
1352       vl_api_mac_entry_t *mac = &mp->mac[i];
1353       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1354               i + 1, ntohl (mac->sw_if_index),
1355               format_ethernet_address, mac->mac_addr, mac->action);
1356       if (i == 1000)
1357         break;
1358     }
1359 }
1360
1361 static void
1362 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1363 {
1364   /* JSON output not supported */
1365 }
1366
1367 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1368 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1369
1370 /*
1371  * Special-case: build the bridge domain table, maintain
1372  * the next bd id vbl.
1373  */
1374 static void vl_api_bridge_domain_details_t_handler
1375   (vl_api_bridge_domain_details_t * mp)
1376 {
1377   vat_main_t *vam = &vat_main;
1378   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1379   int i;
1380
1381   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1382          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1383
1384   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1385          ntohl (mp->bd_id), mp->learn, mp->forward,
1386          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1387
1388   if (n_sw_ifs)
1389     {
1390       vl_api_bridge_domain_sw_if_t *sw_ifs;
1391       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1392              "Interface Name");
1393
1394       sw_ifs = mp->sw_if_details;
1395       for (i = 0; i < n_sw_ifs; i++)
1396         {
1397           u8 *sw_if_name = 0;
1398           u32 sw_if_index;
1399           hash_pair_t *p;
1400
1401           sw_if_index = ntohl (sw_ifs->sw_if_index);
1402
1403           /* *INDENT-OFF* */
1404           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1405                              ({
1406                                if ((u32) p->value[0] == sw_if_index)
1407                                  {
1408                                    sw_if_name = (u8 *)(p->key);
1409                                    break;
1410                                  }
1411                              }));
1412           /* *INDENT-ON* */
1413           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1414                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1415                  "sw_if_index not found!");
1416
1417           sw_ifs++;
1418         }
1419     }
1420 }
1421
1422 static void vl_api_bridge_domain_details_t_handler_json
1423   (vl_api_bridge_domain_details_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   vat_json_node_t *node, *array = NULL;
1427   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1428
1429   if (VAT_JSON_ARRAY != vam->json_tree.type)
1430     {
1431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1432       vat_json_init_array (&vam->json_tree);
1433     }
1434   node = vat_json_array_add (&vam->json_tree);
1435
1436   vat_json_init_object (node);
1437   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1438   vat_json_object_add_uint (node, "flood", mp->flood);
1439   vat_json_object_add_uint (node, "forward", mp->forward);
1440   vat_json_object_add_uint (node, "learn", mp->learn);
1441   vat_json_object_add_uint (node, "bvi_sw_if_index",
1442                             ntohl (mp->bvi_sw_if_index));
1443   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1444   array = vat_json_object_add (node, "sw_if");
1445   vat_json_init_array (array);
1446
1447
1448
1449   if (n_sw_ifs)
1450     {
1451       vl_api_bridge_domain_sw_if_t *sw_ifs;
1452       int i;
1453
1454       sw_ifs = mp->sw_if_details;
1455       for (i = 0; i < n_sw_ifs; i++)
1456         {
1457           node = vat_json_array_add (array);
1458           vat_json_init_object (node);
1459           vat_json_object_add_uint (node, "sw_if_index",
1460                                     ntohl (sw_ifs->sw_if_index));
1461           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1462           sw_ifs++;
1463         }
1464     }
1465 }
1466
1467 static void vl_api_control_ping_reply_t_handler
1468   (vl_api_control_ping_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   i32 retval = ntohl (mp->retval);
1472   if (vam->async_mode)
1473     {
1474       vam->async_errors += (retval < 0);
1475     }
1476   else
1477     {
1478       vam->retval = retval;
1479       vam->result_ready = 1;
1480     }
1481   if (vam->socket_client_main)
1482     vam->socket_client_main->control_pings_outstanding--;
1483 }
1484
1485 static void vl_api_control_ping_reply_t_handler_json
1486   (vl_api_control_ping_reply_t * mp)
1487 {
1488   vat_main_t *vam = &vat_main;
1489   i32 retval = ntohl (mp->retval);
1490
1491   if (VAT_JSON_NONE != vam->json_tree.type)
1492     {
1493       vat_json_print (vam->ofp, &vam->json_tree);
1494       vat_json_free (&vam->json_tree);
1495       vam->json_tree.type = VAT_JSON_NONE;
1496     }
1497   else
1498     {
1499       /* just print [] */
1500       vat_json_init_array (&vam->json_tree);
1501       vat_json_print (vam->ofp, &vam->json_tree);
1502       vam->json_tree.type = VAT_JSON_NONE;
1503     }
1504
1505   vam->retval = retval;
1506   vam->result_ready = 1;
1507 }
1508
1509 static void
1510   vl_api_bridge_domain_set_mac_age_reply_t_handler
1511   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   i32 retval = ntohl (mp->retval);
1515   if (vam->async_mode)
1516     {
1517       vam->async_errors += (retval < 0);
1518     }
1519   else
1520     {
1521       vam->retval = retval;
1522       vam->result_ready = 1;
1523     }
1524 }
1525
1526 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1527   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1528 {
1529   vat_main_t *vam = &vat_main;
1530   vat_json_node_t node;
1531
1532   vat_json_init_object (&node);
1533   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1534
1535   vat_json_print (vam->ofp, &node);
1536   vat_json_free (&node);
1537
1538   vam->retval = ntohl (mp->retval);
1539   vam->result_ready = 1;
1540 }
1541
1542 static void
1543 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   i32 retval = ntohl (mp->retval);
1547   if (vam->async_mode)
1548     {
1549       vam->async_errors += (retval < 0);
1550     }
1551   else
1552     {
1553       vam->retval = retval;
1554       vam->result_ready = 1;
1555     }
1556 }
1557
1558 static void vl_api_l2_flags_reply_t_handler_json
1559   (vl_api_l2_flags_reply_t * mp)
1560 {
1561   vat_main_t *vam = &vat_main;
1562   vat_json_node_t node;
1563
1564   vat_json_init_object (&node);
1565   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1566   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1567                             ntohl (mp->resulting_feature_bitmap));
1568
1569   vat_json_print (vam->ofp, &node);
1570   vat_json_free (&node);
1571
1572   vam->retval = ntohl (mp->retval);
1573   vam->result_ready = 1;
1574 }
1575
1576 static void vl_api_bridge_flags_reply_t_handler
1577   (vl_api_bridge_flags_reply_t * mp)
1578 {
1579   vat_main_t *vam = &vat_main;
1580   i32 retval = ntohl (mp->retval);
1581   if (vam->async_mode)
1582     {
1583       vam->async_errors += (retval < 0);
1584     }
1585   else
1586     {
1587       vam->retval = retval;
1588       vam->result_ready = 1;
1589     }
1590 }
1591
1592 static void vl_api_bridge_flags_reply_t_handler_json
1593   (vl_api_bridge_flags_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   vat_json_node_t node;
1597
1598   vat_json_init_object (&node);
1599   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1600   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1601                             ntohl (mp->resulting_feature_bitmap));
1602
1603   vat_json_print (vam->ofp, &node);
1604   vat_json_free (&node);
1605
1606   vam->retval = ntohl (mp->retval);
1607   vam->result_ready = 1;
1608 }
1609
1610 static void vl_api_tap_connect_reply_t_handler
1611   (vl_api_tap_connect_reply_t * mp)
1612 {
1613   vat_main_t *vam = &vat_main;
1614   i32 retval = ntohl (mp->retval);
1615   if (vam->async_mode)
1616     {
1617       vam->async_errors += (retval < 0);
1618     }
1619   else
1620     {
1621       vam->retval = retval;
1622       vam->sw_if_index = ntohl (mp->sw_if_index);
1623       vam->result_ready = 1;
1624     }
1625
1626 }
1627
1628 static void vl_api_tap_connect_reply_t_handler_json
1629   (vl_api_tap_connect_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   vat_json_node_t node;
1633
1634   vat_json_init_object (&node);
1635   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1636   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1637
1638   vat_json_print (vam->ofp, &node);
1639   vat_json_free (&node);
1640
1641   vam->retval = ntohl (mp->retval);
1642   vam->result_ready = 1;
1643
1644 }
1645
1646 static void
1647 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1648 {
1649   vat_main_t *vam = &vat_main;
1650   i32 retval = ntohl (mp->retval);
1651   if (vam->async_mode)
1652     {
1653       vam->async_errors += (retval < 0);
1654     }
1655   else
1656     {
1657       vam->retval = retval;
1658       vam->sw_if_index = ntohl (mp->sw_if_index);
1659       vam->result_ready = 1;
1660     }
1661 }
1662
1663 static void vl_api_tap_modify_reply_t_handler_json
1664   (vl_api_tap_modify_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   vat_json_node_t node;
1668
1669   vat_json_init_object (&node);
1670   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1671   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1672
1673   vat_json_print (vam->ofp, &node);
1674   vat_json_free (&node);
1675
1676   vam->retval = ntohl (mp->retval);
1677   vam->result_ready = 1;
1678 }
1679
1680 static void
1681 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   i32 retval = ntohl (mp->retval);
1685   if (vam->async_mode)
1686     {
1687       vam->async_errors += (retval < 0);
1688     }
1689   else
1690     {
1691       vam->retval = retval;
1692       vam->result_ready = 1;
1693     }
1694 }
1695
1696 static void vl_api_tap_delete_reply_t_handler_json
1697   (vl_api_tap_delete_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   vat_json_node_t node;
1701
1702   vat_json_init_object (&node);
1703   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1704
1705   vat_json_print (vam->ofp, &node);
1706   vat_json_free (&node);
1707
1708   vam->retval = ntohl (mp->retval);
1709   vam->result_ready = 1;
1710 }
1711
1712 static void
1713 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1714 {
1715   vat_main_t *vam = &vat_main;
1716   i32 retval = ntohl (mp->retval);
1717   if (vam->async_mode)
1718     {
1719       vam->async_errors += (retval < 0);
1720     }
1721   else
1722     {
1723       vam->retval = retval;
1724       vam->sw_if_index = ntohl (mp->sw_if_index);
1725       vam->result_ready = 1;
1726     }
1727
1728 }
1729
1730 static void vl_api_tap_create_v2_reply_t_handler_json
1731   (vl_api_tap_create_v2_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   vat_json_node_t node;
1735
1736   vat_json_init_object (&node);
1737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1738   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1739
1740   vat_json_print (vam->ofp, &node);
1741   vat_json_free (&node);
1742
1743   vam->retval = ntohl (mp->retval);
1744   vam->result_ready = 1;
1745
1746 }
1747
1748 static void
1749 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1750 {
1751   vat_main_t *vam = &vat_main;
1752   i32 retval = ntohl (mp->retval);
1753   if (vam->async_mode)
1754     {
1755       vam->async_errors += (retval < 0);
1756     }
1757   else
1758     {
1759       vam->retval = retval;
1760       vam->result_ready = 1;
1761     }
1762 }
1763
1764 static void vl_api_tap_delete_v2_reply_t_handler_json
1765   (vl_api_tap_delete_v2_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   vat_json_node_t node;
1769
1770   vat_json_init_object (&node);
1771   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1772
1773   vat_json_print (vam->ofp, &node);
1774   vat_json_free (&node);
1775
1776   vam->retval = ntohl (mp->retval);
1777   vam->result_ready = 1;
1778 }
1779
1780 static void
1781 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   i32 retval = ntohl (mp->retval);
1785
1786   if (vam->async_mode)
1787     {
1788       vam->async_errors += (retval < 0);
1789     }
1790   else
1791     {
1792       vam->retval = retval;
1793       vam->sw_if_index = ntohl (mp->sw_if_index);
1794       vam->result_ready = 1;
1795     }
1796 }
1797
1798 static void vl_api_bond_create_reply_t_handler_json
1799   (vl_api_bond_create_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   vat_json_node_t node;
1803
1804   vat_json_init_object (&node);
1805   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1806   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1807
1808   vat_json_print (vam->ofp, &node);
1809   vat_json_free (&node);
1810
1811   vam->retval = ntohl (mp->retval);
1812   vam->result_ready = 1;
1813 }
1814
1815 static void
1816 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   i32 retval = ntohl (mp->retval);
1820
1821   if (vam->async_mode)
1822     {
1823       vam->async_errors += (retval < 0);
1824     }
1825   else
1826     {
1827       vam->retval = retval;
1828       vam->result_ready = 1;
1829     }
1830 }
1831
1832 static void vl_api_bond_delete_reply_t_handler_json
1833   (vl_api_bond_delete_reply_t * mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   vat_json_node_t node;
1837
1838   vat_json_init_object (&node);
1839   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1840
1841   vat_json_print (vam->ofp, &node);
1842   vat_json_free (&node);
1843
1844   vam->retval = ntohl (mp->retval);
1845   vam->result_ready = 1;
1846 }
1847
1848 static void
1849 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   i32 retval = ntohl (mp->retval);
1853
1854   if (vam->async_mode)
1855     {
1856       vam->async_errors += (retval < 0);
1857     }
1858   else
1859     {
1860       vam->retval = retval;
1861       vam->result_ready = 1;
1862     }
1863 }
1864
1865 static void vl_api_bond_enslave_reply_t_handler_json
1866   (vl_api_bond_enslave_reply_t * mp)
1867 {
1868   vat_main_t *vam = &vat_main;
1869   vat_json_node_t node;
1870
1871   vat_json_init_object (&node);
1872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1873
1874   vat_json_print (vam->ofp, &node);
1875   vat_json_free (&node);
1876
1877   vam->retval = ntohl (mp->retval);
1878   vam->result_ready = 1;
1879 }
1880
1881 static void
1882 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1883                                           mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   i32 retval = ntohl (mp->retval);
1887
1888   if (vam->async_mode)
1889     {
1890       vam->async_errors += (retval < 0);
1891     }
1892   else
1893     {
1894       vam->retval = retval;
1895       vam->result_ready = 1;
1896     }
1897 }
1898
1899 static void vl_api_bond_detach_slave_reply_t_handler_json
1900   (vl_api_bond_detach_slave_reply_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   vat_json_node_t node;
1904
1905   vat_json_init_object (&node);
1906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1907
1908   vat_json_print (vam->ofp, &node);
1909   vat_json_free (&node);
1910
1911   vam->retval = ntohl (mp->retval);
1912   vam->result_ready = 1;
1913 }
1914
1915 static void vl_api_sw_interface_bond_details_t_handler
1916   (vl_api_sw_interface_bond_details_t * mp)
1917 {
1918   vat_main_t *vam = &vat_main;
1919
1920   print (vam->ofp,
1921          "%-16s %-12d %-12U %-13U %-14u %-14u",
1922          mp->interface_name, ntohl (mp->sw_if_index),
1923          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1924          ntohl (mp->active_slaves), ntohl (mp->slaves));
1925 }
1926
1927 static void vl_api_sw_interface_bond_details_t_handler_json
1928   (vl_api_sw_interface_bond_details_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931   vat_json_node_t *node = NULL;
1932
1933   if (VAT_JSON_ARRAY != vam->json_tree.type)
1934     {
1935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1936       vat_json_init_array (&vam->json_tree);
1937     }
1938   node = vat_json_array_add (&vam->json_tree);
1939
1940   vat_json_init_object (node);
1941   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1942   vat_json_object_add_string_copy (node, "interface_name",
1943                                    mp->interface_name);
1944   vat_json_object_add_uint (node, "mode", mp->mode);
1945   vat_json_object_add_uint (node, "load_balance", mp->lb);
1946   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1947   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1948 }
1949
1950 static int
1951 api_sw_interface_bond_dump (vat_main_t * vam)
1952 {
1953   vl_api_sw_interface_bond_dump_t *mp;
1954   vl_api_control_ping_t *mp_ping;
1955   int ret;
1956
1957   print (vam->ofp,
1958          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1959          "interface name", "sw_if_index", "mode", "load balance",
1960          "active slaves", "slaves");
1961
1962   /* Get list of bond interfaces */
1963   M (SW_INTERFACE_BOND_DUMP, mp);
1964   S (mp);
1965
1966   /* Use a control ping for synchronization */
1967   MPING (CONTROL_PING, mp_ping);
1968   S (mp_ping);
1969
1970   W (ret);
1971   return ret;
1972 }
1973
1974 static void vl_api_sw_interface_slave_details_t_handler
1975   (vl_api_sw_interface_slave_details_t * mp)
1976 {
1977   vat_main_t *vam = &vat_main;
1978
1979   print (vam->ofp,
1980          "%-25s %-12d %-12d %d", mp->interface_name,
1981          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1982 }
1983
1984 static void vl_api_sw_interface_slave_details_t_handler_json
1985   (vl_api_sw_interface_slave_details_t * mp)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   vat_json_node_t *node = NULL;
1989
1990   if (VAT_JSON_ARRAY != vam->json_tree.type)
1991     {
1992       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1993       vat_json_init_array (&vam->json_tree);
1994     }
1995   node = vat_json_array_add (&vam->json_tree);
1996
1997   vat_json_init_object (node);
1998   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1999   vat_json_object_add_string_copy (node, "interface_name",
2000                                    mp->interface_name);
2001   vat_json_object_add_uint (node, "passive", mp->is_passive);
2002   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2003 }
2004
2005 static int
2006 api_sw_interface_slave_dump (vat_main_t * vam)
2007 {
2008   unformat_input_t *i = vam->input;
2009   vl_api_sw_interface_slave_dump_t *mp;
2010   vl_api_control_ping_t *mp_ping;
2011   u32 sw_if_index = ~0;
2012   u8 sw_if_index_set = 0;
2013   int ret;
2014
2015   /* Parse args required to build the message */
2016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2017     {
2018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2019         sw_if_index_set = 1;
2020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2021         sw_if_index_set = 1;
2022       else
2023         break;
2024     }
2025
2026   if (sw_if_index_set == 0)
2027     {
2028       errmsg ("missing vpp interface name. ");
2029       return -99;
2030     }
2031
2032   print (vam->ofp,
2033          "\n%-25s %-12s %-12s %s",
2034          "slave interface name", "sw_if_index", "passive", "long_timeout");
2035
2036   /* Get list of bond interfaces */
2037   M (SW_INTERFACE_SLAVE_DUMP, mp);
2038   mp->sw_if_index = ntohl (sw_if_index);
2039   S (mp);
2040
2041   /* Use a control ping for synchronization */
2042   MPING (CONTROL_PING, mp_ping);
2043   S (mp_ping);
2044
2045   W (ret);
2046   return ret;
2047 }
2048
2049 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2050   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2051 {
2052   vat_main_t *vam = &vat_main;
2053   i32 retval = ntohl (mp->retval);
2054   if (vam->async_mode)
2055     {
2056       vam->async_errors += (retval < 0);
2057     }
2058   else
2059     {
2060       vam->retval = retval;
2061       vam->result_ready = 1;
2062     }
2063 }
2064
2065 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2066   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2067 {
2068   vat_main_t *vam = &vat_main;
2069   vat_json_node_t node;
2070
2071   vat_json_init_object (&node);
2072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2074                             ntohl (mp->sw_if_index));
2075
2076   vat_json_print (vam->ofp, &node);
2077   vat_json_free (&node);
2078
2079   vam->retval = ntohl (mp->retval);
2080   vam->result_ready = 1;
2081 }
2082
2083 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2084   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2085 {
2086   vat_main_t *vam = &vat_main;
2087   i32 retval = ntohl (mp->retval);
2088   if (vam->async_mode)
2089     {
2090       vam->async_errors += (retval < 0);
2091     }
2092   else
2093     {
2094       vam->retval = retval;
2095       vam->sw_if_index = ntohl (mp->sw_if_index);
2096       vam->result_ready = 1;
2097     }
2098 }
2099
2100 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2101   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2102 {
2103   vat_main_t *vam = &vat_main;
2104   vat_json_node_t node;
2105
2106   vat_json_init_object (&node);
2107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2108   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2109
2110   vat_json_print (vam->ofp, &node);
2111   vat_json_free (&node);
2112
2113   vam->retval = ntohl (mp->retval);
2114   vam->result_ready = 1;
2115 }
2116
2117 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2118   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2119 {
2120   vat_main_t *vam = &vat_main;
2121   i32 retval = ntohl (mp->retval);
2122   if (vam->async_mode)
2123     {
2124       vam->async_errors += (retval < 0);
2125     }
2126   else
2127     {
2128       vam->retval = retval;
2129       vam->result_ready = 1;
2130     }
2131 }
2132
2133 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2134   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2135 {
2136   vat_main_t *vam = &vat_main;
2137   vat_json_node_t node;
2138
2139   vat_json_init_object (&node);
2140   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2141   vat_json_object_add_uint (&node, "fwd_entry_index",
2142                             clib_net_to_host_u32 (mp->fwd_entry_index));
2143
2144   vat_json_print (vam->ofp, &node);
2145   vat_json_free (&node);
2146
2147   vam->retval = ntohl (mp->retval);
2148   vam->result_ready = 1;
2149 }
2150
2151 u8 *
2152 format_lisp_transport_protocol (u8 * s, va_list * args)
2153 {
2154   u32 proto = va_arg (*args, u32);
2155
2156   switch (proto)
2157     {
2158     case 1:
2159       return format (s, "udp");
2160     case 2:
2161       return format (s, "api");
2162     default:
2163       return 0;
2164     }
2165   return 0;
2166 }
2167
2168 static void vl_api_one_get_transport_protocol_reply_t_handler
2169   (vl_api_one_get_transport_protocol_reply_t * mp)
2170 {
2171   vat_main_t *vam = &vat_main;
2172   i32 retval = ntohl (mp->retval);
2173   if (vam->async_mode)
2174     {
2175       vam->async_errors += (retval < 0);
2176     }
2177   else
2178     {
2179       u32 proto = mp->protocol;
2180       print (vam->ofp, "Transport protocol: %U",
2181              format_lisp_transport_protocol, proto);
2182       vam->retval = retval;
2183       vam->result_ready = 1;
2184     }
2185 }
2186
2187 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2188   (vl_api_one_get_transport_protocol_reply_t * mp)
2189 {
2190   vat_main_t *vam = &vat_main;
2191   vat_json_node_t node;
2192   u8 *s;
2193
2194   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2195   vec_add1 (s, 0);
2196
2197   vat_json_init_object (&node);
2198   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2199   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2200
2201   vec_free (s);
2202   vat_json_print (vam->ofp, &node);
2203   vat_json_free (&node);
2204
2205   vam->retval = ntohl (mp->retval);
2206   vam->result_ready = 1;
2207 }
2208
2209 static void vl_api_one_add_del_locator_set_reply_t_handler
2210   (vl_api_one_add_del_locator_set_reply_t * mp)
2211 {
2212   vat_main_t *vam = &vat_main;
2213   i32 retval = ntohl (mp->retval);
2214   if (vam->async_mode)
2215     {
2216       vam->async_errors += (retval < 0);
2217     }
2218   else
2219     {
2220       vam->retval = retval;
2221       vam->result_ready = 1;
2222     }
2223 }
2224
2225 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2226   (vl_api_one_add_del_locator_set_reply_t * mp)
2227 {
2228   vat_main_t *vam = &vat_main;
2229   vat_json_node_t node;
2230
2231   vat_json_init_object (&node);
2232   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2233   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2234
2235   vat_json_print (vam->ofp, &node);
2236   vat_json_free (&node);
2237
2238   vam->retval = ntohl (mp->retval);
2239   vam->result_ready = 1;
2240 }
2241
2242 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2243   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2244 {
2245   vat_main_t *vam = &vat_main;
2246   i32 retval = ntohl (mp->retval);
2247   if (vam->async_mode)
2248     {
2249       vam->async_errors += (retval < 0);
2250     }
2251   else
2252     {
2253       vam->retval = retval;
2254       vam->sw_if_index = ntohl (mp->sw_if_index);
2255       vam->result_ready = 1;
2256     }
2257   vam->regenerate_interface_table = 1;
2258 }
2259
2260 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2261   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2262 {
2263   vat_main_t *vam = &vat_main;
2264   vat_json_node_t node;
2265
2266   vat_json_init_object (&node);
2267   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2268   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2269
2270   vat_json_print (vam->ofp, &node);
2271   vat_json_free (&node);
2272
2273   vam->retval = ntohl (mp->retval);
2274   vam->result_ready = 1;
2275 }
2276
2277 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2278   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2279 {
2280   vat_main_t *vam = &vat_main;
2281   i32 retval = ntohl (mp->retval);
2282   if (vam->async_mode)
2283     {
2284       vam->async_errors += (retval < 0);
2285     }
2286   else
2287     {
2288       vam->retval = retval;
2289       vam->sw_if_index = ntohl (mp->sw_if_index);
2290       vam->result_ready = 1;
2291     }
2292 }
2293
2294 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2295   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2296 {
2297   vat_main_t *vam = &vat_main;
2298   vat_json_node_t node;
2299
2300   vat_json_init_object (&node);
2301   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2302   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2303
2304   vat_json_print (vam->ofp, &node);
2305   vat_json_free (&node);
2306
2307   vam->retval = ntohl (mp->retval);
2308   vam->result_ready = 1;
2309 }
2310
2311 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2312   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2313 {
2314   vat_main_t *vam = &vat_main;
2315   i32 retval = ntohl (mp->retval);
2316   if (vam->async_mode)
2317     {
2318       vam->async_errors += (retval < 0);
2319     }
2320   else
2321     {
2322       vam->retval = retval;
2323       vam->sw_if_index = ntohl (mp->sw_if_index);
2324       vam->result_ready = 1;
2325     }
2326   vam->regenerate_interface_table = 1;
2327 }
2328
2329 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2330   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   vat_json_node_t node;
2334
2335   vat_json_init_object (&node);
2336   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2337   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2338
2339   vat_json_print (vam->ofp, &node);
2340   vat_json_free (&node);
2341
2342   vam->retval = ntohl (mp->retval);
2343   vam->result_ready = 1;
2344 }
2345
2346 static void vl_api_gre_add_del_tunnel_reply_t_handler
2347   (vl_api_gre_add_del_tunnel_reply_t * mp)
2348 {
2349   vat_main_t *vam = &vat_main;
2350   i32 retval = ntohl (mp->retval);
2351   if (vam->async_mode)
2352     {
2353       vam->async_errors += (retval < 0);
2354     }
2355   else
2356     {
2357       vam->retval = retval;
2358       vam->sw_if_index = ntohl (mp->sw_if_index);
2359       vam->result_ready = 1;
2360     }
2361 }
2362
2363 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2364   (vl_api_gre_add_del_tunnel_reply_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   vat_json_node_t node;
2368
2369   vat_json_init_object (&node);
2370   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2371   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2372
2373   vat_json_print (vam->ofp, &node);
2374   vat_json_free (&node);
2375
2376   vam->retval = ntohl (mp->retval);
2377   vam->result_ready = 1;
2378 }
2379
2380 static void vl_api_create_vhost_user_if_reply_t_handler
2381   (vl_api_create_vhost_user_if_reply_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   i32 retval = ntohl (mp->retval);
2385   if (vam->async_mode)
2386     {
2387       vam->async_errors += (retval < 0);
2388     }
2389   else
2390     {
2391       vam->retval = retval;
2392       vam->sw_if_index = ntohl (mp->sw_if_index);
2393       vam->result_ready = 1;
2394     }
2395   vam->regenerate_interface_table = 1;
2396 }
2397
2398 static void vl_api_create_vhost_user_if_reply_t_handler_json
2399   (vl_api_create_vhost_user_if_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   vat_json_node_t node;
2403
2404   vat_json_init_object (&node);
2405   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2406   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2407
2408   vat_json_print (vam->ofp, &node);
2409   vat_json_free (&node);
2410
2411   vam->retval = ntohl (mp->retval);
2412   vam->result_ready = 1;
2413 }
2414
2415 static void vl_api_dns_resolve_name_reply_t_handler
2416   (vl_api_dns_resolve_name_reply_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419   i32 retval = ntohl (mp->retval);
2420   if (vam->async_mode)
2421     {
2422       vam->async_errors += (retval < 0);
2423     }
2424   else
2425     {
2426       vam->retval = retval;
2427       vam->result_ready = 1;
2428
2429       if (retval == 0)
2430         {
2431           if (mp->ip4_set)
2432             clib_warning ("ip4 address %U", format_ip4_address,
2433                           (ip4_address_t *) mp->ip4_address);
2434           if (mp->ip6_set)
2435             clib_warning ("ip6 address %U", format_ip6_address,
2436                           (ip6_address_t *) mp->ip6_address);
2437         }
2438       else
2439         clib_warning ("retval %d", retval);
2440     }
2441 }
2442
2443 static void vl_api_dns_resolve_name_reply_t_handler_json
2444   (vl_api_dns_resolve_name_reply_t * mp)
2445 {
2446   clib_warning ("not implemented");
2447 }
2448
2449 static void vl_api_dns_resolve_ip_reply_t_handler
2450   (vl_api_dns_resolve_ip_reply_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   i32 retval = ntohl (mp->retval);
2454   if (vam->async_mode)
2455     {
2456       vam->async_errors += (retval < 0);
2457     }
2458   else
2459     {
2460       vam->retval = retval;
2461       vam->result_ready = 1;
2462
2463       if (retval == 0)
2464         {
2465           clib_warning ("canonical name %s", mp->name);
2466         }
2467       else
2468         clib_warning ("retval %d", retval);
2469     }
2470 }
2471
2472 static void vl_api_dns_resolve_ip_reply_t_handler_json
2473   (vl_api_dns_resolve_ip_reply_t * mp)
2474 {
2475   clib_warning ("not implemented");
2476 }
2477
2478
2479 static void vl_api_ip_address_details_t_handler
2480   (vl_api_ip_address_details_t * mp)
2481 {
2482   vat_main_t *vam = &vat_main;
2483   static ip_address_details_t empty_ip_address_details = { {0} };
2484   ip_address_details_t *address = NULL;
2485   ip_details_t *current_ip_details = NULL;
2486   ip_details_t *details = NULL;
2487
2488   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2489
2490   if (!details || vam->current_sw_if_index >= vec_len (details)
2491       || !details[vam->current_sw_if_index].present)
2492     {
2493       errmsg ("ip address details arrived but not stored");
2494       errmsg ("ip_dump should be called first");
2495       return;
2496     }
2497
2498   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2499
2500 #define addresses (current_ip_details->addr)
2501
2502   vec_validate_init_empty (addresses, vec_len (addresses),
2503                            empty_ip_address_details);
2504
2505   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2506
2507   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2508   address->prefix_length = mp->prefix_length;
2509 #undef addresses
2510 }
2511
2512 static void vl_api_ip_address_details_t_handler_json
2513   (vl_api_ip_address_details_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   vat_json_node_t *node = NULL;
2517   struct in6_addr ip6;
2518   struct in_addr ip4;
2519
2520   if (VAT_JSON_ARRAY != vam->json_tree.type)
2521     {
2522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2523       vat_json_init_array (&vam->json_tree);
2524     }
2525   node = vat_json_array_add (&vam->json_tree);
2526
2527   vat_json_init_object (node);
2528   if (vam->is_ipv6)
2529     {
2530       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2531       vat_json_object_add_ip6 (node, "ip", ip6);
2532     }
2533   else
2534     {
2535       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2536       vat_json_object_add_ip4 (node, "ip", ip4);
2537     }
2538   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2539 }
2540
2541 static void
2542 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2543 {
2544   vat_main_t *vam = &vat_main;
2545   static ip_details_t empty_ip_details = { 0 };
2546   ip_details_t *ip = NULL;
2547   u32 sw_if_index = ~0;
2548
2549   sw_if_index = ntohl (mp->sw_if_index);
2550
2551   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2552                            sw_if_index, empty_ip_details);
2553
2554   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2555                          sw_if_index);
2556
2557   ip->present = 1;
2558 }
2559
2560 static void
2561 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2562 {
2563   vat_main_t *vam = &vat_main;
2564
2565   if (VAT_JSON_ARRAY != vam->json_tree.type)
2566     {
2567       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2568       vat_json_init_array (&vam->json_tree);
2569     }
2570   vat_json_array_add_uint (&vam->json_tree,
2571                            clib_net_to_host_u32 (mp->sw_if_index));
2572 }
2573
2574 static void vl_api_map_domain_details_t_handler_json
2575   (vl_api_map_domain_details_t * mp)
2576 {
2577   vat_json_node_t *node = NULL;
2578   vat_main_t *vam = &vat_main;
2579   struct in6_addr ip6;
2580   struct in_addr ip4;
2581
2582   if (VAT_JSON_ARRAY != vam->json_tree.type)
2583     {
2584       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2585       vat_json_init_array (&vam->json_tree);
2586     }
2587
2588   node = vat_json_array_add (&vam->json_tree);
2589   vat_json_init_object (node);
2590
2591   vat_json_object_add_uint (node, "domain_index",
2592                             clib_net_to_host_u32 (mp->domain_index));
2593   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2594   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2595   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2596   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2597   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2598   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2599   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2600   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2601   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2602   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2603   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2604   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2605   vat_json_object_add_uint (node, "flags", mp->flags);
2606   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2607   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2608 }
2609
2610 static void vl_api_map_domain_details_t_handler
2611   (vl_api_map_domain_details_t * mp)
2612 {
2613   vat_main_t *vam = &vat_main;
2614
2615   if (mp->is_translation)
2616     {
2617       print (vam->ofp,
2618              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2619              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2620              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2621              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2622              clib_net_to_host_u32 (mp->domain_index));
2623     }
2624   else
2625     {
2626       print (vam->ofp,
2627              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2628              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2629              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2630              format_ip6_address, mp->ip6_src,
2631              clib_net_to_host_u32 (mp->domain_index));
2632     }
2633   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2634          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2635          mp->is_translation ? "map-t" : "");
2636 }
2637
2638 static void vl_api_map_rule_details_t_handler_json
2639   (vl_api_map_rule_details_t * mp)
2640 {
2641   struct in6_addr ip6;
2642   vat_json_node_t *node = NULL;
2643   vat_main_t *vam = &vat_main;
2644
2645   if (VAT_JSON_ARRAY != vam->json_tree.type)
2646     {
2647       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2648       vat_json_init_array (&vam->json_tree);
2649     }
2650
2651   node = vat_json_array_add (&vam->json_tree);
2652   vat_json_init_object (node);
2653
2654   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2655   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2656   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2657 }
2658
2659 static void
2660 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2661 {
2662   vat_main_t *vam = &vat_main;
2663   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2664          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2665 }
2666
2667 static void
2668 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2669 {
2670   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2671           "router_addr %U host_mac %U",
2672           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2673           format_ip4_address, &mp->host_address,
2674           format_ip4_address, &mp->router_address,
2675           format_ethernet_address, mp->host_mac);
2676 }
2677
2678 static void vl_api_dhcp_compl_event_t_handler_json
2679   (vl_api_dhcp_compl_event_t * mp)
2680 {
2681   /* JSON output not supported */
2682 }
2683
2684 static void
2685 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2686                               u32 counter)
2687 {
2688   vat_main_t *vam = &vat_main;
2689   static u64 default_counter = 0;
2690
2691   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2692                            NULL);
2693   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2694                            sw_if_index, default_counter);
2695   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2696 }
2697
2698 static void
2699 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2700                                 interface_counter_t counter)
2701 {
2702   vat_main_t *vam = &vat_main;
2703   static interface_counter_t default_counter = { 0, };
2704
2705   vec_validate_init_empty (vam->combined_interface_counters,
2706                            vnet_counter_type, NULL);
2707   vec_validate_init_empty (vam->combined_interface_counters
2708                            [vnet_counter_type], sw_if_index, default_counter);
2709   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2710 }
2711
2712 static void vl_api_vnet_interface_simple_counters_t_handler
2713   (vl_api_vnet_interface_simple_counters_t * mp)
2714 {
2715   /* not supported */
2716 }
2717
2718 static void vl_api_vnet_interface_combined_counters_t_handler
2719   (vl_api_vnet_interface_combined_counters_t * mp)
2720 {
2721   /* not supported */
2722 }
2723
2724 static void vl_api_vnet_interface_simple_counters_t_handler_json
2725   (vl_api_vnet_interface_simple_counters_t * mp)
2726 {
2727   u64 *v_packets;
2728   u64 packets;
2729   u32 count;
2730   u32 first_sw_if_index;
2731   int i;
2732
2733   count = ntohl (mp->count);
2734   first_sw_if_index = ntohl (mp->first_sw_if_index);
2735
2736   v_packets = (u64 *) & mp->data;
2737   for (i = 0; i < count; i++)
2738     {
2739       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2740       set_simple_interface_counter (mp->vnet_counter_type,
2741                                     first_sw_if_index + i, packets);
2742       v_packets++;
2743     }
2744 }
2745
2746 static void vl_api_vnet_interface_combined_counters_t_handler_json
2747   (vl_api_vnet_interface_combined_counters_t * mp)
2748 {
2749   interface_counter_t counter;
2750   vlib_counter_t *v;
2751   u32 first_sw_if_index;
2752   int i;
2753   u32 count;
2754
2755   count = ntohl (mp->count);
2756   first_sw_if_index = ntohl (mp->first_sw_if_index);
2757
2758   v = (vlib_counter_t *) & mp->data;
2759   for (i = 0; i < count; i++)
2760     {
2761       counter.packets =
2762         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2763       counter.bytes =
2764         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2765       set_combined_interface_counter (mp->vnet_counter_type,
2766                                       first_sw_if_index + i, counter);
2767       v++;
2768     }
2769 }
2770
2771 static u32
2772 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2773 {
2774   vat_main_t *vam = &vat_main;
2775   u32 i;
2776
2777   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2778     {
2779       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2780         {
2781           return i;
2782         }
2783     }
2784   return ~0;
2785 }
2786
2787 static u32
2788 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   u32 i;
2792
2793   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2794     {
2795       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2796         {
2797           return i;
2798         }
2799     }
2800   return ~0;
2801 }
2802
2803 static void vl_api_vnet_ip4_fib_counters_t_handler
2804   (vl_api_vnet_ip4_fib_counters_t * mp)
2805 {
2806   /* not supported */
2807 }
2808
2809 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2810   (vl_api_vnet_ip4_fib_counters_t * mp)
2811 {
2812   vat_main_t *vam = &vat_main;
2813   vl_api_ip4_fib_counter_t *v;
2814   ip4_fib_counter_t *counter;
2815   struct in_addr ip4;
2816   u32 vrf_id;
2817   u32 vrf_index;
2818   u32 count;
2819   int i;
2820
2821   vrf_id = ntohl (mp->vrf_id);
2822   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2823   if (~0 == vrf_index)
2824     {
2825       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2826       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2827       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2828       vec_validate (vam->ip4_fib_counters, vrf_index);
2829       vam->ip4_fib_counters[vrf_index] = NULL;
2830     }
2831
2832   vec_free (vam->ip4_fib_counters[vrf_index]);
2833   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2834   count = ntohl (mp->count);
2835   for (i = 0; i < count; i++)
2836     {
2837       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2838       counter = &vam->ip4_fib_counters[vrf_index][i];
2839       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2840       counter->address = ip4;
2841       counter->address_length = v->address_length;
2842       counter->packets = clib_net_to_host_u64 (v->packets);
2843       counter->bytes = clib_net_to_host_u64 (v->bytes);
2844       v++;
2845     }
2846 }
2847
2848 static void vl_api_vnet_ip4_nbr_counters_t_handler
2849   (vl_api_vnet_ip4_nbr_counters_t * mp)
2850 {
2851   /* not supported */
2852 }
2853
2854 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2855   (vl_api_vnet_ip4_nbr_counters_t * mp)
2856 {
2857   vat_main_t *vam = &vat_main;
2858   vl_api_ip4_nbr_counter_t *v;
2859   ip4_nbr_counter_t *counter;
2860   u32 sw_if_index;
2861   u32 count;
2862   int i;
2863
2864   sw_if_index = ntohl (mp->sw_if_index);
2865   count = ntohl (mp->count);
2866   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2867
2868   if (mp->begin)
2869     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2870
2871   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2872   for (i = 0; i < count; i++)
2873     {
2874       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2875       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2876       counter->address.s_addr = v->address;
2877       counter->packets = clib_net_to_host_u64 (v->packets);
2878       counter->bytes = clib_net_to_host_u64 (v->bytes);
2879       counter->linkt = v->link_type;
2880       v++;
2881     }
2882 }
2883
2884 static void vl_api_vnet_ip6_fib_counters_t_handler
2885   (vl_api_vnet_ip6_fib_counters_t * mp)
2886 {
2887   /* not supported */
2888 }
2889
2890 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2891   (vl_api_vnet_ip6_fib_counters_t * mp)
2892 {
2893   vat_main_t *vam = &vat_main;
2894   vl_api_ip6_fib_counter_t *v;
2895   ip6_fib_counter_t *counter;
2896   struct in6_addr ip6;
2897   u32 vrf_id;
2898   u32 vrf_index;
2899   u32 count;
2900   int i;
2901
2902   vrf_id = ntohl (mp->vrf_id);
2903   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2904   if (~0 == vrf_index)
2905     {
2906       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2907       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2908       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2909       vec_validate (vam->ip6_fib_counters, vrf_index);
2910       vam->ip6_fib_counters[vrf_index] = NULL;
2911     }
2912
2913   vec_free (vam->ip6_fib_counters[vrf_index]);
2914   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2915   count = ntohl (mp->count);
2916   for (i = 0; i < count; i++)
2917     {
2918       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2919       counter = &vam->ip6_fib_counters[vrf_index][i];
2920       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2921       counter->address = ip6;
2922       counter->address_length = v->address_length;
2923       counter->packets = clib_net_to_host_u64 (v->packets);
2924       counter->bytes = clib_net_to_host_u64 (v->bytes);
2925       v++;
2926     }
2927 }
2928
2929 static void vl_api_vnet_ip6_nbr_counters_t_handler
2930   (vl_api_vnet_ip6_nbr_counters_t * mp)
2931 {
2932   /* not supported */
2933 }
2934
2935 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2936   (vl_api_vnet_ip6_nbr_counters_t * mp)
2937 {
2938   vat_main_t *vam = &vat_main;
2939   vl_api_ip6_nbr_counter_t *v;
2940   ip6_nbr_counter_t *counter;
2941   struct in6_addr ip6;
2942   u32 sw_if_index;
2943   u32 count;
2944   int i;
2945
2946   sw_if_index = ntohl (mp->sw_if_index);
2947   count = ntohl (mp->count);
2948   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2949
2950   if (mp->begin)
2951     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2952
2953   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2954   for (i = 0; i < count; i++)
2955     {
2956       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2957       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2958       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2959       counter->address = ip6;
2960       counter->packets = clib_net_to_host_u64 (v->packets);
2961       counter->bytes = clib_net_to_host_u64 (v->bytes);
2962       v++;
2963     }
2964 }
2965
2966 static void vl_api_get_first_msg_id_reply_t_handler
2967   (vl_api_get_first_msg_id_reply_t * mp)
2968 {
2969   vat_main_t *vam = &vat_main;
2970   i32 retval = ntohl (mp->retval);
2971
2972   if (vam->async_mode)
2973     {
2974       vam->async_errors += (retval < 0);
2975     }
2976   else
2977     {
2978       vam->retval = retval;
2979       vam->result_ready = 1;
2980     }
2981   if (retval >= 0)
2982     {
2983       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2984     }
2985 }
2986
2987 static void vl_api_get_first_msg_id_reply_t_handler_json
2988   (vl_api_get_first_msg_id_reply_t * mp)
2989 {
2990   vat_main_t *vam = &vat_main;
2991   vat_json_node_t node;
2992
2993   vat_json_init_object (&node);
2994   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2995   vat_json_object_add_uint (&node, "first_msg_id",
2996                             (uint) ntohs (mp->first_msg_id));
2997
2998   vat_json_print (vam->ofp, &node);
2999   vat_json_free (&node);
3000
3001   vam->retval = ntohl (mp->retval);
3002   vam->result_ready = 1;
3003 }
3004
3005 static void vl_api_get_node_graph_reply_t_handler
3006   (vl_api_get_node_graph_reply_t * mp)
3007 {
3008   vat_main_t *vam = &vat_main;
3009   api_main_t *am = &api_main;
3010   i32 retval = ntohl (mp->retval);
3011   u8 *pvt_copy, *reply;
3012   void *oldheap;
3013   vlib_node_t *node;
3014   int i;
3015
3016   if (vam->async_mode)
3017     {
3018       vam->async_errors += (retval < 0);
3019     }
3020   else
3021     {
3022       vam->retval = retval;
3023       vam->result_ready = 1;
3024     }
3025
3026   /* "Should never happen..." */
3027   if (retval != 0)
3028     return;
3029
3030   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3031   pvt_copy = vec_dup (reply);
3032
3033   /* Toss the shared-memory original... */
3034   pthread_mutex_lock (&am->vlib_rp->mutex);
3035   oldheap = svm_push_data_heap (am->vlib_rp);
3036
3037   vec_free (reply);
3038
3039   svm_pop_heap (oldheap);
3040   pthread_mutex_unlock (&am->vlib_rp->mutex);
3041
3042   if (vam->graph_nodes)
3043     {
3044       hash_free (vam->graph_node_index_by_name);
3045
3046       for (i = 0; i < vec_len (vam->graph_nodes); i++)
3047         {
3048           node = vam->graph_nodes[i];
3049           vec_free (node->name);
3050           vec_free (node->next_nodes);
3051           vec_free (node);
3052         }
3053       vec_free (vam->graph_nodes);
3054     }
3055
3056   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3057   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3058   vec_free (pvt_copy);
3059
3060   for (i = 0; i < vec_len (vam->graph_nodes); i++)
3061     {
3062       node = vam->graph_nodes[i];
3063       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3064     }
3065 }
3066
3067 static void vl_api_get_node_graph_reply_t_handler_json
3068   (vl_api_get_node_graph_reply_t * mp)
3069 {
3070   vat_main_t *vam = &vat_main;
3071   api_main_t *am = &api_main;
3072   void *oldheap;
3073   vat_json_node_t node;
3074   u8 *reply;
3075
3076   /* $$$$ make this real? */
3077   vat_json_init_object (&node);
3078   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3079   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3080
3081   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3082
3083   /* Toss the shared-memory original... */
3084   pthread_mutex_lock (&am->vlib_rp->mutex);
3085   oldheap = svm_push_data_heap (am->vlib_rp);
3086
3087   vec_free (reply);
3088
3089   svm_pop_heap (oldheap);
3090   pthread_mutex_unlock (&am->vlib_rp->mutex);
3091
3092   vat_json_print (vam->ofp, &node);
3093   vat_json_free (&node);
3094
3095   vam->retval = ntohl (mp->retval);
3096   vam->result_ready = 1;
3097 }
3098
3099 static void
3100 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3101 {
3102   vat_main_t *vam = &vat_main;
3103   u8 *s = 0;
3104
3105   if (mp->local)
3106     {
3107       s = format (s, "%=16d%=16d%=16d",
3108                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3109     }
3110   else
3111     {
3112       s = format (s, "%=16U%=16d%=16d",
3113                   mp->is_ipv6 ? format_ip6_address :
3114                   format_ip4_address,
3115                   mp->ip_address, mp->priority, mp->weight);
3116     }
3117
3118   print (vam->ofp, "%v", s);
3119   vec_free (s);
3120 }
3121
3122 static void
3123 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3124 {
3125   vat_main_t *vam = &vat_main;
3126   vat_json_node_t *node = NULL;
3127   struct in6_addr ip6;
3128   struct in_addr ip4;
3129
3130   if (VAT_JSON_ARRAY != vam->json_tree.type)
3131     {
3132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3133       vat_json_init_array (&vam->json_tree);
3134     }
3135   node = vat_json_array_add (&vam->json_tree);
3136   vat_json_init_object (node);
3137
3138   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3139   vat_json_object_add_uint (node, "priority", mp->priority);
3140   vat_json_object_add_uint (node, "weight", mp->weight);
3141
3142   if (mp->local)
3143     vat_json_object_add_uint (node, "sw_if_index",
3144                               clib_net_to_host_u32 (mp->sw_if_index));
3145   else
3146     {
3147       if (mp->is_ipv6)
3148         {
3149           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3150           vat_json_object_add_ip6 (node, "address", ip6);
3151         }
3152       else
3153         {
3154           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3155           vat_json_object_add_ip4 (node, "address", ip4);
3156         }
3157     }
3158 }
3159
3160 static void
3161 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3162                                           mp)
3163 {
3164   vat_main_t *vam = &vat_main;
3165   u8 *ls_name = 0;
3166
3167   ls_name = format (0, "%s", mp->ls_name);
3168
3169   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3170          ls_name);
3171   vec_free (ls_name);
3172 }
3173
3174 static void
3175   vl_api_one_locator_set_details_t_handler_json
3176   (vl_api_one_locator_set_details_t * mp)
3177 {
3178   vat_main_t *vam = &vat_main;
3179   vat_json_node_t *node = 0;
3180   u8 *ls_name = 0;
3181
3182   ls_name = format (0, "%s", mp->ls_name);
3183   vec_add1 (ls_name, 0);
3184
3185   if (VAT_JSON_ARRAY != vam->json_tree.type)
3186     {
3187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3188       vat_json_init_array (&vam->json_tree);
3189     }
3190   node = vat_json_array_add (&vam->json_tree);
3191
3192   vat_json_init_object (node);
3193   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3194   vat_json_object_add_uint (node, "ls_index",
3195                             clib_net_to_host_u32 (mp->ls_index));
3196   vec_free (ls_name);
3197 }
3198
3199 typedef struct
3200 {
3201   u32 spi;
3202   u8 si;
3203 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3204
3205 uword
3206 unformat_nsh_address (unformat_input_t * input, va_list * args)
3207 {
3208   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3209   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3210 }
3211
3212 u8 *
3213 format_nsh_address_vat (u8 * s, va_list * args)
3214 {
3215   nsh_t *a = va_arg (*args, nsh_t *);
3216   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3217 }
3218
3219 static u8 *
3220 format_lisp_flat_eid (u8 * s, va_list * args)
3221 {
3222   u32 type = va_arg (*args, u32);
3223   u8 *eid = va_arg (*args, u8 *);
3224   u32 eid_len = va_arg (*args, u32);
3225
3226   switch (type)
3227     {
3228     case 0:
3229       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3230     case 1:
3231       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3232     case 2:
3233       return format (s, "%U", format_ethernet_address, eid);
3234     case 3:
3235       return format (s, "%U", format_nsh_address_vat, eid);
3236     }
3237   return 0;
3238 }
3239
3240 static u8 *
3241 format_lisp_eid_vat (u8 * s, va_list * args)
3242 {
3243   u32 type = va_arg (*args, u32);
3244   u8 *eid = va_arg (*args, u8 *);
3245   u32 eid_len = va_arg (*args, u32);
3246   u8 *seid = va_arg (*args, u8 *);
3247   u32 seid_len = va_arg (*args, u32);
3248   u32 is_src_dst = va_arg (*args, u32);
3249
3250   if (is_src_dst)
3251     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3252
3253   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3254
3255   return s;
3256 }
3257
3258 static void
3259 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3260 {
3261   vat_main_t *vam = &vat_main;
3262   u8 *s = 0, *eid = 0;
3263
3264   if (~0 == mp->locator_set_index)
3265     s = format (0, "action: %d", mp->action);
3266   else
3267     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3268
3269   eid = format (0, "%U", format_lisp_eid_vat,
3270                 mp->eid_type,
3271                 mp->eid,
3272                 mp->eid_prefix_len,
3273                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3274   vec_add1 (eid, 0);
3275
3276   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3277          clib_net_to_host_u32 (mp->vni),
3278          eid,
3279          mp->is_local ? "local" : "remote",
3280          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3281          clib_net_to_host_u16 (mp->key_id), mp->key);
3282
3283   vec_free (s);
3284   vec_free (eid);
3285 }
3286
3287 static void
3288 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3289                                              * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   vat_json_node_t *node = 0;
3293   u8 *eid = 0;
3294
3295   if (VAT_JSON_ARRAY != vam->json_tree.type)
3296     {
3297       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3298       vat_json_init_array (&vam->json_tree);
3299     }
3300   node = vat_json_array_add (&vam->json_tree);
3301
3302   vat_json_init_object (node);
3303   if (~0 == mp->locator_set_index)
3304     vat_json_object_add_uint (node, "action", mp->action);
3305   else
3306     vat_json_object_add_uint (node, "locator_set_index",
3307                               clib_net_to_host_u32 (mp->locator_set_index));
3308
3309   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3310   if (mp->eid_type == 3)
3311     {
3312       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3313       vat_json_init_object (nsh_json);
3314       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3315       vat_json_object_add_uint (nsh_json, "spi",
3316                                 clib_net_to_host_u32 (nsh->spi));
3317       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3318     }
3319   else
3320     {
3321       eid = format (0, "%U", format_lisp_eid_vat,
3322                     mp->eid_type,
3323                     mp->eid,
3324                     mp->eid_prefix_len,
3325                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3326       vec_add1 (eid, 0);
3327       vat_json_object_add_string_copy (node, "eid", eid);
3328       vec_free (eid);
3329     }
3330   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3331   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3332   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3333
3334   if (mp->key_id)
3335     {
3336       vat_json_object_add_uint (node, "key_id",
3337                                 clib_net_to_host_u16 (mp->key_id));
3338       vat_json_object_add_string_copy (node, "key", mp->key);
3339     }
3340 }
3341
3342 static void
3343 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3344 {
3345   vat_main_t *vam = &vat_main;
3346   u8 *seid = 0, *deid = 0;
3347   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3348
3349   deid = format (0, "%U", format_lisp_eid_vat,
3350                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3351
3352   seid = format (0, "%U", format_lisp_eid_vat,
3353                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3354
3355   vec_add1 (deid, 0);
3356   vec_add1 (seid, 0);
3357
3358   if (mp->is_ip4)
3359     format_ip_address_fcn = format_ip4_address;
3360   else
3361     format_ip_address_fcn = format_ip6_address;
3362
3363
3364   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3365          clib_net_to_host_u32 (mp->vni),
3366          seid, deid,
3367          format_ip_address_fcn, mp->lloc,
3368          format_ip_address_fcn, mp->rloc,
3369          clib_net_to_host_u32 (mp->pkt_count),
3370          clib_net_to_host_u32 (mp->bytes));
3371
3372   vec_free (deid);
3373   vec_free (seid);
3374 }
3375
3376 static void
3377 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3378 {
3379   struct in6_addr ip6;
3380   struct in_addr ip4;
3381   vat_main_t *vam = &vat_main;
3382   vat_json_node_t *node = 0;
3383   u8 *deid = 0, *seid = 0;
3384
3385   if (VAT_JSON_ARRAY != vam->json_tree.type)
3386     {
3387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3388       vat_json_init_array (&vam->json_tree);
3389     }
3390   node = vat_json_array_add (&vam->json_tree);
3391
3392   vat_json_init_object (node);
3393   deid = format (0, "%U", format_lisp_eid_vat,
3394                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3395
3396   seid = format (0, "%U", format_lisp_eid_vat,
3397                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3398
3399   vec_add1 (deid, 0);
3400   vec_add1 (seid, 0);
3401
3402   vat_json_object_add_string_copy (node, "seid", seid);
3403   vat_json_object_add_string_copy (node, "deid", deid);
3404   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3405
3406   if (mp->is_ip4)
3407     {
3408       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3409       vat_json_object_add_ip4 (node, "lloc", ip4);
3410       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3411       vat_json_object_add_ip4 (node, "rloc", ip4);
3412     }
3413   else
3414     {
3415       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3416       vat_json_object_add_ip6 (node, "lloc", ip6);
3417       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3418       vat_json_object_add_ip6 (node, "rloc", ip6);
3419     }
3420   vat_json_object_add_uint (node, "pkt_count",
3421                             clib_net_to_host_u32 (mp->pkt_count));
3422   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3423
3424   vec_free (deid);
3425   vec_free (seid);
3426 }
3427
3428 static void
3429   vl_api_one_eid_table_map_details_t_handler
3430   (vl_api_one_eid_table_map_details_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   u8 *line = format (0, "%=10d%=10d",
3435                      clib_net_to_host_u32 (mp->vni),
3436                      clib_net_to_host_u32 (mp->dp_table));
3437   print (vam->ofp, "%v", line);
3438   vec_free (line);
3439 }
3440
3441 static void
3442   vl_api_one_eid_table_map_details_t_handler_json
3443   (vl_api_one_eid_table_map_details_t * mp)
3444 {
3445   vat_main_t *vam = &vat_main;
3446   vat_json_node_t *node = NULL;
3447
3448   if (VAT_JSON_ARRAY != vam->json_tree.type)
3449     {
3450       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3451       vat_json_init_array (&vam->json_tree);
3452     }
3453   node = vat_json_array_add (&vam->json_tree);
3454   vat_json_init_object (node);
3455   vat_json_object_add_uint (node, "dp_table",
3456                             clib_net_to_host_u32 (mp->dp_table));
3457   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3458 }
3459
3460 static void
3461   vl_api_one_eid_table_vni_details_t_handler
3462   (vl_api_one_eid_table_vni_details_t * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465
3466   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3467   print (vam->ofp, "%v", line);
3468   vec_free (line);
3469 }
3470
3471 static void
3472   vl_api_one_eid_table_vni_details_t_handler_json
3473   (vl_api_one_eid_table_vni_details_t * mp)
3474 {
3475   vat_main_t *vam = &vat_main;
3476   vat_json_node_t *node = NULL;
3477
3478   if (VAT_JSON_ARRAY != vam->json_tree.type)
3479     {
3480       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3481       vat_json_init_array (&vam->json_tree);
3482     }
3483   node = vat_json_array_add (&vam->json_tree);
3484   vat_json_init_object (node);
3485   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3486 }
3487
3488 static void
3489   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3490   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3491 {
3492   vat_main_t *vam = &vat_main;
3493   int retval = clib_net_to_host_u32 (mp->retval);
3494
3495   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3496   print (vam->ofp, "fallback threshold value: %d", mp->value);
3497
3498   vam->retval = retval;
3499   vam->result_ready = 1;
3500 }
3501
3502 static void
3503   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3504   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3505 {
3506   vat_main_t *vam = &vat_main;
3507   vat_json_node_t _node, *node = &_node;
3508   int retval = clib_net_to_host_u32 (mp->retval);
3509
3510   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3511   vat_json_init_object (node);
3512   vat_json_object_add_uint (node, "value", mp->value);
3513
3514   vat_json_print (vam->ofp, node);
3515   vat_json_free (node);
3516
3517   vam->retval = retval;
3518   vam->result_ready = 1;
3519 }
3520
3521 static void
3522   vl_api_show_one_map_register_state_reply_t_handler
3523   (vl_api_show_one_map_register_state_reply_t * mp)
3524 {
3525   vat_main_t *vam = &vat_main;
3526   int retval = clib_net_to_host_u32 (mp->retval);
3527
3528   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3529
3530   vam->retval = retval;
3531   vam->result_ready = 1;
3532 }
3533
3534 static void
3535   vl_api_show_one_map_register_state_reply_t_handler_json
3536   (vl_api_show_one_map_register_state_reply_t * mp)
3537 {
3538   vat_main_t *vam = &vat_main;
3539   vat_json_node_t _node, *node = &_node;
3540   int retval = clib_net_to_host_u32 (mp->retval);
3541
3542   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3543
3544   vat_json_init_object (node);
3545   vat_json_object_add_string_copy (node, "state", s);
3546
3547   vat_json_print (vam->ofp, node);
3548   vat_json_free (node);
3549
3550   vam->retval = retval;
3551   vam->result_ready = 1;
3552   vec_free (s);
3553 }
3554
3555 static void
3556   vl_api_show_one_rloc_probe_state_reply_t_handler
3557   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3558 {
3559   vat_main_t *vam = &vat_main;
3560   int retval = clib_net_to_host_u32 (mp->retval);
3561
3562   if (retval)
3563     goto end;
3564
3565   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3566 end:
3567   vam->retval = retval;
3568   vam->result_ready = 1;
3569 }
3570
3571 static void
3572   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3573   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3574 {
3575   vat_main_t *vam = &vat_main;
3576   vat_json_node_t _node, *node = &_node;
3577   int retval = clib_net_to_host_u32 (mp->retval);
3578
3579   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3580   vat_json_init_object (node);
3581   vat_json_object_add_string_copy (node, "state", s);
3582
3583   vat_json_print (vam->ofp, node);
3584   vat_json_free (node);
3585
3586   vam->retval = retval;
3587   vam->result_ready = 1;
3588   vec_free (s);
3589 }
3590
3591 static void
3592   vl_api_show_one_stats_enable_disable_reply_t_handler
3593   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   int retval = clib_net_to_host_u32 (mp->retval);
3597
3598   if (retval)
3599     goto end;
3600
3601   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3602 end:
3603   vam->retval = retval;
3604   vam->result_ready = 1;
3605 }
3606
3607 static void
3608   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3609   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3610 {
3611   vat_main_t *vam = &vat_main;
3612   vat_json_node_t _node, *node = &_node;
3613   int retval = clib_net_to_host_u32 (mp->retval);
3614
3615   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3616   vat_json_init_object (node);
3617   vat_json_object_add_string_copy (node, "state", s);
3618
3619   vat_json_print (vam->ofp, node);
3620   vat_json_free (node);
3621
3622   vam->retval = retval;
3623   vam->result_ready = 1;
3624   vec_free (s);
3625 }
3626
3627 static void
3628 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3629 {
3630   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3631   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3632   e->vni = clib_net_to_host_u32 (e->vni);
3633 }
3634
3635 static void
3636   gpe_fwd_entries_get_reply_t_net_to_host
3637   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3638 {
3639   u32 i;
3640
3641   mp->count = clib_net_to_host_u32 (mp->count);
3642   for (i = 0; i < mp->count; i++)
3643     {
3644       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3645     }
3646 }
3647
3648 static u8 *
3649 format_gpe_encap_mode (u8 * s, va_list * args)
3650 {
3651   u32 mode = va_arg (*args, u32);
3652
3653   switch (mode)
3654     {
3655     case 0:
3656       return format (s, "lisp");
3657     case 1:
3658       return format (s, "vxlan");
3659     }
3660   return 0;
3661 }
3662
3663 static void
3664   vl_api_gpe_get_encap_mode_reply_t_handler
3665   (vl_api_gpe_get_encap_mode_reply_t * mp)
3666 {
3667   vat_main_t *vam = &vat_main;
3668
3669   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3670   vam->retval = ntohl (mp->retval);
3671   vam->result_ready = 1;
3672 }
3673
3674 static void
3675   vl_api_gpe_get_encap_mode_reply_t_handler_json
3676   (vl_api_gpe_get_encap_mode_reply_t * mp)
3677 {
3678   vat_main_t *vam = &vat_main;
3679   vat_json_node_t node;
3680
3681   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3682   vec_add1 (encap_mode, 0);
3683
3684   vat_json_init_object (&node);
3685   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3686
3687   vec_free (encap_mode);
3688   vat_json_print (vam->ofp, &node);
3689   vat_json_free (&node);
3690
3691   vam->retval = ntohl (mp->retval);
3692   vam->result_ready = 1;
3693 }
3694
3695 static void
3696   vl_api_gpe_fwd_entry_path_details_t_handler
3697   (vl_api_gpe_fwd_entry_path_details_t * mp)
3698 {
3699   vat_main_t *vam = &vat_main;
3700   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3701
3702   if (mp->lcl_loc.is_ip4)
3703     format_ip_address_fcn = format_ip4_address;
3704   else
3705     format_ip_address_fcn = format_ip6_address;
3706
3707   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3708          format_ip_address_fcn, &mp->lcl_loc,
3709          format_ip_address_fcn, &mp->rmt_loc);
3710 }
3711
3712 static void
3713 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3714 {
3715   struct in6_addr ip6;
3716   struct in_addr ip4;
3717
3718   if (loc->is_ip4)
3719     {
3720       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3721       vat_json_object_add_ip4 (n, "address", ip4);
3722     }
3723   else
3724     {
3725       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3726       vat_json_object_add_ip6 (n, "address", ip6);
3727     }
3728   vat_json_object_add_uint (n, "weight", loc->weight);
3729 }
3730
3731 static void
3732   vl_api_gpe_fwd_entry_path_details_t_handler_json
3733   (vl_api_gpe_fwd_entry_path_details_t * mp)
3734 {
3735   vat_main_t *vam = &vat_main;
3736   vat_json_node_t *node = NULL;
3737   vat_json_node_t *loc_node;
3738
3739   if (VAT_JSON_ARRAY != vam->json_tree.type)
3740     {
3741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3742       vat_json_init_array (&vam->json_tree);
3743     }
3744   node = vat_json_array_add (&vam->json_tree);
3745   vat_json_init_object (node);
3746
3747   loc_node = vat_json_object_add (node, "local_locator");
3748   vat_json_init_object (loc_node);
3749   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3750
3751   loc_node = vat_json_object_add (node, "remote_locator");
3752   vat_json_init_object (loc_node);
3753   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3754 }
3755
3756 static void
3757   vl_api_gpe_fwd_entries_get_reply_t_handler
3758   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3759 {
3760   vat_main_t *vam = &vat_main;
3761   u32 i;
3762   int retval = clib_net_to_host_u32 (mp->retval);
3763   vl_api_gpe_fwd_entry_t *e;
3764
3765   if (retval)
3766     goto end;
3767
3768   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3769
3770   for (i = 0; i < mp->count; i++)
3771     {
3772       e = &mp->entries[i];
3773       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3774              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3775              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3776     }
3777
3778 end:
3779   vam->retval = retval;
3780   vam->result_ready = 1;
3781 }
3782
3783 static void
3784   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3785   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3786 {
3787   u8 *s = 0;
3788   vat_main_t *vam = &vat_main;
3789   vat_json_node_t *e = 0, root;
3790   u32 i;
3791   int retval = clib_net_to_host_u32 (mp->retval);
3792   vl_api_gpe_fwd_entry_t *fwd;
3793
3794   if (retval)
3795     goto end;
3796
3797   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3798   vat_json_init_array (&root);
3799
3800   for (i = 0; i < mp->count; i++)
3801     {
3802       e = vat_json_array_add (&root);
3803       fwd = &mp->entries[i];
3804
3805       vat_json_init_object (e);
3806       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3807       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3808       vat_json_object_add_int (e, "vni", fwd->vni);
3809       vat_json_object_add_int (e, "action", fwd->action);
3810
3811       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3812                   fwd->leid_prefix_len);
3813       vec_add1 (s, 0);
3814       vat_json_object_add_string_copy (e, "leid", s);
3815       vec_free (s);
3816
3817       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3818                   fwd->reid_prefix_len);
3819       vec_add1 (s, 0);
3820       vat_json_object_add_string_copy (e, "reid", s);
3821       vec_free (s);
3822     }
3823
3824   vat_json_print (vam->ofp, &root);
3825   vat_json_free (&root);
3826
3827 end:
3828   vam->retval = retval;
3829   vam->result_ready = 1;
3830 }
3831
3832 static void
3833   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3834   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3835 {
3836   vat_main_t *vam = &vat_main;
3837   u32 i, n;
3838   int retval = clib_net_to_host_u32 (mp->retval);
3839   vl_api_gpe_native_fwd_rpath_t *r;
3840
3841   if (retval)
3842     goto end;
3843
3844   n = clib_net_to_host_u32 (mp->count);
3845
3846   for (i = 0; i < n; i++)
3847     {
3848       r = &mp->entries[i];
3849       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3850              clib_net_to_host_u32 (r->fib_index),
3851              clib_net_to_host_u32 (r->nh_sw_if_index),
3852              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3853     }
3854
3855 end:
3856   vam->retval = retval;
3857   vam->result_ready = 1;
3858 }
3859
3860 static void
3861   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3862   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3863 {
3864   vat_main_t *vam = &vat_main;
3865   vat_json_node_t root, *e;
3866   u32 i, n;
3867   int retval = clib_net_to_host_u32 (mp->retval);
3868   vl_api_gpe_native_fwd_rpath_t *r;
3869   u8 *s;
3870
3871   if (retval)
3872     goto end;
3873
3874   n = clib_net_to_host_u32 (mp->count);
3875   vat_json_init_array (&root);
3876
3877   for (i = 0; i < n; i++)
3878     {
3879       e = vat_json_array_add (&root);
3880       vat_json_init_object (e);
3881       r = &mp->entries[i];
3882       s =
3883         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3884                 r->nh_addr);
3885       vec_add1 (s, 0);
3886       vat_json_object_add_string_copy (e, "ip4", s);
3887       vec_free (s);
3888
3889       vat_json_object_add_uint (e, "fib_index",
3890                                 clib_net_to_host_u32 (r->fib_index));
3891       vat_json_object_add_uint (e, "nh_sw_if_index",
3892                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3893     }
3894
3895   vat_json_print (vam->ofp, &root);
3896   vat_json_free (&root);
3897
3898 end:
3899   vam->retval = retval;
3900   vam->result_ready = 1;
3901 }
3902
3903 static void
3904   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3905   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3906 {
3907   vat_main_t *vam = &vat_main;
3908   u32 i, n;
3909   int retval = clib_net_to_host_u32 (mp->retval);
3910
3911   if (retval)
3912     goto end;
3913
3914   n = clib_net_to_host_u32 (mp->count);
3915
3916   for (i = 0; i < n; i++)
3917     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3918
3919 end:
3920   vam->retval = retval;
3921   vam->result_ready = 1;
3922 }
3923
3924 static void
3925   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3926   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3927 {
3928   vat_main_t *vam = &vat_main;
3929   vat_json_node_t root;
3930   u32 i, n;
3931   int retval = clib_net_to_host_u32 (mp->retval);
3932
3933   if (retval)
3934     goto end;
3935
3936   n = clib_net_to_host_u32 (mp->count);
3937   vat_json_init_array (&root);
3938
3939   for (i = 0; i < n; i++)
3940     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3941
3942   vat_json_print (vam->ofp, &root);
3943   vat_json_free (&root);
3944
3945 end:
3946   vam->retval = retval;
3947   vam->result_ready = 1;
3948 }
3949
3950 static void
3951   vl_api_one_ndp_entries_get_reply_t_handler
3952   (vl_api_one_ndp_entries_get_reply_t * mp)
3953 {
3954   vat_main_t *vam = &vat_main;
3955   u32 i, n;
3956   int retval = clib_net_to_host_u32 (mp->retval);
3957
3958   if (retval)
3959     goto end;
3960
3961   n = clib_net_to_host_u32 (mp->count);
3962
3963   for (i = 0; i < n; i++)
3964     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3965            format_ethernet_address, mp->entries[i].mac);
3966
3967 end:
3968   vam->retval = retval;
3969   vam->result_ready = 1;
3970 }
3971
3972 static void
3973   vl_api_one_ndp_entries_get_reply_t_handler_json
3974   (vl_api_one_ndp_entries_get_reply_t * mp)
3975 {
3976   u8 *s = 0;
3977   vat_main_t *vam = &vat_main;
3978   vat_json_node_t *e = 0, root;
3979   u32 i, n;
3980   int retval = clib_net_to_host_u32 (mp->retval);
3981   vl_api_one_ndp_entry_t *arp_entry;
3982
3983   if (retval)
3984     goto end;
3985
3986   n = clib_net_to_host_u32 (mp->count);
3987   vat_json_init_array (&root);
3988
3989   for (i = 0; i < n; i++)
3990     {
3991       e = vat_json_array_add (&root);
3992       arp_entry = &mp->entries[i];
3993
3994       vat_json_init_object (e);
3995       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3996       vec_add1 (s, 0);
3997
3998       vat_json_object_add_string_copy (e, "mac", s);
3999       vec_free (s);
4000
4001       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4002       vec_add1 (s, 0);
4003       vat_json_object_add_string_copy (e, "ip6", s);
4004       vec_free (s);
4005     }
4006
4007   vat_json_print (vam->ofp, &root);
4008   vat_json_free (&root);
4009
4010 end:
4011   vam->retval = retval;
4012   vam->result_ready = 1;
4013 }
4014
4015 static void
4016   vl_api_one_l2_arp_entries_get_reply_t_handler
4017   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4018 {
4019   vat_main_t *vam = &vat_main;
4020   u32 i, n;
4021   int retval = clib_net_to_host_u32 (mp->retval);
4022
4023   if (retval)
4024     goto end;
4025
4026   n = clib_net_to_host_u32 (mp->count);
4027
4028   for (i = 0; i < n; i++)
4029     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4030            format_ethernet_address, mp->entries[i].mac);
4031
4032 end:
4033   vam->retval = retval;
4034   vam->result_ready = 1;
4035 }
4036
4037 static void
4038   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4039   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4040 {
4041   u8 *s = 0;
4042   vat_main_t *vam = &vat_main;
4043   vat_json_node_t *e = 0, root;
4044   u32 i, n;
4045   int retval = clib_net_to_host_u32 (mp->retval);
4046   vl_api_one_l2_arp_entry_t *arp_entry;
4047
4048   if (retval)
4049     goto end;
4050
4051   n = clib_net_to_host_u32 (mp->count);
4052   vat_json_init_array (&root);
4053
4054   for (i = 0; i < n; i++)
4055     {
4056       e = vat_json_array_add (&root);
4057       arp_entry = &mp->entries[i];
4058
4059       vat_json_init_object (e);
4060       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4061       vec_add1 (s, 0);
4062
4063       vat_json_object_add_string_copy (e, "mac", s);
4064       vec_free (s);
4065
4066       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4067       vec_add1 (s, 0);
4068       vat_json_object_add_string_copy (e, "ip4", s);
4069       vec_free (s);
4070     }
4071
4072   vat_json_print (vam->ofp, &root);
4073   vat_json_free (&root);
4074
4075 end:
4076   vam->retval = retval;
4077   vam->result_ready = 1;
4078 }
4079
4080 static void
4081 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4082 {
4083   vat_main_t *vam = &vat_main;
4084   u32 i, n;
4085   int retval = clib_net_to_host_u32 (mp->retval);
4086
4087   if (retval)
4088     goto end;
4089
4090   n = clib_net_to_host_u32 (mp->count);
4091
4092   for (i = 0; i < n; i++)
4093     {
4094       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4095     }
4096
4097 end:
4098   vam->retval = retval;
4099   vam->result_ready = 1;
4100 }
4101
4102 static void
4103   vl_api_one_ndp_bd_get_reply_t_handler_json
4104   (vl_api_one_ndp_bd_get_reply_t * mp)
4105 {
4106   vat_main_t *vam = &vat_main;
4107   vat_json_node_t root;
4108   u32 i, n;
4109   int retval = clib_net_to_host_u32 (mp->retval);
4110
4111   if (retval)
4112     goto end;
4113
4114   n = clib_net_to_host_u32 (mp->count);
4115   vat_json_init_array (&root);
4116
4117   for (i = 0; i < n; i++)
4118     {
4119       vat_json_array_add_uint (&root,
4120                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4121     }
4122
4123   vat_json_print (vam->ofp, &root);
4124   vat_json_free (&root);
4125
4126 end:
4127   vam->retval = retval;
4128   vam->result_ready = 1;
4129 }
4130
4131 static void
4132   vl_api_one_l2_arp_bd_get_reply_t_handler
4133   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4134 {
4135   vat_main_t *vam = &vat_main;
4136   u32 i, n;
4137   int retval = clib_net_to_host_u32 (mp->retval);
4138
4139   if (retval)
4140     goto end;
4141
4142   n = clib_net_to_host_u32 (mp->count);
4143
4144   for (i = 0; i < n; i++)
4145     {
4146       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4147     }
4148
4149 end:
4150   vam->retval = retval;
4151   vam->result_ready = 1;
4152 }
4153
4154 static void
4155   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4156   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4157 {
4158   vat_main_t *vam = &vat_main;
4159   vat_json_node_t root;
4160   u32 i, n;
4161   int retval = clib_net_to_host_u32 (mp->retval);
4162
4163   if (retval)
4164     goto end;
4165
4166   n = clib_net_to_host_u32 (mp->count);
4167   vat_json_init_array (&root);
4168
4169   for (i = 0; i < n; i++)
4170     {
4171       vat_json_array_add_uint (&root,
4172                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4173     }
4174
4175   vat_json_print (vam->ofp, &root);
4176   vat_json_free (&root);
4177
4178 end:
4179   vam->retval = retval;
4180   vam->result_ready = 1;
4181 }
4182
4183 static void
4184   vl_api_one_adjacencies_get_reply_t_handler
4185   (vl_api_one_adjacencies_get_reply_t * mp)
4186 {
4187   vat_main_t *vam = &vat_main;
4188   u32 i, n;
4189   int retval = clib_net_to_host_u32 (mp->retval);
4190   vl_api_one_adjacency_t *a;
4191
4192   if (retval)
4193     goto end;
4194
4195   n = clib_net_to_host_u32 (mp->count);
4196
4197   for (i = 0; i < n; i++)
4198     {
4199       a = &mp->adjacencies[i];
4200       print (vam->ofp, "%U %40U",
4201              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4202              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4203     }
4204
4205 end:
4206   vam->retval = retval;
4207   vam->result_ready = 1;
4208 }
4209
4210 static void
4211   vl_api_one_adjacencies_get_reply_t_handler_json
4212   (vl_api_one_adjacencies_get_reply_t * mp)
4213 {
4214   u8 *s = 0;
4215   vat_main_t *vam = &vat_main;
4216   vat_json_node_t *e = 0, root;
4217   u32 i, n;
4218   int retval = clib_net_to_host_u32 (mp->retval);
4219   vl_api_one_adjacency_t *a;
4220
4221   if (retval)
4222     goto end;
4223
4224   n = clib_net_to_host_u32 (mp->count);
4225   vat_json_init_array (&root);
4226
4227   for (i = 0; i < n; i++)
4228     {
4229       e = vat_json_array_add (&root);
4230       a = &mp->adjacencies[i];
4231
4232       vat_json_init_object (e);
4233       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4234                   a->leid_prefix_len);
4235       vec_add1 (s, 0);
4236       vat_json_object_add_string_copy (e, "leid", s);
4237       vec_free (s);
4238
4239       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4240                   a->reid_prefix_len);
4241       vec_add1 (s, 0);
4242       vat_json_object_add_string_copy (e, "reid", s);
4243       vec_free (s);
4244     }
4245
4246   vat_json_print (vam->ofp, &root);
4247   vat_json_free (&root);
4248
4249 end:
4250   vam->retval = retval;
4251   vam->result_ready = 1;
4252 }
4253
4254 static void
4255 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4256 {
4257   vat_main_t *vam = &vat_main;
4258
4259   print (vam->ofp, "%=20U",
4260          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4261          mp->ip_address);
4262 }
4263
4264 static void
4265   vl_api_one_map_server_details_t_handler_json
4266   (vl_api_one_map_server_details_t * mp)
4267 {
4268   vat_main_t *vam = &vat_main;
4269   vat_json_node_t *node = NULL;
4270   struct in6_addr ip6;
4271   struct in_addr ip4;
4272
4273   if (VAT_JSON_ARRAY != vam->json_tree.type)
4274     {
4275       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4276       vat_json_init_array (&vam->json_tree);
4277     }
4278   node = vat_json_array_add (&vam->json_tree);
4279
4280   vat_json_init_object (node);
4281   if (mp->is_ipv6)
4282     {
4283       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4284       vat_json_object_add_ip6 (node, "map-server", ip6);
4285     }
4286   else
4287     {
4288       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4289       vat_json_object_add_ip4 (node, "map-server", ip4);
4290     }
4291 }
4292
4293 static void
4294 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4295                                            * mp)
4296 {
4297   vat_main_t *vam = &vat_main;
4298
4299   print (vam->ofp, "%=20U",
4300          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4301          mp->ip_address);
4302 }
4303
4304 static void
4305   vl_api_one_map_resolver_details_t_handler_json
4306   (vl_api_one_map_resolver_details_t * mp)
4307 {
4308   vat_main_t *vam = &vat_main;
4309   vat_json_node_t *node = NULL;
4310   struct in6_addr ip6;
4311   struct in_addr ip4;
4312
4313   if (VAT_JSON_ARRAY != vam->json_tree.type)
4314     {
4315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4316       vat_json_init_array (&vam->json_tree);
4317     }
4318   node = vat_json_array_add (&vam->json_tree);
4319
4320   vat_json_init_object (node);
4321   if (mp->is_ipv6)
4322     {
4323       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4324       vat_json_object_add_ip6 (node, "map resolver", ip6);
4325     }
4326   else
4327     {
4328       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4329       vat_json_object_add_ip4 (node, "map resolver", ip4);
4330     }
4331 }
4332
4333 static void
4334 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4335 {
4336   vat_main_t *vam = &vat_main;
4337   i32 retval = ntohl (mp->retval);
4338
4339   if (0 <= retval)
4340     {
4341       print (vam->ofp, "feature: %s\ngpe: %s",
4342              mp->feature_status ? "enabled" : "disabled",
4343              mp->gpe_status ? "enabled" : "disabled");
4344     }
4345
4346   vam->retval = retval;
4347   vam->result_ready = 1;
4348 }
4349
4350 static void
4351   vl_api_show_one_status_reply_t_handler_json
4352   (vl_api_show_one_status_reply_t * mp)
4353 {
4354   vat_main_t *vam = &vat_main;
4355   vat_json_node_t node;
4356   u8 *gpe_status = NULL;
4357   u8 *feature_status = NULL;
4358
4359   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4360   feature_status = format (0, "%s",
4361                            mp->feature_status ? "enabled" : "disabled");
4362   vec_add1 (gpe_status, 0);
4363   vec_add1 (feature_status, 0);
4364
4365   vat_json_init_object (&node);
4366   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4367   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4368
4369   vec_free (gpe_status);
4370   vec_free (feature_status);
4371
4372   vat_json_print (vam->ofp, &node);
4373   vat_json_free (&node);
4374
4375   vam->retval = ntohl (mp->retval);
4376   vam->result_ready = 1;
4377 }
4378
4379 static void
4380   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4381   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4382 {
4383   vat_main_t *vam = &vat_main;
4384   i32 retval = ntohl (mp->retval);
4385
4386   if (retval >= 0)
4387     {
4388       print (vam->ofp, "%=20s", mp->locator_set_name);
4389     }
4390
4391   vam->retval = retval;
4392   vam->result_ready = 1;
4393 }
4394
4395 static void
4396   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4397   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4398 {
4399   vat_main_t *vam = &vat_main;
4400   vat_json_node_t *node = NULL;
4401
4402   if (VAT_JSON_ARRAY != vam->json_tree.type)
4403     {
4404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4405       vat_json_init_array (&vam->json_tree);
4406     }
4407   node = vat_json_array_add (&vam->json_tree);
4408
4409   vat_json_init_object (node);
4410   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4411
4412   vat_json_print (vam->ofp, node);
4413   vat_json_free (node);
4414
4415   vam->retval = ntohl (mp->retval);
4416   vam->result_ready = 1;
4417 }
4418
4419 static u8 *
4420 format_lisp_map_request_mode (u8 * s, va_list * args)
4421 {
4422   u32 mode = va_arg (*args, u32);
4423
4424   switch (mode)
4425     {
4426     case 0:
4427       return format (0, "dst-only");
4428     case 1:
4429       return format (0, "src-dst");
4430     }
4431   return 0;
4432 }
4433
4434 static void
4435   vl_api_show_one_map_request_mode_reply_t_handler
4436   (vl_api_show_one_map_request_mode_reply_t * mp)
4437 {
4438   vat_main_t *vam = &vat_main;
4439   i32 retval = ntohl (mp->retval);
4440
4441   if (0 <= retval)
4442     {
4443       u32 mode = mp->mode;
4444       print (vam->ofp, "map_request_mode: %U",
4445              format_lisp_map_request_mode, mode);
4446     }
4447
4448   vam->retval = retval;
4449   vam->result_ready = 1;
4450 }
4451
4452 static void
4453   vl_api_show_one_map_request_mode_reply_t_handler_json
4454   (vl_api_show_one_map_request_mode_reply_t * mp)
4455 {
4456   vat_main_t *vam = &vat_main;
4457   vat_json_node_t node;
4458   u8 *s = 0;
4459   u32 mode;
4460
4461   mode = mp->mode;
4462   s = format (0, "%U", format_lisp_map_request_mode, mode);
4463   vec_add1 (s, 0);
4464
4465   vat_json_init_object (&node);
4466   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4467   vat_json_print (vam->ofp, &node);
4468   vat_json_free (&node);
4469
4470   vec_free (s);
4471   vam->retval = ntohl (mp->retval);
4472   vam->result_ready = 1;
4473 }
4474
4475 static void
4476   vl_api_one_show_xtr_mode_reply_t_handler
4477   (vl_api_one_show_xtr_mode_reply_t * mp)
4478 {
4479   vat_main_t *vam = &vat_main;
4480   i32 retval = ntohl (mp->retval);
4481
4482   if (0 <= retval)
4483     {
4484       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4485     }
4486
4487   vam->retval = retval;
4488   vam->result_ready = 1;
4489 }
4490
4491 static void
4492   vl_api_one_show_xtr_mode_reply_t_handler_json
4493   (vl_api_one_show_xtr_mode_reply_t * mp)
4494 {
4495   vat_main_t *vam = &vat_main;
4496   vat_json_node_t node;
4497   u8 *status = 0;
4498
4499   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4500   vec_add1 (status, 0);
4501
4502   vat_json_init_object (&node);
4503   vat_json_object_add_string_copy (&node, "status", status);
4504
4505   vec_free (status);
4506
4507   vat_json_print (vam->ofp, &node);
4508   vat_json_free (&node);
4509
4510   vam->retval = ntohl (mp->retval);
4511   vam->result_ready = 1;
4512 }
4513
4514 static void
4515   vl_api_one_show_pitr_mode_reply_t_handler
4516   (vl_api_one_show_pitr_mode_reply_t * mp)
4517 {
4518   vat_main_t *vam = &vat_main;
4519   i32 retval = ntohl (mp->retval);
4520
4521   if (0 <= retval)
4522     {
4523       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4524     }
4525
4526   vam->retval = retval;
4527   vam->result_ready = 1;
4528 }
4529
4530 static void
4531   vl_api_one_show_pitr_mode_reply_t_handler_json
4532   (vl_api_one_show_pitr_mode_reply_t * mp)
4533 {
4534   vat_main_t *vam = &vat_main;
4535   vat_json_node_t node;
4536   u8 *status = 0;
4537
4538   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4539   vec_add1 (status, 0);
4540
4541   vat_json_init_object (&node);
4542   vat_json_object_add_string_copy (&node, "status", status);
4543
4544   vec_free (status);
4545
4546   vat_json_print (vam->ofp, &node);
4547   vat_json_free (&node);
4548
4549   vam->retval = ntohl (mp->retval);
4550   vam->result_ready = 1;
4551 }
4552
4553 static void
4554   vl_api_one_show_petr_mode_reply_t_handler
4555   (vl_api_one_show_petr_mode_reply_t * mp)
4556 {
4557   vat_main_t *vam = &vat_main;
4558   i32 retval = ntohl (mp->retval);
4559
4560   if (0 <= retval)
4561     {
4562       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4563     }
4564
4565   vam->retval = retval;
4566   vam->result_ready = 1;
4567 }
4568
4569 static void
4570   vl_api_one_show_petr_mode_reply_t_handler_json
4571   (vl_api_one_show_petr_mode_reply_t * mp)
4572 {
4573   vat_main_t *vam = &vat_main;
4574   vat_json_node_t node;
4575   u8 *status = 0;
4576
4577   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4578   vec_add1 (status, 0);
4579
4580   vat_json_init_object (&node);
4581   vat_json_object_add_string_copy (&node, "status", status);
4582
4583   vec_free (status);
4584
4585   vat_json_print (vam->ofp, &node);
4586   vat_json_free (&node);
4587
4588   vam->retval = ntohl (mp->retval);
4589   vam->result_ready = 1;
4590 }
4591
4592 static void
4593   vl_api_show_one_use_petr_reply_t_handler
4594   (vl_api_show_one_use_petr_reply_t * mp)
4595 {
4596   vat_main_t *vam = &vat_main;
4597   i32 retval = ntohl (mp->retval);
4598
4599   if (0 <= retval)
4600     {
4601       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4602       if (mp->status)
4603         {
4604           print (vam->ofp, "Proxy-ETR address; %U",
4605                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4606                  mp->address);
4607         }
4608     }
4609
4610   vam->retval = retval;
4611   vam->result_ready = 1;
4612 }
4613
4614 static void
4615   vl_api_show_one_use_petr_reply_t_handler_json
4616   (vl_api_show_one_use_petr_reply_t * mp)
4617 {
4618   vat_main_t *vam = &vat_main;
4619   vat_json_node_t node;
4620   u8 *status = 0;
4621   struct in_addr ip4;
4622   struct in6_addr ip6;
4623
4624   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4625   vec_add1 (status, 0);
4626
4627   vat_json_init_object (&node);
4628   vat_json_object_add_string_copy (&node, "status", status);
4629   if (mp->status)
4630     {
4631       if (mp->is_ip4)
4632         {
4633           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4634           vat_json_object_add_ip6 (&node, "address", ip6);
4635         }
4636       else
4637         {
4638           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4639           vat_json_object_add_ip4 (&node, "address", ip4);
4640         }
4641     }
4642
4643   vec_free (status);
4644
4645   vat_json_print (vam->ofp, &node);
4646   vat_json_free (&node);
4647
4648   vam->retval = ntohl (mp->retval);
4649   vam->result_ready = 1;
4650 }
4651
4652 static void
4653   vl_api_show_one_nsh_mapping_reply_t_handler
4654   (vl_api_show_one_nsh_mapping_reply_t * mp)
4655 {
4656   vat_main_t *vam = &vat_main;
4657   i32 retval = ntohl (mp->retval);
4658
4659   if (0 <= retval)
4660     {
4661       print (vam->ofp, "%-20s%-16s",
4662              mp->is_set ? "set" : "not-set",
4663              mp->is_set ? (char *) mp->locator_set_name : "");
4664     }
4665
4666   vam->retval = retval;
4667   vam->result_ready = 1;
4668 }
4669
4670 static void
4671   vl_api_show_one_nsh_mapping_reply_t_handler_json
4672   (vl_api_show_one_nsh_mapping_reply_t * mp)
4673 {
4674   vat_main_t *vam = &vat_main;
4675   vat_json_node_t node;
4676   u8 *status = 0;
4677
4678   status = format (0, "%s", mp->is_set ? "yes" : "no");
4679   vec_add1 (status, 0);
4680
4681   vat_json_init_object (&node);
4682   vat_json_object_add_string_copy (&node, "is_set", status);
4683   if (mp->is_set)
4684     {
4685       vat_json_object_add_string_copy (&node, "locator_set",
4686                                        mp->locator_set_name);
4687     }
4688
4689   vec_free (status);
4690
4691   vat_json_print (vam->ofp, &node);
4692   vat_json_free (&node);
4693
4694   vam->retval = ntohl (mp->retval);
4695   vam->result_ready = 1;
4696 }
4697
4698 static void
4699   vl_api_show_one_map_register_ttl_reply_t_handler
4700   (vl_api_show_one_map_register_ttl_reply_t * mp)
4701 {
4702   vat_main_t *vam = &vat_main;
4703   i32 retval = ntohl (mp->retval);
4704
4705   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4706
4707   if (0 <= retval)
4708     {
4709       print (vam->ofp, "ttl: %u", mp->ttl);
4710     }
4711
4712   vam->retval = retval;
4713   vam->result_ready = 1;
4714 }
4715
4716 static void
4717   vl_api_show_one_map_register_ttl_reply_t_handler_json
4718   (vl_api_show_one_map_register_ttl_reply_t * mp)
4719 {
4720   vat_main_t *vam = &vat_main;
4721   vat_json_node_t node;
4722
4723   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4724   vat_json_init_object (&node);
4725   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4726
4727   vat_json_print (vam->ofp, &node);
4728   vat_json_free (&node);
4729
4730   vam->retval = ntohl (mp->retval);
4731   vam->result_ready = 1;
4732 }
4733
4734 static void
4735 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4736 {
4737   vat_main_t *vam = &vat_main;
4738   i32 retval = ntohl (mp->retval);
4739
4740   if (0 <= retval)
4741     {
4742       print (vam->ofp, "%-20s%-16s",
4743              mp->status ? "enabled" : "disabled",
4744              mp->status ? (char *) mp->locator_set_name : "");
4745     }
4746
4747   vam->retval = retval;
4748   vam->result_ready = 1;
4749 }
4750
4751 static void
4752 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4753 {
4754   vat_main_t *vam = &vat_main;
4755   vat_json_node_t node;
4756   u8 *status = 0;
4757
4758   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4759   vec_add1 (status, 0);
4760
4761   vat_json_init_object (&node);
4762   vat_json_object_add_string_copy (&node, "status", status);
4763   if (mp->status)
4764     {
4765       vat_json_object_add_string_copy (&node, "locator_set",
4766                                        mp->locator_set_name);
4767     }
4768
4769   vec_free (status);
4770
4771   vat_json_print (vam->ofp, &node);
4772   vat_json_free (&node);
4773
4774   vam->retval = ntohl (mp->retval);
4775   vam->result_ready = 1;
4776 }
4777
4778 static u8 *
4779 format_policer_type (u8 * s, va_list * va)
4780 {
4781   u32 i = va_arg (*va, u32);
4782
4783   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4784     s = format (s, "1r2c");
4785   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4786     s = format (s, "1r3c");
4787   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4788     s = format (s, "2r3c-2698");
4789   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4790     s = format (s, "2r3c-4115");
4791   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4792     s = format (s, "2r3c-mef5cf1");
4793   else
4794     s = format (s, "ILLEGAL");
4795   return s;
4796 }
4797
4798 static u8 *
4799 format_policer_rate_type (u8 * s, va_list * va)
4800 {
4801   u32 i = va_arg (*va, u32);
4802
4803   if (i == SSE2_QOS_RATE_KBPS)
4804     s = format (s, "kbps");
4805   else if (i == SSE2_QOS_RATE_PPS)
4806     s = format (s, "pps");
4807   else
4808     s = format (s, "ILLEGAL");
4809   return s;
4810 }
4811
4812 static u8 *
4813 format_policer_round_type (u8 * s, va_list * va)
4814 {
4815   u32 i = va_arg (*va, u32);
4816
4817   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4818     s = format (s, "closest");
4819   else if (i == SSE2_QOS_ROUND_TO_UP)
4820     s = format (s, "up");
4821   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4822     s = format (s, "down");
4823   else
4824     s = format (s, "ILLEGAL");
4825   return s;
4826 }
4827
4828 static u8 *
4829 format_policer_action_type (u8 * s, va_list * va)
4830 {
4831   u32 i = va_arg (*va, u32);
4832
4833   if (i == SSE2_QOS_ACTION_DROP)
4834     s = format (s, "drop");
4835   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4836     s = format (s, "transmit");
4837   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4838     s = format (s, "mark-and-transmit");
4839   else
4840     s = format (s, "ILLEGAL");
4841   return s;
4842 }
4843
4844 static u8 *
4845 format_dscp (u8 * s, va_list * va)
4846 {
4847   u32 i = va_arg (*va, u32);
4848   char *t = 0;
4849
4850   switch (i)
4851     {
4852 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4853       foreach_vnet_dscp
4854 #undef _
4855     default:
4856       return format (s, "ILLEGAL");
4857     }
4858   s = format (s, "%s", t);
4859   return s;
4860 }
4861
4862 static void
4863 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4864 {
4865   vat_main_t *vam = &vat_main;
4866   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4867
4868   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4869     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4870   else
4871     conform_dscp_str = format (0, "");
4872
4873   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4874     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4875   else
4876     exceed_dscp_str = format (0, "");
4877
4878   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4879     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4880   else
4881     violate_dscp_str = format (0, "");
4882
4883   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4884          "rate type %U, round type %U, %s rate, %s color-aware, "
4885          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4886          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4887          "conform action %U%s, exceed action %U%s, violate action %U%s",
4888          mp->name,
4889          format_policer_type, mp->type,
4890          ntohl (mp->cir),
4891          ntohl (mp->eir),
4892          clib_net_to_host_u64 (mp->cb),
4893          clib_net_to_host_u64 (mp->eb),
4894          format_policer_rate_type, mp->rate_type,
4895          format_policer_round_type, mp->round_type,
4896          mp->single_rate ? "single" : "dual",
4897          mp->color_aware ? "is" : "not",
4898          ntohl (mp->cir_tokens_per_period),
4899          ntohl (mp->pir_tokens_per_period),
4900          ntohl (mp->scale),
4901          ntohl (mp->current_limit),
4902          ntohl (mp->current_bucket),
4903          ntohl (mp->extended_limit),
4904          ntohl (mp->extended_bucket),
4905          clib_net_to_host_u64 (mp->last_update_time),
4906          format_policer_action_type, mp->conform_action_type,
4907          conform_dscp_str,
4908          format_policer_action_type, mp->exceed_action_type,
4909          exceed_dscp_str,
4910          format_policer_action_type, mp->violate_action_type,
4911          violate_dscp_str);
4912
4913   vec_free (conform_dscp_str);
4914   vec_free (exceed_dscp_str);
4915   vec_free (violate_dscp_str);
4916 }
4917
4918 static void vl_api_policer_details_t_handler_json
4919   (vl_api_policer_details_t * mp)
4920 {
4921   vat_main_t *vam = &vat_main;
4922   vat_json_node_t *node;
4923   u8 *rate_type_str, *round_type_str, *type_str;
4924   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4925
4926   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4927   round_type_str =
4928     format (0, "%U", format_policer_round_type, mp->round_type);
4929   type_str = format (0, "%U", format_policer_type, mp->type);
4930   conform_action_str = format (0, "%U", format_policer_action_type,
4931                                mp->conform_action_type);
4932   exceed_action_str = format (0, "%U", format_policer_action_type,
4933                               mp->exceed_action_type);
4934   violate_action_str = format (0, "%U", format_policer_action_type,
4935                                mp->violate_action_type);
4936
4937   if (VAT_JSON_ARRAY != vam->json_tree.type)
4938     {
4939       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4940       vat_json_init_array (&vam->json_tree);
4941     }
4942   node = vat_json_array_add (&vam->json_tree);
4943
4944   vat_json_init_object (node);
4945   vat_json_object_add_string_copy (node, "name", mp->name);
4946   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4947   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4948   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4949   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4950   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4951   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4952   vat_json_object_add_string_copy (node, "type", type_str);
4953   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4954   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4955   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4956   vat_json_object_add_uint (node, "cir_tokens_per_period",
4957                             ntohl (mp->cir_tokens_per_period));
4958   vat_json_object_add_uint (node, "eir_tokens_per_period",
4959                             ntohl (mp->pir_tokens_per_period));
4960   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4961   vat_json_object_add_uint (node, "current_bucket",
4962                             ntohl (mp->current_bucket));
4963   vat_json_object_add_uint (node, "extended_limit",
4964                             ntohl (mp->extended_limit));
4965   vat_json_object_add_uint (node, "extended_bucket",
4966                             ntohl (mp->extended_bucket));
4967   vat_json_object_add_uint (node, "last_update_time",
4968                             ntohl (mp->last_update_time));
4969   vat_json_object_add_string_copy (node, "conform_action",
4970                                    conform_action_str);
4971   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4972     {
4973       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4974       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4975       vec_free (dscp_str);
4976     }
4977   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4978   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4979     {
4980       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4981       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4982       vec_free (dscp_str);
4983     }
4984   vat_json_object_add_string_copy (node, "violate_action",
4985                                    violate_action_str);
4986   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4987     {
4988       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4989       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4990       vec_free (dscp_str);
4991     }
4992
4993   vec_free (rate_type_str);
4994   vec_free (round_type_str);
4995   vec_free (type_str);
4996   vec_free (conform_action_str);
4997   vec_free (exceed_action_str);
4998   vec_free (violate_action_str);
4999 }
5000
5001 static void
5002 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5003                                            mp)
5004 {
5005   vat_main_t *vam = &vat_main;
5006   int i, count = ntohl (mp->count);
5007
5008   if (count > 0)
5009     print (vam->ofp, "classify table ids (%d) : ", count);
5010   for (i = 0; i < count; i++)
5011     {
5012       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5013       print (vam->ofp, (i < count - 1) ? "," : "");
5014     }
5015   vam->retval = ntohl (mp->retval);
5016   vam->result_ready = 1;
5017 }
5018
5019 static void
5020   vl_api_classify_table_ids_reply_t_handler_json
5021   (vl_api_classify_table_ids_reply_t * mp)
5022 {
5023   vat_main_t *vam = &vat_main;
5024   int i, count = ntohl (mp->count);
5025
5026   if (count > 0)
5027     {
5028       vat_json_node_t node;
5029
5030       vat_json_init_object (&node);
5031       for (i = 0; i < count; i++)
5032         {
5033           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5034         }
5035       vat_json_print (vam->ofp, &node);
5036       vat_json_free (&node);
5037     }
5038   vam->retval = ntohl (mp->retval);
5039   vam->result_ready = 1;
5040 }
5041
5042 static void
5043   vl_api_classify_table_by_interface_reply_t_handler
5044   (vl_api_classify_table_by_interface_reply_t * mp)
5045 {
5046   vat_main_t *vam = &vat_main;
5047   u32 table_id;
5048
5049   table_id = ntohl (mp->l2_table_id);
5050   if (table_id != ~0)
5051     print (vam->ofp, "l2 table id : %d", table_id);
5052   else
5053     print (vam->ofp, "l2 table id : No input ACL tables configured");
5054   table_id = ntohl (mp->ip4_table_id);
5055   if (table_id != ~0)
5056     print (vam->ofp, "ip4 table id : %d", table_id);
5057   else
5058     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5059   table_id = ntohl (mp->ip6_table_id);
5060   if (table_id != ~0)
5061     print (vam->ofp, "ip6 table id : %d", table_id);
5062   else
5063     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5064   vam->retval = ntohl (mp->retval);
5065   vam->result_ready = 1;
5066 }
5067
5068 static void
5069   vl_api_classify_table_by_interface_reply_t_handler_json
5070   (vl_api_classify_table_by_interface_reply_t * mp)
5071 {
5072   vat_main_t *vam = &vat_main;
5073   vat_json_node_t node;
5074
5075   vat_json_init_object (&node);
5076
5077   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5078   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5079   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5080
5081   vat_json_print (vam->ofp, &node);
5082   vat_json_free (&node);
5083
5084   vam->retval = ntohl (mp->retval);
5085   vam->result_ready = 1;
5086 }
5087
5088 static void vl_api_policer_add_del_reply_t_handler
5089   (vl_api_policer_add_del_reply_t * mp)
5090 {
5091   vat_main_t *vam = &vat_main;
5092   i32 retval = ntohl (mp->retval);
5093   if (vam->async_mode)
5094     {
5095       vam->async_errors += (retval < 0);
5096     }
5097   else
5098     {
5099       vam->retval = retval;
5100       vam->result_ready = 1;
5101       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5102         /*
5103          * Note: this is just barely thread-safe, depends on
5104          * the main thread spinning waiting for an answer...
5105          */
5106         errmsg ("policer index %d", ntohl (mp->policer_index));
5107     }
5108 }
5109
5110 static void vl_api_policer_add_del_reply_t_handler_json
5111   (vl_api_policer_add_del_reply_t * mp)
5112 {
5113   vat_main_t *vam = &vat_main;
5114   vat_json_node_t node;
5115
5116   vat_json_init_object (&node);
5117   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5118   vat_json_object_add_uint (&node, "policer_index",
5119                             ntohl (mp->policer_index));
5120
5121   vat_json_print (vam->ofp, &node);
5122   vat_json_free (&node);
5123
5124   vam->retval = ntohl (mp->retval);
5125   vam->result_ready = 1;
5126 }
5127
5128 /* Format hex dump. */
5129 u8 *
5130 format_hex_bytes (u8 * s, va_list * va)
5131 {
5132   u8 *bytes = va_arg (*va, u8 *);
5133   int n_bytes = va_arg (*va, int);
5134   uword i;
5135
5136   /* Print short or long form depending on byte count. */
5137   uword short_form = n_bytes <= 32;
5138   u32 indent = format_get_indent (s);
5139
5140   if (n_bytes == 0)
5141     return s;
5142
5143   for (i = 0; i < n_bytes; i++)
5144     {
5145       if (!short_form && (i % 32) == 0)
5146         s = format (s, "%08x: ", i);
5147       s = format (s, "%02x", bytes[i]);
5148       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5149         s = format (s, "\n%U", format_white_space, indent);
5150     }
5151
5152   return s;
5153 }
5154
5155 static void
5156 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5157                                             * mp)
5158 {
5159   vat_main_t *vam = &vat_main;
5160   i32 retval = ntohl (mp->retval);
5161   if (retval == 0)
5162     {
5163       print (vam->ofp, "classify table info :");
5164       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5165              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5166              ntohl (mp->miss_next_index));
5167       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5168              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5169              ntohl (mp->match_n_vectors));
5170       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5171              ntohl (mp->mask_length));
5172     }
5173   vam->retval = retval;
5174   vam->result_ready = 1;
5175 }
5176
5177 static void
5178   vl_api_classify_table_info_reply_t_handler_json
5179   (vl_api_classify_table_info_reply_t * mp)
5180 {
5181   vat_main_t *vam = &vat_main;
5182   vat_json_node_t node;
5183
5184   i32 retval = ntohl (mp->retval);
5185   if (retval == 0)
5186     {
5187       vat_json_init_object (&node);
5188
5189       vat_json_object_add_int (&node, "sessions",
5190                                ntohl (mp->active_sessions));
5191       vat_json_object_add_int (&node, "nexttbl",
5192                                ntohl (mp->next_table_index));
5193       vat_json_object_add_int (&node, "nextnode",
5194                                ntohl (mp->miss_next_index));
5195       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5196       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5197       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5198       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5199                       ntohl (mp->mask_length), 0);
5200       vat_json_object_add_string_copy (&node, "mask", s);
5201
5202       vat_json_print (vam->ofp, &node);
5203       vat_json_free (&node);
5204     }
5205   vam->retval = ntohl (mp->retval);
5206   vam->result_ready = 1;
5207 }
5208
5209 static void
5210 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5211                                            mp)
5212 {
5213   vat_main_t *vam = &vat_main;
5214
5215   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5216          ntohl (mp->hit_next_index), ntohl (mp->advance),
5217          ntohl (mp->opaque_index));
5218   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5219          ntohl (mp->match_length));
5220 }
5221
5222 static void
5223   vl_api_classify_session_details_t_handler_json
5224   (vl_api_classify_session_details_t * mp)
5225 {
5226   vat_main_t *vam = &vat_main;
5227   vat_json_node_t *node = NULL;
5228
5229   if (VAT_JSON_ARRAY != vam->json_tree.type)
5230     {
5231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5232       vat_json_init_array (&vam->json_tree);
5233     }
5234   node = vat_json_array_add (&vam->json_tree);
5235
5236   vat_json_init_object (node);
5237   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5238   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5239   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5240   u8 *s =
5241     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5242             0);
5243   vat_json_object_add_string_copy (node, "match", s);
5244 }
5245
5246 static void vl_api_pg_create_interface_reply_t_handler
5247   (vl_api_pg_create_interface_reply_t * mp)
5248 {
5249   vat_main_t *vam = &vat_main;
5250
5251   vam->retval = ntohl (mp->retval);
5252   vam->result_ready = 1;
5253 }
5254
5255 static void vl_api_pg_create_interface_reply_t_handler_json
5256   (vl_api_pg_create_interface_reply_t * mp)
5257 {
5258   vat_main_t *vam = &vat_main;
5259   vat_json_node_t node;
5260
5261   i32 retval = ntohl (mp->retval);
5262   if (retval == 0)
5263     {
5264       vat_json_init_object (&node);
5265
5266       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5267
5268       vat_json_print (vam->ofp, &node);
5269       vat_json_free (&node);
5270     }
5271   vam->retval = ntohl (mp->retval);
5272   vam->result_ready = 1;
5273 }
5274
5275 static void vl_api_policer_classify_details_t_handler
5276   (vl_api_policer_classify_details_t * mp)
5277 {
5278   vat_main_t *vam = &vat_main;
5279
5280   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5281          ntohl (mp->table_index));
5282 }
5283
5284 static void vl_api_policer_classify_details_t_handler_json
5285   (vl_api_policer_classify_details_t * mp)
5286 {
5287   vat_main_t *vam = &vat_main;
5288   vat_json_node_t *node;
5289
5290   if (VAT_JSON_ARRAY != vam->json_tree.type)
5291     {
5292       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5293       vat_json_init_array (&vam->json_tree);
5294     }
5295   node = vat_json_array_add (&vam->json_tree);
5296
5297   vat_json_init_object (node);
5298   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5299   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5300 }
5301
5302 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5303   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5304 {
5305   vat_main_t *vam = &vat_main;
5306   i32 retval = ntohl (mp->retval);
5307   if (vam->async_mode)
5308     {
5309       vam->async_errors += (retval < 0);
5310     }
5311   else
5312     {
5313       vam->retval = retval;
5314       vam->sw_if_index = ntohl (mp->sw_if_index);
5315       vam->result_ready = 1;
5316     }
5317   vam->regenerate_interface_table = 1;
5318 }
5319
5320 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5321   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5322 {
5323   vat_main_t *vam = &vat_main;
5324   vat_json_node_t node;
5325
5326   vat_json_init_object (&node);
5327   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5328   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5329
5330   vat_json_print (vam->ofp, &node);
5331   vat_json_free (&node);
5332
5333   vam->retval = ntohl (mp->retval);
5334   vam->result_ready = 1;
5335 }
5336
5337 static void vl_api_flow_classify_details_t_handler
5338   (vl_api_flow_classify_details_t * mp)
5339 {
5340   vat_main_t *vam = &vat_main;
5341
5342   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5343          ntohl (mp->table_index));
5344 }
5345
5346 static void vl_api_flow_classify_details_t_handler_json
5347   (vl_api_flow_classify_details_t * mp)
5348 {
5349   vat_main_t *vam = &vat_main;
5350   vat_json_node_t *node;
5351
5352   if (VAT_JSON_ARRAY != vam->json_tree.type)
5353     {
5354       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5355       vat_json_init_array (&vam->json_tree);
5356     }
5357   node = vat_json_array_add (&vam->json_tree);
5358
5359   vat_json_init_object (node);
5360   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5361   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5362 }
5363
5364 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5365 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5366 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5367 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5368 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5369 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5370 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5371 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5372 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5373 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5374 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5375 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5376 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5377 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5378 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5379 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5380 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5381 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5382 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5383 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5384 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5385 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5386
5387 /*
5388  * Generate boilerplate reply handlers, which
5389  * dig the return value out of the xxx_reply_t API message,
5390  * stick it into vam->retval, and set vam->result_ready
5391  *
5392  * Could also do this by pointing N message decode slots at
5393  * a single function, but that could break in subtle ways.
5394  */
5395
5396 #define foreach_standard_reply_retval_handler           \
5397 _(sw_interface_set_flags_reply)                         \
5398 _(sw_interface_add_del_address_reply)                   \
5399 _(sw_interface_set_rx_mode_reply)                       \
5400 _(sw_interface_set_table_reply)                         \
5401 _(sw_interface_set_mpls_enable_reply)                   \
5402 _(sw_interface_set_vpath_reply)                         \
5403 _(sw_interface_set_vxlan_bypass_reply)                  \
5404 _(sw_interface_set_geneve_bypass_reply)                 \
5405 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5406 _(sw_interface_set_l2_bridge_reply)                     \
5407 _(bridge_domain_add_del_reply)                          \
5408 _(sw_interface_set_l2_xconnect_reply)                   \
5409 _(l2fib_add_del_reply)                                  \
5410 _(l2fib_flush_int_reply)                                \
5411 _(l2fib_flush_bd_reply)                                 \
5412 _(ip_add_del_route_reply)                               \
5413 _(ip_table_add_del_reply)                               \
5414 _(ip_mroute_add_del_reply)                              \
5415 _(mpls_route_add_del_reply)                             \
5416 _(mpls_table_add_del_reply)                             \
5417 _(mpls_ip_bind_unbind_reply)                            \
5418 _(bier_route_add_del_reply)                             \
5419 _(bier_table_add_del_reply)                             \
5420 _(proxy_arp_add_del_reply)                              \
5421 _(proxy_arp_intfc_enable_disable_reply)                 \
5422 _(sw_interface_set_unnumbered_reply)                    \
5423 _(ip_neighbor_add_del_reply)                            \
5424 _(oam_add_del_reply)                                    \
5425 _(reset_fib_reply)                                      \
5426 _(dhcp_proxy_config_reply)                              \
5427 _(dhcp_proxy_set_vss_reply)                             \
5428 _(dhcp_client_config_reply)                             \
5429 _(set_ip_flow_hash_reply)                               \
5430 _(sw_interface_ip6_enable_disable_reply)                \
5431 _(sw_interface_ip6_set_link_local_address_reply)        \
5432 _(ip6nd_proxy_add_del_reply)                            \
5433 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5434 _(sw_interface_ip6nd_ra_config_reply)                   \
5435 _(set_arp_neighbor_limit_reply)                         \
5436 _(l2_patch_add_del_reply)                               \
5437 _(sr_policy_add_reply)                                  \
5438 _(sr_policy_mod_reply)                                  \
5439 _(sr_policy_del_reply)                                  \
5440 _(sr_localsid_add_del_reply)                            \
5441 _(sr_steering_add_del_reply)                            \
5442 _(classify_add_del_session_reply)                       \
5443 _(classify_set_interface_ip_table_reply)                \
5444 _(classify_set_interface_l2_tables_reply)               \
5445 _(l2tpv3_set_tunnel_cookies_reply)                      \
5446 _(l2tpv3_interface_enable_disable_reply)                \
5447 _(l2tpv3_set_lookup_key_reply)                          \
5448 _(l2_fib_clear_table_reply)                             \
5449 _(l2_interface_efp_filter_reply)                        \
5450 _(l2_interface_vlan_tag_rewrite_reply)                  \
5451 _(modify_vhost_user_if_reply)                           \
5452 _(delete_vhost_user_if_reply)                           \
5453 _(ip_probe_neighbor_reply)                              \
5454 _(ip_scan_neighbor_enable_disable_reply)                \
5455 _(want_ip4_arp_events_reply)                            \
5456 _(want_ip6_nd_events_reply)                             \
5457 _(want_l2_macs_events_reply)                            \
5458 _(input_acl_set_interface_reply)                        \
5459 _(ipsec_spd_add_del_reply)                              \
5460 _(ipsec_interface_add_del_spd_reply)                    \
5461 _(ipsec_spd_add_del_entry_reply)                        \
5462 _(ipsec_sad_add_del_entry_reply)                        \
5463 _(ipsec_sa_set_key_reply)                               \
5464 _(ipsec_tunnel_if_add_del_reply)                        \
5465 _(ipsec_tunnel_if_set_key_reply)                        \
5466 _(ipsec_tunnel_if_set_sa_reply)                         \
5467 _(ikev2_profile_add_del_reply)                          \
5468 _(ikev2_profile_set_auth_reply)                         \
5469 _(ikev2_profile_set_id_reply)                           \
5470 _(ikev2_profile_set_ts_reply)                           \
5471 _(ikev2_set_local_key_reply)                            \
5472 _(ikev2_set_responder_reply)                            \
5473 _(ikev2_set_ike_transforms_reply)                       \
5474 _(ikev2_set_esp_transforms_reply)                       \
5475 _(ikev2_set_sa_lifetime_reply)                          \
5476 _(ikev2_initiate_sa_init_reply)                         \
5477 _(ikev2_initiate_del_ike_sa_reply)                      \
5478 _(ikev2_initiate_del_child_sa_reply)                    \
5479 _(ikev2_initiate_rekey_child_sa_reply)                  \
5480 _(delete_loopback_reply)                                \
5481 _(bd_ip_mac_add_del_reply)                              \
5482 _(map_del_domain_reply)                                 \
5483 _(map_add_del_rule_reply)                               \
5484 _(want_interface_events_reply)                          \
5485 _(want_stats_reply)                                     \
5486 _(cop_interface_enable_disable_reply)                   \
5487 _(cop_whitelist_enable_disable_reply)                   \
5488 _(sw_interface_clear_stats_reply)                       \
5489 _(ioam_enable_reply)                                    \
5490 _(ioam_disable_reply)                                   \
5491 _(one_add_del_locator_reply)                            \
5492 _(one_add_del_local_eid_reply)                          \
5493 _(one_add_del_remote_mapping_reply)                     \
5494 _(one_add_del_adjacency_reply)                          \
5495 _(one_add_del_map_resolver_reply)                       \
5496 _(one_add_del_map_server_reply)                         \
5497 _(one_enable_disable_reply)                             \
5498 _(one_rloc_probe_enable_disable_reply)                  \
5499 _(one_map_register_enable_disable_reply)                \
5500 _(one_map_register_set_ttl_reply)                       \
5501 _(one_set_transport_protocol_reply)                     \
5502 _(one_map_register_fallback_threshold_reply)            \
5503 _(one_pitr_set_locator_set_reply)                       \
5504 _(one_map_request_mode_reply)                           \
5505 _(one_add_del_map_request_itr_rlocs_reply)              \
5506 _(one_eid_table_add_del_map_reply)                      \
5507 _(one_use_petr_reply)                                   \
5508 _(one_stats_enable_disable_reply)                       \
5509 _(one_add_del_l2_arp_entry_reply)                       \
5510 _(one_add_del_ndp_entry_reply)                          \
5511 _(one_stats_flush_reply)                                \
5512 _(one_enable_disable_xtr_mode_reply)                    \
5513 _(one_enable_disable_pitr_mode_reply)                   \
5514 _(one_enable_disable_petr_mode_reply)                   \
5515 _(gpe_enable_disable_reply)                             \
5516 _(gpe_set_encap_mode_reply)                             \
5517 _(gpe_add_del_iface_reply)                              \
5518 _(gpe_add_del_native_fwd_rpath_reply)                   \
5519 _(af_packet_delete_reply)                               \
5520 _(policer_classify_set_interface_reply)                 \
5521 _(netmap_create_reply)                                  \
5522 _(netmap_delete_reply)                                  \
5523 _(set_ipfix_exporter_reply)                             \
5524 _(set_ipfix_classify_stream_reply)                      \
5525 _(ipfix_classify_table_add_del_reply)                   \
5526 _(flow_classify_set_interface_reply)                    \
5527 _(sw_interface_span_enable_disable_reply)               \
5528 _(pg_capture_reply)                                     \
5529 _(pg_enable_disable_reply)                              \
5530 _(ip_source_and_port_range_check_add_del_reply)         \
5531 _(ip_source_and_port_range_check_interface_add_del_reply)\
5532 _(delete_subif_reply)                                   \
5533 _(l2_interface_pbb_tag_rewrite_reply)                   \
5534 _(punt_reply)                                           \
5535 _(feature_enable_disable_reply)                         \
5536 _(sw_interface_tag_add_del_reply)                       \
5537 _(sw_interface_set_mtu_reply)                           \
5538 _(p2p_ethernet_add_reply)                               \
5539 _(p2p_ethernet_del_reply)                               \
5540 _(lldp_config_reply)                                    \
5541 _(sw_interface_set_lldp_reply)                          \
5542 _(tcp_configure_src_addresses_reply)                    \
5543 _(dns_enable_disable_reply)                             \
5544 _(dns_name_server_add_del_reply)                        \
5545 _(session_rule_add_del_reply)                           \
5546 _(ip_container_proxy_add_del_reply)                     \
5547 _(output_acl_set_interface_reply)                       \
5548 _(qos_record_enable_disable_reply)
5549
5550 #define _(n)                                    \
5551     static void vl_api_##n##_t_handler          \
5552     (vl_api_##n##_t * mp)                       \
5553     {                                           \
5554         vat_main_t * vam = &vat_main;           \
5555         i32 retval = ntohl(mp->retval);         \
5556         if (vam->async_mode) {                  \
5557             vam->async_errors += (retval < 0);  \
5558         } else {                                \
5559             vam->retval = retval;               \
5560             vam->result_ready = 1;              \
5561         }                                       \
5562     }
5563 foreach_standard_reply_retval_handler;
5564 #undef _
5565
5566 #define _(n)                                    \
5567     static void vl_api_##n##_t_handler_json     \
5568     (vl_api_##n##_t * mp)                       \
5569     {                                           \
5570         vat_main_t * vam = &vat_main;           \
5571         vat_json_node_t node;                   \
5572         vat_json_init_object(&node);            \
5573         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5574         vat_json_print(vam->ofp, &node);        \
5575         vam->retval = ntohl(mp->retval);        \
5576         vam->result_ready = 1;                  \
5577     }
5578 foreach_standard_reply_retval_handler;
5579 #undef _
5580
5581 /*
5582  * Table of message reply handlers, must include boilerplate handlers
5583  * we just generated
5584  */
5585
5586 #define foreach_vpe_api_reply_msg                                       \
5587 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5588 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5589 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5590 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5591 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5592 _(CLI_REPLY, cli_reply)                                                 \
5593 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5594 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5595   sw_interface_add_del_address_reply)                                   \
5596 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5597 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5598 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5599 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5600 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5601 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5602 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5603 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5604   sw_interface_set_l2_xconnect_reply)                                   \
5605 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5606   sw_interface_set_l2_bridge_reply)                                     \
5607 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5608 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5609 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5610 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5611 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5612 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5613 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5614 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5615 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5616 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5617 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5618 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5619 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5620 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5621 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5622 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5623 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5624 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5625 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5626 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5627 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5628 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5629 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5630 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5631 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5632 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5633 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5634 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5635 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5636 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5637 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5638   proxy_arp_intfc_enable_disable_reply)                                 \
5639 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5640 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5641   sw_interface_set_unnumbered_reply)                                    \
5642 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5643 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5644 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5645 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5646 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5647 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5648 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5649 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5650 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5651 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5652 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5653   sw_interface_ip6_enable_disable_reply)                                \
5654 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5655   sw_interface_ip6_set_link_local_address_reply)                        \
5656 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5657 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5658 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5659   sw_interface_ip6nd_ra_prefix_reply)                                   \
5660 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5661   sw_interface_ip6nd_ra_config_reply)                                   \
5662 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5663 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5664 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5665 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5666 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5667 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5668 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5669 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5670 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5671 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5672 classify_set_interface_ip_table_reply)                                  \
5673 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5674   classify_set_interface_l2_tables_reply)                               \
5675 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5676 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5677 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5678 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5679 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5680   l2tpv3_interface_enable_disable_reply)                                \
5681 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5682 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5683 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5684 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5685 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5686 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5687 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5688 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5689 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5690 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5691 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5692 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5693 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5694 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5695 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5696 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5697 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5698 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5699 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5700 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5701 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5702 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5703 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5704 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5705 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5706 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5707 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5708 _(L2_MACS_EVENT, l2_macs_event)                                         \
5709 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5710 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5711 _(IP_DETAILS, ip_details)                                               \
5712 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5713 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5714 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5715 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5716 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5717 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5718 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5719 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5720 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5721 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5722 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5723 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5724 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5725 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5726 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5727 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5728 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5729 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5730 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5731 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5732 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5733 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5734 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5735 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5736 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5737 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5738 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5739 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5740 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5741 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5742 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5743 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5744 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5745 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5746 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5747 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5748 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5749 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5750 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5751 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5752 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5753 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5754 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5755 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5756 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5757 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5758 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5759 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5760   one_map_register_enable_disable_reply)                                \
5761 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5762 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5763 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5764 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5765   one_map_register_fallback_threshold_reply)                            \
5766 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5767   one_rloc_probe_enable_disable_reply)                                  \
5768 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5769 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5770 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5771 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5772 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5773 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5774 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5775 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5776 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5777 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5778 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5779 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5780 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5781 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5782 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5783 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5784   show_one_stats_enable_disable_reply)                                  \
5785 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5786 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5787 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5788 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5789 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5790 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5791 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5792 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5793   one_enable_disable_pitr_mode_reply)                                   \
5794 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5795   one_enable_disable_petr_mode_reply)                                   \
5796 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5797 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5798 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5799 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5800 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5801 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5802 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5803 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5804 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5805 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5806 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5807 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5808   gpe_add_del_native_fwd_rpath_reply)                                   \
5809 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5810   gpe_fwd_entry_path_details)                                           \
5811 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5812 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5813   one_add_del_map_request_itr_rlocs_reply)                              \
5814 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5815   one_get_map_request_itr_rlocs_reply)                                  \
5816 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5817 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5818 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5819 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5820 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5821 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5822   show_one_map_register_state_reply)                                    \
5823 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5824 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5825   show_one_map_register_fallback_threshold_reply)                       \
5826 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5827 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5828 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5829 _(POLICER_DETAILS, policer_details)                                     \
5830 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5831 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5832 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5833 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5834 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5835 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5836 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5837 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5838 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5839 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5840 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5841 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5842 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5843 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5844 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5845 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5846 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5847 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5848 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5849 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5850 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5851 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5852 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5853 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5854 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5855  ip_source_and_port_range_check_add_del_reply)                          \
5856 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5857  ip_source_and_port_range_check_interface_add_del_reply)                \
5858 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5859 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5860 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5861 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5862 _(PUNT_REPLY, punt_reply)                                               \
5863 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5864 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5865 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5866 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5867 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5868 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5869 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5870 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5871 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5872 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5873 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5874 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5875 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5876 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5877 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5878 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5879 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5880 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5881 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5882 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5883 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5884 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5885 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5886
5887 #define foreach_standalone_reply_msg                                    \
5888 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5889 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5890 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5891 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5892 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5893 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5894 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5895
5896 typedef struct
5897 {
5898   u8 *name;
5899   u32 value;
5900 } name_sort_t;
5901
5902 #define STR_VTR_OP_CASE(op)     \
5903     case L2_VTR_ ## op:         \
5904         return "" # op;
5905
5906 static const char *
5907 str_vtr_op (u32 vtr_op)
5908 {
5909   switch (vtr_op)
5910     {
5911       STR_VTR_OP_CASE (DISABLED);
5912       STR_VTR_OP_CASE (PUSH_1);
5913       STR_VTR_OP_CASE (PUSH_2);
5914       STR_VTR_OP_CASE (POP_1);
5915       STR_VTR_OP_CASE (POP_2);
5916       STR_VTR_OP_CASE (TRANSLATE_1_1);
5917       STR_VTR_OP_CASE (TRANSLATE_1_2);
5918       STR_VTR_OP_CASE (TRANSLATE_2_1);
5919       STR_VTR_OP_CASE (TRANSLATE_2_2);
5920     }
5921
5922   return "UNKNOWN";
5923 }
5924
5925 static int
5926 dump_sub_interface_table (vat_main_t * vam)
5927 {
5928   const sw_interface_subif_t *sub = NULL;
5929
5930   if (vam->json_output)
5931     {
5932       clib_warning
5933         ("JSON output supported only for VPE API calls and dump_stats_table");
5934       return -99;
5935     }
5936
5937   print (vam->ofp,
5938          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5939          "Interface", "sw_if_index",
5940          "sub id", "dot1ad", "tags", "outer id",
5941          "inner id", "exact", "default", "outer any", "inner any");
5942
5943   vec_foreach (sub, vam->sw_if_subif_table)
5944   {
5945     print (vam->ofp,
5946            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5947            sub->interface_name,
5948            sub->sw_if_index,
5949            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5950            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5951            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5952            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5953     if (sub->vtr_op != L2_VTR_DISABLED)
5954       {
5955         print (vam->ofp,
5956                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5957                "tag1: %d tag2: %d ]",
5958                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5959                sub->vtr_tag1, sub->vtr_tag2);
5960       }
5961   }
5962
5963   return 0;
5964 }
5965
5966 static int
5967 name_sort_cmp (void *a1, void *a2)
5968 {
5969   name_sort_t *n1 = a1;
5970   name_sort_t *n2 = a2;
5971
5972   return strcmp ((char *) n1->name, (char *) n2->name);
5973 }
5974
5975 static int
5976 dump_interface_table (vat_main_t * vam)
5977 {
5978   hash_pair_t *p;
5979   name_sort_t *nses = 0, *ns;
5980
5981   if (vam->json_output)
5982     {
5983       clib_warning
5984         ("JSON output supported only for VPE API calls and dump_stats_table");
5985       return -99;
5986     }
5987
5988   /* *INDENT-OFF* */
5989   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5990   ({
5991     vec_add2 (nses, ns, 1);
5992     ns->name = (u8 *)(p->key);
5993     ns->value = (u32) p->value[0];
5994   }));
5995   /* *INDENT-ON* */
5996
5997   vec_sort_with_function (nses, name_sort_cmp);
5998
5999   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6000   vec_foreach (ns, nses)
6001   {
6002     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6003   }
6004   vec_free (nses);
6005   return 0;
6006 }
6007
6008 static int
6009 dump_ip_table (vat_main_t * vam, int is_ipv6)
6010 {
6011   const ip_details_t *det = NULL;
6012   const ip_address_details_t *address = NULL;
6013   u32 i = ~0;
6014
6015   print (vam->ofp, "%-12s", "sw_if_index");
6016
6017   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6018   {
6019     i++;
6020     if (!det->present)
6021       {
6022         continue;
6023       }
6024     print (vam->ofp, "%-12d", i);
6025     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6026     if (!det->addr)
6027       {
6028         continue;
6029       }
6030     vec_foreach (address, det->addr)
6031     {
6032       print (vam->ofp,
6033              "            %-30U%-13d",
6034              is_ipv6 ? format_ip6_address : format_ip4_address,
6035              address->ip, address->prefix_length);
6036     }
6037   }
6038
6039   return 0;
6040 }
6041
6042 static int
6043 dump_ipv4_table (vat_main_t * vam)
6044 {
6045   if (vam->json_output)
6046     {
6047       clib_warning
6048         ("JSON output supported only for VPE API calls and dump_stats_table");
6049       return -99;
6050     }
6051
6052   return dump_ip_table (vam, 0);
6053 }
6054
6055 static int
6056 dump_ipv6_table (vat_main_t * vam)
6057 {
6058   if (vam->json_output)
6059     {
6060       clib_warning
6061         ("JSON output supported only for VPE API calls and dump_stats_table");
6062       return -99;
6063     }
6064
6065   return dump_ip_table (vam, 1);
6066 }
6067
6068 static char *
6069 counter_type_to_str (u8 counter_type, u8 is_combined)
6070 {
6071   if (!is_combined)
6072     {
6073       switch (counter_type)
6074         {
6075         case VNET_INTERFACE_COUNTER_DROP:
6076           return "drop";
6077         case VNET_INTERFACE_COUNTER_PUNT:
6078           return "punt";
6079         case VNET_INTERFACE_COUNTER_IP4:
6080           return "ip4";
6081         case VNET_INTERFACE_COUNTER_IP6:
6082           return "ip6";
6083         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6084           return "rx-no-buf";
6085         case VNET_INTERFACE_COUNTER_RX_MISS:
6086           return "rx-miss";
6087         case VNET_INTERFACE_COUNTER_RX_ERROR:
6088           return "rx-error";
6089         case VNET_INTERFACE_COUNTER_TX_ERROR:
6090           return "tx-error";
6091         default:
6092           return "INVALID-COUNTER-TYPE";
6093         }
6094     }
6095   else
6096     {
6097       switch (counter_type)
6098         {
6099         case VNET_INTERFACE_COUNTER_RX:
6100           return "rx";
6101         case VNET_INTERFACE_COUNTER_TX:
6102           return "tx";
6103         default:
6104           return "INVALID-COUNTER-TYPE";
6105         }
6106     }
6107 }
6108
6109 static int
6110 dump_stats_table (vat_main_t * vam)
6111 {
6112   vat_json_node_t node;
6113   vat_json_node_t *msg_array;
6114   vat_json_node_t *msg;
6115   vat_json_node_t *counter_array;
6116   vat_json_node_t *counter;
6117   interface_counter_t c;
6118   u64 packets;
6119   ip4_fib_counter_t *c4;
6120   ip6_fib_counter_t *c6;
6121   ip4_nbr_counter_t *n4;
6122   ip6_nbr_counter_t *n6;
6123   int i, j;
6124
6125   if (!vam->json_output)
6126     {
6127       clib_warning ("dump_stats_table supported only in JSON format");
6128       return -99;
6129     }
6130
6131   vat_json_init_object (&node);
6132
6133   /* interface counters */
6134   msg_array = vat_json_object_add (&node, "interface_counters");
6135   vat_json_init_array (msg_array);
6136   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6137     {
6138       msg = vat_json_array_add (msg_array);
6139       vat_json_init_object (msg);
6140       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6141                                        (u8 *) counter_type_to_str (i, 0));
6142       vat_json_object_add_int (msg, "is_combined", 0);
6143       counter_array = vat_json_object_add (msg, "data");
6144       vat_json_init_array (counter_array);
6145       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6146         {
6147           packets = vam->simple_interface_counters[i][j];
6148           vat_json_array_add_uint (counter_array, packets);
6149         }
6150     }
6151   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6152     {
6153       msg = vat_json_array_add (msg_array);
6154       vat_json_init_object (msg);
6155       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6156                                        (u8 *) counter_type_to_str (i, 1));
6157       vat_json_object_add_int (msg, "is_combined", 1);
6158       counter_array = vat_json_object_add (msg, "data");
6159       vat_json_init_array (counter_array);
6160       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6161         {
6162           c = vam->combined_interface_counters[i][j];
6163           counter = vat_json_array_add (counter_array);
6164           vat_json_init_object (counter);
6165           vat_json_object_add_uint (counter, "packets", c.packets);
6166           vat_json_object_add_uint (counter, "bytes", c.bytes);
6167         }
6168     }
6169
6170   /* ip4 fib counters */
6171   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6172   vat_json_init_array (msg_array);
6173   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6174     {
6175       msg = vat_json_array_add (msg_array);
6176       vat_json_init_object (msg);
6177       vat_json_object_add_uint (msg, "vrf_id",
6178                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6179       counter_array = vat_json_object_add (msg, "c");
6180       vat_json_init_array (counter_array);
6181       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6182         {
6183           counter = vat_json_array_add (counter_array);
6184           vat_json_init_object (counter);
6185           c4 = &vam->ip4_fib_counters[i][j];
6186           vat_json_object_add_ip4 (counter, "address", c4->address);
6187           vat_json_object_add_uint (counter, "address_length",
6188                                     c4->address_length);
6189           vat_json_object_add_uint (counter, "packets", c4->packets);
6190           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6191         }
6192     }
6193
6194   /* ip6 fib counters */
6195   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6196   vat_json_init_array (msg_array);
6197   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6198     {
6199       msg = vat_json_array_add (msg_array);
6200       vat_json_init_object (msg);
6201       vat_json_object_add_uint (msg, "vrf_id",
6202                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6203       counter_array = vat_json_object_add (msg, "c");
6204       vat_json_init_array (counter_array);
6205       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6206         {
6207           counter = vat_json_array_add (counter_array);
6208           vat_json_init_object (counter);
6209           c6 = &vam->ip6_fib_counters[i][j];
6210           vat_json_object_add_ip6 (counter, "address", c6->address);
6211           vat_json_object_add_uint (counter, "address_length",
6212                                     c6->address_length);
6213           vat_json_object_add_uint (counter, "packets", c6->packets);
6214           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6215         }
6216     }
6217
6218   /* ip4 nbr counters */
6219   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6220   vat_json_init_array (msg_array);
6221   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6222     {
6223       msg = vat_json_array_add (msg_array);
6224       vat_json_init_object (msg);
6225       vat_json_object_add_uint (msg, "sw_if_index", i);
6226       counter_array = vat_json_object_add (msg, "c");
6227       vat_json_init_array (counter_array);
6228       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6229         {
6230           counter = vat_json_array_add (counter_array);
6231           vat_json_init_object (counter);
6232           n4 = &vam->ip4_nbr_counters[i][j];
6233           vat_json_object_add_ip4 (counter, "address", n4->address);
6234           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6235           vat_json_object_add_uint (counter, "packets", n4->packets);
6236           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6237         }
6238     }
6239
6240   /* ip6 nbr counters */
6241   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6242   vat_json_init_array (msg_array);
6243   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6244     {
6245       msg = vat_json_array_add (msg_array);
6246       vat_json_init_object (msg);
6247       vat_json_object_add_uint (msg, "sw_if_index", i);
6248       counter_array = vat_json_object_add (msg, "c");
6249       vat_json_init_array (counter_array);
6250       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6251         {
6252           counter = vat_json_array_add (counter_array);
6253           vat_json_init_object (counter);
6254           n6 = &vam->ip6_nbr_counters[i][j];
6255           vat_json_object_add_ip6 (counter, "address", n6->address);
6256           vat_json_object_add_uint (counter, "packets", n6->packets);
6257           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6258         }
6259     }
6260
6261   vat_json_print (vam->ofp, &node);
6262   vat_json_free (&node);
6263
6264   return 0;
6265 }
6266
6267 /*
6268  * Pass CLI buffers directly in the CLI_INBAND API message,
6269  * instead of an additional shared memory area.
6270  */
6271 static int
6272 exec_inband (vat_main_t * vam)
6273 {
6274   vl_api_cli_inband_t *mp;
6275   unformat_input_t *i = vam->input;
6276   int ret;
6277
6278   if (vec_len (i->buffer) == 0)
6279     return -1;
6280
6281   if (vam->exec_mode == 0 && unformat (i, "mode"))
6282     {
6283       vam->exec_mode = 1;
6284       return 0;
6285     }
6286   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6287     {
6288       vam->exec_mode = 0;
6289       return 0;
6290     }
6291
6292   /*
6293    * In order for the CLI command to work, it
6294    * must be a vector ending in \n, not a C-string ending
6295    * in \n\0.
6296    */
6297   u32 len = vec_len (vam->input->buffer);
6298   M2 (CLI_INBAND, mp, len);
6299   clib_memcpy (mp->cmd, vam->input->buffer, len);
6300   mp->length = htonl (len);
6301
6302   S (mp);
6303   W (ret);
6304   /* json responses may or may not include a useful reply... */
6305   if (vec_len (vam->cmd_reply))
6306     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6307   return ret;
6308 }
6309
6310 int
6311 exec (vat_main_t * vam)
6312 {
6313   return exec_inband (vam);
6314 }
6315
6316 static int
6317 api_create_loopback (vat_main_t * vam)
6318 {
6319   unformat_input_t *i = vam->input;
6320   vl_api_create_loopback_t *mp;
6321   vl_api_create_loopback_instance_t *mp_lbi;
6322   u8 mac_address[6];
6323   u8 mac_set = 0;
6324   u8 is_specified = 0;
6325   u32 user_instance = 0;
6326   int ret;
6327
6328   memset (mac_address, 0, sizeof (mac_address));
6329
6330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6331     {
6332       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6333         mac_set = 1;
6334       if (unformat (i, "instance %d", &user_instance))
6335         is_specified = 1;
6336       else
6337         break;
6338     }
6339
6340   if (is_specified)
6341     {
6342       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6343       mp_lbi->is_specified = is_specified;
6344       if (is_specified)
6345         mp_lbi->user_instance = htonl (user_instance);
6346       if (mac_set)
6347         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6348       S (mp_lbi);
6349     }
6350   else
6351     {
6352       /* Construct the API message */
6353       M (CREATE_LOOPBACK, mp);
6354       if (mac_set)
6355         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6356       S (mp);
6357     }
6358
6359   W (ret);
6360   return ret;
6361 }
6362
6363 static int
6364 api_delete_loopback (vat_main_t * vam)
6365 {
6366   unformat_input_t *i = vam->input;
6367   vl_api_delete_loopback_t *mp;
6368   u32 sw_if_index = ~0;
6369   int ret;
6370
6371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6372     {
6373       if (unformat (i, "sw_if_index %d", &sw_if_index))
6374         ;
6375       else
6376         break;
6377     }
6378
6379   if (sw_if_index == ~0)
6380     {
6381       errmsg ("missing sw_if_index");
6382       return -99;
6383     }
6384
6385   /* Construct the API message */
6386   M (DELETE_LOOPBACK, mp);
6387   mp->sw_if_index = ntohl (sw_if_index);
6388
6389   S (mp);
6390   W (ret);
6391   return ret;
6392 }
6393
6394 static int
6395 api_want_stats (vat_main_t * vam)
6396 {
6397   unformat_input_t *i = vam->input;
6398   vl_api_want_stats_t *mp;
6399   int enable = -1;
6400   int ret;
6401
6402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6403     {
6404       if (unformat (i, "enable"))
6405         enable = 1;
6406       else if (unformat (i, "disable"))
6407         enable = 0;
6408       else
6409         break;
6410     }
6411
6412   if (enable == -1)
6413     {
6414       errmsg ("missing enable|disable");
6415       return -99;
6416     }
6417
6418   M (WANT_STATS, mp);
6419   mp->enable_disable = enable;
6420
6421   S (mp);
6422   W (ret);
6423   return ret;
6424 }
6425
6426 static int
6427 api_want_interface_events (vat_main_t * vam)
6428 {
6429   unformat_input_t *i = vam->input;
6430   vl_api_want_interface_events_t *mp;
6431   int enable = -1;
6432   int ret;
6433
6434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6435     {
6436       if (unformat (i, "enable"))
6437         enable = 1;
6438       else if (unformat (i, "disable"))
6439         enable = 0;
6440       else
6441         break;
6442     }
6443
6444   if (enable == -1)
6445     {
6446       errmsg ("missing enable|disable");
6447       return -99;
6448     }
6449
6450   M (WANT_INTERFACE_EVENTS, mp);
6451   mp->enable_disable = enable;
6452
6453   vam->interface_event_display = enable;
6454
6455   S (mp);
6456   W (ret);
6457   return ret;
6458 }
6459
6460
6461 /* Note: non-static, called once to set up the initial intfc table */
6462 int
6463 api_sw_interface_dump (vat_main_t * vam)
6464 {
6465   vl_api_sw_interface_dump_t *mp;
6466   vl_api_control_ping_t *mp_ping;
6467   hash_pair_t *p;
6468   name_sort_t *nses = 0, *ns;
6469   sw_interface_subif_t *sub = NULL;
6470   int ret;
6471
6472   /* Toss the old name table */
6473   /* *INDENT-OFF* */
6474   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6475   ({
6476     vec_add2 (nses, ns, 1);
6477     ns->name = (u8 *)(p->key);
6478     ns->value = (u32) p->value[0];
6479   }));
6480   /* *INDENT-ON* */
6481
6482   hash_free (vam->sw_if_index_by_interface_name);
6483
6484   vec_foreach (ns, nses) vec_free (ns->name);
6485
6486   vec_free (nses);
6487
6488   vec_foreach (sub, vam->sw_if_subif_table)
6489   {
6490     vec_free (sub->interface_name);
6491   }
6492   vec_free (vam->sw_if_subif_table);
6493
6494   /* recreate the interface name hash table */
6495   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6496
6497   /*
6498    * Ask for all interface names. Otherwise, the epic catalog of
6499    * name filters becomes ridiculously long, and vat ends up needing
6500    * to be taught about new interface types.
6501    */
6502   M (SW_INTERFACE_DUMP, mp);
6503   S (mp);
6504
6505   /* Use a control ping for synchronization */
6506   MPING (CONTROL_PING, mp_ping);
6507   S (mp_ping);
6508
6509   W (ret);
6510   return ret;
6511 }
6512
6513 static int
6514 api_sw_interface_set_flags (vat_main_t * vam)
6515 {
6516   unformat_input_t *i = vam->input;
6517   vl_api_sw_interface_set_flags_t *mp;
6518   u32 sw_if_index;
6519   u8 sw_if_index_set = 0;
6520   u8 admin_up = 0;
6521   int ret;
6522
6523   /* Parse args required to build the message */
6524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6525     {
6526       if (unformat (i, "admin-up"))
6527         admin_up = 1;
6528       else if (unformat (i, "admin-down"))
6529         admin_up = 0;
6530       else
6531         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6532         sw_if_index_set = 1;
6533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6534         sw_if_index_set = 1;
6535       else
6536         break;
6537     }
6538
6539   if (sw_if_index_set == 0)
6540     {
6541       errmsg ("missing interface name or sw_if_index");
6542       return -99;
6543     }
6544
6545   /* Construct the API message */
6546   M (SW_INTERFACE_SET_FLAGS, mp);
6547   mp->sw_if_index = ntohl (sw_if_index);
6548   mp->admin_up_down = admin_up;
6549
6550   /* send it... */
6551   S (mp);
6552
6553   /* Wait for a reply, return the good/bad news... */
6554   W (ret);
6555   return ret;
6556 }
6557
6558 static int
6559 api_sw_interface_set_rx_mode (vat_main_t * vam)
6560 {
6561   unformat_input_t *i = vam->input;
6562   vl_api_sw_interface_set_rx_mode_t *mp;
6563   u32 sw_if_index;
6564   u8 sw_if_index_set = 0;
6565   int ret;
6566   u8 queue_id_valid = 0;
6567   u32 queue_id;
6568   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6569
6570   /* Parse args required to build the message */
6571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6572     {
6573       if (unformat (i, "queue %d", &queue_id))
6574         queue_id_valid = 1;
6575       else if (unformat (i, "polling"))
6576         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6577       else if (unformat (i, "interrupt"))
6578         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6579       else if (unformat (i, "adaptive"))
6580         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6581       else
6582         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6583         sw_if_index_set = 1;
6584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6585         sw_if_index_set = 1;
6586       else
6587         break;
6588     }
6589
6590   if (sw_if_index_set == 0)
6591     {
6592       errmsg ("missing interface name or sw_if_index");
6593       return -99;
6594     }
6595   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6596     {
6597       errmsg ("missing rx-mode");
6598       return -99;
6599     }
6600
6601   /* Construct the API message */
6602   M (SW_INTERFACE_SET_RX_MODE, mp);
6603   mp->sw_if_index = ntohl (sw_if_index);
6604   mp->mode = mode;
6605   mp->queue_id_valid = queue_id_valid;
6606   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6607
6608   /* send it... */
6609   S (mp);
6610
6611   /* Wait for a reply, return the good/bad news... */
6612   W (ret);
6613   return ret;
6614 }
6615
6616 static int
6617 api_sw_interface_clear_stats (vat_main_t * vam)
6618 {
6619   unformat_input_t *i = vam->input;
6620   vl_api_sw_interface_clear_stats_t *mp;
6621   u32 sw_if_index;
6622   u8 sw_if_index_set = 0;
6623   int ret;
6624
6625   /* Parse args required to build the message */
6626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6627     {
6628       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6629         sw_if_index_set = 1;
6630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6631         sw_if_index_set = 1;
6632       else
6633         break;
6634     }
6635
6636   /* Construct the API message */
6637   M (SW_INTERFACE_CLEAR_STATS, mp);
6638
6639   if (sw_if_index_set == 1)
6640     mp->sw_if_index = ntohl (sw_if_index);
6641   else
6642     mp->sw_if_index = ~0;
6643
6644   /* send it... */
6645   S (mp);
6646
6647   /* Wait for a reply, return the good/bad news... */
6648   W (ret);
6649   return ret;
6650 }
6651
6652 static int
6653 api_sw_interface_add_del_address (vat_main_t * vam)
6654 {
6655   unformat_input_t *i = vam->input;
6656   vl_api_sw_interface_add_del_address_t *mp;
6657   u32 sw_if_index;
6658   u8 sw_if_index_set = 0;
6659   u8 is_add = 1, del_all = 0;
6660   u32 address_length = 0;
6661   u8 v4_address_set = 0;
6662   u8 v6_address_set = 0;
6663   ip4_address_t v4address;
6664   ip6_address_t v6address;
6665   int ret;
6666
6667   /* Parse args required to build the message */
6668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6669     {
6670       if (unformat (i, "del-all"))
6671         del_all = 1;
6672       else if (unformat (i, "del"))
6673         is_add = 0;
6674       else
6675         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6676         sw_if_index_set = 1;
6677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6678         sw_if_index_set = 1;
6679       else if (unformat (i, "%U/%d",
6680                          unformat_ip4_address, &v4address, &address_length))
6681         v4_address_set = 1;
6682       else if (unformat (i, "%U/%d",
6683                          unformat_ip6_address, &v6address, &address_length))
6684         v6_address_set = 1;
6685       else
6686         break;
6687     }
6688
6689   if (sw_if_index_set == 0)
6690     {
6691       errmsg ("missing interface name or sw_if_index");
6692       return -99;
6693     }
6694   if (v4_address_set && v6_address_set)
6695     {
6696       errmsg ("both v4 and v6 addresses set");
6697       return -99;
6698     }
6699   if (!v4_address_set && !v6_address_set && !del_all)
6700     {
6701       errmsg ("no addresses set");
6702       return -99;
6703     }
6704
6705   /* Construct the API message */
6706   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6707
6708   mp->sw_if_index = ntohl (sw_if_index);
6709   mp->is_add = is_add;
6710   mp->del_all = del_all;
6711   if (v6_address_set)
6712     {
6713       mp->is_ipv6 = 1;
6714       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6715     }
6716   else
6717     {
6718       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6719     }
6720   mp->address_length = address_length;
6721
6722   /* send it... */
6723   S (mp);
6724
6725   /* Wait for a reply, return good/bad news  */
6726   W (ret);
6727   return ret;
6728 }
6729
6730 static int
6731 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6732 {
6733   unformat_input_t *i = vam->input;
6734   vl_api_sw_interface_set_mpls_enable_t *mp;
6735   u32 sw_if_index;
6736   u8 sw_if_index_set = 0;
6737   u8 enable = 1;
6738   int ret;
6739
6740   /* Parse args required to build the message */
6741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6742     {
6743       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6744         sw_if_index_set = 1;
6745       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "disable"))
6748         enable = 0;
6749       else if (unformat (i, "dis"))
6750         enable = 0;
6751       else
6752         break;
6753     }
6754
6755   if (sw_if_index_set == 0)
6756     {
6757       errmsg ("missing interface name or sw_if_index");
6758       return -99;
6759     }
6760
6761   /* Construct the API message */
6762   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6763
6764   mp->sw_if_index = ntohl (sw_if_index);
6765   mp->enable = enable;
6766
6767   /* send it... */
6768   S (mp);
6769
6770   /* Wait for a reply... */
6771   W (ret);
6772   return ret;
6773 }
6774
6775 static int
6776 api_sw_interface_set_table (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_sw_interface_set_table_t *mp;
6780   u32 sw_if_index, vrf_id = 0;
6781   u8 sw_if_index_set = 0;
6782   u8 is_ipv6 = 0;
6783   int ret;
6784
6785   /* Parse args required to build the message */
6786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6787     {
6788       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6789         sw_if_index_set = 1;
6790       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6791         sw_if_index_set = 1;
6792       else if (unformat (i, "vrf %d", &vrf_id))
6793         ;
6794       else if (unformat (i, "ipv6"))
6795         is_ipv6 = 1;
6796       else
6797         break;
6798     }
6799
6800   if (sw_if_index_set == 0)
6801     {
6802       errmsg ("missing interface name or sw_if_index");
6803       return -99;
6804     }
6805
6806   /* Construct the API message */
6807   M (SW_INTERFACE_SET_TABLE, mp);
6808
6809   mp->sw_if_index = ntohl (sw_if_index);
6810   mp->is_ipv6 = is_ipv6;
6811   mp->vrf_id = ntohl (vrf_id);
6812
6813   /* send it... */
6814   S (mp);
6815
6816   /* Wait for a reply... */
6817   W (ret);
6818   return ret;
6819 }
6820
6821 static void vl_api_sw_interface_get_table_reply_t_handler
6822   (vl_api_sw_interface_get_table_reply_t * mp)
6823 {
6824   vat_main_t *vam = &vat_main;
6825
6826   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6827
6828   vam->retval = ntohl (mp->retval);
6829   vam->result_ready = 1;
6830
6831 }
6832
6833 static void vl_api_sw_interface_get_table_reply_t_handler_json
6834   (vl_api_sw_interface_get_table_reply_t * mp)
6835 {
6836   vat_main_t *vam = &vat_main;
6837   vat_json_node_t node;
6838
6839   vat_json_init_object (&node);
6840   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6841   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6842
6843   vat_json_print (vam->ofp, &node);
6844   vat_json_free (&node);
6845
6846   vam->retval = ntohl (mp->retval);
6847   vam->result_ready = 1;
6848 }
6849
6850 static int
6851 api_sw_interface_get_table (vat_main_t * vam)
6852 {
6853   unformat_input_t *i = vam->input;
6854   vl_api_sw_interface_get_table_t *mp;
6855   u32 sw_if_index;
6856   u8 sw_if_index_set = 0;
6857   u8 is_ipv6 = 0;
6858   int ret;
6859
6860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6861     {
6862       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6863         sw_if_index_set = 1;
6864       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6865         sw_if_index_set = 1;
6866       else if (unformat (i, "ipv6"))
6867         is_ipv6 = 1;
6868       else
6869         break;
6870     }
6871
6872   if (sw_if_index_set == 0)
6873     {
6874       errmsg ("missing interface name or sw_if_index");
6875       return -99;
6876     }
6877
6878   M (SW_INTERFACE_GET_TABLE, mp);
6879   mp->sw_if_index = htonl (sw_if_index);
6880   mp->is_ipv6 = is_ipv6;
6881
6882   S (mp);
6883   W (ret);
6884   return ret;
6885 }
6886
6887 static int
6888 api_sw_interface_set_vpath (vat_main_t * vam)
6889 {
6890   unformat_input_t *i = vam->input;
6891   vl_api_sw_interface_set_vpath_t *mp;
6892   u32 sw_if_index = 0;
6893   u8 sw_if_index_set = 0;
6894   u8 is_enable = 0;
6895   int ret;
6896
6897   /* Parse args required to build the message */
6898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6899     {
6900       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6901         sw_if_index_set = 1;
6902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6903         sw_if_index_set = 1;
6904       else if (unformat (i, "enable"))
6905         is_enable = 1;
6906       else if (unformat (i, "disable"))
6907         is_enable = 0;
6908       else
6909         break;
6910     }
6911
6912   if (sw_if_index_set == 0)
6913     {
6914       errmsg ("missing interface name or sw_if_index");
6915       return -99;
6916     }
6917
6918   /* Construct the API message */
6919   M (SW_INTERFACE_SET_VPATH, mp);
6920
6921   mp->sw_if_index = ntohl (sw_if_index);
6922   mp->enable = is_enable;
6923
6924   /* send it... */
6925   S (mp);
6926
6927   /* Wait for a reply... */
6928   W (ret);
6929   return ret;
6930 }
6931
6932 static int
6933 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6934 {
6935   unformat_input_t *i = vam->input;
6936   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6937   u32 sw_if_index = 0;
6938   u8 sw_if_index_set = 0;
6939   u8 is_enable = 1;
6940   u8 is_ipv6 = 0;
6941   int ret;
6942
6943   /* Parse args required to build the message */
6944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6945     {
6946       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6947         sw_if_index_set = 1;
6948       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6949         sw_if_index_set = 1;
6950       else if (unformat (i, "enable"))
6951         is_enable = 1;
6952       else if (unformat (i, "disable"))
6953         is_enable = 0;
6954       else if (unformat (i, "ip4"))
6955         is_ipv6 = 0;
6956       else if (unformat (i, "ip6"))
6957         is_ipv6 = 1;
6958       else
6959         break;
6960     }
6961
6962   if (sw_if_index_set == 0)
6963     {
6964       errmsg ("missing interface name or sw_if_index");
6965       return -99;
6966     }
6967
6968   /* Construct the API message */
6969   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6970
6971   mp->sw_if_index = ntohl (sw_if_index);
6972   mp->enable = is_enable;
6973   mp->is_ipv6 = is_ipv6;
6974
6975   /* send it... */
6976   S (mp);
6977
6978   /* Wait for a reply... */
6979   W (ret);
6980   return ret;
6981 }
6982
6983 static int
6984 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6985 {
6986   unformat_input_t *i = vam->input;
6987   vl_api_sw_interface_set_geneve_bypass_t *mp;
6988   u32 sw_if_index = 0;
6989   u8 sw_if_index_set = 0;
6990   u8 is_enable = 1;
6991   u8 is_ipv6 = 0;
6992   int ret;
6993
6994   /* Parse args required to build the message */
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6998         sw_if_index_set = 1;
6999       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7000         sw_if_index_set = 1;
7001       else if (unformat (i, "enable"))
7002         is_enable = 1;
7003       else if (unformat (i, "disable"))
7004         is_enable = 0;
7005       else if (unformat (i, "ip4"))
7006         is_ipv6 = 0;
7007       else if (unformat (i, "ip6"))
7008         is_ipv6 = 1;
7009       else
7010         break;
7011     }
7012
7013   if (sw_if_index_set == 0)
7014     {
7015       errmsg ("missing interface name or sw_if_index");
7016       return -99;
7017     }
7018
7019   /* Construct the API message */
7020   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7021
7022   mp->sw_if_index = ntohl (sw_if_index);
7023   mp->enable = is_enable;
7024   mp->is_ipv6 = is_ipv6;
7025
7026   /* send it... */
7027   S (mp);
7028
7029   /* Wait for a reply... */
7030   W (ret);
7031   return ret;
7032 }
7033
7034 static int
7035 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7036 {
7037   unformat_input_t *i = vam->input;
7038   vl_api_sw_interface_set_l2_xconnect_t *mp;
7039   u32 rx_sw_if_index;
7040   u8 rx_sw_if_index_set = 0;
7041   u32 tx_sw_if_index;
7042   u8 tx_sw_if_index_set = 0;
7043   u8 enable = 1;
7044   int ret;
7045
7046   /* Parse args required to build the message */
7047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7048     {
7049       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7050         rx_sw_if_index_set = 1;
7051       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7052         tx_sw_if_index_set = 1;
7053       else if (unformat (i, "rx"))
7054         {
7055           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7056             {
7057               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7058                             &rx_sw_if_index))
7059                 rx_sw_if_index_set = 1;
7060             }
7061           else
7062             break;
7063         }
7064       else if (unformat (i, "tx"))
7065         {
7066           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7067             {
7068               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7069                             &tx_sw_if_index))
7070                 tx_sw_if_index_set = 1;
7071             }
7072           else
7073             break;
7074         }
7075       else if (unformat (i, "enable"))
7076         enable = 1;
7077       else if (unformat (i, "disable"))
7078         enable = 0;
7079       else
7080         break;
7081     }
7082
7083   if (rx_sw_if_index_set == 0)
7084     {
7085       errmsg ("missing rx interface name or rx_sw_if_index");
7086       return -99;
7087     }
7088
7089   if (enable && (tx_sw_if_index_set == 0))
7090     {
7091       errmsg ("missing tx interface name or tx_sw_if_index");
7092       return -99;
7093     }
7094
7095   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7096
7097   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7098   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7099   mp->enable = enable;
7100
7101   S (mp);
7102   W (ret);
7103   return ret;
7104 }
7105
7106 static int
7107 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7108 {
7109   unformat_input_t *i = vam->input;
7110   vl_api_sw_interface_set_l2_bridge_t *mp;
7111   u32 rx_sw_if_index;
7112   u8 rx_sw_if_index_set = 0;
7113   u32 bd_id;
7114   u8 bd_id_set = 0;
7115   u8 bvi = 0;
7116   u32 shg = 0;
7117   u8 enable = 1;
7118   int ret;
7119
7120   /* Parse args required to build the message */
7121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7122     {
7123       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7124         rx_sw_if_index_set = 1;
7125       else if (unformat (i, "bd_id %d", &bd_id))
7126         bd_id_set = 1;
7127       else
7128         if (unformat
7129             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7130         rx_sw_if_index_set = 1;
7131       else if (unformat (i, "shg %d", &shg))
7132         ;
7133       else if (unformat (i, "bvi"))
7134         bvi = 1;
7135       else if (unformat (i, "enable"))
7136         enable = 1;
7137       else if (unformat (i, "disable"))
7138         enable = 0;
7139       else
7140         break;
7141     }
7142
7143   if (rx_sw_if_index_set == 0)
7144     {
7145       errmsg ("missing rx interface name or sw_if_index");
7146       return -99;
7147     }
7148
7149   if (enable && (bd_id_set == 0))
7150     {
7151       errmsg ("missing bridge domain");
7152       return -99;
7153     }
7154
7155   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7156
7157   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7158   mp->bd_id = ntohl (bd_id);
7159   mp->shg = (u8) shg;
7160   mp->bvi = bvi;
7161   mp->enable = enable;
7162
7163   S (mp);
7164   W (ret);
7165   return ret;
7166 }
7167
7168 static int
7169 api_bridge_domain_dump (vat_main_t * vam)
7170 {
7171   unformat_input_t *i = vam->input;
7172   vl_api_bridge_domain_dump_t *mp;
7173   vl_api_control_ping_t *mp_ping;
7174   u32 bd_id = ~0;
7175   int ret;
7176
7177   /* Parse args required to build the message */
7178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7179     {
7180       if (unformat (i, "bd_id %d", &bd_id))
7181         ;
7182       else
7183         break;
7184     }
7185
7186   M (BRIDGE_DOMAIN_DUMP, mp);
7187   mp->bd_id = ntohl (bd_id);
7188   S (mp);
7189
7190   /* Use a control ping for synchronization */
7191   MPING (CONTROL_PING, mp_ping);
7192   S (mp_ping);
7193
7194   W (ret);
7195   return ret;
7196 }
7197
7198 static int
7199 api_bridge_domain_add_del (vat_main_t * vam)
7200 {
7201   unformat_input_t *i = vam->input;
7202   vl_api_bridge_domain_add_del_t *mp;
7203   u32 bd_id = ~0;
7204   u8 is_add = 1;
7205   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7206   u8 *bd_tag = NULL;
7207   u32 mac_age = 0;
7208   int ret;
7209
7210   /* Parse args required to build the message */
7211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7212     {
7213       if (unformat (i, "bd_id %d", &bd_id))
7214         ;
7215       else if (unformat (i, "flood %d", &flood))
7216         ;
7217       else if (unformat (i, "uu-flood %d", &uu_flood))
7218         ;
7219       else if (unformat (i, "forward %d", &forward))
7220         ;
7221       else if (unformat (i, "learn %d", &learn))
7222         ;
7223       else if (unformat (i, "arp-term %d", &arp_term))
7224         ;
7225       else if (unformat (i, "mac-age %d", &mac_age))
7226         ;
7227       else if (unformat (i, "bd-tag %s", &bd_tag))
7228         ;
7229       else if (unformat (i, "del"))
7230         {
7231           is_add = 0;
7232           flood = uu_flood = forward = learn = 0;
7233         }
7234       else
7235         break;
7236     }
7237
7238   if (bd_id == ~0)
7239     {
7240       errmsg ("missing bridge domain");
7241       ret = -99;
7242       goto done;
7243     }
7244
7245   if (mac_age > 255)
7246     {
7247       errmsg ("mac age must be less than 256 ");
7248       ret = -99;
7249       goto done;
7250     }
7251
7252   if ((bd_tag) && (vec_len (bd_tag) > 63))
7253     {
7254       errmsg ("bd-tag cannot be longer than 63");
7255       ret = -99;
7256       goto done;
7257     }
7258
7259   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7260
7261   mp->bd_id = ntohl (bd_id);
7262   mp->flood = flood;
7263   mp->uu_flood = uu_flood;
7264   mp->forward = forward;
7265   mp->learn = learn;
7266   mp->arp_term = arp_term;
7267   mp->is_add = is_add;
7268   mp->mac_age = (u8) mac_age;
7269   if (bd_tag)
7270     {
7271       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7272       mp->bd_tag[vec_len (bd_tag)] = 0;
7273     }
7274   S (mp);
7275   W (ret);
7276
7277 done:
7278   vec_free (bd_tag);
7279   return ret;
7280 }
7281
7282 static int
7283 api_l2fib_flush_bd (vat_main_t * vam)
7284 {
7285   unformat_input_t *i = vam->input;
7286   vl_api_l2fib_flush_bd_t *mp;
7287   u32 bd_id = ~0;
7288   int ret;
7289
7290   /* Parse args required to build the message */
7291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7292     {
7293       if (unformat (i, "bd_id %d", &bd_id));
7294       else
7295         break;
7296     }
7297
7298   if (bd_id == ~0)
7299     {
7300       errmsg ("missing bridge domain");
7301       return -99;
7302     }
7303
7304   M (L2FIB_FLUSH_BD, mp);
7305
7306   mp->bd_id = htonl (bd_id);
7307
7308   S (mp);
7309   W (ret);
7310   return ret;
7311 }
7312
7313 static int
7314 api_l2fib_flush_int (vat_main_t * vam)
7315 {
7316   unformat_input_t *i = vam->input;
7317   vl_api_l2fib_flush_int_t *mp;
7318   u32 sw_if_index = ~0;
7319   int ret;
7320
7321   /* Parse args required to build the message */
7322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7323     {
7324       if (unformat (i, "sw_if_index %d", &sw_if_index));
7325       else
7326         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7327       else
7328         break;
7329     }
7330
7331   if (sw_if_index == ~0)
7332     {
7333       errmsg ("missing interface name or sw_if_index");
7334       return -99;
7335     }
7336
7337   M (L2FIB_FLUSH_INT, mp);
7338
7339   mp->sw_if_index = ntohl (sw_if_index);
7340
7341   S (mp);
7342   W (ret);
7343   return ret;
7344 }
7345
7346 static int
7347 api_l2fib_add_del (vat_main_t * vam)
7348 {
7349   unformat_input_t *i = vam->input;
7350   vl_api_l2fib_add_del_t *mp;
7351   f64 timeout;
7352   u8 mac[6] = { 0 };
7353   u8 mac_set = 0;
7354   u32 bd_id;
7355   u8 bd_id_set = 0;
7356   u32 sw_if_index = ~0;
7357   u8 sw_if_index_set = 0;
7358   u8 is_add = 1;
7359   u8 static_mac = 0;
7360   u8 filter_mac = 0;
7361   u8 bvi_mac = 0;
7362   int count = 1;
7363   f64 before = 0;
7364   int j;
7365
7366   /* Parse args required to build the message */
7367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7368     {
7369       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7370         mac_set = 1;
7371       else if (unformat (i, "bd_id %d", &bd_id))
7372         bd_id_set = 1;
7373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7374         sw_if_index_set = 1;
7375       else if (unformat (i, "sw_if"))
7376         {
7377           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7378             {
7379               if (unformat
7380                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7381                 sw_if_index_set = 1;
7382             }
7383           else
7384             break;
7385         }
7386       else if (unformat (i, "static"))
7387         static_mac = 1;
7388       else if (unformat (i, "filter"))
7389         {
7390           filter_mac = 1;
7391           static_mac = 1;
7392         }
7393       else if (unformat (i, "bvi"))
7394         {
7395           bvi_mac = 1;
7396           static_mac = 1;
7397         }
7398       else if (unformat (i, "del"))
7399         is_add = 0;
7400       else if (unformat (i, "count %d", &count))
7401         ;
7402       else
7403         break;
7404     }
7405
7406   if (mac_set == 0)
7407     {
7408       errmsg ("missing mac address");
7409       return -99;
7410     }
7411
7412   if (bd_id_set == 0)
7413     {
7414       errmsg ("missing bridge domain");
7415       return -99;
7416     }
7417
7418   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7419     {
7420       errmsg ("missing interface name or sw_if_index");
7421       return -99;
7422     }
7423
7424   if (count > 1)
7425     {
7426       /* Turn on async mode */
7427       vam->async_mode = 1;
7428       vam->async_errors = 0;
7429       before = vat_time_now (vam);
7430     }
7431
7432   for (j = 0; j < count; j++)
7433     {
7434       M (L2FIB_ADD_DEL, mp);
7435
7436       clib_memcpy (mp->mac, mac, 6);
7437       mp->bd_id = ntohl (bd_id);
7438       mp->is_add = is_add;
7439
7440       if (is_add)
7441         {
7442           mp->sw_if_index = ntohl (sw_if_index);
7443           mp->static_mac = static_mac;
7444           mp->filter_mac = filter_mac;
7445           mp->bvi_mac = bvi_mac;
7446         }
7447       increment_mac_address (mac);
7448       /* send it... */
7449       S (mp);
7450     }
7451
7452   if (count > 1)
7453     {
7454       vl_api_control_ping_t *mp_ping;
7455       f64 after;
7456
7457       /* Shut off async mode */
7458       vam->async_mode = 0;
7459
7460       MPING (CONTROL_PING, mp_ping);
7461       S (mp_ping);
7462
7463       timeout = vat_time_now (vam) + 1.0;
7464       while (vat_time_now (vam) < timeout)
7465         if (vam->result_ready == 1)
7466           goto out;
7467       vam->retval = -99;
7468
7469     out:
7470       if (vam->retval == -99)
7471         errmsg ("timeout");
7472
7473       if (vam->async_errors > 0)
7474         {
7475           errmsg ("%d asynchronous errors", vam->async_errors);
7476           vam->retval = -98;
7477         }
7478       vam->async_errors = 0;
7479       after = vat_time_now (vam);
7480
7481       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7482              count, after - before, count / (after - before));
7483     }
7484   else
7485     {
7486       int ret;
7487
7488       /* Wait for a reply... */
7489       W (ret);
7490       return ret;
7491     }
7492   /* Return the good/bad news */
7493   return (vam->retval);
7494 }
7495
7496 static int
7497 api_bridge_domain_set_mac_age (vat_main_t * vam)
7498 {
7499   unformat_input_t *i = vam->input;
7500   vl_api_bridge_domain_set_mac_age_t *mp;
7501   u32 bd_id = ~0;
7502   u32 mac_age = 0;
7503   int ret;
7504
7505   /* Parse args required to build the message */
7506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7507     {
7508       if (unformat (i, "bd_id %d", &bd_id));
7509       else if (unformat (i, "mac-age %d", &mac_age));
7510       else
7511         break;
7512     }
7513
7514   if (bd_id == ~0)
7515     {
7516       errmsg ("missing bridge domain");
7517       return -99;
7518     }
7519
7520   if (mac_age > 255)
7521     {
7522       errmsg ("mac age must be less than 256 ");
7523       return -99;
7524     }
7525
7526   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7527
7528   mp->bd_id = htonl (bd_id);
7529   mp->mac_age = (u8) mac_age;
7530
7531   S (mp);
7532   W (ret);
7533   return ret;
7534 }
7535
7536 static int
7537 api_l2_flags (vat_main_t * vam)
7538 {
7539   unformat_input_t *i = vam->input;
7540   vl_api_l2_flags_t *mp;
7541   u32 sw_if_index;
7542   u32 flags = 0;
7543   u8 sw_if_index_set = 0;
7544   u8 is_set = 0;
7545   int ret;
7546
7547   /* Parse args required to build the message */
7548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7549     {
7550       if (unformat (i, "sw_if_index %d", &sw_if_index))
7551         sw_if_index_set = 1;
7552       else if (unformat (i, "sw_if"))
7553         {
7554           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7555             {
7556               if (unformat
7557                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7558                 sw_if_index_set = 1;
7559             }
7560           else
7561             break;
7562         }
7563       else if (unformat (i, "learn"))
7564         flags |= L2_LEARN;
7565       else if (unformat (i, "forward"))
7566         flags |= L2_FWD;
7567       else if (unformat (i, "flood"))
7568         flags |= L2_FLOOD;
7569       else if (unformat (i, "uu-flood"))
7570         flags |= L2_UU_FLOOD;
7571       else if (unformat (i, "arp-term"))
7572         flags |= L2_ARP_TERM;
7573       else if (unformat (i, "off"))
7574         is_set = 0;
7575       else if (unformat (i, "disable"))
7576         is_set = 0;
7577       else
7578         break;
7579     }
7580
7581   if (sw_if_index_set == 0)
7582     {
7583       errmsg ("missing interface name or sw_if_index");
7584       return -99;
7585     }
7586
7587   M (L2_FLAGS, mp);
7588
7589   mp->sw_if_index = ntohl (sw_if_index);
7590   mp->feature_bitmap = ntohl (flags);
7591   mp->is_set = is_set;
7592
7593   S (mp);
7594   W (ret);
7595   return ret;
7596 }
7597
7598 static int
7599 api_bridge_flags (vat_main_t * vam)
7600 {
7601   unformat_input_t *i = vam->input;
7602   vl_api_bridge_flags_t *mp;
7603   u32 bd_id;
7604   u8 bd_id_set = 0;
7605   u8 is_set = 1;
7606   u32 flags = 0;
7607   int ret;
7608
7609   /* Parse args required to build the message */
7610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7611     {
7612       if (unformat (i, "bd_id %d", &bd_id))
7613         bd_id_set = 1;
7614       else if (unformat (i, "learn"))
7615         flags |= L2_LEARN;
7616       else if (unformat (i, "forward"))
7617         flags |= L2_FWD;
7618       else if (unformat (i, "flood"))
7619         flags |= L2_FLOOD;
7620       else if (unformat (i, "uu-flood"))
7621         flags |= L2_UU_FLOOD;
7622       else if (unformat (i, "arp-term"))
7623         flags |= L2_ARP_TERM;
7624       else if (unformat (i, "off"))
7625         is_set = 0;
7626       else if (unformat (i, "disable"))
7627         is_set = 0;
7628       else
7629         break;
7630     }
7631
7632   if (bd_id_set == 0)
7633     {
7634       errmsg ("missing bridge domain");
7635       return -99;
7636     }
7637
7638   M (BRIDGE_FLAGS, mp);
7639
7640   mp->bd_id = ntohl (bd_id);
7641   mp->feature_bitmap = ntohl (flags);
7642   mp->is_set = is_set;
7643
7644   S (mp);
7645   W (ret);
7646   return ret;
7647 }
7648
7649 static int
7650 api_bd_ip_mac_add_del (vat_main_t * vam)
7651 {
7652   unformat_input_t *i = vam->input;
7653   vl_api_bd_ip_mac_add_del_t *mp;
7654   u32 bd_id;
7655   u8 is_ipv6 = 0;
7656   u8 is_add = 1;
7657   u8 bd_id_set = 0;
7658   u8 ip_set = 0;
7659   u8 mac_set = 0;
7660   ip4_address_t v4addr;
7661   ip6_address_t v6addr;
7662   u8 macaddr[6];
7663   int ret;
7664
7665
7666   /* Parse args required to build the message */
7667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7668     {
7669       if (unformat (i, "bd_id %d", &bd_id))
7670         {
7671           bd_id_set++;
7672         }
7673       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7674         {
7675           ip_set++;
7676         }
7677       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7678         {
7679           ip_set++;
7680           is_ipv6++;
7681         }
7682       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7683         {
7684           mac_set++;
7685         }
7686       else if (unformat (i, "del"))
7687         is_add = 0;
7688       else
7689         break;
7690     }
7691
7692   if (bd_id_set == 0)
7693     {
7694       errmsg ("missing bridge domain");
7695       return -99;
7696     }
7697   else if (ip_set == 0)
7698     {
7699       errmsg ("missing IP address");
7700       return -99;
7701     }
7702   else if (mac_set == 0)
7703     {
7704       errmsg ("missing MAC address");
7705       return -99;
7706     }
7707
7708   M (BD_IP_MAC_ADD_DEL, mp);
7709
7710   mp->bd_id = ntohl (bd_id);
7711   mp->is_ipv6 = is_ipv6;
7712   mp->is_add = is_add;
7713   if (is_ipv6)
7714     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7715   else
7716     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7717   clib_memcpy (mp->mac_address, macaddr, 6);
7718   S (mp);
7719   W (ret);
7720   return ret;
7721 }
7722
7723 static int
7724 api_tap_connect (vat_main_t * vam)
7725 {
7726   unformat_input_t *i = vam->input;
7727   vl_api_tap_connect_t *mp;
7728   u8 mac_address[6];
7729   u8 random_mac = 1;
7730   u8 name_set = 0;
7731   u8 *tap_name;
7732   u8 *tag = 0;
7733   ip4_address_t ip4_address;
7734   u32 ip4_mask_width;
7735   int ip4_address_set = 0;
7736   ip6_address_t ip6_address;
7737   u32 ip6_mask_width;
7738   int ip6_address_set = 0;
7739   int ret;
7740
7741   memset (mac_address, 0, sizeof (mac_address));
7742
7743   /* Parse args required to build the message */
7744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7745     {
7746       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7747         {
7748           random_mac = 0;
7749         }
7750       else if (unformat (i, "random-mac"))
7751         random_mac = 1;
7752       else if (unformat (i, "tapname %s", &tap_name))
7753         name_set = 1;
7754       else if (unformat (i, "tag %s", &tag))
7755         ;
7756       else if (unformat (i, "address %U/%d",
7757                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7758         ip4_address_set = 1;
7759       else if (unformat (i, "address %U/%d",
7760                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7761         ip6_address_set = 1;
7762       else
7763         break;
7764     }
7765
7766   if (name_set == 0)
7767     {
7768       errmsg ("missing tap name");
7769       return -99;
7770     }
7771   if (vec_len (tap_name) > 63)
7772     {
7773       errmsg ("tap name too long");
7774       return -99;
7775     }
7776   vec_add1 (tap_name, 0);
7777
7778   if (vec_len (tag) > 63)
7779     {
7780       errmsg ("tag too long");
7781       return -99;
7782     }
7783
7784   /* Construct the API message */
7785   M (TAP_CONNECT, mp);
7786
7787   mp->use_random_mac = random_mac;
7788   clib_memcpy (mp->mac_address, mac_address, 6);
7789   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7790   if (tag)
7791     clib_memcpy (mp->tag, tag, vec_len (tag));
7792
7793   if (ip4_address_set)
7794     {
7795       mp->ip4_address_set = 1;
7796       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7797       mp->ip4_mask_width = ip4_mask_width;
7798     }
7799   if (ip6_address_set)
7800     {
7801       mp->ip6_address_set = 1;
7802       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7803       mp->ip6_mask_width = ip6_mask_width;
7804     }
7805
7806   vec_free (tap_name);
7807   vec_free (tag);
7808
7809   /* send it... */
7810   S (mp);
7811
7812   /* Wait for a reply... */
7813   W (ret);
7814   return ret;
7815 }
7816
7817 static int
7818 api_tap_modify (vat_main_t * vam)
7819 {
7820   unformat_input_t *i = vam->input;
7821   vl_api_tap_modify_t *mp;
7822   u8 mac_address[6];
7823   u8 random_mac = 1;
7824   u8 name_set = 0;
7825   u8 *tap_name;
7826   u32 sw_if_index = ~0;
7827   u8 sw_if_index_set = 0;
7828   int ret;
7829
7830   memset (mac_address, 0, sizeof (mac_address));
7831
7832   /* Parse args required to build the message */
7833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7834     {
7835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7836         sw_if_index_set = 1;
7837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7838         sw_if_index_set = 1;
7839       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7840         {
7841           random_mac = 0;
7842         }
7843       else if (unformat (i, "random-mac"))
7844         random_mac = 1;
7845       else if (unformat (i, "tapname %s", &tap_name))
7846         name_set = 1;
7847       else
7848         break;
7849     }
7850
7851   if (sw_if_index_set == 0)
7852     {
7853       errmsg ("missing vpp interface name");
7854       return -99;
7855     }
7856   if (name_set == 0)
7857     {
7858       errmsg ("missing tap name");
7859       return -99;
7860     }
7861   if (vec_len (tap_name) > 63)
7862     {
7863       errmsg ("tap name too long");
7864     }
7865   vec_add1 (tap_name, 0);
7866
7867   /* Construct the API message */
7868   M (TAP_MODIFY, mp);
7869
7870   mp->use_random_mac = random_mac;
7871   mp->sw_if_index = ntohl (sw_if_index);
7872   clib_memcpy (mp->mac_address, mac_address, 6);
7873   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7874   vec_free (tap_name);
7875
7876   /* send it... */
7877   S (mp);
7878
7879   /* Wait for a reply... */
7880   W (ret);
7881   return ret;
7882 }
7883
7884 static int
7885 api_tap_delete (vat_main_t * vam)
7886 {
7887   unformat_input_t *i = vam->input;
7888   vl_api_tap_delete_t *mp;
7889   u32 sw_if_index = ~0;
7890   u8 sw_if_index_set = 0;
7891   int ret;
7892
7893   /* Parse args required to build the message */
7894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7895     {
7896       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7897         sw_if_index_set = 1;
7898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7899         sw_if_index_set = 1;
7900       else
7901         break;
7902     }
7903
7904   if (sw_if_index_set == 0)
7905     {
7906       errmsg ("missing vpp interface name");
7907       return -99;
7908     }
7909
7910   /* Construct the API message */
7911   M (TAP_DELETE, mp);
7912
7913   mp->sw_if_index = ntohl (sw_if_index);
7914
7915   /* send it... */
7916   S (mp);
7917
7918   /* Wait for a reply... */
7919   W (ret);
7920   return ret;
7921 }
7922
7923 static int
7924 api_tap_create_v2 (vat_main_t * vam)
7925 {
7926   unformat_input_t *i = vam->input;
7927   vl_api_tap_create_v2_t *mp;
7928   u8 mac_address[6];
7929   u8 random_mac = 1;
7930   u32 id = ~0;
7931   u8 *host_if_name = 0;
7932   u8 *host_ns = 0;
7933   u8 host_mac_addr[6];
7934   u8 host_mac_addr_set = 0;
7935   u8 *host_bridge = 0;
7936   ip4_address_t host_ip4_addr;
7937   ip4_address_t host_ip4_gw;
7938   u8 host_ip4_gw_set = 0;
7939   u32 host_ip4_prefix_len = 0;
7940   ip6_address_t host_ip6_addr;
7941   ip6_address_t host_ip6_gw;
7942   u8 host_ip6_gw_set = 0;
7943   u32 host_ip6_prefix_len = 0;
7944   int ret;
7945   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7946
7947   memset (mac_address, 0, sizeof (mac_address));
7948
7949   /* Parse args required to build the message */
7950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7951     {
7952       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7953         {
7954           random_mac = 0;
7955         }
7956       else if (unformat (i, "id %u", &id))
7957         ;
7958       else if (unformat (i, "host-if-name %s", &host_if_name))
7959         ;
7960       else if (unformat (i, "host-ns %s", &host_ns))
7961         ;
7962       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7963                          host_mac_addr))
7964         host_mac_addr_set = 1;
7965       else if (unformat (i, "host-bridge %s", &host_bridge))
7966         ;
7967       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7968                          &host_ip4_addr, &host_ip4_prefix_len))
7969         ;
7970       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7971                          &host_ip6_addr, &host_ip6_prefix_len))
7972         ;
7973       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7974                          &host_ip4_gw))
7975         host_ip4_gw_set = 1;
7976       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7977                          &host_ip6_gw))
7978         host_ip6_gw_set = 1;
7979       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7980         ;
7981       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7982         ;
7983       else
7984         break;
7985     }
7986
7987   if (vec_len (host_if_name) > 63)
7988     {
7989       errmsg ("tap name too long. ");
7990       return -99;
7991     }
7992   if (vec_len (host_ns) > 63)
7993     {
7994       errmsg ("host name space too long. ");
7995       return -99;
7996     }
7997   if (vec_len (host_bridge) > 63)
7998     {
7999       errmsg ("host bridge name too long. ");
8000       return -99;
8001     }
8002   if (host_ip4_prefix_len > 32)
8003     {
8004       errmsg ("host ip4 prefix length not valid. ");
8005       return -99;
8006     }
8007   if (host_ip6_prefix_len > 128)
8008     {
8009       errmsg ("host ip6 prefix length not valid. ");
8010       return -99;
8011     }
8012   if (!is_pow2 (rx_ring_sz))
8013     {
8014       errmsg ("rx ring size must be power of 2. ");
8015       return -99;
8016     }
8017   if (rx_ring_sz > 32768)
8018     {
8019       errmsg ("rx ring size must be 32768 or lower. ");
8020       return -99;
8021     }
8022   if (!is_pow2 (tx_ring_sz))
8023     {
8024       errmsg ("tx ring size must be power of 2. ");
8025       return -99;
8026     }
8027   if (tx_ring_sz > 32768)
8028     {
8029       errmsg ("tx ring size must be 32768 or lower. ");
8030       return -99;
8031     }
8032
8033   /* Construct the API message */
8034   M (TAP_CREATE_V2, mp);
8035
8036   mp->use_random_mac = random_mac;
8037
8038   mp->id = ntohl (id);
8039   mp->host_namespace_set = host_ns != 0;
8040   mp->host_bridge_set = host_bridge != 0;
8041   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8042   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8043   mp->rx_ring_sz = ntohs (rx_ring_sz);
8044   mp->tx_ring_sz = ntohs (tx_ring_sz);
8045
8046   if (random_mac == 0)
8047     clib_memcpy (mp->mac_address, mac_address, 6);
8048   if (host_mac_addr_set)
8049     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8050   if (host_if_name)
8051     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8052   if (host_ns)
8053     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8054   if (host_bridge)
8055     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8056   if (host_ip4_prefix_len)
8057     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8058   if (host_ip4_prefix_len)
8059     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8060   if (host_ip4_gw_set)
8061     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8062   if (host_ip6_gw_set)
8063     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8064
8065   vec_free (host_ns);
8066   vec_free (host_if_name);
8067   vec_free (host_bridge);
8068
8069   /* send it... */
8070   S (mp);
8071
8072   /* Wait for a reply... */
8073   W (ret);
8074   return ret;
8075 }
8076
8077 static int
8078 api_tap_delete_v2 (vat_main_t * vam)
8079 {
8080   unformat_input_t *i = vam->input;
8081   vl_api_tap_delete_v2_t *mp;
8082   u32 sw_if_index = ~0;
8083   u8 sw_if_index_set = 0;
8084   int ret;
8085
8086   /* Parse args required to build the message */
8087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8088     {
8089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8090         sw_if_index_set = 1;
8091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8092         sw_if_index_set = 1;
8093       else
8094         break;
8095     }
8096
8097   if (sw_if_index_set == 0)
8098     {
8099       errmsg ("missing vpp interface name. ");
8100       return -99;
8101     }
8102
8103   /* Construct the API message */
8104   M (TAP_DELETE_V2, mp);
8105
8106   mp->sw_if_index = ntohl (sw_if_index);
8107
8108   /* send it... */
8109   S (mp);
8110
8111   /* Wait for a reply... */
8112   W (ret);
8113   return ret;
8114 }
8115
8116 static int
8117 api_bond_create (vat_main_t * vam)
8118 {
8119   unformat_input_t *i = vam->input;
8120   vl_api_bond_create_t *mp;
8121   u8 mac_address[6];
8122   u8 custom_mac = 0;
8123   int ret;
8124   u8 mode;
8125   u8 lb;
8126   u8 mode_is_set = 0;
8127
8128   memset (mac_address, 0, sizeof (mac_address));
8129   lb = BOND_LB_L2;
8130
8131   /* Parse args required to build the message */
8132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8133     {
8134       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8135         mode_is_set = 1;
8136       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8137                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8138         ;
8139       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8140                          mac_address))
8141         custom_mac = 1;
8142       else
8143         break;
8144     }
8145
8146   if (mode_is_set == 0)
8147     {
8148       errmsg ("Missing bond mode. ");
8149       return -99;
8150     }
8151
8152   /* Construct the API message */
8153   M (BOND_CREATE, mp);
8154
8155   mp->use_custom_mac = custom_mac;
8156
8157   mp->mode = mode;
8158   mp->lb = lb;
8159
8160   if (custom_mac)
8161     clib_memcpy (mp->mac_address, mac_address, 6);
8162
8163   /* send it... */
8164   S (mp);
8165
8166   /* Wait for a reply... */
8167   W (ret);
8168   return ret;
8169 }
8170
8171 static int
8172 api_bond_delete (vat_main_t * vam)
8173 {
8174   unformat_input_t *i = vam->input;
8175   vl_api_bond_delete_t *mp;
8176   u32 sw_if_index = ~0;
8177   u8 sw_if_index_set = 0;
8178   int ret;
8179
8180   /* Parse args required to build the message */
8181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8182     {
8183       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8184         sw_if_index_set = 1;
8185       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8186         sw_if_index_set = 1;
8187       else
8188         break;
8189     }
8190
8191   if (sw_if_index_set == 0)
8192     {
8193       errmsg ("missing vpp interface name. ");
8194       return -99;
8195     }
8196
8197   /* Construct the API message */
8198   M (BOND_DELETE, mp);
8199
8200   mp->sw_if_index = ntohl (sw_if_index);
8201
8202   /* send it... */
8203   S (mp);
8204
8205   /* Wait for a reply... */
8206   W (ret);
8207   return ret;
8208 }
8209
8210 static int
8211 api_bond_enslave (vat_main_t * vam)
8212 {
8213   unformat_input_t *i = vam->input;
8214   vl_api_bond_enslave_t *mp;
8215   u32 bond_sw_if_index;
8216   int ret;
8217   u8 is_passive;
8218   u8 is_long_timeout;
8219   u32 bond_sw_if_index_is_set = 0;
8220   u32 sw_if_index;
8221   u8 sw_if_index_is_set = 0;
8222
8223   /* Parse args required to build the message */
8224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8225     {
8226       if (unformat (i, "sw_if_index %d", &sw_if_index))
8227         sw_if_index_is_set = 1;
8228       else if (unformat (i, "bond %u", &bond_sw_if_index))
8229         bond_sw_if_index_is_set = 1;
8230       else if (unformat (i, "passive %d", &is_passive))
8231         ;
8232       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8233         ;
8234       else
8235         break;
8236     }
8237
8238   if (bond_sw_if_index_is_set == 0)
8239     {
8240       errmsg ("Missing bond sw_if_index. ");
8241       return -99;
8242     }
8243   if (sw_if_index_is_set == 0)
8244     {
8245       errmsg ("Missing slave sw_if_index. ");
8246       return -99;
8247     }
8248
8249   /* Construct the API message */
8250   M (BOND_ENSLAVE, mp);
8251
8252   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8253   mp->sw_if_index = ntohl (sw_if_index);
8254   mp->is_long_timeout = is_long_timeout;
8255   mp->is_passive = is_passive;
8256
8257   /* send it... */
8258   S (mp);
8259
8260   /* Wait for a reply... */
8261   W (ret);
8262   return ret;
8263 }
8264
8265 static int
8266 api_bond_detach_slave (vat_main_t * vam)
8267 {
8268   unformat_input_t *i = vam->input;
8269   vl_api_bond_detach_slave_t *mp;
8270   u32 sw_if_index = ~0;
8271   u8 sw_if_index_set = 0;
8272   int ret;
8273
8274   /* Parse args required to build the message */
8275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8276     {
8277       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8278         sw_if_index_set = 1;
8279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8280         sw_if_index_set = 1;
8281       else
8282         break;
8283     }
8284
8285   if (sw_if_index_set == 0)
8286     {
8287       errmsg ("missing vpp interface name. ");
8288       return -99;
8289     }
8290
8291   /* Construct the API message */
8292   M (BOND_DETACH_SLAVE, mp);
8293
8294   mp->sw_if_index = ntohl (sw_if_index);
8295
8296   /* send it... */
8297   S (mp);
8298
8299   /* Wait for a reply... */
8300   W (ret);
8301   return ret;
8302 }
8303
8304 static int
8305 api_ip_table_add_del (vat_main_t * vam)
8306 {
8307   unformat_input_t *i = vam->input;
8308   vl_api_ip_table_add_del_t *mp;
8309   u32 table_id = ~0;
8310   u8 is_ipv6 = 0;
8311   u8 is_add = 1;
8312   int ret = 0;
8313
8314   /* Parse args required to build the message */
8315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8316     {
8317       if (unformat (i, "ipv6"))
8318         is_ipv6 = 1;
8319       else if (unformat (i, "del"))
8320         is_add = 0;
8321       else if (unformat (i, "add"))
8322         is_add = 1;
8323       else if (unformat (i, "table %d", &table_id))
8324         ;
8325       else
8326         {
8327           clib_warning ("parse error '%U'", format_unformat_error, i);
8328           return -99;
8329         }
8330     }
8331
8332   if (~0 == table_id)
8333     {
8334       errmsg ("missing table-ID");
8335       return -99;
8336     }
8337
8338   /* Construct the API message */
8339   M (IP_TABLE_ADD_DEL, mp);
8340
8341   mp->table_id = ntohl (table_id);
8342   mp->is_ipv6 = is_ipv6;
8343   mp->is_add = is_add;
8344
8345   /* send it... */
8346   S (mp);
8347
8348   /* Wait for a reply... */
8349   W (ret);
8350
8351   return ret;
8352 }
8353
8354 static int
8355 api_ip_add_del_route (vat_main_t * vam)
8356 {
8357   unformat_input_t *i = vam->input;
8358   vl_api_ip_add_del_route_t *mp;
8359   u32 sw_if_index = ~0, vrf_id = 0;
8360   u8 is_ipv6 = 0;
8361   u8 is_local = 0, is_drop = 0;
8362   u8 is_unreach = 0, is_prohibit = 0;
8363   u8 is_add = 1;
8364   u32 next_hop_weight = 1;
8365   u8 is_multipath = 0;
8366   u8 address_set = 0;
8367   u8 address_length_set = 0;
8368   u32 next_hop_table_id = 0;
8369   u32 resolve_attempts = 0;
8370   u32 dst_address_length = 0;
8371   u8 next_hop_set = 0;
8372   ip4_address_t v4_dst_address, v4_next_hop_address;
8373   ip6_address_t v6_dst_address, v6_next_hop_address;
8374   int count = 1;
8375   int j;
8376   f64 before = 0;
8377   u32 random_add_del = 0;
8378   u32 *random_vector = 0;
8379   uword *random_hash;
8380   u32 random_seed = 0xdeaddabe;
8381   u32 classify_table_index = ~0;
8382   u8 is_classify = 0;
8383   u8 resolve_host = 0, resolve_attached = 0;
8384   mpls_label_t *next_hop_out_label_stack = NULL;
8385   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8386   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8387
8388   /* Parse args required to build the message */
8389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8390     {
8391       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8392         ;
8393       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8394         ;
8395       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8396         {
8397           address_set = 1;
8398           is_ipv6 = 0;
8399         }
8400       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8401         {
8402           address_set = 1;
8403           is_ipv6 = 1;
8404         }
8405       else if (unformat (i, "/%d", &dst_address_length))
8406         {
8407           address_length_set = 1;
8408         }
8409
8410       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8411                                          &v4_next_hop_address))
8412         {
8413           next_hop_set = 1;
8414         }
8415       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8416                                          &v6_next_hop_address))
8417         {
8418           next_hop_set = 1;
8419         }
8420       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8421         ;
8422       else if (unformat (i, "weight %d", &next_hop_weight))
8423         ;
8424       else if (unformat (i, "drop"))
8425         {
8426           is_drop = 1;
8427         }
8428       else if (unformat (i, "null-send-unreach"))
8429         {
8430           is_unreach = 1;
8431         }
8432       else if (unformat (i, "null-send-prohibit"))
8433         {
8434           is_prohibit = 1;
8435         }
8436       else if (unformat (i, "local"))
8437         {
8438           is_local = 1;
8439         }
8440       else if (unformat (i, "classify %d", &classify_table_index))
8441         {
8442           is_classify = 1;
8443         }
8444       else if (unformat (i, "del"))
8445         is_add = 0;
8446       else if (unformat (i, "add"))
8447         is_add = 1;
8448       else if (unformat (i, "resolve-via-host"))
8449         resolve_host = 1;
8450       else if (unformat (i, "resolve-via-attached"))
8451         resolve_attached = 1;
8452       else if (unformat (i, "multipath"))
8453         is_multipath = 1;
8454       else if (unformat (i, "vrf %d", &vrf_id))
8455         ;
8456       else if (unformat (i, "count %d", &count))
8457         ;
8458       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8459         ;
8460       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8461         ;
8462       else if (unformat (i, "out-label %d", &next_hop_out_label))
8463         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8464       else if (unformat (i, "via-label %d", &next_hop_via_label))
8465         ;
8466       else if (unformat (i, "random"))
8467         random_add_del = 1;
8468       else if (unformat (i, "seed %d", &random_seed))
8469         ;
8470       else
8471         {
8472           clib_warning ("parse error '%U'", format_unformat_error, i);
8473           return -99;
8474         }
8475     }
8476
8477   if (!next_hop_set && !is_drop && !is_local &&
8478       !is_classify && !is_unreach && !is_prohibit &&
8479       MPLS_LABEL_INVALID == next_hop_via_label)
8480     {
8481       errmsg
8482         ("next hop / local / drop / unreach / prohibit / classify not set");
8483       return -99;
8484     }
8485
8486   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8487     {
8488       errmsg ("next hop and next-hop via label set");
8489       return -99;
8490     }
8491   if (address_set == 0)
8492     {
8493       errmsg ("missing addresses");
8494       return -99;
8495     }
8496
8497   if (address_length_set == 0)
8498     {
8499       errmsg ("missing address length");
8500       return -99;
8501     }
8502
8503   /* Generate a pile of unique, random routes */
8504   if (random_add_del)
8505     {
8506       u32 this_random_address;
8507       random_hash = hash_create (count, sizeof (uword));
8508
8509       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8510       for (j = 0; j <= count; j++)
8511         {
8512           do
8513             {
8514               this_random_address = random_u32 (&random_seed);
8515               this_random_address =
8516                 clib_host_to_net_u32 (this_random_address);
8517             }
8518           while (hash_get (random_hash, this_random_address));
8519           vec_add1 (random_vector, this_random_address);
8520           hash_set (random_hash, this_random_address, 1);
8521         }
8522       hash_free (random_hash);
8523       v4_dst_address.as_u32 = random_vector[0];
8524     }
8525
8526   if (count > 1)
8527     {
8528       /* Turn on async mode */
8529       vam->async_mode = 1;
8530       vam->async_errors = 0;
8531       before = vat_time_now (vam);
8532     }
8533
8534   for (j = 0; j < count; j++)
8535     {
8536       /* Construct the API message */
8537       M2 (IP_ADD_DEL_ROUTE, mp,
8538           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8539
8540       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8541       mp->table_id = ntohl (vrf_id);
8542
8543       mp->is_add = is_add;
8544       mp->is_drop = is_drop;
8545       mp->is_unreach = is_unreach;
8546       mp->is_prohibit = is_prohibit;
8547       mp->is_ipv6 = is_ipv6;
8548       mp->is_local = is_local;
8549       mp->is_classify = is_classify;
8550       mp->is_multipath = is_multipath;
8551       mp->is_resolve_host = resolve_host;
8552       mp->is_resolve_attached = resolve_attached;
8553       mp->next_hop_weight = next_hop_weight;
8554       mp->dst_address_length = dst_address_length;
8555       mp->next_hop_table_id = ntohl (next_hop_table_id);
8556       mp->classify_table_index = ntohl (classify_table_index);
8557       mp->next_hop_via_label = ntohl (next_hop_via_label);
8558       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8559       if (0 != mp->next_hop_n_out_labels)
8560         {
8561           memcpy (mp->next_hop_out_label_stack,
8562                   next_hop_out_label_stack,
8563                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8564           vec_free (next_hop_out_label_stack);
8565         }
8566
8567       if (is_ipv6)
8568         {
8569           clib_memcpy (mp->dst_address, &v6_dst_address,
8570                        sizeof (v6_dst_address));
8571           if (next_hop_set)
8572             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8573                          sizeof (v6_next_hop_address));
8574           increment_v6_address (&v6_dst_address);
8575         }
8576       else
8577         {
8578           clib_memcpy (mp->dst_address, &v4_dst_address,
8579                        sizeof (v4_dst_address));
8580           if (next_hop_set)
8581             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8582                          sizeof (v4_next_hop_address));
8583           if (random_add_del)
8584             v4_dst_address.as_u32 = random_vector[j + 1];
8585           else
8586             increment_v4_address (&v4_dst_address);
8587         }
8588       /* send it... */
8589       S (mp);
8590       /* If we receive SIGTERM, stop now... */
8591       if (vam->do_exit)
8592         break;
8593     }
8594
8595   /* When testing multiple add/del ops, use a control-ping to sync */
8596   if (count > 1)
8597     {
8598       vl_api_control_ping_t *mp_ping;
8599       f64 after;
8600       f64 timeout;
8601
8602       /* Shut off async mode */
8603       vam->async_mode = 0;
8604
8605       MPING (CONTROL_PING, mp_ping);
8606       S (mp_ping);
8607
8608       timeout = vat_time_now (vam) + 1.0;
8609       while (vat_time_now (vam) < timeout)
8610         if (vam->result_ready == 1)
8611           goto out;
8612       vam->retval = -99;
8613
8614     out:
8615       if (vam->retval == -99)
8616         errmsg ("timeout");
8617
8618       if (vam->async_errors > 0)
8619         {
8620           errmsg ("%d asynchronous errors", vam->async_errors);
8621           vam->retval = -98;
8622         }
8623       vam->async_errors = 0;
8624       after = vat_time_now (vam);
8625
8626       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8627       if (j > 0)
8628         count = j;
8629
8630       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8631              count, after - before, count / (after - before));
8632     }
8633   else
8634     {
8635       int ret;
8636
8637       /* Wait for a reply... */
8638       W (ret);
8639       return ret;
8640     }
8641
8642   /* Return the good/bad news */
8643   return (vam->retval);
8644 }
8645
8646 static int
8647 api_ip_mroute_add_del (vat_main_t * vam)
8648 {
8649   unformat_input_t *i = vam->input;
8650   vl_api_ip_mroute_add_del_t *mp;
8651   u32 sw_if_index = ~0, vrf_id = 0;
8652   u8 is_ipv6 = 0;
8653   u8 is_local = 0;
8654   u8 is_add = 1;
8655   u8 address_set = 0;
8656   u32 grp_address_length = 0;
8657   ip4_address_t v4_grp_address, v4_src_address;
8658   ip6_address_t v6_grp_address, v6_src_address;
8659   mfib_itf_flags_t iflags = 0;
8660   mfib_entry_flags_t eflags = 0;
8661   int ret;
8662
8663   /* Parse args required to build the message */
8664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8665     {
8666       if (unformat (i, "sw_if_index %d", &sw_if_index))
8667         ;
8668       else if (unformat (i, "%U %U",
8669                          unformat_ip4_address, &v4_src_address,
8670                          unformat_ip4_address, &v4_grp_address))
8671         {
8672           grp_address_length = 64;
8673           address_set = 1;
8674           is_ipv6 = 0;
8675         }
8676       else if (unformat (i, "%U %U",
8677                          unformat_ip6_address, &v6_src_address,
8678                          unformat_ip6_address, &v6_grp_address))
8679         {
8680           grp_address_length = 256;
8681           address_set = 1;
8682           is_ipv6 = 1;
8683         }
8684       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8685         {
8686           memset (&v4_src_address, 0, sizeof (v4_src_address));
8687           grp_address_length = 32;
8688           address_set = 1;
8689           is_ipv6 = 0;
8690         }
8691       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8692         {
8693           memset (&v6_src_address, 0, sizeof (v6_src_address));
8694           grp_address_length = 128;
8695           address_set = 1;
8696           is_ipv6 = 1;
8697         }
8698       else if (unformat (i, "/%d", &grp_address_length))
8699         ;
8700       else if (unformat (i, "local"))
8701         {
8702           is_local = 1;
8703         }
8704       else if (unformat (i, "del"))
8705         is_add = 0;
8706       else if (unformat (i, "add"))
8707         is_add = 1;
8708       else if (unformat (i, "vrf %d", &vrf_id))
8709         ;
8710       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8711         ;
8712       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8713         ;
8714       else
8715         {
8716           clib_warning ("parse error '%U'", format_unformat_error, i);
8717           return -99;
8718         }
8719     }
8720
8721   if (address_set == 0)
8722     {
8723       errmsg ("missing addresses\n");
8724       return -99;
8725     }
8726
8727   /* Construct the API message */
8728   M (IP_MROUTE_ADD_DEL, mp);
8729
8730   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8731   mp->table_id = ntohl (vrf_id);
8732
8733   mp->is_add = is_add;
8734   mp->is_ipv6 = is_ipv6;
8735   mp->is_local = is_local;
8736   mp->itf_flags = ntohl (iflags);
8737   mp->entry_flags = ntohl (eflags);
8738   mp->grp_address_length = grp_address_length;
8739   mp->grp_address_length = ntohs (mp->grp_address_length);
8740
8741   if (is_ipv6)
8742     {
8743       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8744       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8745     }
8746   else
8747     {
8748       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8749       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8750
8751     }
8752
8753   /* send it... */
8754   S (mp);
8755   /* Wait for a reply... */
8756   W (ret);
8757   return ret;
8758 }
8759
8760 static int
8761 api_mpls_table_add_del (vat_main_t * vam)
8762 {
8763   unformat_input_t *i = vam->input;
8764   vl_api_mpls_table_add_del_t *mp;
8765   u32 table_id = ~0;
8766   u8 is_add = 1;
8767   int ret = 0;
8768
8769   /* Parse args required to build the message */
8770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8771     {
8772       if (unformat (i, "table %d", &table_id))
8773         ;
8774       else if (unformat (i, "del"))
8775         is_add = 0;
8776       else if (unformat (i, "add"))
8777         is_add = 1;
8778       else
8779         {
8780           clib_warning ("parse error '%U'", format_unformat_error, i);
8781           return -99;
8782         }
8783     }
8784
8785   if (~0 == table_id)
8786     {
8787       errmsg ("missing table-ID");
8788       return -99;
8789     }
8790
8791   /* Construct the API message */
8792   M (MPLS_TABLE_ADD_DEL, mp);
8793
8794   mp->mt_table_id = ntohl (table_id);
8795   mp->mt_is_add = is_add;
8796
8797   /* send it... */
8798   S (mp);
8799
8800   /* Wait for a reply... */
8801   W (ret);
8802
8803   return ret;
8804 }
8805
8806 static int
8807 api_mpls_route_add_del (vat_main_t * vam)
8808 {
8809   unformat_input_t *i = vam->input;
8810   vl_api_mpls_route_add_del_t *mp;
8811   u32 sw_if_index = ~0, table_id = 0;
8812   u8 is_add = 1;
8813   u32 next_hop_weight = 1;
8814   u8 is_multipath = 0;
8815   u32 next_hop_table_id = 0;
8816   u8 next_hop_set = 0;
8817   ip4_address_t v4_next_hop_address = {
8818     .as_u32 = 0,
8819   };
8820   ip6_address_t v6_next_hop_address = { {0} };
8821   int count = 1;
8822   int j;
8823   f64 before = 0;
8824   u32 classify_table_index = ~0;
8825   u8 is_classify = 0;
8826   u8 resolve_host = 0, resolve_attached = 0;
8827   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8828   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8829   mpls_label_t *next_hop_out_label_stack = NULL;
8830   mpls_label_t local_label = MPLS_LABEL_INVALID;
8831   u8 is_eos = 0;
8832   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8833
8834   /* Parse args required to build the message */
8835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8836     {
8837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8838         ;
8839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8840         ;
8841       else if (unformat (i, "%d", &local_label))
8842         ;
8843       else if (unformat (i, "eos"))
8844         is_eos = 1;
8845       else if (unformat (i, "non-eos"))
8846         is_eos = 0;
8847       else if (unformat (i, "via %U", unformat_ip4_address,
8848                          &v4_next_hop_address))
8849         {
8850           next_hop_set = 1;
8851           next_hop_proto = DPO_PROTO_IP4;
8852         }
8853       else if (unformat (i, "via %U", unformat_ip6_address,
8854                          &v6_next_hop_address))
8855         {
8856           next_hop_set = 1;
8857           next_hop_proto = DPO_PROTO_IP6;
8858         }
8859       else if (unformat (i, "weight %d", &next_hop_weight))
8860         ;
8861       else if (unformat (i, "classify %d", &classify_table_index))
8862         {
8863           is_classify = 1;
8864         }
8865       else if (unformat (i, "del"))
8866         is_add = 0;
8867       else if (unformat (i, "add"))
8868         is_add = 1;
8869       else if (unformat (i, "resolve-via-host"))
8870         resolve_host = 1;
8871       else if (unformat (i, "resolve-via-attached"))
8872         resolve_attached = 1;
8873       else if (unformat (i, "multipath"))
8874         is_multipath = 1;
8875       else if (unformat (i, "count %d", &count))
8876         ;
8877       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8878         {
8879           next_hop_set = 1;
8880           next_hop_proto = DPO_PROTO_IP4;
8881         }
8882       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8883         {
8884           next_hop_set = 1;
8885           next_hop_proto = DPO_PROTO_IP6;
8886         }
8887       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8888         ;
8889       else if (unformat (i, "via-label %d", &next_hop_via_label))
8890         ;
8891       else if (unformat (i, "out-label %d", &next_hop_out_label))
8892         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8893       else
8894         {
8895           clib_warning ("parse error '%U'", format_unformat_error, i);
8896           return -99;
8897         }
8898     }
8899
8900   if (!next_hop_set && !is_classify)
8901     {
8902       errmsg ("next hop / classify not set");
8903       return -99;
8904     }
8905
8906   if (MPLS_LABEL_INVALID == local_label)
8907     {
8908       errmsg ("missing label");
8909       return -99;
8910     }
8911
8912   if (count > 1)
8913     {
8914       /* Turn on async mode */
8915       vam->async_mode = 1;
8916       vam->async_errors = 0;
8917       before = vat_time_now (vam);
8918     }
8919
8920   for (j = 0; j < count; j++)
8921     {
8922       /* Construct the API message */
8923       M2 (MPLS_ROUTE_ADD_DEL, mp,
8924           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8925
8926       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8927       mp->mr_table_id = ntohl (table_id);
8928
8929       mp->mr_is_add = is_add;
8930       mp->mr_next_hop_proto = next_hop_proto;
8931       mp->mr_is_classify = is_classify;
8932       mp->mr_is_multipath = is_multipath;
8933       mp->mr_is_resolve_host = resolve_host;
8934       mp->mr_is_resolve_attached = resolve_attached;
8935       mp->mr_next_hop_weight = next_hop_weight;
8936       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8937       mp->mr_classify_table_index = ntohl (classify_table_index);
8938       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8939       mp->mr_label = ntohl (local_label);
8940       mp->mr_eos = is_eos;
8941
8942       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8943       if (0 != mp->mr_next_hop_n_out_labels)
8944         {
8945           memcpy (mp->mr_next_hop_out_label_stack,
8946                   next_hop_out_label_stack,
8947                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8948           vec_free (next_hop_out_label_stack);
8949         }
8950
8951       if (next_hop_set)
8952         {
8953           if (DPO_PROTO_IP4 == next_hop_proto)
8954             {
8955               clib_memcpy (mp->mr_next_hop,
8956                            &v4_next_hop_address,
8957                            sizeof (v4_next_hop_address));
8958             }
8959           else if (DPO_PROTO_IP6 == next_hop_proto)
8960
8961             {
8962               clib_memcpy (mp->mr_next_hop,
8963                            &v6_next_hop_address,
8964                            sizeof (v6_next_hop_address));
8965             }
8966         }
8967       local_label++;
8968
8969       /* send it... */
8970       S (mp);
8971       /* If we receive SIGTERM, stop now... */
8972       if (vam->do_exit)
8973         break;
8974     }
8975
8976   /* When testing multiple add/del ops, use a control-ping to sync */
8977   if (count > 1)
8978     {
8979       vl_api_control_ping_t *mp_ping;
8980       f64 after;
8981       f64 timeout;
8982
8983       /* Shut off async mode */
8984       vam->async_mode = 0;
8985
8986       MPING (CONTROL_PING, mp_ping);
8987       S (mp_ping);
8988
8989       timeout = vat_time_now (vam) + 1.0;
8990       while (vat_time_now (vam) < timeout)
8991         if (vam->result_ready == 1)
8992           goto out;
8993       vam->retval = -99;
8994
8995     out:
8996       if (vam->retval == -99)
8997         errmsg ("timeout");
8998
8999       if (vam->async_errors > 0)
9000         {
9001           errmsg ("%d asynchronous errors", vam->async_errors);
9002           vam->retval = -98;
9003         }
9004       vam->async_errors = 0;
9005       after = vat_time_now (vam);
9006
9007       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9008       if (j > 0)
9009         count = j;
9010
9011       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9012              count, after - before, count / (after - before));
9013     }
9014   else
9015     {
9016       int ret;
9017
9018       /* Wait for a reply... */
9019       W (ret);
9020       return ret;
9021     }
9022
9023   /* Return the good/bad news */
9024   return (vam->retval);
9025 }
9026
9027 static int
9028 api_mpls_ip_bind_unbind (vat_main_t * vam)
9029 {
9030   unformat_input_t *i = vam->input;
9031   vl_api_mpls_ip_bind_unbind_t *mp;
9032   u32 ip_table_id = 0;
9033   u8 is_bind = 1;
9034   u8 is_ip4 = 1;
9035   ip4_address_t v4_address;
9036   ip6_address_t v6_address;
9037   u32 address_length;
9038   u8 address_set = 0;
9039   mpls_label_t local_label = MPLS_LABEL_INVALID;
9040   int ret;
9041
9042   /* Parse args required to build the message */
9043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9044     {
9045       if (unformat (i, "%U/%d", unformat_ip4_address,
9046                     &v4_address, &address_length))
9047         {
9048           is_ip4 = 1;
9049           address_set = 1;
9050         }
9051       else if (unformat (i, "%U/%d", unformat_ip6_address,
9052                          &v6_address, &address_length))
9053         {
9054           is_ip4 = 0;
9055           address_set = 1;
9056         }
9057       else if (unformat (i, "%d", &local_label))
9058         ;
9059       else if (unformat (i, "table-id %d", &ip_table_id))
9060         ;
9061       else if (unformat (i, "unbind"))
9062         is_bind = 0;
9063       else if (unformat (i, "bind"))
9064         is_bind = 1;
9065       else
9066         {
9067           clib_warning ("parse error '%U'", format_unformat_error, i);
9068           return -99;
9069         }
9070     }
9071
9072   if (!address_set)
9073     {
9074       errmsg ("IP addres not set");
9075       return -99;
9076     }
9077
9078   if (MPLS_LABEL_INVALID == local_label)
9079     {
9080       errmsg ("missing label");
9081       return -99;
9082     }
9083
9084   /* Construct the API message */
9085   M (MPLS_IP_BIND_UNBIND, mp);
9086
9087   mp->mb_is_bind = is_bind;
9088   mp->mb_is_ip4 = is_ip4;
9089   mp->mb_ip_table_id = ntohl (ip_table_id);
9090   mp->mb_mpls_table_id = 0;
9091   mp->mb_label = ntohl (local_label);
9092   mp->mb_address_length = address_length;
9093
9094   if (is_ip4)
9095     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9096   else
9097     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9098
9099   /* send it... */
9100   S (mp);
9101
9102   /* Wait for a reply... */
9103   W (ret);
9104   return ret;
9105 }
9106
9107 static int
9108 api_bier_table_add_del (vat_main_t * vam)
9109 {
9110   unformat_input_t *i = vam->input;
9111   vl_api_bier_table_add_del_t *mp;
9112   u8 is_add = 1;
9113   u32 set = 0, sub_domain = 0, hdr_len = 3;
9114   mpls_label_t local_label = MPLS_LABEL_INVALID;
9115   int ret;
9116
9117   /* Parse args required to build the message */
9118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9119     {
9120       if (unformat (i, "sub-domain %d", &sub_domain))
9121         ;
9122       else if (unformat (i, "set %d", &set))
9123         ;
9124       else if (unformat (i, "label %d", &local_label))
9125         ;
9126       else if (unformat (i, "hdr-len %d", &hdr_len))
9127         ;
9128       else if (unformat (i, "add"))
9129         is_add = 1;
9130       else if (unformat (i, "del"))
9131         is_add = 0;
9132       else
9133         {
9134           clib_warning ("parse error '%U'", format_unformat_error, i);
9135           return -99;
9136         }
9137     }
9138
9139   if (MPLS_LABEL_INVALID == local_label)
9140     {
9141       errmsg ("missing label\n");
9142       return -99;
9143     }
9144
9145   /* Construct the API message */
9146   M (BIER_TABLE_ADD_DEL, mp);
9147
9148   mp->bt_is_add = is_add;
9149   mp->bt_label = ntohl (local_label);
9150   mp->bt_tbl_id.bt_set = set;
9151   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9152   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9153
9154   /* send it... */
9155   S (mp);
9156
9157   /* Wait for a reply... */
9158   W (ret);
9159
9160   return (ret);
9161 }
9162
9163 static int
9164 api_bier_route_add_del (vat_main_t * vam)
9165 {
9166   unformat_input_t *i = vam->input;
9167   vl_api_bier_route_add_del_t *mp;
9168   u8 is_add = 1;
9169   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9170   ip4_address_t v4_next_hop_address;
9171   ip6_address_t v6_next_hop_address;
9172   u8 next_hop_set = 0;
9173   u8 next_hop_proto_is_ip4 = 1;
9174   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9175   int ret;
9176
9177   /* Parse args required to build the message */
9178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9179     {
9180       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9181         {
9182           next_hop_proto_is_ip4 = 1;
9183           next_hop_set = 1;
9184         }
9185       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9186         {
9187           next_hop_proto_is_ip4 = 0;
9188           next_hop_set = 1;
9189         }
9190       if (unformat (i, "sub-domain %d", &sub_domain))
9191         ;
9192       else if (unformat (i, "set %d", &set))
9193         ;
9194       else if (unformat (i, "hdr-len %d", &hdr_len))
9195         ;
9196       else if (unformat (i, "bp %d", &bp))
9197         ;
9198       else if (unformat (i, "add"))
9199         is_add = 1;
9200       else if (unformat (i, "del"))
9201         is_add = 0;
9202       else if (unformat (i, "out-label %d", &next_hop_out_label))
9203         ;
9204       else
9205         {
9206           clib_warning ("parse error '%U'", format_unformat_error, i);
9207           return -99;
9208         }
9209     }
9210
9211   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9212     {
9213       errmsg ("next hop / label set\n");
9214       return -99;
9215     }
9216   if (0 == bp)
9217     {
9218       errmsg ("bit=position not set\n");
9219       return -99;
9220     }
9221
9222   /* Construct the API message */
9223   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9224
9225   mp->br_is_add = is_add;
9226   mp->br_tbl_id.bt_set = set;
9227   mp->br_tbl_id.bt_sub_domain = sub_domain;
9228   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9229   mp->br_bp = ntohs (bp);
9230   mp->br_n_paths = 1;
9231   mp->br_paths[0].n_labels = 1;
9232   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9233   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9234
9235   if (next_hop_proto_is_ip4)
9236     {
9237       clib_memcpy (mp->br_paths[0].next_hop,
9238                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9239     }
9240   else
9241     {
9242       clib_memcpy (mp->br_paths[0].next_hop,
9243                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9244     }
9245
9246   /* send it... */
9247   S (mp);
9248
9249   /* Wait for a reply... */
9250   W (ret);
9251
9252   return (ret);
9253 }
9254
9255 static int
9256 api_proxy_arp_add_del (vat_main_t * vam)
9257 {
9258   unformat_input_t *i = vam->input;
9259   vl_api_proxy_arp_add_del_t *mp;
9260   u32 vrf_id = 0;
9261   u8 is_add = 1;
9262   ip4_address_t lo, hi;
9263   u8 range_set = 0;
9264   int ret;
9265
9266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9267     {
9268       if (unformat (i, "vrf %d", &vrf_id))
9269         ;
9270       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9271                          unformat_ip4_address, &hi))
9272         range_set = 1;
9273       else if (unformat (i, "del"))
9274         is_add = 0;
9275       else
9276         {
9277           clib_warning ("parse error '%U'", format_unformat_error, i);
9278           return -99;
9279         }
9280     }
9281
9282   if (range_set == 0)
9283     {
9284       errmsg ("address range not set");
9285       return -99;
9286     }
9287
9288   M (PROXY_ARP_ADD_DEL, mp);
9289
9290   mp->vrf_id = ntohl (vrf_id);
9291   mp->is_add = is_add;
9292   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
9293   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
9294
9295   S (mp);
9296   W (ret);
9297   return ret;
9298 }
9299
9300 static int
9301 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9302 {
9303   unformat_input_t *i = vam->input;
9304   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9305   u32 sw_if_index;
9306   u8 enable = 1;
9307   u8 sw_if_index_set = 0;
9308   int ret;
9309
9310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9311     {
9312       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9313         sw_if_index_set = 1;
9314       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9315         sw_if_index_set = 1;
9316       else if (unformat (i, "enable"))
9317         enable = 1;
9318       else if (unformat (i, "disable"))
9319         enable = 0;
9320       else
9321         {
9322           clib_warning ("parse error '%U'", format_unformat_error, i);
9323           return -99;
9324         }
9325     }
9326
9327   if (sw_if_index_set == 0)
9328     {
9329       errmsg ("missing interface name or sw_if_index");
9330       return -99;
9331     }
9332
9333   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9334
9335   mp->sw_if_index = ntohl (sw_if_index);
9336   mp->enable_disable = enable;
9337
9338   S (mp);
9339   W (ret);
9340   return ret;
9341 }
9342
9343 static int
9344 api_mpls_tunnel_add_del (vat_main_t * vam)
9345 {
9346   unformat_input_t *i = vam->input;
9347   vl_api_mpls_tunnel_add_del_t *mp;
9348
9349   u8 is_add = 1;
9350   u8 l2_only = 0;
9351   u32 sw_if_index = ~0;
9352   u32 next_hop_sw_if_index = ~0;
9353   u32 next_hop_proto_is_ip4 = 1;
9354
9355   u32 next_hop_table_id = 0;
9356   ip4_address_t v4_next_hop_address = {
9357     .as_u32 = 0,
9358   };
9359   ip6_address_t v6_next_hop_address = { {0} };
9360   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9361   int ret;
9362
9363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9364     {
9365       if (unformat (i, "add"))
9366         is_add = 1;
9367       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9368         is_add = 0;
9369       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9370         ;
9371       else if (unformat (i, "via %U",
9372                          unformat_ip4_address, &v4_next_hop_address))
9373         {
9374           next_hop_proto_is_ip4 = 1;
9375         }
9376       else if (unformat (i, "via %U",
9377                          unformat_ip6_address, &v6_next_hop_address))
9378         {
9379           next_hop_proto_is_ip4 = 0;
9380         }
9381       else if (unformat (i, "l2-only"))
9382         l2_only = 1;
9383       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9384         ;
9385       else if (unformat (i, "out-label %d", &next_hop_out_label))
9386         vec_add1 (labels, ntohl (next_hop_out_label));
9387       else
9388         {
9389           clib_warning ("parse error '%U'", format_unformat_error, i);
9390           return -99;
9391         }
9392     }
9393
9394   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9395
9396   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9397   mp->mt_sw_if_index = ntohl (sw_if_index);
9398   mp->mt_is_add = is_add;
9399   mp->mt_l2_only = l2_only;
9400   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9401   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9402
9403   mp->mt_next_hop_n_out_labels = vec_len (labels);
9404
9405   if (0 != mp->mt_next_hop_n_out_labels)
9406     {
9407       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9408                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9409       vec_free (labels);
9410     }
9411
9412   if (next_hop_proto_is_ip4)
9413     {
9414       clib_memcpy (mp->mt_next_hop,
9415                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9416     }
9417   else
9418     {
9419       clib_memcpy (mp->mt_next_hop,
9420                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9421     }
9422
9423   S (mp);
9424   W (ret);
9425   return ret;
9426 }
9427
9428 static int
9429 api_sw_interface_set_unnumbered (vat_main_t * vam)
9430 {
9431   unformat_input_t *i = vam->input;
9432   vl_api_sw_interface_set_unnumbered_t *mp;
9433   u32 sw_if_index;
9434   u32 unnum_sw_index = ~0;
9435   u8 is_add = 1;
9436   u8 sw_if_index_set = 0;
9437   int ret;
9438
9439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9440     {
9441       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9442         sw_if_index_set = 1;
9443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9444         sw_if_index_set = 1;
9445       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9446         ;
9447       else if (unformat (i, "del"))
9448         is_add = 0;
9449       else
9450         {
9451           clib_warning ("parse error '%U'", format_unformat_error, i);
9452           return -99;
9453         }
9454     }
9455
9456   if (sw_if_index_set == 0)
9457     {
9458       errmsg ("missing interface name or sw_if_index");
9459       return -99;
9460     }
9461
9462   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9463
9464   mp->sw_if_index = ntohl (sw_if_index);
9465   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9466   mp->is_add = is_add;
9467
9468   S (mp);
9469   W (ret);
9470   return ret;
9471 }
9472
9473 static int
9474 api_ip_neighbor_add_del (vat_main_t * vam)
9475 {
9476   unformat_input_t *i = vam->input;
9477   vl_api_ip_neighbor_add_del_t *mp;
9478   u32 sw_if_index;
9479   u8 sw_if_index_set = 0;
9480   u8 is_add = 1;
9481   u8 is_static = 0;
9482   u8 is_no_fib_entry = 0;
9483   u8 mac_address[6];
9484   u8 mac_set = 0;
9485   u8 v4_address_set = 0;
9486   u8 v6_address_set = 0;
9487   ip4_address_t v4address;
9488   ip6_address_t v6address;
9489   int ret;
9490
9491   memset (mac_address, 0, sizeof (mac_address));
9492
9493   /* Parse args required to build the message */
9494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9495     {
9496       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9497         {
9498           mac_set = 1;
9499         }
9500       else if (unformat (i, "del"))
9501         is_add = 0;
9502       else
9503         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9504         sw_if_index_set = 1;
9505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9506         sw_if_index_set = 1;
9507       else if (unformat (i, "is_static"))
9508         is_static = 1;
9509       else if (unformat (i, "no-fib-entry"))
9510         is_no_fib_entry = 1;
9511       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9512         v4_address_set = 1;
9513       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9514         v6_address_set = 1;
9515       else
9516         {
9517           clib_warning ("parse error '%U'", format_unformat_error, i);
9518           return -99;
9519         }
9520     }
9521
9522   if (sw_if_index_set == 0)
9523     {
9524       errmsg ("missing interface name or sw_if_index");
9525       return -99;
9526     }
9527   if (v4_address_set && v6_address_set)
9528     {
9529       errmsg ("both v4 and v6 addresses set");
9530       return -99;
9531     }
9532   if (!v4_address_set && !v6_address_set)
9533     {
9534       errmsg ("no address set");
9535       return -99;
9536     }
9537
9538   /* Construct the API message */
9539   M (IP_NEIGHBOR_ADD_DEL, mp);
9540
9541   mp->sw_if_index = ntohl (sw_if_index);
9542   mp->is_add = is_add;
9543   mp->is_static = is_static;
9544   mp->is_no_adj_fib = is_no_fib_entry;
9545   if (mac_set)
9546     clib_memcpy (mp->mac_address, mac_address, 6);
9547   if (v6_address_set)
9548     {
9549       mp->is_ipv6 = 1;
9550       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9551     }
9552   else
9553     {
9554       /* mp->is_ipv6 = 0; via memset in M macro above */
9555       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9556     }
9557
9558   /* send it... */
9559   S (mp);
9560
9561   /* Wait for a reply, return good/bad news  */
9562   W (ret);
9563   return ret;
9564 }
9565
9566 static int
9567 api_create_vlan_subif (vat_main_t * vam)
9568 {
9569   unformat_input_t *i = vam->input;
9570   vl_api_create_vlan_subif_t *mp;
9571   u32 sw_if_index;
9572   u8 sw_if_index_set = 0;
9573   u32 vlan_id;
9574   u8 vlan_id_set = 0;
9575   int ret;
9576
9577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9578     {
9579       if (unformat (i, "sw_if_index %d", &sw_if_index))
9580         sw_if_index_set = 1;
9581       else
9582         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9583         sw_if_index_set = 1;
9584       else if (unformat (i, "vlan %d", &vlan_id))
9585         vlan_id_set = 1;
9586       else
9587         {
9588           clib_warning ("parse error '%U'", format_unformat_error, i);
9589           return -99;
9590         }
9591     }
9592
9593   if (sw_if_index_set == 0)
9594     {
9595       errmsg ("missing interface name or sw_if_index");
9596       return -99;
9597     }
9598
9599   if (vlan_id_set == 0)
9600     {
9601       errmsg ("missing vlan_id");
9602       return -99;
9603     }
9604   M (CREATE_VLAN_SUBIF, mp);
9605
9606   mp->sw_if_index = ntohl (sw_if_index);
9607   mp->vlan_id = ntohl (vlan_id);
9608
9609   S (mp);
9610   W (ret);
9611   return ret;
9612 }
9613
9614 #define foreach_create_subif_bit                \
9615 _(no_tags)                                      \
9616 _(one_tag)                                      \
9617 _(two_tags)                                     \
9618 _(dot1ad)                                       \
9619 _(exact_match)                                  \
9620 _(default_sub)                                  \
9621 _(outer_vlan_id_any)                            \
9622 _(inner_vlan_id_any)
9623
9624 static int
9625 api_create_subif (vat_main_t * vam)
9626 {
9627   unformat_input_t *i = vam->input;
9628   vl_api_create_subif_t *mp;
9629   u32 sw_if_index;
9630   u8 sw_if_index_set = 0;
9631   u32 sub_id;
9632   u8 sub_id_set = 0;
9633   u32 no_tags = 0;
9634   u32 one_tag = 0;
9635   u32 two_tags = 0;
9636   u32 dot1ad = 0;
9637   u32 exact_match = 0;
9638   u32 default_sub = 0;
9639   u32 outer_vlan_id_any = 0;
9640   u32 inner_vlan_id_any = 0;
9641   u32 tmp;
9642   u16 outer_vlan_id = 0;
9643   u16 inner_vlan_id = 0;
9644   int ret;
9645
9646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9647     {
9648       if (unformat (i, "sw_if_index %d", &sw_if_index))
9649         sw_if_index_set = 1;
9650       else
9651         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9652         sw_if_index_set = 1;
9653       else if (unformat (i, "sub_id %d", &sub_id))
9654         sub_id_set = 1;
9655       else if (unformat (i, "outer_vlan_id %d", &tmp))
9656         outer_vlan_id = tmp;
9657       else if (unformat (i, "inner_vlan_id %d", &tmp))
9658         inner_vlan_id = tmp;
9659
9660 #define _(a) else if (unformat (i, #a)) a = 1 ;
9661       foreach_create_subif_bit
9662 #undef _
9663         else
9664         {
9665           clib_warning ("parse error '%U'", format_unformat_error, i);
9666           return -99;
9667         }
9668     }
9669
9670   if (sw_if_index_set == 0)
9671     {
9672       errmsg ("missing interface name or sw_if_index");
9673       return -99;
9674     }
9675
9676   if (sub_id_set == 0)
9677     {
9678       errmsg ("missing sub_id");
9679       return -99;
9680     }
9681   M (CREATE_SUBIF, mp);
9682
9683   mp->sw_if_index = ntohl (sw_if_index);
9684   mp->sub_id = ntohl (sub_id);
9685
9686 #define _(a) mp->a = a;
9687   foreach_create_subif_bit;
9688 #undef _
9689
9690   mp->outer_vlan_id = ntohs (outer_vlan_id);
9691   mp->inner_vlan_id = ntohs (inner_vlan_id);
9692
9693   S (mp);
9694   W (ret);
9695   return ret;
9696 }
9697
9698 static int
9699 api_oam_add_del (vat_main_t * vam)
9700 {
9701   unformat_input_t *i = vam->input;
9702   vl_api_oam_add_del_t *mp;
9703   u32 vrf_id = 0;
9704   u8 is_add = 1;
9705   ip4_address_t src, dst;
9706   u8 src_set = 0;
9707   u8 dst_set = 0;
9708   int ret;
9709
9710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9711     {
9712       if (unformat (i, "vrf %d", &vrf_id))
9713         ;
9714       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9715         src_set = 1;
9716       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9717         dst_set = 1;
9718       else if (unformat (i, "del"))
9719         is_add = 0;
9720       else
9721         {
9722           clib_warning ("parse error '%U'", format_unformat_error, i);
9723           return -99;
9724         }
9725     }
9726
9727   if (src_set == 0)
9728     {
9729       errmsg ("missing src addr");
9730       return -99;
9731     }
9732
9733   if (dst_set == 0)
9734     {
9735       errmsg ("missing dst addr");
9736       return -99;
9737     }
9738
9739   M (OAM_ADD_DEL, mp);
9740
9741   mp->vrf_id = ntohl (vrf_id);
9742   mp->is_add = is_add;
9743   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9744   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9745
9746   S (mp);
9747   W (ret);
9748   return ret;
9749 }
9750
9751 static int
9752 api_reset_fib (vat_main_t * vam)
9753 {
9754   unformat_input_t *i = vam->input;
9755   vl_api_reset_fib_t *mp;
9756   u32 vrf_id = 0;
9757   u8 is_ipv6 = 0;
9758   u8 vrf_id_set = 0;
9759
9760   int ret;
9761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9762     {
9763       if (unformat (i, "vrf %d", &vrf_id))
9764         vrf_id_set = 1;
9765       else if (unformat (i, "ipv6"))
9766         is_ipv6 = 1;
9767       else
9768         {
9769           clib_warning ("parse error '%U'", format_unformat_error, i);
9770           return -99;
9771         }
9772     }
9773
9774   if (vrf_id_set == 0)
9775     {
9776       errmsg ("missing vrf id");
9777       return -99;
9778     }
9779
9780   M (RESET_FIB, mp);
9781
9782   mp->vrf_id = ntohl (vrf_id);
9783   mp->is_ipv6 = is_ipv6;
9784
9785   S (mp);
9786   W (ret);
9787   return ret;
9788 }
9789
9790 static int
9791 api_dhcp_proxy_config (vat_main_t * vam)
9792 {
9793   unformat_input_t *i = vam->input;
9794   vl_api_dhcp_proxy_config_t *mp;
9795   u32 rx_vrf_id = 0;
9796   u32 server_vrf_id = 0;
9797   u8 is_add = 1;
9798   u8 v4_address_set = 0;
9799   u8 v6_address_set = 0;
9800   ip4_address_t v4address;
9801   ip6_address_t v6address;
9802   u8 v4_src_address_set = 0;
9803   u8 v6_src_address_set = 0;
9804   ip4_address_t v4srcaddress;
9805   ip6_address_t v6srcaddress;
9806   int ret;
9807
9808   /* Parse args required to build the message */
9809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9810     {
9811       if (unformat (i, "del"))
9812         is_add = 0;
9813       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9814         ;
9815       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9816         ;
9817       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9818         v4_address_set = 1;
9819       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9820         v6_address_set = 1;
9821       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9822         v4_src_address_set = 1;
9823       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9824         v6_src_address_set = 1;
9825       else
9826         break;
9827     }
9828
9829   if (v4_address_set && v6_address_set)
9830     {
9831       errmsg ("both v4 and v6 server addresses set");
9832       return -99;
9833     }
9834   if (!v4_address_set && !v6_address_set)
9835     {
9836       errmsg ("no server addresses set");
9837       return -99;
9838     }
9839
9840   if (v4_src_address_set && v6_src_address_set)
9841     {
9842       errmsg ("both v4 and v6  src addresses set");
9843       return -99;
9844     }
9845   if (!v4_src_address_set && !v6_src_address_set)
9846     {
9847       errmsg ("no src addresses set");
9848       return -99;
9849     }
9850
9851   if (!(v4_src_address_set && v4_address_set) &&
9852       !(v6_src_address_set && v6_address_set))
9853     {
9854       errmsg ("no matching server and src addresses set");
9855       return -99;
9856     }
9857
9858   /* Construct the API message */
9859   M (DHCP_PROXY_CONFIG, mp);
9860
9861   mp->is_add = is_add;
9862   mp->rx_vrf_id = ntohl (rx_vrf_id);
9863   mp->server_vrf_id = ntohl (server_vrf_id);
9864   if (v6_address_set)
9865     {
9866       mp->is_ipv6 = 1;
9867       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9868       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9869     }
9870   else
9871     {
9872       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9873       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9874     }
9875
9876   /* send it... */
9877   S (mp);
9878
9879   /* Wait for a reply, return good/bad news  */
9880   W (ret);
9881   return ret;
9882 }
9883
9884 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9885 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9886
9887 static void
9888 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9889 {
9890   vat_main_t *vam = &vat_main;
9891   u32 i, count = mp->count;
9892   vl_api_dhcp_server_t *s;
9893
9894   if (mp->is_ipv6)
9895     print (vam->ofp,
9896            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9897            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9898            ntohl (mp->rx_vrf_id),
9899            format_ip6_address, mp->dhcp_src_address,
9900            mp->vss_type, mp->vss_vpn_ascii_id,
9901            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9902   else
9903     print (vam->ofp,
9904            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9905            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9906            ntohl (mp->rx_vrf_id),
9907            format_ip4_address, mp->dhcp_src_address,
9908            mp->vss_type, mp->vss_vpn_ascii_id,
9909            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9910
9911   for (i = 0; i < count; i++)
9912     {
9913       s = &mp->servers[i];
9914
9915       if (mp->is_ipv6)
9916         print (vam->ofp,
9917                " Server Table-ID %d, Server Address %U",
9918                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9919       else
9920         print (vam->ofp,
9921                " Server Table-ID %d, Server Address %U",
9922                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9923     }
9924 }
9925
9926 static void vl_api_dhcp_proxy_details_t_handler_json
9927   (vl_api_dhcp_proxy_details_t * mp)
9928 {
9929   vat_main_t *vam = &vat_main;
9930   vat_json_node_t *node = NULL;
9931   u32 i, count = mp->count;
9932   struct in_addr ip4;
9933   struct in6_addr ip6;
9934   vl_api_dhcp_server_t *s;
9935
9936   if (VAT_JSON_ARRAY != vam->json_tree.type)
9937     {
9938       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9939       vat_json_init_array (&vam->json_tree);
9940     }
9941   node = vat_json_array_add (&vam->json_tree);
9942
9943   vat_json_init_object (node);
9944   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9945   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9946                              sizeof (mp->vss_type));
9947   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9948                                    mp->vss_vpn_ascii_id);
9949   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9950   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9951
9952   if (mp->is_ipv6)
9953     {
9954       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9955       vat_json_object_add_ip6 (node, "src_address", ip6);
9956     }
9957   else
9958     {
9959       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9960       vat_json_object_add_ip4 (node, "src_address", ip4);
9961     }
9962
9963   for (i = 0; i < count; i++)
9964     {
9965       s = &mp->servers[i];
9966
9967       vat_json_object_add_uint (node, "server-table-id",
9968                                 ntohl (s->server_vrf_id));
9969
9970       if (mp->is_ipv6)
9971         {
9972           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9973           vat_json_object_add_ip4 (node, "src_address", ip4);
9974         }
9975       else
9976         {
9977           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9978           vat_json_object_add_ip6 (node, "server_address", ip6);
9979         }
9980     }
9981 }
9982
9983 static int
9984 api_dhcp_proxy_dump (vat_main_t * vam)
9985 {
9986   unformat_input_t *i = vam->input;
9987   vl_api_control_ping_t *mp_ping;
9988   vl_api_dhcp_proxy_dump_t *mp;
9989   u8 is_ipv6 = 0;
9990   int ret;
9991
9992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9993     {
9994       if (unformat (i, "ipv6"))
9995         is_ipv6 = 1;
9996       else
9997         {
9998           clib_warning ("parse error '%U'", format_unformat_error, i);
9999           return -99;
10000         }
10001     }
10002
10003   M (DHCP_PROXY_DUMP, mp);
10004
10005   mp->is_ip6 = is_ipv6;
10006   S (mp);
10007
10008   /* Use a control ping for synchronization */
10009   MPING (CONTROL_PING, mp_ping);
10010   S (mp_ping);
10011
10012   W (ret);
10013   return ret;
10014 }
10015
10016 static int
10017 api_dhcp_proxy_set_vss (vat_main_t * vam)
10018 {
10019   unformat_input_t *i = vam->input;
10020   vl_api_dhcp_proxy_set_vss_t *mp;
10021   u8 is_ipv6 = 0;
10022   u8 is_add = 1;
10023   u32 tbl_id = ~0;
10024   u8 vss_type = VSS_TYPE_DEFAULT;
10025   u8 *vpn_ascii_id = 0;
10026   u32 oui = 0;
10027   u32 fib_id = 0;
10028   int ret;
10029
10030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10031     {
10032       if (unformat (i, "tbl_id %d", &tbl_id))
10033         ;
10034       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10035         vss_type = VSS_TYPE_ASCII;
10036       else if (unformat (i, "fib_id %d", &fib_id))
10037         vss_type = VSS_TYPE_VPN_ID;
10038       else if (unformat (i, "oui %d", &oui))
10039         vss_type = VSS_TYPE_VPN_ID;
10040       else if (unformat (i, "ipv6"))
10041         is_ipv6 = 1;
10042       else if (unformat (i, "del"))
10043         is_add = 0;
10044       else
10045         break;
10046     }
10047
10048   if (tbl_id == ~0)
10049     {
10050       errmsg ("missing tbl_id ");
10051       vec_free (vpn_ascii_id);
10052       return -99;
10053     }
10054
10055   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10056     {
10057       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10058       vec_free (vpn_ascii_id);
10059       return -99;
10060     }
10061
10062   M (DHCP_PROXY_SET_VSS, mp);
10063   mp->tbl_id = ntohl (tbl_id);
10064   mp->vss_type = vss_type;
10065   if (vpn_ascii_id)
10066     {
10067       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10068       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10069     }
10070   mp->vpn_index = ntohl (fib_id);
10071   mp->oui = ntohl (oui);
10072   mp->is_ipv6 = is_ipv6;
10073   mp->is_add = is_add;
10074
10075   S (mp);
10076   W (ret);
10077
10078   vec_free (vpn_ascii_id);
10079   return ret;
10080 }
10081
10082 static int
10083 api_dhcp_client_config (vat_main_t * vam)
10084 {
10085   unformat_input_t *i = vam->input;
10086   vl_api_dhcp_client_config_t *mp;
10087   u32 sw_if_index;
10088   u8 sw_if_index_set = 0;
10089   u8 is_add = 1;
10090   u8 *hostname = 0;
10091   u8 disable_event = 0;
10092   int ret;
10093
10094   /* Parse args required to build the message */
10095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10096     {
10097       if (unformat (i, "del"))
10098         is_add = 0;
10099       else
10100         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10101         sw_if_index_set = 1;
10102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10103         sw_if_index_set = 1;
10104       else if (unformat (i, "hostname %s", &hostname))
10105         ;
10106       else if (unformat (i, "disable_event"))
10107         disable_event = 1;
10108       else
10109         break;
10110     }
10111
10112   if (sw_if_index_set == 0)
10113     {
10114       errmsg ("missing interface name or sw_if_index");
10115       return -99;
10116     }
10117
10118   if (vec_len (hostname) > 63)
10119     {
10120       errmsg ("hostname too long");
10121     }
10122   vec_add1 (hostname, 0);
10123
10124   /* Construct the API message */
10125   M (DHCP_CLIENT_CONFIG, mp);
10126
10127   mp->sw_if_index = htonl (sw_if_index);
10128   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
10129   vec_free (hostname);
10130   mp->is_add = is_add;
10131   mp->want_dhcp_event = disable_event ? 0 : 1;
10132   mp->pid = htonl (getpid ());
10133
10134   /* send it... */
10135   S (mp);
10136
10137   /* Wait for a reply, return good/bad news  */
10138   W (ret);
10139   return ret;
10140 }
10141
10142 static int
10143 api_set_ip_flow_hash (vat_main_t * vam)
10144 {
10145   unformat_input_t *i = vam->input;
10146   vl_api_set_ip_flow_hash_t *mp;
10147   u32 vrf_id = 0;
10148   u8 is_ipv6 = 0;
10149   u8 vrf_id_set = 0;
10150   u8 src = 0;
10151   u8 dst = 0;
10152   u8 sport = 0;
10153   u8 dport = 0;
10154   u8 proto = 0;
10155   u8 reverse = 0;
10156   int ret;
10157
10158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10159     {
10160       if (unformat (i, "vrf %d", &vrf_id))
10161         vrf_id_set = 1;
10162       else if (unformat (i, "ipv6"))
10163         is_ipv6 = 1;
10164       else if (unformat (i, "src"))
10165         src = 1;
10166       else if (unformat (i, "dst"))
10167         dst = 1;
10168       else if (unformat (i, "sport"))
10169         sport = 1;
10170       else if (unformat (i, "dport"))
10171         dport = 1;
10172       else if (unformat (i, "proto"))
10173         proto = 1;
10174       else if (unformat (i, "reverse"))
10175         reverse = 1;
10176
10177       else
10178         {
10179           clib_warning ("parse error '%U'", format_unformat_error, i);
10180           return -99;
10181         }
10182     }
10183
10184   if (vrf_id_set == 0)
10185     {
10186       errmsg ("missing vrf id");
10187       return -99;
10188     }
10189
10190   M (SET_IP_FLOW_HASH, mp);
10191   mp->src = src;
10192   mp->dst = dst;
10193   mp->sport = sport;
10194   mp->dport = dport;
10195   mp->proto = proto;
10196   mp->reverse = reverse;
10197   mp->vrf_id = ntohl (vrf_id);
10198   mp->is_ipv6 = is_ipv6;
10199
10200   S (mp);
10201   W (ret);
10202   return ret;
10203 }
10204
10205 static int
10206 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10207 {
10208   unformat_input_t *i = vam->input;
10209   vl_api_sw_interface_ip6_enable_disable_t *mp;
10210   u32 sw_if_index;
10211   u8 sw_if_index_set = 0;
10212   u8 enable = 0;
10213   int ret;
10214
10215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10216     {
10217       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10218         sw_if_index_set = 1;
10219       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10220         sw_if_index_set = 1;
10221       else if (unformat (i, "enable"))
10222         enable = 1;
10223       else if (unformat (i, "disable"))
10224         enable = 0;
10225       else
10226         {
10227           clib_warning ("parse error '%U'", format_unformat_error, i);
10228           return -99;
10229         }
10230     }
10231
10232   if (sw_if_index_set == 0)
10233     {
10234       errmsg ("missing interface name or sw_if_index");
10235       return -99;
10236     }
10237
10238   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10239
10240   mp->sw_if_index = ntohl (sw_if_index);
10241   mp->enable = enable;
10242
10243   S (mp);
10244   W (ret);
10245   return ret;
10246 }
10247
10248 static int
10249 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10250 {
10251   unformat_input_t *i = vam->input;
10252   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10253   u32 sw_if_index;
10254   u8 sw_if_index_set = 0;
10255   u8 v6_address_set = 0;
10256   ip6_address_t v6address;
10257   int ret;
10258
10259   /* Parse args required to build the message */
10260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10261     {
10262       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10263         sw_if_index_set = 1;
10264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10265         sw_if_index_set = 1;
10266       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10267         v6_address_set = 1;
10268       else
10269         break;
10270     }
10271
10272   if (sw_if_index_set == 0)
10273     {
10274       errmsg ("missing interface name or sw_if_index");
10275       return -99;
10276     }
10277   if (!v6_address_set)
10278     {
10279       errmsg ("no address set");
10280       return -99;
10281     }
10282
10283   /* Construct the API message */
10284   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10285
10286   mp->sw_if_index = ntohl (sw_if_index);
10287   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10288
10289   /* send it... */
10290   S (mp);
10291
10292   /* Wait for a reply, return good/bad news  */
10293   W (ret);
10294   return ret;
10295 }
10296
10297 static int
10298 api_ip6nd_proxy_add_del (vat_main_t * vam)
10299 {
10300   unformat_input_t *i = vam->input;
10301   vl_api_ip6nd_proxy_add_del_t *mp;
10302   u32 sw_if_index = ~0;
10303   u8 v6_address_set = 0;
10304   ip6_address_t v6address;
10305   u8 is_del = 0;
10306   int ret;
10307
10308   /* Parse args required to build the message */
10309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10310     {
10311       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10312         ;
10313       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10314         ;
10315       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10316         v6_address_set = 1;
10317       if (unformat (i, "del"))
10318         is_del = 1;
10319       else
10320         {
10321           clib_warning ("parse error '%U'", format_unformat_error, i);
10322           return -99;
10323         }
10324     }
10325
10326   if (sw_if_index == ~0)
10327     {
10328       errmsg ("missing interface name or sw_if_index");
10329       return -99;
10330     }
10331   if (!v6_address_set)
10332     {
10333       errmsg ("no address set");
10334       return -99;
10335     }
10336
10337   /* Construct the API message */
10338   M (IP6ND_PROXY_ADD_DEL, mp);
10339
10340   mp->is_del = is_del;
10341   mp->sw_if_index = ntohl (sw_if_index);
10342   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10343
10344   /* send it... */
10345   S (mp);
10346
10347   /* Wait for a reply, return good/bad news  */
10348   W (ret);
10349   return ret;
10350 }
10351
10352 static int
10353 api_ip6nd_proxy_dump (vat_main_t * vam)
10354 {
10355   vl_api_ip6nd_proxy_dump_t *mp;
10356   vl_api_control_ping_t *mp_ping;
10357   int ret;
10358
10359   M (IP6ND_PROXY_DUMP, mp);
10360
10361   S (mp);
10362
10363   /* Use a control ping for synchronization */
10364   MPING (CONTROL_PING, mp_ping);
10365   S (mp_ping);
10366
10367   W (ret);
10368   return ret;
10369 }
10370
10371 static void vl_api_ip6nd_proxy_details_t_handler
10372   (vl_api_ip6nd_proxy_details_t * mp)
10373 {
10374   vat_main_t *vam = &vat_main;
10375
10376   print (vam->ofp, "host %U sw_if_index %d",
10377          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10378 }
10379
10380 static void vl_api_ip6nd_proxy_details_t_handler_json
10381   (vl_api_ip6nd_proxy_details_t * mp)
10382 {
10383   vat_main_t *vam = &vat_main;
10384   struct in6_addr ip6;
10385   vat_json_node_t *node = NULL;
10386
10387   if (VAT_JSON_ARRAY != vam->json_tree.type)
10388     {
10389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10390       vat_json_init_array (&vam->json_tree);
10391     }
10392   node = vat_json_array_add (&vam->json_tree);
10393
10394   vat_json_init_object (node);
10395   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10396
10397   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10398   vat_json_object_add_ip6 (node, "host", ip6);
10399 }
10400
10401 static int
10402 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10403 {
10404   unformat_input_t *i = vam->input;
10405   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10406   u32 sw_if_index;
10407   u8 sw_if_index_set = 0;
10408   u32 address_length = 0;
10409   u8 v6_address_set = 0;
10410   ip6_address_t v6address;
10411   u8 use_default = 0;
10412   u8 no_advertise = 0;
10413   u8 off_link = 0;
10414   u8 no_autoconfig = 0;
10415   u8 no_onlink = 0;
10416   u8 is_no = 0;
10417   u32 val_lifetime = 0;
10418   u32 pref_lifetime = 0;
10419   int ret;
10420
10421   /* Parse args required to build the message */
10422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10423     {
10424       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10425         sw_if_index_set = 1;
10426       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10427         sw_if_index_set = 1;
10428       else if (unformat (i, "%U/%d",
10429                          unformat_ip6_address, &v6address, &address_length))
10430         v6_address_set = 1;
10431       else if (unformat (i, "val_life %d", &val_lifetime))
10432         ;
10433       else if (unformat (i, "pref_life %d", &pref_lifetime))
10434         ;
10435       else if (unformat (i, "def"))
10436         use_default = 1;
10437       else if (unformat (i, "noadv"))
10438         no_advertise = 1;
10439       else if (unformat (i, "offl"))
10440         off_link = 1;
10441       else if (unformat (i, "noauto"))
10442         no_autoconfig = 1;
10443       else if (unformat (i, "nolink"))
10444         no_onlink = 1;
10445       else if (unformat (i, "isno"))
10446         is_no = 1;
10447       else
10448         {
10449           clib_warning ("parse error '%U'", format_unformat_error, i);
10450           return -99;
10451         }
10452     }
10453
10454   if (sw_if_index_set == 0)
10455     {
10456       errmsg ("missing interface name or sw_if_index");
10457       return -99;
10458     }
10459   if (!v6_address_set)
10460     {
10461       errmsg ("no address set");
10462       return -99;
10463     }
10464
10465   /* Construct the API message */
10466   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10467
10468   mp->sw_if_index = ntohl (sw_if_index);
10469   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10470   mp->address_length = address_length;
10471   mp->use_default = use_default;
10472   mp->no_advertise = no_advertise;
10473   mp->off_link = off_link;
10474   mp->no_autoconfig = no_autoconfig;
10475   mp->no_onlink = no_onlink;
10476   mp->is_no = is_no;
10477   mp->val_lifetime = ntohl (val_lifetime);
10478   mp->pref_lifetime = ntohl (pref_lifetime);
10479
10480   /* send it... */
10481   S (mp);
10482
10483   /* Wait for a reply, return good/bad news  */
10484   W (ret);
10485   return ret;
10486 }
10487
10488 static int
10489 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10490 {
10491   unformat_input_t *i = vam->input;
10492   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10493   u32 sw_if_index;
10494   u8 sw_if_index_set = 0;
10495   u8 suppress = 0;
10496   u8 managed = 0;
10497   u8 other = 0;
10498   u8 ll_option = 0;
10499   u8 send_unicast = 0;
10500   u8 cease = 0;
10501   u8 is_no = 0;
10502   u8 default_router = 0;
10503   u32 max_interval = 0;
10504   u32 min_interval = 0;
10505   u32 lifetime = 0;
10506   u32 initial_count = 0;
10507   u32 initial_interval = 0;
10508   int ret;
10509
10510
10511   /* Parse args required to build the message */
10512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10513     {
10514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10515         sw_if_index_set = 1;
10516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10517         sw_if_index_set = 1;
10518       else if (unformat (i, "maxint %d", &max_interval))
10519         ;
10520       else if (unformat (i, "minint %d", &min_interval))
10521         ;
10522       else if (unformat (i, "life %d", &lifetime))
10523         ;
10524       else if (unformat (i, "count %d", &initial_count))
10525         ;
10526       else if (unformat (i, "interval %d", &initial_interval))
10527         ;
10528       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10529         suppress = 1;
10530       else if (unformat (i, "managed"))
10531         managed = 1;
10532       else if (unformat (i, "other"))
10533         other = 1;
10534       else if (unformat (i, "ll"))
10535         ll_option = 1;
10536       else if (unformat (i, "send"))
10537         send_unicast = 1;
10538       else if (unformat (i, "cease"))
10539         cease = 1;
10540       else if (unformat (i, "isno"))
10541         is_no = 1;
10542       else if (unformat (i, "def"))
10543         default_router = 1;
10544       else
10545         {
10546           clib_warning ("parse error '%U'", format_unformat_error, i);
10547           return -99;
10548         }
10549     }
10550
10551   if (sw_if_index_set == 0)
10552     {
10553       errmsg ("missing interface name or sw_if_index");
10554       return -99;
10555     }
10556
10557   /* Construct the API message */
10558   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10559
10560   mp->sw_if_index = ntohl (sw_if_index);
10561   mp->max_interval = ntohl (max_interval);
10562   mp->min_interval = ntohl (min_interval);
10563   mp->lifetime = ntohl (lifetime);
10564   mp->initial_count = ntohl (initial_count);
10565   mp->initial_interval = ntohl (initial_interval);
10566   mp->suppress = suppress;
10567   mp->managed = managed;
10568   mp->other = other;
10569   mp->ll_option = ll_option;
10570   mp->send_unicast = send_unicast;
10571   mp->cease = cease;
10572   mp->is_no = is_no;
10573   mp->default_router = default_router;
10574
10575   /* send it... */
10576   S (mp);
10577
10578   /* Wait for a reply, return good/bad news  */
10579   W (ret);
10580   return ret;
10581 }
10582
10583 static int
10584 api_set_arp_neighbor_limit (vat_main_t * vam)
10585 {
10586   unformat_input_t *i = vam->input;
10587   vl_api_set_arp_neighbor_limit_t *mp;
10588   u32 arp_nbr_limit;
10589   u8 limit_set = 0;
10590   u8 is_ipv6 = 0;
10591   int ret;
10592
10593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10594     {
10595       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10596         limit_set = 1;
10597       else if (unformat (i, "ipv6"))
10598         is_ipv6 = 1;
10599       else
10600         {
10601           clib_warning ("parse error '%U'", format_unformat_error, i);
10602           return -99;
10603         }
10604     }
10605
10606   if (limit_set == 0)
10607     {
10608       errmsg ("missing limit value");
10609       return -99;
10610     }
10611
10612   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10613
10614   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10615   mp->is_ipv6 = is_ipv6;
10616
10617   S (mp);
10618   W (ret);
10619   return ret;
10620 }
10621
10622 static int
10623 api_l2_patch_add_del (vat_main_t * vam)
10624 {
10625   unformat_input_t *i = vam->input;
10626   vl_api_l2_patch_add_del_t *mp;
10627   u32 rx_sw_if_index;
10628   u8 rx_sw_if_index_set = 0;
10629   u32 tx_sw_if_index;
10630   u8 tx_sw_if_index_set = 0;
10631   u8 is_add = 1;
10632   int ret;
10633
10634   /* Parse args required to build the message */
10635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10636     {
10637       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10638         rx_sw_if_index_set = 1;
10639       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10640         tx_sw_if_index_set = 1;
10641       else if (unformat (i, "rx"))
10642         {
10643           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10644             {
10645               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10646                             &rx_sw_if_index))
10647                 rx_sw_if_index_set = 1;
10648             }
10649           else
10650             break;
10651         }
10652       else if (unformat (i, "tx"))
10653         {
10654           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10655             {
10656               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10657                             &tx_sw_if_index))
10658                 tx_sw_if_index_set = 1;
10659             }
10660           else
10661             break;
10662         }
10663       else if (unformat (i, "del"))
10664         is_add = 0;
10665       else
10666         break;
10667     }
10668
10669   if (rx_sw_if_index_set == 0)
10670     {
10671       errmsg ("missing rx interface name or rx_sw_if_index");
10672       return -99;
10673     }
10674
10675   if (tx_sw_if_index_set == 0)
10676     {
10677       errmsg ("missing tx interface name or tx_sw_if_index");
10678       return -99;
10679     }
10680
10681   M (L2_PATCH_ADD_DEL, mp);
10682
10683   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10684   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10685   mp->is_add = is_add;
10686
10687   S (mp);
10688   W (ret);
10689   return ret;
10690 }
10691
10692 u8 is_del;
10693 u8 localsid_addr[16];
10694 u8 end_psp;
10695 u8 behavior;
10696 u32 sw_if_index;
10697 u32 vlan_index;
10698 u32 fib_table;
10699 u8 nh_addr[16];
10700
10701 static int
10702 api_sr_localsid_add_del (vat_main_t * vam)
10703 {
10704   unformat_input_t *i = vam->input;
10705   vl_api_sr_localsid_add_del_t *mp;
10706
10707   u8 is_del;
10708   ip6_address_t localsid;
10709   u8 end_psp = 0;
10710   u8 behavior = ~0;
10711   u32 sw_if_index;
10712   u32 fib_table = ~(u32) 0;
10713   ip6_address_t next_hop;
10714
10715   bool nexthop_set = 0;
10716
10717   int ret;
10718
10719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10720     {
10721       if (unformat (i, "del"))
10722         is_del = 1;
10723       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10724       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10725         nexthop_set = 1;
10726       else if (unformat (i, "behavior %u", &behavior));
10727       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10728       else if (unformat (i, "fib-table %u", &fib_table));
10729       else if (unformat (i, "end.psp %u", &behavior));
10730       else
10731         break;
10732     }
10733
10734   M (SR_LOCALSID_ADD_DEL, mp);
10735
10736   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10737   if (nexthop_set)
10738     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10739   mp->behavior = behavior;
10740   mp->sw_if_index = ntohl (sw_if_index);
10741   mp->fib_table = ntohl (fib_table);
10742   mp->end_psp = end_psp;
10743   mp->is_del = is_del;
10744
10745   S (mp);
10746   W (ret);
10747   return ret;
10748 }
10749
10750 static int
10751 api_ioam_enable (vat_main_t * vam)
10752 {
10753   unformat_input_t *input = vam->input;
10754   vl_api_ioam_enable_t *mp;
10755   u32 id = 0;
10756   int has_trace_option = 0;
10757   int has_pot_option = 0;
10758   int has_seqno_option = 0;
10759   int has_analyse_option = 0;
10760   int ret;
10761
10762   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10763     {
10764       if (unformat (input, "trace"))
10765         has_trace_option = 1;
10766       else if (unformat (input, "pot"))
10767         has_pot_option = 1;
10768       else if (unformat (input, "seqno"))
10769         has_seqno_option = 1;
10770       else if (unformat (input, "analyse"))
10771         has_analyse_option = 1;
10772       else
10773         break;
10774     }
10775   M (IOAM_ENABLE, mp);
10776   mp->id = htons (id);
10777   mp->seqno = has_seqno_option;
10778   mp->analyse = has_analyse_option;
10779   mp->pot_enable = has_pot_option;
10780   mp->trace_enable = has_trace_option;
10781
10782   S (mp);
10783   W (ret);
10784   return ret;
10785 }
10786
10787
10788 static int
10789 api_ioam_disable (vat_main_t * vam)
10790 {
10791   vl_api_ioam_disable_t *mp;
10792   int ret;
10793
10794   M (IOAM_DISABLE, mp);
10795   S (mp);
10796   W (ret);
10797   return ret;
10798 }
10799
10800 #define foreach_tcp_proto_field                 \
10801 _(src_port)                                     \
10802 _(dst_port)
10803
10804 #define foreach_udp_proto_field                 \
10805 _(src_port)                                     \
10806 _(dst_port)
10807
10808 #define foreach_ip4_proto_field                 \
10809 _(src_address)                                  \
10810 _(dst_address)                                  \
10811 _(tos)                                          \
10812 _(length)                                       \
10813 _(fragment_id)                                  \
10814 _(ttl)                                          \
10815 _(protocol)                                     \
10816 _(checksum)
10817
10818 typedef struct
10819 {
10820   u16 src_port, dst_port;
10821 } tcpudp_header_t;
10822
10823 #if VPP_API_TEST_BUILTIN == 0
10824 uword
10825 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10826 {
10827   u8 **maskp = va_arg (*args, u8 **);
10828   u8 *mask = 0;
10829   u8 found_something = 0;
10830   tcp_header_t *tcp;
10831
10832 #define _(a) u8 a=0;
10833   foreach_tcp_proto_field;
10834 #undef _
10835
10836   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10837     {
10838       if (0);
10839 #define _(a) else if (unformat (input, #a)) a=1;
10840       foreach_tcp_proto_field
10841 #undef _
10842         else
10843         break;
10844     }
10845
10846 #define _(a) found_something += a;
10847   foreach_tcp_proto_field;
10848 #undef _
10849
10850   if (found_something == 0)
10851     return 0;
10852
10853   vec_validate (mask, sizeof (*tcp) - 1);
10854
10855   tcp = (tcp_header_t *) mask;
10856
10857 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10858   foreach_tcp_proto_field;
10859 #undef _
10860
10861   *maskp = mask;
10862   return 1;
10863 }
10864
10865 uword
10866 unformat_udp_mask (unformat_input_t * input, va_list * args)
10867 {
10868   u8 **maskp = va_arg (*args, u8 **);
10869   u8 *mask = 0;
10870   u8 found_something = 0;
10871   udp_header_t *udp;
10872
10873 #define _(a) u8 a=0;
10874   foreach_udp_proto_field;
10875 #undef _
10876
10877   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10878     {
10879       if (0);
10880 #define _(a) else if (unformat (input, #a)) a=1;
10881       foreach_udp_proto_field
10882 #undef _
10883         else
10884         break;
10885     }
10886
10887 #define _(a) found_something += a;
10888   foreach_udp_proto_field;
10889 #undef _
10890
10891   if (found_something == 0)
10892     return 0;
10893
10894   vec_validate (mask, sizeof (*udp) - 1);
10895
10896   udp = (udp_header_t *) mask;
10897
10898 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10899   foreach_udp_proto_field;
10900 #undef _
10901
10902   *maskp = mask;
10903   return 1;
10904 }
10905
10906 uword
10907 unformat_l4_mask (unformat_input_t * input, va_list * args)
10908 {
10909   u8 **maskp = va_arg (*args, u8 **);
10910   u16 src_port = 0, dst_port = 0;
10911   tcpudp_header_t *tcpudp;
10912
10913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10914     {
10915       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10916         return 1;
10917       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10918         return 1;
10919       else if (unformat (input, "src_port"))
10920         src_port = 0xFFFF;
10921       else if (unformat (input, "dst_port"))
10922         dst_port = 0xFFFF;
10923       else
10924         return 0;
10925     }
10926
10927   if (!src_port && !dst_port)
10928     return 0;
10929
10930   u8 *mask = 0;
10931   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10932
10933   tcpudp = (tcpudp_header_t *) mask;
10934   tcpudp->src_port = src_port;
10935   tcpudp->dst_port = dst_port;
10936
10937   *maskp = mask;
10938
10939   return 1;
10940 }
10941
10942 uword
10943 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10944 {
10945   u8 **maskp = va_arg (*args, u8 **);
10946   u8 *mask = 0;
10947   u8 found_something = 0;
10948   ip4_header_t *ip;
10949
10950 #define _(a) u8 a=0;
10951   foreach_ip4_proto_field;
10952 #undef _
10953   u8 version = 0;
10954   u8 hdr_length = 0;
10955
10956
10957   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10958     {
10959       if (unformat (input, "version"))
10960         version = 1;
10961       else if (unformat (input, "hdr_length"))
10962         hdr_length = 1;
10963       else if (unformat (input, "src"))
10964         src_address = 1;
10965       else if (unformat (input, "dst"))
10966         dst_address = 1;
10967       else if (unformat (input, "proto"))
10968         protocol = 1;
10969
10970 #define _(a) else if (unformat (input, #a)) a=1;
10971       foreach_ip4_proto_field
10972 #undef _
10973         else
10974         break;
10975     }
10976
10977 #define _(a) found_something += a;
10978   foreach_ip4_proto_field;
10979 #undef _
10980
10981   if (found_something == 0)
10982     return 0;
10983
10984   vec_validate (mask, sizeof (*ip) - 1);
10985
10986   ip = (ip4_header_t *) mask;
10987
10988 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10989   foreach_ip4_proto_field;
10990 #undef _
10991
10992   ip->ip_version_and_header_length = 0;
10993
10994   if (version)
10995     ip->ip_version_and_header_length |= 0xF0;
10996
10997   if (hdr_length)
10998     ip->ip_version_and_header_length |= 0x0F;
10999
11000   *maskp = mask;
11001   return 1;
11002 }
11003
11004 #define foreach_ip6_proto_field                 \
11005 _(src_address)                                  \
11006 _(dst_address)                                  \
11007 _(payload_length)                               \
11008 _(hop_limit)                                    \
11009 _(protocol)
11010
11011 uword
11012 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11013 {
11014   u8 **maskp = va_arg (*args, u8 **);
11015   u8 *mask = 0;
11016   u8 found_something = 0;
11017   ip6_header_t *ip;
11018   u32 ip_version_traffic_class_and_flow_label;
11019
11020 #define _(a) u8 a=0;
11021   foreach_ip6_proto_field;
11022 #undef _
11023   u8 version = 0;
11024   u8 traffic_class = 0;
11025   u8 flow_label = 0;
11026
11027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11028     {
11029       if (unformat (input, "version"))
11030         version = 1;
11031       else if (unformat (input, "traffic-class"))
11032         traffic_class = 1;
11033       else if (unformat (input, "flow-label"))
11034         flow_label = 1;
11035       else if (unformat (input, "src"))
11036         src_address = 1;
11037       else if (unformat (input, "dst"))
11038         dst_address = 1;
11039       else if (unformat (input, "proto"))
11040         protocol = 1;
11041
11042 #define _(a) else if (unformat (input, #a)) a=1;
11043       foreach_ip6_proto_field
11044 #undef _
11045         else
11046         break;
11047     }
11048
11049 #define _(a) found_something += a;
11050   foreach_ip6_proto_field;
11051 #undef _
11052
11053   if (found_something == 0)
11054     return 0;
11055
11056   vec_validate (mask, sizeof (*ip) - 1);
11057
11058   ip = (ip6_header_t *) mask;
11059
11060 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11061   foreach_ip6_proto_field;
11062 #undef _
11063
11064   ip_version_traffic_class_and_flow_label = 0;
11065
11066   if (version)
11067     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11068
11069   if (traffic_class)
11070     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11071
11072   if (flow_label)
11073     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11074
11075   ip->ip_version_traffic_class_and_flow_label =
11076     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11077
11078   *maskp = mask;
11079   return 1;
11080 }
11081
11082 uword
11083 unformat_l3_mask (unformat_input_t * input, va_list * args)
11084 {
11085   u8 **maskp = va_arg (*args, u8 **);
11086
11087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11088     {
11089       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11090         return 1;
11091       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11092         return 1;
11093       else
11094         break;
11095     }
11096   return 0;
11097 }
11098
11099 uword
11100 unformat_l2_mask (unformat_input_t * input, va_list * args)
11101 {
11102   u8 **maskp = va_arg (*args, u8 **);
11103   u8 *mask = 0;
11104   u8 src = 0;
11105   u8 dst = 0;
11106   u8 proto = 0;
11107   u8 tag1 = 0;
11108   u8 tag2 = 0;
11109   u8 ignore_tag1 = 0;
11110   u8 ignore_tag2 = 0;
11111   u8 cos1 = 0;
11112   u8 cos2 = 0;
11113   u8 dot1q = 0;
11114   u8 dot1ad = 0;
11115   int len = 14;
11116
11117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11118     {
11119       if (unformat (input, "src"))
11120         src = 1;
11121       else if (unformat (input, "dst"))
11122         dst = 1;
11123       else if (unformat (input, "proto"))
11124         proto = 1;
11125       else if (unformat (input, "tag1"))
11126         tag1 = 1;
11127       else if (unformat (input, "tag2"))
11128         tag2 = 1;
11129       else if (unformat (input, "ignore-tag1"))
11130         ignore_tag1 = 1;
11131       else if (unformat (input, "ignore-tag2"))
11132         ignore_tag2 = 1;
11133       else if (unformat (input, "cos1"))
11134         cos1 = 1;
11135       else if (unformat (input, "cos2"))
11136         cos2 = 1;
11137       else if (unformat (input, "dot1q"))
11138         dot1q = 1;
11139       else if (unformat (input, "dot1ad"))
11140         dot1ad = 1;
11141       else
11142         break;
11143     }
11144   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11145        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11146     return 0;
11147
11148   if (tag1 || ignore_tag1 || cos1 || dot1q)
11149     len = 18;
11150   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11151     len = 22;
11152
11153   vec_validate (mask, len - 1);
11154
11155   if (dst)
11156     memset (mask, 0xff, 6);
11157
11158   if (src)
11159     memset (mask + 6, 0xff, 6);
11160
11161   if (tag2 || dot1ad)
11162     {
11163       /* inner vlan tag */
11164       if (tag2)
11165         {
11166           mask[19] = 0xff;
11167           mask[18] = 0x0f;
11168         }
11169       if (cos2)
11170         mask[18] |= 0xe0;
11171       if (proto)
11172         mask[21] = mask[20] = 0xff;
11173       if (tag1)
11174         {
11175           mask[15] = 0xff;
11176           mask[14] = 0x0f;
11177         }
11178       if (cos1)
11179         mask[14] |= 0xe0;
11180       *maskp = mask;
11181       return 1;
11182     }
11183   if (tag1 | dot1q)
11184     {
11185       if (tag1)
11186         {
11187           mask[15] = 0xff;
11188           mask[14] = 0x0f;
11189         }
11190       if (cos1)
11191         mask[14] |= 0xe0;
11192       if (proto)
11193         mask[16] = mask[17] = 0xff;
11194
11195       *maskp = mask;
11196       return 1;
11197     }
11198   if (cos2)
11199     mask[18] |= 0xe0;
11200   if (cos1)
11201     mask[14] |= 0xe0;
11202   if (proto)
11203     mask[12] = mask[13] = 0xff;
11204
11205   *maskp = mask;
11206   return 1;
11207 }
11208
11209 uword
11210 unformat_classify_mask (unformat_input_t * input, va_list * args)
11211 {
11212   u8 **maskp = va_arg (*args, u8 **);
11213   u32 *skipp = va_arg (*args, u32 *);
11214   u32 *matchp = va_arg (*args, u32 *);
11215   u32 match;
11216   u8 *mask = 0;
11217   u8 *l2 = 0;
11218   u8 *l3 = 0;
11219   u8 *l4 = 0;
11220   int i;
11221
11222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11223     {
11224       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11225         ;
11226       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11227         ;
11228       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11229         ;
11230       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11231         ;
11232       else
11233         break;
11234     }
11235
11236   if (l4 && !l3)
11237     {
11238       vec_free (mask);
11239       vec_free (l2);
11240       vec_free (l4);
11241       return 0;
11242     }
11243
11244   if (mask || l2 || l3 || l4)
11245     {
11246       if (l2 || l3 || l4)
11247         {
11248           /* "With a free Ethernet header in every package" */
11249           if (l2 == 0)
11250             vec_validate (l2, 13);
11251           mask = l2;
11252           if (vec_len (l3))
11253             {
11254               vec_append (mask, l3);
11255               vec_free (l3);
11256             }
11257           if (vec_len (l4))
11258             {
11259               vec_append (mask, l4);
11260               vec_free (l4);
11261             }
11262         }
11263
11264       /* Scan forward looking for the first significant mask octet */
11265       for (i = 0; i < vec_len (mask); i++)
11266         if (mask[i])
11267           break;
11268
11269       /* compute (skip, match) params */
11270       *skipp = i / sizeof (u32x4);
11271       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11272
11273       /* Pad mask to an even multiple of the vector size */
11274       while (vec_len (mask) % sizeof (u32x4))
11275         vec_add1 (mask, 0);
11276
11277       match = vec_len (mask) / sizeof (u32x4);
11278
11279       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11280         {
11281           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11282           if (*tmp || *(tmp + 1))
11283             break;
11284           match--;
11285         }
11286       if (match == 0)
11287         clib_warning ("BUG: match 0");
11288
11289       _vec_len (mask) = match * sizeof (u32x4);
11290
11291       *matchp = match;
11292       *maskp = mask;
11293
11294       return 1;
11295     }
11296
11297   return 0;
11298 }
11299 #endif /* VPP_API_TEST_BUILTIN */
11300
11301 #define foreach_l2_next                         \
11302 _(drop, DROP)                                   \
11303 _(ethernet, ETHERNET_INPUT)                     \
11304 _(ip4, IP4_INPUT)                               \
11305 _(ip6, IP6_INPUT)
11306
11307 uword
11308 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11309 {
11310   u32 *miss_next_indexp = va_arg (*args, u32 *);
11311   u32 next_index = 0;
11312   u32 tmp;
11313
11314 #define _(n,N) \
11315   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11316   foreach_l2_next;
11317 #undef _
11318
11319   if (unformat (input, "%d", &tmp))
11320     {
11321       next_index = tmp;
11322       goto out;
11323     }
11324
11325   return 0;
11326
11327 out:
11328   *miss_next_indexp = next_index;
11329   return 1;
11330 }
11331
11332 #define foreach_ip_next                         \
11333 _(drop, DROP)                                   \
11334 _(local, LOCAL)                                 \
11335 _(rewrite, REWRITE)
11336
11337 uword
11338 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11339 {
11340   u32 *miss_next_indexp = va_arg (*args, u32 *);
11341   u32 next_index = 0;
11342   u32 tmp;
11343
11344 #define _(n,N) \
11345   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11346   foreach_ip_next;
11347 #undef _
11348
11349   if (unformat (input, "%d", &tmp))
11350     {
11351       next_index = tmp;
11352       goto out;
11353     }
11354
11355   return 0;
11356
11357 out:
11358   *miss_next_indexp = next_index;
11359   return 1;
11360 }
11361
11362 #define foreach_acl_next                        \
11363 _(deny, DENY)
11364
11365 uword
11366 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11367 {
11368   u32 *miss_next_indexp = va_arg (*args, u32 *);
11369   u32 next_index = 0;
11370   u32 tmp;
11371
11372 #define _(n,N) \
11373   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11374   foreach_acl_next;
11375 #undef _
11376
11377   if (unformat (input, "permit"))
11378     {
11379       next_index = ~0;
11380       goto out;
11381     }
11382   else if (unformat (input, "%d", &tmp))
11383     {
11384       next_index = tmp;
11385       goto out;
11386     }
11387
11388   return 0;
11389
11390 out:
11391   *miss_next_indexp = next_index;
11392   return 1;
11393 }
11394
11395 uword
11396 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11397 {
11398   u32 *r = va_arg (*args, u32 *);
11399
11400   if (unformat (input, "conform-color"))
11401     *r = POLICE_CONFORM;
11402   else if (unformat (input, "exceed-color"))
11403     *r = POLICE_EXCEED;
11404   else
11405     return 0;
11406
11407   return 1;
11408 }
11409
11410 static int
11411 api_classify_add_del_table (vat_main_t * vam)
11412 {
11413   unformat_input_t *i = vam->input;
11414   vl_api_classify_add_del_table_t *mp;
11415
11416   u32 nbuckets = 2;
11417   u32 skip = ~0;
11418   u32 match = ~0;
11419   int is_add = 1;
11420   int del_chain = 0;
11421   u32 table_index = ~0;
11422   u32 next_table_index = ~0;
11423   u32 miss_next_index = ~0;
11424   u32 memory_size = 32 << 20;
11425   u8 *mask = 0;
11426   u32 current_data_flag = 0;
11427   int current_data_offset = 0;
11428   int ret;
11429
11430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11431     {
11432       if (unformat (i, "del"))
11433         is_add = 0;
11434       else if (unformat (i, "del-chain"))
11435         {
11436           is_add = 0;
11437           del_chain = 1;
11438         }
11439       else if (unformat (i, "buckets %d", &nbuckets))
11440         ;
11441       else if (unformat (i, "memory_size %d", &memory_size))
11442         ;
11443       else if (unformat (i, "skip %d", &skip))
11444         ;
11445       else if (unformat (i, "match %d", &match))
11446         ;
11447       else if (unformat (i, "table %d", &table_index))
11448         ;
11449       else if (unformat (i, "mask %U", unformat_classify_mask,
11450                          &mask, &skip, &match))
11451         ;
11452       else if (unformat (i, "next-table %d", &next_table_index))
11453         ;
11454       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11455                          &miss_next_index))
11456         ;
11457       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11458                          &miss_next_index))
11459         ;
11460       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11461                          &miss_next_index))
11462         ;
11463       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11464         ;
11465       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11466         ;
11467       else
11468         break;
11469     }
11470
11471   if (is_add && mask == 0)
11472     {
11473       errmsg ("Mask required");
11474       return -99;
11475     }
11476
11477   if (is_add && skip == ~0)
11478     {
11479       errmsg ("skip count required");
11480       return -99;
11481     }
11482
11483   if (is_add && match == ~0)
11484     {
11485       errmsg ("match count required");
11486       return -99;
11487     }
11488
11489   if (!is_add && table_index == ~0)
11490     {
11491       errmsg ("table index required for delete");
11492       return -99;
11493     }
11494
11495   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11496
11497   mp->is_add = is_add;
11498   mp->del_chain = del_chain;
11499   mp->table_index = ntohl (table_index);
11500   mp->nbuckets = ntohl (nbuckets);
11501   mp->memory_size = ntohl (memory_size);
11502   mp->skip_n_vectors = ntohl (skip);
11503   mp->match_n_vectors = ntohl (match);
11504   mp->next_table_index = ntohl (next_table_index);
11505   mp->miss_next_index = ntohl (miss_next_index);
11506   mp->current_data_flag = ntohl (current_data_flag);
11507   mp->current_data_offset = ntohl (current_data_offset);
11508   clib_memcpy (mp->mask, mask, vec_len (mask));
11509
11510   vec_free (mask);
11511
11512   S (mp);
11513   W (ret);
11514   return ret;
11515 }
11516
11517 #if VPP_API_TEST_BUILTIN == 0
11518 uword
11519 unformat_l4_match (unformat_input_t * input, va_list * args)
11520 {
11521   u8 **matchp = va_arg (*args, u8 **);
11522
11523   u8 *proto_header = 0;
11524   int src_port = 0;
11525   int dst_port = 0;
11526
11527   tcpudp_header_t h;
11528
11529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11530     {
11531       if (unformat (input, "src_port %d", &src_port))
11532         ;
11533       else if (unformat (input, "dst_port %d", &dst_port))
11534         ;
11535       else
11536         return 0;
11537     }
11538
11539   h.src_port = clib_host_to_net_u16 (src_port);
11540   h.dst_port = clib_host_to_net_u16 (dst_port);
11541   vec_validate (proto_header, sizeof (h) - 1);
11542   memcpy (proto_header, &h, sizeof (h));
11543
11544   *matchp = proto_header;
11545
11546   return 1;
11547 }
11548
11549 uword
11550 unformat_ip4_match (unformat_input_t * input, va_list * args)
11551 {
11552   u8 **matchp = va_arg (*args, u8 **);
11553   u8 *match = 0;
11554   ip4_header_t *ip;
11555   int version = 0;
11556   u32 version_val;
11557   int hdr_length = 0;
11558   u32 hdr_length_val;
11559   int src = 0, dst = 0;
11560   ip4_address_t src_val, dst_val;
11561   int proto = 0;
11562   u32 proto_val;
11563   int tos = 0;
11564   u32 tos_val;
11565   int length = 0;
11566   u32 length_val;
11567   int fragment_id = 0;
11568   u32 fragment_id_val;
11569   int ttl = 0;
11570   int ttl_val;
11571   int checksum = 0;
11572   u32 checksum_val;
11573
11574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11575     {
11576       if (unformat (input, "version %d", &version_val))
11577         version = 1;
11578       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11579         hdr_length = 1;
11580       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11581         src = 1;
11582       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11583         dst = 1;
11584       else if (unformat (input, "proto %d", &proto_val))
11585         proto = 1;
11586       else if (unformat (input, "tos %d", &tos_val))
11587         tos = 1;
11588       else if (unformat (input, "length %d", &length_val))
11589         length = 1;
11590       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11591         fragment_id = 1;
11592       else if (unformat (input, "ttl %d", &ttl_val))
11593         ttl = 1;
11594       else if (unformat (input, "checksum %d", &checksum_val))
11595         checksum = 1;
11596       else
11597         break;
11598     }
11599
11600   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11601       + ttl + checksum == 0)
11602     return 0;
11603
11604   /*
11605    * Aligned because we use the real comparison functions
11606    */
11607   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11608
11609   ip = (ip4_header_t *) match;
11610
11611   /* These are realistically matched in practice */
11612   if (src)
11613     ip->src_address.as_u32 = src_val.as_u32;
11614
11615   if (dst)
11616     ip->dst_address.as_u32 = dst_val.as_u32;
11617
11618   if (proto)
11619     ip->protocol = proto_val;
11620
11621
11622   /* These are not, but they're included for completeness */
11623   if (version)
11624     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11625
11626   if (hdr_length)
11627     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11628
11629   if (tos)
11630     ip->tos = tos_val;
11631
11632   if (length)
11633     ip->length = clib_host_to_net_u16 (length_val);
11634
11635   if (ttl)
11636     ip->ttl = ttl_val;
11637
11638   if (checksum)
11639     ip->checksum = clib_host_to_net_u16 (checksum_val);
11640
11641   *matchp = match;
11642   return 1;
11643 }
11644
11645 uword
11646 unformat_ip6_match (unformat_input_t * input, va_list * args)
11647 {
11648   u8 **matchp = va_arg (*args, u8 **);
11649   u8 *match = 0;
11650   ip6_header_t *ip;
11651   int version = 0;
11652   u32 version_val;
11653   u8 traffic_class = 0;
11654   u32 traffic_class_val = 0;
11655   u8 flow_label = 0;
11656   u8 flow_label_val;
11657   int src = 0, dst = 0;
11658   ip6_address_t src_val, dst_val;
11659   int proto = 0;
11660   u32 proto_val;
11661   int payload_length = 0;
11662   u32 payload_length_val;
11663   int hop_limit = 0;
11664   int hop_limit_val;
11665   u32 ip_version_traffic_class_and_flow_label;
11666
11667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11668     {
11669       if (unformat (input, "version %d", &version_val))
11670         version = 1;
11671       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11672         traffic_class = 1;
11673       else if (unformat (input, "flow_label %d", &flow_label_val))
11674         flow_label = 1;
11675       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11676         src = 1;
11677       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11678         dst = 1;
11679       else if (unformat (input, "proto %d", &proto_val))
11680         proto = 1;
11681       else if (unformat (input, "payload_length %d", &payload_length_val))
11682         payload_length = 1;
11683       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11684         hop_limit = 1;
11685       else
11686         break;
11687     }
11688
11689   if (version + traffic_class + flow_label + src + dst + proto +
11690       payload_length + hop_limit == 0)
11691     return 0;
11692
11693   /*
11694    * Aligned because we use the real comparison functions
11695    */
11696   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11697
11698   ip = (ip6_header_t *) match;
11699
11700   if (src)
11701     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11702
11703   if (dst)
11704     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11705
11706   if (proto)
11707     ip->protocol = proto_val;
11708
11709   ip_version_traffic_class_and_flow_label = 0;
11710
11711   if (version)
11712     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11713
11714   if (traffic_class)
11715     ip_version_traffic_class_and_flow_label |=
11716       (traffic_class_val & 0xFF) << 20;
11717
11718   if (flow_label)
11719     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11720
11721   ip->ip_version_traffic_class_and_flow_label =
11722     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11723
11724   if (payload_length)
11725     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11726
11727   if (hop_limit)
11728     ip->hop_limit = hop_limit_val;
11729
11730   *matchp = match;
11731   return 1;
11732 }
11733
11734 uword
11735 unformat_l3_match (unformat_input_t * input, va_list * args)
11736 {
11737   u8 **matchp = va_arg (*args, u8 **);
11738
11739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11740     {
11741       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11742         return 1;
11743       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11744         return 1;
11745       else
11746         break;
11747     }
11748   return 0;
11749 }
11750
11751 uword
11752 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11753 {
11754   u8 *tagp = va_arg (*args, u8 *);
11755   u32 tag;
11756
11757   if (unformat (input, "%d", &tag))
11758     {
11759       tagp[0] = (tag >> 8) & 0x0F;
11760       tagp[1] = tag & 0xFF;
11761       return 1;
11762     }
11763
11764   return 0;
11765 }
11766
11767 uword
11768 unformat_l2_match (unformat_input_t * input, va_list * args)
11769 {
11770   u8 **matchp = va_arg (*args, u8 **);
11771   u8 *match = 0;
11772   u8 src = 0;
11773   u8 src_val[6];
11774   u8 dst = 0;
11775   u8 dst_val[6];
11776   u8 proto = 0;
11777   u16 proto_val;
11778   u8 tag1 = 0;
11779   u8 tag1_val[2];
11780   u8 tag2 = 0;
11781   u8 tag2_val[2];
11782   int len = 14;
11783   u8 ignore_tag1 = 0;
11784   u8 ignore_tag2 = 0;
11785   u8 cos1 = 0;
11786   u8 cos2 = 0;
11787   u32 cos1_val = 0;
11788   u32 cos2_val = 0;
11789
11790   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11791     {
11792       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11793         src = 1;
11794       else
11795         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11796         dst = 1;
11797       else if (unformat (input, "proto %U",
11798                          unformat_ethernet_type_host_byte_order, &proto_val))
11799         proto = 1;
11800       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11801         tag1 = 1;
11802       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11803         tag2 = 1;
11804       else if (unformat (input, "ignore-tag1"))
11805         ignore_tag1 = 1;
11806       else if (unformat (input, "ignore-tag2"))
11807         ignore_tag2 = 1;
11808       else if (unformat (input, "cos1 %d", &cos1_val))
11809         cos1 = 1;
11810       else if (unformat (input, "cos2 %d", &cos2_val))
11811         cos2 = 1;
11812       else
11813         break;
11814     }
11815   if ((src + dst + proto + tag1 + tag2 +
11816        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11817     return 0;
11818
11819   if (tag1 || ignore_tag1 || cos1)
11820     len = 18;
11821   if (tag2 || ignore_tag2 || cos2)
11822     len = 22;
11823
11824   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11825
11826   if (dst)
11827     clib_memcpy (match, dst_val, 6);
11828
11829   if (src)
11830     clib_memcpy (match + 6, src_val, 6);
11831
11832   if (tag2)
11833     {
11834       /* inner vlan tag */
11835       match[19] = tag2_val[1];
11836       match[18] = tag2_val[0];
11837       if (cos2)
11838         match[18] |= (cos2_val & 0x7) << 5;
11839       if (proto)
11840         {
11841           match[21] = proto_val & 0xff;
11842           match[20] = proto_val >> 8;
11843         }
11844       if (tag1)
11845         {
11846           match[15] = tag1_val[1];
11847           match[14] = tag1_val[0];
11848         }
11849       if (cos1)
11850         match[14] |= (cos1_val & 0x7) << 5;
11851       *matchp = match;
11852       return 1;
11853     }
11854   if (tag1)
11855     {
11856       match[15] = tag1_val[1];
11857       match[14] = tag1_val[0];
11858       if (proto)
11859         {
11860           match[17] = proto_val & 0xff;
11861           match[16] = proto_val >> 8;
11862         }
11863       if (cos1)
11864         match[14] |= (cos1_val & 0x7) << 5;
11865
11866       *matchp = match;
11867       return 1;
11868     }
11869   if (cos2)
11870     match[18] |= (cos2_val & 0x7) << 5;
11871   if (cos1)
11872     match[14] |= (cos1_val & 0x7) << 5;
11873   if (proto)
11874     {
11875       match[13] = proto_val & 0xff;
11876       match[12] = proto_val >> 8;
11877     }
11878
11879   *matchp = match;
11880   return 1;
11881 }
11882
11883 uword
11884 unformat_qos_source (unformat_input_t * input, va_list * args)
11885 {
11886   int *qs = va_arg (*args, int *);
11887
11888   if (unformat (input, "ip"))
11889     *qs = QOS_SOURCE_IP;
11890   else if (unformat (input, "mpls"))
11891     *qs = QOS_SOURCE_MPLS;
11892   else if (unformat (input, "ext"))
11893     *qs = QOS_SOURCE_EXT;
11894   else if (unformat (input, "vlan"))
11895     *qs = QOS_SOURCE_VLAN;
11896   else
11897     return 0;
11898
11899   return 1;
11900 }
11901 #endif
11902
11903 uword
11904 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11905 {
11906   u8 **matchp = va_arg (*args, u8 **);
11907   u32 skip_n_vectors = va_arg (*args, u32);
11908   u32 match_n_vectors = va_arg (*args, u32);
11909
11910   u8 *match = 0;
11911   u8 *l2 = 0;
11912   u8 *l3 = 0;
11913   u8 *l4 = 0;
11914
11915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11916     {
11917       if (unformat (input, "hex %U", unformat_hex_string, &match))
11918         ;
11919       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11920         ;
11921       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11922         ;
11923       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11924         ;
11925       else
11926         break;
11927     }
11928
11929   if (l4 && !l3)
11930     {
11931       vec_free (match);
11932       vec_free (l2);
11933       vec_free (l4);
11934       return 0;
11935     }
11936
11937   if (match || l2 || l3 || l4)
11938     {
11939       if (l2 || l3 || l4)
11940         {
11941           /* "Win a free Ethernet header in every packet" */
11942           if (l2 == 0)
11943             vec_validate_aligned (l2, 13, sizeof (u32x4));
11944           match = l2;
11945           if (vec_len (l3))
11946             {
11947               vec_append_aligned (match, l3, sizeof (u32x4));
11948               vec_free (l3);
11949             }
11950           if (vec_len (l4))
11951             {
11952               vec_append_aligned (match, l4, sizeof (u32x4));
11953               vec_free (l4);
11954             }
11955         }
11956
11957       /* Make sure the vector is big enough even if key is all 0's */
11958       vec_validate_aligned
11959         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11960          sizeof (u32x4));
11961
11962       /* Set size, include skipped vectors */
11963       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11964
11965       *matchp = match;
11966
11967       return 1;
11968     }
11969
11970   return 0;
11971 }
11972
11973 static int
11974 api_classify_add_del_session (vat_main_t * vam)
11975 {
11976   unformat_input_t *i = vam->input;
11977   vl_api_classify_add_del_session_t *mp;
11978   int is_add = 1;
11979   u32 table_index = ~0;
11980   u32 hit_next_index = ~0;
11981   u32 opaque_index = ~0;
11982   u8 *match = 0;
11983   i32 advance = 0;
11984   u32 skip_n_vectors = 0;
11985   u32 match_n_vectors = 0;
11986   u32 action = 0;
11987   u32 metadata = 0;
11988   int ret;
11989
11990   /*
11991    * Warning: you have to supply skip_n and match_n
11992    * because the API client cant simply look at the classify
11993    * table object.
11994    */
11995
11996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11997     {
11998       if (unformat (i, "del"))
11999         is_add = 0;
12000       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12001                          &hit_next_index))
12002         ;
12003       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12004                          &hit_next_index))
12005         ;
12006       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12007                          &hit_next_index))
12008         ;
12009       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12010         ;
12011       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12012         ;
12013       else if (unformat (i, "opaque-index %d", &opaque_index))
12014         ;
12015       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12016         ;
12017       else if (unformat (i, "match_n %d", &match_n_vectors))
12018         ;
12019       else if (unformat (i, "match %U", api_unformat_classify_match,
12020                          &match, skip_n_vectors, match_n_vectors))
12021         ;
12022       else if (unformat (i, "advance %d", &advance))
12023         ;
12024       else if (unformat (i, "table-index %d", &table_index))
12025         ;
12026       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12027         action = 1;
12028       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12029         action = 2;
12030       else if (unformat (i, "action %d", &action))
12031         ;
12032       else if (unformat (i, "metadata %d", &metadata))
12033         ;
12034       else
12035         break;
12036     }
12037
12038   if (table_index == ~0)
12039     {
12040       errmsg ("Table index required");
12041       return -99;
12042     }
12043
12044   if (is_add && match == 0)
12045     {
12046       errmsg ("Match value required");
12047       return -99;
12048     }
12049
12050   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12051
12052   mp->is_add = is_add;
12053   mp->table_index = ntohl (table_index);
12054   mp->hit_next_index = ntohl (hit_next_index);
12055   mp->opaque_index = ntohl (opaque_index);
12056   mp->advance = ntohl (advance);
12057   mp->action = action;
12058   mp->metadata = ntohl (metadata);
12059   clib_memcpy (mp->match, match, vec_len (match));
12060   vec_free (match);
12061
12062   S (mp);
12063   W (ret);
12064   return ret;
12065 }
12066
12067 static int
12068 api_classify_set_interface_ip_table (vat_main_t * vam)
12069 {
12070   unformat_input_t *i = vam->input;
12071   vl_api_classify_set_interface_ip_table_t *mp;
12072   u32 sw_if_index;
12073   int sw_if_index_set;
12074   u32 table_index = ~0;
12075   u8 is_ipv6 = 0;
12076   int ret;
12077
12078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12079     {
12080       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12081         sw_if_index_set = 1;
12082       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12083         sw_if_index_set = 1;
12084       else if (unformat (i, "table %d", &table_index))
12085         ;
12086       else
12087         {
12088           clib_warning ("parse error '%U'", format_unformat_error, i);
12089           return -99;
12090         }
12091     }
12092
12093   if (sw_if_index_set == 0)
12094     {
12095       errmsg ("missing interface name or sw_if_index");
12096       return -99;
12097     }
12098
12099
12100   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12101
12102   mp->sw_if_index = ntohl (sw_if_index);
12103   mp->table_index = ntohl (table_index);
12104   mp->is_ipv6 = is_ipv6;
12105
12106   S (mp);
12107   W (ret);
12108   return ret;
12109 }
12110
12111 static int
12112 api_classify_set_interface_l2_tables (vat_main_t * vam)
12113 {
12114   unformat_input_t *i = vam->input;
12115   vl_api_classify_set_interface_l2_tables_t *mp;
12116   u32 sw_if_index;
12117   int sw_if_index_set;
12118   u32 ip4_table_index = ~0;
12119   u32 ip6_table_index = ~0;
12120   u32 other_table_index = ~0;
12121   u32 is_input = 1;
12122   int ret;
12123
12124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12125     {
12126       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12127         sw_if_index_set = 1;
12128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12129         sw_if_index_set = 1;
12130       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12131         ;
12132       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12133         ;
12134       else if (unformat (i, "other-table %d", &other_table_index))
12135         ;
12136       else if (unformat (i, "is-input %d", &is_input))
12137         ;
12138       else
12139         {
12140           clib_warning ("parse error '%U'", format_unformat_error, i);
12141           return -99;
12142         }
12143     }
12144
12145   if (sw_if_index_set == 0)
12146     {
12147       errmsg ("missing interface name or sw_if_index");
12148       return -99;
12149     }
12150
12151
12152   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12153
12154   mp->sw_if_index = ntohl (sw_if_index);
12155   mp->ip4_table_index = ntohl (ip4_table_index);
12156   mp->ip6_table_index = ntohl (ip6_table_index);
12157   mp->other_table_index = ntohl (other_table_index);
12158   mp->is_input = (u8) is_input;
12159
12160   S (mp);
12161   W (ret);
12162   return ret;
12163 }
12164
12165 static int
12166 api_set_ipfix_exporter (vat_main_t * vam)
12167 {
12168   unformat_input_t *i = vam->input;
12169   vl_api_set_ipfix_exporter_t *mp;
12170   ip4_address_t collector_address;
12171   u8 collector_address_set = 0;
12172   u32 collector_port = ~0;
12173   ip4_address_t src_address;
12174   u8 src_address_set = 0;
12175   u32 vrf_id = ~0;
12176   u32 path_mtu = ~0;
12177   u32 template_interval = ~0;
12178   u8 udp_checksum = 0;
12179   int ret;
12180
12181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12182     {
12183       if (unformat (i, "collector_address %U", unformat_ip4_address,
12184                     &collector_address))
12185         collector_address_set = 1;
12186       else if (unformat (i, "collector_port %d", &collector_port))
12187         ;
12188       else if (unformat (i, "src_address %U", unformat_ip4_address,
12189                          &src_address))
12190         src_address_set = 1;
12191       else if (unformat (i, "vrf_id %d", &vrf_id))
12192         ;
12193       else if (unformat (i, "path_mtu %d", &path_mtu))
12194         ;
12195       else if (unformat (i, "template_interval %d", &template_interval))
12196         ;
12197       else if (unformat (i, "udp_checksum"))
12198         udp_checksum = 1;
12199       else
12200         break;
12201     }
12202
12203   if (collector_address_set == 0)
12204     {
12205       errmsg ("collector_address required");
12206       return -99;
12207     }
12208
12209   if (src_address_set == 0)
12210     {
12211       errmsg ("src_address required");
12212       return -99;
12213     }
12214
12215   M (SET_IPFIX_EXPORTER, mp);
12216
12217   memcpy (mp->collector_address, collector_address.data,
12218           sizeof (collector_address.data));
12219   mp->collector_port = htons ((u16) collector_port);
12220   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12221   mp->vrf_id = htonl (vrf_id);
12222   mp->path_mtu = htonl (path_mtu);
12223   mp->template_interval = htonl (template_interval);
12224   mp->udp_checksum = udp_checksum;
12225
12226   S (mp);
12227   W (ret);
12228   return ret;
12229 }
12230
12231 static int
12232 api_set_ipfix_classify_stream (vat_main_t * vam)
12233 {
12234   unformat_input_t *i = vam->input;
12235   vl_api_set_ipfix_classify_stream_t *mp;
12236   u32 domain_id = 0;
12237   u32 src_port = UDP_DST_PORT_ipfix;
12238   int ret;
12239
12240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12241     {
12242       if (unformat (i, "domain %d", &domain_id))
12243         ;
12244       else if (unformat (i, "src_port %d", &src_port))
12245         ;
12246       else
12247         {
12248           errmsg ("unknown input `%U'", format_unformat_error, i);
12249           return -99;
12250         }
12251     }
12252
12253   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12254
12255   mp->domain_id = htonl (domain_id);
12256   mp->src_port = htons ((u16) src_port);
12257
12258   S (mp);
12259   W (ret);
12260   return ret;
12261 }
12262
12263 static int
12264 api_ipfix_classify_table_add_del (vat_main_t * vam)
12265 {
12266   unformat_input_t *i = vam->input;
12267   vl_api_ipfix_classify_table_add_del_t *mp;
12268   int is_add = -1;
12269   u32 classify_table_index = ~0;
12270   u8 ip_version = 0;
12271   u8 transport_protocol = 255;
12272   int ret;
12273
12274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12275     {
12276       if (unformat (i, "add"))
12277         is_add = 1;
12278       else if (unformat (i, "del"))
12279         is_add = 0;
12280       else if (unformat (i, "table %d", &classify_table_index))
12281         ;
12282       else if (unformat (i, "ip4"))
12283         ip_version = 4;
12284       else if (unformat (i, "ip6"))
12285         ip_version = 6;
12286       else if (unformat (i, "tcp"))
12287         transport_protocol = 6;
12288       else if (unformat (i, "udp"))
12289         transport_protocol = 17;
12290       else
12291         {
12292           errmsg ("unknown input `%U'", format_unformat_error, i);
12293           return -99;
12294         }
12295     }
12296
12297   if (is_add == -1)
12298     {
12299       errmsg ("expecting: add|del");
12300       return -99;
12301     }
12302   if (classify_table_index == ~0)
12303     {
12304       errmsg ("classifier table not specified");
12305       return -99;
12306     }
12307   if (ip_version == 0)
12308     {
12309       errmsg ("IP version not specified");
12310       return -99;
12311     }
12312
12313   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12314
12315   mp->is_add = is_add;
12316   mp->table_id = htonl (classify_table_index);
12317   mp->ip_version = ip_version;
12318   mp->transport_protocol = transport_protocol;
12319
12320   S (mp);
12321   W (ret);
12322   return ret;
12323 }
12324
12325 static int
12326 api_get_node_index (vat_main_t * vam)
12327 {
12328   unformat_input_t *i = vam->input;
12329   vl_api_get_node_index_t *mp;
12330   u8 *name = 0;
12331   int ret;
12332
12333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12334     {
12335       if (unformat (i, "node %s", &name))
12336         ;
12337       else
12338         break;
12339     }
12340   if (name == 0)
12341     {
12342       errmsg ("node name required");
12343       return -99;
12344     }
12345   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12346     {
12347       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12348       return -99;
12349     }
12350
12351   M (GET_NODE_INDEX, mp);
12352   clib_memcpy (mp->node_name, name, vec_len (name));
12353   vec_free (name);
12354
12355   S (mp);
12356   W (ret);
12357   return ret;
12358 }
12359
12360 static int
12361 api_get_next_index (vat_main_t * vam)
12362 {
12363   unformat_input_t *i = vam->input;
12364   vl_api_get_next_index_t *mp;
12365   u8 *node_name = 0, *next_node_name = 0;
12366   int ret;
12367
12368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12369     {
12370       if (unformat (i, "node-name %s", &node_name))
12371         ;
12372       else if (unformat (i, "next-node-name %s", &next_node_name))
12373         break;
12374     }
12375
12376   if (node_name == 0)
12377     {
12378       errmsg ("node name required");
12379       return -99;
12380     }
12381   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12382     {
12383       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12384       return -99;
12385     }
12386
12387   if (next_node_name == 0)
12388     {
12389       errmsg ("next node name required");
12390       return -99;
12391     }
12392   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12393     {
12394       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12395       return -99;
12396     }
12397
12398   M (GET_NEXT_INDEX, mp);
12399   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12400   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12401   vec_free (node_name);
12402   vec_free (next_node_name);
12403
12404   S (mp);
12405   W (ret);
12406   return ret;
12407 }
12408
12409 static int
12410 api_add_node_next (vat_main_t * vam)
12411 {
12412   unformat_input_t *i = vam->input;
12413   vl_api_add_node_next_t *mp;
12414   u8 *name = 0;
12415   u8 *next = 0;
12416   int ret;
12417
12418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12419     {
12420       if (unformat (i, "node %s", &name))
12421         ;
12422       else if (unformat (i, "next %s", &next))
12423         ;
12424       else
12425         break;
12426     }
12427   if (name == 0)
12428     {
12429       errmsg ("node name required");
12430       return -99;
12431     }
12432   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12433     {
12434       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12435       return -99;
12436     }
12437   if (next == 0)
12438     {
12439       errmsg ("next node required");
12440       return -99;
12441     }
12442   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12443     {
12444       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12445       return -99;
12446     }
12447
12448   M (ADD_NODE_NEXT, mp);
12449   clib_memcpy (mp->node_name, name, vec_len (name));
12450   clib_memcpy (mp->next_name, next, vec_len (next));
12451   vec_free (name);
12452   vec_free (next);
12453
12454   S (mp);
12455   W (ret);
12456   return ret;
12457 }
12458
12459 static int
12460 api_l2tpv3_create_tunnel (vat_main_t * vam)
12461 {
12462   unformat_input_t *i = vam->input;
12463   ip6_address_t client_address, our_address;
12464   int client_address_set = 0;
12465   int our_address_set = 0;
12466   u32 local_session_id = 0;
12467   u32 remote_session_id = 0;
12468   u64 local_cookie = 0;
12469   u64 remote_cookie = 0;
12470   u8 l2_sublayer_present = 0;
12471   vl_api_l2tpv3_create_tunnel_t *mp;
12472   int ret;
12473
12474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12475     {
12476       if (unformat (i, "client_address %U", unformat_ip6_address,
12477                     &client_address))
12478         client_address_set = 1;
12479       else if (unformat (i, "our_address %U", unformat_ip6_address,
12480                          &our_address))
12481         our_address_set = 1;
12482       else if (unformat (i, "local_session_id %d", &local_session_id))
12483         ;
12484       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12485         ;
12486       else if (unformat (i, "local_cookie %lld", &local_cookie))
12487         ;
12488       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12489         ;
12490       else if (unformat (i, "l2-sublayer-present"))
12491         l2_sublayer_present = 1;
12492       else
12493         break;
12494     }
12495
12496   if (client_address_set == 0)
12497     {
12498       errmsg ("client_address required");
12499       return -99;
12500     }
12501
12502   if (our_address_set == 0)
12503     {
12504       errmsg ("our_address required");
12505       return -99;
12506     }
12507
12508   M (L2TPV3_CREATE_TUNNEL, mp);
12509
12510   clib_memcpy (mp->client_address, client_address.as_u8,
12511                sizeof (mp->client_address));
12512
12513   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12514
12515   mp->local_session_id = ntohl (local_session_id);
12516   mp->remote_session_id = ntohl (remote_session_id);
12517   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12518   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12519   mp->l2_sublayer_present = l2_sublayer_present;
12520   mp->is_ipv6 = 1;
12521
12522   S (mp);
12523   W (ret);
12524   return ret;
12525 }
12526
12527 static int
12528 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12529 {
12530   unformat_input_t *i = vam->input;
12531   u32 sw_if_index;
12532   u8 sw_if_index_set = 0;
12533   u64 new_local_cookie = 0;
12534   u64 new_remote_cookie = 0;
12535   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12536   int ret;
12537
12538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12539     {
12540       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12541         sw_if_index_set = 1;
12542       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12543         sw_if_index_set = 1;
12544       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12545         ;
12546       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12547         ;
12548       else
12549         break;
12550     }
12551
12552   if (sw_if_index_set == 0)
12553     {
12554       errmsg ("missing interface name or sw_if_index");
12555       return -99;
12556     }
12557
12558   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12559
12560   mp->sw_if_index = ntohl (sw_if_index);
12561   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12562   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12563
12564   S (mp);
12565   W (ret);
12566   return ret;
12567 }
12568
12569 static int
12570 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12571 {
12572   unformat_input_t *i = vam->input;
12573   vl_api_l2tpv3_interface_enable_disable_t *mp;
12574   u32 sw_if_index;
12575   u8 sw_if_index_set = 0;
12576   u8 enable_disable = 1;
12577   int ret;
12578
12579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12580     {
12581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12582         sw_if_index_set = 1;
12583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12584         sw_if_index_set = 1;
12585       else if (unformat (i, "enable"))
12586         enable_disable = 1;
12587       else if (unformat (i, "disable"))
12588         enable_disable = 0;
12589       else
12590         break;
12591     }
12592
12593   if (sw_if_index_set == 0)
12594     {
12595       errmsg ("missing interface name or sw_if_index");
12596       return -99;
12597     }
12598
12599   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12600
12601   mp->sw_if_index = ntohl (sw_if_index);
12602   mp->enable_disable = enable_disable;
12603
12604   S (mp);
12605   W (ret);
12606   return ret;
12607 }
12608
12609 static int
12610 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12611 {
12612   unformat_input_t *i = vam->input;
12613   vl_api_l2tpv3_set_lookup_key_t *mp;
12614   u8 key = ~0;
12615   int ret;
12616
12617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12618     {
12619       if (unformat (i, "lookup_v6_src"))
12620         key = L2T_LOOKUP_SRC_ADDRESS;
12621       else if (unformat (i, "lookup_v6_dst"))
12622         key = L2T_LOOKUP_DST_ADDRESS;
12623       else if (unformat (i, "lookup_session_id"))
12624         key = L2T_LOOKUP_SESSION_ID;
12625       else
12626         break;
12627     }
12628
12629   if (key == (u8) ~ 0)
12630     {
12631       errmsg ("l2tp session lookup key unset");
12632       return -99;
12633     }
12634
12635   M (L2TPV3_SET_LOOKUP_KEY, mp);
12636
12637   mp->key = key;
12638
12639   S (mp);
12640   W (ret);
12641   return ret;
12642 }
12643
12644 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12645   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12646 {
12647   vat_main_t *vam = &vat_main;
12648
12649   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12650          format_ip6_address, mp->our_address,
12651          format_ip6_address, mp->client_address,
12652          clib_net_to_host_u32 (mp->sw_if_index));
12653
12654   print (vam->ofp,
12655          "   local cookies %016llx %016llx remote cookie %016llx",
12656          clib_net_to_host_u64 (mp->local_cookie[0]),
12657          clib_net_to_host_u64 (mp->local_cookie[1]),
12658          clib_net_to_host_u64 (mp->remote_cookie));
12659
12660   print (vam->ofp, "   local session-id %d remote session-id %d",
12661          clib_net_to_host_u32 (mp->local_session_id),
12662          clib_net_to_host_u32 (mp->remote_session_id));
12663
12664   print (vam->ofp, "   l2 specific sublayer %s\n",
12665          mp->l2_sublayer_present ? "preset" : "absent");
12666
12667 }
12668
12669 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12670   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12671 {
12672   vat_main_t *vam = &vat_main;
12673   vat_json_node_t *node = NULL;
12674   struct in6_addr addr;
12675
12676   if (VAT_JSON_ARRAY != vam->json_tree.type)
12677     {
12678       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12679       vat_json_init_array (&vam->json_tree);
12680     }
12681   node = vat_json_array_add (&vam->json_tree);
12682
12683   vat_json_init_object (node);
12684
12685   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12686   vat_json_object_add_ip6 (node, "our_address", addr);
12687   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12688   vat_json_object_add_ip6 (node, "client_address", addr);
12689
12690   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12691   vat_json_init_array (lc);
12692   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12693   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12694   vat_json_object_add_uint (node, "remote_cookie",
12695                             clib_net_to_host_u64 (mp->remote_cookie));
12696
12697   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12698   vat_json_object_add_uint (node, "local_session_id",
12699                             clib_net_to_host_u32 (mp->local_session_id));
12700   vat_json_object_add_uint (node, "remote_session_id",
12701                             clib_net_to_host_u32 (mp->remote_session_id));
12702   vat_json_object_add_string_copy (node, "l2_sublayer",
12703                                    mp->l2_sublayer_present ? (u8 *) "present"
12704                                    : (u8 *) "absent");
12705 }
12706
12707 static int
12708 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12709 {
12710   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12711   vl_api_control_ping_t *mp_ping;
12712   int ret;
12713
12714   /* Get list of l2tpv3-tunnel interfaces */
12715   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12716   S (mp);
12717
12718   /* Use a control ping for synchronization */
12719   MPING (CONTROL_PING, mp_ping);
12720   S (mp_ping);
12721
12722   W (ret);
12723   return ret;
12724 }
12725
12726
12727 static void vl_api_sw_interface_tap_details_t_handler
12728   (vl_api_sw_interface_tap_details_t * mp)
12729 {
12730   vat_main_t *vam = &vat_main;
12731
12732   print (vam->ofp, "%-16s %d",
12733          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12734 }
12735
12736 static void vl_api_sw_interface_tap_details_t_handler_json
12737   (vl_api_sw_interface_tap_details_t * mp)
12738 {
12739   vat_main_t *vam = &vat_main;
12740   vat_json_node_t *node = NULL;
12741
12742   if (VAT_JSON_ARRAY != vam->json_tree.type)
12743     {
12744       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12745       vat_json_init_array (&vam->json_tree);
12746     }
12747   node = vat_json_array_add (&vam->json_tree);
12748
12749   vat_json_init_object (node);
12750   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12751   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12752 }
12753
12754 static int
12755 api_sw_interface_tap_dump (vat_main_t * vam)
12756 {
12757   vl_api_sw_interface_tap_dump_t *mp;
12758   vl_api_control_ping_t *mp_ping;
12759   int ret;
12760
12761   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12762   /* Get list of tap interfaces */
12763   M (SW_INTERFACE_TAP_DUMP, mp);
12764   S (mp);
12765
12766   /* Use a control ping for synchronization */
12767   MPING (CONTROL_PING, mp_ping);
12768   S (mp_ping);
12769
12770   W (ret);
12771   return ret;
12772 }
12773
12774 static void vl_api_sw_interface_tap_v2_details_t_handler
12775   (vl_api_sw_interface_tap_v2_details_t * mp)
12776 {
12777   vat_main_t *vam = &vat_main;
12778
12779   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12780                     mp->host_ip4_prefix_len);
12781   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12782                     mp->host_ip6_prefix_len);
12783
12784   print (vam->ofp,
12785          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12786          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12787          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12788          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12789          mp->host_bridge, ip4, ip6);
12790
12791   vec_free (ip4);
12792   vec_free (ip6);
12793 }
12794
12795 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12796   (vl_api_sw_interface_tap_v2_details_t * mp)
12797 {
12798   vat_main_t *vam = &vat_main;
12799   vat_json_node_t *node = NULL;
12800
12801   if (VAT_JSON_ARRAY != vam->json_tree.type)
12802     {
12803       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12804       vat_json_init_array (&vam->json_tree);
12805     }
12806   node = vat_json_array_add (&vam->json_tree);
12807
12808   vat_json_init_object (node);
12809   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12810   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12811   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12812   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12813   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12814   vat_json_object_add_string_copy (node, "host_mac_addr",
12815                                    format (0, "%U", format_ethernet_address,
12816                                            &mp->host_mac_addr));
12817   vat_json_object_add_string_copy (node, "host_namespace",
12818                                    mp->host_namespace);
12819   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12820   vat_json_object_add_string_copy (node, "host_ip4_addr",
12821                                    format (0, "%U/%d", format_ip4_address,
12822                                            mp->host_ip4_addr,
12823                                            mp->host_ip4_prefix_len));
12824   vat_json_object_add_string_copy (node, "host_ip6_addr",
12825                                    format (0, "%U/%d", format_ip6_address,
12826                                            mp->host_ip6_addr,
12827                                            mp->host_ip6_prefix_len));
12828
12829 }
12830
12831 static int
12832 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12833 {
12834   vl_api_sw_interface_tap_v2_dump_t *mp;
12835   vl_api_control_ping_t *mp_ping;
12836   int ret;
12837
12838   print (vam->ofp,
12839          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12840          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12841          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12842          "host_ip6_addr");
12843
12844   /* Get list of tap interfaces */
12845   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12846   S (mp);
12847
12848   /* Use a control ping for synchronization */
12849   MPING (CONTROL_PING, mp_ping);
12850   S (mp_ping);
12851
12852   W (ret);
12853   return ret;
12854 }
12855
12856 static uword unformat_vxlan_decap_next
12857   (unformat_input_t * input, va_list * args)
12858 {
12859   u32 *result = va_arg (*args, u32 *);
12860   u32 tmp;
12861
12862   if (unformat (input, "l2"))
12863     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12864   else if (unformat (input, "%d", &tmp))
12865     *result = tmp;
12866   else
12867     return 0;
12868   return 1;
12869 }
12870
12871 static int
12872 api_vxlan_add_del_tunnel (vat_main_t * vam)
12873 {
12874   unformat_input_t *line_input = vam->input;
12875   vl_api_vxlan_add_del_tunnel_t *mp;
12876   ip46_address_t src, dst;
12877   u8 is_add = 1;
12878   u8 ipv4_set = 0, ipv6_set = 0;
12879   u8 src_set = 0;
12880   u8 dst_set = 0;
12881   u8 grp_set = 0;
12882   u32 instance = ~0;
12883   u32 mcast_sw_if_index = ~0;
12884   u32 encap_vrf_id = 0;
12885   u32 decap_next_index = ~0;
12886   u32 vni = 0;
12887   int ret;
12888
12889   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12890   memset (&src, 0, sizeof src);
12891   memset (&dst, 0, sizeof dst);
12892
12893   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12894     {
12895       if (unformat (line_input, "del"))
12896         is_add = 0;
12897       else if (unformat (line_input, "instance %d", &instance))
12898         ;
12899       else
12900         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12901         {
12902           ipv4_set = 1;
12903           src_set = 1;
12904         }
12905       else
12906         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12907         {
12908           ipv4_set = 1;
12909           dst_set = 1;
12910         }
12911       else
12912         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12913         {
12914           ipv6_set = 1;
12915           src_set = 1;
12916         }
12917       else
12918         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12919         {
12920           ipv6_set = 1;
12921           dst_set = 1;
12922         }
12923       else if (unformat (line_input, "group %U %U",
12924                          unformat_ip4_address, &dst.ip4,
12925                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12926         {
12927           grp_set = dst_set = 1;
12928           ipv4_set = 1;
12929         }
12930       else if (unformat (line_input, "group %U",
12931                          unformat_ip4_address, &dst.ip4))
12932         {
12933           grp_set = dst_set = 1;
12934           ipv4_set = 1;
12935         }
12936       else if (unformat (line_input, "group %U %U",
12937                          unformat_ip6_address, &dst.ip6,
12938                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12939         {
12940           grp_set = dst_set = 1;
12941           ipv6_set = 1;
12942         }
12943       else if (unformat (line_input, "group %U",
12944                          unformat_ip6_address, &dst.ip6))
12945         {
12946           grp_set = dst_set = 1;
12947           ipv6_set = 1;
12948         }
12949       else
12950         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12951         ;
12952       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12953         ;
12954       else if (unformat (line_input, "decap-next %U",
12955                          unformat_vxlan_decap_next, &decap_next_index))
12956         ;
12957       else if (unformat (line_input, "vni %d", &vni))
12958         ;
12959       else
12960         {
12961           errmsg ("parse error '%U'", format_unformat_error, line_input);
12962           return -99;
12963         }
12964     }
12965
12966   if (src_set == 0)
12967     {
12968       errmsg ("tunnel src address not specified");
12969       return -99;
12970     }
12971   if (dst_set == 0)
12972     {
12973       errmsg ("tunnel dst address not specified");
12974       return -99;
12975     }
12976
12977   if (grp_set && !ip46_address_is_multicast (&dst))
12978     {
12979       errmsg ("tunnel group address not multicast");
12980       return -99;
12981     }
12982   if (grp_set && mcast_sw_if_index == ~0)
12983     {
12984       errmsg ("tunnel nonexistent multicast device");
12985       return -99;
12986     }
12987   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12988     {
12989       errmsg ("tunnel dst address must be unicast");
12990       return -99;
12991     }
12992
12993
12994   if (ipv4_set && ipv6_set)
12995     {
12996       errmsg ("both IPv4 and IPv6 addresses specified");
12997       return -99;
12998     }
12999
13000   if ((vni == 0) || (vni >> 24))
13001     {
13002       errmsg ("vni not specified or out of range");
13003       return -99;
13004     }
13005
13006   M (VXLAN_ADD_DEL_TUNNEL, mp);
13007
13008   if (ipv6_set)
13009     {
13010       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13011       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13012     }
13013   else
13014     {
13015       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13016       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13017     }
13018
13019   mp->instance = htonl (instance);
13020   mp->encap_vrf_id = ntohl (encap_vrf_id);
13021   mp->decap_next_index = ntohl (decap_next_index);
13022   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13023   mp->vni = ntohl (vni);
13024   mp->is_add = is_add;
13025   mp->is_ipv6 = ipv6_set;
13026
13027   S (mp);
13028   W (ret);
13029   return ret;
13030 }
13031
13032 static void vl_api_vxlan_tunnel_details_t_handler
13033   (vl_api_vxlan_tunnel_details_t * mp)
13034 {
13035   vat_main_t *vam = &vat_main;
13036   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13037   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13038
13039   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13040          ntohl (mp->sw_if_index),
13041          ntohl (mp->instance),
13042          format_ip46_address, &src, IP46_TYPE_ANY,
13043          format_ip46_address, &dst, IP46_TYPE_ANY,
13044          ntohl (mp->encap_vrf_id),
13045          ntohl (mp->decap_next_index), ntohl (mp->vni),
13046          ntohl (mp->mcast_sw_if_index));
13047 }
13048
13049 static void vl_api_vxlan_tunnel_details_t_handler_json
13050   (vl_api_vxlan_tunnel_details_t * mp)
13051 {
13052   vat_main_t *vam = &vat_main;
13053   vat_json_node_t *node = NULL;
13054
13055   if (VAT_JSON_ARRAY != vam->json_tree.type)
13056     {
13057       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13058       vat_json_init_array (&vam->json_tree);
13059     }
13060   node = vat_json_array_add (&vam->json_tree);
13061
13062   vat_json_init_object (node);
13063   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13064
13065   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13066
13067   if (mp->is_ipv6)
13068     {
13069       struct in6_addr ip6;
13070
13071       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13072       vat_json_object_add_ip6 (node, "src_address", ip6);
13073       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13074       vat_json_object_add_ip6 (node, "dst_address", ip6);
13075     }
13076   else
13077     {
13078       struct in_addr ip4;
13079
13080       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13081       vat_json_object_add_ip4 (node, "src_address", ip4);
13082       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13083       vat_json_object_add_ip4 (node, "dst_address", ip4);
13084     }
13085   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13086   vat_json_object_add_uint (node, "decap_next_index",
13087                             ntohl (mp->decap_next_index));
13088   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13089   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13090   vat_json_object_add_uint (node, "mcast_sw_if_index",
13091                             ntohl (mp->mcast_sw_if_index));
13092 }
13093
13094 static int
13095 api_vxlan_tunnel_dump (vat_main_t * vam)
13096 {
13097   unformat_input_t *i = vam->input;
13098   vl_api_vxlan_tunnel_dump_t *mp;
13099   vl_api_control_ping_t *mp_ping;
13100   u32 sw_if_index;
13101   u8 sw_if_index_set = 0;
13102   int ret;
13103
13104   /* Parse args required to build the message */
13105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13106     {
13107       if (unformat (i, "sw_if_index %d", &sw_if_index))
13108         sw_if_index_set = 1;
13109       else
13110         break;
13111     }
13112
13113   if (sw_if_index_set == 0)
13114     {
13115       sw_if_index = ~0;
13116     }
13117
13118   if (!vam->json_output)
13119     {
13120       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13121              "sw_if_index", "instance", "src_address", "dst_address",
13122              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13123     }
13124
13125   /* Get list of vxlan-tunnel interfaces */
13126   M (VXLAN_TUNNEL_DUMP, mp);
13127
13128   mp->sw_if_index = htonl (sw_if_index);
13129
13130   S (mp);
13131
13132   /* Use a control ping for synchronization */
13133   MPING (CONTROL_PING, mp_ping);
13134   S (mp_ping);
13135
13136   W (ret);
13137   return ret;
13138 }
13139
13140 static uword unformat_geneve_decap_next
13141   (unformat_input_t * input, va_list * args)
13142 {
13143   u32 *result = va_arg (*args, u32 *);
13144   u32 tmp;
13145
13146   if (unformat (input, "l2"))
13147     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13148   else if (unformat (input, "%d", &tmp))
13149     *result = tmp;
13150   else
13151     return 0;
13152   return 1;
13153 }
13154
13155 static int
13156 api_geneve_add_del_tunnel (vat_main_t * vam)
13157 {
13158   unformat_input_t *line_input = vam->input;
13159   vl_api_geneve_add_del_tunnel_t *mp;
13160   ip46_address_t src, dst;
13161   u8 is_add = 1;
13162   u8 ipv4_set = 0, ipv6_set = 0;
13163   u8 src_set = 0;
13164   u8 dst_set = 0;
13165   u8 grp_set = 0;
13166   u32 mcast_sw_if_index = ~0;
13167   u32 encap_vrf_id = 0;
13168   u32 decap_next_index = ~0;
13169   u32 vni = 0;
13170   int ret;
13171
13172   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13173   memset (&src, 0, sizeof src);
13174   memset (&dst, 0, sizeof dst);
13175
13176   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13177     {
13178       if (unformat (line_input, "del"))
13179         is_add = 0;
13180       else
13181         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13182         {
13183           ipv4_set = 1;
13184           src_set = 1;
13185         }
13186       else
13187         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13188         {
13189           ipv4_set = 1;
13190           dst_set = 1;
13191         }
13192       else
13193         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13194         {
13195           ipv6_set = 1;
13196           src_set = 1;
13197         }
13198       else
13199         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13200         {
13201           ipv6_set = 1;
13202           dst_set = 1;
13203         }
13204       else if (unformat (line_input, "group %U %U",
13205                          unformat_ip4_address, &dst.ip4,
13206                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13207         {
13208           grp_set = dst_set = 1;
13209           ipv4_set = 1;
13210         }
13211       else if (unformat (line_input, "group %U",
13212                          unformat_ip4_address, &dst.ip4))
13213         {
13214           grp_set = dst_set = 1;
13215           ipv4_set = 1;
13216         }
13217       else if (unformat (line_input, "group %U %U",
13218                          unformat_ip6_address, &dst.ip6,
13219                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13220         {
13221           grp_set = dst_set = 1;
13222           ipv6_set = 1;
13223         }
13224       else if (unformat (line_input, "group %U",
13225                          unformat_ip6_address, &dst.ip6))
13226         {
13227           grp_set = dst_set = 1;
13228           ipv6_set = 1;
13229         }
13230       else
13231         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13232         ;
13233       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13234         ;
13235       else if (unformat (line_input, "decap-next %U",
13236                          unformat_geneve_decap_next, &decap_next_index))
13237         ;
13238       else if (unformat (line_input, "vni %d", &vni))
13239         ;
13240       else
13241         {
13242           errmsg ("parse error '%U'", format_unformat_error, line_input);
13243           return -99;
13244         }
13245     }
13246
13247   if (src_set == 0)
13248     {
13249       errmsg ("tunnel src address not specified");
13250       return -99;
13251     }
13252   if (dst_set == 0)
13253     {
13254       errmsg ("tunnel dst address not specified");
13255       return -99;
13256     }
13257
13258   if (grp_set && !ip46_address_is_multicast (&dst))
13259     {
13260       errmsg ("tunnel group address not multicast");
13261       return -99;
13262     }
13263   if (grp_set && mcast_sw_if_index == ~0)
13264     {
13265       errmsg ("tunnel nonexistent multicast device");
13266       return -99;
13267     }
13268   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13269     {
13270       errmsg ("tunnel dst address must be unicast");
13271       return -99;
13272     }
13273
13274
13275   if (ipv4_set && ipv6_set)
13276     {
13277       errmsg ("both IPv4 and IPv6 addresses specified");
13278       return -99;
13279     }
13280
13281   if ((vni == 0) || (vni >> 24))
13282     {
13283       errmsg ("vni not specified or out of range");
13284       return -99;
13285     }
13286
13287   M (GENEVE_ADD_DEL_TUNNEL, mp);
13288
13289   if (ipv6_set)
13290     {
13291       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13292       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13293     }
13294   else
13295     {
13296       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13297       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13298     }
13299   mp->encap_vrf_id = ntohl (encap_vrf_id);
13300   mp->decap_next_index = ntohl (decap_next_index);
13301   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13302   mp->vni = ntohl (vni);
13303   mp->is_add = is_add;
13304   mp->is_ipv6 = ipv6_set;
13305
13306   S (mp);
13307   W (ret);
13308   return ret;
13309 }
13310
13311 static void vl_api_geneve_tunnel_details_t_handler
13312   (vl_api_geneve_tunnel_details_t * mp)
13313 {
13314   vat_main_t *vam = &vat_main;
13315   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13316   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13317
13318   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13319          ntohl (mp->sw_if_index),
13320          format_ip46_address, &src, IP46_TYPE_ANY,
13321          format_ip46_address, &dst, IP46_TYPE_ANY,
13322          ntohl (mp->encap_vrf_id),
13323          ntohl (mp->decap_next_index), ntohl (mp->vni),
13324          ntohl (mp->mcast_sw_if_index));
13325 }
13326
13327 static void vl_api_geneve_tunnel_details_t_handler_json
13328   (vl_api_geneve_tunnel_details_t * mp)
13329 {
13330   vat_main_t *vam = &vat_main;
13331   vat_json_node_t *node = NULL;
13332
13333   if (VAT_JSON_ARRAY != vam->json_tree.type)
13334     {
13335       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13336       vat_json_init_array (&vam->json_tree);
13337     }
13338   node = vat_json_array_add (&vam->json_tree);
13339
13340   vat_json_init_object (node);
13341   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13342   if (mp->is_ipv6)
13343     {
13344       struct in6_addr ip6;
13345
13346       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13347       vat_json_object_add_ip6 (node, "src_address", ip6);
13348       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13349       vat_json_object_add_ip6 (node, "dst_address", ip6);
13350     }
13351   else
13352     {
13353       struct in_addr ip4;
13354
13355       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13356       vat_json_object_add_ip4 (node, "src_address", ip4);
13357       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13358       vat_json_object_add_ip4 (node, "dst_address", ip4);
13359     }
13360   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13361   vat_json_object_add_uint (node, "decap_next_index",
13362                             ntohl (mp->decap_next_index));
13363   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13364   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13365   vat_json_object_add_uint (node, "mcast_sw_if_index",
13366                             ntohl (mp->mcast_sw_if_index));
13367 }
13368
13369 static int
13370 api_geneve_tunnel_dump (vat_main_t * vam)
13371 {
13372   unformat_input_t *i = vam->input;
13373   vl_api_geneve_tunnel_dump_t *mp;
13374   vl_api_control_ping_t *mp_ping;
13375   u32 sw_if_index;
13376   u8 sw_if_index_set = 0;
13377   int ret;
13378
13379   /* Parse args required to build the message */
13380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13381     {
13382       if (unformat (i, "sw_if_index %d", &sw_if_index))
13383         sw_if_index_set = 1;
13384       else
13385         break;
13386     }
13387
13388   if (sw_if_index_set == 0)
13389     {
13390       sw_if_index = ~0;
13391     }
13392
13393   if (!vam->json_output)
13394     {
13395       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13396              "sw_if_index", "local_address", "remote_address",
13397              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13398     }
13399
13400   /* Get list of geneve-tunnel interfaces */
13401   M (GENEVE_TUNNEL_DUMP, mp);
13402
13403   mp->sw_if_index = htonl (sw_if_index);
13404
13405   S (mp);
13406
13407   /* Use a control ping for synchronization */
13408   M (CONTROL_PING, mp_ping);
13409   S (mp_ping);
13410
13411   W (ret);
13412   return ret;
13413 }
13414
13415 static int
13416 api_gre_add_del_tunnel (vat_main_t * vam)
13417 {
13418   unformat_input_t *line_input = vam->input;
13419   vl_api_gre_add_del_tunnel_t *mp;
13420   ip4_address_t src4, dst4;
13421   ip6_address_t src6, dst6;
13422   u8 is_add = 1;
13423   u8 ipv4_set = 0;
13424   u8 ipv6_set = 0;
13425   u8 t_type = GRE_TUNNEL_TYPE_L3;
13426   u8 src_set = 0;
13427   u8 dst_set = 0;
13428   u32 outer_fib_id = 0;
13429   u32 session_id = 0;
13430   u32 instance = ~0;
13431   int ret;
13432
13433   memset (&src4, 0, sizeof src4);
13434   memset (&dst4, 0, sizeof dst4);
13435   memset (&src6, 0, sizeof src6);
13436   memset (&dst6, 0, sizeof dst6);
13437
13438   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13439     {
13440       if (unformat (line_input, "del"))
13441         is_add = 0;
13442       else if (unformat (line_input, "instance %d", &instance))
13443         ;
13444       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13445         {
13446           src_set = 1;
13447           ipv4_set = 1;
13448         }
13449       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13450         {
13451           dst_set = 1;
13452           ipv4_set = 1;
13453         }
13454       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13455         {
13456           src_set = 1;
13457           ipv6_set = 1;
13458         }
13459       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13460         {
13461           dst_set = 1;
13462           ipv6_set = 1;
13463         }
13464       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13465         ;
13466       else if (unformat (line_input, "teb"))
13467         t_type = GRE_TUNNEL_TYPE_TEB;
13468       else if (unformat (line_input, "erspan %d", &session_id))
13469         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13470       else
13471         {
13472           errmsg ("parse error '%U'", format_unformat_error, line_input);
13473           return -99;
13474         }
13475     }
13476
13477   if (src_set == 0)
13478     {
13479       errmsg ("tunnel src address not specified");
13480       return -99;
13481     }
13482   if (dst_set == 0)
13483     {
13484       errmsg ("tunnel dst address not specified");
13485       return -99;
13486     }
13487   if (ipv4_set && ipv6_set)
13488     {
13489       errmsg ("both IPv4 and IPv6 addresses specified");
13490       return -99;
13491     }
13492
13493
13494   M (GRE_ADD_DEL_TUNNEL, mp);
13495
13496   if (ipv4_set)
13497     {
13498       clib_memcpy (&mp->src_address, &src4, 4);
13499       clib_memcpy (&mp->dst_address, &dst4, 4);
13500     }
13501   else
13502     {
13503       clib_memcpy (&mp->src_address, &src6, 16);
13504       clib_memcpy (&mp->dst_address, &dst6, 16);
13505     }
13506   mp->instance = htonl (instance);
13507   mp->outer_fib_id = htonl (outer_fib_id);
13508   mp->is_add = is_add;
13509   mp->session_id = htons ((u16) session_id);
13510   mp->tunnel_type = t_type;
13511   mp->is_ipv6 = ipv6_set;
13512
13513   S (mp);
13514   W (ret);
13515   return ret;
13516 }
13517
13518 static void vl_api_gre_tunnel_details_t_handler
13519   (vl_api_gre_tunnel_details_t * mp)
13520 {
13521   vat_main_t *vam = &vat_main;
13522   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13523   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13524
13525   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13526          ntohl (mp->sw_if_index),
13527          ntohl (mp->instance),
13528          format_ip46_address, &src, IP46_TYPE_ANY,
13529          format_ip46_address, &dst, IP46_TYPE_ANY,
13530          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13531 }
13532
13533 static void vl_api_gre_tunnel_details_t_handler_json
13534   (vl_api_gre_tunnel_details_t * mp)
13535 {
13536   vat_main_t *vam = &vat_main;
13537   vat_json_node_t *node = NULL;
13538   struct in_addr ip4;
13539   struct in6_addr ip6;
13540
13541   if (VAT_JSON_ARRAY != vam->json_tree.type)
13542     {
13543       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13544       vat_json_init_array (&vam->json_tree);
13545     }
13546   node = vat_json_array_add (&vam->json_tree);
13547
13548   vat_json_init_object (node);
13549   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13550   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13551   if (!mp->is_ipv6)
13552     {
13553       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13554       vat_json_object_add_ip4 (node, "src_address", ip4);
13555       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13556       vat_json_object_add_ip4 (node, "dst_address", ip4);
13557     }
13558   else
13559     {
13560       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13561       vat_json_object_add_ip6 (node, "src_address", ip6);
13562       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13563       vat_json_object_add_ip6 (node, "dst_address", ip6);
13564     }
13565   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13566   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13567   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13568   vat_json_object_add_uint (node, "session_id", mp->session_id);
13569 }
13570
13571 static int
13572 api_gre_tunnel_dump (vat_main_t * vam)
13573 {
13574   unformat_input_t *i = vam->input;
13575   vl_api_gre_tunnel_dump_t *mp;
13576   vl_api_control_ping_t *mp_ping;
13577   u32 sw_if_index;
13578   u8 sw_if_index_set = 0;
13579   int ret;
13580
13581   /* Parse args required to build the message */
13582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13583     {
13584       if (unformat (i, "sw_if_index %d", &sw_if_index))
13585         sw_if_index_set = 1;
13586       else
13587         break;
13588     }
13589
13590   if (sw_if_index_set == 0)
13591     {
13592       sw_if_index = ~0;
13593     }
13594
13595   if (!vam->json_output)
13596     {
13597       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13598              "sw_if_index", "instance", "src_address", "dst_address",
13599              "tunnel_type", "outer_fib_id", "session_id");
13600     }
13601
13602   /* Get list of gre-tunnel interfaces */
13603   M (GRE_TUNNEL_DUMP, mp);
13604
13605   mp->sw_if_index = htonl (sw_if_index);
13606
13607   S (mp);
13608
13609   /* Use a control ping for synchronization */
13610   MPING (CONTROL_PING, mp_ping);
13611   S (mp_ping);
13612
13613   W (ret);
13614   return ret;
13615 }
13616
13617 static int
13618 api_l2_fib_clear_table (vat_main_t * vam)
13619 {
13620 //  unformat_input_t * i = vam->input;
13621   vl_api_l2_fib_clear_table_t *mp;
13622   int ret;
13623
13624   M (L2_FIB_CLEAR_TABLE, mp);
13625
13626   S (mp);
13627   W (ret);
13628   return ret;
13629 }
13630
13631 static int
13632 api_l2_interface_efp_filter (vat_main_t * vam)
13633 {
13634   unformat_input_t *i = vam->input;
13635   vl_api_l2_interface_efp_filter_t *mp;
13636   u32 sw_if_index;
13637   u8 enable = 1;
13638   u8 sw_if_index_set = 0;
13639   int ret;
13640
13641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13642     {
13643       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13644         sw_if_index_set = 1;
13645       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13646         sw_if_index_set = 1;
13647       else if (unformat (i, "enable"))
13648         enable = 1;
13649       else if (unformat (i, "disable"))
13650         enable = 0;
13651       else
13652         {
13653           clib_warning ("parse error '%U'", format_unformat_error, i);
13654           return -99;
13655         }
13656     }
13657
13658   if (sw_if_index_set == 0)
13659     {
13660       errmsg ("missing sw_if_index");
13661       return -99;
13662     }
13663
13664   M (L2_INTERFACE_EFP_FILTER, mp);
13665
13666   mp->sw_if_index = ntohl (sw_if_index);
13667   mp->enable_disable = enable;
13668
13669   S (mp);
13670   W (ret);
13671   return ret;
13672 }
13673
13674 #define foreach_vtr_op                          \
13675 _("disable",  L2_VTR_DISABLED)                  \
13676 _("push-1",  L2_VTR_PUSH_1)                     \
13677 _("push-2",  L2_VTR_PUSH_2)                     \
13678 _("pop-1",  L2_VTR_POP_1)                       \
13679 _("pop-2",  L2_VTR_POP_2)                       \
13680 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13681 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13682 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13683 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13684
13685 static int
13686 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13687 {
13688   unformat_input_t *i = vam->input;
13689   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13690   u32 sw_if_index;
13691   u8 sw_if_index_set = 0;
13692   u8 vtr_op_set = 0;
13693   u32 vtr_op = 0;
13694   u32 push_dot1q = 1;
13695   u32 tag1 = ~0;
13696   u32 tag2 = ~0;
13697   int ret;
13698
13699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13700     {
13701       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13702         sw_if_index_set = 1;
13703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13704         sw_if_index_set = 1;
13705       else if (unformat (i, "vtr_op %d", &vtr_op))
13706         vtr_op_set = 1;
13707 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13708       foreach_vtr_op
13709 #undef _
13710         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13711         ;
13712       else if (unformat (i, "tag1 %d", &tag1))
13713         ;
13714       else if (unformat (i, "tag2 %d", &tag2))
13715         ;
13716       else
13717         {
13718           clib_warning ("parse error '%U'", format_unformat_error, i);
13719           return -99;
13720         }
13721     }
13722
13723   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13724     {
13725       errmsg ("missing vtr operation or sw_if_index");
13726       return -99;
13727     }
13728
13729   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13730   mp->sw_if_index = ntohl (sw_if_index);
13731   mp->vtr_op = ntohl (vtr_op);
13732   mp->push_dot1q = ntohl (push_dot1q);
13733   mp->tag1 = ntohl (tag1);
13734   mp->tag2 = ntohl (tag2);
13735
13736   S (mp);
13737   W (ret);
13738   return ret;
13739 }
13740
13741 static int
13742 api_create_vhost_user_if (vat_main_t * vam)
13743 {
13744   unformat_input_t *i = vam->input;
13745   vl_api_create_vhost_user_if_t *mp;
13746   u8 *file_name;
13747   u8 is_server = 0;
13748   u8 file_name_set = 0;
13749   u32 custom_dev_instance = ~0;
13750   u8 hwaddr[6];
13751   u8 use_custom_mac = 0;
13752   u8 *tag = 0;
13753   int ret;
13754
13755   /* Shut up coverity */
13756   memset (hwaddr, 0, sizeof (hwaddr));
13757
13758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13759     {
13760       if (unformat (i, "socket %s", &file_name))
13761         {
13762           file_name_set = 1;
13763         }
13764       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13765         ;
13766       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13767         use_custom_mac = 1;
13768       else if (unformat (i, "server"))
13769         is_server = 1;
13770       else if (unformat (i, "tag %s", &tag))
13771         ;
13772       else
13773         break;
13774     }
13775
13776   if (file_name_set == 0)
13777     {
13778       errmsg ("missing socket file name");
13779       return -99;
13780     }
13781
13782   if (vec_len (file_name) > 255)
13783     {
13784       errmsg ("socket file name too long");
13785       return -99;
13786     }
13787   vec_add1 (file_name, 0);
13788
13789   M (CREATE_VHOST_USER_IF, mp);
13790
13791   mp->is_server = is_server;
13792   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13793   vec_free (file_name);
13794   if (custom_dev_instance != ~0)
13795     {
13796       mp->renumber = 1;
13797       mp->custom_dev_instance = ntohl (custom_dev_instance);
13798     }
13799   mp->use_custom_mac = use_custom_mac;
13800   clib_memcpy (mp->mac_address, hwaddr, 6);
13801   if (tag)
13802     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13803   vec_free (tag);
13804
13805   S (mp);
13806   W (ret);
13807   return ret;
13808 }
13809
13810 static int
13811 api_modify_vhost_user_if (vat_main_t * vam)
13812 {
13813   unformat_input_t *i = vam->input;
13814   vl_api_modify_vhost_user_if_t *mp;
13815   u8 *file_name;
13816   u8 is_server = 0;
13817   u8 file_name_set = 0;
13818   u32 custom_dev_instance = ~0;
13819   u8 sw_if_index_set = 0;
13820   u32 sw_if_index = (u32) ~ 0;
13821   int ret;
13822
13823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13824     {
13825       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13826         sw_if_index_set = 1;
13827       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13828         sw_if_index_set = 1;
13829       else if (unformat (i, "socket %s", &file_name))
13830         {
13831           file_name_set = 1;
13832         }
13833       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13834         ;
13835       else if (unformat (i, "server"))
13836         is_server = 1;
13837       else
13838         break;
13839     }
13840
13841   if (sw_if_index_set == 0)
13842     {
13843       errmsg ("missing sw_if_index or interface name");
13844       return -99;
13845     }
13846
13847   if (file_name_set == 0)
13848     {
13849       errmsg ("missing socket file name");
13850       return -99;
13851     }
13852
13853   if (vec_len (file_name) > 255)
13854     {
13855       errmsg ("socket file name too long");
13856       return -99;
13857     }
13858   vec_add1 (file_name, 0);
13859
13860   M (MODIFY_VHOST_USER_IF, mp);
13861
13862   mp->sw_if_index = ntohl (sw_if_index);
13863   mp->is_server = is_server;
13864   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13865   vec_free (file_name);
13866   if (custom_dev_instance != ~0)
13867     {
13868       mp->renumber = 1;
13869       mp->custom_dev_instance = ntohl (custom_dev_instance);
13870     }
13871
13872   S (mp);
13873   W (ret);
13874   return ret;
13875 }
13876
13877 static int
13878 api_delete_vhost_user_if (vat_main_t * vam)
13879 {
13880   unformat_input_t *i = vam->input;
13881   vl_api_delete_vhost_user_if_t *mp;
13882   u32 sw_if_index = ~0;
13883   u8 sw_if_index_set = 0;
13884   int ret;
13885
13886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13887     {
13888       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13889         sw_if_index_set = 1;
13890       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13891         sw_if_index_set = 1;
13892       else
13893         break;
13894     }
13895
13896   if (sw_if_index_set == 0)
13897     {
13898       errmsg ("missing sw_if_index or interface name");
13899       return -99;
13900     }
13901
13902
13903   M (DELETE_VHOST_USER_IF, mp);
13904
13905   mp->sw_if_index = ntohl (sw_if_index);
13906
13907   S (mp);
13908   W (ret);
13909   return ret;
13910 }
13911
13912 static void vl_api_sw_interface_vhost_user_details_t_handler
13913   (vl_api_sw_interface_vhost_user_details_t * mp)
13914 {
13915   vat_main_t *vam = &vat_main;
13916
13917   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13918          (char *) mp->interface_name,
13919          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13920          clib_net_to_host_u64 (mp->features), mp->is_server,
13921          ntohl (mp->num_regions), (char *) mp->sock_filename);
13922   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13923 }
13924
13925 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13926   (vl_api_sw_interface_vhost_user_details_t * mp)
13927 {
13928   vat_main_t *vam = &vat_main;
13929   vat_json_node_t *node = NULL;
13930
13931   if (VAT_JSON_ARRAY != vam->json_tree.type)
13932     {
13933       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13934       vat_json_init_array (&vam->json_tree);
13935     }
13936   node = vat_json_array_add (&vam->json_tree);
13937
13938   vat_json_init_object (node);
13939   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13940   vat_json_object_add_string_copy (node, "interface_name",
13941                                    mp->interface_name);
13942   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13943                             ntohl (mp->virtio_net_hdr_sz));
13944   vat_json_object_add_uint (node, "features",
13945                             clib_net_to_host_u64 (mp->features));
13946   vat_json_object_add_uint (node, "is_server", mp->is_server);
13947   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13948   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13949   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13950 }
13951
13952 static int
13953 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13954 {
13955   vl_api_sw_interface_vhost_user_dump_t *mp;
13956   vl_api_control_ping_t *mp_ping;
13957   int ret;
13958   print (vam->ofp,
13959          "Interface name            idx hdr_sz features server regions filename");
13960
13961   /* Get list of vhost-user interfaces */
13962   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13963   S (mp);
13964
13965   /* Use a control ping for synchronization */
13966   MPING (CONTROL_PING, mp_ping);
13967   S (mp_ping);
13968
13969   W (ret);
13970   return ret;
13971 }
13972
13973 static int
13974 api_show_version (vat_main_t * vam)
13975 {
13976   vl_api_show_version_t *mp;
13977   int ret;
13978
13979   M (SHOW_VERSION, mp);
13980
13981   S (mp);
13982   W (ret);
13983   return ret;
13984 }
13985
13986
13987 static int
13988 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13989 {
13990   unformat_input_t *line_input = vam->input;
13991   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13992   ip4_address_t local4, remote4;
13993   ip6_address_t local6, remote6;
13994   u8 is_add = 1;
13995   u8 ipv4_set = 0, ipv6_set = 0;
13996   u8 local_set = 0;
13997   u8 remote_set = 0;
13998   u8 grp_set = 0;
13999   u32 mcast_sw_if_index = ~0;
14000   u32 encap_vrf_id = 0;
14001   u32 decap_vrf_id = 0;
14002   u8 protocol = ~0;
14003   u32 vni;
14004   u8 vni_set = 0;
14005   int ret;
14006
14007   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14008   memset (&local4, 0, sizeof local4);
14009   memset (&remote4, 0, sizeof remote4);
14010   memset (&local6, 0, sizeof local6);
14011   memset (&remote6, 0, sizeof remote6);
14012
14013   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14014     {
14015       if (unformat (line_input, "del"))
14016         is_add = 0;
14017       else if (unformat (line_input, "local %U",
14018                          unformat_ip4_address, &local4))
14019         {
14020           local_set = 1;
14021           ipv4_set = 1;
14022         }
14023       else if (unformat (line_input, "remote %U",
14024                          unformat_ip4_address, &remote4))
14025         {
14026           remote_set = 1;
14027           ipv4_set = 1;
14028         }
14029       else if (unformat (line_input, "local %U",
14030                          unformat_ip6_address, &local6))
14031         {
14032           local_set = 1;
14033           ipv6_set = 1;
14034         }
14035       else if (unformat (line_input, "remote %U",
14036                          unformat_ip6_address, &remote6))
14037         {
14038           remote_set = 1;
14039           ipv6_set = 1;
14040         }
14041       else if (unformat (line_input, "group %U %U",
14042                          unformat_ip4_address, &remote4,
14043                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14044         {
14045           grp_set = remote_set = 1;
14046           ipv4_set = 1;
14047         }
14048       else if (unformat (line_input, "group %U",
14049                          unformat_ip4_address, &remote4))
14050         {
14051           grp_set = remote_set = 1;
14052           ipv4_set = 1;
14053         }
14054       else if (unformat (line_input, "group %U %U",
14055                          unformat_ip6_address, &remote6,
14056                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14057         {
14058           grp_set = remote_set = 1;
14059           ipv6_set = 1;
14060         }
14061       else if (unformat (line_input, "group %U",
14062                          unformat_ip6_address, &remote6))
14063         {
14064           grp_set = remote_set = 1;
14065           ipv6_set = 1;
14066         }
14067       else
14068         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14069         ;
14070       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14071         ;
14072       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14073         ;
14074       else if (unformat (line_input, "vni %d", &vni))
14075         vni_set = 1;
14076       else if (unformat (line_input, "next-ip4"))
14077         protocol = 1;
14078       else if (unformat (line_input, "next-ip6"))
14079         protocol = 2;
14080       else if (unformat (line_input, "next-ethernet"))
14081         protocol = 3;
14082       else if (unformat (line_input, "next-nsh"))
14083         protocol = 4;
14084       else
14085         {
14086           errmsg ("parse error '%U'", format_unformat_error, line_input);
14087           return -99;
14088         }
14089     }
14090
14091   if (local_set == 0)
14092     {
14093       errmsg ("tunnel local address not specified");
14094       return -99;
14095     }
14096   if (remote_set == 0)
14097     {
14098       errmsg ("tunnel remote address not specified");
14099       return -99;
14100     }
14101   if (grp_set && mcast_sw_if_index == ~0)
14102     {
14103       errmsg ("tunnel nonexistent multicast device");
14104       return -99;
14105     }
14106   if (ipv4_set && ipv6_set)
14107     {
14108       errmsg ("both IPv4 and IPv6 addresses specified");
14109       return -99;
14110     }
14111
14112   if (vni_set == 0)
14113     {
14114       errmsg ("vni not specified");
14115       return -99;
14116     }
14117
14118   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14119
14120
14121   if (ipv6_set)
14122     {
14123       clib_memcpy (&mp->local, &local6, sizeof (local6));
14124       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14125     }
14126   else
14127     {
14128       clib_memcpy (&mp->local, &local4, sizeof (local4));
14129       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14130     }
14131
14132   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14133   mp->encap_vrf_id = ntohl (encap_vrf_id);
14134   mp->decap_vrf_id = ntohl (decap_vrf_id);
14135   mp->protocol = protocol;
14136   mp->vni = ntohl (vni);
14137   mp->is_add = is_add;
14138   mp->is_ipv6 = ipv6_set;
14139
14140   S (mp);
14141   W (ret);
14142   return ret;
14143 }
14144
14145 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14146   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14147 {
14148   vat_main_t *vam = &vat_main;
14149   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14150   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14151
14152   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14153          ntohl (mp->sw_if_index),
14154          format_ip46_address, &local, IP46_TYPE_ANY,
14155          format_ip46_address, &remote, IP46_TYPE_ANY,
14156          ntohl (mp->vni), mp->protocol,
14157          ntohl (mp->mcast_sw_if_index),
14158          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14159 }
14160
14161
14162 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14163   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14164 {
14165   vat_main_t *vam = &vat_main;
14166   vat_json_node_t *node = NULL;
14167   struct in_addr ip4;
14168   struct in6_addr ip6;
14169
14170   if (VAT_JSON_ARRAY != vam->json_tree.type)
14171     {
14172       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14173       vat_json_init_array (&vam->json_tree);
14174     }
14175   node = vat_json_array_add (&vam->json_tree);
14176
14177   vat_json_init_object (node);
14178   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14179   if (mp->is_ipv6)
14180     {
14181       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14182       vat_json_object_add_ip6 (node, "local", ip6);
14183       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14184       vat_json_object_add_ip6 (node, "remote", ip6);
14185     }
14186   else
14187     {
14188       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14189       vat_json_object_add_ip4 (node, "local", ip4);
14190       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14191       vat_json_object_add_ip4 (node, "remote", ip4);
14192     }
14193   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14194   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14195   vat_json_object_add_uint (node, "mcast_sw_if_index",
14196                             ntohl (mp->mcast_sw_if_index));
14197   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14198   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14199   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14200 }
14201
14202 static int
14203 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14204 {
14205   unformat_input_t *i = vam->input;
14206   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14207   vl_api_control_ping_t *mp_ping;
14208   u32 sw_if_index;
14209   u8 sw_if_index_set = 0;
14210   int ret;
14211
14212   /* Parse args required to build the message */
14213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14214     {
14215       if (unformat (i, "sw_if_index %d", &sw_if_index))
14216         sw_if_index_set = 1;
14217       else
14218         break;
14219     }
14220
14221   if (sw_if_index_set == 0)
14222     {
14223       sw_if_index = ~0;
14224     }
14225
14226   if (!vam->json_output)
14227     {
14228       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14229              "sw_if_index", "local", "remote", "vni",
14230              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14231     }
14232
14233   /* Get list of vxlan-tunnel interfaces */
14234   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14235
14236   mp->sw_if_index = htonl (sw_if_index);
14237
14238   S (mp);
14239
14240   /* Use a control ping for synchronization */
14241   MPING (CONTROL_PING, mp_ping);
14242   S (mp_ping);
14243
14244   W (ret);
14245   return ret;
14246 }
14247
14248 static void vl_api_l2_fib_table_details_t_handler
14249   (vl_api_l2_fib_table_details_t * mp)
14250 {
14251   vat_main_t *vam = &vat_main;
14252
14253   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14254          "       %d       %d     %d",
14255          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14256          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14257          mp->bvi_mac);
14258 }
14259
14260 static void vl_api_l2_fib_table_details_t_handler_json
14261   (vl_api_l2_fib_table_details_t * mp)
14262 {
14263   vat_main_t *vam = &vat_main;
14264   vat_json_node_t *node = NULL;
14265
14266   if (VAT_JSON_ARRAY != vam->json_tree.type)
14267     {
14268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14269       vat_json_init_array (&vam->json_tree);
14270     }
14271   node = vat_json_array_add (&vam->json_tree);
14272
14273   vat_json_init_object (node);
14274   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14275   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14276   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14277   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14278   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14279   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14280 }
14281
14282 static int
14283 api_l2_fib_table_dump (vat_main_t * vam)
14284 {
14285   unformat_input_t *i = vam->input;
14286   vl_api_l2_fib_table_dump_t *mp;
14287   vl_api_control_ping_t *mp_ping;
14288   u32 bd_id;
14289   u8 bd_id_set = 0;
14290   int ret;
14291
14292   /* Parse args required to build the message */
14293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14294     {
14295       if (unformat (i, "bd_id %d", &bd_id))
14296         bd_id_set = 1;
14297       else
14298         break;
14299     }
14300
14301   if (bd_id_set == 0)
14302     {
14303       errmsg ("missing bridge domain");
14304       return -99;
14305     }
14306
14307   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14308
14309   /* Get list of l2 fib entries */
14310   M (L2_FIB_TABLE_DUMP, mp);
14311
14312   mp->bd_id = ntohl (bd_id);
14313   S (mp);
14314
14315   /* Use a control ping for synchronization */
14316   MPING (CONTROL_PING, mp_ping);
14317   S (mp_ping);
14318
14319   W (ret);
14320   return ret;
14321 }
14322
14323
14324 static int
14325 api_interface_name_renumber (vat_main_t * vam)
14326 {
14327   unformat_input_t *line_input = vam->input;
14328   vl_api_interface_name_renumber_t *mp;
14329   u32 sw_if_index = ~0;
14330   u32 new_show_dev_instance = ~0;
14331   int ret;
14332
14333   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14334     {
14335       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14336                     &sw_if_index))
14337         ;
14338       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14339         ;
14340       else if (unformat (line_input, "new_show_dev_instance %d",
14341                          &new_show_dev_instance))
14342         ;
14343       else
14344         break;
14345     }
14346
14347   if (sw_if_index == ~0)
14348     {
14349       errmsg ("missing interface name or sw_if_index");
14350       return -99;
14351     }
14352
14353   if (new_show_dev_instance == ~0)
14354     {
14355       errmsg ("missing new_show_dev_instance");
14356       return -99;
14357     }
14358
14359   M (INTERFACE_NAME_RENUMBER, mp);
14360
14361   mp->sw_if_index = ntohl (sw_if_index);
14362   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14363
14364   S (mp);
14365   W (ret);
14366   return ret;
14367 }
14368
14369 static int
14370 api_ip_probe_neighbor (vat_main_t * vam)
14371 {
14372   unformat_input_t *i = vam->input;
14373   vl_api_ip_probe_neighbor_t *mp;
14374   u8 int_set = 0;
14375   u8 adr_set = 0;
14376   u8 is_ipv6 = 0;
14377   u8 dst_adr[16];
14378   u32 sw_if_index;
14379   int ret;
14380
14381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14382     {
14383       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14384         int_set = 1;
14385       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14386         int_set = 1;
14387       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14388         adr_set = 1;
14389       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14390         {
14391           adr_set = 1;
14392           is_ipv6 = 1;
14393         }
14394       else
14395         break;
14396     }
14397
14398   if (int_set == 0)
14399     {
14400       errmsg ("missing interface");
14401       return -99;
14402     }
14403
14404   if (adr_set == 0)
14405     {
14406       errmsg ("missing addresses");
14407       return -99;
14408     }
14409
14410   M (IP_PROBE_NEIGHBOR, mp);
14411
14412   mp->sw_if_index = ntohl (sw_if_index);
14413   mp->is_ipv6 = is_ipv6;
14414   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14415
14416   S (mp);
14417   W (ret);
14418   return ret;
14419 }
14420
14421 static int
14422 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14423 {
14424   unformat_input_t *i = vam->input;
14425   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14426   u8 mode = IP_SCAN_V46_NEIGHBORS;
14427   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14428   int ret;
14429
14430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14431     {
14432       if (unformat (i, "ip4"))
14433         mode = IP_SCAN_V4_NEIGHBORS;
14434       else if (unformat (i, "ip6"))
14435         mode = IP_SCAN_V6_NEIGHBORS;
14436       if (unformat (i, "both"))
14437         mode = IP_SCAN_V46_NEIGHBORS;
14438       else if (unformat (i, "disable"))
14439         mode = IP_SCAN_DISABLED;
14440       else if (unformat (i, "interval %d", &interval))
14441         ;
14442       else if (unformat (i, "max-time %d", &time))
14443         ;
14444       else if (unformat (i, "max-update %d", &update))
14445         ;
14446       else if (unformat (i, "delay %d", &delay))
14447         ;
14448       else if (unformat (i, "stale %d", &stale))
14449         ;
14450       else
14451         break;
14452     }
14453
14454   if (interval > 255)
14455     {
14456       errmsg ("interval cannot exceed 255 minutes.");
14457       return -99;
14458     }
14459   if (time > 255)
14460     {
14461       errmsg ("max-time cannot exceed 255 usec.");
14462       return -99;
14463     }
14464   if (update > 255)
14465     {
14466       errmsg ("max-update cannot exceed 255.");
14467       return -99;
14468     }
14469   if (delay > 255)
14470     {
14471       errmsg ("delay cannot exceed 255 msec.");
14472       return -99;
14473     }
14474   if (stale > 255)
14475     {
14476       errmsg ("stale cannot exceed 255 minutes.");
14477       return -99;
14478     }
14479
14480   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14481   mp->mode = mode;
14482   mp->scan_interval = interval;
14483   mp->max_proc_time = time;
14484   mp->max_update = update;
14485   mp->scan_int_delay = delay;
14486   mp->stale_threshold = stale;
14487
14488   S (mp);
14489   W (ret);
14490   return ret;
14491 }
14492
14493 static int
14494 api_want_ip4_arp_events (vat_main_t * vam)
14495 {
14496   unformat_input_t *line_input = vam->input;
14497   vl_api_want_ip4_arp_events_t *mp;
14498   ip4_address_t address;
14499   int address_set = 0;
14500   u32 enable_disable = 1;
14501   int ret;
14502
14503   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14504     {
14505       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14506         address_set = 1;
14507       else if (unformat (line_input, "del"))
14508         enable_disable = 0;
14509       else
14510         break;
14511     }
14512
14513   if (address_set == 0)
14514     {
14515       errmsg ("missing addresses");
14516       return -99;
14517     }
14518
14519   M (WANT_IP4_ARP_EVENTS, mp);
14520   mp->enable_disable = enable_disable;
14521   mp->pid = htonl (getpid ());
14522   mp->address = address.as_u32;
14523
14524   S (mp);
14525   W (ret);
14526   return ret;
14527 }
14528
14529 static int
14530 api_want_ip6_nd_events (vat_main_t * vam)
14531 {
14532   unformat_input_t *line_input = vam->input;
14533   vl_api_want_ip6_nd_events_t *mp;
14534   ip6_address_t address;
14535   int address_set = 0;
14536   u32 enable_disable = 1;
14537   int ret;
14538
14539   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14540     {
14541       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14542         address_set = 1;
14543       else if (unformat (line_input, "del"))
14544         enable_disable = 0;
14545       else
14546         break;
14547     }
14548
14549   if (address_set == 0)
14550     {
14551       errmsg ("missing addresses");
14552       return -99;
14553     }
14554
14555   M (WANT_IP6_ND_EVENTS, mp);
14556   mp->enable_disable = enable_disable;
14557   mp->pid = htonl (getpid ());
14558   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14559
14560   S (mp);
14561   W (ret);
14562   return ret;
14563 }
14564
14565 static int
14566 api_want_l2_macs_events (vat_main_t * vam)
14567 {
14568   unformat_input_t *line_input = vam->input;
14569   vl_api_want_l2_macs_events_t *mp;
14570   u8 enable_disable = 1;
14571   u32 scan_delay = 0;
14572   u32 max_macs_in_event = 0;
14573   u32 learn_limit = 0;
14574   int ret;
14575
14576   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14577     {
14578       if (unformat (line_input, "learn-limit %d", &learn_limit))
14579         ;
14580       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14581         ;
14582       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14583         ;
14584       else if (unformat (line_input, "disable"))
14585         enable_disable = 0;
14586       else
14587         break;
14588     }
14589
14590   M (WANT_L2_MACS_EVENTS, mp);
14591   mp->enable_disable = enable_disable;
14592   mp->pid = htonl (getpid ());
14593   mp->learn_limit = htonl (learn_limit);
14594   mp->scan_delay = (u8) scan_delay;
14595   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14596   S (mp);
14597   W (ret);
14598   return ret;
14599 }
14600
14601 static int
14602 api_input_acl_set_interface (vat_main_t * vam)
14603 {
14604   unformat_input_t *i = vam->input;
14605   vl_api_input_acl_set_interface_t *mp;
14606   u32 sw_if_index;
14607   int sw_if_index_set;
14608   u32 ip4_table_index = ~0;
14609   u32 ip6_table_index = ~0;
14610   u32 l2_table_index = ~0;
14611   u8 is_add = 1;
14612   int ret;
14613
14614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14615     {
14616       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14617         sw_if_index_set = 1;
14618       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14619         sw_if_index_set = 1;
14620       else if (unformat (i, "del"))
14621         is_add = 0;
14622       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14623         ;
14624       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14625         ;
14626       else if (unformat (i, "l2-table %d", &l2_table_index))
14627         ;
14628       else
14629         {
14630           clib_warning ("parse error '%U'", format_unformat_error, i);
14631           return -99;
14632         }
14633     }
14634
14635   if (sw_if_index_set == 0)
14636     {
14637       errmsg ("missing interface name or sw_if_index");
14638       return -99;
14639     }
14640
14641   M (INPUT_ACL_SET_INTERFACE, mp);
14642
14643   mp->sw_if_index = ntohl (sw_if_index);
14644   mp->ip4_table_index = ntohl (ip4_table_index);
14645   mp->ip6_table_index = ntohl (ip6_table_index);
14646   mp->l2_table_index = ntohl (l2_table_index);
14647   mp->is_add = is_add;
14648
14649   S (mp);
14650   W (ret);
14651   return ret;
14652 }
14653
14654 static int
14655 api_output_acl_set_interface (vat_main_t * vam)
14656 {
14657   unformat_input_t *i = vam->input;
14658   vl_api_output_acl_set_interface_t *mp;
14659   u32 sw_if_index;
14660   int sw_if_index_set;
14661   u32 ip4_table_index = ~0;
14662   u32 ip6_table_index = ~0;
14663   u32 l2_table_index = ~0;
14664   u8 is_add = 1;
14665   int ret;
14666
14667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14668     {
14669       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14670         sw_if_index_set = 1;
14671       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14672         sw_if_index_set = 1;
14673       else if (unformat (i, "del"))
14674         is_add = 0;
14675       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14676         ;
14677       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14678         ;
14679       else if (unformat (i, "l2-table %d", &l2_table_index))
14680         ;
14681       else
14682         {
14683           clib_warning ("parse error '%U'", format_unformat_error, i);
14684           return -99;
14685         }
14686     }
14687
14688   if (sw_if_index_set == 0)
14689     {
14690       errmsg ("missing interface name or sw_if_index");
14691       return -99;
14692     }
14693
14694   M (OUTPUT_ACL_SET_INTERFACE, mp);
14695
14696   mp->sw_if_index = ntohl (sw_if_index);
14697   mp->ip4_table_index = ntohl (ip4_table_index);
14698   mp->ip6_table_index = ntohl (ip6_table_index);
14699   mp->l2_table_index = ntohl (l2_table_index);
14700   mp->is_add = is_add;
14701
14702   S (mp);
14703   W (ret);
14704   return ret;
14705 }
14706
14707 static int
14708 api_ip_address_dump (vat_main_t * vam)
14709 {
14710   unformat_input_t *i = vam->input;
14711   vl_api_ip_address_dump_t *mp;
14712   vl_api_control_ping_t *mp_ping;
14713   u32 sw_if_index = ~0;
14714   u8 sw_if_index_set = 0;
14715   u8 ipv4_set = 0;
14716   u8 ipv6_set = 0;
14717   int ret;
14718
14719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14720     {
14721       if (unformat (i, "sw_if_index %d", &sw_if_index))
14722         sw_if_index_set = 1;
14723       else
14724         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14725         sw_if_index_set = 1;
14726       else if (unformat (i, "ipv4"))
14727         ipv4_set = 1;
14728       else if (unformat (i, "ipv6"))
14729         ipv6_set = 1;
14730       else
14731         break;
14732     }
14733
14734   if (ipv4_set && ipv6_set)
14735     {
14736       errmsg ("ipv4 and ipv6 flags cannot be both set");
14737       return -99;
14738     }
14739
14740   if ((!ipv4_set) && (!ipv6_set))
14741     {
14742       errmsg ("no ipv4 nor ipv6 flag set");
14743       return -99;
14744     }
14745
14746   if (sw_if_index_set == 0)
14747     {
14748       errmsg ("missing interface name or sw_if_index");
14749       return -99;
14750     }
14751
14752   vam->current_sw_if_index = sw_if_index;
14753   vam->is_ipv6 = ipv6_set;
14754
14755   M (IP_ADDRESS_DUMP, mp);
14756   mp->sw_if_index = ntohl (sw_if_index);
14757   mp->is_ipv6 = ipv6_set;
14758   S (mp);
14759
14760   /* Use a control ping for synchronization */
14761   MPING (CONTROL_PING, mp_ping);
14762   S (mp_ping);
14763
14764   W (ret);
14765   return ret;
14766 }
14767
14768 static int
14769 api_ip_dump (vat_main_t * vam)
14770 {
14771   vl_api_ip_dump_t *mp;
14772   vl_api_control_ping_t *mp_ping;
14773   unformat_input_t *in = vam->input;
14774   int ipv4_set = 0;
14775   int ipv6_set = 0;
14776   int is_ipv6;
14777   int i;
14778   int ret;
14779
14780   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14781     {
14782       if (unformat (in, "ipv4"))
14783         ipv4_set = 1;
14784       else if (unformat (in, "ipv6"))
14785         ipv6_set = 1;
14786       else
14787         break;
14788     }
14789
14790   if (ipv4_set && ipv6_set)
14791     {
14792       errmsg ("ipv4 and ipv6 flags cannot be both set");
14793       return -99;
14794     }
14795
14796   if ((!ipv4_set) && (!ipv6_set))
14797     {
14798       errmsg ("no ipv4 nor ipv6 flag set");
14799       return -99;
14800     }
14801
14802   is_ipv6 = ipv6_set;
14803   vam->is_ipv6 = is_ipv6;
14804
14805   /* free old data */
14806   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14807     {
14808       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14809     }
14810   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14811
14812   M (IP_DUMP, mp);
14813   mp->is_ipv6 = ipv6_set;
14814   S (mp);
14815
14816   /* Use a control ping for synchronization */
14817   MPING (CONTROL_PING, mp_ping);
14818   S (mp_ping);
14819
14820   W (ret);
14821   return ret;
14822 }
14823
14824 static int
14825 api_ipsec_spd_add_del (vat_main_t * vam)
14826 {
14827   unformat_input_t *i = vam->input;
14828   vl_api_ipsec_spd_add_del_t *mp;
14829   u32 spd_id = ~0;
14830   u8 is_add = 1;
14831   int ret;
14832
14833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14834     {
14835       if (unformat (i, "spd_id %d", &spd_id))
14836         ;
14837       else if (unformat (i, "del"))
14838         is_add = 0;
14839       else
14840         {
14841           clib_warning ("parse error '%U'", format_unformat_error, i);
14842           return -99;
14843         }
14844     }
14845   if (spd_id == ~0)
14846     {
14847       errmsg ("spd_id must be set");
14848       return -99;
14849     }
14850
14851   M (IPSEC_SPD_ADD_DEL, mp);
14852
14853   mp->spd_id = ntohl (spd_id);
14854   mp->is_add = is_add;
14855
14856   S (mp);
14857   W (ret);
14858   return ret;
14859 }
14860
14861 static int
14862 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14863 {
14864   unformat_input_t *i = vam->input;
14865   vl_api_ipsec_interface_add_del_spd_t *mp;
14866   u32 sw_if_index;
14867   u8 sw_if_index_set = 0;
14868   u32 spd_id = (u32) ~ 0;
14869   u8 is_add = 1;
14870   int ret;
14871
14872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14873     {
14874       if (unformat (i, "del"))
14875         is_add = 0;
14876       else if (unformat (i, "spd_id %d", &spd_id))
14877         ;
14878       else
14879         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14880         sw_if_index_set = 1;
14881       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14882         sw_if_index_set = 1;
14883       else
14884         {
14885           clib_warning ("parse error '%U'", format_unformat_error, i);
14886           return -99;
14887         }
14888
14889     }
14890
14891   if (spd_id == (u32) ~ 0)
14892     {
14893       errmsg ("spd_id must be set");
14894       return -99;
14895     }
14896
14897   if (sw_if_index_set == 0)
14898     {
14899       errmsg ("missing interface name or sw_if_index");
14900       return -99;
14901     }
14902
14903   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14904
14905   mp->spd_id = ntohl (spd_id);
14906   mp->sw_if_index = ntohl (sw_if_index);
14907   mp->is_add = is_add;
14908
14909   S (mp);
14910   W (ret);
14911   return ret;
14912 }
14913
14914 static int
14915 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14916 {
14917   unformat_input_t *i = vam->input;
14918   vl_api_ipsec_spd_add_del_entry_t *mp;
14919   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14920   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14921   i32 priority = 0;
14922   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14923   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14924   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14925   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14926   int ret;
14927
14928   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14929   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14930   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14931   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14932   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14933   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14934
14935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14936     {
14937       if (unformat (i, "del"))
14938         is_add = 0;
14939       if (unformat (i, "outbound"))
14940         is_outbound = 1;
14941       if (unformat (i, "inbound"))
14942         is_outbound = 0;
14943       else if (unformat (i, "spd_id %d", &spd_id))
14944         ;
14945       else if (unformat (i, "sa_id %d", &sa_id))
14946         ;
14947       else if (unformat (i, "priority %d", &priority))
14948         ;
14949       else if (unformat (i, "protocol %d", &protocol))
14950         ;
14951       else if (unformat (i, "lport_start %d", &lport_start))
14952         ;
14953       else if (unformat (i, "lport_stop %d", &lport_stop))
14954         ;
14955       else if (unformat (i, "rport_start %d", &rport_start))
14956         ;
14957       else if (unformat (i, "rport_stop %d", &rport_stop))
14958         ;
14959       else
14960         if (unformat
14961             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14962         {
14963           is_ipv6 = 0;
14964           is_ip_any = 0;
14965         }
14966       else
14967         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14968         {
14969           is_ipv6 = 0;
14970           is_ip_any = 0;
14971         }
14972       else
14973         if (unformat
14974             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14975         {
14976           is_ipv6 = 0;
14977           is_ip_any = 0;
14978         }
14979       else
14980         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14981         {
14982           is_ipv6 = 0;
14983           is_ip_any = 0;
14984         }
14985       else
14986         if (unformat
14987             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14988         {
14989           is_ipv6 = 1;
14990           is_ip_any = 0;
14991         }
14992       else
14993         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14994         {
14995           is_ipv6 = 1;
14996           is_ip_any = 0;
14997         }
14998       else
14999         if (unformat
15000             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15001         {
15002           is_ipv6 = 1;
15003           is_ip_any = 0;
15004         }
15005       else
15006         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15007         {
15008           is_ipv6 = 1;
15009           is_ip_any = 0;
15010         }
15011       else
15012         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15013         {
15014           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15015             {
15016               clib_warning ("unsupported action: 'resolve'");
15017               return -99;
15018             }
15019         }
15020       else
15021         {
15022           clib_warning ("parse error '%U'", format_unformat_error, i);
15023           return -99;
15024         }
15025
15026     }
15027
15028   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15029
15030   mp->spd_id = ntohl (spd_id);
15031   mp->priority = ntohl (priority);
15032   mp->is_outbound = is_outbound;
15033
15034   mp->is_ipv6 = is_ipv6;
15035   if (is_ipv6 || is_ip_any)
15036     {
15037       clib_memcpy (mp->remote_address_start, &raddr6_start,
15038                    sizeof (ip6_address_t));
15039       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15040                    sizeof (ip6_address_t));
15041       clib_memcpy (mp->local_address_start, &laddr6_start,
15042                    sizeof (ip6_address_t));
15043       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15044                    sizeof (ip6_address_t));
15045     }
15046   else
15047     {
15048       clib_memcpy (mp->remote_address_start, &raddr4_start,
15049                    sizeof (ip4_address_t));
15050       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15051                    sizeof (ip4_address_t));
15052       clib_memcpy (mp->local_address_start, &laddr4_start,
15053                    sizeof (ip4_address_t));
15054       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15055                    sizeof (ip4_address_t));
15056     }
15057   mp->protocol = (u8) protocol;
15058   mp->local_port_start = ntohs ((u16) lport_start);
15059   mp->local_port_stop = ntohs ((u16) lport_stop);
15060   mp->remote_port_start = ntohs ((u16) rport_start);
15061   mp->remote_port_stop = ntohs ((u16) rport_stop);
15062   mp->policy = (u8) policy;
15063   mp->sa_id = ntohl (sa_id);
15064   mp->is_add = is_add;
15065   mp->is_ip_any = is_ip_any;
15066   S (mp);
15067   W (ret);
15068   return ret;
15069 }
15070
15071 static int
15072 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15073 {
15074   unformat_input_t *i = vam->input;
15075   vl_api_ipsec_sad_add_del_entry_t *mp;
15076   u32 sad_id = 0, spi = 0;
15077   u8 *ck = 0, *ik = 0;
15078   u8 is_add = 1;
15079
15080   u8 protocol = IPSEC_PROTOCOL_AH;
15081   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15082   u32 crypto_alg = 0, integ_alg = 0;
15083   ip4_address_t tun_src4;
15084   ip4_address_t tun_dst4;
15085   ip6_address_t tun_src6;
15086   ip6_address_t tun_dst6;
15087   int ret;
15088
15089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15090     {
15091       if (unformat (i, "del"))
15092         is_add = 0;
15093       else if (unformat (i, "sad_id %d", &sad_id))
15094         ;
15095       else if (unformat (i, "spi %d", &spi))
15096         ;
15097       else if (unformat (i, "esp"))
15098         protocol = IPSEC_PROTOCOL_ESP;
15099       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15100         {
15101           is_tunnel = 1;
15102           is_tunnel_ipv6 = 0;
15103         }
15104       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15105         {
15106           is_tunnel = 1;
15107           is_tunnel_ipv6 = 0;
15108         }
15109       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15110         {
15111           is_tunnel = 1;
15112           is_tunnel_ipv6 = 1;
15113         }
15114       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15115         {
15116           is_tunnel = 1;
15117           is_tunnel_ipv6 = 1;
15118         }
15119       else
15120         if (unformat
15121             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15122         {
15123           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15124               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15125             {
15126               clib_warning ("unsupported crypto-alg: '%U'",
15127                             format_ipsec_crypto_alg, crypto_alg);
15128               return -99;
15129             }
15130         }
15131       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15132         ;
15133       else
15134         if (unformat
15135             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15136         {
15137           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15138               integ_alg >= IPSEC_INTEG_N_ALG)
15139             {
15140               clib_warning ("unsupported integ-alg: '%U'",
15141                             format_ipsec_integ_alg, integ_alg);
15142               return -99;
15143             }
15144         }
15145       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15146         ;
15147       else
15148         {
15149           clib_warning ("parse error '%U'", format_unformat_error, i);
15150           return -99;
15151         }
15152
15153     }
15154
15155   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15156
15157   mp->sad_id = ntohl (sad_id);
15158   mp->is_add = is_add;
15159   mp->protocol = protocol;
15160   mp->spi = ntohl (spi);
15161   mp->is_tunnel = is_tunnel;
15162   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15163   mp->crypto_algorithm = crypto_alg;
15164   mp->integrity_algorithm = integ_alg;
15165   mp->crypto_key_length = vec_len (ck);
15166   mp->integrity_key_length = vec_len (ik);
15167
15168   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15169     mp->crypto_key_length = sizeof (mp->crypto_key);
15170
15171   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15172     mp->integrity_key_length = sizeof (mp->integrity_key);
15173
15174   if (ck)
15175     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15176   if (ik)
15177     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15178
15179   if (is_tunnel)
15180     {
15181       if (is_tunnel_ipv6)
15182         {
15183           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15184                        sizeof (ip6_address_t));
15185           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15186                        sizeof (ip6_address_t));
15187         }
15188       else
15189         {
15190           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15191                        sizeof (ip4_address_t));
15192           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15193                        sizeof (ip4_address_t));
15194         }
15195     }
15196
15197   S (mp);
15198   W (ret);
15199   return ret;
15200 }
15201
15202 static int
15203 api_ipsec_sa_set_key (vat_main_t * vam)
15204 {
15205   unformat_input_t *i = vam->input;
15206   vl_api_ipsec_sa_set_key_t *mp;
15207   u32 sa_id;
15208   u8 *ck = 0, *ik = 0;
15209   int ret;
15210
15211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15212     {
15213       if (unformat (i, "sa_id %d", &sa_id))
15214         ;
15215       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15216         ;
15217       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15218         ;
15219       else
15220         {
15221           clib_warning ("parse error '%U'", format_unformat_error, i);
15222           return -99;
15223         }
15224     }
15225
15226   M (IPSEC_SA_SET_KEY, mp);
15227
15228   mp->sa_id = ntohl (sa_id);
15229   mp->crypto_key_length = vec_len (ck);
15230   mp->integrity_key_length = vec_len (ik);
15231
15232   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15233     mp->crypto_key_length = sizeof (mp->crypto_key);
15234
15235   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15236     mp->integrity_key_length = sizeof (mp->integrity_key);
15237
15238   if (ck)
15239     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15240   if (ik)
15241     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15242
15243   S (mp);
15244   W (ret);
15245   return ret;
15246 }
15247
15248 static int
15249 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15250 {
15251   unformat_input_t *i = vam->input;
15252   vl_api_ipsec_tunnel_if_add_del_t *mp;
15253   u32 local_spi = 0, remote_spi = 0;
15254   u32 crypto_alg = 0, integ_alg = 0;
15255   u8 *lck = NULL, *rck = NULL;
15256   u8 *lik = NULL, *rik = NULL;
15257   ip4_address_t local_ip = { {0} };
15258   ip4_address_t remote_ip = { {0} };
15259   u8 is_add = 1;
15260   u8 esn = 0;
15261   u8 anti_replay = 0;
15262   u8 renumber = 0;
15263   u32 instance = ~0;
15264   int ret;
15265
15266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15267     {
15268       if (unformat (i, "del"))
15269         is_add = 0;
15270       else if (unformat (i, "esn"))
15271         esn = 1;
15272       else if (unformat (i, "anti_replay"))
15273         anti_replay = 1;
15274       else if (unformat (i, "local_spi %d", &local_spi))
15275         ;
15276       else if (unformat (i, "remote_spi %d", &remote_spi))
15277         ;
15278       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15279         ;
15280       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15281         ;
15282       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15283         ;
15284       else
15285         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15286         ;
15287       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15288         ;
15289       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15290         ;
15291       else
15292         if (unformat
15293             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15294         {
15295           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15296               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15297             {
15298               errmsg ("unsupported crypto-alg: '%U'\n",
15299                       format_ipsec_crypto_alg, crypto_alg);
15300               return -99;
15301             }
15302         }
15303       else
15304         if (unformat
15305             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15306         {
15307           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15308               integ_alg >= IPSEC_INTEG_N_ALG)
15309             {
15310               errmsg ("unsupported integ-alg: '%U'\n",
15311                       format_ipsec_integ_alg, integ_alg);
15312               return -99;
15313             }
15314         }
15315       else if (unformat (i, "instance %u", &instance))
15316         renumber = 1;
15317       else
15318         {
15319           errmsg ("parse error '%U'\n", format_unformat_error, i);
15320           return -99;
15321         }
15322     }
15323
15324   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15325
15326   mp->is_add = is_add;
15327   mp->esn = esn;
15328   mp->anti_replay = anti_replay;
15329
15330   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15331   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15332
15333   mp->local_spi = htonl (local_spi);
15334   mp->remote_spi = htonl (remote_spi);
15335   mp->crypto_alg = (u8) crypto_alg;
15336
15337   mp->local_crypto_key_len = 0;
15338   if (lck)
15339     {
15340       mp->local_crypto_key_len = vec_len (lck);
15341       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15342         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15343       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15344     }
15345
15346   mp->remote_crypto_key_len = 0;
15347   if (rck)
15348     {
15349       mp->remote_crypto_key_len = vec_len (rck);
15350       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15351         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15352       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15353     }
15354
15355   mp->integ_alg = (u8) integ_alg;
15356
15357   mp->local_integ_key_len = 0;
15358   if (lik)
15359     {
15360       mp->local_integ_key_len = vec_len (lik);
15361       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15362         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15363       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15364     }
15365
15366   mp->remote_integ_key_len = 0;
15367   if (rik)
15368     {
15369       mp->remote_integ_key_len = vec_len (rik);
15370       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15371         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15372       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15373     }
15374
15375   if (renumber)
15376     {
15377       mp->renumber = renumber;
15378       mp->show_instance = ntohl (instance);
15379     }
15380
15381   S (mp);
15382   W (ret);
15383   return ret;
15384 }
15385
15386 static void
15387 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15388 {
15389   vat_main_t *vam = &vat_main;
15390
15391   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15392          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15393          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15394          "tunnel_src_addr %U tunnel_dst_addr %U "
15395          "salt %u seq_outbound %lu last_seq_inbound %lu "
15396          "replay_window %lu total_data_size %lu\n",
15397          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15398          mp->protocol,
15399          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15400          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15401          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15402          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15403          mp->tunnel_src_addr,
15404          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15405          mp->tunnel_dst_addr,
15406          ntohl (mp->salt),
15407          clib_net_to_host_u64 (mp->seq_outbound),
15408          clib_net_to_host_u64 (mp->last_seq_inbound),
15409          clib_net_to_host_u64 (mp->replay_window),
15410          clib_net_to_host_u64 (mp->total_data_size));
15411 }
15412
15413 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15414 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15415
15416 static void vl_api_ipsec_sa_details_t_handler_json
15417   (vl_api_ipsec_sa_details_t * mp)
15418 {
15419   vat_main_t *vam = &vat_main;
15420   vat_json_node_t *node = NULL;
15421   struct in_addr src_ip4, dst_ip4;
15422   struct in6_addr src_ip6, dst_ip6;
15423
15424   if (VAT_JSON_ARRAY != vam->json_tree.type)
15425     {
15426       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15427       vat_json_init_array (&vam->json_tree);
15428     }
15429   node = vat_json_array_add (&vam->json_tree);
15430
15431   vat_json_init_object (node);
15432   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15433   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15434   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15435   vat_json_object_add_uint (node, "proto", mp->protocol);
15436   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15437   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15438   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15439   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15440   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15441   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15442   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15443                              mp->crypto_key_len);
15444   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15445                              mp->integ_key_len);
15446   if (mp->is_tunnel_ip6)
15447     {
15448       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15449       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15450       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15451       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15452     }
15453   else
15454     {
15455       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15456       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15457       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15458       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15459     }
15460   vat_json_object_add_uint (node, "replay_window",
15461                             clib_net_to_host_u64 (mp->replay_window));
15462   vat_json_object_add_uint (node, "total_data_size",
15463                             clib_net_to_host_u64 (mp->total_data_size));
15464
15465 }
15466
15467 static int
15468 api_ipsec_sa_dump (vat_main_t * vam)
15469 {
15470   unformat_input_t *i = vam->input;
15471   vl_api_ipsec_sa_dump_t *mp;
15472   vl_api_control_ping_t *mp_ping;
15473   u32 sa_id = ~0;
15474   int ret;
15475
15476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15477     {
15478       if (unformat (i, "sa_id %d", &sa_id))
15479         ;
15480       else
15481         {
15482           clib_warning ("parse error '%U'", format_unformat_error, i);
15483           return -99;
15484         }
15485     }
15486
15487   M (IPSEC_SA_DUMP, mp);
15488
15489   mp->sa_id = ntohl (sa_id);
15490
15491   S (mp);
15492
15493   /* Use a control ping for synchronization */
15494   M (CONTROL_PING, mp_ping);
15495   S (mp_ping);
15496
15497   W (ret);
15498   return ret;
15499 }
15500
15501 static int
15502 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15503 {
15504   unformat_input_t *i = vam->input;
15505   vl_api_ipsec_tunnel_if_set_key_t *mp;
15506   u32 sw_if_index = ~0;
15507   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15508   u8 *key = 0;
15509   u32 alg = ~0;
15510   int ret;
15511
15512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15513     {
15514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15515         ;
15516       else
15517         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15518         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15519       else
15520         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15521         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15522       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15523         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15524       else
15525         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15526         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15527       else if (unformat (i, "%U", unformat_hex_string, &key))
15528         ;
15529       else
15530         {
15531           clib_warning ("parse error '%U'", format_unformat_error, i);
15532           return -99;
15533         }
15534     }
15535
15536   if (sw_if_index == ~0)
15537     {
15538       errmsg ("interface must be specified");
15539       return -99;
15540     }
15541
15542   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15543     {
15544       errmsg ("key type must be specified");
15545       return -99;
15546     }
15547
15548   if (alg == ~0)
15549     {
15550       errmsg ("algorithm must be specified");
15551       return -99;
15552     }
15553
15554   if (vec_len (key) == 0)
15555     {
15556       errmsg ("key must be specified");
15557       return -99;
15558     }
15559
15560   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15561
15562   mp->sw_if_index = htonl (sw_if_index);
15563   mp->alg = alg;
15564   mp->key_type = key_type;
15565   mp->key_len = vec_len (key);
15566   clib_memcpy (mp->key, key, vec_len (key));
15567
15568   S (mp);
15569   W (ret);
15570
15571   return ret;
15572 }
15573
15574 static int
15575 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15576 {
15577   unformat_input_t *i = vam->input;
15578   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15579   u32 sw_if_index = ~0;
15580   u32 sa_id = ~0;
15581   u8 is_outbound = (u8) ~ 0;
15582   int ret;
15583
15584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15585     {
15586       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15587         ;
15588       else if (unformat (i, "sa_id %d", &sa_id))
15589         ;
15590       else if (unformat (i, "outbound"))
15591         is_outbound = 1;
15592       else if (unformat (i, "inbound"))
15593         is_outbound = 0;
15594       else
15595         {
15596           clib_warning ("parse error '%U'", format_unformat_error, i);
15597           return -99;
15598         }
15599     }
15600
15601   if (sw_if_index == ~0)
15602     {
15603       errmsg ("interface must be specified");
15604       return -99;
15605     }
15606
15607   if (sa_id == ~0)
15608     {
15609       errmsg ("SA ID must be specified");
15610       return -99;
15611     }
15612
15613   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15614
15615   mp->sw_if_index = htonl (sw_if_index);
15616   mp->sa_id = htonl (sa_id);
15617   mp->is_outbound = is_outbound;
15618
15619   S (mp);
15620   W (ret);
15621
15622   return ret;
15623 }
15624
15625 static int
15626 api_ikev2_profile_add_del (vat_main_t * vam)
15627 {
15628   unformat_input_t *i = vam->input;
15629   vl_api_ikev2_profile_add_del_t *mp;
15630   u8 is_add = 1;
15631   u8 *name = 0;
15632   int ret;
15633
15634   const char *valid_chars = "a-zA-Z0-9_";
15635
15636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15637     {
15638       if (unformat (i, "del"))
15639         is_add = 0;
15640       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15641         vec_add1 (name, 0);
15642       else
15643         {
15644           errmsg ("parse error '%U'", format_unformat_error, i);
15645           return -99;
15646         }
15647     }
15648
15649   if (!vec_len (name))
15650     {
15651       errmsg ("profile name must be specified");
15652       return -99;
15653     }
15654
15655   if (vec_len (name) > 64)
15656     {
15657       errmsg ("profile name too long");
15658       return -99;
15659     }
15660
15661   M (IKEV2_PROFILE_ADD_DEL, mp);
15662
15663   clib_memcpy (mp->name, name, vec_len (name));
15664   mp->is_add = is_add;
15665   vec_free (name);
15666
15667   S (mp);
15668   W (ret);
15669   return ret;
15670 }
15671
15672 static int
15673 api_ikev2_profile_set_auth (vat_main_t * vam)
15674 {
15675   unformat_input_t *i = vam->input;
15676   vl_api_ikev2_profile_set_auth_t *mp;
15677   u8 *name = 0;
15678   u8 *data = 0;
15679   u32 auth_method = 0;
15680   u8 is_hex = 0;
15681   int ret;
15682
15683   const char *valid_chars = "a-zA-Z0-9_";
15684
15685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15686     {
15687       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15688         vec_add1 (name, 0);
15689       else if (unformat (i, "auth_method %U",
15690                          unformat_ikev2_auth_method, &auth_method))
15691         ;
15692       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15693         is_hex = 1;
15694       else if (unformat (i, "auth_data %v", &data))
15695         ;
15696       else
15697         {
15698           errmsg ("parse error '%U'", format_unformat_error, i);
15699           return -99;
15700         }
15701     }
15702
15703   if (!vec_len (name))
15704     {
15705       errmsg ("profile name must be specified");
15706       return -99;
15707     }
15708
15709   if (vec_len (name) > 64)
15710     {
15711       errmsg ("profile name too long");
15712       return -99;
15713     }
15714
15715   if (!vec_len (data))
15716     {
15717       errmsg ("auth_data must be specified");
15718       return -99;
15719     }
15720
15721   if (!auth_method)
15722     {
15723       errmsg ("auth_method must be specified");
15724       return -99;
15725     }
15726
15727   M (IKEV2_PROFILE_SET_AUTH, mp);
15728
15729   mp->is_hex = is_hex;
15730   mp->auth_method = (u8) auth_method;
15731   mp->data_len = vec_len (data);
15732   clib_memcpy (mp->name, name, vec_len (name));
15733   clib_memcpy (mp->data, data, vec_len (data));
15734   vec_free (name);
15735   vec_free (data);
15736
15737   S (mp);
15738   W (ret);
15739   return ret;
15740 }
15741
15742 static int
15743 api_ikev2_profile_set_id (vat_main_t * vam)
15744 {
15745   unformat_input_t *i = vam->input;
15746   vl_api_ikev2_profile_set_id_t *mp;
15747   u8 *name = 0;
15748   u8 *data = 0;
15749   u8 is_local = 0;
15750   u32 id_type = 0;
15751   ip4_address_t ip4;
15752   int ret;
15753
15754   const char *valid_chars = "a-zA-Z0-9_";
15755
15756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15757     {
15758       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15759         vec_add1 (name, 0);
15760       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15761         ;
15762       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15763         {
15764           data = vec_new (u8, 4);
15765           clib_memcpy (data, ip4.as_u8, 4);
15766         }
15767       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15768         ;
15769       else if (unformat (i, "id_data %v", &data))
15770         ;
15771       else if (unformat (i, "local"))
15772         is_local = 1;
15773       else if (unformat (i, "remote"))
15774         is_local = 0;
15775       else
15776         {
15777           errmsg ("parse error '%U'", format_unformat_error, i);
15778           return -99;
15779         }
15780     }
15781
15782   if (!vec_len (name))
15783     {
15784       errmsg ("profile name must be specified");
15785       return -99;
15786     }
15787
15788   if (vec_len (name) > 64)
15789     {
15790       errmsg ("profile name too long");
15791       return -99;
15792     }
15793
15794   if (!vec_len (data))
15795     {
15796       errmsg ("id_data must be specified");
15797       return -99;
15798     }
15799
15800   if (!id_type)
15801     {
15802       errmsg ("id_type must be specified");
15803       return -99;
15804     }
15805
15806   M (IKEV2_PROFILE_SET_ID, mp);
15807
15808   mp->is_local = is_local;
15809   mp->id_type = (u8) id_type;
15810   mp->data_len = vec_len (data);
15811   clib_memcpy (mp->name, name, vec_len (name));
15812   clib_memcpy (mp->data, data, vec_len (data));
15813   vec_free (name);
15814   vec_free (data);
15815
15816   S (mp);
15817   W (ret);
15818   return ret;
15819 }
15820
15821 static int
15822 api_ikev2_profile_set_ts (vat_main_t * vam)
15823 {
15824   unformat_input_t *i = vam->input;
15825   vl_api_ikev2_profile_set_ts_t *mp;
15826   u8 *name = 0;
15827   u8 is_local = 0;
15828   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15829   ip4_address_t start_addr, end_addr;
15830
15831   const char *valid_chars = "a-zA-Z0-9_";
15832   int ret;
15833
15834   start_addr.as_u32 = 0;
15835   end_addr.as_u32 = (u32) ~ 0;
15836
15837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15838     {
15839       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15840         vec_add1 (name, 0);
15841       else if (unformat (i, "protocol %d", &proto))
15842         ;
15843       else if (unformat (i, "start_port %d", &start_port))
15844         ;
15845       else if (unformat (i, "end_port %d", &end_port))
15846         ;
15847       else
15848         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15849         ;
15850       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15851         ;
15852       else if (unformat (i, "local"))
15853         is_local = 1;
15854       else if (unformat (i, "remote"))
15855         is_local = 0;
15856       else
15857         {
15858           errmsg ("parse error '%U'", format_unformat_error, i);
15859           return -99;
15860         }
15861     }
15862
15863   if (!vec_len (name))
15864     {
15865       errmsg ("profile name must be specified");
15866       return -99;
15867     }
15868
15869   if (vec_len (name) > 64)
15870     {
15871       errmsg ("profile name too long");
15872       return -99;
15873     }
15874
15875   M (IKEV2_PROFILE_SET_TS, mp);
15876
15877   mp->is_local = is_local;
15878   mp->proto = (u8) proto;
15879   mp->start_port = (u16) start_port;
15880   mp->end_port = (u16) end_port;
15881   mp->start_addr = start_addr.as_u32;
15882   mp->end_addr = end_addr.as_u32;
15883   clib_memcpy (mp->name, name, vec_len (name));
15884   vec_free (name);
15885
15886   S (mp);
15887   W (ret);
15888   return ret;
15889 }
15890
15891 static int
15892 api_ikev2_set_local_key (vat_main_t * vam)
15893 {
15894   unformat_input_t *i = vam->input;
15895   vl_api_ikev2_set_local_key_t *mp;
15896   u8 *file = 0;
15897   int ret;
15898
15899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15900     {
15901       if (unformat (i, "file %v", &file))
15902         vec_add1 (file, 0);
15903       else
15904         {
15905           errmsg ("parse error '%U'", format_unformat_error, i);
15906           return -99;
15907         }
15908     }
15909
15910   if (!vec_len (file))
15911     {
15912       errmsg ("RSA key file must be specified");
15913       return -99;
15914     }
15915
15916   if (vec_len (file) > 256)
15917     {
15918       errmsg ("file name too long");
15919       return -99;
15920     }
15921
15922   M (IKEV2_SET_LOCAL_KEY, mp);
15923
15924   clib_memcpy (mp->key_file, file, vec_len (file));
15925   vec_free (file);
15926
15927   S (mp);
15928   W (ret);
15929   return ret;
15930 }
15931
15932 static int
15933 api_ikev2_set_responder (vat_main_t * vam)
15934 {
15935   unformat_input_t *i = vam->input;
15936   vl_api_ikev2_set_responder_t *mp;
15937   int ret;
15938   u8 *name = 0;
15939   u32 sw_if_index = ~0;
15940   ip4_address_t address;
15941
15942   const char *valid_chars = "a-zA-Z0-9_";
15943
15944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15945     {
15946       if (unformat
15947           (i, "%U interface %d address %U", unformat_token, valid_chars,
15948            &name, &sw_if_index, unformat_ip4_address, &address))
15949         vec_add1 (name, 0);
15950       else
15951         {
15952           errmsg ("parse error '%U'", format_unformat_error, i);
15953           return -99;
15954         }
15955     }
15956
15957   if (!vec_len (name))
15958     {
15959       errmsg ("profile name must be specified");
15960       return -99;
15961     }
15962
15963   if (vec_len (name) > 64)
15964     {
15965       errmsg ("profile name too long");
15966       return -99;
15967     }
15968
15969   M (IKEV2_SET_RESPONDER, mp);
15970
15971   clib_memcpy (mp->name, name, vec_len (name));
15972   vec_free (name);
15973
15974   mp->sw_if_index = sw_if_index;
15975   clib_memcpy (mp->address, &address, sizeof (address));
15976
15977   S (mp);
15978   W (ret);
15979   return ret;
15980 }
15981
15982 static int
15983 api_ikev2_set_ike_transforms (vat_main_t * vam)
15984 {
15985   unformat_input_t *i = vam->input;
15986   vl_api_ikev2_set_ike_transforms_t *mp;
15987   int ret;
15988   u8 *name = 0;
15989   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15990
15991   const char *valid_chars = "a-zA-Z0-9_";
15992
15993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15994     {
15995       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15996                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15997         vec_add1 (name, 0);
15998       else
15999         {
16000           errmsg ("parse error '%U'", format_unformat_error, i);
16001           return -99;
16002         }
16003     }
16004
16005   if (!vec_len (name))
16006     {
16007       errmsg ("profile name must be specified");
16008       return -99;
16009     }
16010
16011   if (vec_len (name) > 64)
16012     {
16013       errmsg ("profile name too long");
16014       return -99;
16015     }
16016
16017   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16018
16019   clib_memcpy (mp->name, name, vec_len (name));
16020   vec_free (name);
16021   mp->crypto_alg = crypto_alg;
16022   mp->crypto_key_size = crypto_key_size;
16023   mp->integ_alg = integ_alg;
16024   mp->dh_group = dh_group;
16025
16026   S (mp);
16027   W (ret);
16028   return ret;
16029 }
16030
16031
16032 static int
16033 api_ikev2_set_esp_transforms (vat_main_t * vam)
16034 {
16035   unformat_input_t *i = vam->input;
16036   vl_api_ikev2_set_esp_transforms_t *mp;
16037   int ret;
16038   u8 *name = 0;
16039   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16040
16041   const char *valid_chars = "a-zA-Z0-9_";
16042
16043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16044     {
16045       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16046                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16047         vec_add1 (name, 0);
16048       else
16049         {
16050           errmsg ("parse error '%U'", format_unformat_error, i);
16051           return -99;
16052         }
16053     }
16054
16055   if (!vec_len (name))
16056     {
16057       errmsg ("profile name must be specified");
16058       return -99;
16059     }
16060
16061   if (vec_len (name) > 64)
16062     {
16063       errmsg ("profile name too long");
16064       return -99;
16065     }
16066
16067   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16068
16069   clib_memcpy (mp->name, name, vec_len (name));
16070   vec_free (name);
16071   mp->crypto_alg = crypto_alg;
16072   mp->crypto_key_size = crypto_key_size;
16073   mp->integ_alg = integ_alg;
16074   mp->dh_group = dh_group;
16075
16076   S (mp);
16077   W (ret);
16078   return ret;
16079 }
16080
16081 static int
16082 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16083 {
16084   unformat_input_t *i = vam->input;
16085   vl_api_ikev2_set_sa_lifetime_t *mp;
16086   int ret;
16087   u8 *name = 0;
16088   u64 lifetime, lifetime_maxdata;
16089   u32 lifetime_jitter, handover;
16090
16091   const char *valid_chars = "a-zA-Z0-9_";
16092
16093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16094     {
16095       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16096                     &lifetime, &lifetime_jitter, &handover,
16097                     &lifetime_maxdata))
16098         vec_add1 (name, 0);
16099       else
16100         {
16101           errmsg ("parse error '%U'", format_unformat_error, i);
16102           return -99;
16103         }
16104     }
16105
16106   if (!vec_len (name))
16107     {
16108       errmsg ("profile name must be specified");
16109       return -99;
16110     }
16111
16112   if (vec_len (name) > 64)
16113     {
16114       errmsg ("profile name too long");
16115       return -99;
16116     }
16117
16118   M (IKEV2_SET_SA_LIFETIME, mp);
16119
16120   clib_memcpy (mp->name, name, vec_len (name));
16121   vec_free (name);
16122   mp->lifetime = lifetime;
16123   mp->lifetime_jitter = lifetime_jitter;
16124   mp->handover = handover;
16125   mp->lifetime_maxdata = lifetime_maxdata;
16126
16127   S (mp);
16128   W (ret);
16129   return ret;
16130 }
16131
16132 static int
16133 api_ikev2_initiate_sa_init (vat_main_t * vam)
16134 {
16135   unformat_input_t *i = vam->input;
16136   vl_api_ikev2_initiate_sa_init_t *mp;
16137   int ret;
16138   u8 *name = 0;
16139
16140   const char *valid_chars = "a-zA-Z0-9_";
16141
16142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16143     {
16144       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16145         vec_add1 (name, 0);
16146       else
16147         {
16148           errmsg ("parse error '%U'", format_unformat_error, i);
16149           return -99;
16150         }
16151     }
16152
16153   if (!vec_len (name))
16154     {
16155       errmsg ("profile name must be specified");
16156       return -99;
16157     }
16158
16159   if (vec_len (name) > 64)
16160     {
16161       errmsg ("profile name too long");
16162       return -99;
16163     }
16164
16165   M (IKEV2_INITIATE_SA_INIT, mp);
16166
16167   clib_memcpy (mp->name, name, vec_len (name));
16168   vec_free (name);
16169
16170   S (mp);
16171   W (ret);
16172   return ret;
16173 }
16174
16175 static int
16176 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16177 {
16178   unformat_input_t *i = vam->input;
16179   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16180   int ret;
16181   u64 ispi;
16182
16183
16184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16185     {
16186       if (unformat (i, "%lx", &ispi))
16187         ;
16188       else
16189         {
16190           errmsg ("parse error '%U'", format_unformat_error, i);
16191           return -99;
16192         }
16193     }
16194
16195   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16196
16197   mp->ispi = ispi;
16198
16199   S (mp);
16200   W (ret);
16201   return ret;
16202 }
16203
16204 static int
16205 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16206 {
16207   unformat_input_t *i = vam->input;
16208   vl_api_ikev2_initiate_del_child_sa_t *mp;
16209   int ret;
16210   u32 ispi;
16211
16212
16213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16214     {
16215       if (unformat (i, "%x", &ispi))
16216         ;
16217       else
16218         {
16219           errmsg ("parse error '%U'", format_unformat_error, i);
16220           return -99;
16221         }
16222     }
16223
16224   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16225
16226   mp->ispi = ispi;
16227
16228   S (mp);
16229   W (ret);
16230   return ret;
16231 }
16232
16233 static int
16234 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16235 {
16236   unformat_input_t *i = vam->input;
16237   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16238   int ret;
16239   u32 ispi;
16240
16241
16242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16243     {
16244       if (unformat (i, "%x", &ispi))
16245         ;
16246       else
16247         {
16248           errmsg ("parse error '%U'", format_unformat_error, i);
16249           return -99;
16250         }
16251     }
16252
16253   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16254
16255   mp->ispi = ispi;
16256
16257   S (mp);
16258   W (ret);
16259   return ret;
16260 }
16261
16262 /*
16263  * MAP
16264  */
16265 static int
16266 api_map_add_domain (vat_main_t * vam)
16267 {
16268   unformat_input_t *i = vam->input;
16269   vl_api_map_add_domain_t *mp;
16270
16271   ip4_address_t ip4_prefix;
16272   ip6_address_t ip6_prefix;
16273   ip6_address_t ip6_src;
16274   u32 num_m_args = 0;
16275   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16276     0, psid_length = 0;
16277   u8 is_translation = 0;
16278   u32 mtu = 0;
16279   u32 ip6_src_len = 128;
16280   int ret;
16281
16282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16283     {
16284       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16285                     &ip4_prefix, &ip4_prefix_len))
16286         num_m_args++;
16287       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16288                          &ip6_prefix, &ip6_prefix_len))
16289         num_m_args++;
16290       else
16291         if (unformat
16292             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16293              &ip6_src_len))
16294         num_m_args++;
16295       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16296         num_m_args++;
16297       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16298         num_m_args++;
16299       else if (unformat (i, "psid-offset %d", &psid_offset))
16300         num_m_args++;
16301       else if (unformat (i, "psid-len %d", &psid_length))
16302         num_m_args++;
16303       else if (unformat (i, "mtu %d", &mtu))
16304         num_m_args++;
16305       else if (unformat (i, "map-t"))
16306         is_translation = 1;
16307       else
16308         {
16309           clib_warning ("parse error '%U'", format_unformat_error, i);
16310           return -99;
16311         }
16312     }
16313
16314   if (num_m_args < 3)
16315     {
16316       errmsg ("mandatory argument(s) missing");
16317       return -99;
16318     }
16319
16320   /* Construct the API message */
16321   M (MAP_ADD_DOMAIN, mp);
16322
16323   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16324   mp->ip4_prefix_len = ip4_prefix_len;
16325
16326   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16327   mp->ip6_prefix_len = ip6_prefix_len;
16328
16329   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16330   mp->ip6_src_prefix_len = ip6_src_len;
16331
16332   mp->ea_bits_len = ea_bits_len;
16333   mp->psid_offset = psid_offset;
16334   mp->psid_length = psid_length;
16335   mp->is_translation = is_translation;
16336   mp->mtu = htons (mtu);
16337
16338   /* send it... */
16339   S (mp);
16340
16341   /* Wait for a reply, return good/bad news  */
16342   W (ret);
16343   return ret;
16344 }
16345
16346 static int
16347 api_map_del_domain (vat_main_t * vam)
16348 {
16349   unformat_input_t *i = vam->input;
16350   vl_api_map_del_domain_t *mp;
16351
16352   u32 num_m_args = 0;
16353   u32 index;
16354   int ret;
16355
16356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16357     {
16358       if (unformat (i, "index %d", &index))
16359         num_m_args++;
16360       else
16361         {
16362           clib_warning ("parse error '%U'", format_unformat_error, i);
16363           return -99;
16364         }
16365     }
16366
16367   if (num_m_args != 1)
16368     {
16369       errmsg ("mandatory argument(s) missing");
16370       return -99;
16371     }
16372
16373   /* Construct the API message */
16374   M (MAP_DEL_DOMAIN, mp);
16375
16376   mp->index = ntohl (index);
16377
16378   /* send it... */
16379   S (mp);
16380
16381   /* Wait for a reply, return good/bad news  */
16382   W (ret);
16383   return ret;
16384 }
16385
16386 static int
16387 api_map_add_del_rule (vat_main_t * vam)
16388 {
16389   unformat_input_t *i = vam->input;
16390   vl_api_map_add_del_rule_t *mp;
16391   u8 is_add = 1;
16392   ip6_address_t ip6_dst;
16393   u32 num_m_args = 0, index, psid = 0;
16394   int ret;
16395
16396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16397     {
16398       if (unformat (i, "index %d", &index))
16399         num_m_args++;
16400       else if (unformat (i, "psid %d", &psid))
16401         num_m_args++;
16402       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16403         num_m_args++;
16404       else if (unformat (i, "del"))
16405         {
16406           is_add = 0;
16407         }
16408       else
16409         {
16410           clib_warning ("parse error '%U'", format_unformat_error, i);
16411           return -99;
16412         }
16413     }
16414
16415   /* Construct the API message */
16416   M (MAP_ADD_DEL_RULE, mp);
16417
16418   mp->index = ntohl (index);
16419   mp->is_add = is_add;
16420   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16421   mp->psid = ntohs (psid);
16422
16423   /* send it... */
16424   S (mp);
16425
16426   /* Wait for a reply, return good/bad news  */
16427   W (ret);
16428   return ret;
16429 }
16430
16431 static int
16432 api_map_domain_dump (vat_main_t * vam)
16433 {
16434   vl_api_map_domain_dump_t *mp;
16435   vl_api_control_ping_t *mp_ping;
16436   int ret;
16437
16438   /* Construct the API message */
16439   M (MAP_DOMAIN_DUMP, mp);
16440
16441   /* send it... */
16442   S (mp);
16443
16444   /* Use a control ping for synchronization */
16445   MPING (CONTROL_PING, mp_ping);
16446   S (mp_ping);
16447
16448   W (ret);
16449   return ret;
16450 }
16451
16452 static int
16453 api_map_rule_dump (vat_main_t * vam)
16454 {
16455   unformat_input_t *i = vam->input;
16456   vl_api_map_rule_dump_t *mp;
16457   vl_api_control_ping_t *mp_ping;
16458   u32 domain_index = ~0;
16459   int ret;
16460
16461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16462     {
16463       if (unformat (i, "index %u", &domain_index))
16464         ;
16465       else
16466         break;
16467     }
16468
16469   if (domain_index == ~0)
16470     {
16471       clib_warning ("parse error: domain index expected");
16472       return -99;
16473     }
16474
16475   /* Construct the API message */
16476   M (MAP_RULE_DUMP, mp);
16477
16478   mp->domain_index = htonl (domain_index);
16479
16480   /* send it... */
16481   S (mp);
16482
16483   /* Use a control ping for synchronization */
16484   MPING (CONTROL_PING, mp_ping);
16485   S (mp_ping);
16486
16487   W (ret);
16488   return ret;
16489 }
16490
16491 static void vl_api_map_add_domain_reply_t_handler
16492   (vl_api_map_add_domain_reply_t * mp)
16493 {
16494   vat_main_t *vam = &vat_main;
16495   i32 retval = ntohl (mp->retval);
16496
16497   if (vam->async_mode)
16498     {
16499       vam->async_errors += (retval < 0);
16500     }
16501   else
16502     {
16503       vam->retval = retval;
16504       vam->result_ready = 1;
16505     }
16506 }
16507
16508 static void vl_api_map_add_domain_reply_t_handler_json
16509   (vl_api_map_add_domain_reply_t * mp)
16510 {
16511   vat_main_t *vam = &vat_main;
16512   vat_json_node_t node;
16513
16514   vat_json_init_object (&node);
16515   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16516   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16517
16518   vat_json_print (vam->ofp, &node);
16519   vat_json_free (&node);
16520
16521   vam->retval = ntohl (mp->retval);
16522   vam->result_ready = 1;
16523 }
16524
16525 static int
16526 api_get_first_msg_id (vat_main_t * vam)
16527 {
16528   vl_api_get_first_msg_id_t *mp;
16529   unformat_input_t *i = vam->input;
16530   u8 *name;
16531   u8 name_set = 0;
16532   int ret;
16533
16534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16535     {
16536       if (unformat (i, "client %s", &name))
16537         name_set = 1;
16538       else
16539         break;
16540     }
16541
16542   if (name_set == 0)
16543     {
16544       errmsg ("missing client name");
16545       return -99;
16546     }
16547   vec_add1 (name, 0);
16548
16549   if (vec_len (name) > 63)
16550     {
16551       errmsg ("client name too long");
16552       return -99;
16553     }
16554
16555   M (GET_FIRST_MSG_ID, mp);
16556   clib_memcpy (mp->name, name, vec_len (name));
16557   S (mp);
16558   W (ret);
16559   return ret;
16560 }
16561
16562 static int
16563 api_cop_interface_enable_disable (vat_main_t * vam)
16564 {
16565   unformat_input_t *line_input = vam->input;
16566   vl_api_cop_interface_enable_disable_t *mp;
16567   u32 sw_if_index = ~0;
16568   u8 enable_disable = 1;
16569   int ret;
16570
16571   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16572     {
16573       if (unformat (line_input, "disable"))
16574         enable_disable = 0;
16575       if (unformat (line_input, "enable"))
16576         enable_disable = 1;
16577       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16578                          vam, &sw_if_index))
16579         ;
16580       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16581         ;
16582       else
16583         break;
16584     }
16585
16586   if (sw_if_index == ~0)
16587     {
16588       errmsg ("missing interface name or sw_if_index");
16589       return -99;
16590     }
16591
16592   /* Construct the API message */
16593   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16594   mp->sw_if_index = ntohl (sw_if_index);
16595   mp->enable_disable = enable_disable;
16596
16597   /* send it... */
16598   S (mp);
16599   /* Wait for the reply */
16600   W (ret);
16601   return ret;
16602 }
16603
16604 static int
16605 api_cop_whitelist_enable_disable (vat_main_t * vam)
16606 {
16607   unformat_input_t *line_input = vam->input;
16608   vl_api_cop_whitelist_enable_disable_t *mp;
16609   u32 sw_if_index = ~0;
16610   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16611   u32 fib_id = 0;
16612   int ret;
16613
16614   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16615     {
16616       if (unformat (line_input, "ip4"))
16617         ip4 = 1;
16618       else if (unformat (line_input, "ip6"))
16619         ip6 = 1;
16620       else if (unformat (line_input, "default"))
16621         default_cop = 1;
16622       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16623                          vam, &sw_if_index))
16624         ;
16625       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16626         ;
16627       else if (unformat (line_input, "fib-id %d", &fib_id))
16628         ;
16629       else
16630         break;
16631     }
16632
16633   if (sw_if_index == ~0)
16634     {
16635       errmsg ("missing interface name or sw_if_index");
16636       return -99;
16637     }
16638
16639   /* Construct the API message */
16640   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16641   mp->sw_if_index = ntohl (sw_if_index);
16642   mp->fib_id = ntohl (fib_id);
16643   mp->ip4 = ip4;
16644   mp->ip6 = ip6;
16645   mp->default_cop = default_cop;
16646
16647   /* send it... */
16648   S (mp);
16649   /* Wait for the reply */
16650   W (ret);
16651   return ret;
16652 }
16653
16654 static int
16655 api_get_node_graph (vat_main_t * vam)
16656 {
16657   vl_api_get_node_graph_t *mp;
16658   int ret;
16659
16660   M (GET_NODE_GRAPH, mp);
16661
16662   /* send it... */
16663   S (mp);
16664   /* Wait for the reply */
16665   W (ret);
16666   return ret;
16667 }
16668
16669 /* *INDENT-OFF* */
16670 /** Used for parsing LISP eids */
16671 typedef CLIB_PACKED(struct{
16672   u8 addr[16];   /**< eid address */
16673   u32 len;       /**< prefix length if IP */
16674   u8 type;      /**< type of eid */
16675 }) lisp_eid_vat_t;
16676 /* *INDENT-ON* */
16677
16678 static uword
16679 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16680 {
16681   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16682
16683   memset (a, 0, sizeof (a[0]));
16684
16685   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16686     {
16687       a->type = 0;              /* ipv4 type */
16688     }
16689   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16690     {
16691       a->type = 1;              /* ipv6 type */
16692     }
16693   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16694     {
16695       a->type = 2;              /* mac type */
16696     }
16697   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16698     {
16699       a->type = 3;              /* NSH type */
16700       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16701       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16702     }
16703   else
16704     {
16705       return 0;
16706     }
16707
16708   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16709     {
16710       return 0;
16711     }
16712
16713   return 1;
16714 }
16715
16716 static int
16717 lisp_eid_size_vat (u8 type)
16718 {
16719   switch (type)
16720     {
16721     case 0:
16722       return 4;
16723     case 1:
16724       return 16;
16725     case 2:
16726       return 6;
16727     case 3:
16728       return 5;
16729     }
16730   return 0;
16731 }
16732
16733 static void
16734 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16735 {
16736   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16737 }
16738
16739 static int
16740 api_one_add_del_locator_set (vat_main_t * vam)
16741 {
16742   unformat_input_t *input = vam->input;
16743   vl_api_one_add_del_locator_set_t *mp;
16744   u8 is_add = 1;
16745   u8 *locator_set_name = NULL;
16746   u8 locator_set_name_set = 0;
16747   vl_api_local_locator_t locator, *locators = 0;
16748   u32 sw_if_index, priority, weight;
16749   u32 data_len = 0;
16750
16751   int ret;
16752   /* Parse args required to build the message */
16753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16754     {
16755       if (unformat (input, "del"))
16756         {
16757           is_add = 0;
16758         }
16759       else if (unformat (input, "locator-set %s", &locator_set_name))
16760         {
16761           locator_set_name_set = 1;
16762         }
16763       else if (unformat (input, "sw_if_index %u p %u w %u",
16764                          &sw_if_index, &priority, &weight))
16765         {
16766           locator.sw_if_index = htonl (sw_if_index);
16767           locator.priority = priority;
16768           locator.weight = weight;
16769           vec_add1 (locators, locator);
16770         }
16771       else
16772         if (unformat
16773             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16774              &sw_if_index, &priority, &weight))
16775         {
16776           locator.sw_if_index = htonl (sw_if_index);
16777           locator.priority = priority;
16778           locator.weight = weight;
16779           vec_add1 (locators, locator);
16780         }
16781       else
16782         break;
16783     }
16784
16785   if (locator_set_name_set == 0)
16786     {
16787       errmsg ("missing locator-set name");
16788       vec_free (locators);
16789       return -99;
16790     }
16791
16792   if (vec_len (locator_set_name) > 64)
16793     {
16794       errmsg ("locator-set name too long");
16795       vec_free (locator_set_name);
16796       vec_free (locators);
16797       return -99;
16798     }
16799   vec_add1 (locator_set_name, 0);
16800
16801   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16802
16803   /* Construct the API message */
16804   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16805
16806   mp->is_add = is_add;
16807   clib_memcpy (mp->locator_set_name, locator_set_name,
16808                vec_len (locator_set_name));
16809   vec_free (locator_set_name);
16810
16811   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16812   if (locators)
16813     clib_memcpy (mp->locators, locators, data_len);
16814   vec_free (locators);
16815
16816   /* send it... */
16817   S (mp);
16818
16819   /* Wait for a reply... */
16820   W (ret);
16821   return ret;
16822 }
16823
16824 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16825
16826 static int
16827 api_one_add_del_locator (vat_main_t * vam)
16828 {
16829   unformat_input_t *input = vam->input;
16830   vl_api_one_add_del_locator_t *mp;
16831   u32 tmp_if_index = ~0;
16832   u32 sw_if_index = ~0;
16833   u8 sw_if_index_set = 0;
16834   u8 sw_if_index_if_name_set = 0;
16835   u32 priority = ~0;
16836   u8 priority_set = 0;
16837   u32 weight = ~0;
16838   u8 weight_set = 0;
16839   u8 is_add = 1;
16840   u8 *locator_set_name = NULL;
16841   u8 locator_set_name_set = 0;
16842   int ret;
16843
16844   /* Parse args required to build the message */
16845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16846     {
16847       if (unformat (input, "del"))
16848         {
16849           is_add = 0;
16850         }
16851       else if (unformat (input, "locator-set %s", &locator_set_name))
16852         {
16853           locator_set_name_set = 1;
16854         }
16855       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16856                          &tmp_if_index))
16857         {
16858           sw_if_index_if_name_set = 1;
16859           sw_if_index = tmp_if_index;
16860         }
16861       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16862         {
16863           sw_if_index_set = 1;
16864           sw_if_index = tmp_if_index;
16865         }
16866       else if (unformat (input, "p %d", &priority))
16867         {
16868           priority_set = 1;
16869         }
16870       else if (unformat (input, "w %d", &weight))
16871         {
16872           weight_set = 1;
16873         }
16874       else
16875         break;
16876     }
16877
16878   if (locator_set_name_set == 0)
16879     {
16880       errmsg ("missing locator-set name");
16881       return -99;
16882     }
16883
16884   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16885     {
16886       errmsg ("missing sw_if_index");
16887       vec_free (locator_set_name);
16888       return -99;
16889     }
16890
16891   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16892     {
16893       errmsg ("cannot use both params interface name and sw_if_index");
16894       vec_free (locator_set_name);
16895       return -99;
16896     }
16897
16898   if (priority_set == 0)
16899     {
16900       errmsg ("missing locator-set priority");
16901       vec_free (locator_set_name);
16902       return -99;
16903     }
16904
16905   if (weight_set == 0)
16906     {
16907       errmsg ("missing locator-set weight");
16908       vec_free (locator_set_name);
16909       return -99;
16910     }
16911
16912   if (vec_len (locator_set_name) > 64)
16913     {
16914       errmsg ("locator-set name too long");
16915       vec_free (locator_set_name);
16916       return -99;
16917     }
16918   vec_add1 (locator_set_name, 0);
16919
16920   /* Construct the API message */
16921   M (ONE_ADD_DEL_LOCATOR, mp);
16922
16923   mp->is_add = is_add;
16924   mp->sw_if_index = ntohl (sw_if_index);
16925   mp->priority = priority;
16926   mp->weight = weight;
16927   clib_memcpy (mp->locator_set_name, locator_set_name,
16928                vec_len (locator_set_name));
16929   vec_free (locator_set_name);
16930
16931   /* send it... */
16932   S (mp);
16933
16934   /* Wait for a reply... */
16935   W (ret);
16936   return ret;
16937 }
16938
16939 #define api_lisp_add_del_locator api_one_add_del_locator
16940
16941 uword
16942 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16943 {
16944   u32 *key_id = va_arg (*args, u32 *);
16945   u8 *s = 0;
16946
16947   if (unformat (input, "%s", &s))
16948     {
16949       if (!strcmp ((char *) s, "sha1"))
16950         key_id[0] = HMAC_SHA_1_96;
16951       else if (!strcmp ((char *) s, "sha256"))
16952         key_id[0] = HMAC_SHA_256_128;
16953       else
16954         {
16955           clib_warning ("invalid key_id: '%s'", s);
16956           key_id[0] = HMAC_NO_KEY;
16957         }
16958     }
16959   else
16960     return 0;
16961
16962   vec_free (s);
16963   return 1;
16964 }
16965
16966 static int
16967 api_one_add_del_local_eid (vat_main_t * vam)
16968 {
16969   unformat_input_t *input = vam->input;
16970   vl_api_one_add_del_local_eid_t *mp;
16971   u8 is_add = 1;
16972   u8 eid_set = 0;
16973   lisp_eid_vat_t _eid, *eid = &_eid;
16974   u8 *locator_set_name = 0;
16975   u8 locator_set_name_set = 0;
16976   u32 vni = 0;
16977   u16 key_id = 0;
16978   u8 *key = 0;
16979   int ret;
16980
16981   /* Parse args required to build the message */
16982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16983     {
16984       if (unformat (input, "del"))
16985         {
16986           is_add = 0;
16987         }
16988       else if (unformat (input, "vni %d", &vni))
16989         {
16990           ;
16991         }
16992       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16993         {
16994           eid_set = 1;
16995         }
16996       else if (unformat (input, "locator-set %s", &locator_set_name))
16997         {
16998           locator_set_name_set = 1;
16999         }
17000       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17001         ;
17002       else if (unformat (input, "secret-key %_%v%_", &key))
17003         ;
17004       else
17005         break;
17006     }
17007
17008   if (locator_set_name_set == 0)
17009     {
17010       errmsg ("missing locator-set name");
17011       return -99;
17012     }
17013
17014   if (0 == eid_set)
17015     {
17016       errmsg ("EID address not set!");
17017       vec_free (locator_set_name);
17018       return -99;
17019     }
17020
17021   if (key && (0 == key_id))
17022     {
17023       errmsg ("invalid key_id!");
17024       return -99;
17025     }
17026
17027   if (vec_len (key) > 64)
17028     {
17029       errmsg ("key too long");
17030       vec_free (key);
17031       return -99;
17032     }
17033
17034   if (vec_len (locator_set_name) > 64)
17035     {
17036       errmsg ("locator-set name too long");
17037       vec_free (locator_set_name);
17038       return -99;
17039     }
17040   vec_add1 (locator_set_name, 0);
17041
17042   /* Construct the API message */
17043   M (ONE_ADD_DEL_LOCAL_EID, mp);
17044
17045   mp->is_add = is_add;
17046   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17047   mp->eid_type = eid->type;
17048   mp->prefix_len = eid->len;
17049   mp->vni = clib_host_to_net_u32 (vni);
17050   mp->key_id = clib_host_to_net_u16 (key_id);
17051   clib_memcpy (mp->locator_set_name, locator_set_name,
17052                vec_len (locator_set_name));
17053   clib_memcpy (mp->key, key, vec_len (key));
17054
17055   vec_free (locator_set_name);
17056   vec_free (key);
17057
17058   /* send it... */
17059   S (mp);
17060
17061   /* Wait for a reply... */
17062   W (ret);
17063   return ret;
17064 }
17065
17066 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17067
17068 static int
17069 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17070 {
17071   u32 dp_table = 0, vni = 0;;
17072   unformat_input_t *input = vam->input;
17073   vl_api_gpe_add_del_fwd_entry_t *mp;
17074   u8 is_add = 1;
17075   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17076   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17077   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17078   u32 action = ~0, w;
17079   ip4_address_t rmt_rloc4, lcl_rloc4;
17080   ip6_address_t rmt_rloc6, lcl_rloc6;
17081   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17082   int ret;
17083
17084   memset (&rloc, 0, sizeof (rloc));
17085
17086   /* Parse args required to build the message */
17087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17088     {
17089       if (unformat (input, "del"))
17090         is_add = 0;
17091       else if (unformat (input, "add"))
17092         is_add = 1;
17093       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17094         {
17095           rmt_eid_set = 1;
17096         }
17097       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17098         {
17099           lcl_eid_set = 1;
17100         }
17101       else if (unformat (input, "vrf %d", &dp_table))
17102         ;
17103       else if (unformat (input, "bd %d", &dp_table))
17104         ;
17105       else if (unformat (input, "vni %d", &vni))
17106         ;
17107       else if (unformat (input, "w %d", &w))
17108         {
17109           if (!curr_rloc)
17110             {
17111               errmsg ("No RLOC configured for setting priority/weight!");
17112               return -99;
17113             }
17114           curr_rloc->weight = w;
17115         }
17116       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17117                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17118         {
17119           rloc.is_ip4 = 1;
17120
17121           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17122           rloc.weight = 0;
17123           vec_add1 (lcl_locs, rloc);
17124
17125           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17126           vec_add1 (rmt_locs, rloc);
17127           /* weight saved in rmt loc */
17128           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17129         }
17130       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17131                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17132         {
17133           rloc.is_ip4 = 0;
17134           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17135           rloc.weight = 0;
17136           vec_add1 (lcl_locs, rloc);
17137
17138           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17139           vec_add1 (rmt_locs, rloc);
17140           /* weight saved in rmt loc */
17141           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17142         }
17143       else if (unformat (input, "action %d", &action))
17144         {
17145           ;
17146         }
17147       else
17148         {
17149           clib_warning ("parse error '%U'", format_unformat_error, input);
17150           return -99;
17151         }
17152     }
17153
17154   if (!rmt_eid_set)
17155     {
17156       errmsg ("remote eid addresses not set");
17157       return -99;
17158     }
17159
17160   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17161     {
17162       errmsg ("eid types don't match");
17163       return -99;
17164     }
17165
17166   if (0 == rmt_locs && (u32) ~ 0 == action)
17167     {
17168       errmsg ("action not set for negative mapping");
17169       return -99;
17170     }
17171
17172   /* Construct the API message */
17173   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17174       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17175
17176   mp->is_add = is_add;
17177   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17178   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17179   mp->eid_type = rmt_eid->type;
17180   mp->dp_table = clib_host_to_net_u32 (dp_table);
17181   mp->vni = clib_host_to_net_u32 (vni);
17182   mp->rmt_len = rmt_eid->len;
17183   mp->lcl_len = lcl_eid->len;
17184   mp->action = action;
17185
17186   if (0 != rmt_locs && 0 != lcl_locs)
17187     {
17188       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17189       clib_memcpy (mp->locs, lcl_locs,
17190                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17191
17192       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17193       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17194                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17195     }
17196   vec_free (lcl_locs);
17197   vec_free (rmt_locs);
17198
17199   /* send it... */
17200   S (mp);
17201
17202   /* Wait for a reply... */
17203   W (ret);
17204   return ret;
17205 }
17206
17207 static int
17208 api_one_add_del_map_server (vat_main_t * vam)
17209 {
17210   unformat_input_t *input = vam->input;
17211   vl_api_one_add_del_map_server_t *mp;
17212   u8 is_add = 1;
17213   u8 ipv4_set = 0;
17214   u8 ipv6_set = 0;
17215   ip4_address_t ipv4;
17216   ip6_address_t ipv6;
17217   int ret;
17218
17219   /* Parse args required to build the message */
17220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17221     {
17222       if (unformat (input, "del"))
17223         {
17224           is_add = 0;
17225         }
17226       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17227         {
17228           ipv4_set = 1;
17229         }
17230       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17231         {
17232           ipv6_set = 1;
17233         }
17234       else
17235         break;
17236     }
17237
17238   if (ipv4_set && ipv6_set)
17239     {
17240       errmsg ("both eid v4 and v6 addresses set");
17241       return -99;
17242     }
17243
17244   if (!ipv4_set && !ipv6_set)
17245     {
17246       errmsg ("eid addresses not set");
17247       return -99;
17248     }
17249
17250   /* Construct the API message */
17251   M (ONE_ADD_DEL_MAP_SERVER, mp);
17252
17253   mp->is_add = is_add;
17254   if (ipv6_set)
17255     {
17256       mp->is_ipv6 = 1;
17257       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17258     }
17259   else
17260     {
17261       mp->is_ipv6 = 0;
17262       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17263     }
17264
17265   /* send it... */
17266   S (mp);
17267
17268   /* Wait for a reply... */
17269   W (ret);
17270   return ret;
17271 }
17272
17273 #define api_lisp_add_del_map_server api_one_add_del_map_server
17274
17275 static int
17276 api_one_add_del_map_resolver (vat_main_t * vam)
17277 {
17278   unformat_input_t *input = vam->input;
17279   vl_api_one_add_del_map_resolver_t *mp;
17280   u8 is_add = 1;
17281   u8 ipv4_set = 0;
17282   u8 ipv6_set = 0;
17283   ip4_address_t ipv4;
17284   ip6_address_t ipv6;
17285   int ret;
17286
17287   /* Parse args required to build the message */
17288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17289     {
17290       if (unformat (input, "del"))
17291         {
17292           is_add = 0;
17293         }
17294       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17295         {
17296           ipv4_set = 1;
17297         }
17298       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17299         {
17300           ipv6_set = 1;
17301         }
17302       else
17303         break;
17304     }
17305
17306   if (ipv4_set && ipv6_set)
17307     {
17308       errmsg ("both eid v4 and v6 addresses set");
17309       return -99;
17310     }
17311
17312   if (!ipv4_set && !ipv6_set)
17313     {
17314       errmsg ("eid addresses not set");
17315       return -99;
17316     }
17317
17318   /* Construct the API message */
17319   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17320
17321   mp->is_add = is_add;
17322   if (ipv6_set)
17323     {
17324       mp->is_ipv6 = 1;
17325       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17326     }
17327   else
17328     {
17329       mp->is_ipv6 = 0;
17330       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17331     }
17332
17333   /* send it... */
17334   S (mp);
17335
17336   /* Wait for a reply... */
17337   W (ret);
17338   return ret;
17339 }
17340
17341 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17342
17343 static int
17344 api_lisp_gpe_enable_disable (vat_main_t * vam)
17345 {
17346   unformat_input_t *input = vam->input;
17347   vl_api_gpe_enable_disable_t *mp;
17348   u8 is_set = 0;
17349   u8 is_en = 1;
17350   int ret;
17351
17352   /* Parse args required to build the message */
17353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17354     {
17355       if (unformat (input, "enable"))
17356         {
17357           is_set = 1;
17358           is_en = 1;
17359         }
17360       else if (unformat (input, "disable"))
17361         {
17362           is_set = 1;
17363           is_en = 0;
17364         }
17365       else
17366         break;
17367     }
17368
17369   if (is_set == 0)
17370     {
17371       errmsg ("Value not set");
17372       return -99;
17373     }
17374
17375   /* Construct the API message */
17376   M (GPE_ENABLE_DISABLE, mp);
17377
17378   mp->is_en = is_en;
17379
17380   /* send it... */
17381   S (mp);
17382
17383   /* Wait for a reply... */
17384   W (ret);
17385   return ret;
17386 }
17387
17388 static int
17389 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17390 {
17391   unformat_input_t *input = vam->input;
17392   vl_api_one_rloc_probe_enable_disable_t *mp;
17393   u8 is_set = 0;
17394   u8 is_en = 0;
17395   int ret;
17396
17397   /* Parse args required to build the message */
17398   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17399     {
17400       if (unformat (input, "enable"))
17401         {
17402           is_set = 1;
17403           is_en = 1;
17404         }
17405       else if (unformat (input, "disable"))
17406         is_set = 1;
17407       else
17408         break;
17409     }
17410
17411   if (!is_set)
17412     {
17413       errmsg ("Value not set");
17414       return -99;
17415     }
17416
17417   /* Construct the API message */
17418   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17419
17420   mp->is_enabled = is_en;
17421
17422   /* send it... */
17423   S (mp);
17424
17425   /* Wait for a reply... */
17426   W (ret);
17427   return ret;
17428 }
17429
17430 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17431
17432 static int
17433 api_one_map_register_enable_disable (vat_main_t * vam)
17434 {
17435   unformat_input_t *input = vam->input;
17436   vl_api_one_map_register_enable_disable_t *mp;
17437   u8 is_set = 0;
17438   u8 is_en = 0;
17439   int ret;
17440
17441   /* Parse args required to build the message */
17442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17443     {
17444       if (unformat (input, "enable"))
17445         {
17446           is_set = 1;
17447           is_en = 1;
17448         }
17449       else if (unformat (input, "disable"))
17450         is_set = 1;
17451       else
17452         break;
17453     }
17454
17455   if (!is_set)
17456     {
17457       errmsg ("Value not set");
17458       return -99;
17459     }
17460
17461   /* Construct the API message */
17462   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17463
17464   mp->is_enabled = is_en;
17465
17466   /* send it... */
17467   S (mp);
17468
17469   /* Wait for a reply... */
17470   W (ret);
17471   return ret;
17472 }
17473
17474 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17475
17476 static int
17477 api_one_enable_disable (vat_main_t * vam)
17478 {
17479   unformat_input_t *input = vam->input;
17480   vl_api_one_enable_disable_t *mp;
17481   u8 is_set = 0;
17482   u8 is_en = 0;
17483   int ret;
17484
17485   /* Parse args required to build the message */
17486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17487     {
17488       if (unformat (input, "enable"))
17489         {
17490           is_set = 1;
17491           is_en = 1;
17492         }
17493       else if (unformat (input, "disable"))
17494         {
17495           is_set = 1;
17496         }
17497       else
17498         break;
17499     }
17500
17501   if (!is_set)
17502     {
17503       errmsg ("Value not set");
17504       return -99;
17505     }
17506
17507   /* Construct the API message */
17508   M (ONE_ENABLE_DISABLE, mp);
17509
17510   mp->is_en = is_en;
17511
17512   /* send it... */
17513   S (mp);
17514
17515   /* Wait for a reply... */
17516   W (ret);
17517   return ret;
17518 }
17519
17520 #define api_lisp_enable_disable api_one_enable_disable
17521
17522 static int
17523 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17524 {
17525   unformat_input_t *input = vam->input;
17526   vl_api_one_enable_disable_xtr_mode_t *mp;
17527   u8 is_set = 0;
17528   u8 is_en = 0;
17529   int ret;
17530
17531   /* Parse args required to build the message */
17532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17533     {
17534       if (unformat (input, "enable"))
17535         {
17536           is_set = 1;
17537           is_en = 1;
17538         }
17539       else if (unformat (input, "disable"))
17540         {
17541           is_set = 1;
17542         }
17543       else
17544         break;
17545     }
17546
17547   if (!is_set)
17548     {
17549       errmsg ("Value not set");
17550       return -99;
17551     }
17552
17553   /* Construct the API message */
17554   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17555
17556   mp->is_en = is_en;
17557
17558   /* send it... */
17559   S (mp);
17560
17561   /* Wait for a reply... */
17562   W (ret);
17563   return ret;
17564 }
17565
17566 static int
17567 api_one_show_xtr_mode (vat_main_t * vam)
17568 {
17569   vl_api_one_show_xtr_mode_t *mp;
17570   int ret;
17571
17572   /* Construct the API message */
17573   M (ONE_SHOW_XTR_MODE, mp);
17574
17575   /* send it... */
17576   S (mp);
17577
17578   /* Wait for a reply... */
17579   W (ret);
17580   return ret;
17581 }
17582
17583 static int
17584 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17585 {
17586   unformat_input_t *input = vam->input;
17587   vl_api_one_enable_disable_pitr_mode_t *mp;
17588   u8 is_set = 0;
17589   u8 is_en = 0;
17590   int ret;
17591
17592   /* Parse args required to build the message */
17593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17594     {
17595       if (unformat (input, "enable"))
17596         {
17597           is_set = 1;
17598           is_en = 1;
17599         }
17600       else if (unformat (input, "disable"))
17601         {
17602           is_set = 1;
17603         }
17604       else
17605         break;
17606     }
17607
17608   if (!is_set)
17609     {
17610       errmsg ("Value not set");
17611       return -99;
17612     }
17613
17614   /* Construct the API message */
17615   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17616
17617   mp->is_en = is_en;
17618
17619   /* send it... */
17620   S (mp);
17621
17622   /* Wait for a reply... */
17623   W (ret);
17624   return ret;
17625 }
17626
17627 static int
17628 api_one_show_pitr_mode (vat_main_t * vam)
17629 {
17630   vl_api_one_show_pitr_mode_t *mp;
17631   int ret;
17632
17633   /* Construct the API message */
17634   M (ONE_SHOW_PITR_MODE, mp);
17635
17636   /* send it... */
17637   S (mp);
17638
17639   /* Wait for a reply... */
17640   W (ret);
17641   return ret;
17642 }
17643
17644 static int
17645 api_one_enable_disable_petr_mode (vat_main_t * vam)
17646 {
17647   unformat_input_t *input = vam->input;
17648   vl_api_one_enable_disable_petr_mode_t *mp;
17649   u8 is_set = 0;
17650   u8 is_en = 0;
17651   int ret;
17652
17653   /* Parse args required to build the message */
17654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17655     {
17656       if (unformat (input, "enable"))
17657         {
17658           is_set = 1;
17659           is_en = 1;
17660         }
17661       else if (unformat (input, "disable"))
17662         {
17663           is_set = 1;
17664         }
17665       else
17666         break;
17667     }
17668
17669   if (!is_set)
17670     {
17671       errmsg ("Value not set");
17672       return -99;
17673     }
17674
17675   /* Construct the API message */
17676   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17677
17678   mp->is_en = is_en;
17679
17680   /* send it... */
17681   S (mp);
17682
17683   /* Wait for a reply... */
17684   W (ret);
17685   return ret;
17686 }
17687
17688 static int
17689 api_one_show_petr_mode (vat_main_t * vam)
17690 {
17691   vl_api_one_show_petr_mode_t *mp;
17692   int ret;
17693
17694   /* Construct the API message */
17695   M (ONE_SHOW_PETR_MODE, mp);
17696
17697   /* send it... */
17698   S (mp);
17699
17700   /* Wait for a reply... */
17701   W (ret);
17702   return ret;
17703 }
17704
17705 static int
17706 api_show_one_map_register_state (vat_main_t * vam)
17707 {
17708   vl_api_show_one_map_register_state_t *mp;
17709   int ret;
17710
17711   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17712
17713   /* send */
17714   S (mp);
17715
17716   /* wait for reply */
17717   W (ret);
17718   return ret;
17719 }
17720
17721 #define api_show_lisp_map_register_state api_show_one_map_register_state
17722
17723 static int
17724 api_show_one_rloc_probe_state (vat_main_t * vam)
17725 {
17726   vl_api_show_one_rloc_probe_state_t *mp;
17727   int ret;
17728
17729   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17730
17731   /* send */
17732   S (mp);
17733
17734   /* wait for reply */
17735   W (ret);
17736   return ret;
17737 }
17738
17739 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17740
17741 static int
17742 api_one_add_del_ndp_entry (vat_main_t * vam)
17743 {
17744   vl_api_one_add_del_ndp_entry_t *mp;
17745   unformat_input_t *input = vam->input;
17746   u8 is_add = 1;
17747   u8 mac_set = 0;
17748   u8 bd_set = 0;
17749   u8 ip_set = 0;
17750   u8 mac[6] = { 0, };
17751   u8 ip6[16] = { 0, };
17752   u32 bd = ~0;
17753   int ret;
17754
17755   /* Parse args required to build the message */
17756   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17757     {
17758       if (unformat (input, "del"))
17759         is_add = 0;
17760       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17761         mac_set = 1;
17762       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17763         ip_set = 1;
17764       else if (unformat (input, "bd %d", &bd))
17765         bd_set = 1;
17766       else
17767         {
17768           errmsg ("parse error '%U'", format_unformat_error, input);
17769           return -99;
17770         }
17771     }
17772
17773   if (!bd_set || !ip_set || (!mac_set && is_add))
17774     {
17775       errmsg ("Missing BD, IP or MAC!");
17776       return -99;
17777     }
17778
17779   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17780   mp->is_add = is_add;
17781   clib_memcpy (mp->mac, mac, 6);
17782   mp->bd = clib_host_to_net_u32 (bd);
17783   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17784
17785   /* send */
17786   S (mp);
17787
17788   /* wait for reply */
17789   W (ret);
17790   return ret;
17791 }
17792
17793 static int
17794 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17795 {
17796   vl_api_one_add_del_l2_arp_entry_t *mp;
17797   unformat_input_t *input = vam->input;
17798   u8 is_add = 1;
17799   u8 mac_set = 0;
17800   u8 bd_set = 0;
17801   u8 ip_set = 0;
17802   u8 mac[6] = { 0, };
17803   u32 ip4 = 0, bd = ~0;
17804   int ret;
17805
17806   /* Parse args required to build the message */
17807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17808     {
17809       if (unformat (input, "del"))
17810         is_add = 0;
17811       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17812         mac_set = 1;
17813       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17814         ip_set = 1;
17815       else if (unformat (input, "bd %d", &bd))
17816         bd_set = 1;
17817       else
17818         {
17819           errmsg ("parse error '%U'", format_unformat_error, input);
17820           return -99;
17821         }
17822     }
17823
17824   if (!bd_set || !ip_set || (!mac_set && is_add))
17825     {
17826       errmsg ("Missing BD, IP or MAC!");
17827       return -99;
17828     }
17829
17830   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17831   mp->is_add = is_add;
17832   clib_memcpy (mp->mac, mac, 6);
17833   mp->bd = clib_host_to_net_u32 (bd);
17834   mp->ip4 = ip4;
17835
17836   /* send */
17837   S (mp);
17838
17839   /* wait for reply */
17840   W (ret);
17841   return ret;
17842 }
17843
17844 static int
17845 api_one_ndp_bd_get (vat_main_t * vam)
17846 {
17847   vl_api_one_ndp_bd_get_t *mp;
17848   int ret;
17849
17850   M (ONE_NDP_BD_GET, mp);
17851
17852   /* send */
17853   S (mp);
17854
17855   /* wait for reply */
17856   W (ret);
17857   return ret;
17858 }
17859
17860 static int
17861 api_one_ndp_entries_get (vat_main_t * vam)
17862 {
17863   vl_api_one_ndp_entries_get_t *mp;
17864   unformat_input_t *input = vam->input;
17865   u8 bd_set = 0;
17866   u32 bd = ~0;
17867   int ret;
17868
17869   /* Parse args required to build the message */
17870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17871     {
17872       if (unformat (input, "bd %d", &bd))
17873         bd_set = 1;
17874       else
17875         {
17876           errmsg ("parse error '%U'", format_unformat_error, input);
17877           return -99;
17878         }
17879     }
17880
17881   if (!bd_set)
17882     {
17883       errmsg ("Expected bridge domain!");
17884       return -99;
17885     }
17886
17887   M (ONE_NDP_ENTRIES_GET, mp);
17888   mp->bd = clib_host_to_net_u32 (bd);
17889
17890   /* send */
17891   S (mp);
17892
17893   /* wait for reply */
17894   W (ret);
17895   return ret;
17896 }
17897
17898 static int
17899 api_one_l2_arp_bd_get (vat_main_t * vam)
17900 {
17901   vl_api_one_l2_arp_bd_get_t *mp;
17902   int ret;
17903
17904   M (ONE_L2_ARP_BD_GET, mp);
17905
17906   /* send */
17907   S (mp);
17908
17909   /* wait for reply */
17910   W (ret);
17911   return ret;
17912 }
17913
17914 static int
17915 api_one_l2_arp_entries_get (vat_main_t * vam)
17916 {
17917   vl_api_one_l2_arp_entries_get_t *mp;
17918   unformat_input_t *input = vam->input;
17919   u8 bd_set = 0;
17920   u32 bd = ~0;
17921   int ret;
17922
17923   /* Parse args required to build the message */
17924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17925     {
17926       if (unformat (input, "bd %d", &bd))
17927         bd_set = 1;
17928       else
17929         {
17930           errmsg ("parse error '%U'", format_unformat_error, input);
17931           return -99;
17932         }
17933     }
17934
17935   if (!bd_set)
17936     {
17937       errmsg ("Expected bridge domain!");
17938       return -99;
17939     }
17940
17941   M (ONE_L2_ARP_ENTRIES_GET, mp);
17942   mp->bd = clib_host_to_net_u32 (bd);
17943
17944   /* send */
17945   S (mp);
17946
17947   /* wait for reply */
17948   W (ret);
17949   return ret;
17950 }
17951
17952 static int
17953 api_one_stats_enable_disable (vat_main_t * vam)
17954 {
17955   vl_api_one_stats_enable_disable_t *mp;
17956   unformat_input_t *input = vam->input;
17957   u8 is_set = 0;
17958   u8 is_en = 0;
17959   int ret;
17960
17961   /* Parse args required to build the message */
17962   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17963     {
17964       if (unformat (input, "enable"))
17965         {
17966           is_set = 1;
17967           is_en = 1;
17968         }
17969       else if (unformat (input, "disable"))
17970         {
17971           is_set = 1;
17972         }
17973       else
17974         break;
17975     }
17976
17977   if (!is_set)
17978     {
17979       errmsg ("Value not set");
17980       return -99;
17981     }
17982
17983   M (ONE_STATS_ENABLE_DISABLE, mp);
17984   mp->is_en = is_en;
17985
17986   /* send */
17987   S (mp);
17988
17989   /* wait for reply */
17990   W (ret);
17991   return ret;
17992 }
17993
17994 static int
17995 api_show_one_stats_enable_disable (vat_main_t * vam)
17996 {
17997   vl_api_show_one_stats_enable_disable_t *mp;
17998   int ret;
17999
18000   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18001
18002   /* send */
18003   S (mp);
18004
18005   /* wait for reply */
18006   W (ret);
18007   return ret;
18008 }
18009
18010 static int
18011 api_show_one_map_request_mode (vat_main_t * vam)
18012 {
18013   vl_api_show_one_map_request_mode_t *mp;
18014   int ret;
18015
18016   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18017
18018   /* send */
18019   S (mp);
18020
18021   /* wait for reply */
18022   W (ret);
18023   return ret;
18024 }
18025
18026 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18027
18028 static int
18029 api_one_map_request_mode (vat_main_t * vam)
18030 {
18031   unformat_input_t *input = vam->input;
18032   vl_api_one_map_request_mode_t *mp;
18033   u8 mode = 0;
18034   int ret;
18035
18036   /* Parse args required to build the message */
18037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18038     {
18039       if (unformat (input, "dst-only"))
18040         mode = 0;
18041       else if (unformat (input, "src-dst"))
18042         mode = 1;
18043       else
18044         {
18045           errmsg ("parse error '%U'", format_unformat_error, input);
18046           return -99;
18047         }
18048     }
18049
18050   M (ONE_MAP_REQUEST_MODE, mp);
18051
18052   mp->mode = mode;
18053
18054   /* send */
18055   S (mp);
18056
18057   /* wait for reply */
18058   W (ret);
18059   return ret;
18060 }
18061
18062 #define api_lisp_map_request_mode api_one_map_request_mode
18063
18064 /**
18065  * Enable/disable ONE proxy ITR.
18066  *
18067  * @param vam vpp API test context
18068  * @return return code
18069  */
18070 static int
18071 api_one_pitr_set_locator_set (vat_main_t * vam)
18072 {
18073   u8 ls_name_set = 0;
18074   unformat_input_t *input = vam->input;
18075   vl_api_one_pitr_set_locator_set_t *mp;
18076   u8 is_add = 1;
18077   u8 *ls_name = 0;
18078   int ret;
18079
18080   /* Parse args required to build the message */
18081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18082     {
18083       if (unformat (input, "del"))
18084         is_add = 0;
18085       else if (unformat (input, "locator-set %s", &ls_name))
18086         ls_name_set = 1;
18087       else
18088         {
18089           errmsg ("parse error '%U'", format_unformat_error, input);
18090           return -99;
18091         }
18092     }
18093
18094   if (!ls_name_set)
18095     {
18096       errmsg ("locator-set name not set!");
18097       return -99;
18098     }
18099
18100   M (ONE_PITR_SET_LOCATOR_SET, mp);
18101
18102   mp->is_add = is_add;
18103   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18104   vec_free (ls_name);
18105
18106   /* send */
18107   S (mp);
18108
18109   /* wait for reply */
18110   W (ret);
18111   return ret;
18112 }
18113
18114 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18115
18116 static int
18117 api_one_nsh_set_locator_set (vat_main_t * vam)
18118 {
18119   u8 ls_name_set = 0;
18120   unformat_input_t *input = vam->input;
18121   vl_api_one_nsh_set_locator_set_t *mp;
18122   u8 is_add = 1;
18123   u8 *ls_name = 0;
18124   int ret;
18125
18126   /* Parse args required to build the message */
18127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18128     {
18129       if (unformat (input, "del"))
18130         is_add = 0;
18131       else if (unformat (input, "ls %s", &ls_name))
18132         ls_name_set = 1;
18133       else
18134         {
18135           errmsg ("parse error '%U'", format_unformat_error, input);
18136           return -99;
18137         }
18138     }
18139
18140   if (!ls_name_set && is_add)
18141     {
18142       errmsg ("locator-set name not set!");
18143       return -99;
18144     }
18145
18146   M (ONE_NSH_SET_LOCATOR_SET, mp);
18147
18148   mp->is_add = is_add;
18149   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18150   vec_free (ls_name);
18151
18152   /* send */
18153   S (mp);
18154
18155   /* wait for reply */
18156   W (ret);
18157   return ret;
18158 }
18159
18160 static int
18161 api_show_one_pitr (vat_main_t * vam)
18162 {
18163   vl_api_show_one_pitr_t *mp;
18164   int ret;
18165
18166   if (!vam->json_output)
18167     {
18168       print (vam->ofp, "%=20s", "lisp status:");
18169     }
18170
18171   M (SHOW_ONE_PITR, mp);
18172   /* send it... */
18173   S (mp);
18174
18175   /* Wait for a reply... */
18176   W (ret);
18177   return ret;
18178 }
18179
18180 #define api_show_lisp_pitr api_show_one_pitr
18181
18182 static int
18183 api_one_use_petr (vat_main_t * vam)
18184 {
18185   unformat_input_t *input = vam->input;
18186   vl_api_one_use_petr_t *mp;
18187   u8 is_add = 0;
18188   ip_address_t ip;
18189   int ret;
18190
18191   memset (&ip, 0, sizeof (ip));
18192
18193   /* Parse args required to build the message */
18194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18195     {
18196       if (unformat (input, "disable"))
18197         is_add = 0;
18198       else
18199         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18200         {
18201           is_add = 1;
18202           ip_addr_version (&ip) = IP4;
18203         }
18204       else
18205         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18206         {
18207           is_add = 1;
18208           ip_addr_version (&ip) = IP6;
18209         }
18210       else
18211         {
18212           errmsg ("parse error '%U'", format_unformat_error, input);
18213           return -99;
18214         }
18215     }
18216
18217   M (ONE_USE_PETR, mp);
18218
18219   mp->is_add = is_add;
18220   if (is_add)
18221     {
18222       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18223       if (mp->is_ip4)
18224         clib_memcpy (mp->address, &ip, 4);
18225       else
18226         clib_memcpy (mp->address, &ip, 16);
18227     }
18228
18229   /* send */
18230   S (mp);
18231
18232   /* wait for reply */
18233   W (ret);
18234   return ret;
18235 }
18236
18237 #define api_lisp_use_petr api_one_use_petr
18238
18239 static int
18240 api_show_one_nsh_mapping (vat_main_t * vam)
18241 {
18242   vl_api_show_one_use_petr_t *mp;
18243   int ret;
18244
18245   if (!vam->json_output)
18246     {
18247       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18248     }
18249
18250   M (SHOW_ONE_NSH_MAPPING, mp);
18251   /* send it... */
18252   S (mp);
18253
18254   /* Wait for a reply... */
18255   W (ret);
18256   return ret;
18257 }
18258
18259 static int
18260 api_show_one_use_petr (vat_main_t * vam)
18261 {
18262   vl_api_show_one_use_petr_t *mp;
18263   int ret;
18264
18265   if (!vam->json_output)
18266     {
18267       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18268     }
18269
18270   M (SHOW_ONE_USE_PETR, mp);
18271   /* send it... */
18272   S (mp);
18273
18274   /* Wait for a reply... */
18275   W (ret);
18276   return ret;
18277 }
18278
18279 #define api_show_lisp_use_petr api_show_one_use_petr
18280
18281 /**
18282  * Add/delete mapping between vni and vrf
18283  */
18284 static int
18285 api_one_eid_table_add_del_map (vat_main_t * vam)
18286 {
18287   unformat_input_t *input = vam->input;
18288   vl_api_one_eid_table_add_del_map_t *mp;
18289   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18290   u32 vni, vrf, bd_index;
18291   int ret;
18292
18293   /* Parse args required to build the message */
18294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18295     {
18296       if (unformat (input, "del"))
18297         is_add = 0;
18298       else if (unformat (input, "vrf %d", &vrf))
18299         vrf_set = 1;
18300       else if (unformat (input, "bd_index %d", &bd_index))
18301         bd_index_set = 1;
18302       else if (unformat (input, "vni %d", &vni))
18303         vni_set = 1;
18304       else
18305         break;
18306     }
18307
18308   if (!vni_set || (!vrf_set && !bd_index_set))
18309     {
18310       errmsg ("missing arguments!");
18311       return -99;
18312     }
18313
18314   if (vrf_set && bd_index_set)
18315     {
18316       errmsg ("error: both vrf and bd entered!");
18317       return -99;
18318     }
18319
18320   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18321
18322   mp->is_add = is_add;
18323   mp->vni = htonl (vni);
18324   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18325   mp->is_l2 = bd_index_set;
18326
18327   /* send */
18328   S (mp);
18329
18330   /* wait for reply */
18331   W (ret);
18332   return ret;
18333 }
18334
18335 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18336
18337 uword
18338 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18339 {
18340   u32 *action = va_arg (*args, u32 *);
18341   u8 *s = 0;
18342
18343   if (unformat (input, "%s", &s))
18344     {
18345       if (!strcmp ((char *) s, "no-action"))
18346         action[0] = 0;
18347       else if (!strcmp ((char *) s, "natively-forward"))
18348         action[0] = 1;
18349       else if (!strcmp ((char *) s, "send-map-request"))
18350         action[0] = 2;
18351       else if (!strcmp ((char *) s, "drop"))
18352         action[0] = 3;
18353       else
18354         {
18355           clib_warning ("invalid action: '%s'", s);
18356           action[0] = 3;
18357         }
18358     }
18359   else
18360     return 0;
18361
18362   vec_free (s);
18363   return 1;
18364 }
18365
18366 /**
18367  * Add/del remote mapping to/from ONE control plane
18368  *
18369  * @param vam vpp API test context
18370  * @return return code
18371  */
18372 static int
18373 api_one_add_del_remote_mapping (vat_main_t * vam)
18374 {
18375   unformat_input_t *input = vam->input;
18376   vl_api_one_add_del_remote_mapping_t *mp;
18377   u32 vni = 0;
18378   lisp_eid_vat_t _eid, *eid = &_eid;
18379   lisp_eid_vat_t _seid, *seid = &_seid;
18380   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18381   u32 action = ~0, p, w, data_len;
18382   ip4_address_t rloc4;
18383   ip6_address_t rloc6;
18384   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18385   int ret;
18386
18387   memset (&rloc, 0, sizeof (rloc));
18388
18389   /* Parse args required to build the message */
18390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18391     {
18392       if (unformat (input, "del-all"))
18393         {
18394           del_all = 1;
18395         }
18396       else if (unformat (input, "del"))
18397         {
18398           is_add = 0;
18399         }
18400       else if (unformat (input, "add"))
18401         {
18402           is_add = 1;
18403         }
18404       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18405         {
18406           eid_set = 1;
18407         }
18408       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18409         {
18410           seid_set = 1;
18411         }
18412       else if (unformat (input, "vni %d", &vni))
18413         {
18414           ;
18415         }
18416       else if (unformat (input, "p %d w %d", &p, &w))
18417         {
18418           if (!curr_rloc)
18419             {
18420               errmsg ("No RLOC configured for setting priority/weight!");
18421               return -99;
18422             }
18423           curr_rloc->priority = p;
18424           curr_rloc->weight = w;
18425         }
18426       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18427         {
18428           rloc.is_ip4 = 1;
18429           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18430           vec_add1 (rlocs, rloc);
18431           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18432         }
18433       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18434         {
18435           rloc.is_ip4 = 0;
18436           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18437           vec_add1 (rlocs, rloc);
18438           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18439         }
18440       else if (unformat (input, "action %U",
18441                          unformat_negative_mapping_action, &action))
18442         {
18443           ;
18444         }
18445       else
18446         {
18447           clib_warning ("parse error '%U'", format_unformat_error, input);
18448           return -99;
18449         }
18450     }
18451
18452   if (0 == eid_set)
18453     {
18454       errmsg ("missing params!");
18455       return -99;
18456     }
18457
18458   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18459     {
18460       errmsg ("no action set for negative map-reply!");
18461       return -99;
18462     }
18463
18464   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18465
18466   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18467   mp->is_add = is_add;
18468   mp->vni = htonl (vni);
18469   mp->action = (u8) action;
18470   mp->is_src_dst = seid_set;
18471   mp->eid_len = eid->len;
18472   mp->seid_len = seid->len;
18473   mp->del_all = del_all;
18474   mp->eid_type = eid->type;
18475   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18476   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18477
18478   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18479   clib_memcpy (mp->rlocs, rlocs, data_len);
18480   vec_free (rlocs);
18481
18482   /* send it... */
18483   S (mp);
18484
18485   /* Wait for a reply... */
18486   W (ret);
18487   return ret;
18488 }
18489
18490 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18491
18492 /**
18493  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18494  * forwarding entries in data-plane accordingly.
18495  *
18496  * @param vam vpp API test context
18497  * @return return code
18498  */
18499 static int
18500 api_one_add_del_adjacency (vat_main_t * vam)
18501 {
18502   unformat_input_t *input = vam->input;
18503   vl_api_one_add_del_adjacency_t *mp;
18504   u32 vni = 0;
18505   ip4_address_t leid4, reid4;
18506   ip6_address_t leid6, reid6;
18507   u8 reid_mac[6] = { 0 };
18508   u8 leid_mac[6] = { 0 };
18509   u8 reid_type, leid_type;
18510   u32 leid_len = 0, reid_len = 0, len;
18511   u8 is_add = 1;
18512   int ret;
18513
18514   leid_type = reid_type = (u8) ~ 0;
18515
18516   /* Parse args required to build the message */
18517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18518     {
18519       if (unformat (input, "del"))
18520         {
18521           is_add = 0;
18522         }
18523       else if (unformat (input, "add"))
18524         {
18525           is_add = 1;
18526         }
18527       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18528                          &reid4, &len))
18529         {
18530           reid_type = 0;        /* ipv4 */
18531           reid_len = len;
18532         }
18533       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18534                          &reid6, &len))
18535         {
18536           reid_type = 1;        /* ipv6 */
18537           reid_len = len;
18538         }
18539       else if (unformat (input, "reid %U", unformat_ethernet_address,
18540                          reid_mac))
18541         {
18542           reid_type = 2;        /* mac */
18543         }
18544       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18545                          &leid4, &len))
18546         {
18547           leid_type = 0;        /* ipv4 */
18548           leid_len = len;
18549         }
18550       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18551                          &leid6, &len))
18552         {
18553           leid_type = 1;        /* ipv6 */
18554           leid_len = len;
18555         }
18556       else if (unformat (input, "leid %U", unformat_ethernet_address,
18557                          leid_mac))
18558         {
18559           leid_type = 2;        /* mac */
18560         }
18561       else if (unformat (input, "vni %d", &vni))
18562         {
18563           ;
18564         }
18565       else
18566         {
18567           errmsg ("parse error '%U'", format_unformat_error, input);
18568           return -99;
18569         }
18570     }
18571
18572   if ((u8) ~ 0 == reid_type)
18573     {
18574       errmsg ("missing params!");
18575       return -99;
18576     }
18577
18578   if (leid_type != reid_type)
18579     {
18580       errmsg ("remote and local EIDs are of different types!");
18581       return -99;
18582     }
18583
18584   M (ONE_ADD_DEL_ADJACENCY, mp);
18585   mp->is_add = is_add;
18586   mp->vni = htonl (vni);
18587   mp->leid_len = leid_len;
18588   mp->reid_len = reid_len;
18589   mp->eid_type = reid_type;
18590
18591   switch (mp->eid_type)
18592     {
18593     case 0:
18594       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18595       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18596       break;
18597     case 1:
18598       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18599       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18600       break;
18601     case 2:
18602       clib_memcpy (mp->leid, leid_mac, 6);
18603       clib_memcpy (mp->reid, reid_mac, 6);
18604       break;
18605     default:
18606       errmsg ("unknown EID type %d!", mp->eid_type);
18607       return 0;
18608     }
18609
18610   /* send it... */
18611   S (mp);
18612
18613   /* Wait for a reply... */
18614   W (ret);
18615   return ret;
18616 }
18617
18618 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18619
18620 uword
18621 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18622 {
18623   u32 *mode = va_arg (*args, u32 *);
18624
18625   if (unformat (input, "lisp"))
18626     *mode = 0;
18627   else if (unformat (input, "vxlan"))
18628     *mode = 1;
18629   else
18630     return 0;
18631
18632   return 1;
18633 }
18634
18635 static int
18636 api_gpe_get_encap_mode (vat_main_t * vam)
18637 {
18638   vl_api_gpe_get_encap_mode_t *mp;
18639   int ret;
18640
18641   /* Construct the API message */
18642   M (GPE_GET_ENCAP_MODE, mp);
18643
18644   /* send it... */
18645   S (mp);
18646
18647   /* Wait for a reply... */
18648   W (ret);
18649   return ret;
18650 }
18651
18652 static int
18653 api_gpe_set_encap_mode (vat_main_t * vam)
18654 {
18655   unformat_input_t *input = vam->input;
18656   vl_api_gpe_set_encap_mode_t *mp;
18657   int ret;
18658   u32 mode = 0;
18659
18660   /* Parse args required to build the message */
18661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18662     {
18663       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18664         ;
18665       else
18666         break;
18667     }
18668
18669   /* Construct the API message */
18670   M (GPE_SET_ENCAP_MODE, mp);
18671
18672   mp->mode = mode;
18673
18674   /* send it... */
18675   S (mp);
18676
18677   /* Wait for a reply... */
18678   W (ret);
18679   return ret;
18680 }
18681
18682 static int
18683 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18684 {
18685   unformat_input_t *input = vam->input;
18686   vl_api_gpe_add_del_iface_t *mp;
18687   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18688   u32 dp_table = 0, vni = 0;
18689   int ret;
18690
18691   /* Parse args required to build the message */
18692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18693     {
18694       if (unformat (input, "up"))
18695         {
18696           action_set = 1;
18697           is_add = 1;
18698         }
18699       else if (unformat (input, "down"))
18700         {
18701           action_set = 1;
18702           is_add = 0;
18703         }
18704       else if (unformat (input, "table_id %d", &dp_table))
18705         {
18706           dp_table_set = 1;
18707         }
18708       else if (unformat (input, "bd_id %d", &dp_table))
18709         {
18710           dp_table_set = 1;
18711           is_l2 = 1;
18712         }
18713       else if (unformat (input, "vni %d", &vni))
18714         {
18715           vni_set = 1;
18716         }
18717       else
18718         break;
18719     }
18720
18721   if (action_set == 0)
18722     {
18723       errmsg ("Action not set");
18724       return -99;
18725     }
18726   if (dp_table_set == 0 || vni_set == 0)
18727     {
18728       errmsg ("vni and dp_table must be set");
18729       return -99;
18730     }
18731
18732   /* Construct the API message */
18733   M (GPE_ADD_DEL_IFACE, mp);
18734
18735   mp->is_add = is_add;
18736   mp->dp_table = clib_host_to_net_u32 (dp_table);
18737   mp->is_l2 = is_l2;
18738   mp->vni = clib_host_to_net_u32 (vni);
18739
18740   /* send it... */
18741   S (mp);
18742
18743   /* Wait for a reply... */
18744   W (ret);
18745   return ret;
18746 }
18747
18748 static int
18749 api_one_map_register_fallback_threshold (vat_main_t * vam)
18750 {
18751   unformat_input_t *input = vam->input;
18752   vl_api_one_map_register_fallback_threshold_t *mp;
18753   u32 value = 0;
18754   u8 is_set = 0;
18755   int ret;
18756
18757   /* Parse args required to build the message */
18758   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18759     {
18760       if (unformat (input, "%u", &value))
18761         is_set = 1;
18762       else
18763         {
18764           clib_warning ("parse error '%U'", format_unformat_error, input);
18765           return -99;
18766         }
18767     }
18768
18769   if (!is_set)
18770     {
18771       errmsg ("fallback threshold value is missing!");
18772       return -99;
18773     }
18774
18775   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18776   mp->value = clib_host_to_net_u32 (value);
18777
18778   /* send it... */
18779   S (mp);
18780
18781   /* Wait for a reply... */
18782   W (ret);
18783   return ret;
18784 }
18785
18786 static int
18787 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18788 {
18789   vl_api_show_one_map_register_fallback_threshold_t *mp;
18790   int ret;
18791
18792   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18793
18794   /* send it... */
18795   S (mp);
18796
18797   /* Wait for a reply... */
18798   W (ret);
18799   return ret;
18800 }
18801
18802 uword
18803 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18804 {
18805   u32 *proto = va_arg (*args, u32 *);
18806
18807   if (unformat (input, "udp"))
18808     *proto = 1;
18809   else if (unformat (input, "api"))
18810     *proto = 2;
18811   else
18812     return 0;
18813
18814   return 1;
18815 }
18816
18817 static int
18818 api_one_set_transport_protocol (vat_main_t * vam)
18819 {
18820   unformat_input_t *input = vam->input;
18821   vl_api_one_set_transport_protocol_t *mp;
18822   u8 is_set = 0;
18823   u32 protocol = 0;
18824   int ret;
18825
18826   /* Parse args required to build the message */
18827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18828     {
18829       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18830         is_set = 1;
18831       else
18832         {
18833           clib_warning ("parse error '%U'", format_unformat_error, input);
18834           return -99;
18835         }
18836     }
18837
18838   if (!is_set)
18839     {
18840       errmsg ("Transport protocol missing!");
18841       return -99;
18842     }
18843
18844   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18845   mp->protocol = (u8) protocol;
18846
18847   /* send it... */
18848   S (mp);
18849
18850   /* Wait for a reply... */
18851   W (ret);
18852   return ret;
18853 }
18854
18855 static int
18856 api_one_get_transport_protocol (vat_main_t * vam)
18857 {
18858   vl_api_one_get_transport_protocol_t *mp;
18859   int ret;
18860
18861   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18862
18863   /* send it... */
18864   S (mp);
18865
18866   /* Wait for a reply... */
18867   W (ret);
18868   return ret;
18869 }
18870
18871 static int
18872 api_one_map_register_set_ttl (vat_main_t * vam)
18873 {
18874   unformat_input_t *input = vam->input;
18875   vl_api_one_map_register_set_ttl_t *mp;
18876   u32 ttl = 0;
18877   u8 is_set = 0;
18878   int ret;
18879
18880   /* Parse args required to build the message */
18881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18882     {
18883       if (unformat (input, "%u", &ttl))
18884         is_set = 1;
18885       else
18886         {
18887           clib_warning ("parse error '%U'", format_unformat_error, input);
18888           return -99;
18889         }
18890     }
18891
18892   if (!is_set)
18893     {
18894       errmsg ("TTL value missing!");
18895       return -99;
18896     }
18897
18898   M (ONE_MAP_REGISTER_SET_TTL, mp);
18899   mp->ttl = clib_host_to_net_u32 (ttl);
18900
18901   /* send it... */
18902   S (mp);
18903
18904   /* Wait for a reply... */
18905   W (ret);
18906   return ret;
18907 }
18908
18909 static int
18910 api_show_one_map_register_ttl (vat_main_t * vam)
18911 {
18912   vl_api_show_one_map_register_ttl_t *mp;
18913   int ret;
18914
18915   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18916
18917   /* send it... */
18918   S (mp);
18919
18920   /* Wait for a reply... */
18921   W (ret);
18922   return ret;
18923 }
18924
18925 /**
18926  * Add/del map request itr rlocs from ONE control plane and updates
18927  *
18928  * @param vam vpp API test context
18929  * @return return code
18930  */
18931 static int
18932 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18933 {
18934   unformat_input_t *input = vam->input;
18935   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18936   u8 *locator_set_name = 0;
18937   u8 locator_set_name_set = 0;
18938   u8 is_add = 1;
18939   int ret;
18940
18941   /* Parse args required to build the message */
18942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18943     {
18944       if (unformat (input, "del"))
18945         {
18946           is_add = 0;
18947         }
18948       else if (unformat (input, "%_%v%_", &locator_set_name))
18949         {
18950           locator_set_name_set = 1;
18951         }
18952       else
18953         {
18954           clib_warning ("parse error '%U'", format_unformat_error, input);
18955           return -99;
18956         }
18957     }
18958
18959   if (is_add && !locator_set_name_set)
18960     {
18961       errmsg ("itr-rloc is not set!");
18962       return -99;
18963     }
18964
18965   if (is_add && vec_len (locator_set_name) > 64)
18966     {
18967       errmsg ("itr-rloc locator-set name too long");
18968       vec_free (locator_set_name);
18969       return -99;
18970     }
18971
18972   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18973   mp->is_add = is_add;
18974   if (is_add)
18975     {
18976       clib_memcpy (mp->locator_set_name, locator_set_name,
18977                    vec_len (locator_set_name));
18978     }
18979   else
18980     {
18981       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18982     }
18983   vec_free (locator_set_name);
18984
18985   /* send it... */
18986   S (mp);
18987
18988   /* Wait for a reply... */
18989   W (ret);
18990   return ret;
18991 }
18992
18993 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18994
18995 static int
18996 api_one_locator_dump (vat_main_t * vam)
18997 {
18998   unformat_input_t *input = vam->input;
18999   vl_api_one_locator_dump_t *mp;
19000   vl_api_control_ping_t *mp_ping;
19001   u8 is_index_set = 0, is_name_set = 0;
19002   u8 *ls_name = 0;
19003   u32 ls_index = ~0;
19004   int ret;
19005
19006   /* Parse args required to build the message */
19007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19008     {
19009       if (unformat (input, "ls_name %_%v%_", &ls_name))
19010         {
19011           is_name_set = 1;
19012         }
19013       else if (unformat (input, "ls_index %d", &ls_index))
19014         {
19015           is_index_set = 1;
19016         }
19017       else
19018         {
19019           errmsg ("parse error '%U'", format_unformat_error, input);
19020           return -99;
19021         }
19022     }
19023
19024   if (!is_index_set && !is_name_set)
19025     {
19026       errmsg ("error: expected one of index or name!");
19027       return -99;
19028     }
19029
19030   if (is_index_set && is_name_set)
19031     {
19032       errmsg ("error: only one param expected!");
19033       return -99;
19034     }
19035
19036   if (vec_len (ls_name) > 62)
19037     {
19038       errmsg ("error: locator set name too long!");
19039       return -99;
19040     }
19041
19042   if (!vam->json_output)
19043     {
19044       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19045     }
19046
19047   M (ONE_LOCATOR_DUMP, mp);
19048   mp->is_index_set = is_index_set;
19049
19050   if (is_index_set)
19051     mp->ls_index = clib_host_to_net_u32 (ls_index);
19052   else
19053     {
19054       vec_add1 (ls_name, 0);
19055       strncpy ((char *) mp->ls_name, (char *) ls_name,
19056                sizeof (mp->ls_name) - 1);
19057     }
19058
19059   /* send it... */
19060   S (mp);
19061
19062   /* Use a control ping for synchronization */
19063   MPING (CONTROL_PING, mp_ping);
19064   S (mp_ping);
19065
19066   /* Wait for a reply... */
19067   W (ret);
19068   return ret;
19069 }
19070
19071 #define api_lisp_locator_dump api_one_locator_dump
19072
19073 static int
19074 api_one_locator_set_dump (vat_main_t * vam)
19075 {
19076   vl_api_one_locator_set_dump_t *mp;
19077   vl_api_control_ping_t *mp_ping;
19078   unformat_input_t *input = vam->input;
19079   u8 filter = 0;
19080   int ret;
19081
19082   /* Parse args required to build the message */
19083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19084     {
19085       if (unformat (input, "local"))
19086         {
19087           filter = 1;
19088         }
19089       else if (unformat (input, "remote"))
19090         {
19091           filter = 2;
19092         }
19093       else
19094         {
19095           errmsg ("parse error '%U'", format_unformat_error, input);
19096           return -99;
19097         }
19098     }
19099
19100   if (!vam->json_output)
19101     {
19102       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19103     }
19104
19105   M (ONE_LOCATOR_SET_DUMP, mp);
19106
19107   mp->filter = filter;
19108
19109   /* send it... */
19110   S (mp);
19111
19112   /* Use a control ping for synchronization */
19113   MPING (CONTROL_PING, mp_ping);
19114   S (mp_ping);
19115
19116   /* Wait for a reply... */
19117   W (ret);
19118   return ret;
19119 }
19120
19121 #define api_lisp_locator_set_dump api_one_locator_set_dump
19122
19123 static int
19124 api_one_eid_table_map_dump (vat_main_t * vam)
19125 {
19126   u8 is_l2 = 0;
19127   u8 mode_set = 0;
19128   unformat_input_t *input = vam->input;
19129   vl_api_one_eid_table_map_dump_t *mp;
19130   vl_api_control_ping_t *mp_ping;
19131   int ret;
19132
19133   /* Parse args required to build the message */
19134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19135     {
19136       if (unformat (input, "l2"))
19137         {
19138           is_l2 = 1;
19139           mode_set = 1;
19140         }
19141       else if (unformat (input, "l3"))
19142         {
19143           is_l2 = 0;
19144           mode_set = 1;
19145         }
19146       else
19147         {
19148           errmsg ("parse error '%U'", format_unformat_error, input);
19149           return -99;
19150         }
19151     }
19152
19153   if (!mode_set)
19154     {
19155       errmsg ("expected one of 'l2' or 'l3' parameter!");
19156       return -99;
19157     }
19158
19159   if (!vam->json_output)
19160     {
19161       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19162     }
19163
19164   M (ONE_EID_TABLE_MAP_DUMP, mp);
19165   mp->is_l2 = is_l2;
19166
19167   /* send it... */
19168   S (mp);
19169
19170   /* Use a control ping for synchronization */
19171   MPING (CONTROL_PING, mp_ping);
19172   S (mp_ping);
19173
19174   /* Wait for a reply... */
19175   W (ret);
19176   return ret;
19177 }
19178
19179 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19180
19181 static int
19182 api_one_eid_table_vni_dump (vat_main_t * vam)
19183 {
19184   vl_api_one_eid_table_vni_dump_t *mp;
19185   vl_api_control_ping_t *mp_ping;
19186   int ret;
19187
19188   if (!vam->json_output)
19189     {
19190       print (vam->ofp, "VNI");
19191     }
19192
19193   M (ONE_EID_TABLE_VNI_DUMP, mp);
19194
19195   /* send it... */
19196   S (mp);
19197
19198   /* Use a control ping for synchronization */
19199   MPING (CONTROL_PING, mp_ping);
19200   S (mp_ping);
19201
19202   /* Wait for a reply... */
19203   W (ret);
19204   return ret;
19205 }
19206
19207 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19208
19209 static int
19210 api_one_eid_table_dump (vat_main_t * vam)
19211 {
19212   unformat_input_t *i = vam->input;
19213   vl_api_one_eid_table_dump_t *mp;
19214   vl_api_control_ping_t *mp_ping;
19215   struct in_addr ip4;
19216   struct in6_addr ip6;
19217   u8 mac[6];
19218   u8 eid_type = ~0, eid_set = 0;
19219   u32 prefix_length = ~0, t, vni = 0;
19220   u8 filter = 0;
19221   int ret;
19222   lisp_nsh_api_t nsh;
19223
19224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19225     {
19226       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19227         {
19228           eid_set = 1;
19229           eid_type = 0;
19230           prefix_length = t;
19231         }
19232       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19233         {
19234           eid_set = 1;
19235           eid_type = 1;
19236           prefix_length = t;
19237         }
19238       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19239         {
19240           eid_set = 1;
19241           eid_type = 2;
19242         }
19243       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19244         {
19245           eid_set = 1;
19246           eid_type = 3;
19247         }
19248       else if (unformat (i, "vni %d", &t))
19249         {
19250           vni = t;
19251         }
19252       else if (unformat (i, "local"))
19253         {
19254           filter = 1;
19255         }
19256       else if (unformat (i, "remote"))
19257         {
19258           filter = 2;
19259         }
19260       else
19261         {
19262           errmsg ("parse error '%U'", format_unformat_error, i);
19263           return -99;
19264         }
19265     }
19266
19267   if (!vam->json_output)
19268     {
19269       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19270              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19271     }
19272
19273   M (ONE_EID_TABLE_DUMP, mp);
19274
19275   mp->filter = filter;
19276   if (eid_set)
19277     {
19278       mp->eid_set = 1;
19279       mp->vni = htonl (vni);
19280       mp->eid_type = eid_type;
19281       switch (eid_type)
19282         {
19283         case 0:
19284           mp->prefix_length = prefix_length;
19285           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19286           break;
19287         case 1:
19288           mp->prefix_length = prefix_length;
19289           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19290           break;
19291         case 2:
19292           clib_memcpy (mp->eid, mac, sizeof (mac));
19293           break;
19294         case 3:
19295           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19296           break;
19297         default:
19298           errmsg ("unknown EID type %d!", eid_type);
19299           return -99;
19300         }
19301     }
19302
19303   /* send it... */
19304   S (mp);
19305
19306   /* Use a control ping for synchronization */
19307   MPING (CONTROL_PING, mp_ping);
19308   S (mp_ping);
19309
19310   /* Wait for a reply... */
19311   W (ret);
19312   return ret;
19313 }
19314
19315 #define api_lisp_eid_table_dump api_one_eid_table_dump
19316
19317 static int
19318 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19319 {
19320   unformat_input_t *i = vam->input;
19321   vl_api_gpe_fwd_entries_get_t *mp;
19322   u8 vni_set = 0;
19323   u32 vni = ~0;
19324   int ret;
19325
19326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19327     {
19328       if (unformat (i, "vni %d", &vni))
19329         {
19330           vni_set = 1;
19331         }
19332       else
19333         {
19334           errmsg ("parse error '%U'", format_unformat_error, i);
19335           return -99;
19336         }
19337     }
19338
19339   if (!vni_set)
19340     {
19341       errmsg ("vni not set!");
19342       return -99;
19343     }
19344
19345   if (!vam->json_output)
19346     {
19347       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19348              "leid", "reid");
19349     }
19350
19351   M (GPE_FWD_ENTRIES_GET, mp);
19352   mp->vni = clib_host_to_net_u32 (vni);
19353
19354   /* send it... */
19355   S (mp);
19356
19357   /* Wait for a reply... */
19358   W (ret);
19359   return ret;
19360 }
19361
19362 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19363 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19364 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19365 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19366 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19367 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19368 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19369 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19370
19371 static int
19372 api_one_adjacencies_get (vat_main_t * vam)
19373 {
19374   unformat_input_t *i = vam->input;
19375   vl_api_one_adjacencies_get_t *mp;
19376   u8 vni_set = 0;
19377   u32 vni = ~0;
19378   int ret;
19379
19380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19381     {
19382       if (unformat (i, "vni %d", &vni))
19383         {
19384           vni_set = 1;
19385         }
19386       else
19387         {
19388           errmsg ("parse error '%U'", format_unformat_error, i);
19389           return -99;
19390         }
19391     }
19392
19393   if (!vni_set)
19394     {
19395       errmsg ("vni not set!");
19396       return -99;
19397     }
19398
19399   if (!vam->json_output)
19400     {
19401       print (vam->ofp, "%s %40s", "leid", "reid");
19402     }
19403
19404   M (ONE_ADJACENCIES_GET, mp);
19405   mp->vni = clib_host_to_net_u32 (vni);
19406
19407   /* send it... */
19408   S (mp);
19409
19410   /* Wait for a reply... */
19411   W (ret);
19412   return ret;
19413 }
19414
19415 #define api_lisp_adjacencies_get api_one_adjacencies_get
19416
19417 static int
19418 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19419 {
19420   unformat_input_t *i = vam->input;
19421   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19422   int ret;
19423   u8 ip_family_set = 0, is_ip4 = 1;
19424
19425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19426     {
19427       if (unformat (i, "ip4"))
19428         {
19429           ip_family_set = 1;
19430           is_ip4 = 1;
19431         }
19432       else if (unformat (i, "ip6"))
19433         {
19434           ip_family_set = 1;
19435           is_ip4 = 0;
19436         }
19437       else
19438         {
19439           errmsg ("parse error '%U'", format_unformat_error, i);
19440           return -99;
19441         }
19442     }
19443
19444   if (!ip_family_set)
19445     {
19446       errmsg ("ip family not set!");
19447       return -99;
19448     }
19449
19450   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19451   mp->is_ip4 = is_ip4;
19452
19453   /* send it... */
19454   S (mp);
19455
19456   /* Wait for a reply... */
19457   W (ret);
19458   return ret;
19459 }
19460
19461 static int
19462 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19463 {
19464   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19465   int ret;
19466
19467   if (!vam->json_output)
19468     {
19469       print (vam->ofp, "VNIs");
19470     }
19471
19472   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19473
19474   /* send it... */
19475   S (mp);
19476
19477   /* Wait for a reply... */
19478   W (ret);
19479   return ret;
19480 }
19481
19482 static int
19483 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19484 {
19485   unformat_input_t *i = vam->input;
19486   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19487   int ret = 0;
19488   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19489   struct in_addr ip4;
19490   struct in6_addr ip6;
19491   u32 table_id = 0, nh_sw_if_index = ~0;
19492
19493   memset (&ip4, 0, sizeof (ip4));
19494   memset (&ip6, 0, sizeof (ip6));
19495
19496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19497     {
19498       if (unformat (i, "del"))
19499         is_add = 0;
19500       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19501                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19502         {
19503           ip_set = 1;
19504           is_ip4 = 1;
19505         }
19506       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19507                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19508         {
19509           ip_set = 1;
19510           is_ip4 = 0;
19511         }
19512       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19513         {
19514           ip_set = 1;
19515           is_ip4 = 1;
19516           nh_sw_if_index = ~0;
19517         }
19518       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19519         {
19520           ip_set = 1;
19521           is_ip4 = 0;
19522           nh_sw_if_index = ~0;
19523         }
19524       else if (unformat (i, "table %d", &table_id))
19525         ;
19526       else
19527         {
19528           errmsg ("parse error '%U'", format_unformat_error, i);
19529           return -99;
19530         }
19531     }
19532
19533   if (!ip_set)
19534     {
19535       errmsg ("nh addr not set!");
19536       return -99;
19537     }
19538
19539   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19540   mp->is_add = is_add;
19541   mp->table_id = clib_host_to_net_u32 (table_id);
19542   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19543   mp->is_ip4 = is_ip4;
19544   if (is_ip4)
19545     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19546   else
19547     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19548
19549   /* send it... */
19550   S (mp);
19551
19552   /* Wait for a reply... */
19553   W (ret);
19554   return ret;
19555 }
19556
19557 static int
19558 api_one_map_server_dump (vat_main_t * vam)
19559 {
19560   vl_api_one_map_server_dump_t *mp;
19561   vl_api_control_ping_t *mp_ping;
19562   int ret;
19563
19564   if (!vam->json_output)
19565     {
19566       print (vam->ofp, "%=20s", "Map server");
19567     }
19568
19569   M (ONE_MAP_SERVER_DUMP, mp);
19570   /* send it... */
19571   S (mp);
19572
19573   /* Use a control ping for synchronization */
19574   MPING (CONTROL_PING, mp_ping);
19575   S (mp_ping);
19576
19577   /* Wait for a reply... */
19578   W (ret);
19579   return ret;
19580 }
19581
19582 #define api_lisp_map_server_dump api_one_map_server_dump
19583
19584 static int
19585 api_one_map_resolver_dump (vat_main_t * vam)
19586 {
19587   vl_api_one_map_resolver_dump_t *mp;
19588   vl_api_control_ping_t *mp_ping;
19589   int ret;
19590
19591   if (!vam->json_output)
19592     {
19593       print (vam->ofp, "%=20s", "Map resolver");
19594     }
19595
19596   M (ONE_MAP_RESOLVER_DUMP, mp);
19597   /* send it... */
19598   S (mp);
19599
19600   /* Use a control ping for synchronization */
19601   MPING (CONTROL_PING, mp_ping);
19602   S (mp_ping);
19603
19604   /* Wait for a reply... */
19605   W (ret);
19606   return ret;
19607 }
19608
19609 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19610
19611 static int
19612 api_one_stats_flush (vat_main_t * vam)
19613 {
19614   vl_api_one_stats_flush_t *mp;
19615   int ret = 0;
19616
19617   M (ONE_STATS_FLUSH, mp);
19618   S (mp);
19619   W (ret);
19620   return ret;
19621 }
19622
19623 static int
19624 api_one_stats_dump (vat_main_t * vam)
19625 {
19626   vl_api_one_stats_dump_t *mp;
19627   vl_api_control_ping_t *mp_ping;
19628   int ret;
19629
19630   M (ONE_STATS_DUMP, mp);
19631   /* send it... */
19632   S (mp);
19633
19634   /* Use a control ping for synchronization */
19635   MPING (CONTROL_PING, mp_ping);
19636   S (mp_ping);
19637
19638   /* Wait for a reply... */
19639   W (ret);
19640   return ret;
19641 }
19642
19643 static int
19644 api_show_one_status (vat_main_t * vam)
19645 {
19646   vl_api_show_one_status_t *mp;
19647   int ret;
19648
19649   if (!vam->json_output)
19650     {
19651       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19652     }
19653
19654   M (SHOW_ONE_STATUS, mp);
19655   /* send it... */
19656   S (mp);
19657   /* Wait for a reply... */
19658   W (ret);
19659   return ret;
19660 }
19661
19662 #define api_show_lisp_status api_show_one_status
19663
19664 static int
19665 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19666 {
19667   vl_api_gpe_fwd_entry_path_dump_t *mp;
19668   vl_api_control_ping_t *mp_ping;
19669   unformat_input_t *i = vam->input;
19670   u32 fwd_entry_index = ~0;
19671   int ret;
19672
19673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19674     {
19675       if (unformat (i, "index %d", &fwd_entry_index))
19676         ;
19677       else
19678         break;
19679     }
19680
19681   if (~0 == fwd_entry_index)
19682     {
19683       errmsg ("no index specified!");
19684       return -99;
19685     }
19686
19687   if (!vam->json_output)
19688     {
19689       print (vam->ofp, "first line");
19690     }
19691
19692   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19693
19694   /* send it... */
19695   S (mp);
19696   /* Use a control ping for synchronization */
19697   MPING (CONTROL_PING, mp_ping);
19698   S (mp_ping);
19699
19700   /* Wait for a reply... */
19701   W (ret);
19702   return ret;
19703 }
19704
19705 static int
19706 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19707 {
19708   vl_api_one_get_map_request_itr_rlocs_t *mp;
19709   int ret;
19710
19711   if (!vam->json_output)
19712     {
19713       print (vam->ofp, "%=20s", "itr-rlocs:");
19714     }
19715
19716   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19717   /* send it... */
19718   S (mp);
19719   /* Wait for a reply... */
19720   W (ret);
19721   return ret;
19722 }
19723
19724 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19725
19726 static int
19727 api_af_packet_create (vat_main_t * vam)
19728 {
19729   unformat_input_t *i = vam->input;
19730   vl_api_af_packet_create_t *mp;
19731   u8 *host_if_name = 0;
19732   u8 hw_addr[6];
19733   u8 random_hw_addr = 1;
19734   int ret;
19735
19736   memset (hw_addr, 0, sizeof (hw_addr));
19737
19738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19739     {
19740       if (unformat (i, "name %s", &host_if_name))
19741         vec_add1 (host_if_name, 0);
19742       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19743         random_hw_addr = 0;
19744       else
19745         break;
19746     }
19747
19748   if (!vec_len (host_if_name))
19749     {
19750       errmsg ("host-interface name must be specified");
19751       return -99;
19752     }
19753
19754   if (vec_len (host_if_name) > 64)
19755     {
19756       errmsg ("host-interface name too long");
19757       return -99;
19758     }
19759
19760   M (AF_PACKET_CREATE, mp);
19761
19762   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19763   clib_memcpy (mp->hw_addr, hw_addr, 6);
19764   mp->use_random_hw_addr = random_hw_addr;
19765   vec_free (host_if_name);
19766
19767   S (mp);
19768
19769   /* *INDENT-OFF* */
19770   W2 (ret,
19771       ({
19772         if (ret == 0)
19773           fprintf (vam->ofp ? vam->ofp : stderr,
19774                    " new sw_if_index = %d\n", vam->sw_if_index);
19775       }));
19776   /* *INDENT-ON* */
19777   return ret;
19778 }
19779
19780 static int
19781 api_af_packet_delete (vat_main_t * vam)
19782 {
19783   unformat_input_t *i = vam->input;
19784   vl_api_af_packet_delete_t *mp;
19785   u8 *host_if_name = 0;
19786   int ret;
19787
19788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19789     {
19790       if (unformat (i, "name %s", &host_if_name))
19791         vec_add1 (host_if_name, 0);
19792       else
19793         break;
19794     }
19795
19796   if (!vec_len (host_if_name))
19797     {
19798       errmsg ("host-interface name must be specified");
19799       return -99;
19800     }
19801
19802   if (vec_len (host_if_name) > 64)
19803     {
19804       errmsg ("host-interface name too long");
19805       return -99;
19806     }
19807
19808   M (AF_PACKET_DELETE, mp);
19809
19810   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19811   vec_free (host_if_name);
19812
19813   S (mp);
19814   W (ret);
19815   return ret;
19816 }
19817
19818 static int
19819 api_policer_add_del (vat_main_t * vam)
19820 {
19821   unformat_input_t *i = vam->input;
19822   vl_api_policer_add_del_t *mp;
19823   u8 is_add = 1;
19824   u8 *name = 0;
19825   u32 cir = 0;
19826   u32 eir = 0;
19827   u64 cb = 0;
19828   u64 eb = 0;
19829   u8 rate_type = 0;
19830   u8 round_type = 0;
19831   u8 type = 0;
19832   u8 color_aware = 0;
19833   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19834   int ret;
19835
19836   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19837   conform_action.dscp = 0;
19838   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19839   exceed_action.dscp = 0;
19840   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19841   violate_action.dscp = 0;
19842
19843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19844     {
19845       if (unformat (i, "del"))
19846         is_add = 0;
19847       else if (unformat (i, "name %s", &name))
19848         vec_add1 (name, 0);
19849       else if (unformat (i, "cir %u", &cir))
19850         ;
19851       else if (unformat (i, "eir %u", &eir))
19852         ;
19853       else if (unformat (i, "cb %u", &cb))
19854         ;
19855       else if (unformat (i, "eb %u", &eb))
19856         ;
19857       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19858                          &rate_type))
19859         ;
19860       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19861                          &round_type))
19862         ;
19863       else if (unformat (i, "type %U", unformat_policer_type, &type))
19864         ;
19865       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19866                          &conform_action))
19867         ;
19868       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19869                          &exceed_action))
19870         ;
19871       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19872                          &violate_action))
19873         ;
19874       else if (unformat (i, "color-aware"))
19875         color_aware = 1;
19876       else
19877         break;
19878     }
19879
19880   if (!vec_len (name))
19881     {
19882       errmsg ("policer name must be specified");
19883       return -99;
19884     }
19885
19886   if (vec_len (name) > 64)
19887     {
19888       errmsg ("policer name too long");
19889       return -99;
19890     }
19891
19892   M (POLICER_ADD_DEL, mp);
19893
19894   clib_memcpy (mp->name, name, vec_len (name));
19895   vec_free (name);
19896   mp->is_add = is_add;
19897   mp->cir = ntohl (cir);
19898   mp->eir = ntohl (eir);
19899   mp->cb = clib_net_to_host_u64 (cb);
19900   mp->eb = clib_net_to_host_u64 (eb);
19901   mp->rate_type = rate_type;
19902   mp->round_type = round_type;
19903   mp->type = type;
19904   mp->conform_action_type = conform_action.action_type;
19905   mp->conform_dscp = conform_action.dscp;
19906   mp->exceed_action_type = exceed_action.action_type;
19907   mp->exceed_dscp = exceed_action.dscp;
19908   mp->violate_action_type = violate_action.action_type;
19909   mp->violate_dscp = violate_action.dscp;
19910   mp->color_aware = color_aware;
19911
19912   S (mp);
19913   W (ret);
19914   return ret;
19915 }
19916
19917 static int
19918 api_policer_dump (vat_main_t * vam)
19919 {
19920   unformat_input_t *i = vam->input;
19921   vl_api_policer_dump_t *mp;
19922   vl_api_control_ping_t *mp_ping;
19923   u8 *match_name = 0;
19924   u8 match_name_valid = 0;
19925   int ret;
19926
19927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19928     {
19929       if (unformat (i, "name %s", &match_name))
19930         {
19931           vec_add1 (match_name, 0);
19932           match_name_valid = 1;
19933         }
19934       else
19935         break;
19936     }
19937
19938   M (POLICER_DUMP, mp);
19939   mp->match_name_valid = match_name_valid;
19940   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19941   vec_free (match_name);
19942   /* send it... */
19943   S (mp);
19944
19945   /* Use a control ping for synchronization */
19946   MPING (CONTROL_PING, mp_ping);
19947   S (mp_ping);
19948
19949   /* Wait for a reply... */
19950   W (ret);
19951   return ret;
19952 }
19953
19954 static int
19955 api_policer_classify_set_interface (vat_main_t * vam)
19956 {
19957   unformat_input_t *i = vam->input;
19958   vl_api_policer_classify_set_interface_t *mp;
19959   u32 sw_if_index;
19960   int sw_if_index_set;
19961   u32 ip4_table_index = ~0;
19962   u32 ip6_table_index = ~0;
19963   u32 l2_table_index = ~0;
19964   u8 is_add = 1;
19965   int ret;
19966
19967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19968     {
19969       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19970         sw_if_index_set = 1;
19971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19972         sw_if_index_set = 1;
19973       else if (unformat (i, "del"))
19974         is_add = 0;
19975       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19976         ;
19977       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19978         ;
19979       else if (unformat (i, "l2-table %d", &l2_table_index))
19980         ;
19981       else
19982         {
19983           clib_warning ("parse error '%U'", format_unformat_error, i);
19984           return -99;
19985         }
19986     }
19987
19988   if (sw_if_index_set == 0)
19989     {
19990       errmsg ("missing interface name or sw_if_index");
19991       return -99;
19992     }
19993
19994   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19995
19996   mp->sw_if_index = ntohl (sw_if_index);
19997   mp->ip4_table_index = ntohl (ip4_table_index);
19998   mp->ip6_table_index = ntohl (ip6_table_index);
19999   mp->l2_table_index = ntohl (l2_table_index);
20000   mp->is_add = is_add;
20001
20002   S (mp);
20003   W (ret);
20004   return ret;
20005 }
20006
20007 static int
20008 api_policer_classify_dump (vat_main_t * vam)
20009 {
20010   unformat_input_t *i = vam->input;
20011   vl_api_policer_classify_dump_t *mp;
20012   vl_api_control_ping_t *mp_ping;
20013   u8 type = POLICER_CLASSIFY_N_TABLES;
20014   int ret;
20015
20016   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20017     ;
20018   else
20019     {
20020       errmsg ("classify table type must be specified");
20021       return -99;
20022     }
20023
20024   if (!vam->json_output)
20025     {
20026       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20027     }
20028
20029   M (POLICER_CLASSIFY_DUMP, mp);
20030   mp->type = type;
20031   /* send it... */
20032   S (mp);
20033
20034   /* Use a control ping for synchronization */
20035   MPING (CONTROL_PING, mp_ping);
20036   S (mp_ping);
20037
20038   /* Wait for a reply... */
20039   W (ret);
20040   return ret;
20041 }
20042
20043 static int
20044 api_netmap_create (vat_main_t * vam)
20045 {
20046   unformat_input_t *i = vam->input;
20047   vl_api_netmap_create_t *mp;
20048   u8 *if_name = 0;
20049   u8 hw_addr[6];
20050   u8 random_hw_addr = 1;
20051   u8 is_pipe = 0;
20052   u8 is_master = 0;
20053   int ret;
20054
20055   memset (hw_addr, 0, sizeof (hw_addr));
20056
20057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20058     {
20059       if (unformat (i, "name %s", &if_name))
20060         vec_add1 (if_name, 0);
20061       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20062         random_hw_addr = 0;
20063       else if (unformat (i, "pipe"))
20064         is_pipe = 1;
20065       else if (unformat (i, "master"))
20066         is_master = 1;
20067       else if (unformat (i, "slave"))
20068         is_master = 0;
20069       else
20070         break;
20071     }
20072
20073   if (!vec_len (if_name))
20074     {
20075       errmsg ("interface name must be specified");
20076       return -99;
20077     }
20078
20079   if (vec_len (if_name) > 64)
20080     {
20081       errmsg ("interface name too long");
20082       return -99;
20083     }
20084
20085   M (NETMAP_CREATE, mp);
20086
20087   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20088   clib_memcpy (mp->hw_addr, hw_addr, 6);
20089   mp->use_random_hw_addr = random_hw_addr;
20090   mp->is_pipe = is_pipe;
20091   mp->is_master = is_master;
20092   vec_free (if_name);
20093
20094   S (mp);
20095   W (ret);
20096   return ret;
20097 }
20098
20099 static int
20100 api_netmap_delete (vat_main_t * vam)
20101 {
20102   unformat_input_t *i = vam->input;
20103   vl_api_netmap_delete_t *mp;
20104   u8 *if_name = 0;
20105   int ret;
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
20112         break;
20113     }
20114
20115   if (!vec_len (if_name))
20116     {
20117       errmsg ("interface name must be specified");
20118       return -99;
20119     }
20120
20121   if (vec_len (if_name) > 64)
20122     {
20123       errmsg ("interface name too long");
20124       return -99;
20125     }
20126
20127   M (NETMAP_DELETE, mp);
20128
20129   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20130   vec_free (if_name);
20131
20132   S (mp);
20133   W (ret);
20134   return ret;
20135 }
20136
20137 static void
20138 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20139 {
20140   if (fp->afi == IP46_TYPE_IP6)
20141     print (vam->ofp,
20142            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20143            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20144            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20145            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20146            format_ip6_address, fp->next_hop);
20147   else if (fp->afi == IP46_TYPE_IP4)
20148     print (vam->ofp,
20149            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20150            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20151            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20152            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20153            format_ip4_address, fp->next_hop);
20154 }
20155
20156 static void
20157 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20158                                  vl_api_fib_path_t * fp)
20159 {
20160   struct in_addr ip4;
20161   struct in6_addr ip6;
20162
20163   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20164   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20165   vat_json_object_add_uint (node, "is_local", fp->is_local);
20166   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20167   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20168   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20169   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20170   if (fp->afi == IP46_TYPE_IP4)
20171     {
20172       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20173       vat_json_object_add_ip4 (node, "next_hop", ip4);
20174     }
20175   else if (fp->afi == IP46_TYPE_IP6)
20176     {
20177       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20178       vat_json_object_add_ip6 (node, "next_hop", ip6);
20179     }
20180 }
20181
20182 static void
20183 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20184 {
20185   vat_main_t *vam = &vat_main;
20186   int count = ntohl (mp->mt_count);
20187   vl_api_fib_path_t *fp;
20188   i32 i;
20189
20190   print (vam->ofp, "[%d]: sw_if_index %d via:",
20191          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20192   fp = mp->mt_paths;
20193   for (i = 0; i < count; i++)
20194     {
20195       vl_api_mpls_fib_path_print (vam, fp);
20196       fp++;
20197     }
20198
20199   print (vam->ofp, "");
20200 }
20201
20202 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20203 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20204
20205 static void
20206 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20207 {
20208   vat_main_t *vam = &vat_main;
20209   vat_json_node_t *node = NULL;
20210   int count = ntohl (mp->mt_count);
20211   vl_api_fib_path_t *fp;
20212   i32 i;
20213
20214   if (VAT_JSON_ARRAY != vam->json_tree.type)
20215     {
20216       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20217       vat_json_init_array (&vam->json_tree);
20218     }
20219   node = vat_json_array_add (&vam->json_tree);
20220
20221   vat_json_init_object (node);
20222   vat_json_object_add_uint (node, "tunnel_index",
20223                             ntohl (mp->mt_tunnel_index));
20224   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20225
20226   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20227
20228   fp = mp->mt_paths;
20229   for (i = 0; i < count; i++)
20230     {
20231       vl_api_mpls_fib_path_json_print (node, fp);
20232       fp++;
20233     }
20234 }
20235
20236 static int
20237 api_mpls_tunnel_dump (vat_main_t * vam)
20238 {
20239   vl_api_mpls_tunnel_dump_t *mp;
20240   vl_api_control_ping_t *mp_ping;
20241   i32 index = -1;
20242   int ret;
20243
20244   /* Parse args required to build the message */
20245   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20246     {
20247       if (!unformat (vam->input, "tunnel_index %d", &index))
20248         {
20249           index = -1;
20250           break;
20251         }
20252     }
20253
20254   print (vam->ofp, "  tunnel_index %d", index);
20255
20256   M (MPLS_TUNNEL_DUMP, mp);
20257   mp->tunnel_index = htonl (index);
20258   S (mp);
20259
20260   /* Use a control ping for synchronization */
20261   MPING (CONTROL_PING, mp_ping);
20262   S (mp_ping);
20263
20264   W (ret);
20265   return ret;
20266 }
20267
20268 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20269 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20270
20271
20272 static void
20273 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20274 {
20275   vat_main_t *vam = &vat_main;
20276   int count = ntohl (mp->count);
20277   vl_api_fib_path_t *fp;
20278   int i;
20279
20280   print (vam->ofp,
20281          "table-id %d, label %u, ess_bit %u",
20282          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20283   fp = mp->path;
20284   for (i = 0; i < count; i++)
20285     {
20286       vl_api_mpls_fib_path_print (vam, fp);
20287       fp++;
20288     }
20289 }
20290
20291 static void vl_api_mpls_fib_details_t_handler_json
20292   (vl_api_mpls_fib_details_t * mp)
20293 {
20294   vat_main_t *vam = &vat_main;
20295   int count = ntohl (mp->count);
20296   vat_json_node_t *node = NULL;
20297   vl_api_fib_path_t *fp;
20298   int i;
20299
20300   if (VAT_JSON_ARRAY != vam->json_tree.type)
20301     {
20302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20303       vat_json_init_array (&vam->json_tree);
20304     }
20305   node = vat_json_array_add (&vam->json_tree);
20306
20307   vat_json_init_object (node);
20308   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20309   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20310   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20311   vat_json_object_add_uint (node, "path_count", count);
20312   fp = mp->path;
20313   for (i = 0; i < count; i++)
20314     {
20315       vl_api_mpls_fib_path_json_print (node, fp);
20316       fp++;
20317     }
20318 }
20319
20320 static int
20321 api_mpls_fib_dump (vat_main_t * vam)
20322 {
20323   vl_api_mpls_fib_dump_t *mp;
20324   vl_api_control_ping_t *mp_ping;
20325   int ret;
20326
20327   M (MPLS_FIB_DUMP, mp);
20328   S (mp);
20329
20330   /* Use a control ping for synchronization */
20331   MPING (CONTROL_PING, mp_ping);
20332   S (mp_ping);
20333
20334   W (ret);
20335   return ret;
20336 }
20337
20338 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20339 #define vl_api_ip_fib_details_t_print vl_noop_handler
20340
20341 static void
20342 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20343 {
20344   vat_main_t *vam = &vat_main;
20345   int count = ntohl (mp->count);
20346   vl_api_fib_path_t *fp;
20347   int i;
20348
20349   print (vam->ofp,
20350          "table-id %d, prefix %U/%d",
20351          ntohl (mp->table_id), format_ip4_address, mp->address,
20352          mp->address_length);
20353   fp = mp->path;
20354   for (i = 0; i < count; i++)
20355     {
20356       if (fp->afi == IP46_TYPE_IP6)
20357         print (vam->ofp,
20358                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20359                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20360                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20361                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20362                format_ip6_address, fp->next_hop);
20363       else if (fp->afi == IP46_TYPE_IP4)
20364         print (vam->ofp,
20365                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20366                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20367                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20368                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20369                format_ip4_address, fp->next_hop);
20370       fp++;
20371     }
20372 }
20373
20374 static void vl_api_ip_fib_details_t_handler_json
20375   (vl_api_ip_fib_details_t * mp)
20376 {
20377   vat_main_t *vam = &vat_main;
20378   int count = ntohl (mp->count);
20379   vat_json_node_t *node = NULL;
20380   struct in_addr ip4;
20381   struct in6_addr ip6;
20382   vl_api_fib_path_t *fp;
20383   int i;
20384
20385   if (VAT_JSON_ARRAY != vam->json_tree.type)
20386     {
20387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20388       vat_json_init_array (&vam->json_tree);
20389     }
20390   node = vat_json_array_add (&vam->json_tree);
20391
20392   vat_json_init_object (node);
20393   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20394   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20395   vat_json_object_add_ip4 (node, "prefix", ip4);
20396   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20397   vat_json_object_add_uint (node, "path_count", count);
20398   fp = mp->path;
20399   for (i = 0; i < count; i++)
20400     {
20401       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20402       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20403       vat_json_object_add_uint (node, "is_local", fp->is_local);
20404       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20405       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20406       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20407       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20408       if (fp->afi == IP46_TYPE_IP4)
20409         {
20410           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20411           vat_json_object_add_ip4 (node, "next_hop", ip4);
20412         }
20413       else if (fp->afi == IP46_TYPE_IP6)
20414         {
20415           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20416           vat_json_object_add_ip6 (node, "next_hop", ip6);
20417         }
20418     }
20419 }
20420
20421 static int
20422 api_ip_fib_dump (vat_main_t * vam)
20423 {
20424   vl_api_ip_fib_dump_t *mp;
20425   vl_api_control_ping_t *mp_ping;
20426   int ret;
20427
20428   M (IP_FIB_DUMP, mp);
20429   S (mp);
20430
20431   /* Use a control ping for synchronization */
20432   MPING (CONTROL_PING, mp_ping);
20433   S (mp_ping);
20434
20435   W (ret);
20436   return ret;
20437 }
20438
20439 static int
20440 api_ip_mfib_dump (vat_main_t * vam)
20441 {
20442   vl_api_ip_mfib_dump_t *mp;
20443   vl_api_control_ping_t *mp_ping;
20444   int ret;
20445
20446   M (IP_MFIB_DUMP, mp);
20447   S (mp);
20448
20449   /* Use a control ping for synchronization */
20450   MPING (CONTROL_PING, mp_ping);
20451   S (mp_ping);
20452
20453   W (ret);
20454   return ret;
20455 }
20456
20457 static void vl_api_ip_neighbor_details_t_handler
20458   (vl_api_ip_neighbor_details_t * mp)
20459 {
20460   vat_main_t *vam = &vat_main;
20461
20462   print (vam->ofp, "%c %U %U",
20463          (mp->is_static) ? 'S' : 'D',
20464          format_ethernet_address, &mp->mac_address,
20465          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20466          &mp->ip_address);
20467 }
20468
20469 static void vl_api_ip_neighbor_details_t_handler_json
20470   (vl_api_ip_neighbor_details_t * mp)
20471 {
20472
20473   vat_main_t *vam = &vat_main;
20474   vat_json_node_t *node;
20475   struct in_addr ip4;
20476   struct in6_addr ip6;
20477
20478   if (VAT_JSON_ARRAY != vam->json_tree.type)
20479     {
20480       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20481       vat_json_init_array (&vam->json_tree);
20482     }
20483   node = vat_json_array_add (&vam->json_tree);
20484
20485   vat_json_init_object (node);
20486   vat_json_object_add_string_copy (node, "flag",
20487                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20488                                    "dynamic");
20489
20490   vat_json_object_add_string_copy (node, "link_layer",
20491                                    format (0, "%U", format_ethernet_address,
20492                                            &mp->mac_address));
20493
20494   if (mp->is_ipv6)
20495     {
20496       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20497       vat_json_object_add_ip6 (node, "ip_address", ip6);
20498     }
20499   else
20500     {
20501       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20502       vat_json_object_add_ip4 (node, "ip_address", ip4);
20503     }
20504 }
20505
20506 static int
20507 api_ip_neighbor_dump (vat_main_t * vam)
20508 {
20509   unformat_input_t *i = vam->input;
20510   vl_api_ip_neighbor_dump_t *mp;
20511   vl_api_control_ping_t *mp_ping;
20512   u8 is_ipv6 = 0;
20513   u32 sw_if_index = ~0;
20514   int ret;
20515
20516   /* Parse args required to build the message */
20517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20518     {
20519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20520         ;
20521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20522         ;
20523       else if (unformat (i, "ip6"))
20524         is_ipv6 = 1;
20525       else
20526         break;
20527     }
20528
20529   if (sw_if_index == ~0)
20530     {
20531       errmsg ("missing interface name or sw_if_index");
20532       return -99;
20533     }
20534
20535   M (IP_NEIGHBOR_DUMP, mp);
20536   mp->is_ipv6 = (u8) is_ipv6;
20537   mp->sw_if_index = ntohl (sw_if_index);
20538   S (mp);
20539
20540   /* Use a control ping for synchronization */
20541   MPING (CONTROL_PING, mp_ping);
20542   S (mp_ping);
20543
20544   W (ret);
20545   return ret;
20546 }
20547
20548 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20549 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20550
20551 static void
20552 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20553 {
20554   vat_main_t *vam = &vat_main;
20555   int count = ntohl (mp->count);
20556   vl_api_fib_path_t *fp;
20557   int i;
20558
20559   print (vam->ofp,
20560          "table-id %d, prefix %U/%d",
20561          ntohl (mp->table_id), format_ip6_address, mp->address,
20562          mp->address_length);
20563   fp = mp->path;
20564   for (i = 0; i < count; i++)
20565     {
20566       if (fp->afi == IP46_TYPE_IP6)
20567         print (vam->ofp,
20568                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20569                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20570                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20571                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20572                format_ip6_address, fp->next_hop);
20573       else if (fp->afi == IP46_TYPE_IP4)
20574         print (vam->ofp,
20575                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20576                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20577                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20578                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20579                format_ip4_address, fp->next_hop);
20580       fp++;
20581     }
20582 }
20583
20584 static void vl_api_ip6_fib_details_t_handler_json
20585   (vl_api_ip6_fib_details_t * mp)
20586 {
20587   vat_main_t *vam = &vat_main;
20588   int count = ntohl (mp->count);
20589   vat_json_node_t *node = NULL;
20590   struct in_addr ip4;
20591   struct in6_addr ip6;
20592   vl_api_fib_path_t *fp;
20593   int i;
20594
20595   if (VAT_JSON_ARRAY != vam->json_tree.type)
20596     {
20597       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20598       vat_json_init_array (&vam->json_tree);
20599     }
20600   node = vat_json_array_add (&vam->json_tree);
20601
20602   vat_json_init_object (node);
20603   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20604   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20605   vat_json_object_add_ip6 (node, "prefix", ip6);
20606   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20607   vat_json_object_add_uint (node, "path_count", count);
20608   fp = mp->path;
20609   for (i = 0; i < count; i++)
20610     {
20611       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20612       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20613       vat_json_object_add_uint (node, "is_local", fp->is_local);
20614       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20615       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20616       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20617       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20618       if (fp->afi == IP46_TYPE_IP4)
20619         {
20620           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20621           vat_json_object_add_ip4 (node, "next_hop", ip4);
20622         }
20623       else if (fp->afi == IP46_TYPE_IP6)
20624         {
20625           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20626           vat_json_object_add_ip6 (node, "next_hop", ip6);
20627         }
20628     }
20629 }
20630
20631 static int
20632 api_ip6_fib_dump (vat_main_t * vam)
20633 {
20634   vl_api_ip6_fib_dump_t *mp;
20635   vl_api_control_ping_t *mp_ping;
20636   int ret;
20637
20638   M (IP6_FIB_DUMP, mp);
20639   S (mp);
20640
20641   /* Use a control ping for synchronization */
20642   MPING (CONTROL_PING, mp_ping);
20643   S (mp_ping);
20644
20645   W (ret);
20646   return ret;
20647 }
20648
20649 static int
20650 api_ip6_mfib_dump (vat_main_t * vam)
20651 {
20652   vl_api_ip6_mfib_dump_t *mp;
20653   vl_api_control_ping_t *mp_ping;
20654   int ret;
20655
20656   M (IP6_MFIB_DUMP, mp);
20657   S (mp);
20658
20659   /* Use a control ping for synchronization */
20660   MPING (CONTROL_PING, mp_ping);
20661   S (mp_ping);
20662
20663   W (ret);
20664   return ret;
20665 }
20666
20667 int
20668 api_classify_table_ids (vat_main_t * vam)
20669 {
20670   vl_api_classify_table_ids_t *mp;
20671   int ret;
20672
20673   /* Construct the API message */
20674   M (CLASSIFY_TABLE_IDS, mp);
20675   mp->context = 0;
20676
20677   S (mp);
20678   W (ret);
20679   return ret;
20680 }
20681
20682 int
20683 api_classify_table_by_interface (vat_main_t * vam)
20684 {
20685   unformat_input_t *input = vam->input;
20686   vl_api_classify_table_by_interface_t *mp;
20687
20688   u32 sw_if_index = ~0;
20689   int ret;
20690   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20691     {
20692       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20693         ;
20694       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20695         ;
20696       else
20697         break;
20698     }
20699   if (sw_if_index == ~0)
20700     {
20701       errmsg ("missing interface name or sw_if_index");
20702       return -99;
20703     }
20704
20705   /* Construct the API message */
20706   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20707   mp->context = 0;
20708   mp->sw_if_index = ntohl (sw_if_index);
20709
20710   S (mp);
20711   W (ret);
20712   return ret;
20713 }
20714
20715 int
20716 api_classify_table_info (vat_main_t * vam)
20717 {
20718   unformat_input_t *input = vam->input;
20719   vl_api_classify_table_info_t *mp;
20720
20721   u32 table_id = ~0;
20722   int ret;
20723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20724     {
20725       if (unformat (input, "table_id %d", &table_id))
20726         ;
20727       else
20728         break;
20729     }
20730   if (table_id == ~0)
20731     {
20732       errmsg ("missing table id");
20733       return -99;
20734     }
20735
20736   /* Construct the API message */
20737   M (CLASSIFY_TABLE_INFO, mp);
20738   mp->context = 0;
20739   mp->table_id = ntohl (table_id);
20740
20741   S (mp);
20742   W (ret);
20743   return ret;
20744 }
20745
20746 int
20747 api_classify_session_dump (vat_main_t * vam)
20748 {
20749   unformat_input_t *input = vam->input;
20750   vl_api_classify_session_dump_t *mp;
20751   vl_api_control_ping_t *mp_ping;
20752
20753   u32 table_id = ~0;
20754   int ret;
20755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20756     {
20757       if (unformat (input, "table_id %d", &table_id))
20758         ;
20759       else
20760         break;
20761     }
20762   if (table_id == ~0)
20763     {
20764       errmsg ("missing table id");
20765       return -99;
20766     }
20767
20768   /* Construct the API message */
20769   M (CLASSIFY_SESSION_DUMP, mp);
20770   mp->context = 0;
20771   mp->table_id = ntohl (table_id);
20772   S (mp);
20773
20774   /* Use a control ping for synchronization */
20775   MPING (CONTROL_PING, mp_ping);
20776   S (mp_ping);
20777
20778   W (ret);
20779   return ret;
20780 }
20781
20782 static void
20783 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20784 {
20785   vat_main_t *vam = &vat_main;
20786
20787   print (vam->ofp, "collector_address %U, collector_port %d, "
20788          "src_address %U, vrf_id %d, path_mtu %u, "
20789          "template_interval %u, udp_checksum %d",
20790          format_ip4_address, mp->collector_address,
20791          ntohs (mp->collector_port),
20792          format_ip4_address, mp->src_address,
20793          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20794          ntohl (mp->template_interval), mp->udp_checksum);
20795
20796   vam->retval = 0;
20797   vam->result_ready = 1;
20798 }
20799
20800 static void
20801   vl_api_ipfix_exporter_details_t_handler_json
20802   (vl_api_ipfix_exporter_details_t * mp)
20803 {
20804   vat_main_t *vam = &vat_main;
20805   vat_json_node_t node;
20806   struct in_addr collector_address;
20807   struct in_addr src_address;
20808
20809   vat_json_init_object (&node);
20810   clib_memcpy (&collector_address, &mp->collector_address,
20811                sizeof (collector_address));
20812   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20813   vat_json_object_add_uint (&node, "collector_port",
20814                             ntohs (mp->collector_port));
20815   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20816   vat_json_object_add_ip4 (&node, "src_address", src_address);
20817   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20818   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20819   vat_json_object_add_uint (&node, "template_interval",
20820                             ntohl (mp->template_interval));
20821   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20822
20823   vat_json_print (vam->ofp, &node);
20824   vat_json_free (&node);
20825   vam->retval = 0;
20826   vam->result_ready = 1;
20827 }
20828
20829 int
20830 api_ipfix_exporter_dump (vat_main_t * vam)
20831 {
20832   vl_api_ipfix_exporter_dump_t *mp;
20833   int ret;
20834
20835   /* Construct the API message */
20836   M (IPFIX_EXPORTER_DUMP, mp);
20837   mp->context = 0;
20838
20839   S (mp);
20840   W (ret);
20841   return ret;
20842 }
20843
20844 static int
20845 api_ipfix_classify_stream_dump (vat_main_t * vam)
20846 {
20847   vl_api_ipfix_classify_stream_dump_t *mp;
20848   int ret;
20849
20850   /* Construct the API message */
20851   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20852   mp->context = 0;
20853
20854   S (mp);
20855   W (ret);
20856   return ret;
20857   /* NOTREACHED */
20858   return 0;
20859 }
20860
20861 static void
20862   vl_api_ipfix_classify_stream_details_t_handler
20863   (vl_api_ipfix_classify_stream_details_t * mp)
20864 {
20865   vat_main_t *vam = &vat_main;
20866   print (vam->ofp, "domain_id %d, src_port %d",
20867          ntohl (mp->domain_id), ntohs (mp->src_port));
20868   vam->retval = 0;
20869   vam->result_ready = 1;
20870 }
20871
20872 static void
20873   vl_api_ipfix_classify_stream_details_t_handler_json
20874   (vl_api_ipfix_classify_stream_details_t * mp)
20875 {
20876   vat_main_t *vam = &vat_main;
20877   vat_json_node_t node;
20878
20879   vat_json_init_object (&node);
20880   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20881   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20882
20883   vat_json_print (vam->ofp, &node);
20884   vat_json_free (&node);
20885   vam->retval = 0;
20886   vam->result_ready = 1;
20887 }
20888
20889 static int
20890 api_ipfix_classify_table_dump (vat_main_t * vam)
20891 {
20892   vl_api_ipfix_classify_table_dump_t *mp;
20893   vl_api_control_ping_t *mp_ping;
20894   int ret;
20895
20896   if (!vam->json_output)
20897     {
20898       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20899              "transport_protocol");
20900     }
20901
20902   /* Construct the API message */
20903   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20904
20905   /* send it... */
20906   S (mp);
20907
20908   /* Use a control ping for synchronization */
20909   MPING (CONTROL_PING, mp_ping);
20910   S (mp_ping);
20911
20912   W (ret);
20913   return ret;
20914 }
20915
20916 static void
20917   vl_api_ipfix_classify_table_details_t_handler
20918   (vl_api_ipfix_classify_table_details_t * mp)
20919 {
20920   vat_main_t *vam = &vat_main;
20921   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20922          mp->transport_protocol);
20923 }
20924
20925 static void
20926   vl_api_ipfix_classify_table_details_t_handler_json
20927   (vl_api_ipfix_classify_table_details_t * mp)
20928 {
20929   vat_json_node_t *node = NULL;
20930   vat_main_t *vam = &vat_main;
20931
20932   if (VAT_JSON_ARRAY != vam->json_tree.type)
20933     {
20934       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20935       vat_json_init_array (&vam->json_tree);
20936     }
20937
20938   node = vat_json_array_add (&vam->json_tree);
20939   vat_json_init_object (node);
20940
20941   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20942   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20943   vat_json_object_add_uint (node, "transport_protocol",
20944                             mp->transport_protocol);
20945 }
20946
20947 static int
20948 api_sw_interface_span_enable_disable (vat_main_t * vam)
20949 {
20950   unformat_input_t *i = vam->input;
20951   vl_api_sw_interface_span_enable_disable_t *mp;
20952   u32 src_sw_if_index = ~0;
20953   u32 dst_sw_if_index = ~0;
20954   u8 state = 3;
20955   int ret;
20956   u8 is_l2 = 0;
20957
20958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20959     {
20960       if (unformat
20961           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20962         ;
20963       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20964         ;
20965       else
20966         if (unformat
20967             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20968         ;
20969       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20970         ;
20971       else if (unformat (i, "disable"))
20972         state = 0;
20973       else if (unformat (i, "rx"))
20974         state = 1;
20975       else if (unformat (i, "tx"))
20976         state = 2;
20977       else if (unformat (i, "both"))
20978         state = 3;
20979       else if (unformat (i, "l2"))
20980         is_l2 = 1;
20981       else
20982         break;
20983     }
20984
20985   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20986
20987   mp->sw_if_index_from = htonl (src_sw_if_index);
20988   mp->sw_if_index_to = htonl (dst_sw_if_index);
20989   mp->state = state;
20990   mp->is_l2 = is_l2;
20991
20992   S (mp);
20993   W (ret);
20994   return ret;
20995 }
20996
20997 static void
20998 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20999                                             * mp)
21000 {
21001   vat_main_t *vam = &vat_main;
21002   u8 *sw_if_from_name = 0;
21003   u8 *sw_if_to_name = 0;
21004   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21005   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21006   char *states[] = { "none", "rx", "tx", "both" };
21007   hash_pair_t *p;
21008
21009   /* *INDENT-OFF* */
21010   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21011   ({
21012     if ((u32) p->value[0] == sw_if_index_from)
21013       {
21014         sw_if_from_name = (u8 *)(p->key);
21015         if (sw_if_to_name)
21016           break;
21017       }
21018     if ((u32) p->value[0] == sw_if_index_to)
21019       {
21020         sw_if_to_name = (u8 *)(p->key);
21021         if (sw_if_from_name)
21022           break;
21023       }
21024   }));
21025   /* *INDENT-ON* */
21026   print (vam->ofp, "%20s => %20s (%s) %s",
21027          sw_if_from_name, sw_if_to_name, states[mp->state],
21028          mp->is_l2 ? "l2" : "device");
21029 }
21030
21031 static void
21032   vl_api_sw_interface_span_details_t_handler_json
21033   (vl_api_sw_interface_span_details_t * mp)
21034 {
21035   vat_main_t *vam = &vat_main;
21036   vat_json_node_t *node = NULL;
21037   u8 *sw_if_from_name = 0;
21038   u8 *sw_if_to_name = 0;
21039   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21040   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21041   hash_pair_t *p;
21042
21043   /* *INDENT-OFF* */
21044   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21045   ({
21046     if ((u32) p->value[0] == sw_if_index_from)
21047       {
21048         sw_if_from_name = (u8 *)(p->key);
21049         if (sw_if_to_name)
21050           break;
21051       }
21052     if ((u32) p->value[0] == sw_if_index_to)
21053       {
21054         sw_if_to_name = (u8 *)(p->key);
21055         if (sw_if_from_name)
21056           break;
21057       }
21058   }));
21059   /* *INDENT-ON* */
21060
21061   if (VAT_JSON_ARRAY != vam->json_tree.type)
21062     {
21063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21064       vat_json_init_array (&vam->json_tree);
21065     }
21066   node = vat_json_array_add (&vam->json_tree);
21067
21068   vat_json_init_object (node);
21069   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21070   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21071   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21072   if (0 != sw_if_to_name)
21073     {
21074       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21075     }
21076   vat_json_object_add_uint (node, "state", mp->state);
21077   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21078 }
21079
21080 static int
21081 api_sw_interface_span_dump (vat_main_t * vam)
21082 {
21083   unformat_input_t *input = vam->input;
21084   vl_api_sw_interface_span_dump_t *mp;
21085   vl_api_control_ping_t *mp_ping;
21086   u8 is_l2 = 0;
21087   int ret;
21088
21089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21090     {
21091       if (unformat (input, "l2"))
21092         is_l2 = 1;
21093       else
21094         break;
21095     }
21096
21097   M (SW_INTERFACE_SPAN_DUMP, mp);
21098   mp->is_l2 = is_l2;
21099   S (mp);
21100
21101   /* Use a control ping for synchronization */
21102   MPING (CONTROL_PING, mp_ping);
21103   S (mp_ping);
21104
21105   W (ret);
21106   return ret;
21107 }
21108
21109 int
21110 api_pg_create_interface (vat_main_t * vam)
21111 {
21112   unformat_input_t *input = vam->input;
21113   vl_api_pg_create_interface_t *mp;
21114
21115   u32 if_id = ~0;
21116   int ret;
21117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21118     {
21119       if (unformat (input, "if_id %d", &if_id))
21120         ;
21121       else
21122         break;
21123     }
21124   if (if_id == ~0)
21125     {
21126       errmsg ("missing pg interface index");
21127       return -99;
21128     }
21129
21130   /* Construct the API message */
21131   M (PG_CREATE_INTERFACE, mp);
21132   mp->context = 0;
21133   mp->interface_id = ntohl (if_id);
21134
21135   S (mp);
21136   W (ret);
21137   return ret;
21138 }
21139
21140 int
21141 api_pg_capture (vat_main_t * vam)
21142 {
21143   unformat_input_t *input = vam->input;
21144   vl_api_pg_capture_t *mp;
21145
21146   u32 if_id = ~0;
21147   u8 enable = 1;
21148   u32 count = 1;
21149   u8 pcap_file_set = 0;
21150   u8 *pcap_file = 0;
21151   int ret;
21152   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21153     {
21154       if (unformat (input, "if_id %d", &if_id))
21155         ;
21156       else if (unformat (input, "pcap %s", &pcap_file))
21157         pcap_file_set = 1;
21158       else if (unformat (input, "count %d", &count))
21159         ;
21160       else if (unformat (input, "disable"))
21161         enable = 0;
21162       else
21163         break;
21164     }
21165   if (if_id == ~0)
21166     {
21167       errmsg ("missing pg interface index");
21168       return -99;
21169     }
21170   if (pcap_file_set > 0)
21171     {
21172       if (vec_len (pcap_file) > 255)
21173         {
21174           errmsg ("pcap file name is too long");
21175           return -99;
21176         }
21177     }
21178
21179   u32 name_len = vec_len (pcap_file);
21180   /* Construct the API message */
21181   M (PG_CAPTURE, mp);
21182   mp->context = 0;
21183   mp->interface_id = ntohl (if_id);
21184   mp->is_enabled = enable;
21185   mp->count = ntohl (count);
21186   mp->pcap_name_length = ntohl (name_len);
21187   if (pcap_file_set != 0)
21188     {
21189       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21190     }
21191   vec_free (pcap_file);
21192
21193   S (mp);
21194   W (ret);
21195   return ret;
21196 }
21197
21198 int
21199 api_pg_enable_disable (vat_main_t * vam)
21200 {
21201   unformat_input_t *input = vam->input;
21202   vl_api_pg_enable_disable_t *mp;
21203
21204   u8 enable = 1;
21205   u8 stream_name_set = 0;
21206   u8 *stream_name = 0;
21207   int ret;
21208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21209     {
21210       if (unformat (input, "stream %s", &stream_name))
21211         stream_name_set = 1;
21212       else if (unformat (input, "disable"))
21213         enable = 0;
21214       else
21215         break;
21216     }
21217
21218   if (stream_name_set > 0)
21219     {
21220       if (vec_len (stream_name) > 255)
21221         {
21222           errmsg ("stream name too long");
21223           return -99;
21224         }
21225     }
21226
21227   u32 name_len = vec_len (stream_name);
21228   /* Construct the API message */
21229   M (PG_ENABLE_DISABLE, mp);
21230   mp->context = 0;
21231   mp->is_enabled = enable;
21232   if (stream_name_set != 0)
21233     {
21234       mp->stream_name_length = ntohl (name_len);
21235       clib_memcpy (mp->stream_name, stream_name, name_len);
21236     }
21237   vec_free (stream_name);
21238
21239   S (mp);
21240   W (ret);
21241   return ret;
21242 }
21243
21244 int
21245 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21246 {
21247   unformat_input_t *input = vam->input;
21248   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21249
21250   u16 *low_ports = 0;
21251   u16 *high_ports = 0;
21252   u16 this_low;
21253   u16 this_hi;
21254   ip4_address_t ip4_addr;
21255   ip6_address_t ip6_addr;
21256   u32 length;
21257   u32 tmp, tmp2;
21258   u8 prefix_set = 0;
21259   u32 vrf_id = ~0;
21260   u8 is_add = 1;
21261   u8 is_ipv6 = 0;
21262   int ret;
21263
21264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21265     {
21266       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21267         {
21268           prefix_set = 1;
21269         }
21270       else
21271         if (unformat
21272             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21273         {
21274           prefix_set = 1;
21275           is_ipv6 = 1;
21276         }
21277       else if (unformat (input, "vrf %d", &vrf_id))
21278         ;
21279       else if (unformat (input, "del"))
21280         is_add = 0;
21281       else if (unformat (input, "port %d", &tmp))
21282         {
21283           if (tmp == 0 || tmp > 65535)
21284             {
21285               errmsg ("port %d out of range", tmp);
21286               return -99;
21287             }
21288           this_low = tmp;
21289           this_hi = this_low + 1;
21290           vec_add1 (low_ports, this_low);
21291           vec_add1 (high_ports, this_hi);
21292         }
21293       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21294         {
21295           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21296             {
21297               errmsg ("incorrect range parameters");
21298               return -99;
21299             }
21300           this_low = tmp;
21301           /* Note: in debug CLI +1 is added to high before
21302              passing to real fn that does "the work"
21303              (ip_source_and_port_range_check_add_del).
21304              This fn is a wrapper around the binary API fn a
21305              control plane will call, which expects this increment
21306              to have occurred. Hence letting the binary API control
21307              plane fn do the increment for consistency between VAT
21308              and other control planes.
21309            */
21310           this_hi = tmp2;
21311           vec_add1 (low_ports, this_low);
21312           vec_add1 (high_ports, this_hi);
21313         }
21314       else
21315         break;
21316     }
21317
21318   if (prefix_set == 0)
21319     {
21320       errmsg ("<address>/<mask> not specified");
21321       return -99;
21322     }
21323
21324   if (vrf_id == ~0)
21325     {
21326       errmsg ("VRF ID required, not specified");
21327       return -99;
21328     }
21329
21330   if (vrf_id == 0)
21331     {
21332       errmsg
21333         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21334       return -99;
21335     }
21336
21337   if (vec_len (low_ports) == 0)
21338     {
21339       errmsg ("At least one port or port range required");
21340       return -99;
21341     }
21342
21343   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21344
21345   mp->is_add = is_add;
21346
21347   if (is_ipv6)
21348     {
21349       mp->is_ipv6 = 1;
21350       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21351     }
21352   else
21353     {
21354       mp->is_ipv6 = 0;
21355       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21356     }
21357
21358   mp->mask_length = length;
21359   mp->number_of_ranges = vec_len (low_ports);
21360
21361   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21362   vec_free (low_ports);
21363
21364   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21365   vec_free (high_ports);
21366
21367   mp->vrf_id = ntohl (vrf_id);
21368
21369   S (mp);
21370   W (ret);
21371   return ret;
21372 }
21373
21374 int
21375 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21376 {
21377   unformat_input_t *input = vam->input;
21378   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21379   u32 sw_if_index = ~0;
21380   int vrf_set = 0;
21381   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21382   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21383   u8 is_add = 1;
21384   int ret;
21385
21386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21387     {
21388       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21389         ;
21390       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21391         ;
21392       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21393         vrf_set = 1;
21394       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21395         vrf_set = 1;
21396       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21397         vrf_set = 1;
21398       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21399         vrf_set = 1;
21400       else if (unformat (input, "del"))
21401         is_add = 0;
21402       else
21403         break;
21404     }
21405
21406   if (sw_if_index == ~0)
21407     {
21408       errmsg ("Interface required but not specified");
21409       return -99;
21410     }
21411
21412   if (vrf_set == 0)
21413     {
21414       errmsg ("VRF ID required but not specified");
21415       return -99;
21416     }
21417
21418   if (tcp_out_vrf_id == 0
21419       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21420     {
21421       errmsg
21422         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21423       return -99;
21424     }
21425
21426   /* Construct the API message */
21427   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21428
21429   mp->sw_if_index = ntohl (sw_if_index);
21430   mp->is_add = is_add;
21431   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21432   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21433   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21434   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21435
21436   /* send it... */
21437   S (mp);
21438
21439   /* Wait for a reply... */
21440   W (ret);
21441   return ret;
21442 }
21443
21444 static int
21445 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21446 {
21447   unformat_input_t *i = vam->input;
21448   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21449   u32 local_sa_id = 0;
21450   u32 remote_sa_id = 0;
21451   ip4_address_t src_address;
21452   ip4_address_t dst_address;
21453   u8 is_add = 1;
21454   int ret;
21455
21456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21457     {
21458       if (unformat (i, "local_sa %d", &local_sa_id))
21459         ;
21460       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21461         ;
21462       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21463         ;
21464       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21465         ;
21466       else if (unformat (i, "del"))
21467         is_add = 0;
21468       else
21469         {
21470           clib_warning ("parse error '%U'", format_unformat_error, i);
21471           return -99;
21472         }
21473     }
21474
21475   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21476
21477   mp->local_sa_id = ntohl (local_sa_id);
21478   mp->remote_sa_id = ntohl (remote_sa_id);
21479   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21480   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21481   mp->is_add = is_add;
21482
21483   S (mp);
21484   W (ret);
21485   return ret;
21486 }
21487
21488 static int
21489 api_punt (vat_main_t * vam)
21490 {
21491   unformat_input_t *i = vam->input;
21492   vl_api_punt_t *mp;
21493   u32 ipv = ~0;
21494   u32 protocol = ~0;
21495   u32 port = ~0;
21496   int is_add = 1;
21497   int ret;
21498
21499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21500     {
21501       if (unformat (i, "ip %d", &ipv))
21502         ;
21503       else if (unformat (i, "protocol %d", &protocol))
21504         ;
21505       else if (unformat (i, "port %d", &port))
21506         ;
21507       else if (unformat (i, "del"))
21508         is_add = 0;
21509       else
21510         {
21511           clib_warning ("parse error '%U'", format_unformat_error, i);
21512           return -99;
21513         }
21514     }
21515
21516   M (PUNT, mp);
21517
21518   mp->is_add = (u8) is_add;
21519   mp->ipv = (u8) ipv;
21520   mp->l4_protocol = (u8) protocol;
21521   mp->l4_port = htons ((u16) port);
21522
21523   S (mp);
21524   W (ret);
21525   return ret;
21526 }
21527
21528 static void vl_api_ipsec_gre_tunnel_details_t_handler
21529   (vl_api_ipsec_gre_tunnel_details_t * mp)
21530 {
21531   vat_main_t *vam = &vat_main;
21532
21533   print (vam->ofp, "%11d%15U%15U%14d%14d",
21534          ntohl (mp->sw_if_index),
21535          format_ip4_address, &mp->src_address,
21536          format_ip4_address, &mp->dst_address,
21537          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21538 }
21539
21540 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21541   (vl_api_ipsec_gre_tunnel_details_t * mp)
21542 {
21543   vat_main_t *vam = &vat_main;
21544   vat_json_node_t *node = NULL;
21545   struct in_addr ip4;
21546
21547   if (VAT_JSON_ARRAY != vam->json_tree.type)
21548     {
21549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21550       vat_json_init_array (&vam->json_tree);
21551     }
21552   node = vat_json_array_add (&vam->json_tree);
21553
21554   vat_json_init_object (node);
21555   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21556   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21557   vat_json_object_add_ip4 (node, "src_address", ip4);
21558   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21559   vat_json_object_add_ip4 (node, "dst_address", ip4);
21560   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21561   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21562 }
21563
21564 static int
21565 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21566 {
21567   unformat_input_t *i = vam->input;
21568   vl_api_ipsec_gre_tunnel_dump_t *mp;
21569   vl_api_control_ping_t *mp_ping;
21570   u32 sw_if_index;
21571   u8 sw_if_index_set = 0;
21572   int ret;
21573
21574   /* Parse args required to build the message */
21575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21576     {
21577       if (unformat (i, "sw_if_index %d", &sw_if_index))
21578         sw_if_index_set = 1;
21579       else
21580         break;
21581     }
21582
21583   if (sw_if_index_set == 0)
21584     {
21585       sw_if_index = ~0;
21586     }
21587
21588   if (!vam->json_output)
21589     {
21590       print (vam->ofp, "%11s%15s%15s%14s%14s",
21591              "sw_if_index", "src_address", "dst_address",
21592              "local_sa_id", "remote_sa_id");
21593     }
21594
21595   /* Get list of gre-tunnel interfaces */
21596   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21597
21598   mp->sw_if_index = htonl (sw_if_index);
21599
21600   S (mp);
21601
21602   /* Use a control ping for synchronization */
21603   MPING (CONTROL_PING, mp_ping);
21604   S (mp_ping);
21605
21606   W (ret);
21607   return ret;
21608 }
21609
21610 static int
21611 api_delete_subif (vat_main_t * vam)
21612 {
21613   unformat_input_t *i = vam->input;
21614   vl_api_delete_subif_t *mp;
21615   u32 sw_if_index = ~0;
21616   int ret;
21617
21618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21619     {
21620       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21621         ;
21622       if (unformat (i, "sw_if_index %d", &sw_if_index))
21623         ;
21624       else
21625         break;
21626     }
21627
21628   if (sw_if_index == ~0)
21629     {
21630       errmsg ("missing sw_if_index");
21631       return -99;
21632     }
21633
21634   /* Construct the API message */
21635   M (DELETE_SUBIF, mp);
21636   mp->sw_if_index = ntohl (sw_if_index);
21637
21638   S (mp);
21639   W (ret);
21640   return ret;
21641 }
21642
21643 #define foreach_pbb_vtr_op      \
21644 _("disable",  L2_VTR_DISABLED)  \
21645 _("pop",  L2_VTR_POP_2)         \
21646 _("push",  L2_VTR_PUSH_2)
21647
21648 static int
21649 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21650 {
21651   unformat_input_t *i = vam->input;
21652   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21653   u32 sw_if_index = ~0, vtr_op = ~0;
21654   u16 outer_tag = ~0;
21655   u8 dmac[6], smac[6];
21656   u8 dmac_set = 0, smac_set = 0;
21657   u16 vlanid = 0;
21658   u32 sid = ~0;
21659   u32 tmp;
21660   int ret;
21661
21662   /* Shut up coverity */
21663   memset (dmac, 0, sizeof (dmac));
21664   memset (smac, 0, sizeof (smac));
21665
21666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21667     {
21668       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21669         ;
21670       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21671         ;
21672       else if (unformat (i, "vtr_op %d", &vtr_op))
21673         ;
21674 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21675       foreach_pbb_vtr_op
21676 #undef _
21677         else if (unformat (i, "translate_pbb_stag"))
21678         {
21679           if (unformat (i, "%d", &tmp))
21680             {
21681               vtr_op = L2_VTR_TRANSLATE_2_1;
21682               outer_tag = tmp;
21683             }
21684           else
21685             {
21686               errmsg
21687                 ("translate_pbb_stag operation requires outer tag definition");
21688               return -99;
21689             }
21690         }
21691       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21692         dmac_set++;
21693       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21694         smac_set++;
21695       else if (unformat (i, "sid %d", &sid))
21696         ;
21697       else if (unformat (i, "vlanid %d", &tmp))
21698         vlanid = tmp;
21699       else
21700         {
21701           clib_warning ("parse error '%U'", format_unformat_error, i);
21702           return -99;
21703         }
21704     }
21705
21706   if ((sw_if_index == ~0) || (vtr_op == ~0))
21707     {
21708       errmsg ("missing sw_if_index or vtr operation");
21709       return -99;
21710     }
21711   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21712       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21713     {
21714       errmsg
21715         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21716       return -99;
21717     }
21718
21719   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21720   mp->sw_if_index = ntohl (sw_if_index);
21721   mp->vtr_op = ntohl (vtr_op);
21722   mp->outer_tag = ntohs (outer_tag);
21723   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21724   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21725   mp->b_vlanid = ntohs (vlanid);
21726   mp->i_sid = ntohl (sid);
21727
21728   S (mp);
21729   W (ret);
21730   return ret;
21731 }
21732
21733 static int
21734 api_flow_classify_set_interface (vat_main_t * vam)
21735 {
21736   unformat_input_t *i = vam->input;
21737   vl_api_flow_classify_set_interface_t *mp;
21738   u32 sw_if_index;
21739   int sw_if_index_set;
21740   u32 ip4_table_index = ~0;
21741   u32 ip6_table_index = ~0;
21742   u8 is_add = 1;
21743   int ret;
21744
21745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21746     {
21747       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21748         sw_if_index_set = 1;
21749       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21750         sw_if_index_set = 1;
21751       else if (unformat (i, "del"))
21752         is_add = 0;
21753       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21754         ;
21755       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21756         ;
21757       else
21758         {
21759           clib_warning ("parse error '%U'", format_unformat_error, i);
21760           return -99;
21761         }
21762     }
21763
21764   if (sw_if_index_set == 0)
21765     {
21766       errmsg ("missing interface name or sw_if_index");
21767       return -99;
21768     }
21769
21770   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21771
21772   mp->sw_if_index = ntohl (sw_if_index);
21773   mp->ip4_table_index = ntohl (ip4_table_index);
21774   mp->ip6_table_index = ntohl (ip6_table_index);
21775   mp->is_add = is_add;
21776
21777   S (mp);
21778   W (ret);
21779   return ret;
21780 }
21781
21782 static int
21783 api_flow_classify_dump (vat_main_t * vam)
21784 {
21785   unformat_input_t *i = vam->input;
21786   vl_api_flow_classify_dump_t *mp;
21787   vl_api_control_ping_t *mp_ping;
21788   u8 type = FLOW_CLASSIFY_N_TABLES;
21789   int ret;
21790
21791   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21792     ;
21793   else
21794     {
21795       errmsg ("classify table type must be specified");
21796       return -99;
21797     }
21798
21799   if (!vam->json_output)
21800     {
21801       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21802     }
21803
21804   M (FLOW_CLASSIFY_DUMP, mp);
21805   mp->type = type;
21806   /* send it... */
21807   S (mp);
21808
21809   /* Use a control ping for synchronization */
21810   MPING (CONTROL_PING, mp_ping);
21811   S (mp_ping);
21812
21813   /* Wait for a reply... */
21814   W (ret);
21815   return ret;
21816 }
21817
21818 static int
21819 api_feature_enable_disable (vat_main_t * vam)
21820 {
21821   unformat_input_t *i = vam->input;
21822   vl_api_feature_enable_disable_t *mp;
21823   u8 *arc_name = 0;
21824   u8 *feature_name = 0;
21825   u32 sw_if_index = ~0;
21826   u8 enable = 1;
21827   int ret;
21828
21829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21830     {
21831       if (unformat (i, "arc_name %s", &arc_name))
21832         ;
21833       else if (unformat (i, "feature_name %s", &feature_name))
21834         ;
21835       else
21836         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21837         ;
21838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21839         ;
21840       else if (unformat (i, "disable"))
21841         enable = 0;
21842       else
21843         break;
21844     }
21845
21846   if (arc_name == 0)
21847     {
21848       errmsg ("missing arc name");
21849       return -99;
21850     }
21851   if (vec_len (arc_name) > 63)
21852     {
21853       errmsg ("arc name too long");
21854     }
21855
21856   if (feature_name == 0)
21857     {
21858       errmsg ("missing feature name");
21859       return -99;
21860     }
21861   if (vec_len (feature_name) > 63)
21862     {
21863       errmsg ("feature name too long");
21864     }
21865
21866   if (sw_if_index == ~0)
21867     {
21868       errmsg ("missing interface name or sw_if_index");
21869       return -99;
21870     }
21871
21872   /* Construct the API message */
21873   M (FEATURE_ENABLE_DISABLE, mp);
21874   mp->sw_if_index = ntohl (sw_if_index);
21875   mp->enable = enable;
21876   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21877   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21878   vec_free (arc_name);
21879   vec_free (feature_name);
21880
21881   S (mp);
21882   W (ret);
21883   return ret;
21884 }
21885
21886 static int
21887 api_sw_interface_tag_add_del (vat_main_t * vam)
21888 {
21889   unformat_input_t *i = vam->input;
21890   vl_api_sw_interface_tag_add_del_t *mp;
21891   u32 sw_if_index = ~0;
21892   u8 *tag = 0;
21893   u8 enable = 1;
21894   int ret;
21895
21896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21897     {
21898       if (unformat (i, "tag %s", &tag))
21899         ;
21900       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21901         ;
21902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21903         ;
21904       else if (unformat (i, "del"))
21905         enable = 0;
21906       else
21907         break;
21908     }
21909
21910   if (sw_if_index == ~0)
21911     {
21912       errmsg ("missing interface name or sw_if_index");
21913       return -99;
21914     }
21915
21916   if (enable && (tag == 0))
21917     {
21918       errmsg ("no tag specified");
21919       return -99;
21920     }
21921
21922   /* Construct the API message */
21923   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21924   mp->sw_if_index = ntohl (sw_if_index);
21925   mp->is_add = enable;
21926   if (enable)
21927     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21928   vec_free (tag);
21929
21930   S (mp);
21931   W (ret);
21932   return ret;
21933 }
21934
21935 static void vl_api_l2_xconnect_details_t_handler
21936   (vl_api_l2_xconnect_details_t * mp)
21937 {
21938   vat_main_t *vam = &vat_main;
21939
21940   print (vam->ofp, "%15d%15d",
21941          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21942 }
21943
21944 static void vl_api_l2_xconnect_details_t_handler_json
21945   (vl_api_l2_xconnect_details_t * mp)
21946 {
21947   vat_main_t *vam = &vat_main;
21948   vat_json_node_t *node = NULL;
21949
21950   if (VAT_JSON_ARRAY != vam->json_tree.type)
21951     {
21952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21953       vat_json_init_array (&vam->json_tree);
21954     }
21955   node = vat_json_array_add (&vam->json_tree);
21956
21957   vat_json_init_object (node);
21958   vat_json_object_add_uint (node, "rx_sw_if_index",
21959                             ntohl (mp->rx_sw_if_index));
21960   vat_json_object_add_uint (node, "tx_sw_if_index",
21961                             ntohl (mp->tx_sw_if_index));
21962 }
21963
21964 static int
21965 api_l2_xconnect_dump (vat_main_t * vam)
21966 {
21967   vl_api_l2_xconnect_dump_t *mp;
21968   vl_api_control_ping_t *mp_ping;
21969   int ret;
21970
21971   if (!vam->json_output)
21972     {
21973       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21974     }
21975
21976   M (L2_XCONNECT_DUMP, mp);
21977
21978   S (mp);
21979
21980   /* Use a control ping for synchronization */
21981   MPING (CONTROL_PING, mp_ping);
21982   S (mp_ping);
21983
21984   W (ret);
21985   return ret;
21986 }
21987
21988 static int
21989 api_sw_interface_set_mtu (vat_main_t * vam)
21990 {
21991   unformat_input_t *i = vam->input;
21992   vl_api_sw_interface_set_mtu_t *mp;
21993   u32 sw_if_index = ~0;
21994   u32 mtu = 0;
21995   int ret;
21996
21997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21998     {
21999       if (unformat (i, "mtu %d", &mtu))
22000         ;
22001       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22002         ;
22003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22004         ;
22005       else
22006         break;
22007     }
22008
22009   if (sw_if_index == ~0)
22010     {
22011       errmsg ("missing interface name or sw_if_index");
22012       return -99;
22013     }
22014
22015   if (mtu == 0)
22016     {
22017       errmsg ("no mtu specified");
22018       return -99;
22019     }
22020
22021   /* Construct the API message */
22022   M (SW_INTERFACE_SET_MTU, mp);
22023   mp->sw_if_index = ntohl (sw_if_index);
22024   mp->mtu = ntohs ((u16) mtu);
22025
22026   S (mp);
22027   W (ret);
22028   return ret;
22029 }
22030
22031 static int
22032 api_p2p_ethernet_add (vat_main_t * vam)
22033 {
22034   unformat_input_t *i = vam->input;
22035   vl_api_p2p_ethernet_add_t *mp;
22036   u32 parent_if_index = ~0;
22037   u32 sub_id = ~0;
22038   u8 remote_mac[6];
22039   u8 mac_set = 0;
22040   int ret;
22041
22042   memset (remote_mac, 0, sizeof (remote_mac));
22043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22044     {
22045       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22046         ;
22047       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22048         ;
22049       else
22050         if (unformat
22051             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22052         mac_set++;
22053       else if (unformat (i, "sub_id %d", &sub_id))
22054         ;
22055       else
22056         {
22057           clib_warning ("parse error '%U'", format_unformat_error, i);
22058           return -99;
22059         }
22060     }
22061
22062   if (parent_if_index == ~0)
22063     {
22064       errmsg ("missing interface name or sw_if_index");
22065       return -99;
22066     }
22067   if (mac_set == 0)
22068     {
22069       errmsg ("missing remote mac address");
22070       return -99;
22071     }
22072   if (sub_id == ~0)
22073     {
22074       errmsg ("missing sub-interface id");
22075       return -99;
22076     }
22077
22078   M (P2P_ETHERNET_ADD, mp);
22079   mp->parent_if_index = ntohl (parent_if_index);
22080   mp->subif_id = ntohl (sub_id);
22081   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22082
22083   S (mp);
22084   W (ret);
22085   return ret;
22086 }
22087
22088 static int
22089 api_p2p_ethernet_del (vat_main_t * vam)
22090 {
22091   unformat_input_t *i = vam->input;
22092   vl_api_p2p_ethernet_del_t *mp;
22093   u32 parent_if_index = ~0;
22094   u8 remote_mac[6];
22095   u8 mac_set = 0;
22096   int ret;
22097
22098   memset (remote_mac, 0, sizeof (remote_mac));
22099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22100     {
22101       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22102         ;
22103       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22104         ;
22105       else
22106         if (unformat
22107             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22108         mac_set++;
22109       else
22110         {
22111           clib_warning ("parse error '%U'", format_unformat_error, i);
22112           return -99;
22113         }
22114     }
22115
22116   if (parent_if_index == ~0)
22117     {
22118       errmsg ("missing interface name or sw_if_index");
22119       return -99;
22120     }
22121   if (mac_set == 0)
22122     {
22123       errmsg ("missing remote mac address");
22124       return -99;
22125     }
22126
22127   M (P2P_ETHERNET_DEL, mp);
22128   mp->parent_if_index = ntohl (parent_if_index);
22129   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22130
22131   S (mp);
22132   W (ret);
22133   return ret;
22134 }
22135
22136 static int
22137 api_lldp_config (vat_main_t * vam)
22138 {
22139   unformat_input_t *i = vam->input;
22140   vl_api_lldp_config_t *mp;
22141   int tx_hold = 0;
22142   int tx_interval = 0;
22143   u8 *sys_name = NULL;
22144   int ret;
22145
22146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22147     {
22148       if (unformat (i, "system-name %s", &sys_name))
22149         ;
22150       else if (unformat (i, "tx-hold %d", &tx_hold))
22151         ;
22152       else if (unformat (i, "tx-interval %d", &tx_interval))
22153         ;
22154       else
22155         {
22156           clib_warning ("parse error '%U'", format_unformat_error, i);
22157           return -99;
22158         }
22159     }
22160
22161   vec_add1 (sys_name, 0);
22162
22163   M (LLDP_CONFIG, mp);
22164   mp->tx_hold = htonl (tx_hold);
22165   mp->tx_interval = htonl (tx_interval);
22166   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22167   vec_free (sys_name);
22168
22169   S (mp);
22170   W (ret);
22171   return ret;
22172 }
22173
22174 static int
22175 api_sw_interface_set_lldp (vat_main_t * vam)
22176 {
22177   unformat_input_t *i = vam->input;
22178   vl_api_sw_interface_set_lldp_t *mp;
22179   u32 sw_if_index = ~0;
22180   u32 enable = 1;
22181   u8 *port_desc = NULL, *mgmt_oid = NULL;
22182   ip4_address_t ip4_addr;
22183   ip6_address_t ip6_addr;
22184   int ret;
22185
22186   memset (&ip4_addr, 0, sizeof (ip4_addr));
22187   memset (&ip6_addr, 0, sizeof (ip6_addr));
22188
22189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22190     {
22191       if (unformat (i, "disable"))
22192         enable = 0;
22193       else
22194         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22195         ;
22196       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22197         ;
22198       else if (unformat (i, "port-desc %s", &port_desc))
22199         ;
22200       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22201         ;
22202       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22203         ;
22204       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22205         ;
22206       else
22207         break;
22208     }
22209
22210   if (sw_if_index == ~0)
22211     {
22212       errmsg ("missing interface name or sw_if_index");
22213       return -99;
22214     }
22215
22216   /* Construct the API message */
22217   vec_add1 (port_desc, 0);
22218   vec_add1 (mgmt_oid, 0);
22219   M (SW_INTERFACE_SET_LLDP, mp);
22220   mp->sw_if_index = ntohl (sw_if_index);
22221   mp->enable = enable;
22222   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22223   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22224   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22225   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22226   vec_free (port_desc);
22227   vec_free (mgmt_oid);
22228
22229   S (mp);
22230   W (ret);
22231   return ret;
22232 }
22233
22234 static int
22235 api_tcp_configure_src_addresses (vat_main_t * vam)
22236 {
22237   vl_api_tcp_configure_src_addresses_t *mp;
22238   unformat_input_t *i = vam->input;
22239   ip4_address_t v4first, v4last;
22240   ip6_address_t v6first, v6last;
22241   u8 range_set = 0;
22242   u32 vrf_id = 0;
22243   int ret;
22244
22245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22246     {
22247       if (unformat (i, "%U - %U",
22248                     unformat_ip4_address, &v4first,
22249                     unformat_ip4_address, &v4last))
22250         {
22251           if (range_set)
22252             {
22253               errmsg ("one range per message (range already set)");
22254               return -99;
22255             }
22256           range_set = 1;
22257         }
22258       else if (unformat (i, "%U - %U",
22259                          unformat_ip6_address, &v6first,
22260                          unformat_ip6_address, &v6last))
22261         {
22262           if (range_set)
22263             {
22264               errmsg ("one range per message (range already set)");
22265               return -99;
22266             }
22267           range_set = 2;
22268         }
22269       else if (unformat (i, "vrf %d", &vrf_id))
22270         ;
22271       else
22272         break;
22273     }
22274
22275   if (range_set == 0)
22276     {
22277       errmsg ("address range not set");
22278       return -99;
22279     }
22280
22281   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22282   mp->vrf_id = ntohl (vrf_id);
22283   /* ipv6? */
22284   if (range_set == 2)
22285     {
22286       mp->is_ipv6 = 1;
22287       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22288       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22289     }
22290   else
22291     {
22292       mp->is_ipv6 = 0;
22293       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22294       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22295     }
22296   S (mp);
22297   W (ret);
22298   return ret;
22299 }
22300
22301 static void vl_api_app_namespace_add_del_reply_t_handler
22302   (vl_api_app_namespace_add_del_reply_t * mp)
22303 {
22304   vat_main_t *vam = &vat_main;
22305   i32 retval = ntohl (mp->retval);
22306   if (vam->async_mode)
22307     {
22308       vam->async_errors += (retval < 0);
22309     }
22310   else
22311     {
22312       vam->retval = retval;
22313       if (retval == 0)
22314         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22315       vam->result_ready = 1;
22316     }
22317 }
22318
22319 static void vl_api_app_namespace_add_del_reply_t_handler_json
22320   (vl_api_app_namespace_add_del_reply_t * mp)
22321 {
22322   vat_main_t *vam = &vat_main;
22323   vat_json_node_t node;
22324
22325   vat_json_init_object (&node);
22326   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22327   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22328
22329   vat_json_print (vam->ofp, &node);
22330   vat_json_free (&node);
22331
22332   vam->retval = ntohl (mp->retval);
22333   vam->result_ready = 1;
22334 }
22335
22336 static int
22337 api_app_namespace_add_del (vat_main_t * vam)
22338 {
22339   vl_api_app_namespace_add_del_t *mp;
22340   unformat_input_t *i = vam->input;
22341   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22342   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22343   u64 secret;
22344   int ret;
22345
22346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22347     {
22348       if (unformat (i, "id %_%v%_", &ns_id))
22349         ;
22350       else if (unformat (i, "secret %lu", &secret))
22351         secret_set = 1;
22352       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22353         sw_if_index_set = 1;
22354       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22355         ;
22356       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22357         ;
22358       else
22359         break;
22360     }
22361   if (!ns_id || !secret_set || !sw_if_index_set)
22362     {
22363       errmsg ("namespace id, secret and sw_if_index must be set");
22364       return -99;
22365     }
22366   if (vec_len (ns_id) > 64)
22367     {
22368       errmsg ("namespace id too long");
22369       return -99;
22370     }
22371   M (APP_NAMESPACE_ADD_DEL, mp);
22372
22373   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22374   mp->namespace_id_len = vec_len (ns_id);
22375   mp->secret = clib_host_to_net_u64 (secret);
22376   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22377   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22378   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22379   vec_free (ns_id);
22380   S (mp);
22381   W (ret);
22382   return ret;
22383 }
22384
22385 static int
22386 api_sock_init_shm (vat_main_t * vam)
22387 {
22388 #if VPP_API_TEST_BUILTIN == 0
22389   unformat_input_t *i = vam->input;
22390   vl_api_shm_elem_config_t *config = 0;
22391   u64 size = 64 << 20;
22392   int rv;
22393
22394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22395     {
22396       if (unformat (i, "size %U", unformat_memory_size, &size))
22397         ;
22398       else
22399         break;
22400     }
22401
22402   /*
22403    * Canned custom ring allocator config.
22404    * Should probably parse all of this
22405    */
22406   vec_validate (config, 6);
22407   config[0].type = VL_API_VLIB_RING;
22408   config[0].size = 256;
22409   config[0].count = 32;
22410
22411   config[1].type = VL_API_VLIB_RING;
22412   config[1].size = 1024;
22413   config[1].count = 16;
22414
22415   config[2].type = VL_API_VLIB_RING;
22416   config[2].size = 4096;
22417   config[2].count = 2;
22418
22419   config[3].type = VL_API_CLIENT_RING;
22420   config[3].size = 256;
22421   config[3].count = 32;
22422
22423   config[4].type = VL_API_CLIENT_RING;
22424   config[4].size = 1024;
22425   config[4].count = 16;
22426
22427   config[5].type = VL_API_CLIENT_RING;
22428   config[5].size = 4096;
22429   config[5].count = 2;
22430
22431   config[6].type = VL_API_QUEUE;
22432   config[6].count = 128;
22433   config[6].size = sizeof (uword);
22434
22435   rv = vl_socket_client_init_shm (config);
22436   if (!rv)
22437     vam->client_index_invalid = 1;
22438   return rv;
22439 #else
22440   return -99;
22441 #endif
22442 }
22443
22444 static int
22445 api_dns_enable_disable (vat_main_t * vam)
22446 {
22447   unformat_input_t *line_input = vam->input;
22448   vl_api_dns_enable_disable_t *mp;
22449   u8 enable_disable = 1;
22450   int ret;
22451
22452   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22453     {
22454       if (unformat (line_input, "disable"))
22455         enable_disable = 0;
22456       if (unformat (line_input, "enable"))
22457         enable_disable = 1;
22458       else
22459         break;
22460     }
22461
22462   /* Construct the API message */
22463   M (DNS_ENABLE_DISABLE, mp);
22464   mp->enable = enable_disable;
22465
22466   /* send it... */
22467   S (mp);
22468   /* Wait for the reply */
22469   W (ret);
22470   return ret;
22471 }
22472
22473 static int
22474 api_dns_resolve_name (vat_main_t * vam)
22475 {
22476   unformat_input_t *line_input = vam->input;
22477   vl_api_dns_resolve_name_t *mp;
22478   u8 *name = 0;
22479   int ret;
22480
22481   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22482     {
22483       if (unformat (line_input, "%s", &name))
22484         ;
22485       else
22486         break;
22487     }
22488
22489   if (vec_len (name) > 127)
22490     {
22491       errmsg ("name too long");
22492       return -99;
22493     }
22494
22495   /* Construct the API message */
22496   M (DNS_RESOLVE_NAME, mp);
22497   memcpy (mp->name, name, vec_len (name));
22498   vec_free (name);
22499
22500   /* send it... */
22501   S (mp);
22502   /* Wait for the reply */
22503   W (ret);
22504   return ret;
22505 }
22506
22507 static int
22508 api_dns_resolve_ip (vat_main_t * vam)
22509 {
22510   unformat_input_t *line_input = vam->input;
22511   vl_api_dns_resolve_ip_t *mp;
22512   int is_ip6 = -1;
22513   ip4_address_t addr4;
22514   ip6_address_t addr6;
22515   int ret;
22516
22517   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22518     {
22519       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22520         is_ip6 = 1;
22521       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22522         is_ip6 = 0;
22523       else
22524         break;
22525     }
22526
22527   if (is_ip6 == -1)
22528     {
22529       errmsg ("missing address");
22530       return -99;
22531     }
22532
22533   /* Construct the API message */
22534   M (DNS_RESOLVE_IP, mp);
22535   mp->is_ip6 = is_ip6;
22536   if (is_ip6)
22537     memcpy (mp->address, &addr6, sizeof (addr6));
22538   else
22539     memcpy (mp->address, &addr4, sizeof (addr4));
22540
22541   /* send it... */
22542   S (mp);
22543   /* Wait for the reply */
22544   W (ret);
22545   return ret;
22546 }
22547
22548 static int
22549 api_dns_name_server_add_del (vat_main_t * vam)
22550 {
22551   unformat_input_t *i = vam->input;
22552   vl_api_dns_name_server_add_del_t *mp;
22553   u8 is_add = 1;
22554   ip6_address_t ip6_server;
22555   ip4_address_t ip4_server;
22556   int ip6_set = 0;
22557   int ip4_set = 0;
22558   int ret = 0;
22559
22560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22561     {
22562       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22563         ip6_set = 1;
22564       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22565         ip4_set = 1;
22566       else if (unformat (i, "del"))
22567         is_add = 0;
22568       else
22569         {
22570           clib_warning ("parse error '%U'", format_unformat_error, i);
22571           return -99;
22572         }
22573     }
22574
22575   if (ip4_set && ip6_set)
22576     {
22577       errmsg ("Only one server address allowed per message");
22578       return -99;
22579     }
22580   if ((ip4_set + ip6_set) == 0)
22581     {
22582       errmsg ("Server address required");
22583       return -99;
22584     }
22585
22586   /* Construct the API message */
22587   M (DNS_NAME_SERVER_ADD_DEL, mp);
22588
22589   if (ip6_set)
22590     {
22591       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22592       mp->is_ip6 = 1;
22593     }
22594   else
22595     {
22596       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22597       mp->is_ip6 = 0;
22598     }
22599
22600   mp->is_add = is_add;
22601
22602   /* send it... */
22603   S (mp);
22604
22605   /* Wait for a reply, return good/bad news  */
22606   W (ret);
22607   return ret;
22608 }
22609
22610 static void
22611 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22612 {
22613   vat_main_t *vam = &vat_main;
22614
22615   if (mp->is_ip4)
22616     {
22617       print (vam->ofp,
22618              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22619              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22620              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22621              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22622              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22623              clib_net_to_host_u32 (mp->action_index), mp->tag);
22624     }
22625   else
22626     {
22627       print (vam->ofp,
22628              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22629              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22630              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22631              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22632              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22633              clib_net_to_host_u32 (mp->action_index), mp->tag);
22634     }
22635 }
22636
22637 static void
22638 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22639                                              mp)
22640 {
22641   vat_main_t *vam = &vat_main;
22642   vat_json_node_t *node = NULL;
22643   struct in6_addr ip6;
22644   struct in_addr ip4;
22645
22646   if (VAT_JSON_ARRAY != vam->json_tree.type)
22647     {
22648       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22649       vat_json_init_array (&vam->json_tree);
22650     }
22651   node = vat_json_array_add (&vam->json_tree);
22652   vat_json_init_object (node);
22653
22654   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22655   vat_json_object_add_uint (node, "appns_index",
22656                             clib_net_to_host_u32 (mp->appns_index));
22657   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22658   vat_json_object_add_uint (node, "scope", mp->scope);
22659   vat_json_object_add_uint (node, "action_index",
22660                             clib_net_to_host_u32 (mp->action_index));
22661   vat_json_object_add_uint (node, "lcl_port",
22662                             clib_net_to_host_u16 (mp->lcl_port));
22663   vat_json_object_add_uint (node, "rmt_port",
22664                             clib_net_to_host_u16 (mp->rmt_port));
22665   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22666   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22667   vat_json_object_add_string_copy (node, "tag", mp->tag);
22668   if (mp->is_ip4)
22669     {
22670       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22671       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22672       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22673       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22674     }
22675   else
22676     {
22677       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22678       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22679       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22680       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22681     }
22682 }
22683
22684 static int
22685 api_session_rule_add_del (vat_main_t * vam)
22686 {
22687   vl_api_session_rule_add_del_t *mp;
22688   unformat_input_t *i = vam->input;
22689   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22690   u32 appns_index = 0, scope = 0;
22691   ip4_address_t lcl_ip4, rmt_ip4;
22692   ip6_address_t lcl_ip6, rmt_ip6;
22693   u8 is_ip4 = 1, conn_set = 0;
22694   u8 is_add = 1, *tag = 0;
22695   int ret;
22696
22697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22698     {
22699       if (unformat (i, "del"))
22700         is_add = 0;
22701       else if (unformat (i, "add"))
22702         ;
22703       else if (unformat (i, "proto tcp"))
22704         proto = 0;
22705       else if (unformat (i, "proto udp"))
22706         proto = 1;
22707       else if (unformat (i, "appns %d", &appns_index))
22708         ;
22709       else if (unformat (i, "scope %d", &scope))
22710         ;
22711       else if (unformat (i, "tag %_%v%_", &tag))
22712         ;
22713       else
22714         if (unformat
22715             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22716              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22717              &rmt_port))
22718         {
22719           is_ip4 = 1;
22720           conn_set = 1;
22721         }
22722       else
22723         if (unformat
22724             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22725              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22726              &rmt_port))
22727         {
22728           is_ip4 = 0;
22729           conn_set = 1;
22730         }
22731       else if (unformat (i, "action %d", &action))
22732         ;
22733       else
22734         break;
22735     }
22736   if (proto == ~0 || !conn_set || action == ~0)
22737     {
22738       errmsg ("transport proto, connection and action must be set");
22739       return -99;
22740     }
22741
22742   if (scope > 3)
22743     {
22744       errmsg ("scope should be 0-3");
22745       return -99;
22746     }
22747
22748   M (SESSION_RULE_ADD_DEL, mp);
22749
22750   mp->is_ip4 = is_ip4;
22751   mp->transport_proto = proto;
22752   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22753   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22754   mp->lcl_plen = lcl_plen;
22755   mp->rmt_plen = rmt_plen;
22756   mp->action_index = clib_host_to_net_u32 (action);
22757   mp->appns_index = clib_host_to_net_u32 (appns_index);
22758   mp->scope = scope;
22759   mp->is_add = is_add;
22760   if (is_ip4)
22761     {
22762       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22763       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22764     }
22765   else
22766     {
22767       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22768       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22769     }
22770   if (tag)
22771     {
22772       clib_memcpy (mp->tag, tag, vec_len (tag));
22773       vec_free (tag);
22774     }
22775
22776   S (mp);
22777   W (ret);
22778   return ret;
22779 }
22780
22781 static int
22782 api_session_rules_dump (vat_main_t * vam)
22783 {
22784   vl_api_session_rules_dump_t *mp;
22785   vl_api_control_ping_t *mp_ping;
22786   int ret;
22787
22788   if (!vam->json_output)
22789     {
22790       print (vam->ofp, "%=20s", "Session Rules");
22791     }
22792
22793   M (SESSION_RULES_DUMP, mp);
22794   /* send it... */
22795   S (mp);
22796
22797   /* Use a control ping for synchronization */
22798   MPING (CONTROL_PING, mp_ping);
22799   S (mp_ping);
22800
22801   /* Wait for a reply... */
22802   W (ret);
22803   return ret;
22804 }
22805
22806 static int
22807 api_ip_container_proxy_add_del (vat_main_t * vam)
22808 {
22809   vl_api_ip_container_proxy_add_del_t *mp;
22810   unformat_input_t *i = vam->input;
22811   u32 plen = ~0, sw_if_index = ~0;
22812   ip4_address_t ip4;
22813   ip6_address_t ip6;
22814   u8 is_ip4 = 1;
22815   u8 is_add = 1;
22816   int ret;
22817
22818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22819     {
22820       if (unformat (i, "del"))
22821         is_add = 0;
22822       else if (unformat (i, "add"))
22823         ;
22824       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22825         {
22826           is_ip4 = 1;
22827           plen = 32;
22828         }
22829       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22830         {
22831           is_ip4 = 0;
22832           plen = 128;
22833         }
22834       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22835         ;
22836       else
22837         break;
22838     }
22839   if (sw_if_index == ~0 || plen == ~0)
22840     {
22841       errmsg ("address and sw_if_index must be set");
22842       return -99;
22843     }
22844
22845   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22846
22847   mp->is_ip4 = is_ip4;
22848   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22849   mp->plen = plen;
22850   mp->is_add = is_add;
22851   if (is_ip4)
22852     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22853   else
22854     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22855
22856   S (mp);
22857   W (ret);
22858   return ret;
22859 }
22860
22861 static int
22862 api_qos_record_enable_disable (vat_main_t * vam)
22863 {
22864   unformat_input_t *i = vam->input;
22865   vl_api_qos_record_enable_disable_t *mp;
22866   u32 sw_if_index, qs = 0xff;
22867   u8 sw_if_index_set = 0;
22868   u8 enable = 1;
22869   int ret;
22870
22871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22872     {
22873       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22874         sw_if_index_set = 1;
22875       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22876         sw_if_index_set = 1;
22877       else if (unformat (i, "%U", unformat_qos_source, &qs))
22878         ;
22879       else if (unformat (i, "disable"))
22880         enable = 0;
22881       else
22882         {
22883           clib_warning ("parse error '%U'", format_unformat_error, i);
22884           return -99;
22885         }
22886     }
22887
22888   if (sw_if_index_set == 0)
22889     {
22890       errmsg ("missing interface name or sw_if_index");
22891       return -99;
22892     }
22893   if (qs == 0xff)
22894     {
22895       errmsg ("input location must be specified");
22896       return -99;
22897     }
22898
22899   M (QOS_RECORD_ENABLE_DISABLE, mp);
22900
22901   mp->sw_if_index = ntohl (sw_if_index);
22902   mp->input_source = qs;
22903   mp->enable = enable;
22904
22905   S (mp);
22906   W (ret);
22907   return ret;
22908 }
22909
22910 static int
22911 q_or_quit (vat_main_t * vam)
22912 {
22913 #if VPP_API_TEST_BUILTIN == 0
22914   longjmp (vam->jump_buf, 1);
22915 #endif
22916   return 0;                     /* not so much */
22917 }
22918
22919 static int
22920 q (vat_main_t * vam)
22921 {
22922   return q_or_quit (vam);
22923 }
22924
22925 static int
22926 quit (vat_main_t * vam)
22927 {
22928   return q_or_quit (vam);
22929 }
22930
22931 static int
22932 comment (vat_main_t * vam)
22933 {
22934   return 0;
22935 }
22936
22937 static int
22938 cmd_cmp (void *a1, void *a2)
22939 {
22940   u8 **c1 = a1;
22941   u8 **c2 = a2;
22942
22943   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22944 }
22945
22946 static int
22947 help (vat_main_t * vam)
22948 {
22949   u8 **cmds = 0;
22950   u8 *name = 0;
22951   hash_pair_t *p;
22952   unformat_input_t *i = vam->input;
22953   int j;
22954
22955   if (unformat (i, "%s", &name))
22956     {
22957       uword *hs;
22958
22959       vec_add1 (name, 0);
22960
22961       hs = hash_get_mem (vam->help_by_name, name);
22962       if (hs)
22963         print (vam->ofp, "usage: %s %s", name, hs[0]);
22964       else
22965         print (vam->ofp, "No such msg / command '%s'", name);
22966       vec_free (name);
22967       return 0;
22968     }
22969
22970   print (vam->ofp, "Help is available for the following:");
22971
22972     /* *INDENT-OFF* */
22973     hash_foreach_pair (p, vam->function_by_name,
22974     ({
22975       vec_add1 (cmds, (u8 *)(p->key));
22976     }));
22977     /* *INDENT-ON* */
22978
22979   vec_sort_with_function (cmds, cmd_cmp);
22980
22981   for (j = 0; j < vec_len (cmds); j++)
22982     print (vam->ofp, "%s", cmds[j]);
22983
22984   vec_free (cmds);
22985   return 0;
22986 }
22987
22988 static int
22989 set (vat_main_t * vam)
22990 {
22991   u8 *name = 0, *value = 0;
22992   unformat_input_t *i = vam->input;
22993
22994   if (unformat (i, "%s", &name))
22995     {
22996       /* The input buffer is a vector, not a string. */
22997       value = vec_dup (i->buffer);
22998       vec_delete (value, i->index, 0);
22999       /* Almost certainly has a trailing newline */
23000       if (value[vec_len (value) - 1] == '\n')
23001         value[vec_len (value) - 1] = 0;
23002       /* Make sure it's a proper string, one way or the other */
23003       vec_add1 (value, 0);
23004       (void) clib_macro_set_value (&vam->macro_main,
23005                                    (char *) name, (char *) value);
23006     }
23007   else
23008     errmsg ("usage: set <name> <value>");
23009
23010   vec_free (name);
23011   vec_free (value);
23012   return 0;
23013 }
23014
23015 static int
23016 unset (vat_main_t * vam)
23017 {
23018   u8 *name = 0;
23019
23020   if (unformat (vam->input, "%s", &name))
23021     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23022       errmsg ("unset: %s wasn't set", name);
23023   vec_free (name);
23024   return 0;
23025 }
23026
23027 typedef struct
23028 {
23029   u8 *name;
23030   u8 *value;
23031 } macro_sort_t;
23032
23033
23034 static int
23035 macro_sort_cmp (void *a1, void *a2)
23036 {
23037   macro_sort_t *s1 = a1;
23038   macro_sort_t *s2 = a2;
23039
23040   return strcmp ((char *) (s1->name), (char *) (s2->name));
23041 }
23042
23043 static int
23044 dump_macro_table (vat_main_t * vam)
23045 {
23046   macro_sort_t *sort_me = 0, *sm;
23047   int i;
23048   hash_pair_t *p;
23049
23050     /* *INDENT-OFF* */
23051     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23052     ({
23053       vec_add2 (sort_me, sm, 1);
23054       sm->name = (u8 *)(p->key);
23055       sm->value = (u8 *) (p->value[0]);
23056     }));
23057     /* *INDENT-ON* */
23058
23059   vec_sort_with_function (sort_me, macro_sort_cmp);
23060
23061   if (vec_len (sort_me))
23062     print (vam->ofp, "%-15s%s", "Name", "Value");
23063   else
23064     print (vam->ofp, "The macro table is empty...");
23065
23066   for (i = 0; i < vec_len (sort_me); i++)
23067     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23068   return 0;
23069 }
23070
23071 static int
23072 dump_node_table (vat_main_t * vam)
23073 {
23074   int i, j;
23075   vlib_node_t *node, *next_node;
23076
23077   if (vec_len (vam->graph_nodes) == 0)
23078     {
23079       print (vam->ofp, "Node table empty, issue get_node_graph...");
23080       return 0;
23081     }
23082
23083   for (i = 0; i < vec_len (vam->graph_nodes); i++)
23084     {
23085       node = vam->graph_nodes[i];
23086       print (vam->ofp, "[%d] %s", i, node->name);
23087       for (j = 0; j < vec_len (node->next_nodes); j++)
23088         {
23089           if (node->next_nodes[j] != ~0)
23090             {
23091               next_node = vam->graph_nodes[node->next_nodes[j]];
23092               print (vam->ofp, "  [%d] %s", j, next_node->name);
23093             }
23094         }
23095     }
23096   return 0;
23097 }
23098
23099 static int
23100 value_sort_cmp (void *a1, void *a2)
23101 {
23102   name_sort_t *n1 = a1;
23103   name_sort_t *n2 = a2;
23104
23105   if (n1->value < n2->value)
23106     return -1;
23107   if (n1->value > n2->value)
23108     return 1;
23109   return 0;
23110 }
23111
23112
23113 static int
23114 dump_msg_api_table (vat_main_t * vam)
23115 {
23116   api_main_t *am = &api_main;
23117   name_sort_t *nses = 0, *ns;
23118   hash_pair_t *hp;
23119   int i;
23120
23121   /* *INDENT-OFF* */
23122   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23123   ({
23124     vec_add2 (nses, ns, 1);
23125     ns->name = (u8 *)(hp->key);
23126     ns->value = (u32) hp->value[0];
23127   }));
23128   /* *INDENT-ON* */
23129
23130   vec_sort_with_function (nses, value_sort_cmp);
23131
23132   for (i = 0; i < vec_len (nses); i++)
23133     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23134   vec_free (nses);
23135   return 0;
23136 }
23137
23138 static int
23139 get_msg_id (vat_main_t * vam)
23140 {
23141   u8 *name_and_crc;
23142   u32 message_index;
23143
23144   if (unformat (vam->input, "%s", &name_and_crc))
23145     {
23146       message_index = vl_msg_api_get_msg_index (name_and_crc);
23147       if (message_index == ~0)
23148         {
23149           print (vam->ofp, " '%s' not found", name_and_crc);
23150           return 0;
23151         }
23152       print (vam->ofp, " '%s' has message index %d",
23153              name_and_crc, message_index);
23154       return 0;
23155     }
23156   errmsg ("name_and_crc required...");
23157   return 0;
23158 }
23159
23160 static int
23161 search_node_table (vat_main_t * vam)
23162 {
23163   unformat_input_t *line_input = vam->input;
23164   u8 *node_to_find;
23165   int j;
23166   vlib_node_t *node, *next_node;
23167   uword *p;
23168
23169   if (vam->graph_node_index_by_name == 0)
23170     {
23171       print (vam->ofp, "Node table empty, issue get_node_graph...");
23172       return 0;
23173     }
23174
23175   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23176     {
23177       if (unformat (line_input, "%s", &node_to_find))
23178         {
23179           vec_add1 (node_to_find, 0);
23180           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23181           if (p == 0)
23182             {
23183               print (vam->ofp, "%s not found...", node_to_find);
23184               goto out;
23185             }
23186           node = vam->graph_nodes[p[0]];
23187           print (vam->ofp, "[%d] %s", p[0], node->name);
23188           for (j = 0; j < vec_len (node->next_nodes); j++)
23189             {
23190               if (node->next_nodes[j] != ~0)
23191                 {
23192                   next_node = vam->graph_nodes[node->next_nodes[j]];
23193                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23194                 }
23195             }
23196         }
23197
23198       else
23199         {
23200           clib_warning ("parse error '%U'", format_unformat_error,
23201                         line_input);
23202           return -99;
23203         }
23204
23205     out:
23206       vec_free (node_to_find);
23207
23208     }
23209
23210   return 0;
23211 }
23212
23213
23214 static int
23215 script (vat_main_t * vam)
23216 {
23217 #if (VPP_API_TEST_BUILTIN==0)
23218   u8 *s = 0;
23219   char *save_current_file;
23220   unformat_input_t save_input;
23221   jmp_buf save_jump_buf;
23222   u32 save_line_number;
23223
23224   FILE *new_fp, *save_ifp;
23225
23226   if (unformat (vam->input, "%s", &s))
23227     {
23228       new_fp = fopen ((char *) s, "r");
23229       if (new_fp == 0)
23230         {
23231           errmsg ("Couldn't open script file %s", s);
23232           vec_free (s);
23233           return -99;
23234         }
23235     }
23236   else
23237     {
23238       errmsg ("Missing script name");
23239       return -99;
23240     }
23241
23242   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23243   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23244   save_ifp = vam->ifp;
23245   save_line_number = vam->input_line_number;
23246   save_current_file = (char *) vam->current_file;
23247
23248   vam->input_line_number = 0;
23249   vam->ifp = new_fp;
23250   vam->current_file = s;
23251   do_one_file (vam);
23252
23253   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
23254   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23255   vam->ifp = save_ifp;
23256   vam->input_line_number = save_line_number;
23257   vam->current_file = (u8 *) save_current_file;
23258   vec_free (s);
23259
23260   return 0;
23261 #else
23262   clib_warning ("use the exec command...");
23263   return -99;
23264 #endif
23265 }
23266
23267 static int
23268 echo (vat_main_t * vam)
23269 {
23270   print (vam->ofp, "%v", vam->input->buffer);
23271   return 0;
23272 }
23273
23274 /* List of API message constructors, CLI names map to api_xxx */
23275 #define foreach_vpe_api_msg                                             \
23276 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23277 _(sw_interface_dump,"")                                                 \
23278 _(sw_interface_set_flags,                                               \
23279   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23280 _(sw_interface_add_del_address,                                         \
23281   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23282 _(sw_interface_set_rx_mode,                                             \
23283   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23284 _(sw_interface_set_table,                                               \
23285   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23286 _(sw_interface_set_mpls_enable,                                         \
23287   "<intfc> | sw_if_index [disable | dis]")                              \
23288 _(sw_interface_set_vpath,                                               \
23289   "<intfc> | sw_if_index <id> enable | disable")                        \
23290 _(sw_interface_set_vxlan_bypass,                                        \
23291   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23292 _(sw_interface_set_geneve_bypass,                                       \
23293   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23294 _(sw_interface_set_l2_xconnect,                                         \
23295   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23296   "enable | disable")                                                   \
23297 _(sw_interface_set_l2_bridge,                                           \
23298   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23299   "[shg <split-horizon-group>] [bvi]\n"                                 \
23300   "enable | disable")                                                   \
23301 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23302 _(bridge_domain_add_del,                                                \
23303   "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") \
23304 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23305 _(l2fib_add_del,                                                        \
23306   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23307 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23308 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23309 _(l2_flags,                                                             \
23310   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23311 _(bridge_flags,                                                         \
23312   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23313 _(tap_connect,                                                          \
23314   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23315 _(tap_modify,                                                           \
23316   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23317 _(tap_delete,                                                           \
23318   "<vpp-if-name> | sw_if_index <id>")                                   \
23319 _(sw_interface_tap_dump, "")                                            \
23320 _(tap_create_v2,                                                        \
23321   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23322 _(tap_delete_v2,                                                        \
23323   "<vpp-if-name> | sw_if_index <id>")                                   \
23324 _(sw_interface_tap_v2_dump, "")                                         \
23325 _(bond_create,                                                          \
23326   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23327   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23328 _(bond_delete,                                                          \
23329   "<vpp-if-name> | sw_if_index <id>")                                   \
23330 _(bond_enslave,                                                         \
23331   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23332 _(bond_detach_slave,                                                    \
23333   "sw_if_index <n>")                                                    \
23334 _(sw_interface_bond_dump, "")                                           \
23335 _(sw_interface_slave_dump,                                              \
23336   "<vpp-if-name> | sw_if_index <id>")                                   \
23337 _(ip_table_add_del,                                                     \
23338   "table-id <n> [ipv6]\n")                                              \
23339 _(ip_add_del_route,                                                     \
23340   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23341   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23342   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23343   "[multipath] [count <n>]")                                            \
23344 _(ip_mroute_add_del,                                                    \
23345   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23346   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23347 _(mpls_table_add_del,                                                   \
23348   "table-id <n>\n")                                                     \
23349 _(mpls_route_add_del,                                                   \
23350   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23351   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23352   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23353   "[multipath] [count <n>]")                                            \
23354 _(mpls_ip_bind_unbind,                                                  \
23355   "<label> <addr/len>")                                                 \
23356 _(mpls_tunnel_add_del,                                                  \
23357   " via <addr> [table-id <n>]\n"                                        \
23358   "sw_if_index <id>] [l2]  [del]")                                      \
23359 _(bier_table_add_del,                                                   \
23360   "<label> <sub-domain> <set> <bsl> [del]")                             \
23361 _(bier_route_add_del,                                                   \
23362   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23363   "[<intfc> | sw_if_index <id>]"                                        \
23364   "[weight <n>] [del] [multipath]")                                     \
23365 _(proxy_arp_add_del,                                                    \
23366   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23367 _(proxy_arp_intfc_enable_disable,                                       \
23368   "<intfc> | sw_if_index <id> enable | disable")                        \
23369 _(sw_interface_set_unnumbered,                                          \
23370   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23371 _(ip_neighbor_add_del,                                                  \
23372   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23373   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23374 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23375 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23376   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23377   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23378   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23379 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23380 _(reset_fib, "vrf <n> [ipv6]")                                          \
23381 _(dhcp_proxy_config,                                                    \
23382   "svr <v46-address> src <v46-address>\n"                               \
23383    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23384 _(dhcp_proxy_set_vss,                                                   \
23385   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23386 _(dhcp_proxy_dump, "ip6")                                               \
23387 _(dhcp_client_config,                                                   \
23388   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23389 _(set_ip_flow_hash,                                                     \
23390   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23391 _(sw_interface_ip6_enable_disable,                                      \
23392   "<intfc> | sw_if_index <id> enable | disable")                        \
23393 _(sw_interface_ip6_set_link_local_address,                              \
23394   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23395 _(ip6nd_proxy_add_del,                                                  \
23396   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23397 _(ip6nd_proxy_dump, "")                                                 \
23398 _(sw_interface_ip6nd_ra_prefix,                                         \
23399   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23400   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23401   "[nolink] [isno]")                                                    \
23402 _(sw_interface_ip6nd_ra_config,                                         \
23403   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23404   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23405   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23406 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23407 _(l2_patch_add_del,                                                     \
23408   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23409   "enable | disable")                                                   \
23410 _(sr_localsid_add_del,                                                  \
23411   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23412   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23413 _(classify_add_del_table,                                               \
23414   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23415   " [del] [del-chain] mask <mask-value>\n"                              \
23416   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23417   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23418 _(classify_add_del_session,                                             \
23419   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23420   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23421   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23422   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23423 _(classify_set_interface_ip_table,                                      \
23424   "<intfc> | sw_if_index <nn> table <nn>")                              \
23425 _(classify_set_interface_l2_tables,                                     \
23426   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23427   "  [other-table <nn>]")                                               \
23428 _(get_node_index, "node <node-name")                                    \
23429 _(add_node_next, "node <node-name> next <next-node-name>")              \
23430 _(l2tpv3_create_tunnel,                                                 \
23431   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23432   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23433   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23434 _(l2tpv3_set_tunnel_cookies,                                            \
23435   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23436   "[new_remote_cookie <nn>]\n")                                         \
23437 _(l2tpv3_interface_enable_disable,                                      \
23438   "<intfc> | sw_if_index <nn> enable | disable")                        \
23439 _(l2tpv3_set_lookup_key,                                                \
23440   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23441 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23442 _(vxlan_add_del_tunnel,                                                 \
23443   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23444   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23445   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23446 _(geneve_add_del_tunnel,                                                \
23447   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23448   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23449   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23450 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23451 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23452 _(gre_add_del_tunnel,                                                   \
23453   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23454   "[teb | erspan <session-id>] [del]")                                  \
23455 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23456 _(l2_fib_clear_table, "")                                               \
23457 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23458 _(l2_interface_vlan_tag_rewrite,                                        \
23459   "<intfc> | sw_if_index <nn> \n"                                       \
23460   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23461   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23462 _(create_vhost_user_if,                                                 \
23463         "socket <filename> [server] [renumber <dev_instance>] "         \
23464         "[mac <mac_address>]")                                          \
23465 _(modify_vhost_user_if,                                                 \
23466         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23467         "[server] [renumber <dev_instance>]")                           \
23468 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23469 _(sw_interface_vhost_user_dump, "")                                     \
23470 _(show_version, "")                                                     \
23471 _(vxlan_gpe_add_del_tunnel,                                             \
23472   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23473   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23474   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23475   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23476 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23477 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23478 _(interface_name_renumber,                                              \
23479   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23480 _(input_acl_set_interface,                                              \
23481   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23482   "  [l2-table <nn>] [del]")                                            \
23483 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23484 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23485   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23486 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23487 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23488 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23489 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23490 _(ip_dump, "ipv4 | ipv6")                                               \
23491 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23492 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23493   "  spid_id <n> ")                                                     \
23494 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23495   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23496   "  integ_alg <alg> integ_key <hex>")                                  \
23497 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23498   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23499   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23500   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23501 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23502 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23503   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23504   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23505   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23506   "  [instance <n>]")     \
23507 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23508 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23509   "  <alg> <hex>\n")                                                    \
23510 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23511 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23512 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23513   "(auth_data 0x<data> | auth_data <data>)")                            \
23514 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23515   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23516 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23517   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23518   "(local|remote)")                                                     \
23519 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23520 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23521 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23522 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23523 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23524 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23525 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23526 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23527 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23528 _(delete_loopback,"sw_if_index <nn>")                                   \
23529 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23530 _(map_add_domain,                                                       \
23531   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23532   "ip6-src <ip6addr> "                                                  \
23533   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23534 _(map_del_domain, "index <n>")                                          \
23535 _(map_add_del_rule,                                                     \
23536   "index <n> psid <n> dst <ip6addr> [del]")                             \
23537 _(map_domain_dump, "")                                                  \
23538 _(map_rule_dump, "index <map-domain>")                                  \
23539 _(want_interface_events,  "enable|disable")                             \
23540 _(want_stats,"enable|disable")                                          \
23541 _(get_first_msg_id, "client <name>")                                    \
23542 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23543 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23544   "fib-id <nn> [ip4][ip6][default]")                                    \
23545 _(get_node_graph, " ")                                                  \
23546 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23547 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23548 _(ioam_disable, "")                                                     \
23549 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23550                             " sw_if_index <sw_if_index> p <priority> "  \
23551                             "w <weight>] [del]")                        \
23552 _(one_add_del_locator, "locator-set <locator_name> "                    \
23553                         "iface <intf> | sw_if_index <sw_if_index> "     \
23554                         "p <priority> w <weight> [del]")                \
23555 _(one_add_del_local_eid,"vni <vni> eid "                                \
23556                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23557                          "locator-set <locator_name> [del]"             \
23558                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23559 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23560 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23561 _(one_enable_disable, "enable|disable")                                 \
23562 _(one_map_register_enable_disable, "enable|disable")                    \
23563 _(one_map_register_fallback_threshold, "<value>")                       \
23564 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23565 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23566                                "[seid <seid>] "                         \
23567                                "rloc <locator> p <prio> "               \
23568                                "w <weight> [rloc <loc> ... ] "          \
23569                                "action <action> [del-all]")             \
23570 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23571                           "<local-eid>")                                \
23572 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23573 _(one_use_petr, "ip-address> | disable")                                \
23574 _(one_map_request_mode, "src-dst|dst-only")                             \
23575 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23576 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23577 _(one_locator_set_dump, "[local | remote]")                             \
23578 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23579 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23580                        "[local] | [remote]")                            \
23581 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23582 _(one_ndp_bd_get, "")                                                   \
23583 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23584 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23585 _(one_l2_arp_bd_get, "")                                                \
23586 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23587 _(one_stats_enable_disable, "enable|disalbe")                           \
23588 _(show_one_stats_enable_disable, "")                                    \
23589 _(one_eid_table_vni_dump, "")                                           \
23590 _(one_eid_table_map_dump, "l2|l3")                                      \
23591 _(one_map_resolver_dump, "")                                            \
23592 _(one_map_server_dump, "")                                              \
23593 _(one_adjacencies_get, "vni <vni>")                                     \
23594 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23595 _(show_one_rloc_probe_state, "")                                        \
23596 _(show_one_map_register_state, "")                                      \
23597 _(show_one_status, "")                                                  \
23598 _(one_stats_dump, "")                                                   \
23599 _(one_stats_flush, "")                                                  \
23600 _(one_get_map_request_itr_rlocs, "")                                    \
23601 _(one_map_register_set_ttl, "<ttl>")                                    \
23602 _(one_set_transport_protocol, "udp|api")                                \
23603 _(one_get_transport_protocol, "")                                       \
23604 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23605 _(one_show_xtr_mode, "")                                                \
23606 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23607 _(one_show_pitr_mode, "")                                               \
23608 _(one_enable_disable_petr_mode, "enable|disable")                       \
23609 _(one_show_petr_mode, "")                                               \
23610 _(show_one_nsh_mapping, "")                                             \
23611 _(show_one_pitr, "")                                                    \
23612 _(show_one_use_petr, "")                                                \
23613 _(show_one_map_request_mode, "")                                        \
23614 _(show_one_map_register_ttl, "")                                        \
23615 _(show_one_map_register_fallback_threshold, "")                         \
23616 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23617                             " sw_if_index <sw_if_index> p <priority> "  \
23618                             "w <weight>] [del]")                        \
23619 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23620                         "iface <intf> | sw_if_index <sw_if_index> "     \
23621                         "p <priority> w <weight> [del]")                \
23622 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23623                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23624                          "locator-set <locator_name> [del]"             \
23625                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23626 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23627 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23628 _(lisp_enable_disable, "enable|disable")                                \
23629 _(lisp_map_register_enable_disable, "enable|disable")                   \
23630 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23631 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23632                                "[seid <seid>] "                         \
23633                                "rloc <locator> p <prio> "               \
23634                                "w <weight> [rloc <loc> ... ] "          \
23635                                "action <action> [del-all]")             \
23636 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23637                           "<local-eid>")                                \
23638 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23639 _(lisp_use_petr, "<ip-address> | disable")                              \
23640 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23641 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23642 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23643 _(lisp_locator_set_dump, "[local | remote]")                            \
23644 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23645 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23646                        "[local] | [remote]")                            \
23647 _(lisp_eid_table_vni_dump, "")                                          \
23648 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23649 _(lisp_map_resolver_dump, "")                                           \
23650 _(lisp_map_server_dump, "")                                             \
23651 _(lisp_adjacencies_get, "vni <vni>")                                    \
23652 _(gpe_fwd_entry_vnis_get, "")                                           \
23653 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23654 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23655                                 "[table <table-id>]")                   \
23656 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23657 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23658 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23659 _(gpe_get_encap_mode, "")                                               \
23660 _(lisp_gpe_add_del_iface, "up|down")                                    \
23661 _(lisp_gpe_enable_disable, "enable|disable")                            \
23662 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23663   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23664 _(show_lisp_rloc_probe_state, "")                                       \
23665 _(show_lisp_map_register_state, "")                                     \
23666 _(show_lisp_status, "")                                                 \
23667 _(lisp_get_map_request_itr_rlocs, "")                                   \
23668 _(show_lisp_pitr, "")                                                   \
23669 _(show_lisp_use_petr, "")                                               \
23670 _(show_lisp_map_request_mode, "")                                       \
23671 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23672 _(af_packet_delete, "name <host interface name>")                       \
23673 _(policer_add_del, "name <policer name> <params> [del]")                \
23674 _(policer_dump, "[name <policer name>]")                                \
23675 _(policer_classify_set_interface,                                       \
23676   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23677   "  [l2-table <nn>] [del]")                                            \
23678 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23679 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23680     "[master|slave]")                                                   \
23681 _(netmap_delete, "name <interface name>")                               \
23682 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23683 _(mpls_fib_dump, "")                                                    \
23684 _(classify_table_ids, "")                                               \
23685 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23686 _(classify_table_info, "table_id <nn>")                                 \
23687 _(classify_session_dump, "table_id <nn>")                               \
23688 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23689     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23690     "[template_interval <nn>] [udp_checksum]")                          \
23691 _(ipfix_exporter_dump, "")                                              \
23692 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23693 _(ipfix_classify_stream_dump, "")                                       \
23694 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23695 _(ipfix_classify_table_dump, "")                                        \
23696 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23697 _(sw_interface_span_dump, "[l2]")                                           \
23698 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23699 _(pg_create_interface, "if_id <nn>")                                    \
23700 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23701 _(pg_enable_disable, "[stream <id>] disable")                           \
23702 _(ip_source_and_port_range_check_add_del,                               \
23703   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23704 _(ip_source_and_port_range_check_interface_add_del,                     \
23705   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23706   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23707 _(ipsec_gre_add_del_tunnel,                                             \
23708   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23709 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23710 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23711 _(l2_interface_pbb_tag_rewrite,                                         \
23712   "<intfc> | sw_if_index <nn> \n"                                       \
23713   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23714   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23715 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23716 _(flow_classify_set_interface,                                          \
23717   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23718 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23719 _(ip_fib_dump, "")                                                      \
23720 _(ip_mfib_dump, "")                                                     \
23721 _(ip6_fib_dump, "")                                                     \
23722 _(ip6_mfib_dump, "")                                                    \
23723 _(feature_enable_disable, "arc_name <arc_name> "                        \
23724   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23725 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23726 "[disable]")                                                            \
23727 _(l2_xconnect_dump, "")                                                 \
23728 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23729 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23730 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23731 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23732 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23733 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23734 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23735   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23736 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23737 _(sock_init_shm, "size <nnn>")                                          \
23738 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23739 _(dns_enable_disable, "[enable][disable]")                              \
23740 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23741 _(dns_resolve_name, "<hostname>")                                       \
23742 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23743 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23744 _(dns_resolve_name, "<hostname>")                                       \
23745 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23746   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23747 _(session_rules_dump, "")                                               \
23748 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23749 _(output_acl_set_interface,                                             \
23750   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23751   "  [l2-table <nn>] [del]")                                            \
23752 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23753
23754 /* List of command functions, CLI names map directly to functions */
23755 #define foreach_cli_function                                    \
23756 _(comment, "usage: comment <ignore-rest-of-line>")              \
23757 _(dump_interface_table, "usage: dump_interface_table")          \
23758 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23759 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23760 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23761 _(dump_stats_table, "usage: dump_stats_table")                  \
23762 _(dump_macro_table, "usage: dump_macro_table ")                 \
23763 _(dump_node_table, "usage: dump_node_table")                    \
23764 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23765 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23766 _(echo, "usage: echo <message>")                                \
23767 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23768 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23769 _(help, "usage: help")                                          \
23770 _(q, "usage: quit")                                             \
23771 _(quit, "usage: quit")                                          \
23772 _(search_node_table, "usage: search_node_table <name>...")      \
23773 _(set, "usage: set <variable-name> <value>")                    \
23774 _(script, "usage: script <file-name>")                          \
23775 _(unset, "usage: unset <variable-name>")
23776 #define _(N,n)                                  \
23777     static void vl_api_##n##_t_handler_uni      \
23778     (vl_api_##n##_t * mp)                       \
23779     {                                           \
23780         vat_main_t * vam = &vat_main;           \
23781         if (vam->json_output) {                 \
23782             vl_api_##n##_t_handler_json(mp);    \
23783         } else {                                \
23784             vl_api_##n##_t_handler(mp);         \
23785         }                                       \
23786     }
23787 foreach_vpe_api_reply_msg;
23788 #if VPP_API_TEST_BUILTIN == 0
23789 foreach_standalone_reply_msg;
23790 #endif
23791 #undef _
23792
23793 void
23794 vat_api_hookup (vat_main_t * vam)
23795 {
23796 #define _(N,n)                                                  \
23797     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23798                            vl_api_##n##_t_handler_uni,          \
23799                            vl_noop_handler,                     \
23800                            vl_api_##n##_t_endian,               \
23801                            vl_api_##n##_t_print,                \
23802                            sizeof(vl_api_##n##_t), 1);
23803   foreach_vpe_api_reply_msg;
23804 #if VPP_API_TEST_BUILTIN == 0
23805   foreach_standalone_reply_msg;
23806 #endif
23807 #undef _
23808
23809 #if (VPP_API_TEST_BUILTIN==0)
23810   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23811
23812   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23813
23814   vam->function_by_name = hash_create_string (0, sizeof (uword));
23815
23816   vam->help_by_name = hash_create_string (0, sizeof (uword));
23817 #endif
23818
23819   /* API messages we can send */
23820 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23821   foreach_vpe_api_msg;
23822 #undef _
23823
23824   /* Help strings */
23825 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23826   foreach_vpe_api_msg;
23827 #undef _
23828
23829   /* CLI functions */
23830 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23831   foreach_cli_function;
23832 #undef _
23833
23834   /* Help strings */
23835 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23836   foreach_cli_function;
23837 #undef _
23838 }
23839
23840 #if VPP_API_TEST_BUILTIN
23841 static clib_error_t *
23842 vat_api_hookup_shim (vlib_main_t * vm)
23843 {
23844   vat_api_hookup (&vat_main);
23845   return 0;
23846 }
23847
23848 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23849 #endif
23850
23851 /*
23852  * fd.io coding-style-patch-verification: ON
23853  *
23854  * Local Variables:
23855  * eval: (c-set-style "gnu")
23856  * End:
23857  */