DHCP Client Dump
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/ip/ip_neighbor.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/in_out_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include "vat/json_format.h"
57
58 #include <inttypes.h>
59 #include <sys/stat.h>
60
61 #define vl_typedefs             /* define message structures */
62 #include <vpp/api/vpe_all_api_h.h>
63 #undef vl_typedefs
64
65 /* declare message handlers for each api */
66
67 #define vl_endianfun            /* define message structures */
68 #include <vpp/api/vpe_all_api_h.h>
69 #undef vl_endianfun
70
71 /* instantiate all the print functions we know about */
72 #define vl_print(handle, ...)
73 #define vl_printfun
74 #include <vpp/api/vpe_all_api_h.h>
75 #undef vl_printfun
76
77 #define __plugin_msg_base 0
78 #include <vlibapi/vat_helper_macros.h>
79
80 #if VPP_API_TEST_BUILTIN == 0
81 #include <netdb.h>
82
83 u32
84 vl (void *p)
85 {
86   return vec_len (p);
87 }
88
89 int
90 vat_socket_connect (vat_main_t * vam)
91 {
92   vam->socket_client_main = &socket_client_main;
93   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
94                                    0 /* default socket rx, tx buffer */ );
95 }
96 #else /* vpp built-in case, we don't do sockets... */
97 int
98 vat_socket_connect (vat_main_t * vam)
99 {
100   return 0;
101 }
102
103 int
104 vl_socket_client_read (int wait)
105 {
106   return -1;
107 };
108
109 int
110 vl_socket_client_write ()
111 {
112   return -1;
113 };
114
115 void *
116 vl_socket_client_msg_alloc (int nbytes)
117 {
118   return 0;
119 }
120 #endif
121
122
123 f64
124 vat_time_now (vat_main_t * vam)
125 {
126 #if VPP_API_TEST_BUILTIN
127   return vlib_time_now (vam->vlib_main);
128 #else
129   return clib_time_now (&vam->clib_time);
130 #endif
131 }
132
133 void
134 errmsg (char *fmt, ...)
135 {
136   vat_main_t *vam = &vat_main;
137   va_list va;
138   u8 *s;
139
140   va_start (va, fmt);
141   s = va_format (0, fmt, &va);
142   va_end (va);
143
144   vec_add1 (s, 0);
145
146 #if VPP_API_TEST_BUILTIN
147   vlib_cli_output (vam->vlib_main, (char *) s);
148 #else
149   {
150     if (vam->ifp != stdin)
151       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
152                vam->input_line_number);
153     fformat (vam->ofp, (char *) s);
154     fflush (vam->ofp);
155   }
156 #endif
157
158   vec_free (s);
159 }
160
161 #if VPP_API_TEST_BUILTIN == 0
162 static uword
163 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
164 {
165   vat_main_t *vam = va_arg (*args, vat_main_t *);
166   u32 *result = va_arg (*args, u32 *);
167   u8 *if_name;
168   uword *p;
169
170   if (!unformat (input, "%s", &if_name))
171     return 0;
172
173   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
174   if (p == 0)
175     return 0;
176   *result = p[0];
177   return 1;
178 }
179
180 /* Parse an IP4 address %d.%d.%d.%d. */
181 uword
182 unformat_ip4_address (unformat_input_t * input, va_list * args)
183 {
184   u8 *result = va_arg (*args, u8 *);
185   unsigned a[4];
186
187   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
188     return 0;
189
190   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
191     return 0;
192
193   result[0] = a[0];
194   result[1] = a[1];
195   result[2] = a[2];
196   result[3] = a[3];
197
198   return 1;
199 }
200
201 uword
202 unformat_ethernet_address (unformat_input_t * input, va_list * args)
203 {
204   u8 *result = va_arg (*args, u8 *);
205   u32 i, a[6];
206
207   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
208                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
209     return 0;
210
211   /* Check range. */
212   for (i = 0; i < 6; i++)
213     if (a[i] >= (1 << 8))
214       return 0;
215
216   for (i = 0; i < 6; i++)
217     result[i] = a[i];
218
219   return 1;
220 }
221
222 /* Returns ethernet type as an int in host byte order. */
223 uword
224 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
225                                         va_list * args)
226 {
227   u16 *result = va_arg (*args, u16 *);
228   int type;
229
230   /* Numeric type. */
231   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
232     {
233       if (type >= (1 << 16))
234         return 0;
235       *result = type;
236       return 1;
237     }
238   return 0;
239 }
240
241 /* Parse an IP6 address. */
242 uword
243 unformat_ip6_address (unformat_input_t * input, va_list * args)
244 {
245   ip6_address_t *result = va_arg (*args, ip6_address_t *);
246   u16 hex_quads[8];
247   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
248   uword c, n_colon, double_colon_index;
249
250   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
251   double_colon_index = ARRAY_LEN (hex_quads);
252   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
253     {
254       hex_digit = 16;
255       if (c >= '0' && c <= '9')
256         hex_digit = c - '0';
257       else if (c >= 'a' && c <= 'f')
258         hex_digit = c + 10 - 'a';
259       else if (c >= 'A' && c <= 'F')
260         hex_digit = c + 10 - 'A';
261       else if (c == ':' && n_colon < 2)
262         n_colon++;
263       else
264         {
265           unformat_put_input (input);
266           break;
267         }
268
269       /* Too many hex quads. */
270       if (n_hex_quads >= ARRAY_LEN (hex_quads))
271         return 0;
272
273       if (hex_digit < 16)
274         {
275           hex_quad = (hex_quad << 4) | hex_digit;
276
277           /* Hex quad must fit in 16 bits. */
278           if (n_hex_digits >= 4)
279             return 0;
280
281           n_colon = 0;
282           n_hex_digits++;
283         }
284
285       /* Save position of :: */
286       if (n_colon == 2)
287         {
288           /* More than one :: ? */
289           if (double_colon_index < ARRAY_LEN (hex_quads))
290             return 0;
291           double_colon_index = n_hex_quads;
292         }
293
294       if (n_colon > 0 && n_hex_digits > 0)
295         {
296           hex_quads[n_hex_quads++] = hex_quad;
297           hex_quad = 0;
298           n_hex_digits = 0;
299         }
300     }
301
302   if (n_hex_digits > 0)
303     hex_quads[n_hex_quads++] = hex_quad;
304
305   {
306     word i;
307
308     /* Expand :: to appropriate number of zero hex quads. */
309     if (double_colon_index < ARRAY_LEN (hex_quads))
310       {
311         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
312
313         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
314           hex_quads[n_zero + i] = hex_quads[i];
315
316         for (i = 0; i < n_zero; i++)
317           hex_quads[double_colon_index + i] = 0;
318
319         n_hex_quads = ARRAY_LEN (hex_quads);
320       }
321
322     /* Too few hex quads given. */
323     if (n_hex_quads < ARRAY_LEN (hex_quads))
324       return 0;
325
326     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
327       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
328
329     return 1;
330   }
331 }
332
333 uword
334 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
335 {
336   u32 *r = va_arg (*args, u32 *);
337
338   if (0);
339 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
340   foreach_ipsec_policy_action
341 #undef _
342     else
343     return 0;
344   return 1;
345 }
346
347 uword
348 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
349 {
350   u32 *r = va_arg (*args, u32 *);
351
352   if (0);
353 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
354   foreach_ipsec_crypto_alg
355 #undef _
356     else
357     return 0;
358   return 1;
359 }
360
361 u8 *
362 format_ipsec_crypto_alg (u8 * s, va_list * args)
363 {
364   u32 i = va_arg (*args, u32);
365   u8 *t = 0;
366
367   switch (i)
368     {
369 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
370       foreach_ipsec_crypto_alg
371 #undef _
372     default:
373       return format (s, "unknown");
374     }
375   return format (s, "%s", t);
376 }
377
378 uword
379 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
380 {
381   u32 *r = va_arg (*args, u32 *);
382
383   if (0);
384 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
385   foreach_ipsec_integ_alg
386 #undef _
387     else
388     return 0;
389   return 1;
390 }
391
392 u8 *
393 format_ipsec_integ_alg (u8 * s, va_list * args)
394 {
395   u32 i = va_arg (*args, u32);
396   u8 *t = 0;
397
398   switch (i)
399     {
400 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
401       foreach_ipsec_integ_alg
402 #undef _
403     default:
404       return format (s, "unknown");
405     }
406   return format (s, "%s", t);
407 }
408
409 uword
410 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
411 {
412   u32 *r = va_arg (*args, u32 *);
413
414   if (0);
415 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
416   foreach_ikev2_auth_method
417 #undef _
418     else
419     return 0;
420   return 1;
421 }
422
423 uword
424 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
425 {
426   u32 *r = va_arg (*args, u32 *);
427
428   if (0);
429 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
430   foreach_ikev2_id_type
431 #undef _
432     else
433     return 0;
434   return 1;
435 }
436 #else /* VPP_API_TEST_BUILTIN == 1 */
437 static uword
438 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
439 {
440   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
441   vnet_main_t *vnm = vnet_get_main ();
442   u32 *result = va_arg (*args, u32 *);
443   u32 sw_if_index;
444
445   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
446     return 0;
447
448   *result = sw_if_index;
449   return 1;
450 }
451 #endif /* VPP_API_TEST_BUILTIN */
452
453 static uword
454 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "kbps"))
459     *r = SSE2_QOS_RATE_KBPS;
460   else if (unformat (input, "pps"))
461     *r = SSE2_QOS_RATE_PPS;
462   else
463     return 0;
464   return 1;
465 }
466
467 static uword
468 unformat_policer_round_type (unformat_input_t * input, va_list * args)
469 {
470   u8 *r = va_arg (*args, u8 *);
471
472   if (unformat (input, "closest"))
473     *r = SSE2_QOS_ROUND_TO_CLOSEST;
474   else if (unformat (input, "up"))
475     *r = SSE2_QOS_ROUND_TO_UP;
476   else if (unformat (input, "down"))
477     *r = SSE2_QOS_ROUND_TO_DOWN;
478   else
479     return 0;
480   return 1;
481 }
482
483 static uword
484 unformat_policer_type (unformat_input_t * input, va_list * args)
485 {
486   u8 *r = va_arg (*args, u8 *);
487
488   if (unformat (input, "1r2c"))
489     *r = SSE2_QOS_POLICER_TYPE_1R2C;
490   else if (unformat (input, "1r3c"))
491     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
492   else if (unformat (input, "2r3c-2698"))
493     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
494   else if (unformat (input, "2r3c-4115"))
495     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
496   else if (unformat (input, "2r3c-mef5cf1"))
497     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
498   else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_dscp (unformat_input_t * input, va_list * va)
505 {
506   u8 *r = va_arg (*va, u8 *);
507
508   if (0);
509 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
510   foreach_vnet_dscp
511 #undef _
512     else
513     return 0;
514   return 1;
515 }
516
517 static uword
518 unformat_policer_action_type (unformat_input_t * input, va_list * va)
519 {
520   sse2_qos_pol_action_params_st *a
521     = va_arg (*va, sse2_qos_pol_action_params_st *);
522
523   if (unformat (input, "drop"))
524     a->action_type = SSE2_QOS_ACTION_DROP;
525   else if (unformat (input, "transmit"))
526     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
527   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
528     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
529   else
530     return 0;
531   return 1;
532 }
533
534 static uword
535 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
536 {
537   u32 *r = va_arg (*va, u32 *);
538   u32 tid;
539
540   if (unformat (input, "ip4"))
541     tid = POLICER_CLASSIFY_TABLE_IP4;
542   else if (unformat (input, "ip6"))
543     tid = POLICER_CLASSIFY_TABLE_IP6;
544   else if (unformat (input, "l2"))
545     tid = POLICER_CLASSIFY_TABLE_L2;
546   else
547     return 0;
548
549   *r = tid;
550   return 1;
551 }
552
553 static uword
554 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
555 {
556   u32 *r = va_arg (*va, u32 *);
557   u32 tid;
558
559   if (unformat (input, "ip4"))
560     tid = FLOW_CLASSIFY_TABLE_IP4;
561   else if (unformat (input, "ip6"))
562     tid = FLOW_CLASSIFY_TABLE_IP6;
563   else
564     return 0;
565
566   *r = tid;
567   return 1;
568 }
569
570 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
571 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
572 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
573 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
574
575 #if (VPP_API_TEST_BUILTIN==0)
576 uword
577 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
578 {
579   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
580   mfib_itf_attribute_t attr;
581
582   old = *iflags;
583   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
584   {
585     if (unformat (input, mfib_itf_flag_long_names[attr]))
586       *iflags |= (1 << attr);
587   }
588   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
589   {
590     if (unformat (input, mfib_itf_flag_names[attr]))
591       *iflags |= (1 << attr);
592   }
593
594   return (old == *iflags ? 0 : 1);
595 }
596
597 uword
598 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
599 {
600   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
601   mfib_entry_attribute_t attr;
602
603   old = *eflags;
604   FOR_EACH_MFIB_ATTRIBUTE (attr)
605   {
606     if (unformat (input, mfib_flag_long_names[attr]))
607       *eflags |= (1 << attr);
608   }
609   FOR_EACH_MFIB_ATTRIBUTE (attr)
610   {
611     if (unformat (input, mfib_flag_names[attr]))
612       *eflags |= (1 << attr);
613   }
614
615   return (old == *eflags ? 0 : 1);
616 }
617
618 u8 *
619 format_ip4_address (u8 * s, va_list * args)
620 {
621   u8 *a = va_arg (*args, u8 *);
622   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
623 }
624
625 u8 *
626 format_ip6_address (u8 * s, va_list * args)
627 {
628   ip6_address_t *a = va_arg (*args, ip6_address_t *);
629   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
630
631   i_max_n_zero = ARRAY_LEN (a->as_u16);
632   max_n_zeros = 0;
633   i_first_zero = i_max_n_zero;
634   n_zeros = 0;
635   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
636     {
637       u32 is_zero = a->as_u16[i] == 0;
638       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
639         {
640           i_first_zero = i;
641           n_zeros = 0;
642         }
643       n_zeros += is_zero;
644       if ((!is_zero && n_zeros > max_n_zeros)
645           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
646         {
647           i_max_n_zero = i_first_zero;
648           max_n_zeros = n_zeros;
649           i_first_zero = ARRAY_LEN (a->as_u16);
650           n_zeros = 0;
651         }
652     }
653
654   last_double_colon = 0;
655   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
656     {
657       if (i == i_max_n_zero && max_n_zeros > 1)
658         {
659           s = format (s, "::");
660           i += max_n_zeros - 1;
661           last_double_colon = 1;
662         }
663       else
664         {
665           s = format (s, "%s%x",
666                       (last_double_colon || i == 0) ? "" : ":",
667                       clib_net_to_host_u16 (a->as_u16[i]));
668           last_double_colon = 0;
669         }
670     }
671
672   return s;
673 }
674
675 /* Format an IP46 address. */
676 u8 *
677 format_ip46_address (u8 * s, va_list * args)
678 {
679   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
680   ip46_type_t type = va_arg (*args, ip46_type_t);
681   int is_ip4 = 1;
682
683   switch (type)
684     {
685     case IP46_TYPE_ANY:
686       is_ip4 = ip46_address_is_ip4 (ip46);
687       break;
688     case IP46_TYPE_IP4:
689       is_ip4 = 1;
690       break;
691     case IP46_TYPE_IP6:
692       is_ip4 = 0;
693       break;
694     }
695
696   return is_ip4 ?
697     format (s, "%U", format_ip4_address, &ip46->ip4) :
698     format (s, "%U", format_ip6_address, &ip46->ip6);
699 }
700
701 u8 *
702 format_ethernet_address (u8 * s, va_list * args)
703 {
704   u8 *a = va_arg (*args, u8 *);
705
706   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
707                  a[0], a[1], a[2], a[3], a[4], a[5]);
708 }
709 #endif
710
711 static void
712 increment_v4_address (ip4_address_t * a)
713 {
714   u32 v;
715
716   v = ntohl (a->as_u32) + 1;
717   a->as_u32 = ntohl (v);
718 }
719
720 static void
721 increment_v6_address (ip6_address_t * a)
722 {
723   u64 v0, v1;
724
725   v0 = clib_net_to_host_u64 (a->as_u64[0]);
726   v1 = clib_net_to_host_u64 (a->as_u64[1]);
727
728   v1 += 1;
729   if (v1 == 0)
730     v0 += 1;
731   a->as_u64[0] = clib_net_to_host_u64 (v0);
732   a->as_u64[1] = clib_net_to_host_u64 (v1);
733 }
734
735 static void
736 increment_mac_address (u8 * mac)
737 {
738   u64 tmp = *((u64 *) mac);
739   tmp = clib_net_to_host_u64 (tmp);
740   tmp += 1 << 16;               /* skip unused (least significant) octets */
741   tmp = clib_host_to_net_u64 (tmp);
742
743   clib_memcpy (mac, &tmp, 6);
744 }
745
746 static void vl_api_create_loopback_reply_t_handler
747   (vl_api_create_loopback_reply_t * mp)
748 {
749   vat_main_t *vam = &vat_main;
750   i32 retval = ntohl (mp->retval);
751
752   vam->retval = retval;
753   vam->regenerate_interface_table = 1;
754   vam->sw_if_index = ntohl (mp->sw_if_index);
755   vam->result_ready = 1;
756 }
757
758 static void vl_api_create_loopback_reply_t_handler_json
759   (vl_api_create_loopback_reply_t * mp)
760 {
761   vat_main_t *vam = &vat_main;
762   vat_json_node_t node;
763
764   vat_json_init_object (&node);
765   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
766   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
767
768   vat_json_print (vam->ofp, &node);
769   vat_json_free (&node);
770   vam->retval = ntohl (mp->retval);
771   vam->result_ready = 1;
772 }
773
774 static void vl_api_create_loopback_instance_reply_t_handler
775   (vl_api_create_loopback_instance_reply_t * mp)
776 {
777   vat_main_t *vam = &vat_main;
778   i32 retval = ntohl (mp->retval);
779
780   vam->retval = retval;
781   vam->regenerate_interface_table = 1;
782   vam->sw_if_index = ntohl (mp->sw_if_index);
783   vam->result_ready = 1;
784 }
785
786 static void vl_api_create_loopback_instance_reply_t_handler_json
787   (vl_api_create_loopback_instance_reply_t * mp)
788 {
789   vat_main_t *vam = &vat_main;
790   vat_json_node_t node;
791
792   vat_json_init_object (&node);
793   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
794   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
795
796   vat_json_print (vam->ofp, &node);
797   vat_json_free (&node);
798   vam->retval = ntohl (mp->retval);
799   vam->result_ready = 1;
800 }
801
802 static void vl_api_af_packet_create_reply_t_handler
803   (vl_api_af_packet_create_reply_t * mp)
804 {
805   vat_main_t *vam = &vat_main;
806   i32 retval = ntohl (mp->retval);
807
808   vam->retval = retval;
809   vam->regenerate_interface_table = 1;
810   vam->sw_if_index = ntohl (mp->sw_if_index);
811   vam->result_ready = 1;
812 }
813
814 static void vl_api_af_packet_create_reply_t_handler_json
815   (vl_api_af_packet_create_reply_t * mp)
816 {
817   vat_main_t *vam = &vat_main;
818   vat_json_node_t node;
819
820   vat_json_init_object (&node);
821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
822   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
823
824   vat_json_print (vam->ofp, &node);
825   vat_json_free (&node);
826
827   vam->retval = ntohl (mp->retval);
828   vam->result_ready = 1;
829 }
830
831 static void vl_api_create_vlan_subif_reply_t_handler
832   (vl_api_create_vlan_subif_reply_t * mp)
833 {
834   vat_main_t *vam = &vat_main;
835   i32 retval = ntohl (mp->retval);
836
837   vam->retval = retval;
838   vam->regenerate_interface_table = 1;
839   vam->sw_if_index = ntohl (mp->sw_if_index);
840   vam->result_ready = 1;
841 }
842
843 static void vl_api_create_vlan_subif_reply_t_handler_json
844   (vl_api_create_vlan_subif_reply_t * mp)
845 {
846   vat_main_t *vam = &vat_main;
847   vat_json_node_t node;
848
849   vat_json_init_object (&node);
850   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
851   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
852
853   vat_json_print (vam->ofp, &node);
854   vat_json_free (&node);
855
856   vam->retval = ntohl (mp->retval);
857   vam->result_ready = 1;
858 }
859
860 static void vl_api_create_subif_reply_t_handler
861   (vl_api_create_subif_reply_t * mp)
862 {
863   vat_main_t *vam = &vat_main;
864   i32 retval = ntohl (mp->retval);
865
866   vam->retval = retval;
867   vam->regenerate_interface_table = 1;
868   vam->sw_if_index = ntohl (mp->sw_if_index);
869   vam->result_ready = 1;
870 }
871
872 static void vl_api_create_subif_reply_t_handler_json
873   (vl_api_create_subif_reply_t * mp)
874 {
875   vat_main_t *vam = &vat_main;
876   vat_json_node_t node;
877
878   vat_json_init_object (&node);
879   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
880   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
881
882   vat_json_print (vam->ofp, &node);
883   vat_json_free (&node);
884
885   vam->retval = ntohl (mp->retval);
886   vam->result_ready = 1;
887 }
888
889 static void vl_api_interface_name_renumber_reply_t_handler
890   (vl_api_interface_name_renumber_reply_t * mp)
891 {
892   vat_main_t *vam = &vat_main;
893   i32 retval = ntohl (mp->retval);
894
895   vam->retval = retval;
896   vam->regenerate_interface_table = 1;
897   vam->result_ready = 1;
898 }
899
900 static void vl_api_interface_name_renumber_reply_t_handler_json
901   (vl_api_interface_name_renumber_reply_t * mp)
902 {
903   vat_main_t *vam = &vat_main;
904   vat_json_node_t node;
905
906   vat_json_init_object (&node);
907   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
908
909   vat_json_print (vam->ofp, &node);
910   vat_json_free (&node);
911
912   vam->retval = ntohl (mp->retval);
913   vam->result_ready = 1;
914 }
915
916 /*
917  * Special-case: build the interface table, maintain
918  * the next loopback sw_if_index vbl.
919  */
920 static void vl_api_sw_interface_details_t_handler
921   (vl_api_sw_interface_details_t * mp)
922 {
923   vat_main_t *vam = &vat_main;
924   u8 *s = format (0, "%s%c", mp->interface_name, 0);
925
926   hash_set_mem (vam->sw_if_index_by_interface_name, s,
927                 ntohl (mp->sw_if_index));
928
929   /* In sub interface case, fill the sub interface table entry */
930   if (mp->sw_if_index != mp->sup_sw_if_index)
931     {
932       sw_interface_subif_t *sub = NULL;
933
934       vec_add2 (vam->sw_if_subif_table, sub, 1);
935
936       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
937       strncpy ((char *) sub->interface_name, (char *) s,
938                vec_len (sub->interface_name));
939       sub->sw_if_index = ntohl (mp->sw_if_index);
940       sub->sub_id = ntohl (mp->sub_id);
941
942       sub->sub_dot1ad = mp->sub_dot1ad;
943       sub->sub_number_of_tags = mp->sub_number_of_tags;
944       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
945       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
946       sub->sub_exact_match = mp->sub_exact_match;
947       sub->sub_default = mp->sub_default;
948       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
949       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
950
951       /* vlan tag rewrite */
952       sub->vtr_op = ntohl (mp->vtr_op);
953       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
954       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
955       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
956     }
957 }
958
959 static void vl_api_sw_interface_details_t_handler_json
960   (vl_api_sw_interface_details_t * mp)
961 {
962   vat_main_t *vam = &vat_main;
963   vat_json_node_t *node = NULL;
964
965   if (VAT_JSON_ARRAY != vam->json_tree.type)
966     {
967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
968       vat_json_init_array (&vam->json_tree);
969     }
970   node = vat_json_array_add (&vam->json_tree);
971
972   vat_json_init_object (node);
973   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
974   vat_json_object_add_uint (node, "sup_sw_if_index",
975                             ntohl (mp->sup_sw_if_index));
976   vat_json_object_add_uint (node, "l2_address_length",
977                             ntohl (mp->l2_address_length));
978   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
979                              sizeof (mp->l2_address));
980   vat_json_object_add_string_copy (node, "interface_name",
981                                    mp->interface_name);
982   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
983   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
984   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
985   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
986   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
987   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
988   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
989   vat_json_object_add_uint (node, "sub_number_of_tags",
990                             mp->sub_number_of_tags);
991   vat_json_object_add_uint (node, "sub_outer_vlan_id",
992                             ntohs (mp->sub_outer_vlan_id));
993   vat_json_object_add_uint (node, "sub_inner_vlan_id",
994                             ntohs (mp->sub_inner_vlan_id));
995   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
996   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
997   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
998                             mp->sub_outer_vlan_id_any);
999   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1000                             mp->sub_inner_vlan_id_any);
1001   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1002   vat_json_object_add_uint (node, "vtr_push_dot1q",
1003                             ntohl (mp->vtr_push_dot1q));
1004   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1005   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1006   if (mp->sub_dot1ah)
1007     {
1008       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1009                                        format (0, "%U",
1010                                                format_ethernet_address,
1011                                                &mp->b_dmac));
1012       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1013                                        format (0, "%U",
1014                                                format_ethernet_address,
1015                                                &mp->b_smac));
1016       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1017       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1018     }
1019 }
1020
1021 #if VPP_API_TEST_BUILTIN == 0
1022 static void vl_api_sw_interface_event_t_handler
1023   (vl_api_sw_interface_event_t * mp)
1024 {
1025   vat_main_t *vam = &vat_main;
1026   if (vam->interface_event_display)
1027     errmsg ("interface flags: sw_if_index %d %s %s",
1028             ntohl (mp->sw_if_index),
1029             mp->admin_up_down ? "admin-up" : "admin-down",
1030             mp->link_up_down ? "link-up" : "link-down");
1031 }
1032 #endif
1033
1034 static void vl_api_sw_interface_event_t_handler_json
1035   (vl_api_sw_interface_event_t * mp)
1036 {
1037   /* JSON output not supported */
1038 }
1039
1040 static void
1041 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1042 {
1043   vat_main_t *vam = &vat_main;
1044   i32 retval = ntohl (mp->retval);
1045
1046   vam->retval = retval;
1047   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1048   vam->result_ready = 1;
1049 }
1050
1051 static void
1052 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1053 {
1054   vat_main_t *vam = &vat_main;
1055   vat_json_node_t node;
1056   api_main_t *am = &api_main;
1057   void *oldheap;
1058   u8 *reply;
1059
1060   vat_json_init_object (&node);
1061   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1062   vat_json_object_add_uint (&node, "reply_in_shmem",
1063                             ntohl (mp->reply_in_shmem));
1064   /* Toss the shared-memory original... */
1065   pthread_mutex_lock (&am->vlib_rp->mutex);
1066   oldheap = svm_push_data_heap (am->vlib_rp);
1067
1068   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1069   vec_free (reply);
1070
1071   svm_pop_heap (oldheap);
1072   pthread_mutex_unlock (&am->vlib_rp->mutex);
1073
1074   vat_json_print (vam->ofp, &node);
1075   vat_json_free (&node);
1076
1077   vam->retval = ntohl (mp->retval);
1078   vam->result_ready = 1;
1079 }
1080
1081 static void
1082 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1083 {
1084   vat_main_t *vam = &vat_main;
1085   i32 retval = ntohl (mp->retval);
1086   u32 length = ntohl (mp->length);
1087
1088   vec_reset_length (vam->cmd_reply);
1089
1090   vam->retval = retval;
1091   if (retval == 0)
1092     {
1093       vec_validate (vam->cmd_reply, length);
1094       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1095       vam->cmd_reply[length] = 0;
1096     }
1097   vam->result_ready = 1;
1098 }
1099
1100 static void
1101 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   vat_json_node_t node;
1105
1106   vec_reset_length (vam->cmd_reply);
1107
1108   vat_json_init_object (&node);
1109   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1110   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1111
1112   vat_json_print (vam->ofp, &node);
1113   vat_json_free (&node);
1114
1115   vam->retval = ntohl (mp->retval);
1116   vam->result_ready = 1;
1117 }
1118
1119 static void vl_api_classify_add_del_table_reply_t_handler
1120   (vl_api_classify_add_del_table_reply_t * mp)
1121 {
1122   vat_main_t *vam = &vat_main;
1123   i32 retval = ntohl (mp->retval);
1124   if (vam->async_mode)
1125     {
1126       vam->async_errors += (retval < 0);
1127     }
1128   else
1129     {
1130       vam->retval = retval;
1131       if (retval == 0 &&
1132           ((mp->new_table_index != 0xFFFFFFFF) ||
1133            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1134            (mp->match_n_vectors != 0xFFFFFFFF)))
1135         /*
1136          * Note: this is just barely thread-safe, depends on
1137          * the main thread spinning waiting for an answer...
1138          */
1139         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1140                 ntohl (mp->new_table_index),
1141                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1142       vam->result_ready = 1;
1143     }
1144 }
1145
1146 static void vl_api_classify_add_del_table_reply_t_handler_json
1147   (vl_api_classify_add_del_table_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   vat_json_node_t node;
1151
1152   vat_json_init_object (&node);
1153   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1154   vat_json_object_add_uint (&node, "new_table_index",
1155                             ntohl (mp->new_table_index));
1156   vat_json_object_add_uint (&node, "skip_n_vectors",
1157                             ntohl (mp->skip_n_vectors));
1158   vat_json_object_add_uint (&node, "match_n_vectors",
1159                             ntohl (mp->match_n_vectors));
1160
1161   vat_json_print (vam->ofp, &node);
1162   vat_json_free (&node);
1163
1164   vam->retval = ntohl (mp->retval);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void vl_api_get_node_index_reply_t_handler
1169   (vl_api_get_node_index_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   i32 retval = ntohl (mp->retval);
1173   if (vam->async_mode)
1174     {
1175       vam->async_errors += (retval < 0);
1176     }
1177   else
1178     {
1179       vam->retval = retval;
1180       if (retval == 0)
1181         errmsg ("node index %d", ntohl (mp->node_index));
1182       vam->result_ready = 1;
1183     }
1184 }
1185
1186 static void vl_api_get_node_index_reply_t_handler_json
1187   (vl_api_get_node_index_reply_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   vat_json_node_t node;
1191
1192   vat_json_init_object (&node);
1193   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1194   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1195
1196   vat_json_print (vam->ofp, &node);
1197   vat_json_free (&node);
1198
1199   vam->retval = ntohl (mp->retval);
1200   vam->result_ready = 1;
1201 }
1202
1203 static void vl_api_get_next_index_reply_t_handler
1204   (vl_api_get_next_index_reply_t * mp)
1205 {
1206   vat_main_t *vam = &vat_main;
1207   i32 retval = ntohl (mp->retval);
1208   if (vam->async_mode)
1209     {
1210       vam->async_errors += (retval < 0);
1211     }
1212   else
1213     {
1214       vam->retval = retval;
1215       if (retval == 0)
1216         errmsg ("next node index %d", ntohl (mp->next_index));
1217       vam->result_ready = 1;
1218     }
1219 }
1220
1221 static void vl_api_get_next_index_reply_t_handler_json
1222   (vl_api_get_next_index_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   vat_json_node_t node;
1226
1227   vat_json_init_object (&node);
1228   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1229   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1230
1231   vat_json_print (vam->ofp, &node);
1232   vat_json_free (&node);
1233
1234   vam->retval = ntohl (mp->retval);
1235   vam->result_ready = 1;
1236 }
1237
1238 static void vl_api_add_node_next_reply_t_handler
1239   (vl_api_add_node_next_reply_t * mp)
1240 {
1241   vat_main_t *vam = &vat_main;
1242   i32 retval = ntohl (mp->retval);
1243   if (vam->async_mode)
1244     {
1245       vam->async_errors += (retval < 0);
1246     }
1247   else
1248     {
1249       vam->retval = retval;
1250       if (retval == 0)
1251         errmsg ("next index %d", ntohl (mp->next_index));
1252       vam->result_ready = 1;
1253     }
1254 }
1255
1256 static void vl_api_add_node_next_reply_t_handler_json
1257   (vl_api_add_node_next_reply_t * mp)
1258 {
1259   vat_main_t *vam = &vat_main;
1260   vat_json_node_t node;
1261
1262   vat_json_init_object (&node);
1263   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1264   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1265
1266   vat_json_print (vam->ofp, &node);
1267   vat_json_free (&node);
1268
1269   vam->retval = ntohl (mp->retval);
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_show_version_reply_t_handler
1274   (vl_api_show_version_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278
1279   if (retval >= 0)
1280     {
1281       errmsg ("        program: %s", mp->program);
1282       errmsg ("        version: %s", mp->version);
1283       errmsg ("     build date: %s", mp->build_date);
1284       errmsg ("build directory: %s", mp->build_directory);
1285     }
1286   vam->retval = retval;
1287   vam->result_ready = 1;
1288 }
1289
1290 static void vl_api_show_version_reply_t_handler_json
1291   (vl_api_show_version_reply_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   vat_json_node_t node;
1295
1296   vat_json_init_object (&node);
1297   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1298   vat_json_object_add_string_copy (&node, "program", mp->program);
1299   vat_json_object_add_string_copy (&node, "version", mp->version);
1300   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1301   vat_json_object_add_string_copy (&node, "build_directory",
1302                                    mp->build_directory);
1303
1304   vat_json_print (vam->ofp, &node);
1305   vat_json_free (&node);
1306
1307   vam->retval = ntohl (mp->retval);
1308   vam->result_ready = 1;
1309 }
1310
1311 static void
1312 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1313 {
1314   u32 sw_if_index = ntohl (mp->sw_if_index);
1315   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1316           mp->mac_ip ? "mac/ip binding" : "address resolution",
1317           ntohl (mp->pid), format_ip4_address, &mp->address,
1318           format_ethernet_address, mp->new_mac, sw_if_index);
1319 }
1320
1321 static void
1322 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1323 {
1324   /* JSON output not supported */
1325 }
1326
1327 static void
1328 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1329 {
1330   u32 sw_if_index = ntohl (mp->sw_if_index);
1331   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1332           mp->mac_ip ? "mac/ip binding" : "address resolution",
1333           ntohl (mp->pid), format_ip6_address, mp->address,
1334           format_ethernet_address, mp->new_mac, sw_if_index);
1335 }
1336
1337 static void
1338 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1339 {
1340   /* JSON output not supported */
1341 }
1342
1343 static void
1344 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1345 {
1346   u32 n_macs = ntohl (mp->n_macs);
1347   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1348           ntohl (mp->pid), mp->client_index, n_macs);
1349   int i;
1350   for (i = 0; i < n_macs; i++)
1351     {
1352       vl_api_mac_entry_t *mac = &mp->mac[i];
1353       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1354               i + 1, ntohl (mac->sw_if_index),
1355               format_ethernet_address, mac->mac_addr, mac->action);
1356       if (i == 1000)
1357         break;
1358     }
1359 }
1360
1361 static void
1362 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1363 {
1364   /* JSON output not supported */
1365 }
1366
1367 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1368 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1369
1370 /*
1371  * Special-case: build the bridge domain table, maintain
1372  * the next bd id vbl.
1373  */
1374 static void vl_api_bridge_domain_details_t_handler
1375   (vl_api_bridge_domain_details_t * mp)
1376 {
1377   vat_main_t *vam = &vat_main;
1378   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1379   int i;
1380
1381   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1382          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1383
1384   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1385          ntohl (mp->bd_id), mp->learn, mp->forward,
1386          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1387
1388   if (n_sw_ifs)
1389     {
1390       vl_api_bridge_domain_sw_if_t *sw_ifs;
1391       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1392              "Interface Name");
1393
1394       sw_ifs = mp->sw_if_details;
1395       for (i = 0; i < n_sw_ifs; i++)
1396         {
1397           u8 *sw_if_name = 0;
1398           u32 sw_if_index;
1399           hash_pair_t *p;
1400
1401           sw_if_index = ntohl (sw_ifs->sw_if_index);
1402
1403           /* *INDENT-OFF* */
1404           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1405                              ({
1406                                if ((u32) p->value[0] == sw_if_index)
1407                                  {
1408                                    sw_if_name = (u8 *)(p->key);
1409                                    break;
1410                                  }
1411                              }));
1412           /* *INDENT-ON* */
1413           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1414                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1415                  "sw_if_index not found!");
1416
1417           sw_ifs++;
1418         }
1419     }
1420 }
1421
1422 static void vl_api_bridge_domain_details_t_handler_json
1423   (vl_api_bridge_domain_details_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   vat_json_node_t *node, *array = NULL;
1427   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1428
1429   if (VAT_JSON_ARRAY != vam->json_tree.type)
1430     {
1431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1432       vat_json_init_array (&vam->json_tree);
1433     }
1434   node = vat_json_array_add (&vam->json_tree);
1435
1436   vat_json_init_object (node);
1437   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1438   vat_json_object_add_uint (node, "flood", mp->flood);
1439   vat_json_object_add_uint (node, "forward", mp->forward);
1440   vat_json_object_add_uint (node, "learn", mp->learn);
1441   vat_json_object_add_uint (node, "bvi_sw_if_index",
1442                             ntohl (mp->bvi_sw_if_index));
1443   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1444   array = vat_json_object_add (node, "sw_if");
1445   vat_json_init_array (array);
1446
1447
1448
1449   if (n_sw_ifs)
1450     {
1451       vl_api_bridge_domain_sw_if_t *sw_ifs;
1452       int i;
1453
1454       sw_ifs = mp->sw_if_details;
1455       for (i = 0; i < n_sw_ifs; i++)
1456         {
1457           node = vat_json_array_add (array);
1458           vat_json_init_object (node);
1459           vat_json_object_add_uint (node, "sw_if_index",
1460                                     ntohl (sw_ifs->sw_if_index));
1461           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1462           sw_ifs++;
1463         }
1464     }
1465 }
1466
1467 static void vl_api_control_ping_reply_t_handler
1468   (vl_api_control_ping_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   i32 retval = ntohl (mp->retval);
1472   if (vam->async_mode)
1473     {
1474       vam->async_errors += (retval < 0);
1475     }
1476   else
1477     {
1478       vam->retval = retval;
1479       vam->result_ready = 1;
1480     }
1481   if (vam->socket_client_main)
1482     vam->socket_client_main->control_pings_outstanding--;
1483 }
1484
1485 static void vl_api_control_ping_reply_t_handler_json
1486   (vl_api_control_ping_reply_t * mp)
1487 {
1488   vat_main_t *vam = &vat_main;
1489   i32 retval = ntohl (mp->retval);
1490
1491   if (VAT_JSON_NONE != vam->json_tree.type)
1492     {
1493       vat_json_print (vam->ofp, &vam->json_tree);
1494       vat_json_free (&vam->json_tree);
1495       vam->json_tree.type = VAT_JSON_NONE;
1496     }
1497   else
1498     {
1499       /* just print [] */
1500       vat_json_init_array (&vam->json_tree);
1501       vat_json_print (vam->ofp, &vam->json_tree);
1502       vam->json_tree.type = VAT_JSON_NONE;
1503     }
1504
1505   vam->retval = retval;
1506   vam->result_ready = 1;
1507 }
1508
1509 static void
1510   vl_api_bridge_domain_set_mac_age_reply_t_handler
1511   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   i32 retval = ntohl (mp->retval);
1515   if (vam->async_mode)
1516     {
1517       vam->async_errors += (retval < 0);
1518     }
1519   else
1520     {
1521       vam->retval = retval;
1522       vam->result_ready = 1;
1523     }
1524 }
1525
1526 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1527   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1528 {
1529   vat_main_t *vam = &vat_main;
1530   vat_json_node_t node;
1531
1532   vat_json_init_object (&node);
1533   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1534
1535   vat_json_print (vam->ofp, &node);
1536   vat_json_free (&node);
1537
1538   vam->retval = ntohl (mp->retval);
1539   vam->result_ready = 1;
1540 }
1541
1542 static void
1543 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   i32 retval = ntohl (mp->retval);
1547   if (vam->async_mode)
1548     {
1549       vam->async_errors += (retval < 0);
1550     }
1551   else
1552     {
1553       vam->retval = retval;
1554       vam->result_ready = 1;
1555     }
1556 }
1557
1558 static void vl_api_l2_flags_reply_t_handler_json
1559   (vl_api_l2_flags_reply_t * mp)
1560 {
1561   vat_main_t *vam = &vat_main;
1562   vat_json_node_t node;
1563
1564   vat_json_init_object (&node);
1565   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1566   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1567                             ntohl (mp->resulting_feature_bitmap));
1568
1569   vat_json_print (vam->ofp, &node);
1570   vat_json_free (&node);
1571
1572   vam->retval = ntohl (mp->retval);
1573   vam->result_ready = 1;
1574 }
1575
1576 static void vl_api_bridge_flags_reply_t_handler
1577   (vl_api_bridge_flags_reply_t * mp)
1578 {
1579   vat_main_t *vam = &vat_main;
1580   i32 retval = ntohl (mp->retval);
1581   if (vam->async_mode)
1582     {
1583       vam->async_errors += (retval < 0);
1584     }
1585   else
1586     {
1587       vam->retval = retval;
1588       vam->result_ready = 1;
1589     }
1590 }
1591
1592 static void vl_api_bridge_flags_reply_t_handler_json
1593   (vl_api_bridge_flags_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   vat_json_node_t node;
1597
1598   vat_json_init_object (&node);
1599   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1600   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1601                             ntohl (mp->resulting_feature_bitmap));
1602
1603   vat_json_print (vam->ofp, &node);
1604   vat_json_free (&node);
1605
1606   vam->retval = ntohl (mp->retval);
1607   vam->result_ready = 1;
1608 }
1609
1610 static void vl_api_tap_connect_reply_t_handler
1611   (vl_api_tap_connect_reply_t * mp)
1612 {
1613   vat_main_t *vam = &vat_main;
1614   i32 retval = ntohl (mp->retval);
1615   if (vam->async_mode)
1616     {
1617       vam->async_errors += (retval < 0);
1618     }
1619   else
1620     {
1621       vam->retval = retval;
1622       vam->sw_if_index = ntohl (mp->sw_if_index);
1623       vam->result_ready = 1;
1624     }
1625
1626 }
1627
1628 static void vl_api_tap_connect_reply_t_handler_json
1629   (vl_api_tap_connect_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   vat_json_node_t node;
1633
1634   vat_json_init_object (&node);
1635   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1636   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1637
1638   vat_json_print (vam->ofp, &node);
1639   vat_json_free (&node);
1640
1641   vam->retval = ntohl (mp->retval);
1642   vam->result_ready = 1;
1643
1644 }
1645
1646 static void
1647 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1648 {
1649   vat_main_t *vam = &vat_main;
1650   i32 retval = ntohl (mp->retval);
1651   if (vam->async_mode)
1652     {
1653       vam->async_errors += (retval < 0);
1654     }
1655   else
1656     {
1657       vam->retval = retval;
1658       vam->sw_if_index = ntohl (mp->sw_if_index);
1659       vam->result_ready = 1;
1660     }
1661 }
1662
1663 static void vl_api_tap_modify_reply_t_handler_json
1664   (vl_api_tap_modify_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   vat_json_node_t node;
1668
1669   vat_json_init_object (&node);
1670   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1671   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1672
1673   vat_json_print (vam->ofp, &node);
1674   vat_json_free (&node);
1675
1676   vam->retval = ntohl (mp->retval);
1677   vam->result_ready = 1;
1678 }
1679
1680 static void
1681 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   i32 retval = ntohl (mp->retval);
1685   if (vam->async_mode)
1686     {
1687       vam->async_errors += (retval < 0);
1688     }
1689   else
1690     {
1691       vam->retval = retval;
1692       vam->result_ready = 1;
1693     }
1694 }
1695
1696 static void vl_api_tap_delete_reply_t_handler_json
1697   (vl_api_tap_delete_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   vat_json_node_t node;
1701
1702   vat_json_init_object (&node);
1703   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1704
1705   vat_json_print (vam->ofp, &node);
1706   vat_json_free (&node);
1707
1708   vam->retval = ntohl (mp->retval);
1709   vam->result_ready = 1;
1710 }
1711
1712 static void
1713 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1714 {
1715   vat_main_t *vam = &vat_main;
1716   i32 retval = ntohl (mp->retval);
1717   if (vam->async_mode)
1718     {
1719       vam->async_errors += (retval < 0);
1720     }
1721   else
1722     {
1723       vam->retval = retval;
1724       vam->sw_if_index = ntohl (mp->sw_if_index);
1725       vam->result_ready = 1;
1726     }
1727
1728 }
1729
1730 static void vl_api_tap_create_v2_reply_t_handler_json
1731   (vl_api_tap_create_v2_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   vat_json_node_t node;
1735
1736   vat_json_init_object (&node);
1737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1738   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1739
1740   vat_json_print (vam->ofp, &node);
1741   vat_json_free (&node);
1742
1743   vam->retval = ntohl (mp->retval);
1744   vam->result_ready = 1;
1745
1746 }
1747
1748 static void
1749 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1750 {
1751   vat_main_t *vam = &vat_main;
1752   i32 retval = ntohl (mp->retval);
1753   if (vam->async_mode)
1754     {
1755       vam->async_errors += (retval < 0);
1756     }
1757   else
1758     {
1759       vam->retval = retval;
1760       vam->result_ready = 1;
1761     }
1762 }
1763
1764 static void vl_api_tap_delete_v2_reply_t_handler_json
1765   (vl_api_tap_delete_v2_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   vat_json_node_t node;
1769
1770   vat_json_init_object (&node);
1771   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1772
1773   vat_json_print (vam->ofp, &node);
1774   vat_json_free (&node);
1775
1776   vam->retval = ntohl (mp->retval);
1777   vam->result_ready = 1;
1778 }
1779
1780 static void
1781 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   i32 retval = ntohl (mp->retval);
1785
1786   if (vam->async_mode)
1787     {
1788       vam->async_errors += (retval < 0);
1789     }
1790   else
1791     {
1792       vam->retval = retval;
1793       vam->sw_if_index = ntohl (mp->sw_if_index);
1794       vam->result_ready = 1;
1795     }
1796 }
1797
1798 static void vl_api_bond_create_reply_t_handler_json
1799   (vl_api_bond_create_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   vat_json_node_t node;
1803
1804   vat_json_init_object (&node);
1805   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1806   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1807
1808   vat_json_print (vam->ofp, &node);
1809   vat_json_free (&node);
1810
1811   vam->retval = ntohl (mp->retval);
1812   vam->result_ready = 1;
1813 }
1814
1815 static void
1816 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   i32 retval = ntohl (mp->retval);
1820
1821   if (vam->async_mode)
1822     {
1823       vam->async_errors += (retval < 0);
1824     }
1825   else
1826     {
1827       vam->retval = retval;
1828       vam->result_ready = 1;
1829     }
1830 }
1831
1832 static void vl_api_bond_delete_reply_t_handler_json
1833   (vl_api_bond_delete_reply_t * mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   vat_json_node_t node;
1837
1838   vat_json_init_object (&node);
1839   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1840
1841   vat_json_print (vam->ofp, &node);
1842   vat_json_free (&node);
1843
1844   vam->retval = ntohl (mp->retval);
1845   vam->result_ready = 1;
1846 }
1847
1848 static void
1849 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   i32 retval = ntohl (mp->retval);
1853
1854   if (vam->async_mode)
1855     {
1856       vam->async_errors += (retval < 0);
1857     }
1858   else
1859     {
1860       vam->retval = retval;
1861       vam->result_ready = 1;
1862     }
1863 }
1864
1865 static void vl_api_bond_enslave_reply_t_handler_json
1866   (vl_api_bond_enslave_reply_t * mp)
1867 {
1868   vat_main_t *vam = &vat_main;
1869   vat_json_node_t node;
1870
1871   vat_json_init_object (&node);
1872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1873
1874   vat_json_print (vam->ofp, &node);
1875   vat_json_free (&node);
1876
1877   vam->retval = ntohl (mp->retval);
1878   vam->result_ready = 1;
1879 }
1880
1881 static void
1882 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1883                                           mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   i32 retval = ntohl (mp->retval);
1887
1888   if (vam->async_mode)
1889     {
1890       vam->async_errors += (retval < 0);
1891     }
1892   else
1893     {
1894       vam->retval = retval;
1895       vam->result_ready = 1;
1896     }
1897 }
1898
1899 static void vl_api_bond_detach_slave_reply_t_handler_json
1900   (vl_api_bond_detach_slave_reply_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   vat_json_node_t node;
1904
1905   vat_json_init_object (&node);
1906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1907
1908   vat_json_print (vam->ofp, &node);
1909   vat_json_free (&node);
1910
1911   vam->retval = ntohl (mp->retval);
1912   vam->result_ready = 1;
1913 }
1914
1915 static void vl_api_sw_interface_bond_details_t_handler
1916   (vl_api_sw_interface_bond_details_t * mp)
1917 {
1918   vat_main_t *vam = &vat_main;
1919
1920   print (vam->ofp,
1921          "%-16s %-12d %-12U %-13U %-14u %-14u",
1922          mp->interface_name, ntohl (mp->sw_if_index),
1923          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1924          ntohl (mp->active_slaves), ntohl (mp->slaves));
1925 }
1926
1927 static void vl_api_sw_interface_bond_details_t_handler_json
1928   (vl_api_sw_interface_bond_details_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931   vat_json_node_t *node = NULL;
1932
1933   if (VAT_JSON_ARRAY != vam->json_tree.type)
1934     {
1935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1936       vat_json_init_array (&vam->json_tree);
1937     }
1938   node = vat_json_array_add (&vam->json_tree);
1939
1940   vat_json_init_object (node);
1941   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1942   vat_json_object_add_string_copy (node, "interface_name",
1943                                    mp->interface_name);
1944   vat_json_object_add_uint (node, "mode", mp->mode);
1945   vat_json_object_add_uint (node, "load_balance", mp->lb);
1946   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1947   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1948 }
1949
1950 static int
1951 api_sw_interface_bond_dump (vat_main_t * vam)
1952 {
1953   vl_api_sw_interface_bond_dump_t *mp;
1954   vl_api_control_ping_t *mp_ping;
1955   int ret;
1956
1957   print (vam->ofp,
1958          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1959          "interface name", "sw_if_index", "mode", "load balance",
1960          "active slaves", "slaves");
1961
1962   /* Get list of bond interfaces */
1963   M (SW_INTERFACE_BOND_DUMP, mp);
1964   S (mp);
1965
1966   /* Use a control ping for synchronization */
1967   MPING (CONTROL_PING, mp_ping);
1968   S (mp_ping);
1969
1970   W (ret);
1971   return ret;
1972 }
1973
1974 static void vl_api_sw_interface_slave_details_t_handler
1975   (vl_api_sw_interface_slave_details_t * mp)
1976 {
1977   vat_main_t *vam = &vat_main;
1978
1979   print (vam->ofp,
1980          "%-25s %-12d %-12d %d", mp->interface_name,
1981          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1982 }
1983
1984 static void vl_api_sw_interface_slave_details_t_handler_json
1985   (vl_api_sw_interface_slave_details_t * mp)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   vat_json_node_t *node = NULL;
1989
1990   if (VAT_JSON_ARRAY != vam->json_tree.type)
1991     {
1992       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1993       vat_json_init_array (&vam->json_tree);
1994     }
1995   node = vat_json_array_add (&vam->json_tree);
1996
1997   vat_json_init_object (node);
1998   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1999   vat_json_object_add_string_copy (node, "interface_name",
2000                                    mp->interface_name);
2001   vat_json_object_add_uint (node, "passive", mp->is_passive);
2002   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2003 }
2004
2005 static int
2006 api_sw_interface_slave_dump (vat_main_t * vam)
2007 {
2008   unformat_input_t *i = vam->input;
2009   vl_api_sw_interface_slave_dump_t *mp;
2010   vl_api_control_ping_t *mp_ping;
2011   u32 sw_if_index = ~0;
2012   u8 sw_if_index_set = 0;
2013   int ret;
2014
2015   /* Parse args required to build the message */
2016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2017     {
2018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2019         sw_if_index_set = 1;
2020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2021         sw_if_index_set = 1;
2022       else
2023         break;
2024     }
2025
2026   if (sw_if_index_set == 0)
2027     {
2028       errmsg ("missing vpp interface name. ");
2029       return -99;
2030     }
2031
2032   print (vam->ofp,
2033          "\n%-25s %-12s %-12s %s",
2034          "slave interface name", "sw_if_index", "passive", "long_timeout");
2035
2036   /* Get list of bond interfaces */
2037   M (SW_INTERFACE_SLAVE_DUMP, mp);
2038   mp->sw_if_index = ntohl (sw_if_index);
2039   S (mp);
2040
2041   /* Use a control ping for synchronization */
2042   MPING (CONTROL_PING, mp_ping);
2043   S (mp_ping);
2044
2045   W (ret);
2046   return ret;
2047 }
2048
2049 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2050   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2051 {
2052   vat_main_t *vam = &vat_main;
2053   i32 retval = ntohl (mp->retval);
2054   if (vam->async_mode)
2055     {
2056       vam->async_errors += (retval < 0);
2057     }
2058   else
2059     {
2060       vam->retval = retval;
2061       vam->result_ready = 1;
2062     }
2063 }
2064
2065 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2066   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2067 {
2068   vat_main_t *vam = &vat_main;
2069   vat_json_node_t node;
2070
2071   vat_json_init_object (&node);
2072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2074                             ntohl (mp->sw_if_index));
2075
2076   vat_json_print (vam->ofp, &node);
2077   vat_json_free (&node);
2078
2079   vam->retval = ntohl (mp->retval);
2080   vam->result_ready = 1;
2081 }
2082
2083 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2084   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2085 {
2086   vat_main_t *vam = &vat_main;
2087   i32 retval = ntohl (mp->retval);
2088   if (vam->async_mode)
2089     {
2090       vam->async_errors += (retval < 0);
2091     }
2092   else
2093     {
2094       vam->retval = retval;
2095       vam->sw_if_index = ntohl (mp->sw_if_index);
2096       vam->result_ready = 1;
2097     }
2098 }
2099
2100 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2101   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2102 {
2103   vat_main_t *vam = &vat_main;
2104   vat_json_node_t node;
2105
2106   vat_json_init_object (&node);
2107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2108   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2109
2110   vat_json_print (vam->ofp, &node);
2111   vat_json_free (&node);
2112
2113   vam->retval = ntohl (mp->retval);
2114   vam->result_ready = 1;
2115 }
2116
2117 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2118   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2119 {
2120   vat_main_t *vam = &vat_main;
2121   i32 retval = ntohl (mp->retval);
2122   if (vam->async_mode)
2123     {
2124       vam->async_errors += (retval < 0);
2125     }
2126   else
2127     {
2128       vam->retval = retval;
2129       vam->result_ready = 1;
2130     }
2131 }
2132
2133 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2134   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2135 {
2136   vat_main_t *vam = &vat_main;
2137   vat_json_node_t node;
2138
2139   vat_json_init_object (&node);
2140   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2141   vat_json_object_add_uint (&node, "fwd_entry_index",
2142                             clib_net_to_host_u32 (mp->fwd_entry_index));
2143
2144   vat_json_print (vam->ofp, &node);
2145   vat_json_free (&node);
2146
2147   vam->retval = ntohl (mp->retval);
2148   vam->result_ready = 1;
2149 }
2150
2151 u8 *
2152 format_lisp_transport_protocol (u8 * s, va_list * args)
2153 {
2154   u32 proto = va_arg (*args, u32);
2155
2156   switch (proto)
2157     {
2158     case 1:
2159       return format (s, "udp");
2160     case 2:
2161       return format (s, "api");
2162     default:
2163       return 0;
2164     }
2165   return 0;
2166 }
2167
2168 static void vl_api_one_get_transport_protocol_reply_t_handler
2169   (vl_api_one_get_transport_protocol_reply_t * mp)
2170 {
2171   vat_main_t *vam = &vat_main;
2172   i32 retval = ntohl (mp->retval);
2173   if (vam->async_mode)
2174     {
2175       vam->async_errors += (retval < 0);
2176     }
2177   else
2178     {
2179       u32 proto = mp->protocol;
2180       print (vam->ofp, "Transport protocol: %U",
2181              format_lisp_transport_protocol, proto);
2182       vam->retval = retval;
2183       vam->result_ready = 1;
2184     }
2185 }
2186
2187 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2188   (vl_api_one_get_transport_protocol_reply_t * mp)
2189 {
2190   vat_main_t *vam = &vat_main;
2191   vat_json_node_t node;
2192   u8 *s;
2193
2194   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2195   vec_add1 (s, 0);
2196
2197   vat_json_init_object (&node);
2198   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2199   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2200
2201   vec_free (s);
2202   vat_json_print (vam->ofp, &node);
2203   vat_json_free (&node);
2204
2205   vam->retval = ntohl (mp->retval);
2206   vam->result_ready = 1;
2207 }
2208
2209 static void vl_api_one_add_del_locator_set_reply_t_handler
2210   (vl_api_one_add_del_locator_set_reply_t * mp)
2211 {
2212   vat_main_t *vam = &vat_main;
2213   i32 retval = ntohl (mp->retval);
2214   if (vam->async_mode)
2215     {
2216       vam->async_errors += (retval < 0);
2217     }
2218   else
2219     {
2220       vam->retval = retval;
2221       vam->result_ready = 1;
2222     }
2223 }
2224
2225 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2226   (vl_api_one_add_del_locator_set_reply_t * mp)
2227 {
2228   vat_main_t *vam = &vat_main;
2229   vat_json_node_t node;
2230
2231   vat_json_init_object (&node);
2232   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2233   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2234
2235   vat_json_print (vam->ofp, &node);
2236   vat_json_free (&node);
2237
2238   vam->retval = ntohl (mp->retval);
2239   vam->result_ready = 1;
2240 }
2241
2242 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2243   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2244 {
2245   vat_main_t *vam = &vat_main;
2246   i32 retval = ntohl (mp->retval);
2247   if (vam->async_mode)
2248     {
2249       vam->async_errors += (retval < 0);
2250     }
2251   else
2252     {
2253       vam->retval = retval;
2254       vam->sw_if_index = ntohl (mp->sw_if_index);
2255       vam->result_ready = 1;
2256     }
2257   vam->regenerate_interface_table = 1;
2258 }
2259
2260 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2261   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2262 {
2263   vat_main_t *vam = &vat_main;
2264   vat_json_node_t node;
2265
2266   vat_json_init_object (&node);
2267   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2268   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2269
2270   vat_json_print (vam->ofp, &node);
2271   vat_json_free (&node);
2272
2273   vam->retval = ntohl (mp->retval);
2274   vam->result_ready = 1;
2275 }
2276
2277 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2278   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2279 {
2280   vat_main_t *vam = &vat_main;
2281   i32 retval = ntohl (mp->retval);
2282   if (vam->async_mode)
2283     {
2284       vam->async_errors += (retval < 0);
2285     }
2286   else
2287     {
2288       vam->retval = retval;
2289       vam->sw_if_index = ntohl (mp->sw_if_index);
2290       vam->result_ready = 1;
2291     }
2292 }
2293
2294 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2295   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2296 {
2297   vat_main_t *vam = &vat_main;
2298   vat_json_node_t node;
2299
2300   vat_json_init_object (&node);
2301   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2302   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2303
2304   vat_json_print (vam->ofp, &node);
2305   vat_json_free (&node);
2306
2307   vam->retval = ntohl (mp->retval);
2308   vam->result_ready = 1;
2309 }
2310
2311 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2312   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2313 {
2314   vat_main_t *vam = &vat_main;
2315   i32 retval = ntohl (mp->retval);
2316   if (vam->async_mode)
2317     {
2318       vam->async_errors += (retval < 0);
2319     }
2320   else
2321     {
2322       vam->retval = retval;
2323       vam->sw_if_index = ntohl (mp->sw_if_index);
2324       vam->result_ready = 1;
2325     }
2326   vam->regenerate_interface_table = 1;
2327 }
2328
2329 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2330   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   vat_json_node_t node;
2334
2335   vat_json_init_object (&node);
2336   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2337   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2338
2339   vat_json_print (vam->ofp, &node);
2340   vat_json_free (&node);
2341
2342   vam->retval = ntohl (mp->retval);
2343   vam->result_ready = 1;
2344 }
2345
2346 static void vl_api_gre_add_del_tunnel_reply_t_handler
2347   (vl_api_gre_add_del_tunnel_reply_t * mp)
2348 {
2349   vat_main_t *vam = &vat_main;
2350   i32 retval = ntohl (mp->retval);
2351   if (vam->async_mode)
2352     {
2353       vam->async_errors += (retval < 0);
2354     }
2355   else
2356     {
2357       vam->retval = retval;
2358       vam->sw_if_index = ntohl (mp->sw_if_index);
2359       vam->result_ready = 1;
2360     }
2361 }
2362
2363 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2364   (vl_api_gre_add_del_tunnel_reply_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   vat_json_node_t node;
2368
2369   vat_json_init_object (&node);
2370   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2371   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2372
2373   vat_json_print (vam->ofp, &node);
2374   vat_json_free (&node);
2375
2376   vam->retval = ntohl (mp->retval);
2377   vam->result_ready = 1;
2378 }
2379
2380 static void vl_api_create_vhost_user_if_reply_t_handler
2381   (vl_api_create_vhost_user_if_reply_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   i32 retval = ntohl (mp->retval);
2385   if (vam->async_mode)
2386     {
2387       vam->async_errors += (retval < 0);
2388     }
2389   else
2390     {
2391       vam->retval = retval;
2392       vam->sw_if_index = ntohl (mp->sw_if_index);
2393       vam->result_ready = 1;
2394     }
2395   vam->regenerate_interface_table = 1;
2396 }
2397
2398 static void vl_api_create_vhost_user_if_reply_t_handler_json
2399   (vl_api_create_vhost_user_if_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   vat_json_node_t node;
2403
2404   vat_json_init_object (&node);
2405   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2406   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2407
2408   vat_json_print (vam->ofp, &node);
2409   vat_json_free (&node);
2410
2411   vam->retval = ntohl (mp->retval);
2412   vam->result_ready = 1;
2413 }
2414
2415 static void vl_api_dns_resolve_name_reply_t_handler
2416   (vl_api_dns_resolve_name_reply_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419   i32 retval = ntohl (mp->retval);
2420   if (vam->async_mode)
2421     {
2422       vam->async_errors += (retval < 0);
2423     }
2424   else
2425     {
2426       vam->retval = retval;
2427       vam->result_ready = 1;
2428
2429       if (retval == 0)
2430         {
2431           if (mp->ip4_set)
2432             clib_warning ("ip4 address %U", format_ip4_address,
2433                           (ip4_address_t *) mp->ip4_address);
2434           if (mp->ip6_set)
2435             clib_warning ("ip6 address %U", format_ip6_address,
2436                           (ip6_address_t *) mp->ip6_address);
2437         }
2438       else
2439         clib_warning ("retval %d", retval);
2440     }
2441 }
2442
2443 static void vl_api_dns_resolve_name_reply_t_handler_json
2444   (vl_api_dns_resolve_name_reply_t * mp)
2445 {
2446   clib_warning ("not implemented");
2447 }
2448
2449 static void vl_api_dns_resolve_ip_reply_t_handler
2450   (vl_api_dns_resolve_ip_reply_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   i32 retval = ntohl (mp->retval);
2454   if (vam->async_mode)
2455     {
2456       vam->async_errors += (retval < 0);
2457     }
2458   else
2459     {
2460       vam->retval = retval;
2461       vam->result_ready = 1;
2462
2463       if (retval == 0)
2464         {
2465           clib_warning ("canonical name %s", mp->name);
2466         }
2467       else
2468         clib_warning ("retval %d", retval);
2469     }
2470 }
2471
2472 static void vl_api_dns_resolve_ip_reply_t_handler_json
2473   (vl_api_dns_resolve_ip_reply_t * mp)
2474 {
2475   clib_warning ("not implemented");
2476 }
2477
2478
2479 static void vl_api_ip_address_details_t_handler
2480   (vl_api_ip_address_details_t * mp)
2481 {
2482   vat_main_t *vam = &vat_main;
2483   static ip_address_details_t empty_ip_address_details = { {0} };
2484   ip_address_details_t *address = NULL;
2485   ip_details_t *current_ip_details = NULL;
2486   ip_details_t *details = NULL;
2487
2488   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2489
2490   if (!details || vam->current_sw_if_index >= vec_len (details)
2491       || !details[vam->current_sw_if_index].present)
2492     {
2493       errmsg ("ip address details arrived but not stored");
2494       errmsg ("ip_dump should be called first");
2495       return;
2496     }
2497
2498   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2499
2500 #define addresses (current_ip_details->addr)
2501
2502   vec_validate_init_empty (addresses, vec_len (addresses),
2503                            empty_ip_address_details);
2504
2505   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2506
2507   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2508   address->prefix_length = mp->prefix_length;
2509 #undef addresses
2510 }
2511
2512 static void vl_api_ip_address_details_t_handler_json
2513   (vl_api_ip_address_details_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   vat_json_node_t *node = NULL;
2517   struct in6_addr ip6;
2518   struct in_addr ip4;
2519
2520   if (VAT_JSON_ARRAY != vam->json_tree.type)
2521     {
2522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2523       vat_json_init_array (&vam->json_tree);
2524     }
2525   node = vat_json_array_add (&vam->json_tree);
2526
2527   vat_json_init_object (node);
2528   if (vam->is_ipv6)
2529     {
2530       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2531       vat_json_object_add_ip6 (node, "ip", ip6);
2532     }
2533   else
2534     {
2535       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2536       vat_json_object_add_ip4 (node, "ip", ip4);
2537     }
2538   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2539 }
2540
2541 static void
2542 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2543 {
2544   vat_main_t *vam = &vat_main;
2545   static ip_details_t empty_ip_details = { 0 };
2546   ip_details_t *ip = NULL;
2547   u32 sw_if_index = ~0;
2548
2549   sw_if_index = ntohl (mp->sw_if_index);
2550
2551   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2552                            sw_if_index, empty_ip_details);
2553
2554   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2555                          sw_if_index);
2556
2557   ip->present = 1;
2558 }
2559
2560 static void
2561 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2562 {
2563   vat_main_t *vam = &vat_main;
2564
2565   if (VAT_JSON_ARRAY != vam->json_tree.type)
2566     {
2567       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2568       vat_json_init_array (&vam->json_tree);
2569     }
2570   vat_json_array_add_uint (&vam->json_tree,
2571                            clib_net_to_host_u32 (mp->sw_if_index));
2572 }
2573
2574 static void vl_api_map_domain_details_t_handler_json
2575   (vl_api_map_domain_details_t * mp)
2576 {
2577   vat_json_node_t *node = NULL;
2578   vat_main_t *vam = &vat_main;
2579   struct in6_addr ip6;
2580   struct in_addr ip4;
2581
2582   if (VAT_JSON_ARRAY != vam->json_tree.type)
2583     {
2584       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2585       vat_json_init_array (&vam->json_tree);
2586     }
2587
2588   node = vat_json_array_add (&vam->json_tree);
2589   vat_json_init_object (node);
2590
2591   vat_json_object_add_uint (node, "domain_index",
2592                             clib_net_to_host_u32 (mp->domain_index));
2593   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2594   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2595   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2596   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2597   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2598   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2599   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2600   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2601   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2602   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2603   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2604   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2605   vat_json_object_add_uint (node, "flags", mp->flags);
2606   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2607   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2608 }
2609
2610 static void vl_api_map_domain_details_t_handler
2611   (vl_api_map_domain_details_t * mp)
2612 {
2613   vat_main_t *vam = &vat_main;
2614
2615   if (mp->is_translation)
2616     {
2617       print (vam->ofp,
2618              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2619              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2620              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2621              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2622              clib_net_to_host_u32 (mp->domain_index));
2623     }
2624   else
2625     {
2626       print (vam->ofp,
2627              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2628              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2629              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2630              format_ip6_address, mp->ip6_src,
2631              clib_net_to_host_u32 (mp->domain_index));
2632     }
2633   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2634          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2635          mp->is_translation ? "map-t" : "");
2636 }
2637
2638 static void vl_api_map_rule_details_t_handler_json
2639   (vl_api_map_rule_details_t * mp)
2640 {
2641   struct in6_addr ip6;
2642   vat_json_node_t *node = NULL;
2643   vat_main_t *vam = &vat_main;
2644
2645   if (VAT_JSON_ARRAY != vam->json_tree.type)
2646     {
2647       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2648       vat_json_init_array (&vam->json_tree);
2649     }
2650
2651   node = vat_json_array_add (&vam->json_tree);
2652   vat_json_init_object (node);
2653
2654   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2655   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2656   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2657 }
2658
2659 static void
2660 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2661 {
2662   vat_main_t *vam = &vat_main;
2663   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2664          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2665 }
2666
2667 static void
2668 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2669 {
2670   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2671           "router_addr %U host_mac %U",
2672           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2673           mp->lease.hostname,
2674           format_ip4_address, &mp->lease.host_address,
2675           format_ip4_address, &mp->lease.router_address,
2676           format_ethernet_address, mp->lease.host_mac);
2677 }
2678
2679 static void vl_api_dhcp_compl_event_t_handler_json
2680   (vl_api_dhcp_compl_event_t * mp)
2681 {
2682   /* JSON output not supported */
2683 }
2684
2685 static void
2686 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2687                               u32 counter)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   static u64 default_counter = 0;
2691
2692   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2693                            NULL);
2694   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2695                            sw_if_index, default_counter);
2696   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2697 }
2698
2699 static void
2700 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2701                                 interface_counter_t counter)
2702 {
2703   vat_main_t *vam = &vat_main;
2704   static interface_counter_t default_counter = { 0, };
2705
2706   vec_validate_init_empty (vam->combined_interface_counters,
2707                            vnet_counter_type, NULL);
2708   vec_validate_init_empty (vam->combined_interface_counters
2709                            [vnet_counter_type], sw_if_index, default_counter);
2710   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2711 }
2712
2713 static void vl_api_vnet_interface_simple_counters_t_handler
2714   (vl_api_vnet_interface_simple_counters_t * mp)
2715 {
2716   /* not supported */
2717 }
2718
2719 static void vl_api_vnet_interface_combined_counters_t_handler
2720   (vl_api_vnet_interface_combined_counters_t * mp)
2721 {
2722   /* not supported */
2723 }
2724
2725 static void vl_api_vnet_interface_simple_counters_t_handler_json
2726   (vl_api_vnet_interface_simple_counters_t * mp)
2727 {
2728   u64 *v_packets;
2729   u64 packets;
2730   u32 count;
2731   u32 first_sw_if_index;
2732   int i;
2733
2734   count = ntohl (mp->count);
2735   first_sw_if_index = ntohl (mp->first_sw_if_index);
2736
2737   v_packets = (u64 *) & mp->data;
2738   for (i = 0; i < count; i++)
2739     {
2740       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2741       set_simple_interface_counter (mp->vnet_counter_type,
2742                                     first_sw_if_index + i, packets);
2743       v_packets++;
2744     }
2745 }
2746
2747 static void vl_api_vnet_interface_combined_counters_t_handler_json
2748   (vl_api_vnet_interface_combined_counters_t * mp)
2749 {
2750   interface_counter_t counter;
2751   vlib_counter_t *v;
2752   u32 first_sw_if_index;
2753   int i;
2754   u32 count;
2755
2756   count = ntohl (mp->count);
2757   first_sw_if_index = ntohl (mp->first_sw_if_index);
2758
2759   v = (vlib_counter_t *) & mp->data;
2760   for (i = 0; i < count; i++)
2761     {
2762       counter.packets =
2763         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2764       counter.bytes =
2765         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2766       set_combined_interface_counter (mp->vnet_counter_type,
2767                                       first_sw_if_index + i, counter);
2768       v++;
2769     }
2770 }
2771
2772 static u32
2773 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2774 {
2775   vat_main_t *vam = &vat_main;
2776   u32 i;
2777
2778   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2779     {
2780       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2781         {
2782           return i;
2783         }
2784     }
2785   return ~0;
2786 }
2787
2788 static u32
2789 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   u32 i;
2793
2794   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2795     {
2796       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2797         {
2798           return i;
2799         }
2800     }
2801   return ~0;
2802 }
2803
2804 static void vl_api_vnet_ip4_fib_counters_t_handler
2805   (vl_api_vnet_ip4_fib_counters_t * mp)
2806 {
2807   /* not supported */
2808 }
2809
2810 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2811   (vl_api_vnet_ip4_fib_counters_t * mp)
2812 {
2813   vat_main_t *vam = &vat_main;
2814   vl_api_ip4_fib_counter_t *v;
2815   ip4_fib_counter_t *counter;
2816   struct in_addr ip4;
2817   u32 vrf_id;
2818   u32 vrf_index;
2819   u32 count;
2820   int i;
2821
2822   vrf_id = ntohl (mp->vrf_id);
2823   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2824   if (~0 == vrf_index)
2825     {
2826       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2827       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2828       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2829       vec_validate (vam->ip4_fib_counters, vrf_index);
2830       vam->ip4_fib_counters[vrf_index] = NULL;
2831     }
2832
2833   vec_free (vam->ip4_fib_counters[vrf_index]);
2834   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2835   count = ntohl (mp->count);
2836   for (i = 0; i < count; i++)
2837     {
2838       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2839       counter = &vam->ip4_fib_counters[vrf_index][i];
2840       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2841       counter->address = ip4;
2842       counter->address_length = v->address_length;
2843       counter->packets = clib_net_to_host_u64 (v->packets);
2844       counter->bytes = clib_net_to_host_u64 (v->bytes);
2845       v++;
2846     }
2847 }
2848
2849 static void vl_api_vnet_ip4_nbr_counters_t_handler
2850   (vl_api_vnet_ip4_nbr_counters_t * mp)
2851 {
2852   /* not supported */
2853 }
2854
2855 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2856   (vl_api_vnet_ip4_nbr_counters_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   vl_api_ip4_nbr_counter_t *v;
2860   ip4_nbr_counter_t *counter;
2861   u32 sw_if_index;
2862   u32 count;
2863   int i;
2864
2865   sw_if_index = ntohl (mp->sw_if_index);
2866   count = ntohl (mp->count);
2867   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2868
2869   if (mp->begin)
2870     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2871
2872   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2873   for (i = 0; i < count; i++)
2874     {
2875       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2876       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2877       counter->address.s_addr = v->address;
2878       counter->packets = clib_net_to_host_u64 (v->packets);
2879       counter->bytes = clib_net_to_host_u64 (v->bytes);
2880       counter->linkt = v->link_type;
2881       v++;
2882     }
2883 }
2884
2885 static void vl_api_vnet_ip6_fib_counters_t_handler
2886   (vl_api_vnet_ip6_fib_counters_t * mp)
2887 {
2888   /* not supported */
2889 }
2890
2891 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2892   (vl_api_vnet_ip6_fib_counters_t * mp)
2893 {
2894   vat_main_t *vam = &vat_main;
2895   vl_api_ip6_fib_counter_t *v;
2896   ip6_fib_counter_t *counter;
2897   struct in6_addr ip6;
2898   u32 vrf_id;
2899   u32 vrf_index;
2900   u32 count;
2901   int i;
2902
2903   vrf_id = ntohl (mp->vrf_id);
2904   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2905   if (~0 == vrf_index)
2906     {
2907       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2908       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2909       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2910       vec_validate (vam->ip6_fib_counters, vrf_index);
2911       vam->ip6_fib_counters[vrf_index] = NULL;
2912     }
2913
2914   vec_free (vam->ip6_fib_counters[vrf_index]);
2915   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2916   count = ntohl (mp->count);
2917   for (i = 0; i < count; i++)
2918     {
2919       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2920       counter = &vam->ip6_fib_counters[vrf_index][i];
2921       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2922       counter->address = ip6;
2923       counter->address_length = v->address_length;
2924       counter->packets = clib_net_to_host_u64 (v->packets);
2925       counter->bytes = clib_net_to_host_u64 (v->bytes);
2926       v++;
2927     }
2928 }
2929
2930 static void vl_api_vnet_ip6_nbr_counters_t_handler
2931   (vl_api_vnet_ip6_nbr_counters_t * mp)
2932 {
2933   /* not supported */
2934 }
2935
2936 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2937   (vl_api_vnet_ip6_nbr_counters_t * mp)
2938 {
2939   vat_main_t *vam = &vat_main;
2940   vl_api_ip6_nbr_counter_t *v;
2941   ip6_nbr_counter_t *counter;
2942   struct in6_addr ip6;
2943   u32 sw_if_index;
2944   u32 count;
2945   int i;
2946
2947   sw_if_index = ntohl (mp->sw_if_index);
2948   count = ntohl (mp->count);
2949   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2950
2951   if (mp->begin)
2952     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2953
2954   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2955   for (i = 0; i < count; i++)
2956     {
2957       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2958       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2959       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2960       counter->address = ip6;
2961       counter->packets = clib_net_to_host_u64 (v->packets);
2962       counter->bytes = clib_net_to_host_u64 (v->bytes);
2963       v++;
2964     }
2965 }
2966
2967 static void vl_api_get_first_msg_id_reply_t_handler
2968   (vl_api_get_first_msg_id_reply_t * mp)
2969 {
2970   vat_main_t *vam = &vat_main;
2971   i32 retval = ntohl (mp->retval);
2972
2973   if (vam->async_mode)
2974     {
2975       vam->async_errors += (retval < 0);
2976     }
2977   else
2978     {
2979       vam->retval = retval;
2980       vam->result_ready = 1;
2981     }
2982   if (retval >= 0)
2983     {
2984       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2985     }
2986 }
2987
2988 static void vl_api_get_first_msg_id_reply_t_handler_json
2989   (vl_api_get_first_msg_id_reply_t * mp)
2990 {
2991   vat_main_t *vam = &vat_main;
2992   vat_json_node_t node;
2993
2994   vat_json_init_object (&node);
2995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2996   vat_json_object_add_uint (&node, "first_msg_id",
2997                             (uint) ntohs (mp->first_msg_id));
2998
2999   vat_json_print (vam->ofp, &node);
3000   vat_json_free (&node);
3001
3002   vam->retval = ntohl (mp->retval);
3003   vam->result_ready = 1;
3004 }
3005
3006 static void vl_api_get_node_graph_reply_t_handler
3007   (vl_api_get_node_graph_reply_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   api_main_t *am = &api_main;
3011   i32 retval = ntohl (mp->retval);
3012   u8 *pvt_copy, *reply;
3013   void *oldheap;
3014   vlib_node_t *node;
3015   int i;
3016
3017   if (vam->async_mode)
3018     {
3019       vam->async_errors += (retval < 0);
3020     }
3021   else
3022     {
3023       vam->retval = retval;
3024       vam->result_ready = 1;
3025     }
3026
3027   /* "Should never happen..." */
3028   if (retval != 0)
3029     return;
3030
3031   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3032   pvt_copy = vec_dup (reply);
3033
3034   /* Toss the shared-memory original... */
3035   pthread_mutex_lock (&am->vlib_rp->mutex);
3036   oldheap = svm_push_data_heap (am->vlib_rp);
3037
3038   vec_free (reply);
3039
3040   svm_pop_heap (oldheap);
3041   pthread_mutex_unlock (&am->vlib_rp->mutex);
3042
3043   if (vam->graph_nodes)
3044     {
3045       hash_free (vam->graph_node_index_by_name);
3046
3047       for (i = 0; i < vec_len (vam->graph_nodes); i++)
3048         {
3049           node = vam->graph_nodes[i];
3050           vec_free (node->name);
3051           vec_free (node->next_nodes);
3052           vec_free (node);
3053         }
3054       vec_free (vam->graph_nodes);
3055     }
3056
3057   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3058   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3059   vec_free (pvt_copy);
3060
3061   for (i = 0; i < vec_len (vam->graph_nodes); i++)
3062     {
3063       node = vam->graph_nodes[i];
3064       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3065     }
3066 }
3067
3068 static void vl_api_get_node_graph_reply_t_handler_json
3069   (vl_api_get_node_graph_reply_t * mp)
3070 {
3071   vat_main_t *vam = &vat_main;
3072   api_main_t *am = &api_main;
3073   void *oldheap;
3074   vat_json_node_t node;
3075   u8 *reply;
3076
3077   /* $$$$ make this real? */
3078   vat_json_init_object (&node);
3079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3080   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3081
3082   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3083
3084   /* Toss the shared-memory original... */
3085   pthread_mutex_lock (&am->vlib_rp->mutex);
3086   oldheap = svm_push_data_heap (am->vlib_rp);
3087
3088   vec_free (reply);
3089
3090   svm_pop_heap (oldheap);
3091   pthread_mutex_unlock (&am->vlib_rp->mutex);
3092
3093   vat_json_print (vam->ofp, &node);
3094   vat_json_free (&node);
3095
3096   vam->retval = ntohl (mp->retval);
3097   vam->result_ready = 1;
3098 }
3099
3100 static void
3101 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3102 {
3103   vat_main_t *vam = &vat_main;
3104   u8 *s = 0;
3105
3106   if (mp->local)
3107     {
3108       s = format (s, "%=16d%=16d%=16d",
3109                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3110     }
3111   else
3112     {
3113       s = format (s, "%=16U%=16d%=16d",
3114                   mp->is_ipv6 ? format_ip6_address :
3115                   format_ip4_address,
3116                   mp->ip_address, mp->priority, mp->weight);
3117     }
3118
3119   print (vam->ofp, "%v", s);
3120   vec_free (s);
3121 }
3122
3123 static void
3124 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3125 {
3126   vat_main_t *vam = &vat_main;
3127   vat_json_node_t *node = NULL;
3128   struct in6_addr ip6;
3129   struct in_addr ip4;
3130
3131   if (VAT_JSON_ARRAY != vam->json_tree.type)
3132     {
3133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3134       vat_json_init_array (&vam->json_tree);
3135     }
3136   node = vat_json_array_add (&vam->json_tree);
3137   vat_json_init_object (node);
3138
3139   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3140   vat_json_object_add_uint (node, "priority", mp->priority);
3141   vat_json_object_add_uint (node, "weight", mp->weight);
3142
3143   if (mp->local)
3144     vat_json_object_add_uint (node, "sw_if_index",
3145                               clib_net_to_host_u32 (mp->sw_if_index));
3146   else
3147     {
3148       if (mp->is_ipv6)
3149         {
3150           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3151           vat_json_object_add_ip6 (node, "address", ip6);
3152         }
3153       else
3154         {
3155           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3156           vat_json_object_add_ip4 (node, "address", ip4);
3157         }
3158     }
3159 }
3160
3161 static void
3162 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3163                                           mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166   u8 *ls_name = 0;
3167
3168   ls_name = format (0, "%s", mp->ls_name);
3169
3170   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3171          ls_name);
3172   vec_free (ls_name);
3173 }
3174
3175 static void
3176   vl_api_one_locator_set_details_t_handler_json
3177   (vl_api_one_locator_set_details_t * mp)
3178 {
3179   vat_main_t *vam = &vat_main;
3180   vat_json_node_t *node = 0;
3181   u8 *ls_name = 0;
3182
3183   ls_name = format (0, "%s", mp->ls_name);
3184   vec_add1 (ls_name, 0);
3185
3186   if (VAT_JSON_ARRAY != vam->json_tree.type)
3187     {
3188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3189       vat_json_init_array (&vam->json_tree);
3190     }
3191   node = vat_json_array_add (&vam->json_tree);
3192
3193   vat_json_init_object (node);
3194   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3195   vat_json_object_add_uint (node, "ls_index",
3196                             clib_net_to_host_u32 (mp->ls_index));
3197   vec_free (ls_name);
3198 }
3199
3200 typedef struct
3201 {
3202   u32 spi;
3203   u8 si;
3204 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3205
3206 uword
3207 unformat_nsh_address (unformat_input_t * input, va_list * args)
3208 {
3209   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3210   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3211 }
3212
3213 u8 *
3214 format_nsh_address_vat (u8 * s, va_list * args)
3215 {
3216   nsh_t *a = va_arg (*args, nsh_t *);
3217   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3218 }
3219
3220 static u8 *
3221 format_lisp_flat_eid (u8 * s, va_list * args)
3222 {
3223   u32 type = va_arg (*args, u32);
3224   u8 *eid = va_arg (*args, u8 *);
3225   u32 eid_len = va_arg (*args, u32);
3226
3227   switch (type)
3228     {
3229     case 0:
3230       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3231     case 1:
3232       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3233     case 2:
3234       return format (s, "%U", format_ethernet_address, eid);
3235     case 3:
3236       return format (s, "%U", format_nsh_address_vat, eid);
3237     }
3238   return 0;
3239 }
3240
3241 static u8 *
3242 format_lisp_eid_vat (u8 * s, va_list * args)
3243 {
3244   u32 type = va_arg (*args, u32);
3245   u8 *eid = va_arg (*args, u8 *);
3246   u32 eid_len = va_arg (*args, u32);
3247   u8 *seid = va_arg (*args, u8 *);
3248   u32 seid_len = va_arg (*args, u32);
3249   u32 is_src_dst = va_arg (*args, u32);
3250
3251   if (is_src_dst)
3252     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3253
3254   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3255
3256   return s;
3257 }
3258
3259 static void
3260 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3261 {
3262   vat_main_t *vam = &vat_main;
3263   u8 *s = 0, *eid = 0;
3264
3265   if (~0 == mp->locator_set_index)
3266     s = format (0, "action: %d", mp->action);
3267   else
3268     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3269
3270   eid = format (0, "%U", format_lisp_eid_vat,
3271                 mp->eid_type,
3272                 mp->eid,
3273                 mp->eid_prefix_len,
3274                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3275   vec_add1 (eid, 0);
3276
3277   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3278          clib_net_to_host_u32 (mp->vni),
3279          eid,
3280          mp->is_local ? "local" : "remote",
3281          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3282          clib_net_to_host_u16 (mp->key_id), mp->key);
3283
3284   vec_free (s);
3285   vec_free (eid);
3286 }
3287
3288 static void
3289 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3290                                              * mp)
3291 {
3292   vat_main_t *vam = &vat_main;
3293   vat_json_node_t *node = 0;
3294   u8 *eid = 0;
3295
3296   if (VAT_JSON_ARRAY != vam->json_tree.type)
3297     {
3298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3299       vat_json_init_array (&vam->json_tree);
3300     }
3301   node = vat_json_array_add (&vam->json_tree);
3302
3303   vat_json_init_object (node);
3304   if (~0 == mp->locator_set_index)
3305     vat_json_object_add_uint (node, "action", mp->action);
3306   else
3307     vat_json_object_add_uint (node, "locator_set_index",
3308                               clib_net_to_host_u32 (mp->locator_set_index));
3309
3310   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3311   if (mp->eid_type == 3)
3312     {
3313       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3314       vat_json_init_object (nsh_json);
3315       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3316       vat_json_object_add_uint (nsh_json, "spi",
3317                                 clib_net_to_host_u32 (nsh->spi));
3318       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3319     }
3320   else
3321     {
3322       eid = format (0, "%U", format_lisp_eid_vat,
3323                     mp->eid_type,
3324                     mp->eid,
3325                     mp->eid_prefix_len,
3326                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3327       vec_add1 (eid, 0);
3328       vat_json_object_add_string_copy (node, "eid", eid);
3329       vec_free (eid);
3330     }
3331   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3332   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3333   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3334
3335   if (mp->key_id)
3336     {
3337       vat_json_object_add_uint (node, "key_id",
3338                                 clib_net_to_host_u16 (mp->key_id));
3339       vat_json_object_add_string_copy (node, "key", mp->key);
3340     }
3341 }
3342
3343 static void
3344 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3345 {
3346   vat_main_t *vam = &vat_main;
3347   u8 *seid = 0, *deid = 0;
3348   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3349
3350   deid = format (0, "%U", format_lisp_eid_vat,
3351                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3352
3353   seid = format (0, "%U", format_lisp_eid_vat,
3354                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3355
3356   vec_add1 (deid, 0);
3357   vec_add1 (seid, 0);
3358
3359   if (mp->is_ip4)
3360     format_ip_address_fcn = format_ip4_address;
3361   else
3362     format_ip_address_fcn = format_ip6_address;
3363
3364
3365   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3366          clib_net_to_host_u32 (mp->vni),
3367          seid, deid,
3368          format_ip_address_fcn, mp->lloc,
3369          format_ip_address_fcn, mp->rloc,
3370          clib_net_to_host_u32 (mp->pkt_count),
3371          clib_net_to_host_u32 (mp->bytes));
3372
3373   vec_free (deid);
3374   vec_free (seid);
3375 }
3376
3377 static void
3378 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3379 {
3380   struct in6_addr ip6;
3381   struct in_addr ip4;
3382   vat_main_t *vam = &vat_main;
3383   vat_json_node_t *node = 0;
3384   u8 *deid = 0, *seid = 0;
3385
3386   if (VAT_JSON_ARRAY != vam->json_tree.type)
3387     {
3388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3389       vat_json_init_array (&vam->json_tree);
3390     }
3391   node = vat_json_array_add (&vam->json_tree);
3392
3393   vat_json_init_object (node);
3394   deid = format (0, "%U", format_lisp_eid_vat,
3395                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3396
3397   seid = format (0, "%U", format_lisp_eid_vat,
3398                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3399
3400   vec_add1 (deid, 0);
3401   vec_add1 (seid, 0);
3402
3403   vat_json_object_add_string_copy (node, "seid", seid);
3404   vat_json_object_add_string_copy (node, "deid", deid);
3405   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3406
3407   if (mp->is_ip4)
3408     {
3409       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3410       vat_json_object_add_ip4 (node, "lloc", ip4);
3411       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3412       vat_json_object_add_ip4 (node, "rloc", ip4);
3413     }
3414   else
3415     {
3416       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3417       vat_json_object_add_ip6 (node, "lloc", ip6);
3418       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3419       vat_json_object_add_ip6 (node, "rloc", ip6);
3420     }
3421   vat_json_object_add_uint (node, "pkt_count",
3422                             clib_net_to_host_u32 (mp->pkt_count));
3423   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3424
3425   vec_free (deid);
3426   vec_free (seid);
3427 }
3428
3429 static void
3430   vl_api_one_eid_table_map_details_t_handler
3431   (vl_api_one_eid_table_map_details_t * mp)
3432 {
3433   vat_main_t *vam = &vat_main;
3434
3435   u8 *line = format (0, "%=10d%=10d",
3436                      clib_net_to_host_u32 (mp->vni),
3437                      clib_net_to_host_u32 (mp->dp_table));
3438   print (vam->ofp, "%v", line);
3439   vec_free (line);
3440 }
3441
3442 static void
3443   vl_api_one_eid_table_map_details_t_handler_json
3444   (vl_api_one_eid_table_map_details_t * mp)
3445 {
3446   vat_main_t *vam = &vat_main;
3447   vat_json_node_t *node = NULL;
3448
3449   if (VAT_JSON_ARRAY != vam->json_tree.type)
3450     {
3451       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3452       vat_json_init_array (&vam->json_tree);
3453     }
3454   node = vat_json_array_add (&vam->json_tree);
3455   vat_json_init_object (node);
3456   vat_json_object_add_uint (node, "dp_table",
3457                             clib_net_to_host_u32 (mp->dp_table));
3458   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3459 }
3460
3461 static void
3462   vl_api_one_eid_table_vni_details_t_handler
3463   (vl_api_one_eid_table_vni_details_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466
3467   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3468   print (vam->ofp, "%v", line);
3469   vec_free (line);
3470 }
3471
3472 static void
3473   vl_api_one_eid_table_vni_details_t_handler_json
3474   (vl_api_one_eid_table_vni_details_t * mp)
3475 {
3476   vat_main_t *vam = &vat_main;
3477   vat_json_node_t *node = NULL;
3478
3479   if (VAT_JSON_ARRAY != vam->json_tree.type)
3480     {
3481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3482       vat_json_init_array (&vam->json_tree);
3483     }
3484   node = vat_json_array_add (&vam->json_tree);
3485   vat_json_init_object (node);
3486   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3487 }
3488
3489 static void
3490   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3491   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3492 {
3493   vat_main_t *vam = &vat_main;
3494   int retval = clib_net_to_host_u32 (mp->retval);
3495
3496   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3497   print (vam->ofp, "fallback threshold value: %d", mp->value);
3498
3499   vam->retval = retval;
3500   vam->result_ready = 1;
3501 }
3502
3503 static void
3504   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3505   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3506 {
3507   vat_main_t *vam = &vat_main;
3508   vat_json_node_t _node, *node = &_node;
3509   int retval = clib_net_to_host_u32 (mp->retval);
3510
3511   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3512   vat_json_init_object (node);
3513   vat_json_object_add_uint (node, "value", mp->value);
3514
3515   vat_json_print (vam->ofp, node);
3516   vat_json_free (node);
3517
3518   vam->retval = retval;
3519   vam->result_ready = 1;
3520 }
3521
3522 static void
3523   vl_api_show_one_map_register_state_reply_t_handler
3524   (vl_api_show_one_map_register_state_reply_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   int retval = clib_net_to_host_u32 (mp->retval);
3528
3529   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3530
3531   vam->retval = retval;
3532   vam->result_ready = 1;
3533 }
3534
3535 static void
3536   vl_api_show_one_map_register_state_reply_t_handler_json
3537   (vl_api_show_one_map_register_state_reply_t * mp)
3538 {
3539   vat_main_t *vam = &vat_main;
3540   vat_json_node_t _node, *node = &_node;
3541   int retval = clib_net_to_host_u32 (mp->retval);
3542
3543   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3544
3545   vat_json_init_object (node);
3546   vat_json_object_add_string_copy (node, "state", s);
3547
3548   vat_json_print (vam->ofp, node);
3549   vat_json_free (node);
3550
3551   vam->retval = retval;
3552   vam->result_ready = 1;
3553   vec_free (s);
3554 }
3555
3556 static void
3557   vl_api_show_one_rloc_probe_state_reply_t_handler
3558   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3559 {
3560   vat_main_t *vam = &vat_main;
3561   int retval = clib_net_to_host_u32 (mp->retval);
3562
3563   if (retval)
3564     goto end;
3565
3566   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3567 end:
3568   vam->retval = retval;
3569   vam->result_ready = 1;
3570 }
3571
3572 static void
3573   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3574   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3575 {
3576   vat_main_t *vam = &vat_main;
3577   vat_json_node_t _node, *node = &_node;
3578   int retval = clib_net_to_host_u32 (mp->retval);
3579
3580   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3581   vat_json_init_object (node);
3582   vat_json_object_add_string_copy (node, "state", s);
3583
3584   vat_json_print (vam->ofp, node);
3585   vat_json_free (node);
3586
3587   vam->retval = retval;
3588   vam->result_ready = 1;
3589   vec_free (s);
3590 }
3591
3592 static void
3593   vl_api_show_one_stats_enable_disable_reply_t_handler
3594   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3595 {
3596   vat_main_t *vam = &vat_main;
3597   int retval = clib_net_to_host_u32 (mp->retval);
3598
3599   if (retval)
3600     goto end;
3601
3602   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3603 end:
3604   vam->retval = retval;
3605   vam->result_ready = 1;
3606 }
3607
3608 static void
3609   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3610   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3611 {
3612   vat_main_t *vam = &vat_main;
3613   vat_json_node_t _node, *node = &_node;
3614   int retval = clib_net_to_host_u32 (mp->retval);
3615
3616   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3617   vat_json_init_object (node);
3618   vat_json_object_add_string_copy (node, "state", s);
3619
3620   vat_json_print (vam->ofp, node);
3621   vat_json_free (node);
3622
3623   vam->retval = retval;
3624   vam->result_ready = 1;
3625   vec_free (s);
3626 }
3627
3628 static void
3629 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3630 {
3631   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3632   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3633   e->vni = clib_net_to_host_u32 (e->vni);
3634 }
3635
3636 static void
3637   gpe_fwd_entries_get_reply_t_net_to_host
3638   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3639 {
3640   u32 i;
3641
3642   mp->count = clib_net_to_host_u32 (mp->count);
3643   for (i = 0; i < mp->count; i++)
3644     {
3645       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3646     }
3647 }
3648
3649 static u8 *
3650 format_gpe_encap_mode (u8 * s, va_list * args)
3651 {
3652   u32 mode = va_arg (*args, u32);
3653
3654   switch (mode)
3655     {
3656     case 0:
3657       return format (s, "lisp");
3658     case 1:
3659       return format (s, "vxlan");
3660     }
3661   return 0;
3662 }
3663
3664 static void
3665   vl_api_gpe_get_encap_mode_reply_t_handler
3666   (vl_api_gpe_get_encap_mode_reply_t * mp)
3667 {
3668   vat_main_t *vam = &vat_main;
3669
3670   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3671   vam->retval = ntohl (mp->retval);
3672   vam->result_ready = 1;
3673 }
3674
3675 static void
3676   vl_api_gpe_get_encap_mode_reply_t_handler_json
3677   (vl_api_gpe_get_encap_mode_reply_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680   vat_json_node_t node;
3681
3682   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3683   vec_add1 (encap_mode, 0);
3684
3685   vat_json_init_object (&node);
3686   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3687
3688   vec_free (encap_mode);
3689   vat_json_print (vam->ofp, &node);
3690   vat_json_free (&node);
3691
3692   vam->retval = ntohl (mp->retval);
3693   vam->result_ready = 1;
3694 }
3695
3696 static void
3697   vl_api_gpe_fwd_entry_path_details_t_handler
3698   (vl_api_gpe_fwd_entry_path_details_t * mp)
3699 {
3700   vat_main_t *vam = &vat_main;
3701   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3702
3703   if (mp->lcl_loc.is_ip4)
3704     format_ip_address_fcn = format_ip4_address;
3705   else
3706     format_ip_address_fcn = format_ip6_address;
3707
3708   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3709          format_ip_address_fcn, &mp->lcl_loc,
3710          format_ip_address_fcn, &mp->rmt_loc);
3711 }
3712
3713 static void
3714 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3715 {
3716   struct in6_addr ip6;
3717   struct in_addr ip4;
3718
3719   if (loc->is_ip4)
3720     {
3721       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3722       vat_json_object_add_ip4 (n, "address", ip4);
3723     }
3724   else
3725     {
3726       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3727       vat_json_object_add_ip6 (n, "address", ip6);
3728     }
3729   vat_json_object_add_uint (n, "weight", loc->weight);
3730 }
3731
3732 static void
3733   vl_api_gpe_fwd_entry_path_details_t_handler_json
3734   (vl_api_gpe_fwd_entry_path_details_t * mp)
3735 {
3736   vat_main_t *vam = &vat_main;
3737   vat_json_node_t *node = NULL;
3738   vat_json_node_t *loc_node;
3739
3740   if (VAT_JSON_ARRAY != vam->json_tree.type)
3741     {
3742       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3743       vat_json_init_array (&vam->json_tree);
3744     }
3745   node = vat_json_array_add (&vam->json_tree);
3746   vat_json_init_object (node);
3747
3748   loc_node = vat_json_object_add (node, "local_locator");
3749   vat_json_init_object (loc_node);
3750   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3751
3752   loc_node = vat_json_object_add (node, "remote_locator");
3753   vat_json_init_object (loc_node);
3754   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3755 }
3756
3757 static void
3758   vl_api_gpe_fwd_entries_get_reply_t_handler
3759   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3760 {
3761   vat_main_t *vam = &vat_main;
3762   u32 i;
3763   int retval = clib_net_to_host_u32 (mp->retval);
3764   vl_api_gpe_fwd_entry_t *e;
3765
3766   if (retval)
3767     goto end;
3768
3769   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3770
3771   for (i = 0; i < mp->count; i++)
3772     {
3773       e = &mp->entries[i];
3774       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3775              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3776              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3777     }
3778
3779 end:
3780   vam->retval = retval;
3781   vam->result_ready = 1;
3782 }
3783
3784 static void
3785   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3786   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3787 {
3788   u8 *s = 0;
3789   vat_main_t *vam = &vat_main;
3790   vat_json_node_t *e = 0, root;
3791   u32 i;
3792   int retval = clib_net_to_host_u32 (mp->retval);
3793   vl_api_gpe_fwd_entry_t *fwd;
3794
3795   if (retval)
3796     goto end;
3797
3798   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3799   vat_json_init_array (&root);
3800
3801   for (i = 0; i < mp->count; i++)
3802     {
3803       e = vat_json_array_add (&root);
3804       fwd = &mp->entries[i];
3805
3806       vat_json_init_object (e);
3807       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3808       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3809       vat_json_object_add_int (e, "vni", fwd->vni);
3810       vat_json_object_add_int (e, "action", fwd->action);
3811
3812       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3813                   fwd->leid_prefix_len);
3814       vec_add1 (s, 0);
3815       vat_json_object_add_string_copy (e, "leid", s);
3816       vec_free (s);
3817
3818       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3819                   fwd->reid_prefix_len);
3820       vec_add1 (s, 0);
3821       vat_json_object_add_string_copy (e, "reid", s);
3822       vec_free (s);
3823     }
3824
3825   vat_json_print (vam->ofp, &root);
3826   vat_json_free (&root);
3827
3828 end:
3829   vam->retval = retval;
3830   vam->result_ready = 1;
3831 }
3832
3833 static void
3834   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3835   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3836 {
3837   vat_main_t *vam = &vat_main;
3838   u32 i, n;
3839   int retval = clib_net_to_host_u32 (mp->retval);
3840   vl_api_gpe_native_fwd_rpath_t *r;
3841
3842   if (retval)
3843     goto end;
3844
3845   n = clib_net_to_host_u32 (mp->count);
3846
3847   for (i = 0; i < n; i++)
3848     {
3849       r = &mp->entries[i];
3850       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3851              clib_net_to_host_u32 (r->fib_index),
3852              clib_net_to_host_u32 (r->nh_sw_if_index),
3853              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3854     }
3855
3856 end:
3857   vam->retval = retval;
3858   vam->result_ready = 1;
3859 }
3860
3861 static void
3862   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3863   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3864 {
3865   vat_main_t *vam = &vat_main;
3866   vat_json_node_t root, *e;
3867   u32 i, n;
3868   int retval = clib_net_to_host_u32 (mp->retval);
3869   vl_api_gpe_native_fwd_rpath_t *r;
3870   u8 *s;
3871
3872   if (retval)
3873     goto end;
3874
3875   n = clib_net_to_host_u32 (mp->count);
3876   vat_json_init_array (&root);
3877
3878   for (i = 0; i < n; i++)
3879     {
3880       e = vat_json_array_add (&root);
3881       vat_json_init_object (e);
3882       r = &mp->entries[i];
3883       s =
3884         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3885                 r->nh_addr);
3886       vec_add1 (s, 0);
3887       vat_json_object_add_string_copy (e, "ip4", s);
3888       vec_free (s);
3889
3890       vat_json_object_add_uint (e, "fib_index",
3891                                 clib_net_to_host_u32 (r->fib_index));
3892       vat_json_object_add_uint (e, "nh_sw_if_index",
3893                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3894     }
3895
3896   vat_json_print (vam->ofp, &root);
3897   vat_json_free (&root);
3898
3899 end:
3900   vam->retval = retval;
3901   vam->result_ready = 1;
3902 }
3903
3904 static void
3905   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3906   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3907 {
3908   vat_main_t *vam = &vat_main;
3909   u32 i, n;
3910   int retval = clib_net_to_host_u32 (mp->retval);
3911
3912   if (retval)
3913     goto end;
3914
3915   n = clib_net_to_host_u32 (mp->count);
3916
3917   for (i = 0; i < n; i++)
3918     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3919
3920 end:
3921   vam->retval = retval;
3922   vam->result_ready = 1;
3923 }
3924
3925 static void
3926   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3927   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3928 {
3929   vat_main_t *vam = &vat_main;
3930   vat_json_node_t root;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933
3934   if (retval)
3935     goto end;
3936
3937   n = clib_net_to_host_u32 (mp->count);
3938   vat_json_init_array (&root);
3939
3940   for (i = 0; i < n; i++)
3941     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3942
3943   vat_json_print (vam->ofp, &root);
3944   vat_json_free (&root);
3945
3946 end:
3947   vam->retval = retval;
3948   vam->result_ready = 1;
3949 }
3950
3951 static void
3952   vl_api_one_ndp_entries_get_reply_t_handler
3953   (vl_api_one_ndp_entries_get_reply_t * mp)
3954 {
3955   vat_main_t *vam = &vat_main;
3956   u32 i, n;
3957   int retval = clib_net_to_host_u32 (mp->retval);
3958
3959   if (retval)
3960     goto end;
3961
3962   n = clib_net_to_host_u32 (mp->count);
3963
3964   for (i = 0; i < n; i++)
3965     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3966            format_ethernet_address, mp->entries[i].mac);
3967
3968 end:
3969   vam->retval = retval;
3970   vam->result_ready = 1;
3971 }
3972
3973 static void
3974   vl_api_one_ndp_entries_get_reply_t_handler_json
3975   (vl_api_one_ndp_entries_get_reply_t * mp)
3976 {
3977   u8 *s = 0;
3978   vat_main_t *vam = &vat_main;
3979   vat_json_node_t *e = 0, root;
3980   u32 i, n;
3981   int retval = clib_net_to_host_u32 (mp->retval);
3982   vl_api_one_ndp_entry_t *arp_entry;
3983
3984   if (retval)
3985     goto end;
3986
3987   n = clib_net_to_host_u32 (mp->count);
3988   vat_json_init_array (&root);
3989
3990   for (i = 0; i < n; i++)
3991     {
3992       e = vat_json_array_add (&root);
3993       arp_entry = &mp->entries[i];
3994
3995       vat_json_init_object (e);
3996       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3997       vec_add1 (s, 0);
3998
3999       vat_json_object_add_string_copy (e, "mac", s);
4000       vec_free (s);
4001
4002       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4003       vec_add1 (s, 0);
4004       vat_json_object_add_string_copy (e, "ip6", s);
4005       vec_free (s);
4006     }
4007
4008   vat_json_print (vam->ofp, &root);
4009   vat_json_free (&root);
4010
4011 end:
4012   vam->retval = retval;
4013   vam->result_ready = 1;
4014 }
4015
4016 static void
4017   vl_api_one_l2_arp_entries_get_reply_t_handler
4018   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4019 {
4020   vat_main_t *vam = &vat_main;
4021   u32 i, n;
4022   int retval = clib_net_to_host_u32 (mp->retval);
4023
4024   if (retval)
4025     goto end;
4026
4027   n = clib_net_to_host_u32 (mp->count);
4028
4029   for (i = 0; i < n; i++)
4030     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4031            format_ethernet_address, mp->entries[i].mac);
4032
4033 end:
4034   vam->retval = retval;
4035   vam->result_ready = 1;
4036 }
4037
4038 static void
4039   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4040   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4041 {
4042   u8 *s = 0;
4043   vat_main_t *vam = &vat_main;
4044   vat_json_node_t *e = 0, root;
4045   u32 i, n;
4046   int retval = clib_net_to_host_u32 (mp->retval);
4047   vl_api_one_l2_arp_entry_t *arp_entry;
4048
4049   if (retval)
4050     goto end;
4051
4052   n = clib_net_to_host_u32 (mp->count);
4053   vat_json_init_array (&root);
4054
4055   for (i = 0; i < n; i++)
4056     {
4057       e = vat_json_array_add (&root);
4058       arp_entry = &mp->entries[i];
4059
4060       vat_json_init_object (e);
4061       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4062       vec_add1 (s, 0);
4063
4064       vat_json_object_add_string_copy (e, "mac", s);
4065       vec_free (s);
4066
4067       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4068       vec_add1 (s, 0);
4069       vat_json_object_add_string_copy (e, "ip4", s);
4070       vec_free (s);
4071     }
4072
4073   vat_json_print (vam->ofp, &root);
4074   vat_json_free (&root);
4075
4076 end:
4077   vam->retval = retval;
4078   vam->result_ready = 1;
4079 }
4080
4081 static void
4082 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4083 {
4084   vat_main_t *vam = &vat_main;
4085   u32 i, n;
4086   int retval = clib_net_to_host_u32 (mp->retval);
4087
4088   if (retval)
4089     goto end;
4090
4091   n = clib_net_to_host_u32 (mp->count);
4092
4093   for (i = 0; i < n; i++)
4094     {
4095       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4096     }
4097
4098 end:
4099   vam->retval = retval;
4100   vam->result_ready = 1;
4101 }
4102
4103 static void
4104   vl_api_one_ndp_bd_get_reply_t_handler_json
4105   (vl_api_one_ndp_bd_get_reply_t * mp)
4106 {
4107   vat_main_t *vam = &vat_main;
4108   vat_json_node_t root;
4109   u32 i, n;
4110   int retval = clib_net_to_host_u32 (mp->retval);
4111
4112   if (retval)
4113     goto end;
4114
4115   n = clib_net_to_host_u32 (mp->count);
4116   vat_json_init_array (&root);
4117
4118   for (i = 0; i < n; i++)
4119     {
4120       vat_json_array_add_uint (&root,
4121                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4122     }
4123
4124   vat_json_print (vam->ofp, &root);
4125   vat_json_free (&root);
4126
4127 end:
4128   vam->retval = retval;
4129   vam->result_ready = 1;
4130 }
4131
4132 static void
4133   vl_api_one_l2_arp_bd_get_reply_t_handler
4134   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4135 {
4136   vat_main_t *vam = &vat_main;
4137   u32 i, n;
4138   int retval = clib_net_to_host_u32 (mp->retval);
4139
4140   if (retval)
4141     goto end;
4142
4143   n = clib_net_to_host_u32 (mp->count);
4144
4145   for (i = 0; i < n; i++)
4146     {
4147       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4148     }
4149
4150 end:
4151   vam->retval = retval;
4152   vam->result_ready = 1;
4153 }
4154
4155 static void
4156   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4157   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t root;
4161   u32 i, n;
4162   int retval = clib_net_to_host_u32 (mp->retval);
4163
4164   if (retval)
4165     goto end;
4166
4167   n = clib_net_to_host_u32 (mp->count);
4168   vat_json_init_array (&root);
4169
4170   for (i = 0; i < n; i++)
4171     {
4172       vat_json_array_add_uint (&root,
4173                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4174     }
4175
4176   vat_json_print (vam->ofp, &root);
4177   vat_json_free (&root);
4178
4179 end:
4180   vam->retval = retval;
4181   vam->result_ready = 1;
4182 }
4183
4184 static void
4185   vl_api_one_adjacencies_get_reply_t_handler
4186   (vl_api_one_adjacencies_get_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   u32 i, n;
4190   int retval = clib_net_to_host_u32 (mp->retval);
4191   vl_api_one_adjacency_t *a;
4192
4193   if (retval)
4194     goto end;
4195
4196   n = clib_net_to_host_u32 (mp->count);
4197
4198   for (i = 0; i < n; i++)
4199     {
4200       a = &mp->adjacencies[i];
4201       print (vam->ofp, "%U %40U",
4202              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4203              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4204     }
4205
4206 end:
4207   vam->retval = retval;
4208   vam->result_ready = 1;
4209 }
4210
4211 static void
4212   vl_api_one_adjacencies_get_reply_t_handler_json
4213   (vl_api_one_adjacencies_get_reply_t * mp)
4214 {
4215   u8 *s = 0;
4216   vat_main_t *vam = &vat_main;
4217   vat_json_node_t *e = 0, root;
4218   u32 i, n;
4219   int retval = clib_net_to_host_u32 (mp->retval);
4220   vl_api_one_adjacency_t *a;
4221
4222   if (retval)
4223     goto end;
4224
4225   n = clib_net_to_host_u32 (mp->count);
4226   vat_json_init_array (&root);
4227
4228   for (i = 0; i < n; i++)
4229     {
4230       e = vat_json_array_add (&root);
4231       a = &mp->adjacencies[i];
4232
4233       vat_json_init_object (e);
4234       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4235                   a->leid_prefix_len);
4236       vec_add1 (s, 0);
4237       vat_json_object_add_string_copy (e, "leid", s);
4238       vec_free (s);
4239
4240       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4241                   a->reid_prefix_len);
4242       vec_add1 (s, 0);
4243       vat_json_object_add_string_copy (e, "reid", s);
4244       vec_free (s);
4245     }
4246
4247   vat_json_print (vam->ofp, &root);
4248   vat_json_free (&root);
4249
4250 end:
4251   vam->retval = retval;
4252   vam->result_ready = 1;
4253 }
4254
4255 static void
4256 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4257 {
4258   vat_main_t *vam = &vat_main;
4259
4260   print (vam->ofp, "%=20U",
4261          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4262          mp->ip_address);
4263 }
4264
4265 static void
4266   vl_api_one_map_server_details_t_handler_json
4267   (vl_api_one_map_server_details_t * mp)
4268 {
4269   vat_main_t *vam = &vat_main;
4270   vat_json_node_t *node = NULL;
4271   struct in6_addr ip6;
4272   struct in_addr ip4;
4273
4274   if (VAT_JSON_ARRAY != vam->json_tree.type)
4275     {
4276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4277       vat_json_init_array (&vam->json_tree);
4278     }
4279   node = vat_json_array_add (&vam->json_tree);
4280
4281   vat_json_init_object (node);
4282   if (mp->is_ipv6)
4283     {
4284       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4285       vat_json_object_add_ip6 (node, "map-server", ip6);
4286     }
4287   else
4288     {
4289       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4290       vat_json_object_add_ip4 (node, "map-server", ip4);
4291     }
4292 }
4293
4294 static void
4295 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4296                                            * mp)
4297 {
4298   vat_main_t *vam = &vat_main;
4299
4300   print (vam->ofp, "%=20U",
4301          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4302          mp->ip_address);
4303 }
4304
4305 static void
4306   vl_api_one_map_resolver_details_t_handler_json
4307   (vl_api_one_map_resolver_details_t * mp)
4308 {
4309   vat_main_t *vam = &vat_main;
4310   vat_json_node_t *node = NULL;
4311   struct in6_addr ip6;
4312   struct in_addr ip4;
4313
4314   if (VAT_JSON_ARRAY != vam->json_tree.type)
4315     {
4316       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4317       vat_json_init_array (&vam->json_tree);
4318     }
4319   node = vat_json_array_add (&vam->json_tree);
4320
4321   vat_json_init_object (node);
4322   if (mp->is_ipv6)
4323     {
4324       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4325       vat_json_object_add_ip6 (node, "map resolver", ip6);
4326     }
4327   else
4328     {
4329       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4330       vat_json_object_add_ip4 (node, "map resolver", ip4);
4331     }
4332 }
4333
4334 static void
4335 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4336 {
4337   vat_main_t *vam = &vat_main;
4338   i32 retval = ntohl (mp->retval);
4339
4340   if (0 <= retval)
4341     {
4342       print (vam->ofp, "feature: %s\ngpe: %s",
4343              mp->feature_status ? "enabled" : "disabled",
4344              mp->gpe_status ? "enabled" : "disabled");
4345     }
4346
4347   vam->retval = retval;
4348   vam->result_ready = 1;
4349 }
4350
4351 static void
4352   vl_api_show_one_status_reply_t_handler_json
4353   (vl_api_show_one_status_reply_t * mp)
4354 {
4355   vat_main_t *vam = &vat_main;
4356   vat_json_node_t node;
4357   u8 *gpe_status = NULL;
4358   u8 *feature_status = NULL;
4359
4360   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4361   feature_status = format (0, "%s",
4362                            mp->feature_status ? "enabled" : "disabled");
4363   vec_add1 (gpe_status, 0);
4364   vec_add1 (feature_status, 0);
4365
4366   vat_json_init_object (&node);
4367   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4368   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4369
4370   vec_free (gpe_status);
4371   vec_free (feature_status);
4372
4373   vat_json_print (vam->ofp, &node);
4374   vat_json_free (&node);
4375
4376   vam->retval = ntohl (mp->retval);
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4382   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   i32 retval = ntohl (mp->retval);
4386
4387   if (retval >= 0)
4388     {
4389       print (vam->ofp, "%=20s", mp->locator_set_name);
4390     }
4391
4392   vam->retval = retval;
4393   vam->result_ready = 1;
4394 }
4395
4396 static void
4397   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4398   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4399 {
4400   vat_main_t *vam = &vat_main;
4401   vat_json_node_t *node = NULL;
4402
4403   if (VAT_JSON_ARRAY != vam->json_tree.type)
4404     {
4405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4406       vat_json_init_array (&vam->json_tree);
4407     }
4408   node = vat_json_array_add (&vam->json_tree);
4409
4410   vat_json_init_object (node);
4411   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4412
4413   vat_json_print (vam->ofp, node);
4414   vat_json_free (node);
4415
4416   vam->retval = ntohl (mp->retval);
4417   vam->result_ready = 1;
4418 }
4419
4420 static u8 *
4421 format_lisp_map_request_mode (u8 * s, va_list * args)
4422 {
4423   u32 mode = va_arg (*args, u32);
4424
4425   switch (mode)
4426     {
4427     case 0:
4428       return format (0, "dst-only");
4429     case 1:
4430       return format (0, "src-dst");
4431     }
4432   return 0;
4433 }
4434
4435 static void
4436   vl_api_show_one_map_request_mode_reply_t_handler
4437   (vl_api_show_one_map_request_mode_reply_t * mp)
4438 {
4439   vat_main_t *vam = &vat_main;
4440   i32 retval = ntohl (mp->retval);
4441
4442   if (0 <= retval)
4443     {
4444       u32 mode = mp->mode;
4445       print (vam->ofp, "map_request_mode: %U",
4446              format_lisp_map_request_mode, mode);
4447     }
4448
4449   vam->retval = retval;
4450   vam->result_ready = 1;
4451 }
4452
4453 static void
4454   vl_api_show_one_map_request_mode_reply_t_handler_json
4455   (vl_api_show_one_map_request_mode_reply_t * mp)
4456 {
4457   vat_main_t *vam = &vat_main;
4458   vat_json_node_t node;
4459   u8 *s = 0;
4460   u32 mode;
4461
4462   mode = mp->mode;
4463   s = format (0, "%U", format_lisp_map_request_mode, mode);
4464   vec_add1 (s, 0);
4465
4466   vat_json_init_object (&node);
4467   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4468   vat_json_print (vam->ofp, &node);
4469   vat_json_free (&node);
4470
4471   vec_free (s);
4472   vam->retval = ntohl (mp->retval);
4473   vam->result_ready = 1;
4474 }
4475
4476 static void
4477   vl_api_one_show_xtr_mode_reply_t_handler
4478   (vl_api_one_show_xtr_mode_reply_t * mp)
4479 {
4480   vat_main_t *vam = &vat_main;
4481   i32 retval = ntohl (mp->retval);
4482
4483   if (0 <= retval)
4484     {
4485       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4486     }
4487
4488   vam->retval = retval;
4489   vam->result_ready = 1;
4490 }
4491
4492 static void
4493   vl_api_one_show_xtr_mode_reply_t_handler_json
4494   (vl_api_one_show_xtr_mode_reply_t * mp)
4495 {
4496   vat_main_t *vam = &vat_main;
4497   vat_json_node_t node;
4498   u8 *status = 0;
4499
4500   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4501   vec_add1 (status, 0);
4502
4503   vat_json_init_object (&node);
4504   vat_json_object_add_string_copy (&node, "status", status);
4505
4506   vec_free (status);
4507
4508   vat_json_print (vam->ofp, &node);
4509   vat_json_free (&node);
4510
4511   vam->retval = ntohl (mp->retval);
4512   vam->result_ready = 1;
4513 }
4514
4515 static void
4516   vl_api_one_show_pitr_mode_reply_t_handler
4517   (vl_api_one_show_pitr_mode_reply_t * mp)
4518 {
4519   vat_main_t *vam = &vat_main;
4520   i32 retval = ntohl (mp->retval);
4521
4522   if (0 <= retval)
4523     {
4524       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4525     }
4526
4527   vam->retval = retval;
4528   vam->result_ready = 1;
4529 }
4530
4531 static void
4532   vl_api_one_show_pitr_mode_reply_t_handler_json
4533   (vl_api_one_show_pitr_mode_reply_t * mp)
4534 {
4535   vat_main_t *vam = &vat_main;
4536   vat_json_node_t node;
4537   u8 *status = 0;
4538
4539   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4540   vec_add1 (status, 0);
4541
4542   vat_json_init_object (&node);
4543   vat_json_object_add_string_copy (&node, "status", status);
4544
4545   vec_free (status);
4546
4547   vat_json_print (vam->ofp, &node);
4548   vat_json_free (&node);
4549
4550   vam->retval = ntohl (mp->retval);
4551   vam->result_ready = 1;
4552 }
4553
4554 static void
4555   vl_api_one_show_petr_mode_reply_t_handler
4556   (vl_api_one_show_petr_mode_reply_t * mp)
4557 {
4558   vat_main_t *vam = &vat_main;
4559   i32 retval = ntohl (mp->retval);
4560
4561   if (0 <= retval)
4562     {
4563       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4564     }
4565
4566   vam->retval = retval;
4567   vam->result_ready = 1;
4568 }
4569
4570 static void
4571   vl_api_one_show_petr_mode_reply_t_handler_json
4572   (vl_api_one_show_petr_mode_reply_t * mp)
4573 {
4574   vat_main_t *vam = &vat_main;
4575   vat_json_node_t node;
4576   u8 *status = 0;
4577
4578   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4579   vec_add1 (status, 0);
4580
4581   vat_json_init_object (&node);
4582   vat_json_object_add_string_copy (&node, "status", status);
4583
4584   vec_free (status);
4585
4586   vat_json_print (vam->ofp, &node);
4587   vat_json_free (&node);
4588
4589   vam->retval = ntohl (mp->retval);
4590   vam->result_ready = 1;
4591 }
4592
4593 static void
4594   vl_api_show_one_use_petr_reply_t_handler
4595   (vl_api_show_one_use_petr_reply_t * mp)
4596 {
4597   vat_main_t *vam = &vat_main;
4598   i32 retval = ntohl (mp->retval);
4599
4600   if (0 <= retval)
4601     {
4602       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4603       if (mp->status)
4604         {
4605           print (vam->ofp, "Proxy-ETR address; %U",
4606                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4607                  mp->address);
4608         }
4609     }
4610
4611   vam->retval = retval;
4612   vam->result_ready = 1;
4613 }
4614
4615 static void
4616   vl_api_show_one_use_petr_reply_t_handler_json
4617   (vl_api_show_one_use_petr_reply_t * mp)
4618 {
4619   vat_main_t *vam = &vat_main;
4620   vat_json_node_t node;
4621   u8 *status = 0;
4622   struct in_addr ip4;
4623   struct in6_addr ip6;
4624
4625   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4626   vec_add1 (status, 0);
4627
4628   vat_json_init_object (&node);
4629   vat_json_object_add_string_copy (&node, "status", status);
4630   if (mp->status)
4631     {
4632       if (mp->is_ip4)
4633         {
4634           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4635           vat_json_object_add_ip6 (&node, "address", ip6);
4636         }
4637       else
4638         {
4639           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4640           vat_json_object_add_ip4 (&node, "address", ip4);
4641         }
4642     }
4643
4644   vec_free (status);
4645
4646   vat_json_print (vam->ofp, &node);
4647   vat_json_free (&node);
4648
4649   vam->retval = ntohl (mp->retval);
4650   vam->result_ready = 1;
4651 }
4652
4653 static void
4654   vl_api_show_one_nsh_mapping_reply_t_handler
4655   (vl_api_show_one_nsh_mapping_reply_t * mp)
4656 {
4657   vat_main_t *vam = &vat_main;
4658   i32 retval = ntohl (mp->retval);
4659
4660   if (0 <= retval)
4661     {
4662       print (vam->ofp, "%-20s%-16s",
4663              mp->is_set ? "set" : "not-set",
4664              mp->is_set ? (char *) mp->locator_set_name : "");
4665     }
4666
4667   vam->retval = retval;
4668   vam->result_ready = 1;
4669 }
4670
4671 static void
4672   vl_api_show_one_nsh_mapping_reply_t_handler_json
4673   (vl_api_show_one_nsh_mapping_reply_t * mp)
4674 {
4675   vat_main_t *vam = &vat_main;
4676   vat_json_node_t node;
4677   u8 *status = 0;
4678
4679   status = format (0, "%s", mp->is_set ? "yes" : "no");
4680   vec_add1 (status, 0);
4681
4682   vat_json_init_object (&node);
4683   vat_json_object_add_string_copy (&node, "is_set", status);
4684   if (mp->is_set)
4685     {
4686       vat_json_object_add_string_copy (&node, "locator_set",
4687                                        mp->locator_set_name);
4688     }
4689
4690   vec_free (status);
4691
4692   vat_json_print (vam->ofp, &node);
4693   vat_json_free (&node);
4694
4695   vam->retval = ntohl (mp->retval);
4696   vam->result_ready = 1;
4697 }
4698
4699 static void
4700   vl_api_show_one_map_register_ttl_reply_t_handler
4701   (vl_api_show_one_map_register_ttl_reply_t * mp)
4702 {
4703   vat_main_t *vam = &vat_main;
4704   i32 retval = ntohl (mp->retval);
4705
4706   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4707
4708   if (0 <= retval)
4709     {
4710       print (vam->ofp, "ttl: %u", mp->ttl);
4711     }
4712
4713   vam->retval = retval;
4714   vam->result_ready = 1;
4715 }
4716
4717 static void
4718   vl_api_show_one_map_register_ttl_reply_t_handler_json
4719   (vl_api_show_one_map_register_ttl_reply_t * mp)
4720 {
4721   vat_main_t *vam = &vat_main;
4722   vat_json_node_t node;
4723
4724   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4725   vat_json_init_object (&node);
4726   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4727
4728   vat_json_print (vam->ofp, &node);
4729   vat_json_free (&node);
4730
4731   vam->retval = ntohl (mp->retval);
4732   vam->result_ready = 1;
4733 }
4734
4735 static void
4736 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4737 {
4738   vat_main_t *vam = &vat_main;
4739   i32 retval = ntohl (mp->retval);
4740
4741   if (0 <= retval)
4742     {
4743       print (vam->ofp, "%-20s%-16s",
4744              mp->status ? "enabled" : "disabled",
4745              mp->status ? (char *) mp->locator_set_name : "");
4746     }
4747
4748   vam->retval = retval;
4749   vam->result_ready = 1;
4750 }
4751
4752 static void
4753 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   vat_json_node_t node;
4757   u8 *status = 0;
4758
4759   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4760   vec_add1 (status, 0);
4761
4762   vat_json_init_object (&node);
4763   vat_json_object_add_string_copy (&node, "status", status);
4764   if (mp->status)
4765     {
4766       vat_json_object_add_string_copy (&node, "locator_set",
4767                                        mp->locator_set_name);
4768     }
4769
4770   vec_free (status);
4771
4772   vat_json_print (vam->ofp, &node);
4773   vat_json_free (&node);
4774
4775   vam->retval = ntohl (mp->retval);
4776   vam->result_ready = 1;
4777 }
4778
4779 static u8 *
4780 format_policer_type (u8 * s, va_list * va)
4781 {
4782   u32 i = va_arg (*va, u32);
4783
4784   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4785     s = format (s, "1r2c");
4786   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4787     s = format (s, "1r3c");
4788   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4789     s = format (s, "2r3c-2698");
4790   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4791     s = format (s, "2r3c-4115");
4792   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4793     s = format (s, "2r3c-mef5cf1");
4794   else
4795     s = format (s, "ILLEGAL");
4796   return s;
4797 }
4798
4799 static u8 *
4800 format_policer_rate_type (u8 * s, va_list * va)
4801 {
4802   u32 i = va_arg (*va, u32);
4803
4804   if (i == SSE2_QOS_RATE_KBPS)
4805     s = format (s, "kbps");
4806   else if (i == SSE2_QOS_RATE_PPS)
4807     s = format (s, "pps");
4808   else
4809     s = format (s, "ILLEGAL");
4810   return s;
4811 }
4812
4813 static u8 *
4814 format_policer_round_type (u8 * s, va_list * va)
4815 {
4816   u32 i = va_arg (*va, u32);
4817
4818   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4819     s = format (s, "closest");
4820   else if (i == SSE2_QOS_ROUND_TO_UP)
4821     s = format (s, "up");
4822   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4823     s = format (s, "down");
4824   else
4825     s = format (s, "ILLEGAL");
4826   return s;
4827 }
4828
4829 static u8 *
4830 format_policer_action_type (u8 * s, va_list * va)
4831 {
4832   u32 i = va_arg (*va, u32);
4833
4834   if (i == SSE2_QOS_ACTION_DROP)
4835     s = format (s, "drop");
4836   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4837     s = format (s, "transmit");
4838   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4839     s = format (s, "mark-and-transmit");
4840   else
4841     s = format (s, "ILLEGAL");
4842   return s;
4843 }
4844
4845 static u8 *
4846 format_dscp (u8 * s, va_list * va)
4847 {
4848   u32 i = va_arg (*va, u32);
4849   char *t = 0;
4850
4851   switch (i)
4852     {
4853 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4854       foreach_vnet_dscp
4855 #undef _
4856     default:
4857       return format (s, "ILLEGAL");
4858     }
4859   s = format (s, "%s", t);
4860   return s;
4861 }
4862
4863 static void
4864 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4865 {
4866   vat_main_t *vam = &vat_main;
4867   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4868
4869   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4870     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4871   else
4872     conform_dscp_str = format (0, "");
4873
4874   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4875     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4876   else
4877     exceed_dscp_str = format (0, "");
4878
4879   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4880     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4881   else
4882     violate_dscp_str = format (0, "");
4883
4884   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4885          "rate type %U, round type %U, %s rate, %s color-aware, "
4886          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4887          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4888          "conform action %U%s, exceed action %U%s, violate action %U%s",
4889          mp->name,
4890          format_policer_type, mp->type,
4891          ntohl (mp->cir),
4892          ntohl (mp->eir),
4893          clib_net_to_host_u64 (mp->cb),
4894          clib_net_to_host_u64 (mp->eb),
4895          format_policer_rate_type, mp->rate_type,
4896          format_policer_round_type, mp->round_type,
4897          mp->single_rate ? "single" : "dual",
4898          mp->color_aware ? "is" : "not",
4899          ntohl (mp->cir_tokens_per_period),
4900          ntohl (mp->pir_tokens_per_period),
4901          ntohl (mp->scale),
4902          ntohl (mp->current_limit),
4903          ntohl (mp->current_bucket),
4904          ntohl (mp->extended_limit),
4905          ntohl (mp->extended_bucket),
4906          clib_net_to_host_u64 (mp->last_update_time),
4907          format_policer_action_type, mp->conform_action_type,
4908          conform_dscp_str,
4909          format_policer_action_type, mp->exceed_action_type,
4910          exceed_dscp_str,
4911          format_policer_action_type, mp->violate_action_type,
4912          violate_dscp_str);
4913
4914   vec_free (conform_dscp_str);
4915   vec_free (exceed_dscp_str);
4916   vec_free (violate_dscp_str);
4917 }
4918
4919 static void vl_api_policer_details_t_handler_json
4920   (vl_api_policer_details_t * mp)
4921 {
4922   vat_main_t *vam = &vat_main;
4923   vat_json_node_t *node;
4924   u8 *rate_type_str, *round_type_str, *type_str;
4925   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4926
4927   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4928   round_type_str =
4929     format (0, "%U", format_policer_round_type, mp->round_type);
4930   type_str = format (0, "%U", format_policer_type, mp->type);
4931   conform_action_str = format (0, "%U", format_policer_action_type,
4932                                mp->conform_action_type);
4933   exceed_action_str = format (0, "%U", format_policer_action_type,
4934                               mp->exceed_action_type);
4935   violate_action_str = format (0, "%U", format_policer_action_type,
4936                                mp->violate_action_type);
4937
4938   if (VAT_JSON_ARRAY != vam->json_tree.type)
4939     {
4940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4941       vat_json_init_array (&vam->json_tree);
4942     }
4943   node = vat_json_array_add (&vam->json_tree);
4944
4945   vat_json_init_object (node);
4946   vat_json_object_add_string_copy (node, "name", mp->name);
4947   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4948   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4949   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4950   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4951   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4952   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4953   vat_json_object_add_string_copy (node, "type", type_str);
4954   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4955   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4956   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4957   vat_json_object_add_uint (node, "cir_tokens_per_period",
4958                             ntohl (mp->cir_tokens_per_period));
4959   vat_json_object_add_uint (node, "eir_tokens_per_period",
4960                             ntohl (mp->pir_tokens_per_period));
4961   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4962   vat_json_object_add_uint (node, "current_bucket",
4963                             ntohl (mp->current_bucket));
4964   vat_json_object_add_uint (node, "extended_limit",
4965                             ntohl (mp->extended_limit));
4966   vat_json_object_add_uint (node, "extended_bucket",
4967                             ntohl (mp->extended_bucket));
4968   vat_json_object_add_uint (node, "last_update_time",
4969                             ntohl (mp->last_update_time));
4970   vat_json_object_add_string_copy (node, "conform_action",
4971                                    conform_action_str);
4972   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4973     {
4974       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4975       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4976       vec_free (dscp_str);
4977     }
4978   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4979   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4980     {
4981       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4982       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4983       vec_free (dscp_str);
4984     }
4985   vat_json_object_add_string_copy (node, "violate_action",
4986                                    violate_action_str);
4987   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4988     {
4989       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4990       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4991       vec_free (dscp_str);
4992     }
4993
4994   vec_free (rate_type_str);
4995   vec_free (round_type_str);
4996   vec_free (type_str);
4997   vec_free (conform_action_str);
4998   vec_free (exceed_action_str);
4999   vec_free (violate_action_str);
5000 }
5001
5002 static void
5003 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5004                                            mp)
5005 {
5006   vat_main_t *vam = &vat_main;
5007   int i, count = ntohl (mp->count);
5008
5009   if (count > 0)
5010     print (vam->ofp, "classify table ids (%d) : ", count);
5011   for (i = 0; i < count; i++)
5012     {
5013       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5014       print (vam->ofp, (i < count - 1) ? "," : "");
5015     }
5016   vam->retval = ntohl (mp->retval);
5017   vam->result_ready = 1;
5018 }
5019
5020 static void
5021   vl_api_classify_table_ids_reply_t_handler_json
5022   (vl_api_classify_table_ids_reply_t * mp)
5023 {
5024   vat_main_t *vam = &vat_main;
5025   int i, count = ntohl (mp->count);
5026
5027   if (count > 0)
5028     {
5029       vat_json_node_t node;
5030
5031       vat_json_init_object (&node);
5032       for (i = 0; i < count; i++)
5033         {
5034           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5035         }
5036       vat_json_print (vam->ofp, &node);
5037       vat_json_free (&node);
5038     }
5039   vam->retval = ntohl (mp->retval);
5040   vam->result_ready = 1;
5041 }
5042
5043 static void
5044   vl_api_classify_table_by_interface_reply_t_handler
5045   (vl_api_classify_table_by_interface_reply_t * mp)
5046 {
5047   vat_main_t *vam = &vat_main;
5048   u32 table_id;
5049
5050   table_id = ntohl (mp->l2_table_id);
5051   if (table_id != ~0)
5052     print (vam->ofp, "l2 table id : %d", table_id);
5053   else
5054     print (vam->ofp, "l2 table id : No input ACL tables configured");
5055   table_id = ntohl (mp->ip4_table_id);
5056   if (table_id != ~0)
5057     print (vam->ofp, "ip4 table id : %d", table_id);
5058   else
5059     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5060   table_id = ntohl (mp->ip6_table_id);
5061   if (table_id != ~0)
5062     print (vam->ofp, "ip6 table id : %d", table_id);
5063   else
5064     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5065   vam->retval = ntohl (mp->retval);
5066   vam->result_ready = 1;
5067 }
5068
5069 static void
5070   vl_api_classify_table_by_interface_reply_t_handler_json
5071   (vl_api_classify_table_by_interface_reply_t * mp)
5072 {
5073   vat_main_t *vam = &vat_main;
5074   vat_json_node_t node;
5075
5076   vat_json_init_object (&node);
5077
5078   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5079   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5080   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5081
5082   vat_json_print (vam->ofp, &node);
5083   vat_json_free (&node);
5084
5085   vam->retval = ntohl (mp->retval);
5086   vam->result_ready = 1;
5087 }
5088
5089 static void vl_api_policer_add_del_reply_t_handler
5090   (vl_api_policer_add_del_reply_t * mp)
5091 {
5092   vat_main_t *vam = &vat_main;
5093   i32 retval = ntohl (mp->retval);
5094   if (vam->async_mode)
5095     {
5096       vam->async_errors += (retval < 0);
5097     }
5098   else
5099     {
5100       vam->retval = retval;
5101       vam->result_ready = 1;
5102       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5103         /*
5104          * Note: this is just barely thread-safe, depends on
5105          * the main thread spinning waiting for an answer...
5106          */
5107         errmsg ("policer index %d", ntohl (mp->policer_index));
5108     }
5109 }
5110
5111 static void vl_api_policer_add_del_reply_t_handler_json
5112   (vl_api_policer_add_del_reply_t * mp)
5113 {
5114   vat_main_t *vam = &vat_main;
5115   vat_json_node_t node;
5116
5117   vat_json_init_object (&node);
5118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5119   vat_json_object_add_uint (&node, "policer_index",
5120                             ntohl (mp->policer_index));
5121
5122   vat_json_print (vam->ofp, &node);
5123   vat_json_free (&node);
5124
5125   vam->retval = ntohl (mp->retval);
5126   vam->result_ready = 1;
5127 }
5128
5129 /* Format hex dump. */
5130 u8 *
5131 format_hex_bytes (u8 * s, va_list * va)
5132 {
5133   u8 *bytes = va_arg (*va, u8 *);
5134   int n_bytes = va_arg (*va, int);
5135   uword i;
5136
5137   /* Print short or long form depending on byte count. */
5138   uword short_form = n_bytes <= 32;
5139   u32 indent = format_get_indent (s);
5140
5141   if (n_bytes == 0)
5142     return s;
5143
5144   for (i = 0; i < n_bytes; i++)
5145     {
5146       if (!short_form && (i % 32) == 0)
5147         s = format (s, "%08x: ", i);
5148       s = format (s, "%02x", bytes[i]);
5149       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5150         s = format (s, "\n%U", format_white_space, indent);
5151     }
5152
5153   return s;
5154 }
5155
5156 static void
5157 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5158                                             * mp)
5159 {
5160   vat_main_t *vam = &vat_main;
5161   i32 retval = ntohl (mp->retval);
5162   if (retval == 0)
5163     {
5164       print (vam->ofp, "classify table info :");
5165       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5166              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5167              ntohl (mp->miss_next_index));
5168       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5169              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5170              ntohl (mp->match_n_vectors));
5171       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5172              ntohl (mp->mask_length));
5173     }
5174   vam->retval = retval;
5175   vam->result_ready = 1;
5176 }
5177
5178 static void
5179   vl_api_classify_table_info_reply_t_handler_json
5180   (vl_api_classify_table_info_reply_t * mp)
5181 {
5182   vat_main_t *vam = &vat_main;
5183   vat_json_node_t node;
5184
5185   i32 retval = ntohl (mp->retval);
5186   if (retval == 0)
5187     {
5188       vat_json_init_object (&node);
5189
5190       vat_json_object_add_int (&node, "sessions",
5191                                ntohl (mp->active_sessions));
5192       vat_json_object_add_int (&node, "nexttbl",
5193                                ntohl (mp->next_table_index));
5194       vat_json_object_add_int (&node, "nextnode",
5195                                ntohl (mp->miss_next_index));
5196       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5197       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5198       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5199       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5200                       ntohl (mp->mask_length), 0);
5201       vat_json_object_add_string_copy (&node, "mask", s);
5202
5203       vat_json_print (vam->ofp, &node);
5204       vat_json_free (&node);
5205     }
5206   vam->retval = ntohl (mp->retval);
5207   vam->result_ready = 1;
5208 }
5209
5210 static void
5211 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5212                                            mp)
5213 {
5214   vat_main_t *vam = &vat_main;
5215
5216   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5217          ntohl (mp->hit_next_index), ntohl (mp->advance),
5218          ntohl (mp->opaque_index));
5219   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5220          ntohl (mp->match_length));
5221 }
5222
5223 static void
5224   vl_api_classify_session_details_t_handler_json
5225   (vl_api_classify_session_details_t * mp)
5226 {
5227   vat_main_t *vam = &vat_main;
5228   vat_json_node_t *node = NULL;
5229
5230   if (VAT_JSON_ARRAY != vam->json_tree.type)
5231     {
5232       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5233       vat_json_init_array (&vam->json_tree);
5234     }
5235   node = vat_json_array_add (&vam->json_tree);
5236
5237   vat_json_init_object (node);
5238   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5239   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5240   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5241   u8 *s =
5242     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5243             0);
5244   vat_json_object_add_string_copy (node, "match", s);
5245 }
5246
5247 static void vl_api_pg_create_interface_reply_t_handler
5248   (vl_api_pg_create_interface_reply_t * mp)
5249 {
5250   vat_main_t *vam = &vat_main;
5251
5252   vam->retval = ntohl (mp->retval);
5253   vam->result_ready = 1;
5254 }
5255
5256 static void vl_api_pg_create_interface_reply_t_handler_json
5257   (vl_api_pg_create_interface_reply_t * mp)
5258 {
5259   vat_main_t *vam = &vat_main;
5260   vat_json_node_t node;
5261
5262   i32 retval = ntohl (mp->retval);
5263   if (retval == 0)
5264     {
5265       vat_json_init_object (&node);
5266
5267       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5268
5269       vat_json_print (vam->ofp, &node);
5270       vat_json_free (&node);
5271     }
5272   vam->retval = ntohl (mp->retval);
5273   vam->result_ready = 1;
5274 }
5275
5276 static void vl_api_policer_classify_details_t_handler
5277   (vl_api_policer_classify_details_t * mp)
5278 {
5279   vat_main_t *vam = &vat_main;
5280
5281   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5282          ntohl (mp->table_index));
5283 }
5284
5285 static void vl_api_policer_classify_details_t_handler_json
5286   (vl_api_policer_classify_details_t * mp)
5287 {
5288   vat_main_t *vam = &vat_main;
5289   vat_json_node_t *node;
5290
5291   if (VAT_JSON_ARRAY != vam->json_tree.type)
5292     {
5293       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5294       vat_json_init_array (&vam->json_tree);
5295     }
5296   node = vat_json_array_add (&vam->json_tree);
5297
5298   vat_json_init_object (node);
5299   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5300   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5301 }
5302
5303 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5304   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5305 {
5306   vat_main_t *vam = &vat_main;
5307   i32 retval = ntohl (mp->retval);
5308   if (vam->async_mode)
5309     {
5310       vam->async_errors += (retval < 0);
5311     }
5312   else
5313     {
5314       vam->retval = retval;
5315       vam->sw_if_index = ntohl (mp->sw_if_index);
5316       vam->result_ready = 1;
5317     }
5318   vam->regenerate_interface_table = 1;
5319 }
5320
5321 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5322   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5323 {
5324   vat_main_t *vam = &vat_main;
5325   vat_json_node_t node;
5326
5327   vat_json_init_object (&node);
5328   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5329   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5330
5331   vat_json_print (vam->ofp, &node);
5332   vat_json_free (&node);
5333
5334   vam->retval = ntohl (mp->retval);
5335   vam->result_ready = 1;
5336 }
5337
5338 static void vl_api_flow_classify_details_t_handler
5339   (vl_api_flow_classify_details_t * mp)
5340 {
5341   vat_main_t *vam = &vat_main;
5342
5343   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5344          ntohl (mp->table_index));
5345 }
5346
5347 static void vl_api_flow_classify_details_t_handler_json
5348   (vl_api_flow_classify_details_t * mp)
5349 {
5350   vat_main_t *vam = &vat_main;
5351   vat_json_node_t *node;
5352
5353   if (VAT_JSON_ARRAY != vam->json_tree.type)
5354     {
5355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5356       vat_json_init_array (&vam->json_tree);
5357     }
5358   node = vat_json_array_add (&vam->json_tree);
5359
5360   vat_json_init_object (node);
5361   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5362   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5363 }
5364
5365 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5366 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5367 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5368 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5369 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5370 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5371 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5372 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5373 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5374 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5375 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5376 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5377 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5378 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5379 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5380 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5381 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5382 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5383 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5384 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5385 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5386 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5387
5388 /*
5389  * Generate boilerplate reply handlers, which
5390  * dig the return value out of the xxx_reply_t API message,
5391  * stick it into vam->retval, and set vam->result_ready
5392  *
5393  * Could also do this by pointing N message decode slots at
5394  * a single function, but that could break in subtle ways.
5395  */
5396
5397 #define foreach_standard_reply_retval_handler           \
5398 _(sw_interface_set_flags_reply)                         \
5399 _(sw_interface_add_del_address_reply)                   \
5400 _(sw_interface_set_rx_mode_reply)                       \
5401 _(sw_interface_set_table_reply)                         \
5402 _(sw_interface_set_mpls_enable_reply)                   \
5403 _(sw_interface_set_vpath_reply)                         \
5404 _(sw_interface_set_vxlan_bypass_reply)                  \
5405 _(sw_interface_set_geneve_bypass_reply)                 \
5406 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5407 _(sw_interface_set_l2_bridge_reply)                     \
5408 _(bridge_domain_add_del_reply)                          \
5409 _(sw_interface_set_l2_xconnect_reply)                   \
5410 _(l2fib_add_del_reply)                                  \
5411 _(l2fib_flush_int_reply)                                \
5412 _(l2fib_flush_bd_reply)                                 \
5413 _(ip_add_del_route_reply)                               \
5414 _(ip_table_add_del_reply)                               \
5415 _(ip_mroute_add_del_reply)                              \
5416 _(mpls_route_add_del_reply)                             \
5417 _(mpls_table_add_del_reply)                             \
5418 _(mpls_ip_bind_unbind_reply)                            \
5419 _(bier_route_add_del_reply)                             \
5420 _(bier_table_add_del_reply)                             \
5421 _(proxy_arp_add_del_reply)                              \
5422 _(proxy_arp_intfc_enable_disable_reply)                 \
5423 _(sw_interface_set_unnumbered_reply)                    \
5424 _(ip_neighbor_add_del_reply)                            \
5425 _(oam_add_del_reply)                                    \
5426 _(reset_fib_reply)                                      \
5427 _(dhcp_proxy_config_reply)                              \
5428 _(dhcp_proxy_set_vss_reply)                             \
5429 _(dhcp_client_config_reply)                             \
5430 _(set_ip_flow_hash_reply)                               \
5431 _(sw_interface_ip6_enable_disable_reply)                \
5432 _(sw_interface_ip6_set_link_local_address_reply)        \
5433 _(ip6nd_proxy_add_del_reply)                            \
5434 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5435 _(sw_interface_ip6nd_ra_config_reply)                   \
5436 _(set_arp_neighbor_limit_reply)                         \
5437 _(l2_patch_add_del_reply)                               \
5438 _(sr_policy_add_reply)                                  \
5439 _(sr_policy_mod_reply)                                  \
5440 _(sr_policy_del_reply)                                  \
5441 _(sr_localsid_add_del_reply)                            \
5442 _(sr_steering_add_del_reply)                            \
5443 _(classify_add_del_session_reply)                       \
5444 _(classify_set_interface_ip_table_reply)                \
5445 _(classify_set_interface_l2_tables_reply)               \
5446 _(l2tpv3_set_tunnel_cookies_reply)                      \
5447 _(l2tpv3_interface_enable_disable_reply)                \
5448 _(l2tpv3_set_lookup_key_reply)                          \
5449 _(l2_fib_clear_table_reply)                             \
5450 _(l2_interface_efp_filter_reply)                        \
5451 _(l2_interface_vlan_tag_rewrite_reply)                  \
5452 _(modify_vhost_user_if_reply)                           \
5453 _(delete_vhost_user_if_reply)                           \
5454 _(ip_probe_neighbor_reply)                              \
5455 _(ip_scan_neighbor_enable_disable_reply)                \
5456 _(want_ip4_arp_events_reply)                            \
5457 _(want_ip6_nd_events_reply)                             \
5458 _(want_l2_macs_events_reply)                            \
5459 _(input_acl_set_interface_reply)                        \
5460 _(ipsec_spd_add_del_reply)                              \
5461 _(ipsec_interface_add_del_spd_reply)                    \
5462 _(ipsec_spd_add_del_entry_reply)                        \
5463 _(ipsec_sad_add_del_entry_reply)                        \
5464 _(ipsec_sa_set_key_reply)                               \
5465 _(ipsec_tunnel_if_add_del_reply)                        \
5466 _(ipsec_tunnel_if_set_key_reply)                        \
5467 _(ipsec_tunnel_if_set_sa_reply)                         \
5468 _(ikev2_profile_add_del_reply)                          \
5469 _(ikev2_profile_set_auth_reply)                         \
5470 _(ikev2_profile_set_id_reply)                           \
5471 _(ikev2_profile_set_ts_reply)                           \
5472 _(ikev2_set_local_key_reply)                            \
5473 _(ikev2_set_responder_reply)                            \
5474 _(ikev2_set_ike_transforms_reply)                       \
5475 _(ikev2_set_esp_transforms_reply)                       \
5476 _(ikev2_set_sa_lifetime_reply)                          \
5477 _(ikev2_initiate_sa_init_reply)                         \
5478 _(ikev2_initiate_del_ike_sa_reply)                      \
5479 _(ikev2_initiate_del_child_sa_reply)                    \
5480 _(ikev2_initiate_rekey_child_sa_reply)                  \
5481 _(delete_loopback_reply)                                \
5482 _(bd_ip_mac_add_del_reply)                              \
5483 _(map_del_domain_reply)                                 \
5484 _(map_add_del_rule_reply)                               \
5485 _(want_interface_events_reply)                          \
5486 _(want_stats_reply)                                     \
5487 _(cop_interface_enable_disable_reply)                   \
5488 _(cop_whitelist_enable_disable_reply)                   \
5489 _(sw_interface_clear_stats_reply)                       \
5490 _(ioam_enable_reply)                                    \
5491 _(ioam_disable_reply)                                   \
5492 _(one_add_del_locator_reply)                            \
5493 _(one_add_del_local_eid_reply)                          \
5494 _(one_add_del_remote_mapping_reply)                     \
5495 _(one_add_del_adjacency_reply)                          \
5496 _(one_add_del_map_resolver_reply)                       \
5497 _(one_add_del_map_server_reply)                         \
5498 _(one_enable_disable_reply)                             \
5499 _(one_rloc_probe_enable_disable_reply)                  \
5500 _(one_map_register_enable_disable_reply)                \
5501 _(one_map_register_set_ttl_reply)                       \
5502 _(one_set_transport_protocol_reply)                     \
5503 _(one_map_register_fallback_threshold_reply)            \
5504 _(one_pitr_set_locator_set_reply)                       \
5505 _(one_map_request_mode_reply)                           \
5506 _(one_add_del_map_request_itr_rlocs_reply)              \
5507 _(one_eid_table_add_del_map_reply)                      \
5508 _(one_use_petr_reply)                                   \
5509 _(one_stats_enable_disable_reply)                       \
5510 _(one_add_del_l2_arp_entry_reply)                       \
5511 _(one_add_del_ndp_entry_reply)                          \
5512 _(one_stats_flush_reply)                                \
5513 _(one_enable_disable_xtr_mode_reply)                    \
5514 _(one_enable_disable_pitr_mode_reply)                   \
5515 _(one_enable_disable_petr_mode_reply)                   \
5516 _(gpe_enable_disable_reply)                             \
5517 _(gpe_set_encap_mode_reply)                             \
5518 _(gpe_add_del_iface_reply)                              \
5519 _(gpe_add_del_native_fwd_rpath_reply)                   \
5520 _(af_packet_delete_reply)                               \
5521 _(policer_classify_set_interface_reply)                 \
5522 _(netmap_create_reply)                                  \
5523 _(netmap_delete_reply)                                  \
5524 _(set_ipfix_exporter_reply)                             \
5525 _(set_ipfix_classify_stream_reply)                      \
5526 _(ipfix_classify_table_add_del_reply)                   \
5527 _(flow_classify_set_interface_reply)                    \
5528 _(sw_interface_span_enable_disable_reply)               \
5529 _(pg_capture_reply)                                     \
5530 _(pg_enable_disable_reply)                              \
5531 _(ip_source_and_port_range_check_add_del_reply)         \
5532 _(ip_source_and_port_range_check_interface_add_del_reply)\
5533 _(delete_subif_reply)                                   \
5534 _(l2_interface_pbb_tag_rewrite_reply)                   \
5535 _(punt_reply)                                           \
5536 _(feature_enable_disable_reply)                         \
5537 _(sw_interface_tag_add_del_reply)                       \
5538 _(sw_interface_set_mtu_reply)                           \
5539 _(p2p_ethernet_add_reply)                               \
5540 _(p2p_ethernet_del_reply)                               \
5541 _(lldp_config_reply)                                    \
5542 _(sw_interface_set_lldp_reply)                          \
5543 _(tcp_configure_src_addresses_reply)                    \
5544 _(dns_enable_disable_reply)                             \
5545 _(dns_name_server_add_del_reply)                        \
5546 _(session_rule_add_del_reply)                           \
5547 _(ip_container_proxy_add_del_reply)                     \
5548 _(output_acl_set_interface_reply)                       \
5549 _(qos_record_enable_disable_reply)
5550
5551 #define _(n)                                    \
5552     static void vl_api_##n##_t_handler          \
5553     (vl_api_##n##_t * mp)                       \
5554     {                                           \
5555         vat_main_t * vam = &vat_main;           \
5556         i32 retval = ntohl(mp->retval);         \
5557         if (vam->async_mode) {                  \
5558             vam->async_errors += (retval < 0);  \
5559         } else {                                \
5560             vam->retval = retval;               \
5561             vam->result_ready = 1;              \
5562         }                                       \
5563     }
5564 foreach_standard_reply_retval_handler;
5565 #undef _
5566
5567 #define _(n)                                    \
5568     static void vl_api_##n##_t_handler_json     \
5569     (vl_api_##n##_t * mp)                       \
5570     {                                           \
5571         vat_main_t * vam = &vat_main;           \
5572         vat_json_node_t node;                   \
5573         vat_json_init_object(&node);            \
5574         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5575         vat_json_print(vam->ofp, &node);        \
5576         vam->retval = ntohl(mp->retval);        \
5577         vam->result_ready = 1;                  \
5578     }
5579 foreach_standard_reply_retval_handler;
5580 #undef _
5581
5582 /*
5583  * Table of message reply handlers, must include boilerplate handlers
5584  * we just generated
5585  */
5586
5587 #define foreach_vpe_api_reply_msg                                       \
5588 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5589 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5590 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5591 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5592 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5593 _(CLI_REPLY, cli_reply)                                                 \
5594 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5595 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5596   sw_interface_add_del_address_reply)                                   \
5597 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5598 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5599 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5600 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5601 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5602 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5603 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5604 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5605   sw_interface_set_l2_xconnect_reply)                                   \
5606 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5607   sw_interface_set_l2_bridge_reply)                                     \
5608 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5609 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5610 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5611 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5612 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5613 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5614 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5615 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5616 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5617 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5618 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5619 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5620 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5621 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5622 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5623 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5624 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5625 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5626 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5627 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5628 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5629 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5630 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5631 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5632 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5633 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5634 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5635 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5636 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5637 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5638 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5639   proxy_arp_intfc_enable_disable_reply)                                 \
5640 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5641 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5642   sw_interface_set_unnumbered_reply)                                    \
5643 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5644 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5645 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5646 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5647 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5648 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5649 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5650 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5651 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5652 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5653 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5654   sw_interface_ip6_enable_disable_reply)                                \
5655 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5656   sw_interface_ip6_set_link_local_address_reply)                        \
5657 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5658 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5659 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5660   sw_interface_ip6nd_ra_prefix_reply)                                   \
5661 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5662   sw_interface_ip6nd_ra_config_reply)                                   \
5663 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5664 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5665 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5666 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5667 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5668 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5669 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5670 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5671 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5672 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5673 classify_set_interface_ip_table_reply)                                  \
5674 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5675   classify_set_interface_l2_tables_reply)                               \
5676 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5677 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5678 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5679 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5680 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5681   l2tpv3_interface_enable_disable_reply)                                \
5682 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5683 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5684 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5685 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5686 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5687 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5688 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5689 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5690 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5691 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5692 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5693 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5694 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5695 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5696 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5697 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5698 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5699 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5700 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5701 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5702 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5703 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5704 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5705 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5706 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5707 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5708 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5709 _(L2_MACS_EVENT, l2_macs_event)                                         \
5710 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5711 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5712 _(IP_DETAILS, ip_details)                                               \
5713 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5714 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5715 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5716 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5717 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5718 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5719 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5720 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5721 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5722 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5723 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5724 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5725 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5726 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5727 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5728 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5729 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5730 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5731 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5732 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5733 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5734 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5735 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5736 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5737 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5738 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5739 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5740 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5741 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5742 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5743 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5744 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5745 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5746 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5747 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5748 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5749 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5750 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5751 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5752 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5753 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5754 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5755 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5756 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5757 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5758 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5759 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5760 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5761   one_map_register_enable_disable_reply)                                \
5762 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5763 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5764 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5765 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5766   one_map_register_fallback_threshold_reply)                            \
5767 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5768   one_rloc_probe_enable_disable_reply)                                  \
5769 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5770 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5771 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5772 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5773 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5774 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5775 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5776 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5777 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5778 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5779 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5780 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5781 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5782 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5783 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5784 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5785   show_one_stats_enable_disable_reply)                                  \
5786 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5787 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5788 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5789 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5790 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5791 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5792 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5793 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5794   one_enable_disable_pitr_mode_reply)                                   \
5795 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5796   one_enable_disable_petr_mode_reply)                                   \
5797 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5798 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5799 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5800 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5801 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5802 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5803 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5804 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5805 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5806 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5807 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5808 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5809   gpe_add_del_native_fwd_rpath_reply)                                   \
5810 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5811   gpe_fwd_entry_path_details)                                           \
5812 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5813 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5814   one_add_del_map_request_itr_rlocs_reply)                              \
5815 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5816   one_get_map_request_itr_rlocs_reply)                                  \
5817 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5818 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5819 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5820 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5821 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5822 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5823   show_one_map_register_state_reply)                                    \
5824 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5825 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5826   show_one_map_register_fallback_threshold_reply)                       \
5827 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5828 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5829 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5830 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5831 _(POLICER_DETAILS, policer_details)                                     \
5832 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5833 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5834 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5835 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5836 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5837 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5838 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5839 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5840 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5841 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5842 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5843 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5844 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5845 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5846 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5847 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5848 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5849 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5850 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5851 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5852 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5853 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5854 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5855 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5856 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5857  ip_source_and_port_range_check_add_del_reply)                          \
5858 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5859  ip_source_and_port_range_check_interface_add_del_reply)                \
5860 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5861 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5862 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5863 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5864 _(PUNT_REPLY, punt_reply)                                               \
5865 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5866 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5867 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5868 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5869 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5870 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5871 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5872 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5873 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5874 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5875 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5876 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5877 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5878 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5879 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5880 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5881 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5882 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5883 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5884 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5885 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5886 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5887 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5888
5889 #define foreach_standalone_reply_msg                                    \
5890 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5891 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5892 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5893 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5894 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5895 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5896 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5897
5898 typedef struct
5899 {
5900   u8 *name;
5901   u32 value;
5902 } name_sort_t;
5903
5904 #define STR_VTR_OP_CASE(op)     \
5905     case L2_VTR_ ## op:         \
5906         return "" # op;
5907
5908 static const char *
5909 str_vtr_op (u32 vtr_op)
5910 {
5911   switch (vtr_op)
5912     {
5913       STR_VTR_OP_CASE (DISABLED);
5914       STR_VTR_OP_CASE (PUSH_1);
5915       STR_VTR_OP_CASE (PUSH_2);
5916       STR_VTR_OP_CASE (POP_1);
5917       STR_VTR_OP_CASE (POP_2);
5918       STR_VTR_OP_CASE (TRANSLATE_1_1);
5919       STR_VTR_OP_CASE (TRANSLATE_1_2);
5920       STR_VTR_OP_CASE (TRANSLATE_2_1);
5921       STR_VTR_OP_CASE (TRANSLATE_2_2);
5922     }
5923
5924   return "UNKNOWN";
5925 }
5926
5927 static int
5928 dump_sub_interface_table (vat_main_t * vam)
5929 {
5930   const sw_interface_subif_t *sub = NULL;
5931
5932   if (vam->json_output)
5933     {
5934       clib_warning
5935         ("JSON output supported only for VPE API calls and dump_stats_table");
5936       return -99;
5937     }
5938
5939   print (vam->ofp,
5940          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5941          "Interface", "sw_if_index",
5942          "sub id", "dot1ad", "tags", "outer id",
5943          "inner id", "exact", "default", "outer any", "inner any");
5944
5945   vec_foreach (sub, vam->sw_if_subif_table)
5946   {
5947     print (vam->ofp,
5948            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5949            sub->interface_name,
5950            sub->sw_if_index,
5951            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5952            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5953            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5954            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5955     if (sub->vtr_op != L2_VTR_DISABLED)
5956       {
5957         print (vam->ofp,
5958                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5959                "tag1: %d tag2: %d ]",
5960                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5961                sub->vtr_tag1, sub->vtr_tag2);
5962       }
5963   }
5964
5965   return 0;
5966 }
5967
5968 static int
5969 name_sort_cmp (void *a1, void *a2)
5970 {
5971   name_sort_t *n1 = a1;
5972   name_sort_t *n2 = a2;
5973
5974   return strcmp ((char *) n1->name, (char *) n2->name);
5975 }
5976
5977 static int
5978 dump_interface_table (vat_main_t * vam)
5979 {
5980   hash_pair_t *p;
5981   name_sort_t *nses = 0, *ns;
5982
5983   if (vam->json_output)
5984     {
5985       clib_warning
5986         ("JSON output supported only for VPE API calls and dump_stats_table");
5987       return -99;
5988     }
5989
5990   /* *INDENT-OFF* */
5991   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5992   ({
5993     vec_add2 (nses, ns, 1);
5994     ns->name = (u8 *)(p->key);
5995     ns->value = (u32) p->value[0];
5996   }));
5997   /* *INDENT-ON* */
5998
5999   vec_sort_with_function (nses, name_sort_cmp);
6000
6001   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6002   vec_foreach (ns, nses)
6003   {
6004     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6005   }
6006   vec_free (nses);
6007   return 0;
6008 }
6009
6010 static int
6011 dump_ip_table (vat_main_t * vam, int is_ipv6)
6012 {
6013   const ip_details_t *det = NULL;
6014   const ip_address_details_t *address = NULL;
6015   u32 i = ~0;
6016
6017   print (vam->ofp, "%-12s", "sw_if_index");
6018
6019   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6020   {
6021     i++;
6022     if (!det->present)
6023       {
6024         continue;
6025       }
6026     print (vam->ofp, "%-12d", i);
6027     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6028     if (!det->addr)
6029       {
6030         continue;
6031       }
6032     vec_foreach (address, det->addr)
6033     {
6034       print (vam->ofp,
6035              "            %-30U%-13d",
6036              is_ipv6 ? format_ip6_address : format_ip4_address,
6037              address->ip, address->prefix_length);
6038     }
6039   }
6040
6041   return 0;
6042 }
6043
6044 static int
6045 dump_ipv4_table (vat_main_t * vam)
6046 {
6047   if (vam->json_output)
6048     {
6049       clib_warning
6050         ("JSON output supported only for VPE API calls and dump_stats_table");
6051       return -99;
6052     }
6053
6054   return dump_ip_table (vam, 0);
6055 }
6056
6057 static int
6058 dump_ipv6_table (vat_main_t * vam)
6059 {
6060   if (vam->json_output)
6061     {
6062       clib_warning
6063         ("JSON output supported only for VPE API calls and dump_stats_table");
6064       return -99;
6065     }
6066
6067   return dump_ip_table (vam, 1);
6068 }
6069
6070 static char *
6071 counter_type_to_str (u8 counter_type, u8 is_combined)
6072 {
6073   if (!is_combined)
6074     {
6075       switch (counter_type)
6076         {
6077         case VNET_INTERFACE_COUNTER_DROP:
6078           return "drop";
6079         case VNET_INTERFACE_COUNTER_PUNT:
6080           return "punt";
6081         case VNET_INTERFACE_COUNTER_IP4:
6082           return "ip4";
6083         case VNET_INTERFACE_COUNTER_IP6:
6084           return "ip6";
6085         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6086           return "rx-no-buf";
6087         case VNET_INTERFACE_COUNTER_RX_MISS:
6088           return "rx-miss";
6089         case VNET_INTERFACE_COUNTER_RX_ERROR:
6090           return "rx-error";
6091         case VNET_INTERFACE_COUNTER_TX_ERROR:
6092           return "tx-error";
6093         default:
6094           return "INVALID-COUNTER-TYPE";
6095         }
6096     }
6097   else
6098     {
6099       switch (counter_type)
6100         {
6101         case VNET_INTERFACE_COUNTER_RX:
6102           return "rx";
6103         case VNET_INTERFACE_COUNTER_TX:
6104           return "tx";
6105         default:
6106           return "INVALID-COUNTER-TYPE";
6107         }
6108     }
6109 }
6110
6111 static int
6112 dump_stats_table (vat_main_t * vam)
6113 {
6114   vat_json_node_t node;
6115   vat_json_node_t *msg_array;
6116   vat_json_node_t *msg;
6117   vat_json_node_t *counter_array;
6118   vat_json_node_t *counter;
6119   interface_counter_t c;
6120   u64 packets;
6121   ip4_fib_counter_t *c4;
6122   ip6_fib_counter_t *c6;
6123   ip4_nbr_counter_t *n4;
6124   ip6_nbr_counter_t *n6;
6125   int i, j;
6126
6127   if (!vam->json_output)
6128     {
6129       clib_warning ("dump_stats_table supported only in JSON format");
6130       return -99;
6131     }
6132
6133   vat_json_init_object (&node);
6134
6135   /* interface counters */
6136   msg_array = vat_json_object_add (&node, "interface_counters");
6137   vat_json_init_array (msg_array);
6138   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6139     {
6140       msg = vat_json_array_add (msg_array);
6141       vat_json_init_object (msg);
6142       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6143                                        (u8 *) counter_type_to_str (i, 0));
6144       vat_json_object_add_int (msg, "is_combined", 0);
6145       counter_array = vat_json_object_add (msg, "data");
6146       vat_json_init_array (counter_array);
6147       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6148         {
6149           packets = vam->simple_interface_counters[i][j];
6150           vat_json_array_add_uint (counter_array, packets);
6151         }
6152     }
6153   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6154     {
6155       msg = vat_json_array_add (msg_array);
6156       vat_json_init_object (msg);
6157       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6158                                        (u8 *) counter_type_to_str (i, 1));
6159       vat_json_object_add_int (msg, "is_combined", 1);
6160       counter_array = vat_json_object_add (msg, "data");
6161       vat_json_init_array (counter_array);
6162       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6163         {
6164           c = vam->combined_interface_counters[i][j];
6165           counter = vat_json_array_add (counter_array);
6166           vat_json_init_object (counter);
6167           vat_json_object_add_uint (counter, "packets", c.packets);
6168           vat_json_object_add_uint (counter, "bytes", c.bytes);
6169         }
6170     }
6171
6172   /* ip4 fib counters */
6173   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6174   vat_json_init_array (msg_array);
6175   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6176     {
6177       msg = vat_json_array_add (msg_array);
6178       vat_json_init_object (msg);
6179       vat_json_object_add_uint (msg, "vrf_id",
6180                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6181       counter_array = vat_json_object_add (msg, "c");
6182       vat_json_init_array (counter_array);
6183       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6184         {
6185           counter = vat_json_array_add (counter_array);
6186           vat_json_init_object (counter);
6187           c4 = &vam->ip4_fib_counters[i][j];
6188           vat_json_object_add_ip4 (counter, "address", c4->address);
6189           vat_json_object_add_uint (counter, "address_length",
6190                                     c4->address_length);
6191           vat_json_object_add_uint (counter, "packets", c4->packets);
6192           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6193         }
6194     }
6195
6196   /* ip6 fib counters */
6197   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6198   vat_json_init_array (msg_array);
6199   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6200     {
6201       msg = vat_json_array_add (msg_array);
6202       vat_json_init_object (msg);
6203       vat_json_object_add_uint (msg, "vrf_id",
6204                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6205       counter_array = vat_json_object_add (msg, "c");
6206       vat_json_init_array (counter_array);
6207       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6208         {
6209           counter = vat_json_array_add (counter_array);
6210           vat_json_init_object (counter);
6211           c6 = &vam->ip6_fib_counters[i][j];
6212           vat_json_object_add_ip6 (counter, "address", c6->address);
6213           vat_json_object_add_uint (counter, "address_length",
6214                                     c6->address_length);
6215           vat_json_object_add_uint (counter, "packets", c6->packets);
6216           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6217         }
6218     }
6219
6220   /* ip4 nbr counters */
6221   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6222   vat_json_init_array (msg_array);
6223   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6224     {
6225       msg = vat_json_array_add (msg_array);
6226       vat_json_init_object (msg);
6227       vat_json_object_add_uint (msg, "sw_if_index", i);
6228       counter_array = vat_json_object_add (msg, "c");
6229       vat_json_init_array (counter_array);
6230       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6231         {
6232           counter = vat_json_array_add (counter_array);
6233           vat_json_init_object (counter);
6234           n4 = &vam->ip4_nbr_counters[i][j];
6235           vat_json_object_add_ip4 (counter, "address", n4->address);
6236           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6237           vat_json_object_add_uint (counter, "packets", n4->packets);
6238           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6239         }
6240     }
6241
6242   /* ip6 nbr counters */
6243   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6244   vat_json_init_array (msg_array);
6245   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6246     {
6247       msg = vat_json_array_add (msg_array);
6248       vat_json_init_object (msg);
6249       vat_json_object_add_uint (msg, "sw_if_index", i);
6250       counter_array = vat_json_object_add (msg, "c");
6251       vat_json_init_array (counter_array);
6252       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6253         {
6254           counter = vat_json_array_add (counter_array);
6255           vat_json_init_object (counter);
6256           n6 = &vam->ip6_nbr_counters[i][j];
6257           vat_json_object_add_ip6 (counter, "address", n6->address);
6258           vat_json_object_add_uint (counter, "packets", n6->packets);
6259           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6260         }
6261     }
6262
6263   vat_json_print (vam->ofp, &node);
6264   vat_json_free (&node);
6265
6266   return 0;
6267 }
6268
6269 /*
6270  * Pass CLI buffers directly in the CLI_INBAND API message,
6271  * instead of an additional shared memory area.
6272  */
6273 static int
6274 exec_inband (vat_main_t * vam)
6275 {
6276   vl_api_cli_inband_t *mp;
6277   unformat_input_t *i = vam->input;
6278   int ret;
6279
6280   if (vec_len (i->buffer) == 0)
6281     return -1;
6282
6283   if (vam->exec_mode == 0 && unformat (i, "mode"))
6284     {
6285       vam->exec_mode = 1;
6286       return 0;
6287     }
6288   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6289     {
6290       vam->exec_mode = 0;
6291       return 0;
6292     }
6293
6294   /*
6295    * In order for the CLI command to work, it
6296    * must be a vector ending in \n, not a C-string ending
6297    * in \n\0.
6298    */
6299   u32 len = vec_len (vam->input->buffer);
6300   M2 (CLI_INBAND, mp, len);
6301   clib_memcpy (mp->cmd, vam->input->buffer, len);
6302   mp->length = htonl (len);
6303
6304   S (mp);
6305   W (ret);
6306   /* json responses may or may not include a useful reply... */
6307   if (vec_len (vam->cmd_reply))
6308     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6309   return ret;
6310 }
6311
6312 int
6313 exec (vat_main_t * vam)
6314 {
6315   return exec_inband (vam);
6316 }
6317
6318 static int
6319 api_create_loopback (vat_main_t * vam)
6320 {
6321   unformat_input_t *i = vam->input;
6322   vl_api_create_loopback_t *mp;
6323   vl_api_create_loopback_instance_t *mp_lbi;
6324   u8 mac_address[6];
6325   u8 mac_set = 0;
6326   u8 is_specified = 0;
6327   u32 user_instance = 0;
6328   int ret;
6329
6330   memset (mac_address, 0, sizeof (mac_address));
6331
6332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6333     {
6334       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6335         mac_set = 1;
6336       if (unformat (i, "instance %d", &user_instance))
6337         is_specified = 1;
6338       else
6339         break;
6340     }
6341
6342   if (is_specified)
6343     {
6344       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6345       mp_lbi->is_specified = is_specified;
6346       if (is_specified)
6347         mp_lbi->user_instance = htonl (user_instance);
6348       if (mac_set)
6349         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6350       S (mp_lbi);
6351     }
6352   else
6353     {
6354       /* Construct the API message */
6355       M (CREATE_LOOPBACK, mp);
6356       if (mac_set)
6357         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6358       S (mp);
6359     }
6360
6361   W (ret);
6362   return ret;
6363 }
6364
6365 static int
6366 api_delete_loopback (vat_main_t * vam)
6367 {
6368   unformat_input_t *i = vam->input;
6369   vl_api_delete_loopback_t *mp;
6370   u32 sw_if_index = ~0;
6371   int ret;
6372
6373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6374     {
6375       if (unformat (i, "sw_if_index %d", &sw_if_index))
6376         ;
6377       else
6378         break;
6379     }
6380
6381   if (sw_if_index == ~0)
6382     {
6383       errmsg ("missing sw_if_index");
6384       return -99;
6385     }
6386
6387   /* Construct the API message */
6388   M (DELETE_LOOPBACK, mp);
6389   mp->sw_if_index = ntohl (sw_if_index);
6390
6391   S (mp);
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_want_stats (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_want_stats_t *mp;
6401   int enable = -1;
6402   int ret;
6403
6404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6405     {
6406       if (unformat (i, "enable"))
6407         enable = 1;
6408       else if (unformat (i, "disable"))
6409         enable = 0;
6410       else
6411         break;
6412     }
6413
6414   if (enable == -1)
6415     {
6416       errmsg ("missing enable|disable");
6417       return -99;
6418     }
6419
6420   M (WANT_STATS, mp);
6421   mp->enable_disable = enable;
6422
6423   S (mp);
6424   W (ret);
6425   return ret;
6426 }
6427
6428 static int
6429 api_want_interface_events (vat_main_t * vam)
6430 {
6431   unformat_input_t *i = vam->input;
6432   vl_api_want_interface_events_t *mp;
6433   int enable = -1;
6434   int ret;
6435
6436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6437     {
6438       if (unformat (i, "enable"))
6439         enable = 1;
6440       else if (unformat (i, "disable"))
6441         enable = 0;
6442       else
6443         break;
6444     }
6445
6446   if (enable == -1)
6447     {
6448       errmsg ("missing enable|disable");
6449       return -99;
6450     }
6451
6452   M (WANT_INTERFACE_EVENTS, mp);
6453   mp->enable_disable = enable;
6454
6455   vam->interface_event_display = enable;
6456
6457   S (mp);
6458   W (ret);
6459   return ret;
6460 }
6461
6462
6463 /* Note: non-static, called once to set up the initial intfc table */
6464 int
6465 api_sw_interface_dump (vat_main_t * vam)
6466 {
6467   vl_api_sw_interface_dump_t *mp;
6468   vl_api_control_ping_t *mp_ping;
6469   hash_pair_t *p;
6470   name_sort_t *nses = 0, *ns;
6471   sw_interface_subif_t *sub = NULL;
6472   int ret;
6473
6474   /* Toss the old name table */
6475   /* *INDENT-OFF* */
6476   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6477   ({
6478     vec_add2 (nses, ns, 1);
6479     ns->name = (u8 *)(p->key);
6480     ns->value = (u32) p->value[0];
6481   }));
6482   /* *INDENT-ON* */
6483
6484   hash_free (vam->sw_if_index_by_interface_name);
6485
6486   vec_foreach (ns, nses) vec_free (ns->name);
6487
6488   vec_free (nses);
6489
6490   vec_foreach (sub, vam->sw_if_subif_table)
6491   {
6492     vec_free (sub->interface_name);
6493   }
6494   vec_free (vam->sw_if_subif_table);
6495
6496   /* recreate the interface name hash table */
6497   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6498
6499   /*
6500    * Ask for all interface names. Otherwise, the epic catalog of
6501    * name filters becomes ridiculously long, and vat ends up needing
6502    * to be taught about new interface types.
6503    */
6504   M (SW_INTERFACE_DUMP, mp);
6505   S (mp);
6506
6507   /* Use a control ping for synchronization */
6508   MPING (CONTROL_PING, mp_ping);
6509   S (mp_ping);
6510
6511   W (ret);
6512   return ret;
6513 }
6514
6515 static int
6516 api_sw_interface_set_flags (vat_main_t * vam)
6517 {
6518   unformat_input_t *i = vam->input;
6519   vl_api_sw_interface_set_flags_t *mp;
6520   u32 sw_if_index;
6521   u8 sw_if_index_set = 0;
6522   u8 admin_up = 0;
6523   int ret;
6524
6525   /* Parse args required to build the message */
6526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6527     {
6528       if (unformat (i, "admin-up"))
6529         admin_up = 1;
6530       else if (unformat (i, "admin-down"))
6531         admin_up = 0;
6532       else
6533         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6534         sw_if_index_set = 1;
6535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6536         sw_if_index_set = 1;
6537       else
6538         break;
6539     }
6540
6541   if (sw_if_index_set == 0)
6542     {
6543       errmsg ("missing interface name or sw_if_index");
6544       return -99;
6545     }
6546
6547   /* Construct the API message */
6548   M (SW_INTERFACE_SET_FLAGS, mp);
6549   mp->sw_if_index = ntohl (sw_if_index);
6550   mp->admin_up_down = admin_up;
6551
6552   /* send it... */
6553   S (mp);
6554
6555   /* Wait for a reply, return the good/bad news... */
6556   W (ret);
6557   return ret;
6558 }
6559
6560 static int
6561 api_sw_interface_set_rx_mode (vat_main_t * vam)
6562 {
6563   unformat_input_t *i = vam->input;
6564   vl_api_sw_interface_set_rx_mode_t *mp;
6565   u32 sw_if_index;
6566   u8 sw_if_index_set = 0;
6567   int ret;
6568   u8 queue_id_valid = 0;
6569   u32 queue_id;
6570   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6571
6572   /* Parse args required to build the message */
6573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6574     {
6575       if (unformat (i, "queue %d", &queue_id))
6576         queue_id_valid = 1;
6577       else if (unformat (i, "polling"))
6578         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6579       else if (unformat (i, "interrupt"))
6580         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6581       else if (unformat (i, "adaptive"))
6582         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6583       else
6584         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6585         sw_if_index_set = 1;
6586       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6587         sw_if_index_set = 1;
6588       else
6589         break;
6590     }
6591
6592   if (sw_if_index_set == 0)
6593     {
6594       errmsg ("missing interface name or sw_if_index");
6595       return -99;
6596     }
6597   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6598     {
6599       errmsg ("missing rx-mode");
6600       return -99;
6601     }
6602
6603   /* Construct the API message */
6604   M (SW_INTERFACE_SET_RX_MODE, mp);
6605   mp->sw_if_index = ntohl (sw_if_index);
6606   mp->mode = mode;
6607   mp->queue_id_valid = queue_id_valid;
6608   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6609
6610   /* send it... */
6611   S (mp);
6612
6613   /* Wait for a reply, return the good/bad news... */
6614   W (ret);
6615   return ret;
6616 }
6617
6618 static int
6619 api_sw_interface_clear_stats (vat_main_t * vam)
6620 {
6621   unformat_input_t *i = vam->input;
6622   vl_api_sw_interface_clear_stats_t *mp;
6623   u32 sw_if_index;
6624   u8 sw_if_index_set = 0;
6625   int ret;
6626
6627   /* Parse args required to build the message */
6628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6629     {
6630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6631         sw_if_index_set = 1;
6632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6633         sw_if_index_set = 1;
6634       else
6635         break;
6636     }
6637
6638   /* Construct the API message */
6639   M (SW_INTERFACE_CLEAR_STATS, mp);
6640
6641   if (sw_if_index_set == 1)
6642     mp->sw_if_index = ntohl (sw_if_index);
6643   else
6644     mp->sw_if_index = ~0;
6645
6646   /* send it... */
6647   S (mp);
6648
6649   /* Wait for a reply, return the good/bad news... */
6650   W (ret);
6651   return ret;
6652 }
6653
6654 static int
6655 api_sw_interface_add_del_address (vat_main_t * vam)
6656 {
6657   unformat_input_t *i = vam->input;
6658   vl_api_sw_interface_add_del_address_t *mp;
6659   u32 sw_if_index;
6660   u8 sw_if_index_set = 0;
6661   u8 is_add = 1, del_all = 0;
6662   u32 address_length = 0;
6663   u8 v4_address_set = 0;
6664   u8 v6_address_set = 0;
6665   ip4_address_t v4address;
6666   ip6_address_t v6address;
6667   int ret;
6668
6669   /* Parse args required to build the message */
6670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6671     {
6672       if (unformat (i, "del-all"))
6673         del_all = 1;
6674       else if (unformat (i, "del"))
6675         is_add = 0;
6676       else
6677         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6678         sw_if_index_set = 1;
6679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6680         sw_if_index_set = 1;
6681       else if (unformat (i, "%U/%d",
6682                          unformat_ip4_address, &v4address, &address_length))
6683         v4_address_set = 1;
6684       else if (unformat (i, "%U/%d",
6685                          unformat_ip6_address, &v6address, &address_length))
6686         v6_address_set = 1;
6687       else
6688         break;
6689     }
6690
6691   if (sw_if_index_set == 0)
6692     {
6693       errmsg ("missing interface name or sw_if_index");
6694       return -99;
6695     }
6696   if (v4_address_set && v6_address_set)
6697     {
6698       errmsg ("both v4 and v6 addresses set");
6699       return -99;
6700     }
6701   if (!v4_address_set && !v6_address_set && !del_all)
6702     {
6703       errmsg ("no addresses set");
6704       return -99;
6705     }
6706
6707   /* Construct the API message */
6708   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6709
6710   mp->sw_if_index = ntohl (sw_if_index);
6711   mp->is_add = is_add;
6712   mp->del_all = del_all;
6713   if (v6_address_set)
6714     {
6715       mp->is_ipv6 = 1;
6716       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6717     }
6718   else
6719     {
6720       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6721     }
6722   mp->address_length = address_length;
6723
6724   /* send it... */
6725   S (mp);
6726
6727   /* Wait for a reply, return good/bad news  */
6728   W (ret);
6729   return ret;
6730 }
6731
6732 static int
6733 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6734 {
6735   unformat_input_t *i = vam->input;
6736   vl_api_sw_interface_set_mpls_enable_t *mp;
6737   u32 sw_if_index;
6738   u8 sw_if_index_set = 0;
6739   u8 enable = 1;
6740   int ret;
6741
6742   /* Parse args required to build the message */
6743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6744     {
6745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6748         sw_if_index_set = 1;
6749       else if (unformat (i, "disable"))
6750         enable = 0;
6751       else if (unformat (i, "dis"))
6752         enable = 0;
6753       else
6754         break;
6755     }
6756
6757   if (sw_if_index_set == 0)
6758     {
6759       errmsg ("missing interface name or sw_if_index");
6760       return -99;
6761     }
6762
6763   /* Construct the API message */
6764   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6765
6766   mp->sw_if_index = ntohl (sw_if_index);
6767   mp->enable = enable;
6768
6769   /* send it... */
6770   S (mp);
6771
6772   /* Wait for a reply... */
6773   W (ret);
6774   return ret;
6775 }
6776
6777 static int
6778 api_sw_interface_set_table (vat_main_t * vam)
6779 {
6780   unformat_input_t *i = vam->input;
6781   vl_api_sw_interface_set_table_t *mp;
6782   u32 sw_if_index, vrf_id = 0;
6783   u8 sw_if_index_set = 0;
6784   u8 is_ipv6 = 0;
6785   int ret;
6786
6787   /* Parse args required to build the message */
6788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6789     {
6790       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6791         sw_if_index_set = 1;
6792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6793         sw_if_index_set = 1;
6794       else if (unformat (i, "vrf %d", &vrf_id))
6795         ;
6796       else if (unformat (i, "ipv6"))
6797         is_ipv6 = 1;
6798       else
6799         break;
6800     }
6801
6802   if (sw_if_index_set == 0)
6803     {
6804       errmsg ("missing interface name or sw_if_index");
6805       return -99;
6806     }
6807
6808   /* Construct the API message */
6809   M (SW_INTERFACE_SET_TABLE, mp);
6810
6811   mp->sw_if_index = ntohl (sw_if_index);
6812   mp->is_ipv6 = is_ipv6;
6813   mp->vrf_id = ntohl (vrf_id);
6814
6815   /* send it... */
6816   S (mp);
6817
6818   /* Wait for a reply... */
6819   W (ret);
6820   return ret;
6821 }
6822
6823 static void vl_api_sw_interface_get_table_reply_t_handler
6824   (vl_api_sw_interface_get_table_reply_t * mp)
6825 {
6826   vat_main_t *vam = &vat_main;
6827
6828   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6829
6830   vam->retval = ntohl (mp->retval);
6831   vam->result_ready = 1;
6832
6833 }
6834
6835 static void vl_api_sw_interface_get_table_reply_t_handler_json
6836   (vl_api_sw_interface_get_table_reply_t * mp)
6837 {
6838   vat_main_t *vam = &vat_main;
6839   vat_json_node_t node;
6840
6841   vat_json_init_object (&node);
6842   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6843   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6844
6845   vat_json_print (vam->ofp, &node);
6846   vat_json_free (&node);
6847
6848   vam->retval = ntohl (mp->retval);
6849   vam->result_ready = 1;
6850 }
6851
6852 static int
6853 api_sw_interface_get_table (vat_main_t * vam)
6854 {
6855   unformat_input_t *i = vam->input;
6856   vl_api_sw_interface_get_table_t *mp;
6857   u32 sw_if_index;
6858   u8 sw_if_index_set = 0;
6859   u8 is_ipv6 = 0;
6860   int ret;
6861
6862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6863     {
6864       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6865         sw_if_index_set = 1;
6866       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6867         sw_if_index_set = 1;
6868       else if (unformat (i, "ipv6"))
6869         is_ipv6 = 1;
6870       else
6871         break;
6872     }
6873
6874   if (sw_if_index_set == 0)
6875     {
6876       errmsg ("missing interface name or sw_if_index");
6877       return -99;
6878     }
6879
6880   M (SW_INTERFACE_GET_TABLE, mp);
6881   mp->sw_if_index = htonl (sw_if_index);
6882   mp->is_ipv6 = is_ipv6;
6883
6884   S (mp);
6885   W (ret);
6886   return ret;
6887 }
6888
6889 static int
6890 api_sw_interface_set_vpath (vat_main_t * vam)
6891 {
6892   unformat_input_t *i = vam->input;
6893   vl_api_sw_interface_set_vpath_t *mp;
6894   u32 sw_if_index = 0;
6895   u8 sw_if_index_set = 0;
6896   u8 is_enable = 0;
6897   int ret;
6898
6899   /* Parse args required to build the message */
6900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6901     {
6902       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6903         sw_if_index_set = 1;
6904       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6905         sw_if_index_set = 1;
6906       else if (unformat (i, "enable"))
6907         is_enable = 1;
6908       else if (unformat (i, "disable"))
6909         is_enable = 0;
6910       else
6911         break;
6912     }
6913
6914   if (sw_if_index_set == 0)
6915     {
6916       errmsg ("missing interface name or sw_if_index");
6917       return -99;
6918     }
6919
6920   /* Construct the API message */
6921   M (SW_INTERFACE_SET_VPATH, mp);
6922
6923   mp->sw_if_index = ntohl (sw_if_index);
6924   mp->enable = is_enable;
6925
6926   /* send it... */
6927   S (mp);
6928
6929   /* Wait for a reply... */
6930   W (ret);
6931   return ret;
6932 }
6933
6934 static int
6935 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6936 {
6937   unformat_input_t *i = vam->input;
6938   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6939   u32 sw_if_index = 0;
6940   u8 sw_if_index_set = 0;
6941   u8 is_enable = 1;
6942   u8 is_ipv6 = 0;
6943   int ret;
6944
6945   /* Parse args required to build the message */
6946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947     {
6948       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6949         sw_if_index_set = 1;
6950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6951         sw_if_index_set = 1;
6952       else if (unformat (i, "enable"))
6953         is_enable = 1;
6954       else if (unformat (i, "disable"))
6955         is_enable = 0;
6956       else if (unformat (i, "ip4"))
6957         is_ipv6 = 0;
6958       else if (unformat (i, "ip6"))
6959         is_ipv6 = 1;
6960       else
6961         break;
6962     }
6963
6964   if (sw_if_index_set == 0)
6965     {
6966       errmsg ("missing interface name or sw_if_index");
6967       return -99;
6968     }
6969
6970   /* Construct the API message */
6971   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6972
6973   mp->sw_if_index = ntohl (sw_if_index);
6974   mp->enable = is_enable;
6975   mp->is_ipv6 = is_ipv6;
6976
6977   /* send it... */
6978   S (mp);
6979
6980   /* Wait for a reply... */
6981   W (ret);
6982   return ret;
6983 }
6984
6985 static int
6986 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6987 {
6988   unformat_input_t *i = vam->input;
6989   vl_api_sw_interface_set_geneve_bypass_t *mp;
6990   u32 sw_if_index = 0;
6991   u8 sw_if_index_set = 0;
6992   u8 is_enable = 1;
6993   u8 is_ipv6 = 0;
6994   int ret;
6995
6996   /* Parse args required to build the message */
6997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6998     {
6999       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7000         sw_if_index_set = 1;
7001       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7002         sw_if_index_set = 1;
7003       else if (unformat (i, "enable"))
7004         is_enable = 1;
7005       else if (unformat (i, "disable"))
7006         is_enable = 0;
7007       else if (unformat (i, "ip4"))
7008         is_ipv6 = 0;
7009       else if (unformat (i, "ip6"))
7010         is_ipv6 = 1;
7011       else
7012         break;
7013     }
7014
7015   if (sw_if_index_set == 0)
7016     {
7017       errmsg ("missing interface name or sw_if_index");
7018       return -99;
7019     }
7020
7021   /* Construct the API message */
7022   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7023
7024   mp->sw_if_index = ntohl (sw_if_index);
7025   mp->enable = is_enable;
7026   mp->is_ipv6 = is_ipv6;
7027
7028   /* send it... */
7029   S (mp);
7030
7031   /* Wait for a reply... */
7032   W (ret);
7033   return ret;
7034 }
7035
7036 static int
7037 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7038 {
7039   unformat_input_t *i = vam->input;
7040   vl_api_sw_interface_set_l2_xconnect_t *mp;
7041   u32 rx_sw_if_index;
7042   u8 rx_sw_if_index_set = 0;
7043   u32 tx_sw_if_index;
7044   u8 tx_sw_if_index_set = 0;
7045   u8 enable = 1;
7046   int ret;
7047
7048   /* Parse args required to build the message */
7049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7050     {
7051       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7052         rx_sw_if_index_set = 1;
7053       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7054         tx_sw_if_index_set = 1;
7055       else if (unformat (i, "rx"))
7056         {
7057           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7058             {
7059               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7060                             &rx_sw_if_index))
7061                 rx_sw_if_index_set = 1;
7062             }
7063           else
7064             break;
7065         }
7066       else if (unformat (i, "tx"))
7067         {
7068           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7069             {
7070               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7071                             &tx_sw_if_index))
7072                 tx_sw_if_index_set = 1;
7073             }
7074           else
7075             break;
7076         }
7077       else if (unformat (i, "enable"))
7078         enable = 1;
7079       else if (unformat (i, "disable"))
7080         enable = 0;
7081       else
7082         break;
7083     }
7084
7085   if (rx_sw_if_index_set == 0)
7086     {
7087       errmsg ("missing rx interface name or rx_sw_if_index");
7088       return -99;
7089     }
7090
7091   if (enable && (tx_sw_if_index_set == 0))
7092     {
7093       errmsg ("missing tx interface name or tx_sw_if_index");
7094       return -99;
7095     }
7096
7097   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7098
7099   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7100   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7101   mp->enable = enable;
7102
7103   S (mp);
7104   W (ret);
7105   return ret;
7106 }
7107
7108 static int
7109 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7110 {
7111   unformat_input_t *i = vam->input;
7112   vl_api_sw_interface_set_l2_bridge_t *mp;
7113   u32 rx_sw_if_index;
7114   u8 rx_sw_if_index_set = 0;
7115   u32 bd_id;
7116   u8 bd_id_set = 0;
7117   u8 bvi = 0;
7118   u32 shg = 0;
7119   u8 enable = 1;
7120   int ret;
7121
7122   /* Parse args required to build the message */
7123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7124     {
7125       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7126         rx_sw_if_index_set = 1;
7127       else if (unformat (i, "bd_id %d", &bd_id))
7128         bd_id_set = 1;
7129       else
7130         if (unformat
7131             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7132         rx_sw_if_index_set = 1;
7133       else if (unformat (i, "shg %d", &shg))
7134         ;
7135       else if (unformat (i, "bvi"))
7136         bvi = 1;
7137       else if (unformat (i, "enable"))
7138         enable = 1;
7139       else if (unformat (i, "disable"))
7140         enable = 0;
7141       else
7142         break;
7143     }
7144
7145   if (rx_sw_if_index_set == 0)
7146     {
7147       errmsg ("missing rx interface name or sw_if_index");
7148       return -99;
7149     }
7150
7151   if (enable && (bd_id_set == 0))
7152     {
7153       errmsg ("missing bridge domain");
7154       return -99;
7155     }
7156
7157   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7158
7159   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7160   mp->bd_id = ntohl (bd_id);
7161   mp->shg = (u8) shg;
7162   mp->bvi = bvi;
7163   mp->enable = enable;
7164
7165   S (mp);
7166   W (ret);
7167   return ret;
7168 }
7169
7170 static int
7171 api_bridge_domain_dump (vat_main_t * vam)
7172 {
7173   unformat_input_t *i = vam->input;
7174   vl_api_bridge_domain_dump_t *mp;
7175   vl_api_control_ping_t *mp_ping;
7176   u32 bd_id = ~0;
7177   int ret;
7178
7179   /* Parse args required to build the message */
7180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7181     {
7182       if (unformat (i, "bd_id %d", &bd_id))
7183         ;
7184       else
7185         break;
7186     }
7187
7188   M (BRIDGE_DOMAIN_DUMP, mp);
7189   mp->bd_id = ntohl (bd_id);
7190   S (mp);
7191
7192   /* Use a control ping for synchronization */
7193   MPING (CONTROL_PING, mp_ping);
7194   S (mp_ping);
7195
7196   W (ret);
7197   return ret;
7198 }
7199
7200 static int
7201 api_bridge_domain_add_del (vat_main_t * vam)
7202 {
7203   unformat_input_t *i = vam->input;
7204   vl_api_bridge_domain_add_del_t *mp;
7205   u32 bd_id = ~0;
7206   u8 is_add = 1;
7207   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7208   u8 *bd_tag = NULL;
7209   u32 mac_age = 0;
7210   int ret;
7211
7212   /* Parse args required to build the message */
7213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7214     {
7215       if (unformat (i, "bd_id %d", &bd_id))
7216         ;
7217       else if (unformat (i, "flood %d", &flood))
7218         ;
7219       else if (unformat (i, "uu-flood %d", &uu_flood))
7220         ;
7221       else if (unformat (i, "forward %d", &forward))
7222         ;
7223       else if (unformat (i, "learn %d", &learn))
7224         ;
7225       else if (unformat (i, "arp-term %d", &arp_term))
7226         ;
7227       else if (unformat (i, "mac-age %d", &mac_age))
7228         ;
7229       else if (unformat (i, "bd-tag %s", &bd_tag))
7230         ;
7231       else if (unformat (i, "del"))
7232         {
7233           is_add = 0;
7234           flood = uu_flood = forward = learn = 0;
7235         }
7236       else
7237         break;
7238     }
7239
7240   if (bd_id == ~0)
7241     {
7242       errmsg ("missing bridge domain");
7243       ret = -99;
7244       goto done;
7245     }
7246
7247   if (mac_age > 255)
7248     {
7249       errmsg ("mac age must be less than 256 ");
7250       ret = -99;
7251       goto done;
7252     }
7253
7254   if ((bd_tag) && (vec_len (bd_tag) > 63))
7255     {
7256       errmsg ("bd-tag cannot be longer than 63");
7257       ret = -99;
7258       goto done;
7259     }
7260
7261   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7262
7263   mp->bd_id = ntohl (bd_id);
7264   mp->flood = flood;
7265   mp->uu_flood = uu_flood;
7266   mp->forward = forward;
7267   mp->learn = learn;
7268   mp->arp_term = arp_term;
7269   mp->is_add = is_add;
7270   mp->mac_age = (u8) mac_age;
7271   if (bd_tag)
7272     {
7273       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7274       mp->bd_tag[vec_len (bd_tag)] = 0;
7275     }
7276   S (mp);
7277   W (ret);
7278
7279 done:
7280   vec_free (bd_tag);
7281   return ret;
7282 }
7283
7284 static int
7285 api_l2fib_flush_bd (vat_main_t * vam)
7286 {
7287   unformat_input_t *i = vam->input;
7288   vl_api_l2fib_flush_bd_t *mp;
7289   u32 bd_id = ~0;
7290   int ret;
7291
7292   /* Parse args required to build the message */
7293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7294     {
7295       if (unformat (i, "bd_id %d", &bd_id));
7296       else
7297         break;
7298     }
7299
7300   if (bd_id == ~0)
7301     {
7302       errmsg ("missing bridge domain");
7303       return -99;
7304     }
7305
7306   M (L2FIB_FLUSH_BD, mp);
7307
7308   mp->bd_id = htonl (bd_id);
7309
7310   S (mp);
7311   W (ret);
7312   return ret;
7313 }
7314
7315 static int
7316 api_l2fib_flush_int (vat_main_t * vam)
7317 {
7318   unformat_input_t *i = vam->input;
7319   vl_api_l2fib_flush_int_t *mp;
7320   u32 sw_if_index = ~0;
7321   int ret;
7322
7323   /* Parse args required to build the message */
7324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7325     {
7326       if (unformat (i, "sw_if_index %d", &sw_if_index));
7327       else
7328         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7329       else
7330         break;
7331     }
7332
7333   if (sw_if_index == ~0)
7334     {
7335       errmsg ("missing interface name or sw_if_index");
7336       return -99;
7337     }
7338
7339   M (L2FIB_FLUSH_INT, mp);
7340
7341   mp->sw_if_index = ntohl (sw_if_index);
7342
7343   S (mp);
7344   W (ret);
7345   return ret;
7346 }
7347
7348 static int
7349 api_l2fib_add_del (vat_main_t * vam)
7350 {
7351   unformat_input_t *i = vam->input;
7352   vl_api_l2fib_add_del_t *mp;
7353   f64 timeout;
7354   u8 mac[6] = { 0 };
7355   u8 mac_set = 0;
7356   u32 bd_id;
7357   u8 bd_id_set = 0;
7358   u32 sw_if_index = 0;
7359   u8 sw_if_index_set = 0;
7360   u8 is_add = 1;
7361   u8 static_mac = 0;
7362   u8 filter_mac = 0;
7363   u8 bvi_mac = 0;
7364   int count = 1;
7365   f64 before = 0;
7366   int j;
7367
7368   /* Parse args required to build the message */
7369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7370     {
7371       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7372         mac_set = 1;
7373       else if (unformat (i, "bd_id %d", &bd_id))
7374         bd_id_set = 1;
7375       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7376         sw_if_index_set = 1;
7377       else if (unformat (i, "sw_if"))
7378         {
7379           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7380             {
7381               if (unformat
7382                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7383                 sw_if_index_set = 1;
7384             }
7385           else
7386             break;
7387         }
7388       else if (unformat (i, "static"))
7389         static_mac = 1;
7390       else if (unformat (i, "filter"))
7391         {
7392           filter_mac = 1;
7393           static_mac = 1;
7394         }
7395       else if (unformat (i, "bvi"))
7396         {
7397           bvi_mac = 1;
7398           static_mac = 1;
7399         }
7400       else if (unformat (i, "del"))
7401         is_add = 0;
7402       else if (unformat (i, "count %d", &count))
7403         ;
7404       else
7405         break;
7406     }
7407
7408   if (mac_set == 0)
7409     {
7410       errmsg ("missing mac address");
7411       return -99;
7412     }
7413
7414   if (bd_id_set == 0)
7415     {
7416       errmsg ("missing bridge domain");
7417       return -99;
7418     }
7419
7420   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7421     {
7422       errmsg ("missing interface name or sw_if_index");
7423       return -99;
7424     }
7425
7426   if (count > 1)
7427     {
7428       /* Turn on async mode */
7429       vam->async_mode = 1;
7430       vam->async_errors = 0;
7431       before = vat_time_now (vam);
7432     }
7433
7434   for (j = 0; j < count; j++)
7435     {
7436       M (L2FIB_ADD_DEL, mp);
7437
7438       clib_memcpy (mp->mac, mac, 6);
7439       mp->bd_id = ntohl (bd_id);
7440       mp->is_add = is_add;
7441       mp->sw_if_index = ntohl (sw_if_index);
7442
7443       if (is_add)
7444         {
7445           mp->static_mac = static_mac;
7446           mp->filter_mac = filter_mac;
7447           mp->bvi_mac = bvi_mac;
7448         }
7449       increment_mac_address (mac);
7450       /* send it... */
7451       S (mp);
7452     }
7453
7454   if (count > 1)
7455     {
7456       vl_api_control_ping_t *mp_ping;
7457       f64 after;
7458
7459       /* Shut off async mode */
7460       vam->async_mode = 0;
7461
7462       MPING (CONTROL_PING, mp_ping);
7463       S (mp_ping);
7464
7465       timeout = vat_time_now (vam) + 1.0;
7466       while (vat_time_now (vam) < timeout)
7467         if (vam->result_ready == 1)
7468           goto out;
7469       vam->retval = -99;
7470
7471     out:
7472       if (vam->retval == -99)
7473         errmsg ("timeout");
7474
7475       if (vam->async_errors > 0)
7476         {
7477           errmsg ("%d asynchronous errors", vam->async_errors);
7478           vam->retval = -98;
7479         }
7480       vam->async_errors = 0;
7481       after = vat_time_now (vam);
7482
7483       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7484              count, after - before, count / (after - before));
7485     }
7486   else
7487     {
7488       int ret;
7489
7490       /* Wait for a reply... */
7491       W (ret);
7492       return ret;
7493     }
7494   /* Return the good/bad news */
7495   return (vam->retval);
7496 }
7497
7498 static int
7499 api_bridge_domain_set_mac_age (vat_main_t * vam)
7500 {
7501   unformat_input_t *i = vam->input;
7502   vl_api_bridge_domain_set_mac_age_t *mp;
7503   u32 bd_id = ~0;
7504   u32 mac_age = 0;
7505   int ret;
7506
7507   /* Parse args required to build the message */
7508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7509     {
7510       if (unformat (i, "bd_id %d", &bd_id));
7511       else if (unformat (i, "mac-age %d", &mac_age));
7512       else
7513         break;
7514     }
7515
7516   if (bd_id == ~0)
7517     {
7518       errmsg ("missing bridge domain");
7519       return -99;
7520     }
7521
7522   if (mac_age > 255)
7523     {
7524       errmsg ("mac age must be less than 256 ");
7525       return -99;
7526     }
7527
7528   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7529
7530   mp->bd_id = htonl (bd_id);
7531   mp->mac_age = (u8) mac_age;
7532
7533   S (mp);
7534   W (ret);
7535   return ret;
7536 }
7537
7538 static int
7539 api_l2_flags (vat_main_t * vam)
7540 {
7541   unformat_input_t *i = vam->input;
7542   vl_api_l2_flags_t *mp;
7543   u32 sw_if_index;
7544   u32 flags = 0;
7545   u8 sw_if_index_set = 0;
7546   u8 is_set = 0;
7547   int ret;
7548
7549   /* Parse args required to build the message */
7550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7551     {
7552       if (unformat (i, "sw_if_index %d", &sw_if_index))
7553         sw_if_index_set = 1;
7554       else if (unformat (i, "sw_if"))
7555         {
7556           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7557             {
7558               if (unformat
7559                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7560                 sw_if_index_set = 1;
7561             }
7562           else
7563             break;
7564         }
7565       else if (unformat (i, "learn"))
7566         flags |= L2_LEARN;
7567       else if (unformat (i, "forward"))
7568         flags |= L2_FWD;
7569       else if (unformat (i, "flood"))
7570         flags |= L2_FLOOD;
7571       else if (unformat (i, "uu-flood"))
7572         flags |= L2_UU_FLOOD;
7573       else if (unformat (i, "arp-term"))
7574         flags |= L2_ARP_TERM;
7575       else if (unformat (i, "off"))
7576         is_set = 0;
7577       else if (unformat (i, "disable"))
7578         is_set = 0;
7579       else
7580         break;
7581     }
7582
7583   if (sw_if_index_set == 0)
7584     {
7585       errmsg ("missing interface name or sw_if_index");
7586       return -99;
7587     }
7588
7589   M (L2_FLAGS, mp);
7590
7591   mp->sw_if_index = ntohl (sw_if_index);
7592   mp->feature_bitmap = ntohl (flags);
7593   mp->is_set = is_set;
7594
7595   S (mp);
7596   W (ret);
7597   return ret;
7598 }
7599
7600 static int
7601 api_bridge_flags (vat_main_t * vam)
7602 {
7603   unformat_input_t *i = vam->input;
7604   vl_api_bridge_flags_t *mp;
7605   u32 bd_id;
7606   u8 bd_id_set = 0;
7607   u8 is_set = 1;
7608   u32 flags = 0;
7609   int ret;
7610
7611   /* Parse args required to build the message */
7612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7613     {
7614       if (unformat (i, "bd_id %d", &bd_id))
7615         bd_id_set = 1;
7616       else if (unformat (i, "learn"))
7617         flags |= L2_LEARN;
7618       else if (unformat (i, "forward"))
7619         flags |= L2_FWD;
7620       else if (unformat (i, "flood"))
7621         flags |= L2_FLOOD;
7622       else if (unformat (i, "uu-flood"))
7623         flags |= L2_UU_FLOOD;
7624       else if (unformat (i, "arp-term"))
7625         flags |= L2_ARP_TERM;
7626       else if (unformat (i, "off"))
7627         is_set = 0;
7628       else if (unformat (i, "disable"))
7629         is_set = 0;
7630       else
7631         break;
7632     }
7633
7634   if (bd_id_set == 0)
7635     {
7636       errmsg ("missing bridge domain");
7637       return -99;
7638     }
7639
7640   M (BRIDGE_FLAGS, mp);
7641
7642   mp->bd_id = ntohl (bd_id);
7643   mp->feature_bitmap = ntohl (flags);
7644   mp->is_set = is_set;
7645
7646   S (mp);
7647   W (ret);
7648   return ret;
7649 }
7650
7651 static int
7652 api_bd_ip_mac_add_del (vat_main_t * vam)
7653 {
7654   unformat_input_t *i = vam->input;
7655   vl_api_bd_ip_mac_add_del_t *mp;
7656   u32 bd_id;
7657   u8 is_ipv6 = 0;
7658   u8 is_add = 1;
7659   u8 bd_id_set = 0;
7660   u8 ip_set = 0;
7661   u8 mac_set = 0;
7662   ip4_address_t v4addr;
7663   ip6_address_t v6addr;
7664   u8 macaddr[6];
7665   int ret;
7666
7667
7668   /* Parse args required to build the message */
7669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7670     {
7671       if (unformat (i, "bd_id %d", &bd_id))
7672         {
7673           bd_id_set++;
7674         }
7675       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7676         {
7677           ip_set++;
7678         }
7679       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7680         {
7681           ip_set++;
7682           is_ipv6++;
7683         }
7684       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7685         {
7686           mac_set++;
7687         }
7688       else if (unformat (i, "del"))
7689         is_add = 0;
7690       else
7691         break;
7692     }
7693
7694   if (bd_id_set == 0)
7695     {
7696       errmsg ("missing bridge domain");
7697       return -99;
7698     }
7699   else if (ip_set == 0)
7700     {
7701       errmsg ("missing IP address");
7702       return -99;
7703     }
7704   else if (mac_set == 0)
7705     {
7706       errmsg ("missing MAC address");
7707       return -99;
7708     }
7709
7710   M (BD_IP_MAC_ADD_DEL, mp);
7711
7712   mp->bd_id = ntohl (bd_id);
7713   mp->is_ipv6 = is_ipv6;
7714   mp->is_add = is_add;
7715   if (is_ipv6)
7716     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7717   else
7718     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7719   clib_memcpy (mp->mac_address, macaddr, 6);
7720   S (mp);
7721   W (ret);
7722   return ret;
7723 }
7724
7725 static int
7726 api_tap_connect (vat_main_t * vam)
7727 {
7728   unformat_input_t *i = vam->input;
7729   vl_api_tap_connect_t *mp;
7730   u8 mac_address[6];
7731   u8 random_mac = 1;
7732   u8 name_set = 0;
7733   u8 *tap_name;
7734   u8 *tag = 0;
7735   ip4_address_t ip4_address;
7736   u32 ip4_mask_width;
7737   int ip4_address_set = 0;
7738   ip6_address_t ip6_address;
7739   u32 ip6_mask_width;
7740   int ip6_address_set = 0;
7741   int ret;
7742
7743   memset (mac_address, 0, sizeof (mac_address));
7744
7745   /* Parse args required to build the message */
7746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7747     {
7748       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7749         {
7750           random_mac = 0;
7751         }
7752       else if (unformat (i, "random-mac"))
7753         random_mac = 1;
7754       else if (unformat (i, "tapname %s", &tap_name))
7755         name_set = 1;
7756       else if (unformat (i, "tag %s", &tag))
7757         ;
7758       else if (unformat (i, "address %U/%d",
7759                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7760         ip4_address_set = 1;
7761       else if (unformat (i, "address %U/%d",
7762                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7763         ip6_address_set = 1;
7764       else
7765         break;
7766     }
7767
7768   if (name_set == 0)
7769     {
7770       errmsg ("missing tap name");
7771       return -99;
7772     }
7773   if (vec_len (tap_name) > 63)
7774     {
7775       errmsg ("tap name too long");
7776       return -99;
7777     }
7778   vec_add1 (tap_name, 0);
7779
7780   if (vec_len (tag) > 63)
7781     {
7782       errmsg ("tag too long");
7783       return -99;
7784     }
7785
7786   /* Construct the API message */
7787   M (TAP_CONNECT, mp);
7788
7789   mp->use_random_mac = random_mac;
7790   clib_memcpy (mp->mac_address, mac_address, 6);
7791   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7792   if (tag)
7793     clib_memcpy (mp->tag, tag, vec_len (tag));
7794
7795   if (ip4_address_set)
7796     {
7797       mp->ip4_address_set = 1;
7798       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7799       mp->ip4_mask_width = ip4_mask_width;
7800     }
7801   if (ip6_address_set)
7802     {
7803       mp->ip6_address_set = 1;
7804       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7805       mp->ip6_mask_width = ip6_mask_width;
7806     }
7807
7808   vec_free (tap_name);
7809   vec_free (tag);
7810
7811   /* send it... */
7812   S (mp);
7813
7814   /* Wait for a reply... */
7815   W (ret);
7816   return ret;
7817 }
7818
7819 static int
7820 api_tap_modify (vat_main_t * vam)
7821 {
7822   unformat_input_t *i = vam->input;
7823   vl_api_tap_modify_t *mp;
7824   u8 mac_address[6];
7825   u8 random_mac = 1;
7826   u8 name_set = 0;
7827   u8 *tap_name;
7828   u32 sw_if_index = ~0;
7829   u8 sw_if_index_set = 0;
7830   int ret;
7831
7832   memset (mac_address, 0, sizeof (mac_address));
7833
7834   /* Parse args required to build the message */
7835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7836     {
7837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7838         sw_if_index_set = 1;
7839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7840         sw_if_index_set = 1;
7841       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7842         {
7843           random_mac = 0;
7844         }
7845       else if (unformat (i, "random-mac"))
7846         random_mac = 1;
7847       else if (unformat (i, "tapname %s", &tap_name))
7848         name_set = 1;
7849       else
7850         break;
7851     }
7852
7853   if (sw_if_index_set == 0)
7854     {
7855       errmsg ("missing vpp interface name");
7856       return -99;
7857     }
7858   if (name_set == 0)
7859     {
7860       errmsg ("missing tap name");
7861       return -99;
7862     }
7863   if (vec_len (tap_name) > 63)
7864     {
7865       errmsg ("tap name too long");
7866     }
7867   vec_add1 (tap_name, 0);
7868
7869   /* Construct the API message */
7870   M (TAP_MODIFY, mp);
7871
7872   mp->use_random_mac = random_mac;
7873   mp->sw_if_index = ntohl (sw_if_index);
7874   clib_memcpy (mp->mac_address, mac_address, 6);
7875   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7876   vec_free (tap_name);
7877
7878   /* send it... */
7879   S (mp);
7880
7881   /* Wait for a reply... */
7882   W (ret);
7883   return ret;
7884 }
7885
7886 static int
7887 api_tap_delete (vat_main_t * vam)
7888 {
7889   unformat_input_t *i = vam->input;
7890   vl_api_tap_delete_t *mp;
7891   u32 sw_if_index = ~0;
7892   u8 sw_if_index_set = 0;
7893   int ret;
7894
7895   /* Parse args required to build the message */
7896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7897     {
7898       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7899         sw_if_index_set = 1;
7900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7901         sw_if_index_set = 1;
7902       else
7903         break;
7904     }
7905
7906   if (sw_if_index_set == 0)
7907     {
7908       errmsg ("missing vpp interface name");
7909       return -99;
7910     }
7911
7912   /* Construct the API message */
7913   M (TAP_DELETE, mp);
7914
7915   mp->sw_if_index = ntohl (sw_if_index);
7916
7917   /* send it... */
7918   S (mp);
7919
7920   /* Wait for a reply... */
7921   W (ret);
7922   return ret;
7923 }
7924
7925 static int
7926 api_tap_create_v2 (vat_main_t * vam)
7927 {
7928   unformat_input_t *i = vam->input;
7929   vl_api_tap_create_v2_t *mp;
7930   u8 mac_address[6];
7931   u8 random_mac = 1;
7932   u32 id = ~0;
7933   u8 *host_if_name = 0;
7934   u8 *host_ns = 0;
7935   u8 host_mac_addr[6];
7936   u8 host_mac_addr_set = 0;
7937   u8 *host_bridge = 0;
7938   ip4_address_t host_ip4_addr;
7939   ip4_address_t host_ip4_gw;
7940   u8 host_ip4_gw_set = 0;
7941   u32 host_ip4_prefix_len = 0;
7942   ip6_address_t host_ip6_addr;
7943   ip6_address_t host_ip6_gw;
7944   u8 host_ip6_gw_set = 0;
7945   u32 host_ip6_prefix_len = 0;
7946   int ret;
7947   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7948
7949   memset (mac_address, 0, sizeof (mac_address));
7950
7951   /* Parse args required to build the message */
7952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7953     {
7954       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7955         {
7956           random_mac = 0;
7957         }
7958       else if (unformat (i, "id %u", &id))
7959         ;
7960       else if (unformat (i, "host-if-name %s", &host_if_name))
7961         ;
7962       else if (unformat (i, "host-ns %s", &host_ns))
7963         ;
7964       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7965                          host_mac_addr))
7966         host_mac_addr_set = 1;
7967       else if (unformat (i, "host-bridge %s", &host_bridge))
7968         ;
7969       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7970                          &host_ip4_addr, &host_ip4_prefix_len))
7971         ;
7972       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7973                          &host_ip6_addr, &host_ip6_prefix_len))
7974         ;
7975       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7976                          &host_ip4_gw))
7977         host_ip4_gw_set = 1;
7978       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7979                          &host_ip6_gw))
7980         host_ip6_gw_set = 1;
7981       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7982         ;
7983       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7984         ;
7985       else
7986         break;
7987     }
7988
7989   if (vec_len (host_if_name) > 63)
7990     {
7991       errmsg ("tap name too long. ");
7992       return -99;
7993     }
7994   if (vec_len (host_ns) > 63)
7995     {
7996       errmsg ("host name space too long. ");
7997       return -99;
7998     }
7999   if (vec_len (host_bridge) > 63)
8000     {
8001       errmsg ("host bridge name too long. ");
8002       return -99;
8003     }
8004   if (host_ip4_prefix_len > 32)
8005     {
8006       errmsg ("host ip4 prefix length not valid. ");
8007       return -99;
8008     }
8009   if (host_ip6_prefix_len > 128)
8010     {
8011       errmsg ("host ip6 prefix length not valid. ");
8012       return -99;
8013     }
8014   if (!is_pow2 (rx_ring_sz))
8015     {
8016       errmsg ("rx ring size must be power of 2. ");
8017       return -99;
8018     }
8019   if (rx_ring_sz > 32768)
8020     {
8021       errmsg ("rx ring size must be 32768 or lower. ");
8022       return -99;
8023     }
8024   if (!is_pow2 (tx_ring_sz))
8025     {
8026       errmsg ("tx ring size must be power of 2. ");
8027       return -99;
8028     }
8029   if (tx_ring_sz > 32768)
8030     {
8031       errmsg ("tx ring size must be 32768 or lower. ");
8032       return -99;
8033     }
8034
8035   /* Construct the API message */
8036   M (TAP_CREATE_V2, mp);
8037
8038   mp->use_random_mac = random_mac;
8039
8040   mp->id = ntohl (id);
8041   mp->host_namespace_set = host_ns != 0;
8042   mp->host_bridge_set = host_bridge != 0;
8043   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8044   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8045   mp->rx_ring_sz = ntohs (rx_ring_sz);
8046   mp->tx_ring_sz = ntohs (tx_ring_sz);
8047
8048   if (random_mac == 0)
8049     clib_memcpy (mp->mac_address, mac_address, 6);
8050   if (host_mac_addr_set)
8051     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8052   if (host_if_name)
8053     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8054   if (host_ns)
8055     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8056   if (host_bridge)
8057     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8058   if (host_ip4_prefix_len)
8059     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8060   if (host_ip4_prefix_len)
8061     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8062   if (host_ip4_gw_set)
8063     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8064   if (host_ip6_gw_set)
8065     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8066
8067   vec_free (host_ns);
8068   vec_free (host_if_name);
8069   vec_free (host_bridge);
8070
8071   /* send it... */
8072   S (mp);
8073
8074   /* Wait for a reply... */
8075   W (ret);
8076   return ret;
8077 }
8078
8079 static int
8080 api_tap_delete_v2 (vat_main_t * vam)
8081 {
8082   unformat_input_t *i = vam->input;
8083   vl_api_tap_delete_v2_t *mp;
8084   u32 sw_if_index = ~0;
8085   u8 sw_if_index_set = 0;
8086   int ret;
8087
8088   /* Parse args required to build the message */
8089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8090     {
8091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8092         sw_if_index_set = 1;
8093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8094         sw_if_index_set = 1;
8095       else
8096         break;
8097     }
8098
8099   if (sw_if_index_set == 0)
8100     {
8101       errmsg ("missing vpp interface name. ");
8102       return -99;
8103     }
8104
8105   /* Construct the API message */
8106   M (TAP_DELETE_V2, mp);
8107
8108   mp->sw_if_index = ntohl (sw_if_index);
8109
8110   /* send it... */
8111   S (mp);
8112
8113   /* Wait for a reply... */
8114   W (ret);
8115   return ret;
8116 }
8117
8118 static int
8119 api_bond_create (vat_main_t * vam)
8120 {
8121   unformat_input_t *i = vam->input;
8122   vl_api_bond_create_t *mp;
8123   u8 mac_address[6];
8124   u8 custom_mac = 0;
8125   int ret;
8126   u8 mode;
8127   u8 lb;
8128   u8 mode_is_set = 0;
8129
8130   memset (mac_address, 0, sizeof (mac_address));
8131   lb = BOND_LB_L2;
8132
8133   /* Parse args required to build the message */
8134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8135     {
8136       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8137         mode_is_set = 1;
8138       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8139                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8140         ;
8141       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8142                          mac_address))
8143         custom_mac = 1;
8144       else
8145         break;
8146     }
8147
8148   if (mode_is_set == 0)
8149     {
8150       errmsg ("Missing bond mode. ");
8151       return -99;
8152     }
8153
8154   /* Construct the API message */
8155   M (BOND_CREATE, mp);
8156
8157   mp->use_custom_mac = custom_mac;
8158
8159   mp->mode = mode;
8160   mp->lb = lb;
8161
8162   if (custom_mac)
8163     clib_memcpy (mp->mac_address, mac_address, 6);
8164
8165   /* send it... */
8166   S (mp);
8167
8168   /* Wait for a reply... */
8169   W (ret);
8170   return ret;
8171 }
8172
8173 static int
8174 api_bond_delete (vat_main_t * vam)
8175 {
8176   unformat_input_t *i = vam->input;
8177   vl_api_bond_delete_t *mp;
8178   u32 sw_if_index = ~0;
8179   u8 sw_if_index_set = 0;
8180   int ret;
8181
8182   /* Parse args required to build the message */
8183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8184     {
8185       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8186         sw_if_index_set = 1;
8187       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8188         sw_if_index_set = 1;
8189       else
8190         break;
8191     }
8192
8193   if (sw_if_index_set == 0)
8194     {
8195       errmsg ("missing vpp interface name. ");
8196       return -99;
8197     }
8198
8199   /* Construct the API message */
8200   M (BOND_DELETE, mp);
8201
8202   mp->sw_if_index = ntohl (sw_if_index);
8203
8204   /* send it... */
8205   S (mp);
8206
8207   /* Wait for a reply... */
8208   W (ret);
8209   return ret;
8210 }
8211
8212 static int
8213 api_bond_enslave (vat_main_t * vam)
8214 {
8215   unformat_input_t *i = vam->input;
8216   vl_api_bond_enslave_t *mp;
8217   u32 bond_sw_if_index;
8218   int ret;
8219   u8 is_passive;
8220   u8 is_long_timeout;
8221   u32 bond_sw_if_index_is_set = 0;
8222   u32 sw_if_index;
8223   u8 sw_if_index_is_set = 0;
8224
8225   /* Parse args required to build the message */
8226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8227     {
8228       if (unformat (i, "sw_if_index %d", &sw_if_index))
8229         sw_if_index_is_set = 1;
8230       else if (unformat (i, "bond %u", &bond_sw_if_index))
8231         bond_sw_if_index_is_set = 1;
8232       else if (unformat (i, "passive %d", &is_passive))
8233         ;
8234       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8235         ;
8236       else
8237         break;
8238     }
8239
8240   if (bond_sw_if_index_is_set == 0)
8241     {
8242       errmsg ("Missing bond sw_if_index. ");
8243       return -99;
8244     }
8245   if (sw_if_index_is_set == 0)
8246     {
8247       errmsg ("Missing slave sw_if_index. ");
8248       return -99;
8249     }
8250
8251   /* Construct the API message */
8252   M (BOND_ENSLAVE, mp);
8253
8254   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8255   mp->sw_if_index = ntohl (sw_if_index);
8256   mp->is_long_timeout = is_long_timeout;
8257   mp->is_passive = is_passive;
8258
8259   /* send it... */
8260   S (mp);
8261
8262   /* Wait for a reply... */
8263   W (ret);
8264   return ret;
8265 }
8266
8267 static int
8268 api_bond_detach_slave (vat_main_t * vam)
8269 {
8270   unformat_input_t *i = vam->input;
8271   vl_api_bond_detach_slave_t *mp;
8272   u32 sw_if_index = ~0;
8273   u8 sw_if_index_set = 0;
8274   int ret;
8275
8276   /* Parse args required to build the message */
8277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8278     {
8279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8280         sw_if_index_set = 1;
8281       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8282         sw_if_index_set = 1;
8283       else
8284         break;
8285     }
8286
8287   if (sw_if_index_set == 0)
8288     {
8289       errmsg ("missing vpp interface name. ");
8290       return -99;
8291     }
8292
8293   /* Construct the API message */
8294   M (BOND_DETACH_SLAVE, mp);
8295
8296   mp->sw_if_index = ntohl (sw_if_index);
8297
8298   /* send it... */
8299   S (mp);
8300
8301   /* Wait for a reply... */
8302   W (ret);
8303   return ret;
8304 }
8305
8306 static int
8307 api_ip_table_add_del (vat_main_t * vam)
8308 {
8309   unformat_input_t *i = vam->input;
8310   vl_api_ip_table_add_del_t *mp;
8311   u32 table_id = ~0;
8312   u8 is_ipv6 = 0;
8313   u8 is_add = 1;
8314   int ret = 0;
8315
8316   /* Parse args required to build the message */
8317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8318     {
8319       if (unformat (i, "ipv6"))
8320         is_ipv6 = 1;
8321       else if (unformat (i, "del"))
8322         is_add = 0;
8323       else if (unformat (i, "add"))
8324         is_add = 1;
8325       else if (unformat (i, "table %d", &table_id))
8326         ;
8327       else
8328         {
8329           clib_warning ("parse error '%U'", format_unformat_error, i);
8330           return -99;
8331         }
8332     }
8333
8334   if (~0 == table_id)
8335     {
8336       errmsg ("missing table-ID");
8337       return -99;
8338     }
8339
8340   /* Construct the API message */
8341   M (IP_TABLE_ADD_DEL, mp);
8342
8343   mp->table_id = ntohl (table_id);
8344   mp->is_ipv6 = is_ipv6;
8345   mp->is_add = is_add;
8346
8347   /* send it... */
8348   S (mp);
8349
8350   /* Wait for a reply... */
8351   W (ret);
8352
8353   return ret;
8354 }
8355
8356 static int
8357 api_ip_add_del_route (vat_main_t * vam)
8358 {
8359   unformat_input_t *i = vam->input;
8360   vl_api_ip_add_del_route_t *mp;
8361   u32 sw_if_index = ~0, vrf_id = 0;
8362   u8 is_ipv6 = 0;
8363   u8 is_local = 0, is_drop = 0;
8364   u8 is_unreach = 0, is_prohibit = 0;
8365   u8 is_add = 1;
8366   u32 next_hop_weight = 1;
8367   u8 is_multipath = 0;
8368   u8 address_set = 0;
8369   u8 address_length_set = 0;
8370   u32 next_hop_table_id = 0;
8371   u32 resolve_attempts = 0;
8372   u32 dst_address_length = 0;
8373   u8 next_hop_set = 0;
8374   ip4_address_t v4_dst_address, v4_next_hop_address;
8375   ip6_address_t v6_dst_address, v6_next_hop_address;
8376   int count = 1;
8377   int j;
8378   f64 before = 0;
8379   u32 random_add_del = 0;
8380   u32 *random_vector = 0;
8381   uword *random_hash;
8382   u32 random_seed = 0xdeaddabe;
8383   u32 classify_table_index = ~0;
8384   u8 is_classify = 0;
8385   u8 resolve_host = 0, resolve_attached = 0;
8386   mpls_label_t *next_hop_out_label_stack = NULL;
8387   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8388   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8389
8390   /* Parse args required to build the message */
8391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8392     {
8393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8394         ;
8395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8396         ;
8397       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8398         {
8399           address_set = 1;
8400           is_ipv6 = 0;
8401         }
8402       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8403         {
8404           address_set = 1;
8405           is_ipv6 = 1;
8406         }
8407       else if (unformat (i, "/%d", &dst_address_length))
8408         {
8409           address_length_set = 1;
8410         }
8411
8412       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8413                                          &v4_next_hop_address))
8414         {
8415           next_hop_set = 1;
8416         }
8417       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8418                                          &v6_next_hop_address))
8419         {
8420           next_hop_set = 1;
8421         }
8422       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8423         ;
8424       else if (unformat (i, "weight %d", &next_hop_weight))
8425         ;
8426       else if (unformat (i, "drop"))
8427         {
8428           is_drop = 1;
8429         }
8430       else if (unformat (i, "null-send-unreach"))
8431         {
8432           is_unreach = 1;
8433         }
8434       else if (unformat (i, "null-send-prohibit"))
8435         {
8436           is_prohibit = 1;
8437         }
8438       else if (unformat (i, "local"))
8439         {
8440           is_local = 1;
8441         }
8442       else if (unformat (i, "classify %d", &classify_table_index))
8443         {
8444           is_classify = 1;
8445         }
8446       else if (unformat (i, "del"))
8447         is_add = 0;
8448       else if (unformat (i, "add"))
8449         is_add = 1;
8450       else if (unformat (i, "resolve-via-host"))
8451         resolve_host = 1;
8452       else if (unformat (i, "resolve-via-attached"))
8453         resolve_attached = 1;
8454       else if (unformat (i, "multipath"))
8455         is_multipath = 1;
8456       else if (unformat (i, "vrf %d", &vrf_id))
8457         ;
8458       else if (unformat (i, "count %d", &count))
8459         ;
8460       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8461         ;
8462       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8463         ;
8464       else if (unformat (i, "out-label %d", &next_hop_out_label))
8465         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8466       else if (unformat (i, "via-label %d", &next_hop_via_label))
8467         ;
8468       else if (unformat (i, "random"))
8469         random_add_del = 1;
8470       else if (unformat (i, "seed %d", &random_seed))
8471         ;
8472       else
8473         {
8474           clib_warning ("parse error '%U'", format_unformat_error, i);
8475           return -99;
8476         }
8477     }
8478
8479   if (!next_hop_set && !is_drop && !is_local &&
8480       !is_classify && !is_unreach && !is_prohibit &&
8481       MPLS_LABEL_INVALID == next_hop_via_label)
8482     {
8483       errmsg
8484         ("next hop / local / drop / unreach / prohibit / classify not set");
8485       return -99;
8486     }
8487
8488   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8489     {
8490       errmsg ("next hop and next-hop via label set");
8491       return -99;
8492     }
8493   if (address_set == 0)
8494     {
8495       errmsg ("missing addresses");
8496       return -99;
8497     }
8498
8499   if (address_length_set == 0)
8500     {
8501       errmsg ("missing address length");
8502       return -99;
8503     }
8504
8505   /* Generate a pile of unique, random routes */
8506   if (random_add_del)
8507     {
8508       u32 this_random_address;
8509       random_hash = hash_create (count, sizeof (uword));
8510
8511       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8512       for (j = 0; j <= count; j++)
8513         {
8514           do
8515             {
8516               this_random_address = random_u32 (&random_seed);
8517               this_random_address =
8518                 clib_host_to_net_u32 (this_random_address);
8519             }
8520           while (hash_get (random_hash, this_random_address));
8521           vec_add1 (random_vector, this_random_address);
8522           hash_set (random_hash, this_random_address, 1);
8523         }
8524       hash_free (random_hash);
8525       v4_dst_address.as_u32 = random_vector[0];
8526     }
8527
8528   if (count > 1)
8529     {
8530       /* Turn on async mode */
8531       vam->async_mode = 1;
8532       vam->async_errors = 0;
8533       before = vat_time_now (vam);
8534     }
8535
8536   for (j = 0; j < count; j++)
8537     {
8538       /* Construct the API message */
8539       M2 (IP_ADD_DEL_ROUTE, mp,
8540           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8541
8542       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8543       mp->table_id = ntohl (vrf_id);
8544
8545       mp->is_add = is_add;
8546       mp->is_drop = is_drop;
8547       mp->is_unreach = is_unreach;
8548       mp->is_prohibit = is_prohibit;
8549       mp->is_ipv6 = is_ipv6;
8550       mp->is_local = is_local;
8551       mp->is_classify = is_classify;
8552       mp->is_multipath = is_multipath;
8553       mp->is_resolve_host = resolve_host;
8554       mp->is_resolve_attached = resolve_attached;
8555       mp->next_hop_weight = next_hop_weight;
8556       mp->dst_address_length = dst_address_length;
8557       mp->next_hop_table_id = ntohl (next_hop_table_id);
8558       mp->classify_table_index = ntohl (classify_table_index);
8559       mp->next_hop_via_label = ntohl (next_hop_via_label);
8560       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8561       if (0 != mp->next_hop_n_out_labels)
8562         {
8563           memcpy (mp->next_hop_out_label_stack,
8564                   next_hop_out_label_stack,
8565                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8566           vec_free (next_hop_out_label_stack);
8567         }
8568
8569       if (is_ipv6)
8570         {
8571           clib_memcpy (mp->dst_address, &v6_dst_address,
8572                        sizeof (v6_dst_address));
8573           if (next_hop_set)
8574             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8575                          sizeof (v6_next_hop_address));
8576           increment_v6_address (&v6_dst_address);
8577         }
8578       else
8579         {
8580           clib_memcpy (mp->dst_address, &v4_dst_address,
8581                        sizeof (v4_dst_address));
8582           if (next_hop_set)
8583             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8584                          sizeof (v4_next_hop_address));
8585           if (random_add_del)
8586             v4_dst_address.as_u32 = random_vector[j + 1];
8587           else
8588             increment_v4_address (&v4_dst_address);
8589         }
8590       /* send it... */
8591       S (mp);
8592       /* If we receive SIGTERM, stop now... */
8593       if (vam->do_exit)
8594         break;
8595     }
8596
8597   /* When testing multiple add/del ops, use a control-ping to sync */
8598   if (count > 1)
8599     {
8600       vl_api_control_ping_t *mp_ping;
8601       f64 after;
8602       f64 timeout;
8603
8604       /* Shut off async mode */
8605       vam->async_mode = 0;
8606
8607       MPING (CONTROL_PING, mp_ping);
8608       S (mp_ping);
8609
8610       timeout = vat_time_now (vam) + 1.0;
8611       while (vat_time_now (vam) < timeout)
8612         if (vam->result_ready == 1)
8613           goto out;
8614       vam->retval = -99;
8615
8616     out:
8617       if (vam->retval == -99)
8618         errmsg ("timeout");
8619
8620       if (vam->async_errors > 0)
8621         {
8622           errmsg ("%d asynchronous errors", vam->async_errors);
8623           vam->retval = -98;
8624         }
8625       vam->async_errors = 0;
8626       after = vat_time_now (vam);
8627
8628       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8629       if (j > 0)
8630         count = j;
8631
8632       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8633              count, after - before, count / (after - before));
8634     }
8635   else
8636     {
8637       int ret;
8638
8639       /* Wait for a reply... */
8640       W (ret);
8641       return ret;
8642     }
8643
8644   /* Return the good/bad news */
8645   return (vam->retval);
8646 }
8647
8648 static int
8649 api_ip_mroute_add_del (vat_main_t * vam)
8650 {
8651   unformat_input_t *i = vam->input;
8652   vl_api_ip_mroute_add_del_t *mp;
8653   u32 sw_if_index = ~0, vrf_id = 0;
8654   u8 is_ipv6 = 0;
8655   u8 is_local = 0;
8656   u8 is_add = 1;
8657   u8 address_set = 0;
8658   u32 grp_address_length = 0;
8659   ip4_address_t v4_grp_address, v4_src_address;
8660   ip6_address_t v6_grp_address, v6_src_address;
8661   mfib_itf_flags_t iflags = 0;
8662   mfib_entry_flags_t eflags = 0;
8663   int ret;
8664
8665   /* Parse args required to build the message */
8666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8667     {
8668       if (unformat (i, "sw_if_index %d", &sw_if_index))
8669         ;
8670       else if (unformat (i, "%U %U",
8671                          unformat_ip4_address, &v4_src_address,
8672                          unformat_ip4_address, &v4_grp_address))
8673         {
8674           grp_address_length = 64;
8675           address_set = 1;
8676           is_ipv6 = 0;
8677         }
8678       else if (unformat (i, "%U %U",
8679                          unformat_ip6_address, &v6_src_address,
8680                          unformat_ip6_address, &v6_grp_address))
8681         {
8682           grp_address_length = 256;
8683           address_set = 1;
8684           is_ipv6 = 1;
8685         }
8686       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8687         {
8688           memset (&v4_src_address, 0, sizeof (v4_src_address));
8689           grp_address_length = 32;
8690           address_set = 1;
8691           is_ipv6 = 0;
8692         }
8693       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8694         {
8695           memset (&v6_src_address, 0, sizeof (v6_src_address));
8696           grp_address_length = 128;
8697           address_set = 1;
8698           is_ipv6 = 1;
8699         }
8700       else if (unformat (i, "/%d", &grp_address_length))
8701         ;
8702       else if (unformat (i, "local"))
8703         {
8704           is_local = 1;
8705         }
8706       else if (unformat (i, "del"))
8707         is_add = 0;
8708       else if (unformat (i, "add"))
8709         is_add = 1;
8710       else if (unformat (i, "vrf %d", &vrf_id))
8711         ;
8712       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8713         ;
8714       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8715         ;
8716       else
8717         {
8718           clib_warning ("parse error '%U'", format_unformat_error, i);
8719           return -99;
8720         }
8721     }
8722
8723   if (address_set == 0)
8724     {
8725       errmsg ("missing addresses\n");
8726       return -99;
8727     }
8728
8729   /* Construct the API message */
8730   M (IP_MROUTE_ADD_DEL, mp);
8731
8732   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8733   mp->table_id = ntohl (vrf_id);
8734
8735   mp->is_add = is_add;
8736   mp->is_ipv6 = is_ipv6;
8737   mp->is_local = is_local;
8738   mp->itf_flags = ntohl (iflags);
8739   mp->entry_flags = ntohl (eflags);
8740   mp->grp_address_length = grp_address_length;
8741   mp->grp_address_length = ntohs (mp->grp_address_length);
8742
8743   if (is_ipv6)
8744     {
8745       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8746       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8747     }
8748   else
8749     {
8750       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8751       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8752
8753     }
8754
8755   /* send it... */
8756   S (mp);
8757   /* Wait for a reply... */
8758   W (ret);
8759   return ret;
8760 }
8761
8762 static int
8763 api_mpls_table_add_del (vat_main_t * vam)
8764 {
8765   unformat_input_t *i = vam->input;
8766   vl_api_mpls_table_add_del_t *mp;
8767   u32 table_id = ~0;
8768   u8 is_add = 1;
8769   int ret = 0;
8770
8771   /* Parse args required to build the message */
8772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8773     {
8774       if (unformat (i, "table %d", &table_id))
8775         ;
8776       else if (unformat (i, "del"))
8777         is_add = 0;
8778       else if (unformat (i, "add"))
8779         is_add = 1;
8780       else
8781         {
8782           clib_warning ("parse error '%U'", format_unformat_error, i);
8783           return -99;
8784         }
8785     }
8786
8787   if (~0 == table_id)
8788     {
8789       errmsg ("missing table-ID");
8790       return -99;
8791     }
8792
8793   /* Construct the API message */
8794   M (MPLS_TABLE_ADD_DEL, mp);
8795
8796   mp->mt_table_id = ntohl (table_id);
8797   mp->mt_is_add = is_add;
8798
8799   /* send it... */
8800   S (mp);
8801
8802   /* Wait for a reply... */
8803   W (ret);
8804
8805   return ret;
8806 }
8807
8808 static int
8809 api_mpls_route_add_del (vat_main_t * vam)
8810 {
8811   unformat_input_t *i = vam->input;
8812   vl_api_mpls_route_add_del_t *mp;
8813   u32 sw_if_index = ~0, table_id = 0;
8814   u8 is_add = 1;
8815   u32 next_hop_weight = 1;
8816   u8 is_multipath = 0;
8817   u32 next_hop_table_id = 0;
8818   u8 next_hop_set = 0;
8819   ip4_address_t v4_next_hop_address = {
8820     .as_u32 = 0,
8821   };
8822   ip6_address_t v6_next_hop_address = { {0} };
8823   int count = 1;
8824   int j;
8825   f64 before = 0;
8826   u32 classify_table_index = ~0;
8827   u8 is_classify = 0;
8828   u8 resolve_host = 0, resolve_attached = 0;
8829   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8830   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8831   mpls_label_t *next_hop_out_label_stack = NULL;
8832   mpls_label_t local_label = MPLS_LABEL_INVALID;
8833   u8 is_eos = 0;
8834   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8835
8836   /* Parse args required to build the message */
8837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8838     {
8839       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8840         ;
8841       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8842         ;
8843       else if (unformat (i, "%d", &local_label))
8844         ;
8845       else if (unformat (i, "eos"))
8846         is_eos = 1;
8847       else if (unformat (i, "non-eos"))
8848         is_eos = 0;
8849       else if (unformat (i, "via %U", unformat_ip4_address,
8850                          &v4_next_hop_address))
8851         {
8852           next_hop_set = 1;
8853           next_hop_proto = DPO_PROTO_IP4;
8854         }
8855       else if (unformat (i, "via %U", unformat_ip6_address,
8856                          &v6_next_hop_address))
8857         {
8858           next_hop_set = 1;
8859           next_hop_proto = DPO_PROTO_IP6;
8860         }
8861       else if (unformat (i, "weight %d", &next_hop_weight))
8862         ;
8863       else if (unformat (i, "classify %d", &classify_table_index))
8864         {
8865           is_classify = 1;
8866         }
8867       else if (unformat (i, "del"))
8868         is_add = 0;
8869       else if (unformat (i, "add"))
8870         is_add = 1;
8871       else if (unformat (i, "resolve-via-host"))
8872         resolve_host = 1;
8873       else if (unformat (i, "resolve-via-attached"))
8874         resolve_attached = 1;
8875       else if (unformat (i, "multipath"))
8876         is_multipath = 1;
8877       else if (unformat (i, "count %d", &count))
8878         ;
8879       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8880         {
8881           next_hop_set = 1;
8882           next_hop_proto = DPO_PROTO_IP4;
8883         }
8884       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8885         {
8886           next_hop_set = 1;
8887           next_hop_proto = DPO_PROTO_IP6;
8888         }
8889       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8890         ;
8891       else if (unformat (i, "via-label %d", &next_hop_via_label))
8892         ;
8893       else if (unformat (i, "out-label %d", &next_hop_out_label))
8894         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8895       else
8896         {
8897           clib_warning ("parse error '%U'", format_unformat_error, i);
8898           return -99;
8899         }
8900     }
8901
8902   if (!next_hop_set && !is_classify)
8903     {
8904       errmsg ("next hop / classify not set");
8905       return -99;
8906     }
8907
8908   if (MPLS_LABEL_INVALID == local_label)
8909     {
8910       errmsg ("missing label");
8911       return -99;
8912     }
8913
8914   if (count > 1)
8915     {
8916       /* Turn on async mode */
8917       vam->async_mode = 1;
8918       vam->async_errors = 0;
8919       before = vat_time_now (vam);
8920     }
8921
8922   for (j = 0; j < count; j++)
8923     {
8924       /* Construct the API message */
8925       M2 (MPLS_ROUTE_ADD_DEL, mp,
8926           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8927
8928       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8929       mp->mr_table_id = ntohl (table_id);
8930
8931       mp->mr_is_add = is_add;
8932       mp->mr_next_hop_proto = next_hop_proto;
8933       mp->mr_is_classify = is_classify;
8934       mp->mr_is_multipath = is_multipath;
8935       mp->mr_is_resolve_host = resolve_host;
8936       mp->mr_is_resolve_attached = resolve_attached;
8937       mp->mr_next_hop_weight = next_hop_weight;
8938       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8939       mp->mr_classify_table_index = ntohl (classify_table_index);
8940       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8941       mp->mr_label = ntohl (local_label);
8942       mp->mr_eos = is_eos;
8943
8944       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8945       if (0 != mp->mr_next_hop_n_out_labels)
8946         {
8947           memcpy (mp->mr_next_hop_out_label_stack,
8948                   next_hop_out_label_stack,
8949                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8950           vec_free (next_hop_out_label_stack);
8951         }
8952
8953       if (next_hop_set)
8954         {
8955           if (DPO_PROTO_IP4 == next_hop_proto)
8956             {
8957               clib_memcpy (mp->mr_next_hop,
8958                            &v4_next_hop_address,
8959                            sizeof (v4_next_hop_address));
8960             }
8961           else if (DPO_PROTO_IP6 == next_hop_proto)
8962
8963             {
8964               clib_memcpy (mp->mr_next_hop,
8965                            &v6_next_hop_address,
8966                            sizeof (v6_next_hop_address));
8967             }
8968         }
8969       local_label++;
8970
8971       /* send it... */
8972       S (mp);
8973       /* If we receive SIGTERM, stop now... */
8974       if (vam->do_exit)
8975         break;
8976     }
8977
8978   /* When testing multiple add/del ops, use a control-ping to sync */
8979   if (count > 1)
8980     {
8981       vl_api_control_ping_t *mp_ping;
8982       f64 after;
8983       f64 timeout;
8984
8985       /* Shut off async mode */
8986       vam->async_mode = 0;
8987
8988       MPING (CONTROL_PING, mp_ping);
8989       S (mp_ping);
8990
8991       timeout = vat_time_now (vam) + 1.0;
8992       while (vat_time_now (vam) < timeout)
8993         if (vam->result_ready == 1)
8994           goto out;
8995       vam->retval = -99;
8996
8997     out:
8998       if (vam->retval == -99)
8999         errmsg ("timeout");
9000
9001       if (vam->async_errors > 0)
9002         {
9003           errmsg ("%d asynchronous errors", vam->async_errors);
9004           vam->retval = -98;
9005         }
9006       vam->async_errors = 0;
9007       after = vat_time_now (vam);
9008
9009       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9010       if (j > 0)
9011         count = j;
9012
9013       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9014              count, after - before, count / (after - before));
9015     }
9016   else
9017     {
9018       int ret;
9019
9020       /* Wait for a reply... */
9021       W (ret);
9022       return ret;
9023     }
9024
9025   /* Return the good/bad news */
9026   return (vam->retval);
9027 }
9028
9029 static int
9030 api_mpls_ip_bind_unbind (vat_main_t * vam)
9031 {
9032   unformat_input_t *i = vam->input;
9033   vl_api_mpls_ip_bind_unbind_t *mp;
9034   u32 ip_table_id = 0;
9035   u8 is_bind = 1;
9036   u8 is_ip4 = 1;
9037   ip4_address_t v4_address;
9038   ip6_address_t v6_address;
9039   u32 address_length;
9040   u8 address_set = 0;
9041   mpls_label_t local_label = MPLS_LABEL_INVALID;
9042   int ret;
9043
9044   /* Parse args required to build the message */
9045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9046     {
9047       if (unformat (i, "%U/%d", unformat_ip4_address,
9048                     &v4_address, &address_length))
9049         {
9050           is_ip4 = 1;
9051           address_set = 1;
9052         }
9053       else if (unformat (i, "%U/%d", unformat_ip6_address,
9054                          &v6_address, &address_length))
9055         {
9056           is_ip4 = 0;
9057           address_set = 1;
9058         }
9059       else if (unformat (i, "%d", &local_label))
9060         ;
9061       else if (unformat (i, "table-id %d", &ip_table_id))
9062         ;
9063       else if (unformat (i, "unbind"))
9064         is_bind = 0;
9065       else if (unformat (i, "bind"))
9066         is_bind = 1;
9067       else
9068         {
9069           clib_warning ("parse error '%U'", format_unformat_error, i);
9070           return -99;
9071         }
9072     }
9073
9074   if (!address_set)
9075     {
9076       errmsg ("IP addres not set");
9077       return -99;
9078     }
9079
9080   if (MPLS_LABEL_INVALID == local_label)
9081     {
9082       errmsg ("missing label");
9083       return -99;
9084     }
9085
9086   /* Construct the API message */
9087   M (MPLS_IP_BIND_UNBIND, mp);
9088
9089   mp->mb_is_bind = is_bind;
9090   mp->mb_is_ip4 = is_ip4;
9091   mp->mb_ip_table_id = ntohl (ip_table_id);
9092   mp->mb_mpls_table_id = 0;
9093   mp->mb_label = ntohl (local_label);
9094   mp->mb_address_length = address_length;
9095
9096   if (is_ip4)
9097     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9098   else
9099     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9100
9101   /* send it... */
9102   S (mp);
9103
9104   /* Wait for a reply... */
9105   W (ret);
9106   return ret;
9107 }
9108
9109 static int
9110 api_bier_table_add_del (vat_main_t * vam)
9111 {
9112   unformat_input_t *i = vam->input;
9113   vl_api_bier_table_add_del_t *mp;
9114   u8 is_add = 1;
9115   u32 set = 0, sub_domain = 0, hdr_len = 3;
9116   mpls_label_t local_label = MPLS_LABEL_INVALID;
9117   int ret;
9118
9119   /* Parse args required to build the message */
9120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9121     {
9122       if (unformat (i, "sub-domain %d", &sub_domain))
9123         ;
9124       else if (unformat (i, "set %d", &set))
9125         ;
9126       else if (unformat (i, "label %d", &local_label))
9127         ;
9128       else if (unformat (i, "hdr-len %d", &hdr_len))
9129         ;
9130       else if (unformat (i, "add"))
9131         is_add = 1;
9132       else if (unformat (i, "del"))
9133         is_add = 0;
9134       else
9135         {
9136           clib_warning ("parse error '%U'", format_unformat_error, i);
9137           return -99;
9138         }
9139     }
9140
9141   if (MPLS_LABEL_INVALID == local_label)
9142     {
9143       errmsg ("missing label\n");
9144       return -99;
9145     }
9146
9147   /* Construct the API message */
9148   M (BIER_TABLE_ADD_DEL, mp);
9149
9150   mp->bt_is_add = is_add;
9151   mp->bt_label = ntohl (local_label);
9152   mp->bt_tbl_id.bt_set = set;
9153   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9154   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9155
9156   /* send it... */
9157   S (mp);
9158
9159   /* Wait for a reply... */
9160   W (ret);
9161
9162   return (ret);
9163 }
9164
9165 static int
9166 api_bier_route_add_del (vat_main_t * vam)
9167 {
9168   unformat_input_t *i = vam->input;
9169   vl_api_bier_route_add_del_t *mp;
9170   u8 is_add = 1;
9171   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9172   ip4_address_t v4_next_hop_address;
9173   ip6_address_t v6_next_hop_address;
9174   u8 next_hop_set = 0;
9175   u8 next_hop_proto_is_ip4 = 1;
9176   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9177   int ret;
9178
9179   /* Parse args required to build the message */
9180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9181     {
9182       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9183         {
9184           next_hop_proto_is_ip4 = 1;
9185           next_hop_set = 1;
9186         }
9187       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9188         {
9189           next_hop_proto_is_ip4 = 0;
9190           next_hop_set = 1;
9191         }
9192       if (unformat (i, "sub-domain %d", &sub_domain))
9193         ;
9194       else if (unformat (i, "set %d", &set))
9195         ;
9196       else if (unformat (i, "hdr-len %d", &hdr_len))
9197         ;
9198       else if (unformat (i, "bp %d", &bp))
9199         ;
9200       else if (unformat (i, "add"))
9201         is_add = 1;
9202       else if (unformat (i, "del"))
9203         is_add = 0;
9204       else if (unformat (i, "out-label %d", &next_hop_out_label))
9205         ;
9206       else
9207         {
9208           clib_warning ("parse error '%U'", format_unformat_error, i);
9209           return -99;
9210         }
9211     }
9212
9213   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9214     {
9215       errmsg ("next hop / label set\n");
9216       return -99;
9217     }
9218   if (0 == bp)
9219     {
9220       errmsg ("bit=position not set\n");
9221       return -99;
9222     }
9223
9224   /* Construct the API message */
9225   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9226
9227   mp->br_is_add = is_add;
9228   mp->br_tbl_id.bt_set = set;
9229   mp->br_tbl_id.bt_sub_domain = sub_domain;
9230   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9231   mp->br_bp = ntohs (bp);
9232   mp->br_n_paths = 1;
9233   mp->br_paths[0].n_labels = 1;
9234   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9235   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9236
9237   if (next_hop_proto_is_ip4)
9238     {
9239       clib_memcpy (mp->br_paths[0].next_hop,
9240                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9241     }
9242   else
9243     {
9244       clib_memcpy (mp->br_paths[0].next_hop,
9245                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9246     }
9247
9248   /* send it... */
9249   S (mp);
9250
9251   /* Wait for a reply... */
9252   W (ret);
9253
9254   return (ret);
9255 }
9256
9257 static int
9258 api_proxy_arp_add_del (vat_main_t * vam)
9259 {
9260   unformat_input_t *i = vam->input;
9261   vl_api_proxy_arp_add_del_t *mp;
9262   u32 vrf_id = 0;
9263   u8 is_add = 1;
9264   ip4_address_t lo, hi;
9265   u8 range_set = 0;
9266   int ret;
9267
9268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9269     {
9270       if (unformat (i, "vrf %d", &vrf_id))
9271         ;
9272       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9273                          unformat_ip4_address, &hi))
9274         range_set = 1;
9275       else if (unformat (i, "del"))
9276         is_add = 0;
9277       else
9278         {
9279           clib_warning ("parse error '%U'", format_unformat_error, i);
9280           return -99;
9281         }
9282     }
9283
9284   if (range_set == 0)
9285     {
9286       errmsg ("address range not set");
9287       return -99;
9288     }
9289
9290   M (PROXY_ARP_ADD_DEL, mp);
9291
9292   mp->proxy.vrf_id = ntohl (vrf_id);
9293   mp->is_add = is_add;
9294   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9295   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9296
9297   S (mp);
9298   W (ret);
9299   return ret;
9300 }
9301
9302 static int
9303 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9304 {
9305   unformat_input_t *i = vam->input;
9306   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9307   u32 sw_if_index;
9308   u8 enable = 1;
9309   u8 sw_if_index_set = 0;
9310   int ret;
9311
9312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9313     {
9314       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9315         sw_if_index_set = 1;
9316       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9317         sw_if_index_set = 1;
9318       else if (unformat (i, "enable"))
9319         enable = 1;
9320       else if (unformat (i, "disable"))
9321         enable = 0;
9322       else
9323         {
9324           clib_warning ("parse error '%U'", format_unformat_error, i);
9325           return -99;
9326         }
9327     }
9328
9329   if (sw_if_index_set == 0)
9330     {
9331       errmsg ("missing interface name or sw_if_index");
9332       return -99;
9333     }
9334
9335   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9336
9337   mp->sw_if_index = ntohl (sw_if_index);
9338   mp->enable_disable = enable;
9339
9340   S (mp);
9341   W (ret);
9342   return ret;
9343 }
9344
9345 static int
9346 api_mpls_tunnel_add_del (vat_main_t * vam)
9347 {
9348   unformat_input_t *i = vam->input;
9349   vl_api_mpls_tunnel_add_del_t *mp;
9350
9351   u8 is_add = 1;
9352   u8 l2_only = 0;
9353   u32 sw_if_index = ~0;
9354   u32 next_hop_sw_if_index = ~0;
9355   u32 next_hop_proto_is_ip4 = 1;
9356
9357   u32 next_hop_table_id = 0;
9358   ip4_address_t v4_next_hop_address = {
9359     .as_u32 = 0,
9360   };
9361   ip6_address_t v6_next_hop_address = { {0} };
9362   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9363   int ret;
9364
9365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9366     {
9367       if (unformat (i, "add"))
9368         is_add = 1;
9369       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9370         is_add = 0;
9371       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9372         ;
9373       else if (unformat (i, "via %U",
9374                          unformat_ip4_address, &v4_next_hop_address))
9375         {
9376           next_hop_proto_is_ip4 = 1;
9377         }
9378       else if (unformat (i, "via %U",
9379                          unformat_ip6_address, &v6_next_hop_address))
9380         {
9381           next_hop_proto_is_ip4 = 0;
9382         }
9383       else if (unformat (i, "l2-only"))
9384         l2_only = 1;
9385       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9386         ;
9387       else if (unformat (i, "out-label %d", &next_hop_out_label))
9388         vec_add1 (labels, ntohl (next_hop_out_label));
9389       else
9390         {
9391           clib_warning ("parse error '%U'", format_unformat_error, i);
9392           return -99;
9393         }
9394     }
9395
9396   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9397
9398   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9399   mp->mt_sw_if_index = ntohl (sw_if_index);
9400   mp->mt_is_add = is_add;
9401   mp->mt_l2_only = l2_only;
9402   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9403   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9404
9405   mp->mt_next_hop_n_out_labels = vec_len (labels);
9406
9407   if (0 != mp->mt_next_hop_n_out_labels)
9408     {
9409       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9410                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9411       vec_free (labels);
9412     }
9413
9414   if (next_hop_proto_is_ip4)
9415     {
9416       clib_memcpy (mp->mt_next_hop,
9417                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9418     }
9419   else
9420     {
9421       clib_memcpy (mp->mt_next_hop,
9422                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9423     }
9424
9425   S (mp);
9426   W (ret);
9427   return ret;
9428 }
9429
9430 static int
9431 api_sw_interface_set_unnumbered (vat_main_t * vam)
9432 {
9433   unformat_input_t *i = vam->input;
9434   vl_api_sw_interface_set_unnumbered_t *mp;
9435   u32 sw_if_index;
9436   u32 unnum_sw_index = ~0;
9437   u8 is_add = 1;
9438   u8 sw_if_index_set = 0;
9439   int ret;
9440
9441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9442     {
9443       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9444         sw_if_index_set = 1;
9445       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9446         sw_if_index_set = 1;
9447       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9448         ;
9449       else if (unformat (i, "del"))
9450         is_add = 0;
9451       else
9452         {
9453           clib_warning ("parse error '%U'", format_unformat_error, i);
9454           return -99;
9455         }
9456     }
9457
9458   if (sw_if_index_set == 0)
9459     {
9460       errmsg ("missing interface name or sw_if_index");
9461       return -99;
9462     }
9463
9464   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9465
9466   mp->sw_if_index = ntohl (sw_if_index);
9467   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9468   mp->is_add = is_add;
9469
9470   S (mp);
9471   W (ret);
9472   return ret;
9473 }
9474
9475 static int
9476 api_ip_neighbor_add_del (vat_main_t * vam)
9477 {
9478   unformat_input_t *i = vam->input;
9479   vl_api_ip_neighbor_add_del_t *mp;
9480   u32 sw_if_index;
9481   u8 sw_if_index_set = 0;
9482   u8 is_add = 1;
9483   u8 is_static = 0;
9484   u8 is_no_fib_entry = 0;
9485   u8 mac_address[6];
9486   u8 mac_set = 0;
9487   u8 v4_address_set = 0;
9488   u8 v6_address_set = 0;
9489   ip4_address_t v4address;
9490   ip6_address_t v6address;
9491   int ret;
9492
9493   memset (mac_address, 0, sizeof (mac_address));
9494
9495   /* Parse args required to build the message */
9496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9497     {
9498       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9499         {
9500           mac_set = 1;
9501         }
9502       else if (unformat (i, "del"))
9503         is_add = 0;
9504       else
9505         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9506         sw_if_index_set = 1;
9507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9508         sw_if_index_set = 1;
9509       else if (unformat (i, "is_static"))
9510         is_static = 1;
9511       else if (unformat (i, "no-fib-entry"))
9512         is_no_fib_entry = 1;
9513       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9514         v4_address_set = 1;
9515       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9516         v6_address_set = 1;
9517       else
9518         {
9519           clib_warning ("parse error '%U'", format_unformat_error, i);
9520           return -99;
9521         }
9522     }
9523
9524   if (sw_if_index_set == 0)
9525     {
9526       errmsg ("missing interface name or sw_if_index");
9527       return -99;
9528     }
9529   if (v4_address_set && v6_address_set)
9530     {
9531       errmsg ("both v4 and v6 addresses set");
9532       return -99;
9533     }
9534   if (!v4_address_set && !v6_address_set)
9535     {
9536       errmsg ("no address set");
9537       return -99;
9538     }
9539
9540   /* Construct the API message */
9541   M (IP_NEIGHBOR_ADD_DEL, mp);
9542
9543   mp->sw_if_index = ntohl (sw_if_index);
9544   mp->is_add = is_add;
9545   mp->is_static = is_static;
9546   mp->is_no_adj_fib = is_no_fib_entry;
9547   if (mac_set)
9548     clib_memcpy (mp->mac_address, mac_address, 6);
9549   if (v6_address_set)
9550     {
9551       mp->is_ipv6 = 1;
9552       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9553     }
9554   else
9555     {
9556       /* mp->is_ipv6 = 0; via memset in M macro above */
9557       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9558     }
9559
9560   /* send it... */
9561   S (mp);
9562
9563   /* Wait for a reply, return good/bad news  */
9564   W (ret);
9565   return ret;
9566 }
9567
9568 static int
9569 api_create_vlan_subif (vat_main_t * vam)
9570 {
9571   unformat_input_t *i = vam->input;
9572   vl_api_create_vlan_subif_t *mp;
9573   u32 sw_if_index;
9574   u8 sw_if_index_set = 0;
9575   u32 vlan_id;
9576   u8 vlan_id_set = 0;
9577   int ret;
9578
9579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9580     {
9581       if (unformat (i, "sw_if_index %d", &sw_if_index))
9582         sw_if_index_set = 1;
9583       else
9584         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9585         sw_if_index_set = 1;
9586       else if (unformat (i, "vlan %d", &vlan_id))
9587         vlan_id_set = 1;
9588       else
9589         {
9590           clib_warning ("parse error '%U'", format_unformat_error, i);
9591           return -99;
9592         }
9593     }
9594
9595   if (sw_if_index_set == 0)
9596     {
9597       errmsg ("missing interface name or sw_if_index");
9598       return -99;
9599     }
9600
9601   if (vlan_id_set == 0)
9602     {
9603       errmsg ("missing vlan_id");
9604       return -99;
9605     }
9606   M (CREATE_VLAN_SUBIF, mp);
9607
9608   mp->sw_if_index = ntohl (sw_if_index);
9609   mp->vlan_id = ntohl (vlan_id);
9610
9611   S (mp);
9612   W (ret);
9613   return ret;
9614 }
9615
9616 #define foreach_create_subif_bit                \
9617 _(no_tags)                                      \
9618 _(one_tag)                                      \
9619 _(two_tags)                                     \
9620 _(dot1ad)                                       \
9621 _(exact_match)                                  \
9622 _(default_sub)                                  \
9623 _(outer_vlan_id_any)                            \
9624 _(inner_vlan_id_any)
9625
9626 static int
9627 api_create_subif (vat_main_t * vam)
9628 {
9629   unformat_input_t *i = vam->input;
9630   vl_api_create_subif_t *mp;
9631   u32 sw_if_index;
9632   u8 sw_if_index_set = 0;
9633   u32 sub_id;
9634   u8 sub_id_set = 0;
9635   u32 no_tags = 0;
9636   u32 one_tag = 0;
9637   u32 two_tags = 0;
9638   u32 dot1ad = 0;
9639   u32 exact_match = 0;
9640   u32 default_sub = 0;
9641   u32 outer_vlan_id_any = 0;
9642   u32 inner_vlan_id_any = 0;
9643   u32 tmp;
9644   u16 outer_vlan_id = 0;
9645   u16 inner_vlan_id = 0;
9646   int ret;
9647
9648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9649     {
9650       if (unformat (i, "sw_if_index %d", &sw_if_index))
9651         sw_if_index_set = 1;
9652       else
9653         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9654         sw_if_index_set = 1;
9655       else if (unformat (i, "sub_id %d", &sub_id))
9656         sub_id_set = 1;
9657       else if (unformat (i, "outer_vlan_id %d", &tmp))
9658         outer_vlan_id = tmp;
9659       else if (unformat (i, "inner_vlan_id %d", &tmp))
9660         inner_vlan_id = tmp;
9661
9662 #define _(a) else if (unformat (i, #a)) a = 1 ;
9663       foreach_create_subif_bit
9664 #undef _
9665         else
9666         {
9667           clib_warning ("parse error '%U'", format_unformat_error, i);
9668           return -99;
9669         }
9670     }
9671
9672   if (sw_if_index_set == 0)
9673     {
9674       errmsg ("missing interface name or sw_if_index");
9675       return -99;
9676     }
9677
9678   if (sub_id_set == 0)
9679     {
9680       errmsg ("missing sub_id");
9681       return -99;
9682     }
9683   M (CREATE_SUBIF, mp);
9684
9685   mp->sw_if_index = ntohl (sw_if_index);
9686   mp->sub_id = ntohl (sub_id);
9687
9688 #define _(a) mp->a = a;
9689   foreach_create_subif_bit;
9690 #undef _
9691
9692   mp->outer_vlan_id = ntohs (outer_vlan_id);
9693   mp->inner_vlan_id = ntohs (inner_vlan_id);
9694
9695   S (mp);
9696   W (ret);
9697   return ret;
9698 }
9699
9700 static int
9701 api_oam_add_del (vat_main_t * vam)
9702 {
9703   unformat_input_t *i = vam->input;
9704   vl_api_oam_add_del_t *mp;
9705   u32 vrf_id = 0;
9706   u8 is_add = 1;
9707   ip4_address_t src, dst;
9708   u8 src_set = 0;
9709   u8 dst_set = 0;
9710   int ret;
9711
9712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9713     {
9714       if (unformat (i, "vrf %d", &vrf_id))
9715         ;
9716       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9717         src_set = 1;
9718       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9719         dst_set = 1;
9720       else if (unformat (i, "del"))
9721         is_add = 0;
9722       else
9723         {
9724           clib_warning ("parse error '%U'", format_unformat_error, i);
9725           return -99;
9726         }
9727     }
9728
9729   if (src_set == 0)
9730     {
9731       errmsg ("missing src addr");
9732       return -99;
9733     }
9734
9735   if (dst_set == 0)
9736     {
9737       errmsg ("missing dst addr");
9738       return -99;
9739     }
9740
9741   M (OAM_ADD_DEL, mp);
9742
9743   mp->vrf_id = ntohl (vrf_id);
9744   mp->is_add = is_add;
9745   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9746   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9747
9748   S (mp);
9749   W (ret);
9750   return ret;
9751 }
9752
9753 static int
9754 api_reset_fib (vat_main_t * vam)
9755 {
9756   unformat_input_t *i = vam->input;
9757   vl_api_reset_fib_t *mp;
9758   u32 vrf_id = 0;
9759   u8 is_ipv6 = 0;
9760   u8 vrf_id_set = 0;
9761
9762   int ret;
9763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9764     {
9765       if (unformat (i, "vrf %d", &vrf_id))
9766         vrf_id_set = 1;
9767       else if (unformat (i, "ipv6"))
9768         is_ipv6 = 1;
9769       else
9770         {
9771           clib_warning ("parse error '%U'", format_unformat_error, i);
9772           return -99;
9773         }
9774     }
9775
9776   if (vrf_id_set == 0)
9777     {
9778       errmsg ("missing vrf id");
9779       return -99;
9780     }
9781
9782   M (RESET_FIB, mp);
9783
9784   mp->vrf_id = ntohl (vrf_id);
9785   mp->is_ipv6 = is_ipv6;
9786
9787   S (mp);
9788   W (ret);
9789   return ret;
9790 }
9791
9792 static int
9793 api_dhcp_proxy_config (vat_main_t * vam)
9794 {
9795   unformat_input_t *i = vam->input;
9796   vl_api_dhcp_proxy_config_t *mp;
9797   u32 rx_vrf_id = 0;
9798   u32 server_vrf_id = 0;
9799   u8 is_add = 1;
9800   u8 v4_address_set = 0;
9801   u8 v6_address_set = 0;
9802   ip4_address_t v4address;
9803   ip6_address_t v6address;
9804   u8 v4_src_address_set = 0;
9805   u8 v6_src_address_set = 0;
9806   ip4_address_t v4srcaddress;
9807   ip6_address_t v6srcaddress;
9808   int ret;
9809
9810   /* Parse args required to build the message */
9811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9812     {
9813       if (unformat (i, "del"))
9814         is_add = 0;
9815       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9816         ;
9817       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9818         ;
9819       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9820         v4_address_set = 1;
9821       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9822         v6_address_set = 1;
9823       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9824         v4_src_address_set = 1;
9825       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9826         v6_src_address_set = 1;
9827       else
9828         break;
9829     }
9830
9831   if (v4_address_set && v6_address_set)
9832     {
9833       errmsg ("both v4 and v6 server addresses set");
9834       return -99;
9835     }
9836   if (!v4_address_set && !v6_address_set)
9837     {
9838       errmsg ("no server addresses set");
9839       return -99;
9840     }
9841
9842   if (v4_src_address_set && v6_src_address_set)
9843     {
9844       errmsg ("both v4 and v6  src addresses set");
9845       return -99;
9846     }
9847   if (!v4_src_address_set && !v6_src_address_set)
9848     {
9849       errmsg ("no src addresses set");
9850       return -99;
9851     }
9852
9853   if (!(v4_src_address_set && v4_address_set) &&
9854       !(v6_src_address_set && v6_address_set))
9855     {
9856       errmsg ("no matching server and src addresses set");
9857       return -99;
9858     }
9859
9860   /* Construct the API message */
9861   M (DHCP_PROXY_CONFIG, mp);
9862
9863   mp->is_add = is_add;
9864   mp->rx_vrf_id = ntohl (rx_vrf_id);
9865   mp->server_vrf_id = ntohl (server_vrf_id);
9866   if (v6_address_set)
9867     {
9868       mp->is_ipv6 = 1;
9869       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9870       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9871     }
9872   else
9873     {
9874       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9875       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9876     }
9877
9878   /* send it... */
9879   S (mp);
9880
9881   /* Wait for a reply, return good/bad news  */
9882   W (ret);
9883   return ret;
9884 }
9885
9886 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9887 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9888
9889 static void
9890 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9891 {
9892   vat_main_t *vam = &vat_main;
9893   u32 i, count = mp->count;
9894   vl_api_dhcp_server_t *s;
9895
9896   if (mp->is_ipv6)
9897     print (vam->ofp,
9898            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9899            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9900            ntohl (mp->rx_vrf_id),
9901            format_ip6_address, mp->dhcp_src_address,
9902            mp->vss_type, mp->vss_vpn_ascii_id,
9903            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9904   else
9905     print (vam->ofp,
9906            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9907            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9908            ntohl (mp->rx_vrf_id),
9909            format_ip4_address, mp->dhcp_src_address,
9910            mp->vss_type, mp->vss_vpn_ascii_id,
9911            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9912
9913   for (i = 0; i < count; i++)
9914     {
9915       s = &mp->servers[i];
9916
9917       if (mp->is_ipv6)
9918         print (vam->ofp,
9919                " Server Table-ID %d, Server Address %U",
9920                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9921       else
9922         print (vam->ofp,
9923                " Server Table-ID %d, Server Address %U",
9924                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9925     }
9926 }
9927
9928 static void vl_api_dhcp_proxy_details_t_handler_json
9929   (vl_api_dhcp_proxy_details_t * mp)
9930 {
9931   vat_main_t *vam = &vat_main;
9932   vat_json_node_t *node = NULL;
9933   u32 i, count = mp->count;
9934   struct in_addr ip4;
9935   struct in6_addr ip6;
9936   vl_api_dhcp_server_t *s;
9937
9938   if (VAT_JSON_ARRAY != vam->json_tree.type)
9939     {
9940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9941       vat_json_init_array (&vam->json_tree);
9942     }
9943   node = vat_json_array_add (&vam->json_tree);
9944
9945   vat_json_init_object (node);
9946   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9947   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9948                              sizeof (mp->vss_type));
9949   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9950                                    mp->vss_vpn_ascii_id);
9951   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9952   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9953
9954   if (mp->is_ipv6)
9955     {
9956       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9957       vat_json_object_add_ip6 (node, "src_address", ip6);
9958     }
9959   else
9960     {
9961       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9962       vat_json_object_add_ip4 (node, "src_address", ip4);
9963     }
9964
9965   for (i = 0; i < count; i++)
9966     {
9967       s = &mp->servers[i];
9968
9969       vat_json_object_add_uint (node, "server-table-id",
9970                                 ntohl (s->server_vrf_id));
9971
9972       if (mp->is_ipv6)
9973         {
9974           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9975           vat_json_object_add_ip4 (node, "src_address", ip4);
9976         }
9977       else
9978         {
9979           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9980           vat_json_object_add_ip6 (node, "server_address", ip6);
9981         }
9982     }
9983 }
9984
9985 static int
9986 api_dhcp_proxy_dump (vat_main_t * vam)
9987 {
9988   unformat_input_t *i = vam->input;
9989   vl_api_control_ping_t *mp_ping;
9990   vl_api_dhcp_proxy_dump_t *mp;
9991   u8 is_ipv6 = 0;
9992   int ret;
9993
9994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9995     {
9996       if (unformat (i, "ipv6"))
9997         is_ipv6 = 1;
9998       else
9999         {
10000           clib_warning ("parse error '%U'", format_unformat_error, i);
10001           return -99;
10002         }
10003     }
10004
10005   M (DHCP_PROXY_DUMP, mp);
10006
10007   mp->is_ip6 = is_ipv6;
10008   S (mp);
10009
10010   /* Use a control ping for synchronization */
10011   MPING (CONTROL_PING, mp_ping);
10012   S (mp_ping);
10013
10014   W (ret);
10015   return ret;
10016 }
10017
10018 static int
10019 api_dhcp_proxy_set_vss (vat_main_t * vam)
10020 {
10021   unformat_input_t *i = vam->input;
10022   vl_api_dhcp_proxy_set_vss_t *mp;
10023   u8 is_ipv6 = 0;
10024   u8 is_add = 1;
10025   u32 tbl_id = ~0;
10026   u8 vss_type = VSS_TYPE_DEFAULT;
10027   u8 *vpn_ascii_id = 0;
10028   u32 oui = 0;
10029   u32 fib_id = 0;
10030   int ret;
10031
10032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10033     {
10034       if (unformat (i, "tbl_id %d", &tbl_id))
10035         ;
10036       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10037         vss_type = VSS_TYPE_ASCII;
10038       else if (unformat (i, "fib_id %d", &fib_id))
10039         vss_type = VSS_TYPE_VPN_ID;
10040       else if (unformat (i, "oui %d", &oui))
10041         vss_type = VSS_TYPE_VPN_ID;
10042       else if (unformat (i, "ipv6"))
10043         is_ipv6 = 1;
10044       else if (unformat (i, "del"))
10045         is_add = 0;
10046       else
10047         break;
10048     }
10049
10050   if (tbl_id == ~0)
10051     {
10052       errmsg ("missing tbl_id ");
10053       vec_free (vpn_ascii_id);
10054       return -99;
10055     }
10056
10057   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10058     {
10059       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10060       vec_free (vpn_ascii_id);
10061       return -99;
10062     }
10063
10064   M (DHCP_PROXY_SET_VSS, mp);
10065   mp->tbl_id = ntohl (tbl_id);
10066   mp->vss_type = vss_type;
10067   if (vpn_ascii_id)
10068     {
10069       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10070       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10071     }
10072   mp->vpn_index = ntohl (fib_id);
10073   mp->oui = ntohl (oui);
10074   mp->is_ipv6 = is_ipv6;
10075   mp->is_add = is_add;
10076
10077   S (mp);
10078   W (ret);
10079
10080   vec_free (vpn_ascii_id);
10081   return ret;
10082 }
10083
10084 static int
10085 api_dhcp_client_config (vat_main_t * vam)
10086 {
10087   unformat_input_t *i = vam->input;
10088   vl_api_dhcp_client_config_t *mp;
10089   u32 sw_if_index;
10090   u8 sw_if_index_set = 0;
10091   u8 is_add = 1;
10092   u8 *hostname = 0;
10093   u8 disable_event = 0;
10094   int ret;
10095
10096   /* Parse args required to build the message */
10097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10098     {
10099       if (unformat (i, "del"))
10100         is_add = 0;
10101       else
10102         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10103         sw_if_index_set = 1;
10104       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10105         sw_if_index_set = 1;
10106       else if (unformat (i, "hostname %s", &hostname))
10107         ;
10108       else if (unformat (i, "disable_event"))
10109         disable_event = 1;
10110       else
10111         break;
10112     }
10113
10114   if (sw_if_index_set == 0)
10115     {
10116       errmsg ("missing interface name or sw_if_index");
10117       return -99;
10118     }
10119
10120   if (vec_len (hostname) > 63)
10121     {
10122       errmsg ("hostname too long");
10123     }
10124   vec_add1 (hostname, 0);
10125
10126   /* Construct the API message */
10127   M (DHCP_CLIENT_CONFIG, mp);
10128
10129   mp->is_add = is_add;
10130   mp->client.sw_if_index = htonl (sw_if_index);
10131   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10132   vec_free (hostname);
10133   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10134   mp->client.pid = htonl (getpid ());
10135
10136   /* send it... */
10137   S (mp);
10138
10139   /* Wait for a reply, return good/bad news  */
10140   W (ret);
10141   return ret;
10142 }
10143
10144 static int
10145 api_set_ip_flow_hash (vat_main_t * vam)
10146 {
10147   unformat_input_t *i = vam->input;
10148   vl_api_set_ip_flow_hash_t *mp;
10149   u32 vrf_id = 0;
10150   u8 is_ipv6 = 0;
10151   u8 vrf_id_set = 0;
10152   u8 src = 0;
10153   u8 dst = 0;
10154   u8 sport = 0;
10155   u8 dport = 0;
10156   u8 proto = 0;
10157   u8 reverse = 0;
10158   int ret;
10159
10160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10161     {
10162       if (unformat (i, "vrf %d", &vrf_id))
10163         vrf_id_set = 1;
10164       else if (unformat (i, "ipv6"))
10165         is_ipv6 = 1;
10166       else if (unformat (i, "src"))
10167         src = 1;
10168       else if (unformat (i, "dst"))
10169         dst = 1;
10170       else if (unformat (i, "sport"))
10171         sport = 1;
10172       else if (unformat (i, "dport"))
10173         dport = 1;
10174       else if (unformat (i, "proto"))
10175         proto = 1;
10176       else if (unformat (i, "reverse"))
10177         reverse = 1;
10178
10179       else
10180         {
10181           clib_warning ("parse error '%U'", format_unformat_error, i);
10182           return -99;
10183         }
10184     }
10185
10186   if (vrf_id_set == 0)
10187     {
10188       errmsg ("missing vrf id");
10189       return -99;
10190     }
10191
10192   M (SET_IP_FLOW_HASH, mp);
10193   mp->src = src;
10194   mp->dst = dst;
10195   mp->sport = sport;
10196   mp->dport = dport;
10197   mp->proto = proto;
10198   mp->reverse = reverse;
10199   mp->vrf_id = ntohl (vrf_id);
10200   mp->is_ipv6 = is_ipv6;
10201
10202   S (mp);
10203   W (ret);
10204   return ret;
10205 }
10206
10207 static int
10208 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10209 {
10210   unformat_input_t *i = vam->input;
10211   vl_api_sw_interface_ip6_enable_disable_t *mp;
10212   u32 sw_if_index;
10213   u8 sw_if_index_set = 0;
10214   u8 enable = 0;
10215   int ret;
10216
10217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10218     {
10219       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10220         sw_if_index_set = 1;
10221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10222         sw_if_index_set = 1;
10223       else if (unformat (i, "enable"))
10224         enable = 1;
10225       else if (unformat (i, "disable"))
10226         enable = 0;
10227       else
10228         {
10229           clib_warning ("parse error '%U'", format_unformat_error, i);
10230           return -99;
10231         }
10232     }
10233
10234   if (sw_if_index_set == 0)
10235     {
10236       errmsg ("missing interface name or sw_if_index");
10237       return -99;
10238     }
10239
10240   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10241
10242   mp->sw_if_index = ntohl (sw_if_index);
10243   mp->enable = enable;
10244
10245   S (mp);
10246   W (ret);
10247   return ret;
10248 }
10249
10250 static int
10251 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10252 {
10253   unformat_input_t *i = vam->input;
10254   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10255   u32 sw_if_index;
10256   u8 sw_if_index_set = 0;
10257   u8 v6_address_set = 0;
10258   ip6_address_t v6address;
10259   int ret;
10260
10261   /* Parse args required to build the message */
10262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10263     {
10264       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10265         sw_if_index_set = 1;
10266       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10267         sw_if_index_set = 1;
10268       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10269         v6_address_set = 1;
10270       else
10271         break;
10272     }
10273
10274   if (sw_if_index_set == 0)
10275     {
10276       errmsg ("missing interface name or sw_if_index");
10277       return -99;
10278     }
10279   if (!v6_address_set)
10280     {
10281       errmsg ("no address set");
10282       return -99;
10283     }
10284
10285   /* Construct the API message */
10286   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10287
10288   mp->sw_if_index = ntohl (sw_if_index);
10289   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10290
10291   /* send it... */
10292   S (mp);
10293
10294   /* Wait for a reply, return good/bad news  */
10295   W (ret);
10296   return ret;
10297 }
10298
10299 static int
10300 api_ip6nd_proxy_add_del (vat_main_t * vam)
10301 {
10302   unformat_input_t *i = vam->input;
10303   vl_api_ip6nd_proxy_add_del_t *mp;
10304   u32 sw_if_index = ~0;
10305   u8 v6_address_set = 0;
10306   ip6_address_t v6address;
10307   u8 is_del = 0;
10308   int ret;
10309
10310   /* Parse args required to build the message */
10311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10312     {
10313       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10314         ;
10315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10316         ;
10317       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10318         v6_address_set = 1;
10319       if (unformat (i, "del"))
10320         is_del = 1;
10321       else
10322         {
10323           clib_warning ("parse error '%U'", format_unformat_error, i);
10324           return -99;
10325         }
10326     }
10327
10328   if (sw_if_index == ~0)
10329     {
10330       errmsg ("missing interface name or sw_if_index");
10331       return -99;
10332     }
10333   if (!v6_address_set)
10334     {
10335       errmsg ("no address set");
10336       return -99;
10337     }
10338
10339   /* Construct the API message */
10340   M (IP6ND_PROXY_ADD_DEL, mp);
10341
10342   mp->is_del = is_del;
10343   mp->sw_if_index = ntohl (sw_if_index);
10344   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10345
10346   /* send it... */
10347   S (mp);
10348
10349   /* Wait for a reply, return good/bad news  */
10350   W (ret);
10351   return ret;
10352 }
10353
10354 static int
10355 api_ip6nd_proxy_dump (vat_main_t * vam)
10356 {
10357   vl_api_ip6nd_proxy_dump_t *mp;
10358   vl_api_control_ping_t *mp_ping;
10359   int ret;
10360
10361   M (IP6ND_PROXY_DUMP, mp);
10362
10363   S (mp);
10364
10365   /* Use a control ping for synchronization */
10366   MPING (CONTROL_PING, mp_ping);
10367   S (mp_ping);
10368
10369   W (ret);
10370   return ret;
10371 }
10372
10373 static void vl_api_ip6nd_proxy_details_t_handler
10374   (vl_api_ip6nd_proxy_details_t * mp)
10375 {
10376   vat_main_t *vam = &vat_main;
10377
10378   print (vam->ofp, "host %U sw_if_index %d",
10379          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10380 }
10381
10382 static void vl_api_ip6nd_proxy_details_t_handler_json
10383   (vl_api_ip6nd_proxy_details_t * mp)
10384 {
10385   vat_main_t *vam = &vat_main;
10386   struct in6_addr ip6;
10387   vat_json_node_t *node = NULL;
10388
10389   if (VAT_JSON_ARRAY != vam->json_tree.type)
10390     {
10391       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10392       vat_json_init_array (&vam->json_tree);
10393     }
10394   node = vat_json_array_add (&vam->json_tree);
10395
10396   vat_json_init_object (node);
10397   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10398
10399   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10400   vat_json_object_add_ip6 (node, "host", ip6);
10401 }
10402
10403 static int
10404 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10405 {
10406   unformat_input_t *i = vam->input;
10407   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10408   u32 sw_if_index;
10409   u8 sw_if_index_set = 0;
10410   u32 address_length = 0;
10411   u8 v6_address_set = 0;
10412   ip6_address_t v6address;
10413   u8 use_default = 0;
10414   u8 no_advertise = 0;
10415   u8 off_link = 0;
10416   u8 no_autoconfig = 0;
10417   u8 no_onlink = 0;
10418   u8 is_no = 0;
10419   u32 val_lifetime = 0;
10420   u32 pref_lifetime = 0;
10421   int ret;
10422
10423   /* Parse args required to build the message */
10424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10425     {
10426       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10427         sw_if_index_set = 1;
10428       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10429         sw_if_index_set = 1;
10430       else if (unformat (i, "%U/%d",
10431                          unformat_ip6_address, &v6address, &address_length))
10432         v6_address_set = 1;
10433       else if (unformat (i, "val_life %d", &val_lifetime))
10434         ;
10435       else if (unformat (i, "pref_life %d", &pref_lifetime))
10436         ;
10437       else if (unformat (i, "def"))
10438         use_default = 1;
10439       else if (unformat (i, "noadv"))
10440         no_advertise = 1;
10441       else if (unformat (i, "offl"))
10442         off_link = 1;
10443       else if (unformat (i, "noauto"))
10444         no_autoconfig = 1;
10445       else if (unformat (i, "nolink"))
10446         no_onlink = 1;
10447       else if (unformat (i, "isno"))
10448         is_no = 1;
10449       else
10450         {
10451           clib_warning ("parse error '%U'", format_unformat_error, i);
10452           return -99;
10453         }
10454     }
10455
10456   if (sw_if_index_set == 0)
10457     {
10458       errmsg ("missing interface name or sw_if_index");
10459       return -99;
10460     }
10461   if (!v6_address_set)
10462     {
10463       errmsg ("no address set");
10464       return -99;
10465     }
10466
10467   /* Construct the API message */
10468   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10469
10470   mp->sw_if_index = ntohl (sw_if_index);
10471   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10472   mp->address_length = address_length;
10473   mp->use_default = use_default;
10474   mp->no_advertise = no_advertise;
10475   mp->off_link = off_link;
10476   mp->no_autoconfig = no_autoconfig;
10477   mp->no_onlink = no_onlink;
10478   mp->is_no = is_no;
10479   mp->val_lifetime = ntohl (val_lifetime);
10480   mp->pref_lifetime = ntohl (pref_lifetime);
10481
10482   /* send it... */
10483   S (mp);
10484
10485   /* Wait for a reply, return good/bad news  */
10486   W (ret);
10487   return ret;
10488 }
10489
10490 static int
10491 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10492 {
10493   unformat_input_t *i = vam->input;
10494   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10495   u32 sw_if_index;
10496   u8 sw_if_index_set = 0;
10497   u8 suppress = 0;
10498   u8 managed = 0;
10499   u8 other = 0;
10500   u8 ll_option = 0;
10501   u8 send_unicast = 0;
10502   u8 cease = 0;
10503   u8 is_no = 0;
10504   u8 default_router = 0;
10505   u32 max_interval = 0;
10506   u32 min_interval = 0;
10507   u32 lifetime = 0;
10508   u32 initial_count = 0;
10509   u32 initial_interval = 0;
10510   int ret;
10511
10512
10513   /* Parse args required to build the message */
10514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10515     {
10516       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10517         sw_if_index_set = 1;
10518       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10519         sw_if_index_set = 1;
10520       else if (unformat (i, "maxint %d", &max_interval))
10521         ;
10522       else if (unformat (i, "minint %d", &min_interval))
10523         ;
10524       else if (unformat (i, "life %d", &lifetime))
10525         ;
10526       else if (unformat (i, "count %d", &initial_count))
10527         ;
10528       else if (unformat (i, "interval %d", &initial_interval))
10529         ;
10530       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10531         suppress = 1;
10532       else if (unformat (i, "managed"))
10533         managed = 1;
10534       else if (unformat (i, "other"))
10535         other = 1;
10536       else if (unformat (i, "ll"))
10537         ll_option = 1;
10538       else if (unformat (i, "send"))
10539         send_unicast = 1;
10540       else if (unformat (i, "cease"))
10541         cease = 1;
10542       else if (unformat (i, "isno"))
10543         is_no = 1;
10544       else if (unformat (i, "def"))
10545         default_router = 1;
10546       else
10547         {
10548           clib_warning ("parse error '%U'", format_unformat_error, i);
10549           return -99;
10550         }
10551     }
10552
10553   if (sw_if_index_set == 0)
10554     {
10555       errmsg ("missing interface name or sw_if_index");
10556       return -99;
10557     }
10558
10559   /* Construct the API message */
10560   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10561
10562   mp->sw_if_index = ntohl (sw_if_index);
10563   mp->max_interval = ntohl (max_interval);
10564   mp->min_interval = ntohl (min_interval);
10565   mp->lifetime = ntohl (lifetime);
10566   mp->initial_count = ntohl (initial_count);
10567   mp->initial_interval = ntohl (initial_interval);
10568   mp->suppress = suppress;
10569   mp->managed = managed;
10570   mp->other = other;
10571   mp->ll_option = ll_option;
10572   mp->send_unicast = send_unicast;
10573   mp->cease = cease;
10574   mp->is_no = is_no;
10575   mp->default_router = default_router;
10576
10577   /* send it... */
10578   S (mp);
10579
10580   /* Wait for a reply, return good/bad news  */
10581   W (ret);
10582   return ret;
10583 }
10584
10585 static int
10586 api_set_arp_neighbor_limit (vat_main_t * vam)
10587 {
10588   unformat_input_t *i = vam->input;
10589   vl_api_set_arp_neighbor_limit_t *mp;
10590   u32 arp_nbr_limit;
10591   u8 limit_set = 0;
10592   u8 is_ipv6 = 0;
10593   int ret;
10594
10595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10596     {
10597       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10598         limit_set = 1;
10599       else if (unformat (i, "ipv6"))
10600         is_ipv6 = 1;
10601       else
10602         {
10603           clib_warning ("parse error '%U'", format_unformat_error, i);
10604           return -99;
10605         }
10606     }
10607
10608   if (limit_set == 0)
10609     {
10610       errmsg ("missing limit value");
10611       return -99;
10612     }
10613
10614   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10615
10616   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10617   mp->is_ipv6 = is_ipv6;
10618
10619   S (mp);
10620   W (ret);
10621   return ret;
10622 }
10623
10624 static int
10625 api_l2_patch_add_del (vat_main_t * vam)
10626 {
10627   unformat_input_t *i = vam->input;
10628   vl_api_l2_patch_add_del_t *mp;
10629   u32 rx_sw_if_index;
10630   u8 rx_sw_if_index_set = 0;
10631   u32 tx_sw_if_index;
10632   u8 tx_sw_if_index_set = 0;
10633   u8 is_add = 1;
10634   int ret;
10635
10636   /* Parse args required to build the message */
10637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10638     {
10639       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10640         rx_sw_if_index_set = 1;
10641       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10642         tx_sw_if_index_set = 1;
10643       else if (unformat (i, "rx"))
10644         {
10645           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10646             {
10647               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10648                             &rx_sw_if_index))
10649                 rx_sw_if_index_set = 1;
10650             }
10651           else
10652             break;
10653         }
10654       else if (unformat (i, "tx"))
10655         {
10656           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10657             {
10658               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10659                             &tx_sw_if_index))
10660                 tx_sw_if_index_set = 1;
10661             }
10662           else
10663             break;
10664         }
10665       else if (unformat (i, "del"))
10666         is_add = 0;
10667       else
10668         break;
10669     }
10670
10671   if (rx_sw_if_index_set == 0)
10672     {
10673       errmsg ("missing rx interface name or rx_sw_if_index");
10674       return -99;
10675     }
10676
10677   if (tx_sw_if_index_set == 0)
10678     {
10679       errmsg ("missing tx interface name or tx_sw_if_index");
10680       return -99;
10681     }
10682
10683   M (L2_PATCH_ADD_DEL, mp);
10684
10685   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10686   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10687   mp->is_add = is_add;
10688
10689   S (mp);
10690   W (ret);
10691   return ret;
10692 }
10693
10694 u8 is_del;
10695 u8 localsid_addr[16];
10696 u8 end_psp;
10697 u8 behavior;
10698 u32 sw_if_index;
10699 u32 vlan_index;
10700 u32 fib_table;
10701 u8 nh_addr[16];
10702
10703 static int
10704 api_sr_localsid_add_del (vat_main_t * vam)
10705 {
10706   unformat_input_t *i = vam->input;
10707   vl_api_sr_localsid_add_del_t *mp;
10708
10709   u8 is_del;
10710   ip6_address_t localsid;
10711   u8 end_psp = 0;
10712   u8 behavior = ~0;
10713   u32 sw_if_index;
10714   u32 fib_table = ~(u32) 0;
10715   ip6_address_t next_hop;
10716
10717   bool nexthop_set = 0;
10718
10719   int ret;
10720
10721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10722     {
10723       if (unformat (i, "del"))
10724         is_del = 1;
10725       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10726       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10727         nexthop_set = 1;
10728       else if (unformat (i, "behavior %u", &behavior));
10729       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10730       else if (unformat (i, "fib-table %u", &fib_table));
10731       else if (unformat (i, "end.psp %u", &behavior));
10732       else
10733         break;
10734     }
10735
10736   M (SR_LOCALSID_ADD_DEL, mp);
10737
10738   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10739   if (nexthop_set)
10740     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10741   mp->behavior = behavior;
10742   mp->sw_if_index = ntohl (sw_if_index);
10743   mp->fib_table = ntohl (fib_table);
10744   mp->end_psp = end_psp;
10745   mp->is_del = is_del;
10746
10747   S (mp);
10748   W (ret);
10749   return ret;
10750 }
10751
10752 static int
10753 api_ioam_enable (vat_main_t * vam)
10754 {
10755   unformat_input_t *input = vam->input;
10756   vl_api_ioam_enable_t *mp;
10757   u32 id = 0;
10758   int has_trace_option = 0;
10759   int has_pot_option = 0;
10760   int has_seqno_option = 0;
10761   int has_analyse_option = 0;
10762   int ret;
10763
10764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10765     {
10766       if (unformat (input, "trace"))
10767         has_trace_option = 1;
10768       else if (unformat (input, "pot"))
10769         has_pot_option = 1;
10770       else if (unformat (input, "seqno"))
10771         has_seqno_option = 1;
10772       else if (unformat (input, "analyse"))
10773         has_analyse_option = 1;
10774       else
10775         break;
10776     }
10777   M (IOAM_ENABLE, mp);
10778   mp->id = htons (id);
10779   mp->seqno = has_seqno_option;
10780   mp->analyse = has_analyse_option;
10781   mp->pot_enable = has_pot_option;
10782   mp->trace_enable = has_trace_option;
10783
10784   S (mp);
10785   W (ret);
10786   return ret;
10787 }
10788
10789
10790 static int
10791 api_ioam_disable (vat_main_t * vam)
10792 {
10793   vl_api_ioam_disable_t *mp;
10794   int ret;
10795
10796   M (IOAM_DISABLE, mp);
10797   S (mp);
10798   W (ret);
10799   return ret;
10800 }
10801
10802 #define foreach_tcp_proto_field                 \
10803 _(src_port)                                     \
10804 _(dst_port)
10805
10806 #define foreach_udp_proto_field                 \
10807 _(src_port)                                     \
10808 _(dst_port)
10809
10810 #define foreach_ip4_proto_field                 \
10811 _(src_address)                                  \
10812 _(dst_address)                                  \
10813 _(tos)                                          \
10814 _(length)                                       \
10815 _(fragment_id)                                  \
10816 _(ttl)                                          \
10817 _(protocol)                                     \
10818 _(checksum)
10819
10820 typedef struct
10821 {
10822   u16 src_port, dst_port;
10823 } tcpudp_header_t;
10824
10825 #if VPP_API_TEST_BUILTIN == 0
10826 uword
10827 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10828 {
10829   u8 **maskp = va_arg (*args, u8 **);
10830   u8 *mask = 0;
10831   u8 found_something = 0;
10832   tcp_header_t *tcp;
10833
10834 #define _(a) u8 a=0;
10835   foreach_tcp_proto_field;
10836 #undef _
10837
10838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10839     {
10840       if (0);
10841 #define _(a) else if (unformat (input, #a)) a=1;
10842       foreach_tcp_proto_field
10843 #undef _
10844         else
10845         break;
10846     }
10847
10848 #define _(a) found_something += a;
10849   foreach_tcp_proto_field;
10850 #undef _
10851
10852   if (found_something == 0)
10853     return 0;
10854
10855   vec_validate (mask, sizeof (*tcp) - 1);
10856
10857   tcp = (tcp_header_t *) mask;
10858
10859 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10860   foreach_tcp_proto_field;
10861 #undef _
10862
10863   *maskp = mask;
10864   return 1;
10865 }
10866
10867 uword
10868 unformat_udp_mask (unformat_input_t * input, va_list * args)
10869 {
10870   u8 **maskp = va_arg (*args, u8 **);
10871   u8 *mask = 0;
10872   u8 found_something = 0;
10873   udp_header_t *udp;
10874
10875 #define _(a) u8 a=0;
10876   foreach_udp_proto_field;
10877 #undef _
10878
10879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10880     {
10881       if (0);
10882 #define _(a) else if (unformat (input, #a)) a=1;
10883       foreach_udp_proto_field
10884 #undef _
10885         else
10886         break;
10887     }
10888
10889 #define _(a) found_something += a;
10890   foreach_udp_proto_field;
10891 #undef _
10892
10893   if (found_something == 0)
10894     return 0;
10895
10896   vec_validate (mask, sizeof (*udp) - 1);
10897
10898   udp = (udp_header_t *) mask;
10899
10900 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10901   foreach_udp_proto_field;
10902 #undef _
10903
10904   *maskp = mask;
10905   return 1;
10906 }
10907
10908 uword
10909 unformat_l4_mask (unformat_input_t * input, va_list * args)
10910 {
10911   u8 **maskp = va_arg (*args, u8 **);
10912   u16 src_port = 0, dst_port = 0;
10913   tcpudp_header_t *tcpudp;
10914
10915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10916     {
10917       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10918         return 1;
10919       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10920         return 1;
10921       else if (unformat (input, "src_port"))
10922         src_port = 0xFFFF;
10923       else if (unformat (input, "dst_port"))
10924         dst_port = 0xFFFF;
10925       else
10926         return 0;
10927     }
10928
10929   if (!src_port && !dst_port)
10930     return 0;
10931
10932   u8 *mask = 0;
10933   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10934
10935   tcpudp = (tcpudp_header_t *) mask;
10936   tcpudp->src_port = src_port;
10937   tcpudp->dst_port = dst_port;
10938
10939   *maskp = mask;
10940
10941   return 1;
10942 }
10943
10944 uword
10945 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10946 {
10947   u8 **maskp = va_arg (*args, u8 **);
10948   u8 *mask = 0;
10949   u8 found_something = 0;
10950   ip4_header_t *ip;
10951
10952 #define _(a) u8 a=0;
10953   foreach_ip4_proto_field;
10954 #undef _
10955   u8 version = 0;
10956   u8 hdr_length = 0;
10957
10958
10959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10960     {
10961       if (unformat (input, "version"))
10962         version = 1;
10963       else if (unformat (input, "hdr_length"))
10964         hdr_length = 1;
10965       else if (unformat (input, "src"))
10966         src_address = 1;
10967       else if (unformat (input, "dst"))
10968         dst_address = 1;
10969       else if (unformat (input, "proto"))
10970         protocol = 1;
10971
10972 #define _(a) else if (unformat (input, #a)) a=1;
10973       foreach_ip4_proto_field
10974 #undef _
10975         else
10976         break;
10977     }
10978
10979 #define _(a) found_something += a;
10980   foreach_ip4_proto_field;
10981 #undef _
10982
10983   if (found_something == 0)
10984     return 0;
10985
10986   vec_validate (mask, sizeof (*ip) - 1);
10987
10988   ip = (ip4_header_t *) mask;
10989
10990 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10991   foreach_ip4_proto_field;
10992 #undef _
10993
10994   ip->ip_version_and_header_length = 0;
10995
10996   if (version)
10997     ip->ip_version_and_header_length |= 0xF0;
10998
10999   if (hdr_length)
11000     ip->ip_version_and_header_length |= 0x0F;
11001
11002   *maskp = mask;
11003   return 1;
11004 }
11005
11006 #define foreach_ip6_proto_field                 \
11007 _(src_address)                                  \
11008 _(dst_address)                                  \
11009 _(payload_length)                               \
11010 _(hop_limit)                                    \
11011 _(protocol)
11012
11013 uword
11014 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11015 {
11016   u8 **maskp = va_arg (*args, u8 **);
11017   u8 *mask = 0;
11018   u8 found_something = 0;
11019   ip6_header_t *ip;
11020   u32 ip_version_traffic_class_and_flow_label;
11021
11022 #define _(a) u8 a=0;
11023   foreach_ip6_proto_field;
11024 #undef _
11025   u8 version = 0;
11026   u8 traffic_class = 0;
11027   u8 flow_label = 0;
11028
11029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11030     {
11031       if (unformat (input, "version"))
11032         version = 1;
11033       else if (unformat (input, "traffic-class"))
11034         traffic_class = 1;
11035       else if (unformat (input, "flow-label"))
11036         flow_label = 1;
11037       else if (unformat (input, "src"))
11038         src_address = 1;
11039       else if (unformat (input, "dst"))
11040         dst_address = 1;
11041       else if (unformat (input, "proto"))
11042         protocol = 1;
11043
11044 #define _(a) else if (unformat (input, #a)) a=1;
11045       foreach_ip6_proto_field
11046 #undef _
11047         else
11048         break;
11049     }
11050
11051 #define _(a) found_something += a;
11052   foreach_ip6_proto_field;
11053 #undef _
11054
11055   if (found_something == 0)
11056     return 0;
11057
11058   vec_validate (mask, sizeof (*ip) - 1);
11059
11060   ip = (ip6_header_t *) mask;
11061
11062 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11063   foreach_ip6_proto_field;
11064 #undef _
11065
11066   ip_version_traffic_class_and_flow_label = 0;
11067
11068   if (version)
11069     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11070
11071   if (traffic_class)
11072     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11073
11074   if (flow_label)
11075     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11076
11077   ip->ip_version_traffic_class_and_flow_label =
11078     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11079
11080   *maskp = mask;
11081   return 1;
11082 }
11083
11084 uword
11085 unformat_l3_mask (unformat_input_t * input, va_list * args)
11086 {
11087   u8 **maskp = va_arg (*args, u8 **);
11088
11089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11090     {
11091       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11092         return 1;
11093       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11094         return 1;
11095       else
11096         break;
11097     }
11098   return 0;
11099 }
11100
11101 uword
11102 unformat_l2_mask (unformat_input_t * input, va_list * args)
11103 {
11104   u8 **maskp = va_arg (*args, u8 **);
11105   u8 *mask = 0;
11106   u8 src = 0;
11107   u8 dst = 0;
11108   u8 proto = 0;
11109   u8 tag1 = 0;
11110   u8 tag2 = 0;
11111   u8 ignore_tag1 = 0;
11112   u8 ignore_tag2 = 0;
11113   u8 cos1 = 0;
11114   u8 cos2 = 0;
11115   u8 dot1q = 0;
11116   u8 dot1ad = 0;
11117   int len = 14;
11118
11119   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11120     {
11121       if (unformat (input, "src"))
11122         src = 1;
11123       else if (unformat (input, "dst"))
11124         dst = 1;
11125       else if (unformat (input, "proto"))
11126         proto = 1;
11127       else if (unformat (input, "tag1"))
11128         tag1 = 1;
11129       else if (unformat (input, "tag2"))
11130         tag2 = 1;
11131       else if (unformat (input, "ignore-tag1"))
11132         ignore_tag1 = 1;
11133       else if (unformat (input, "ignore-tag2"))
11134         ignore_tag2 = 1;
11135       else if (unformat (input, "cos1"))
11136         cos1 = 1;
11137       else if (unformat (input, "cos2"))
11138         cos2 = 1;
11139       else if (unformat (input, "dot1q"))
11140         dot1q = 1;
11141       else if (unformat (input, "dot1ad"))
11142         dot1ad = 1;
11143       else
11144         break;
11145     }
11146   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11147        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11148     return 0;
11149
11150   if (tag1 || ignore_tag1 || cos1 || dot1q)
11151     len = 18;
11152   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11153     len = 22;
11154
11155   vec_validate (mask, len - 1);
11156
11157   if (dst)
11158     memset (mask, 0xff, 6);
11159
11160   if (src)
11161     memset (mask + 6, 0xff, 6);
11162
11163   if (tag2 || dot1ad)
11164     {
11165       /* inner vlan tag */
11166       if (tag2)
11167         {
11168           mask[19] = 0xff;
11169           mask[18] = 0x0f;
11170         }
11171       if (cos2)
11172         mask[18] |= 0xe0;
11173       if (proto)
11174         mask[21] = mask[20] = 0xff;
11175       if (tag1)
11176         {
11177           mask[15] = 0xff;
11178           mask[14] = 0x0f;
11179         }
11180       if (cos1)
11181         mask[14] |= 0xe0;
11182       *maskp = mask;
11183       return 1;
11184     }
11185   if (tag1 | dot1q)
11186     {
11187       if (tag1)
11188         {
11189           mask[15] = 0xff;
11190           mask[14] = 0x0f;
11191         }
11192       if (cos1)
11193         mask[14] |= 0xe0;
11194       if (proto)
11195         mask[16] = mask[17] = 0xff;
11196
11197       *maskp = mask;
11198       return 1;
11199     }
11200   if (cos2)
11201     mask[18] |= 0xe0;
11202   if (cos1)
11203     mask[14] |= 0xe0;
11204   if (proto)
11205     mask[12] = mask[13] = 0xff;
11206
11207   *maskp = mask;
11208   return 1;
11209 }
11210
11211 uword
11212 unformat_classify_mask (unformat_input_t * input, va_list * args)
11213 {
11214   u8 **maskp = va_arg (*args, u8 **);
11215   u32 *skipp = va_arg (*args, u32 *);
11216   u32 *matchp = va_arg (*args, u32 *);
11217   u32 match;
11218   u8 *mask = 0;
11219   u8 *l2 = 0;
11220   u8 *l3 = 0;
11221   u8 *l4 = 0;
11222   int i;
11223
11224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11225     {
11226       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11227         ;
11228       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11229         ;
11230       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11231         ;
11232       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11233         ;
11234       else
11235         break;
11236     }
11237
11238   if (l4 && !l3)
11239     {
11240       vec_free (mask);
11241       vec_free (l2);
11242       vec_free (l4);
11243       return 0;
11244     }
11245
11246   if (mask || l2 || l3 || l4)
11247     {
11248       if (l2 || l3 || l4)
11249         {
11250           /* "With a free Ethernet header in every package" */
11251           if (l2 == 0)
11252             vec_validate (l2, 13);
11253           mask = l2;
11254           if (vec_len (l3))
11255             {
11256               vec_append (mask, l3);
11257               vec_free (l3);
11258             }
11259           if (vec_len (l4))
11260             {
11261               vec_append (mask, l4);
11262               vec_free (l4);
11263             }
11264         }
11265
11266       /* Scan forward looking for the first significant mask octet */
11267       for (i = 0; i < vec_len (mask); i++)
11268         if (mask[i])
11269           break;
11270
11271       /* compute (skip, match) params */
11272       *skipp = i / sizeof (u32x4);
11273       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11274
11275       /* Pad mask to an even multiple of the vector size */
11276       while (vec_len (mask) % sizeof (u32x4))
11277         vec_add1 (mask, 0);
11278
11279       match = vec_len (mask) / sizeof (u32x4);
11280
11281       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11282         {
11283           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11284           if (*tmp || *(tmp + 1))
11285             break;
11286           match--;
11287         }
11288       if (match == 0)
11289         clib_warning ("BUG: match 0");
11290
11291       _vec_len (mask) = match * sizeof (u32x4);
11292
11293       *matchp = match;
11294       *maskp = mask;
11295
11296       return 1;
11297     }
11298
11299   return 0;
11300 }
11301 #endif /* VPP_API_TEST_BUILTIN */
11302
11303 #define foreach_l2_next                         \
11304 _(drop, DROP)                                   \
11305 _(ethernet, ETHERNET_INPUT)                     \
11306 _(ip4, IP4_INPUT)                               \
11307 _(ip6, IP6_INPUT)
11308
11309 uword
11310 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11311 {
11312   u32 *miss_next_indexp = va_arg (*args, u32 *);
11313   u32 next_index = 0;
11314   u32 tmp;
11315
11316 #define _(n,N) \
11317   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11318   foreach_l2_next;
11319 #undef _
11320
11321   if (unformat (input, "%d", &tmp))
11322     {
11323       next_index = tmp;
11324       goto out;
11325     }
11326
11327   return 0;
11328
11329 out:
11330   *miss_next_indexp = next_index;
11331   return 1;
11332 }
11333
11334 #define foreach_ip_next                         \
11335 _(drop, DROP)                                   \
11336 _(local, LOCAL)                                 \
11337 _(rewrite, REWRITE)
11338
11339 uword
11340 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11341 {
11342   u32 *miss_next_indexp = va_arg (*args, u32 *);
11343   u32 next_index = 0;
11344   u32 tmp;
11345
11346 #define _(n,N) \
11347   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11348   foreach_ip_next;
11349 #undef _
11350
11351   if (unformat (input, "%d", &tmp))
11352     {
11353       next_index = tmp;
11354       goto out;
11355     }
11356
11357   return 0;
11358
11359 out:
11360   *miss_next_indexp = next_index;
11361   return 1;
11362 }
11363
11364 #define foreach_acl_next                        \
11365 _(deny, DENY)
11366
11367 uword
11368 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11369 {
11370   u32 *miss_next_indexp = va_arg (*args, u32 *);
11371   u32 next_index = 0;
11372   u32 tmp;
11373
11374 #define _(n,N) \
11375   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11376   foreach_acl_next;
11377 #undef _
11378
11379   if (unformat (input, "permit"))
11380     {
11381       next_index = ~0;
11382       goto out;
11383     }
11384   else if (unformat (input, "%d", &tmp))
11385     {
11386       next_index = tmp;
11387       goto out;
11388     }
11389
11390   return 0;
11391
11392 out:
11393   *miss_next_indexp = next_index;
11394   return 1;
11395 }
11396
11397 uword
11398 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11399 {
11400   u32 *r = va_arg (*args, u32 *);
11401
11402   if (unformat (input, "conform-color"))
11403     *r = POLICE_CONFORM;
11404   else if (unformat (input, "exceed-color"))
11405     *r = POLICE_EXCEED;
11406   else
11407     return 0;
11408
11409   return 1;
11410 }
11411
11412 static int
11413 api_classify_add_del_table (vat_main_t * vam)
11414 {
11415   unformat_input_t *i = vam->input;
11416   vl_api_classify_add_del_table_t *mp;
11417
11418   u32 nbuckets = 2;
11419   u32 skip = ~0;
11420   u32 match = ~0;
11421   int is_add = 1;
11422   int del_chain = 0;
11423   u32 table_index = ~0;
11424   u32 next_table_index = ~0;
11425   u32 miss_next_index = ~0;
11426   u32 memory_size = 32 << 20;
11427   u8 *mask = 0;
11428   u32 current_data_flag = 0;
11429   int current_data_offset = 0;
11430   int ret;
11431
11432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11433     {
11434       if (unformat (i, "del"))
11435         is_add = 0;
11436       else if (unformat (i, "del-chain"))
11437         {
11438           is_add = 0;
11439           del_chain = 1;
11440         }
11441       else if (unformat (i, "buckets %d", &nbuckets))
11442         ;
11443       else if (unformat (i, "memory_size %d", &memory_size))
11444         ;
11445       else if (unformat (i, "skip %d", &skip))
11446         ;
11447       else if (unformat (i, "match %d", &match))
11448         ;
11449       else if (unformat (i, "table %d", &table_index))
11450         ;
11451       else if (unformat (i, "mask %U", unformat_classify_mask,
11452                          &mask, &skip, &match))
11453         ;
11454       else if (unformat (i, "next-table %d", &next_table_index))
11455         ;
11456       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11457                          &miss_next_index))
11458         ;
11459       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11460                          &miss_next_index))
11461         ;
11462       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11463                          &miss_next_index))
11464         ;
11465       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11466         ;
11467       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11468         ;
11469       else
11470         break;
11471     }
11472
11473   if (is_add && mask == 0)
11474     {
11475       errmsg ("Mask required");
11476       return -99;
11477     }
11478
11479   if (is_add && skip == ~0)
11480     {
11481       errmsg ("skip count required");
11482       return -99;
11483     }
11484
11485   if (is_add && match == ~0)
11486     {
11487       errmsg ("match count required");
11488       return -99;
11489     }
11490
11491   if (!is_add && table_index == ~0)
11492     {
11493       errmsg ("table index required for delete");
11494       return -99;
11495     }
11496
11497   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11498
11499   mp->is_add = is_add;
11500   mp->del_chain = del_chain;
11501   mp->table_index = ntohl (table_index);
11502   mp->nbuckets = ntohl (nbuckets);
11503   mp->memory_size = ntohl (memory_size);
11504   mp->skip_n_vectors = ntohl (skip);
11505   mp->match_n_vectors = ntohl (match);
11506   mp->next_table_index = ntohl (next_table_index);
11507   mp->miss_next_index = ntohl (miss_next_index);
11508   mp->current_data_flag = ntohl (current_data_flag);
11509   mp->current_data_offset = ntohl (current_data_offset);
11510   clib_memcpy (mp->mask, mask, vec_len (mask));
11511
11512   vec_free (mask);
11513
11514   S (mp);
11515   W (ret);
11516   return ret;
11517 }
11518
11519 #if VPP_API_TEST_BUILTIN == 0
11520 uword
11521 unformat_l4_match (unformat_input_t * input, va_list * args)
11522 {
11523   u8 **matchp = va_arg (*args, u8 **);
11524
11525   u8 *proto_header = 0;
11526   int src_port = 0;
11527   int dst_port = 0;
11528
11529   tcpudp_header_t h;
11530
11531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11532     {
11533       if (unformat (input, "src_port %d", &src_port))
11534         ;
11535       else if (unformat (input, "dst_port %d", &dst_port))
11536         ;
11537       else
11538         return 0;
11539     }
11540
11541   h.src_port = clib_host_to_net_u16 (src_port);
11542   h.dst_port = clib_host_to_net_u16 (dst_port);
11543   vec_validate (proto_header, sizeof (h) - 1);
11544   memcpy (proto_header, &h, sizeof (h));
11545
11546   *matchp = proto_header;
11547
11548   return 1;
11549 }
11550
11551 uword
11552 unformat_ip4_match (unformat_input_t * input, va_list * args)
11553 {
11554   u8 **matchp = va_arg (*args, u8 **);
11555   u8 *match = 0;
11556   ip4_header_t *ip;
11557   int version = 0;
11558   u32 version_val;
11559   int hdr_length = 0;
11560   u32 hdr_length_val;
11561   int src = 0, dst = 0;
11562   ip4_address_t src_val, dst_val;
11563   int proto = 0;
11564   u32 proto_val;
11565   int tos = 0;
11566   u32 tos_val;
11567   int length = 0;
11568   u32 length_val;
11569   int fragment_id = 0;
11570   u32 fragment_id_val;
11571   int ttl = 0;
11572   int ttl_val;
11573   int checksum = 0;
11574   u32 checksum_val;
11575
11576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11577     {
11578       if (unformat (input, "version %d", &version_val))
11579         version = 1;
11580       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11581         hdr_length = 1;
11582       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11583         src = 1;
11584       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11585         dst = 1;
11586       else if (unformat (input, "proto %d", &proto_val))
11587         proto = 1;
11588       else if (unformat (input, "tos %d", &tos_val))
11589         tos = 1;
11590       else if (unformat (input, "length %d", &length_val))
11591         length = 1;
11592       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11593         fragment_id = 1;
11594       else if (unformat (input, "ttl %d", &ttl_val))
11595         ttl = 1;
11596       else if (unformat (input, "checksum %d", &checksum_val))
11597         checksum = 1;
11598       else
11599         break;
11600     }
11601
11602   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11603       + ttl + checksum == 0)
11604     return 0;
11605
11606   /*
11607    * Aligned because we use the real comparison functions
11608    */
11609   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11610
11611   ip = (ip4_header_t *) match;
11612
11613   /* These are realistically matched in practice */
11614   if (src)
11615     ip->src_address.as_u32 = src_val.as_u32;
11616
11617   if (dst)
11618     ip->dst_address.as_u32 = dst_val.as_u32;
11619
11620   if (proto)
11621     ip->protocol = proto_val;
11622
11623
11624   /* These are not, but they're included for completeness */
11625   if (version)
11626     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11627
11628   if (hdr_length)
11629     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11630
11631   if (tos)
11632     ip->tos = tos_val;
11633
11634   if (length)
11635     ip->length = clib_host_to_net_u16 (length_val);
11636
11637   if (ttl)
11638     ip->ttl = ttl_val;
11639
11640   if (checksum)
11641     ip->checksum = clib_host_to_net_u16 (checksum_val);
11642
11643   *matchp = match;
11644   return 1;
11645 }
11646
11647 uword
11648 unformat_ip6_match (unformat_input_t * input, va_list * args)
11649 {
11650   u8 **matchp = va_arg (*args, u8 **);
11651   u8 *match = 0;
11652   ip6_header_t *ip;
11653   int version = 0;
11654   u32 version_val;
11655   u8 traffic_class = 0;
11656   u32 traffic_class_val = 0;
11657   u8 flow_label = 0;
11658   u8 flow_label_val;
11659   int src = 0, dst = 0;
11660   ip6_address_t src_val, dst_val;
11661   int proto = 0;
11662   u32 proto_val;
11663   int payload_length = 0;
11664   u32 payload_length_val;
11665   int hop_limit = 0;
11666   int hop_limit_val;
11667   u32 ip_version_traffic_class_and_flow_label;
11668
11669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11670     {
11671       if (unformat (input, "version %d", &version_val))
11672         version = 1;
11673       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11674         traffic_class = 1;
11675       else if (unformat (input, "flow_label %d", &flow_label_val))
11676         flow_label = 1;
11677       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11678         src = 1;
11679       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11680         dst = 1;
11681       else if (unformat (input, "proto %d", &proto_val))
11682         proto = 1;
11683       else if (unformat (input, "payload_length %d", &payload_length_val))
11684         payload_length = 1;
11685       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11686         hop_limit = 1;
11687       else
11688         break;
11689     }
11690
11691   if (version + traffic_class + flow_label + src + dst + proto +
11692       payload_length + hop_limit == 0)
11693     return 0;
11694
11695   /*
11696    * Aligned because we use the real comparison functions
11697    */
11698   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11699
11700   ip = (ip6_header_t *) match;
11701
11702   if (src)
11703     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11704
11705   if (dst)
11706     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11707
11708   if (proto)
11709     ip->protocol = proto_val;
11710
11711   ip_version_traffic_class_and_flow_label = 0;
11712
11713   if (version)
11714     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11715
11716   if (traffic_class)
11717     ip_version_traffic_class_and_flow_label |=
11718       (traffic_class_val & 0xFF) << 20;
11719
11720   if (flow_label)
11721     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11722
11723   ip->ip_version_traffic_class_and_flow_label =
11724     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11725
11726   if (payload_length)
11727     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11728
11729   if (hop_limit)
11730     ip->hop_limit = hop_limit_val;
11731
11732   *matchp = match;
11733   return 1;
11734 }
11735
11736 uword
11737 unformat_l3_match (unformat_input_t * input, va_list * args)
11738 {
11739   u8 **matchp = va_arg (*args, u8 **);
11740
11741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11742     {
11743       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11744         return 1;
11745       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11746         return 1;
11747       else
11748         break;
11749     }
11750   return 0;
11751 }
11752
11753 uword
11754 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11755 {
11756   u8 *tagp = va_arg (*args, u8 *);
11757   u32 tag;
11758
11759   if (unformat (input, "%d", &tag))
11760     {
11761       tagp[0] = (tag >> 8) & 0x0F;
11762       tagp[1] = tag & 0xFF;
11763       return 1;
11764     }
11765
11766   return 0;
11767 }
11768
11769 uword
11770 unformat_l2_match (unformat_input_t * input, va_list * args)
11771 {
11772   u8 **matchp = va_arg (*args, u8 **);
11773   u8 *match = 0;
11774   u8 src = 0;
11775   u8 src_val[6];
11776   u8 dst = 0;
11777   u8 dst_val[6];
11778   u8 proto = 0;
11779   u16 proto_val;
11780   u8 tag1 = 0;
11781   u8 tag1_val[2];
11782   u8 tag2 = 0;
11783   u8 tag2_val[2];
11784   int len = 14;
11785   u8 ignore_tag1 = 0;
11786   u8 ignore_tag2 = 0;
11787   u8 cos1 = 0;
11788   u8 cos2 = 0;
11789   u32 cos1_val = 0;
11790   u32 cos2_val = 0;
11791
11792   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11793     {
11794       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11795         src = 1;
11796       else
11797         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11798         dst = 1;
11799       else if (unformat (input, "proto %U",
11800                          unformat_ethernet_type_host_byte_order, &proto_val))
11801         proto = 1;
11802       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11803         tag1 = 1;
11804       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11805         tag2 = 1;
11806       else if (unformat (input, "ignore-tag1"))
11807         ignore_tag1 = 1;
11808       else if (unformat (input, "ignore-tag2"))
11809         ignore_tag2 = 1;
11810       else if (unformat (input, "cos1 %d", &cos1_val))
11811         cos1 = 1;
11812       else if (unformat (input, "cos2 %d", &cos2_val))
11813         cos2 = 1;
11814       else
11815         break;
11816     }
11817   if ((src + dst + proto + tag1 + tag2 +
11818        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11819     return 0;
11820
11821   if (tag1 || ignore_tag1 || cos1)
11822     len = 18;
11823   if (tag2 || ignore_tag2 || cos2)
11824     len = 22;
11825
11826   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11827
11828   if (dst)
11829     clib_memcpy (match, dst_val, 6);
11830
11831   if (src)
11832     clib_memcpy (match + 6, src_val, 6);
11833
11834   if (tag2)
11835     {
11836       /* inner vlan tag */
11837       match[19] = tag2_val[1];
11838       match[18] = tag2_val[0];
11839       if (cos2)
11840         match[18] |= (cos2_val & 0x7) << 5;
11841       if (proto)
11842         {
11843           match[21] = proto_val & 0xff;
11844           match[20] = proto_val >> 8;
11845         }
11846       if (tag1)
11847         {
11848           match[15] = tag1_val[1];
11849           match[14] = tag1_val[0];
11850         }
11851       if (cos1)
11852         match[14] |= (cos1_val & 0x7) << 5;
11853       *matchp = match;
11854       return 1;
11855     }
11856   if (tag1)
11857     {
11858       match[15] = tag1_val[1];
11859       match[14] = tag1_val[0];
11860       if (proto)
11861         {
11862           match[17] = proto_val & 0xff;
11863           match[16] = proto_val >> 8;
11864         }
11865       if (cos1)
11866         match[14] |= (cos1_val & 0x7) << 5;
11867
11868       *matchp = match;
11869       return 1;
11870     }
11871   if (cos2)
11872     match[18] |= (cos2_val & 0x7) << 5;
11873   if (cos1)
11874     match[14] |= (cos1_val & 0x7) << 5;
11875   if (proto)
11876     {
11877       match[13] = proto_val & 0xff;
11878       match[12] = proto_val >> 8;
11879     }
11880
11881   *matchp = match;
11882   return 1;
11883 }
11884
11885 uword
11886 unformat_qos_source (unformat_input_t * input, va_list * args)
11887 {
11888   int *qs = va_arg (*args, int *);
11889
11890   if (unformat (input, "ip"))
11891     *qs = QOS_SOURCE_IP;
11892   else if (unformat (input, "mpls"))
11893     *qs = QOS_SOURCE_MPLS;
11894   else if (unformat (input, "ext"))
11895     *qs = QOS_SOURCE_EXT;
11896   else if (unformat (input, "vlan"))
11897     *qs = QOS_SOURCE_VLAN;
11898   else
11899     return 0;
11900
11901   return 1;
11902 }
11903 #endif
11904
11905 uword
11906 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11907 {
11908   u8 **matchp = va_arg (*args, u8 **);
11909   u32 skip_n_vectors = va_arg (*args, u32);
11910   u32 match_n_vectors = va_arg (*args, u32);
11911
11912   u8 *match = 0;
11913   u8 *l2 = 0;
11914   u8 *l3 = 0;
11915   u8 *l4 = 0;
11916
11917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11918     {
11919       if (unformat (input, "hex %U", unformat_hex_string, &match))
11920         ;
11921       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11922         ;
11923       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11924         ;
11925       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11926         ;
11927       else
11928         break;
11929     }
11930
11931   if (l4 && !l3)
11932     {
11933       vec_free (match);
11934       vec_free (l2);
11935       vec_free (l4);
11936       return 0;
11937     }
11938
11939   if (match || l2 || l3 || l4)
11940     {
11941       if (l2 || l3 || l4)
11942         {
11943           /* "Win a free Ethernet header in every packet" */
11944           if (l2 == 0)
11945             vec_validate_aligned (l2, 13, sizeof (u32x4));
11946           match = l2;
11947           if (vec_len (l3))
11948             {
11949               vec_append_aligned (match, l3, sizeof (u32x4));
11950               vec_free (l3);
11951             }
11952           if (vec_len (l4))
11953             {
11954               vec_append_aligned (match, l4, sizeof (u32x4));
11955               vec_free (l4);
11956             }
11957         }
11958
11959       /* Make sure the vector is big enough even if key is all 0's */
11960       vec_validate_aligned
11961         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11962          sizeof (u32x4));
11963
11964       /* Set size, include skipped vectors */
11965       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11966
11967       *matchp = match;
11968
11969       return 1;
11970     }
11971
11972   return 0;
11973 }
11974
11975 static int
11976 api_classify_add_del_session (vat_main_t * vam)
11977 {
11978   unformat_input_t *i = vam->input;
11979   vl_api_classify_add_del_session_t *mp;
11980   int is_add = 1;
11981   u32 table_index = ~0;
11982   u32 hit_next_index = ~0;
11983   u32 opaque_index = ~0;
11984   u8 *match = 0;
11985   i32 advance = 0;
11986   u32 skip_n_vectors = 0;
11987   u32 match_n_vectors = 0;
11988   u32 action = 0;
11989   u32 metadata = 0;
11990   int ret;
11991
11992   /*
11993    * Warning: you have to supply skip_n and match_n
11994    * because the API client cant simply look at the classify
11995    * table object.
11996    */
11997
11998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11999     {
12000       if (unformat (i, "del"))
12001         is_add = 0;
12002       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12003                          &hit_next_index))
12004         ;
12005       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12006                          &hit_next_index))
12007         ;
12008       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12009                          &hit_next_index))
12010         ;
12011       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12012         ;
12013       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12014         ;
12015       else if (unformat (i, "opaque-index %d", &opaque_index))
12016         ;
12017       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12018         ;
12019       else if (unformat (i, "match_n %d", &match_n_vectors))
12020         ;
12021       else if (unformat (i, "match %U", api_unformat_classify_match,
12022                          &match, skip_n_vectors, match_n_vectors))
12023         ;
12024       else if (unformat (i, "advance %d", &advance))
12025         ;
12026       else if (unformat (i, "table-index %d", &table_index))
12027         ;
12028       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12029         action = 1;
12030       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12031         action = 2;
12032       else if (unformat (i, "action %d", &action))
12033         ;
12034       else if (unformat (i, "metadata %d", &metadata))
12035         ;
12036       else
12037         break;
12038     }
12039
12040   if (table_index == ~0)
12041     {
12042       errmsg ("Table index required");
12043       return -99;
12044     }
12045
12046   if (is_add && match == 0)
12047     {
12048       errmsg ("Match value required");
12049       return -99;
12050     }
12051
12052   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12053
12054   mp->is_add = is_add;
12055   mp->table_index = ntohl (table_index);
12056   mp->hit_next_index = ntohl (hit_next_index);
12057   mp->opaque_index = ntohl (opaque_index);
12058   mp->advance = ntohl (advance);
12059   mp->action = action;
12060   mp->metadata = ntohl (metadata);
12061   clib_memcpy (mp->match, match, vec_len (match));
12062   vec_free (match);
12063
12064   S (mp);
12065   W (ret);
12066   return ret;
12067 }
12068
12069 static int
12070 api_classify_set_interface_ip_table (vat_main_t * vam)
12071 {
12072   unformat_input_t *i = vam->input;
12073   vl_api_classify_set_interface_ip_table_t *mp;
12074   u32 sw_if_index;
12075   int sw_if_index_set;
12076   u32 table_index = ~0;
12077   u8 is_ipv6 = 0;
12078   int ret;
12079
12080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12081     {
12082       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12083         sw_if_index_set = 1;
12084       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12085         sw_if_index_set = 1;
12086       else if (unformat (i, "table %d", &table_index))
12087         ;
12088       else
12089         {
12090           clib_warning ("parse error '%U'", format_unformat_error, i);
12091           return -99;
12092         }
12093     }
12094
12095   if (sw_if_index_set == 0)
12096     {
12097       errmsg ("missing interface name or sw_if_index");
12098       return -99;
12099     }
12100
12101
12102   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12103
12104   mp->sw_if_index = ntohl (sw_if_index);
12105   mp->table_index = ntohl (table_index);
12106   mp->is_ipv6 = is_ipv6;
12107
12108   S (mp);
12109   W (ret);
12110   return ret;
12111 }
12112
12113 static int
12114 api_classify_set_interface_l2_tables (vat_main_t * vam)
12115 {
12116   unformat_input_t *i = vam->input;
12117   vl_api_classify_set_interface_l2_tables_t *mp;
12118   u32 sw_if_index;
12119   int sw_if_index_set;
12120   u32 ip4_table_index = ~0;
12121   u32 ip6_table_index = ~0;
12122   u32 other_table_index = ~0;
12123   u32 is_input = 1;
12124   int ret;
12125
12126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12127     {
12128       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12129         sw_if_index_set = 1;
12130       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12131         sw_if_index_set = 1;
12132       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12133         ;
12134       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12135         ;
12136       else if (unformat (i, "other-table %d", &other_table_index))
12137         ;
12138       else if (unformat (i, "is-input %d", &is_input))
12139         ;
12140       else
12141         {
12142           clib_warning ("parse error '%U'", format_unformat_error, i);
12143           return -99;
12144         }
12145     }
12146
12147   if (sw_if_index_set == 0)
12148     {
12149       errmsg ("missing interface name or sw_if_index");
12150       return -99;
12151     }
12152
12153
12154   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12155
12156   mp->sw_if_index = ntohl (sw_if_index);
12157   mp->ip4_table_index = ntohl (ip4_table_index);
12158   mp->ip6_table_index = ntohl (ip6_table_index);
12159   mp->other_table_index = ntohl (other_table_index);
12160   mp->is_input = (u8) is_input;
12161
12162   S (mp);
12163   W (ret);
12164   return ret;
12165 }
12166
12167 static int
12168 api_set_ipfix_exporter (vat_main_t * vam)
12169 {
12170   unformat_input_t *i = vam->input;
12171   vl_api_set_ipfix_exporter_t *mp;
12172   ip4_address_t collector_address;
12173   u8 collector_address_set = 0;
12174   u32 collector_port = ~0;
12175   ip4_address_t src_address;
12176   u8 src_address_set = 0;
12177   u32 vrf_id = ~0;
12178   u32 path_mtu = ~0;
12179   u32 template_interval = ~0;
12180   u8 udp_checksum = 0;
12181   int ret;
12182
12183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12184     {
12185       if (unformat (i, "collector_address %U", unformat_ip4_address,
12186                     &collector_address))
12187         collector_address_set = 1;
12188       else if (unformat (i, "collector_port %d", &collector_port))
12189         ;
12190       else if (unformat (i, "src_address %U", unformat_ip4_address,
12191                          &src_address))
12192         src_address_set = 1;
12193       else if (unformat (i, "vrf_id %d", &vrf_id))
12194         ;
12195       else if (unformat (i, "path_mtu %d", &path_mtu))
12196         ;
12197       else if (unformat (i, "template_interval %d", &template_interval))
12198         ;
12199       else if (unformat (i, "udp_checksum"))
12200         udp_checksum = 1;
12201       else
12202         break;
12203     }
12204
12205   if (collector_address_set == 0)
12206     {
12207       errmsg ("collector_address required");
12208       return -99;
12209     }
12210
12211   if (src_address_set == 0)
12212     {
12213       errmsg ("src_address required");
12214       return -99;
12215     }
12216
12217   M (SET_IPFIX_EXPORTER, mp);
12218
12219   memcpy (mp->collector_address, collector_address.data,
12220           sizeof (collector_address.data));
12221   mp->collector_port = htons ((u16) collector_port);
12222   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12223   mp->vrf_id = htonl (vrf_id);
12224   mp->path_mtu = htonl (path_mtu);
12225   mp->template_interval = htonl (template_interval);
12226   mp->udp_checksum = udp_checksum;
12227
12228   S (mp);
12229   W (ret);
12230   return ret;
12231 }
12232
12233 static int
12234 api_set_ipfix_classify_stream (vat_main_t * vam)
12235 {
12236   unformat_input_t *i = vam->input;
12237   vl_api_set_ipfix_classify_stream_t *mp;
12238   u32 domain_id = 0;
12239   u32 src_port = UDP_DST_PORT_ipfix;
12240   int ret;
12241
12242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12243     {
12244       if (unformat (i, "domain %d", &domain_id))
12245         ;
12246       else if (unformat (i, "src_port %d", &src_port))
12247         ;
12248       else
12249         {
12250           errmsg ("unknown input `%U'", format_unformat_error, i);
12251           return -99;
12252         }
12253     }
12254
12255   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12256
12257   mp->domain_id = htonl (domain_id);
12258   mp->src_port = htons ((u16) src_port);
12259
12260   S (mp);
12261   W (ret);
12262   return ret;
12263 }
12264
12265 static int
12266 api_ipfix_classify_table_add_del (vat_main_t * vam)
12267 {
12268   unformat_input_t *i = vam->input;
12269   vl_api_ipfix_classify_table_add_del_t *mp;
12270   int is_add = -1;
12271   u32 classify_table_index = ~0;
12272   u8 ip_version = 0;
12273   u8 transport_protocol = 255;
12274   int ret;
12275
12276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12277     {
12278       if (unformat (i, "add"))
12279         is_add = 1;
12280       else if (unformat (i, "del"))
12281         is_add = 0;
12282       else if (unformat (i, "table %d", &classify_table_index))
12283         ;
12284       else if (unformat (i, "ip4"))
12285         ip_version = 4;
12286       else if (unformat (i, "ip6"))
12287         ip_version = 6;
12288       else if (unformat (i, "tcp"))
12289         transport_protocol = 6;
12290       else if (unformat (i, "udp"))
12291         transport_protocol = 17;
12292       else
12293         {
12294           errmsg ("unknown input `%U'", format_unformat_error, i);
12295           return -99;
12296         }
12297     }
12298
12299   if (is_add == -1)
12300     {
12301       errmsg ("expecting: add|del");
12302       return -99;
12303     }
12304   if (classify_table_index == ~0)
12305     {
12306       errmsg ("classifier table not specified");
12307       return -99;
12308     }
12309   if (ip_version == 0)
12310     {
12311       errmsg ("IP version not specified");
12312       return -99;
12313     }
12314
12315   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12316
12317   mp->is_add = is_add;
12318   mp->table_id = htonl (classify_table_index);
12319   mp->ip_version = ip_version;
12320   mp->transport_protocol = transport_protocol;
12321
12322   S (mp);
12323   W (ret);
12324   return ret;
12325 }
12326
12327 static int
12328 api_get_node_index (vat_main_t * vam)
12329 {
12330   unformat_input_t *i = vam->input;
12331   vl_api_get_node_index_t *mp;
12332   u8 *name = 0;
12333   int ret;
12334
12335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12336     {
12337       if (unformat (i, "node %s", &name))
12338         ;
12339       else
12340         break;
12341     }
12342   if (name == 0)
12343     {
12344       errmsg ("node name required");
12345       return -99;
12346     }
12347   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12348     {
12349       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12350       return -99;
12351     }
12352
12353   M (GET_NODE_INDEX, mp);
12354   clib_memcpy (mp->node_name, name, vec_len (name));
12355   vec_free (name);
12356
12357   S (mp);
12358   W (ret);
12359   return ret;
12360 }
12361
12362 static int
12363 api_get_next_index (vat_main_t * vam)
12364 {
12365   unformat_input_t *i = vam->input;
12366   vl_api_get_next_index_t *mp;
12367   u8 *node_name = 0, *next_node_name = 0;
12368   int ret;
12369
12370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12371     {
12372       if (unformat (i, "node-name %s", &node_name))
12373         ;
12374       else if (unformat (i, "next-node-name %s", &next_node_name))
12375         break;
12376     }
12377
12378   if (node_name == 0)
12379     {
12380       errmsg ("node name required");
12381       return -99;
12382     }
12383   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12384     {
12385       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12386       return -99;
12387     }
12388
12389   if (next_node_name == 0)
12390     {
12391       errmsg ("next node name required");
12392       return -99;
12393     }
12394   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12395     {
12396       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12397       return -99;
12398     }
12399
12400   M (GET_NEXT_INDEX, mp);
12401   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12402   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12403   vec_free (node_name);
12404   vec_free (next_node_name);
12405
12406   S (mp);
12407   W (ret);
12408   return ret;
12409 }
12410
12411 static int
12412 api_add_node_next (vat_main_t * vam)
12413 {
12414   unformat_input_t *i = vam->input;
12415   vl_api_add_node_next_t *mp;
12416   u8 *name = 0;
12417   u8 *next = 0;
12418   int ret;
12419
12420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12421     {
12422       if (unformat (i, "node %s", &name))
12423         ;
12424       else if (unformat (i, "next %s", &next))
12425         ;
12426       else
12427         break;
12428     }
12429   if (name == 0)
12430     {
12431       errmsg ("node name required");
12432       return -99;
12433     }
12434   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12435     {
12436       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12437       return -99;
12438     }
12439   if (next == 0)
12440     {
12441       errmsg ("next node required");
12442       return -99;
12443     }
12444   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12445     {
12446       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12447       return -99;
12448     }
12449
12450   M (ADD_NODE_NEXT, mp);
12451   clib_memcpy (mp->node_name, name, vec_len (name));
12452   clib_memcpy (mp->next_name, next, vec_len (next));
12453   vec_free (name);
12454   vec_free (next);
12455
12456   S (mp);
12457   W (ret);
12458   return ret;
12459 }
12460
12461 static int
12462 api_l2tpv3_create_tunnel (vat_main_t * vam)
12463 {
12464   unformat_input_t *i = vam->input;
12465   ip6_address_t client_address, our_address;
12466   int client_address_set = 0;
12467   int our_address_set = 0;
12468   u32 local_session_id = 0;
12469   u32 remote_session_id = 0;
12470   u64 local_cookie = 0;
12471   u64 remote_cookie = 0;
12472   u8 l2_sublayer_present = 0;
12473   vl_api_l2tpv3_create_tunnel_t *mp;
12474   int ret;
12475
12476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12477     {
12478       if (unformat (i, "client_address %U", unformat_ip6_address,
12479                     &client_address))
12480         client_address_set = 1;
12481       else if (unformat (i, "our_address %U", unformat_ip6_address,
12482                          &our_address))
12483         our_address_set = 1;
12484       else if (unformat (i, "local_session_id %d", &local_session_id))
12485         ;
12486       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12487         ;
12488       else if (unformat (i, "local_cookie %lld", &local_cookie))
12489         ;
12490       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12491         ;
12492       else if (unformat (i, "l2-sublayer-present"))
12493         l2_sublayer_present = 1;
12494       else
12495         break;
12496     }
12497
12498   if (client_address_set == 0)
12499     {
12500       errmsg ("client_address required");
12501       return -99;
12502     }
12503
12504   if (our_address_set == 0)
12505     {
12506       errmsg ("our_address required");
12507       return -99;
12508     }
12509
12510   M (L2TPV3_CREATE_TUNNEL, mp);
12511
12512   clib_memcpy (mp->client_address, client_address.as_u8,
12513                sizeof (mp->client_address));
12514
12515   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12516
12517   mp->local_session_id = ntohl (local_session_id);
12518   mp->remote_session_id = ntohl (remote_session_id);
12519   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12520   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12521   mp->l2_sublayer_present = l2_sublayer_present;
12522   mp->is_ipv6 = 1;
12523
12524   S (mp);
12525   W (ret);
12526   return ret;
12527 }
12528
12529 static int
12530 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12531 {
12532   unformat_input_t *i = vam->input;
12533   u32 sw_if_index;
12534   u8 sw_if_index_set = 0;
12535   u64 new_local_cookie = 0;
12536   u64 new_remote_cookie = 0;
12537   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12538   int ret;
12539
12540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12541     {
12542       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12543         sw_if_index_set = 1;
12544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12545         sw_if_index_set = 1;
12546       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12547         ;
12548       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12549         ;
12550       else
12551         break;
12552     }
12553
12554   if (sw_if_index_set == 0)
12555     {
12556       errmsg ("missing interface name or sw_if_index");
12557       return -99;
12558     }
12559
12560   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12561
12562   mp->sw_if_index = ntohl (sw_if_index);
12563   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12564   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12565
12566   S (mp);
12567   W (ret);
12568   return ret;
12569 }
12570
12571 static int
12572 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12573 {
12574   unformat_input_t *i = vam->input;
12575   vl_api_l2tpv3_interface_enable_disable_t *mp;
12576   u32 sw_if_index;
12577   u8 sw_if_index_set = 0;
12578   u8 enable_disable = 1;
12579   int ret;
12580
12581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12582     {
12583       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12584         sw_if_index_set = 1;
12585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12586         sw_if_index_set = 1;
12587       else if (unformat (i, "enable"))
12588         enable_disable = 1;
12589       else if (unformat (i, "disable"))
12590         enable_disable = 0;
12591       else
12592         break;
12593     }
12594
12595   if (sw_if_index_set == 0)
12596     {
12597       errmsg ("missing interface name or sw_if_index");
12598       return -99;
12599     }
12600
12601   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12602
12603   mp->sw_if_index = ntohl (sw_if_index);
12604   mp->enable_disable = enable_disable;
12605
12606   S (mp);
12607   W (ret);
12608   return ret;
12609 }
12610
12611 static int
12612 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12613 {
12614   unformat_input_t *i = vam->input;
12615   vl_api_l2tpv3_set_lookup_key_t *mp;
12616   u8 key = ~0;
12617   int ret;
12618
12619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12620     {
12621       if (unformat (i, "lookup_v6_src"))
12622         key = L2T_LOOKUP_SRC_ADDRESS;
12623       else if (unformat (i, "lookup_v6_dst"))
12624         key = L2T_LOOKUP_DST_ADDRESS;
12625       else if (unformat (i, "lookup_session_id"))
12626         key = L2T_LOOKUP_SESSION_ID;
12627       else
12628         break;
12629     }
12630
12631   if (key == (u8) ~ 0)
12632     {
12633       errmsg ("l2tp session lookup key unset");
12634       return -99;
12635     }
12636
12637   M (L2TPV3_SET_LOOKUP_KEY, mp);
12638
12639   mp->key = key;
12640
12641   S (mp);
12642   W (ret);
12643   return ret;
12644 }
12645
12646 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12647   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12648 {
12649   vat_main_t *vam = &vat_main;
12650
12651   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12652          format_ip6_address, mp->our_address,
12653          format_ip6_address, mp->client_address,
12654          clib_net_to_host_u32 (mp->sw_if_index));
12655
12656   print (vam->ofp,
12657          "   local cookies %016llx %016llx remote cookie %016llx",
12658          clib_net_to_host_u64 (mp->local_cookie[0]),
12659          clib_net_to_host_u64 (mp->local_cookie[1]),
12660          clib_net_to_host_u64 (mp->remote_cookie));
12661
12662   print (vam->ofp, "   local session-id %d remote session-id %d",
12663          clib_net_to_host_u32 (mp->local_session_id),
12664          clib_net_to_host_u32 (mp->remote_session_id));
12665
12666   print (vam->ofp, "   l2 specific sublayer %s\n",
12667          mp->l2_sublayer_present ? "preset" : "absent");
12668
12669 }
12670
12671 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12672   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12673 {
12674   vat_main_t *vam = &vat_main;
12675   vat_json_node_t *node = NULL;
12676   struct in6_addr addr;
12677
12678   if (VAT_JSON_ARRAY != vam->json_tree.type)
12679     {
12680       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12681       vat_json_init_array (&vam->json_tree);
12682     }
12683   node = vat_json_array_add (&vam->json_tree);
12684
12685   vat_json_init_object (node);
12686
12687   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12688   vat_json_object_add_ip6 (node, "our_address", addr);
12689   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12690   vat_json_object_add_ip6 (node, "client_address", addr);
12691
12692   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12693   vat_json_init_array (lc);
12694   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12695   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12696   vat_json_object_add_uint (node, "remote_cookie",
12697                             clib_net_to_host_u64 (mp->remote_cookie));
12698
12699   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12700   vat_json_object_add_uint (node, "local_session_id",
12701                             clib_net_to_host_u32 (mp->local_session_id));
12702   vat_json_object_add_uint (node, "remote_session_id",
12703                             clib_net_to_host_u32 (mp->remote_session_id));
12704   vat_json_object_add_string_copy (node, "l2_sublayer",
12705                                    mp->l2_sublayer_present ? (u8 *) "present"
12706                                    : (u8 *) "absent");
12707 }
12708
12709 static int
12710 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12711 {
12712   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12713   vl_api_control_ping_t *mp_ping;
12714   int ret;
12715
12716   /* Get list of l2tpv3-tunnel interfaces */
12717   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12718   S (mp);
12719
12720   /* Use a control ping for synchronization */
12721   MPING (CONTROL_PING, mp_ping);
12722   S (mp_ping);
12723
12724   W (ret);
12725   return ret;
12726 }
12727
12728
12729 static void vl_api_sw_interface_tap_details_t_handler
12730   (vl_api_sw_interface_tap_details_t * mp)
12731 {
12732   vat_main_t *vam = &vat_main;
12733
12734   print (vam->ofp, "%-16s %d",
12735          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12736 }
12737
12738 static void vl_api_sw_interface_tap_details_t_handler_json
12739   (vl_api_sw_interface_tap_details_t * mp)
12740 {
12741   vat_main_t *vam = &vat_main;
12742   vat_json_node_t *node = NULL;
12743
12744   if (VAT_JSON_ARRAY != vam->json_tree.type)
12745     {
12746       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12747       vat_json_init_array (&vam->json_tree);
12748     }
12749   node = vat_json_array_add (&vam->json_tree);
12750
12751   vat_json_init_object (node);
12752   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12753   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12754 }
12755
12756 static int
12757 api_sw_interface_tap_dump (vat_main_t * vam)
12758 {
12759   vl_api_sw_interface_tap_dump_t *mp;
12760   vl_api_control_ping_t *mp_ping;
12761   int ret;
12762
12763   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12764   /* Get list of tap interfaces */
12765   M (SW_INTERFACE_TAP_DUMP, mp);
12766   S (mp);
12767
12768   /* Use a control ping for synchronization */
12769   MPING (CONTROL_PING, mp_ping);
12770   S (mp_ping);
12771
12772   W (ret);
12773   return ret;
12774 }
12775
12776 static void vl_api_sw_interface_tap_v2_details_t_handler
12777   (vl_api_sw_interface_tap_v2_details_t * mp)
12778 {
12779   vat_main_t *vam = &vat_main;
12780
12781   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12782                     mp->host_ip4_prefix_len);
12783   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12784                     mp->host_ip6_prefix_len);
12785
12786   print (vam->ofp,
12787          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12788          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12789          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12790          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12791          mp->host_bridge, ip4, ip6);
12792
12793   vec_free (ip4);
12794   vec_free (ip6);
12795 }
12796
12797 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12798   (vl_api_sw_interface_tap_v2_details_t * mp)
12799 {
12800   vat_main_t *vam = &vat_main;
12801   vat_json_node_t *node = NULL;
12802
12803   if (VAT_JSON_ARRAY != vam->json_tree.type)
12804     {
12805       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12806       vat_json_init_array (&vam->json_tree);
12807     }
12808   node = vat_json_array_add (&vam->json_tree);
12809
12810   vat_json_init_object (node);
12811   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12812   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12813   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12814   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12815   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12816   vat_json_object_add_string_copy (node, "host_mac_addr",
12817                                    format (0, "%U", format_ethernet_address,
12818                                            &mp->host_mac_addr));
12819   vat_json_object_add_string_copy (node, "host_namespace",
12820                                    mp->host_namespace);
12821   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12822   vat_json_object_add_string_copy (node, "host_ip4_addr",
12823                                    format (0, "%U/%d", format_ip4_address,
12824                                            mp->host_ip4_addr,
12825                                            mp->host_ip4_prefix_len));
12826   vat_json_object_add_string_copy (node, "host_ip6_addr",
12827                                    format (0, "%U/%d", format_ip6_address,
12828                                            mp->host_ip6_addr,
12829                                            mp->host_ip6_prefix_len));
12830
12831 }
12832
12833 static int
12834 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12835 {
12836   vl_api_sw_interface_tap_v2_dump_t *mp;
12837   vl_api_control_ping_t *mp_ping;
12838   int ret;
12839
12840   print (vam->ofp,
12841          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12842          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12843          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12844          "host_ip6_addr");
12845
12846   /* Get list of tap interfaces */
12847   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12848   S (mp);
12849
12850   /* Use a control ping for synchronization */
12851   MPING (CONTROL_PING, mp_ping);
12852   S (mp_ping);
12853
12854   W (ret);
12855   return ret;
12856 }
12857
12858 static uword unformat_vxlan_decap_next
12859   (unformat_input_t * input, va_list * args)
12860 {
12861   u32 *result = va_arg (*args, u32 *);
12862   u32 tmp;
12863
12864   if (unformat (input, "l2"))
12865     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12866   else if (unformat (input, "%d", &tmp))
12867     *result = tmp;
12868   else
12869     return 0;
12870   return 1;
12871 }
12872
12873 static int
12874 api_vxlan_add_del_tunnel (vat_main_t * vam)
12875 {
12876   unformat_input_t *line_input = vam->input;
12877   vl_api_vxlan_add_del_tunnel_t *mp;
12878   ip46_address_t src, dst;
12879   u8 is_add = 1;
12880   u8 ipv4_set = 0, ipv6_set = 0;
12881   u8 src_set = 0;
12882   u8 dst_set = 0;
12883   u8 grp_set = 0;
12884   u32 instance = ~0;
12885   u32 mcast_sw_if_index = ~0;
12886   u32 encap_vrf_id = 0;
12887   u32 decap_next_index = ~0;
12888   u32 vni = 0;
12889   int ret;
12890
12891   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12892   memset (&src, 0, sizeof src);
12893   memset (&dst, 0, sizeof dst);
12894
12895   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12896     {
12897       if (unformat (line_input, "del"))
12898         is_add = 0;
12899       else if (unformat (line_input, "instance %d", &instance))
12900         ;
12901       else
12902         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12903         {
12904           ipv4_set = 1;
12905           src_set = 1;
12906         }
12907       else
12908         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12909         {
12910           ipv4_set = 1;
12911           dst_set = 1;
12912         }
12913       else
12914         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12915         {
12916           ipv6_set = 1;
12917           src_set = 1;
12918         }
12919       else
12920         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12921         {
12922           ipv6_set = 1;
12923           dst_set = 1;
12924         }
12925       else if (unformat (line_input, "group %U %U",
12926                          unformat_ip4_address, &dst.ip4,
12927                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12928         {
12929           grp_set = dst_set = 1;
12930           ipv4_set = 1;
12931         }
12932       else if (unformat (line_input, "group %U",
12933                          unformat_ip4_address, &dst.ip4))
12934         {
12935           grp_set = dst_set = 1;
12936           ipv4_set = 1;
12937         }
12938       else if (unformat (line_input, "group %U %U",
12939                          unformat_ip6_address, &dst.ip6,
12940                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12941         {
12942           grp_set = dst_set = 1;
12943           ipv6_set = 1;
12944         }
12945       else if (unformat (line_input, "group %U",
12946                          unformat_ip6_address, &dst.ip6))
12947         {
12948           grp_set = dst_set = 1;
12949           ipv6_set = 1;
12950         }
12951       else
12952         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12953         ;
12954       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12955         ;
12956       else if (unformat (line_input, "decap-next %U",
12957                          unformat_vxlan_decap_next, &decap_next_index))
12958         ;
12959       else if (unformat (line_input, "vni %d", &vni))
12960         ;
12961       else
12962         {
12963           errmsg ("parse error '%U'", format_unformat_error, line_input);
12964           return -99;
12965         }
12966     }
12967
12968   if (src_set == 0)
12969     {
12970       errmsg ("tunnel src address not specified");
12971       return -99;
12972     }
12973   if (dst_set == 0)
12974     {
12975       errmsg ("tunnel dst address not specified");
12976       return -99;
12977     }
12978
12979   if (grp_set && !ip46_address_is_multicast (&dst))
12980     {
12981       errmsg ("tunnel group address not multicast");
12982       return -99;
12983     }
12984   if (grp_set && mcast_sw_if_index == ~0)
12985     {
12986       errmsg ("tunnel nonexistent multicast device");
12987       return -99;
12988     }
12989   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12990     {
12991       errmsg ("tunnel dst address must be unicast");
12992       return -99;
12993     }
12994
12995
12996   if (ipv4_set && ipv6_set)
12997     {
12998       errmsg ("both IPv4 and IPv6 addresses specified");
12999       return -99;
13000     }
13001
13002   if ((vni == 0) || (vni >> 24))
13003     {
13004       errmsg ("vni not specified or out of range");
13005       return -99;
13006     }
13007
13008   M (VXLAN_ADD_DEL_TUNNEL, mp);
13009
13010   if (ipv6_set)
13011     {
13012       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13013       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13014     }
13015   else
13016     {
13017       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13018       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13019     }
13020
13021   mp->instance = htonl (instance);
13022   mp->encap_vrf_id = ntohl (encap_vrf_id);
13023   mp->decap_next_index = ntohl (decap_next_index);
13024   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13025   mp->vni = ntohl (vni);
13026   mp->is_add = is_add;
13027   mp->is_ipv6 = ipv6_set;
13028
13029   S (mp);
13030   W (ret);
13031   return ret;
13032 }
13033
13034 static void vl_api_vxlan_tunnel_details_t_handler
13035   (vl_api_vxlan_tunnel_details_t * mp)
13036 {
13037   vat_main_t *vam = &vat_main;
13038   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13039   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13040
13041   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13042          ntohl (mp->sw_if_index),
13043          ntohl (mp->instance),
13044          format_ip46_address, &src, IP46_TYPE_ANY,
13045          format_ip46_address, &dst, IP46_TYPE_ANY,
13046          ntohl (mp->encap_vrf_id),
13047          ntohl (mp->decap_next_index), ntohl (mp->vni),
13048          ntohl (mp->mcast_sw_if_index));
13049 }
13050
13051 static void vl_api_vxlan_tunnel_details_t_handler_json
13052   (vl_api_vxlan_tunnel_details_t * mp)
13053 {
13054   vat_main_t *vam = &vat_main;
13055   vat_json_node_t *node = NULL;
13056
13057   if (VAT_JSON_ARRAY != vam->json_tree.type)
13058     {
13059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13060       vat_json_init_array (&vam->json_tree);
13061     }
13062   node = vat_json_array_add (&vam->json_tree);
13063
13064   vat_json_init_object (node);
13065   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13066
13067   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13068
13069   if (mp->is_ipv6)
13070     {
13071       struct in6_addr ip6;
13072
13073       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13074       vat_json_object_add_ip6 (node, "src_address", ip6);
13075       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13076       vat_json_object_add_ip6 (node, "dst_address", ip6);
13077     }
13078   else
13079     {
13080       struct in_addr ip4;
13081
13082       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13083       vat_json_object_add_ip4 (node, "src_address", ip4);
13084       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13085       vat_json_object_add_ip4 (node, "dst_address", ip4);
13086     }
13087   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13088   vat_json_object_add_uint (node, "decap_next_index",
13089                             ntohl (mp->decap_next_index));
13090   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13091   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13092   vat_json_object_add_uint (node, "mcast_sw_if_index",
13093                             ntohl (mp->mcast_sw_if_index));
13094 }
13095
13096 static int
13097 api_vxlan_tunnel_dump (vat_main_t * vam)
13098 {
13099   unformat_input_t *i = vam->input;
13100   vl_api_vxlan_tunnel_dump_t *mp;
13101   vl_api_control_ping_t *mp_ping;
13102   u32 sw_if_index;
13103   u8 sw_if_index_set = 0;
13104   int ret;
13105
13106   /* Parse args required to build the message */
13107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13108     {
13109       if (unformat (i, "sw_if_index %d", &sw_if_index))
13110         sw_if_index_set = 1;
13111       else
13112         break;
13113     }
13114
13115   if (sw_if_index_set == 0)
13116     {
13117       sw_if_index = ~0;
13118     }
13119
13120   if (!vam->json_output)
13121     {
13122       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13123              "sw_if_index", "instance", "src_address", "dst_address",
13124              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13125     }
13126
13127   /* Get list of vxlan-tunnel interfaces */
13128   M (VXLAN_TUNNEL_DUMP, mp);
13129
13130   mp->sw_if_index = htonl (sw_if_index);
13131
13132   S (mp);
13133
13134   /* Use a control ping for synchronization */
13135   MPING (CONTROL_PING, mp_ping);
13136   S (mp_ping);
13137
13138   W (ret);
13139   return ret;
13140 }
13141
13142 static uword unformat_geneve_decap_next
13143   (unformat_input_t * input, va_list * args)
13144 {
13145   u32 *result = va_arg (*args, u32 *);
13146   u32 tmp;
13147
13148   if (unformat (input, "l2"))
13149     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13150   else if (unformat (input, "%d", &tmp))
13151     *result = tmp;
13152   else
13153     return 0;
13154   return 1;
13155 }
13156
13157 static int
13158 api_geneve_add_del_tunnel (vat_main_t * vam)
13159 {
13160   unformat_input_t *line_input = vam->input;
13161   vl_api_geneve_add_del_tunnel_t *mp;
13162   ip46_address_t src, dst;
13163   u8 is_add = 1;
13164   u8 ipv4_set = 0, ipv6_set = 0;
13165   u8 src_set = 0;
13166   u8 dst_set = 0;
13167   u8 grp_set = 0;
13168   u32 mcast_sw_if_index = ~0;
13169   u32 encap_vrf_id = 0;
13170   u32 decap_next_index = ~0;
13171   u32 vni = 0;
13172   int ret;
13173
13174   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13175   memset (&src, 0, sizeof src);
13176   memset (&dst, 0, sizeof dst);
13177
13178   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13179     {
13180       if (unformat (line_input, "del"))
13181         is_add = 0;
13182       else
13183         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13184         {
13185           ipv4_set = 1;
13186           src_set = 1;
13187         }
13188       else
13189         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13190         {
13191           ipv4_set = 1;
13192           dst_set = 1;
13193         }
13194       else
13195         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13196         {
13197           ipv6_set = 1;
13198           src_set = 1;
13199         }
13200       else
13201         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13202         {
13203           ipv6_set = 1;
13204           dst_set = 1;
13205         }
13206       else if (unformat (line_input, "group %U %U",
13207                          unformat_ip4_address, &dst.ip4,
13208                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13209         {
13210           grp_set = dst_set = 1;
13211           ipv4_set = 1;
13212         }
13213       else if (unformat (line_input, "group %U",
13214                          unformat_ip4_address, &dst.ip4))
13215         {
13216           grp_set = dst_set = 1;
13217           ipv4_set = 1;
13218         }
13219       else if (unformat (line_input, "group %U %U",
13220                          unformat_ip6_address, &dst.ip6,
13221                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13222         {
13223           grp_set = dst_set = 1;
13224           ipv6_set = 1;
13225         }
13226       else if (unformat (line_input, "group %U",
13227                          unformat_ip6_address, &dst.ip6))
13228         {
13229           grp_set = dst_set = 1;
13230           ipv6_set = 1;
13231         }
13232       else
13233         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13234         ;
13235       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13236         ;
13237       else if (unformat (line_input, "decap-next %U",
13238                          unformat_geneve_decap_next, &decap_next_index))
13239         ;
13240       else if (unformat (line_input, "vni %d", &vni))
13241         ;
13242       else
13243         {
13244           errmsg ("parse error '%U'", format_unformat_error, line_input);
13245           return -99;
13246         }
13247     }
13248
13249   if (src_set == 0)
13250     {
13251       errmsg ("tunnel src address not specified");
13252       return -99;
13253     }
13254   if (dst_set == 0)
13255     {
13256       errmsg ("tunnel dst address not specified");
13257       return -99;
13258     }
13259
13260   if (grp_set && !ip46_address_is_multicast (&dst))
13261     {
13262       errmsg ("tunnel group address not multicast");
13263       return -99;
13264     }
13265   if (grp_set && mcast_sw_if_index == ~0)
13266     {
13267       errmsg ("tunnel nonexistent multicast device");
13268       return -99;
13269     }
13270   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13271     {
13272       errmsg ("tunnel dst address must be unicast");
13273       return -99;
13274     }
13275
13276
13277   if (ipv4_set && ipv6_set)
13278     {
13279       errmsg ("both IPv4 and IPv6 addresses specified");
13280       return -99;
13281     }
13282
13283   if ((vni == 0) || (vni >> 24))
13284     {
13285       errmsg ("vni not specified or out of range");
13286       return -99;
13287     }
13288
13289   M (GENEVE_ADD_DEL_TUNNEL, mp);
13290
13291   if (ipv6_set)
13292     {
13293       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13294       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13295     }
13296   else
13297     {
13298       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13299       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13300     }
13301   mp->encap_vrf_id = ntohl (encap_vrf_id);
13302   mp->decap_next_index = ntohl (decap_next_index);
13303   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13304   mp->vni = ntohl (vni);
13305   mp->is_add = is_add;
13306   mp->is_ipv6 = ipv6_set;
13307
13308   S (mp);
13309   W (ret);
13310   return ret;
13311 }
13312
13313 static void vl_api_geneve_tunnel_details_t_handler
13314   (vl_api_geneve_tunnel_details_t * mp)
13315 {
13316   vat_main_t *vam = &vat_main;
13317   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13318   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13319
13320   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13321          ntohl (mp->sw_if_index),
13322          format_ip46_address, &src, IP46_TYPE_ANY,
13323          format_ip46_address, &dst, IP46_TYPE_ANY,
13324          ntohl (mp->encap_vrf_id),
13325          ntohl (mp->decap_next_index), ntohl (mp->vni),
13326          ntohl (mp->mcast_sw_if_index));
13327 }
13328
13329 static void vl_api_geneve_tunnel_details_t_handler_json
13330   (vl_api_geneve_tunnel_details_t * mp)
13331 {
13332   vat_main_t *vam = &vat_main;
13333   vat_json_node_t *node = NULL;
13334
13335   if (VAT_JSON_ARRAY != vam->json_tree.type)
13336     {
13337       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13338       vat_json_init_array (&vam->json_tree);
13339     }
13340   node = vat_json_array_add (&vam->json_tree);
13341
13342   vat_json_init_object (node);
13343   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13344   if (mp->is_ipv6)
13345     {
13346       struct in6_addr ip6;
13347
13348       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13349       vat_json_object_add_ip6 (node, "src_address", ip6);
13350       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13351       vat_json_object_add_ip6 (node, "dst_address", ip6);
13352     }
13353   else
13354     {
13355       struct in_addr ip4;
13356
13357       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13358       vat_json_object_add_ip4 (node, "src_address", ip4);
13359       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13360       vat_json_object_add_ip4 (node, "dst_address", ip4);
13361     }
13362   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13363   vat_json_object_add_uint (node, "decap_next_index",
13364                             ntohl (mp->decap_next_index));
13365   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13366   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13367   vat_json_object_add_uint (node, "mcast_sw_if_index",
13368                             ntohl (mp->mcast_sw_if_index));
13369 }
13370
13371 static int
13372 api_geneve_tunnel_dump (vat_main_t * vam)
13373 {
13374   unformat_input_t *i = vam->input;
13375   vl_api_geneve_tunnel_dump_t *mp;
13376   vl_api_control_ping_t *mp_ping;
13377   u32 sw_if_index;
13378   u8 sw_if_index_set = 0;
13379   int ret;
13380
13381   /* Parse args required to build the message */
13382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13383     {
13384       if (unformat (i, "sw_if_index %d", &sw_if_index))
13385         sw_if_index_set = 1;
13386       else
13387         break;
13388     }
13389
13390   if (sw_if_index_set == 0)
13391     {
13392       sw_if_index = ~0;
13393     }
13394
13395   if (!vam->json_output)
13396     {
13397       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13398              "sw_if_index", "local_address", "remote_address",
13399              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13400     }
13401
13402   /* Get list of geneve-tunnel interfaces */
13403   M (GENEVE_TUNNEL_DUMP, mp);
13404
13405   mp->sw_if_index = htonl (sw_if_index);
13406
13407   S (mp);
13408
13409   /* Use a control ping for synchronization */
13410   M (CONTROL_PING, mp_ping);
13411   S (mp_ping);
13412
13413   W (ret);
13414   return ret;
13415 }
13416
13417 static int
13418 api_gre_add_del_tunnel (vat_main_t * vam)
13419 {
13420   unformat_input_t *line_input = vam->input;
13421   vl_api_gre_add_del_tunnel_t *mp;
13422   ip4_address_t src4, dst4;
13423   ip6_address_t src6, dst6;
13424   u8 is_add = 1;
13425   u8 ipv4_set = 0;
13426   u8 ipv6_set = 0;
13427   u8 t_type = GRE_TUNNEL_TYPE_L3;
13428   u8 src_set = 0;
13429   u8 dst_set = 0;
13430   u32 outer_fib_id = 0;
13431   u32 session_id = 0;
13432   u32 instance = ~0;
13433   int ret;
13434
13435   memset (&src4, 0, sizeof src4);
13436   memset (&dst4, 0, sizeof dst4);
13437   memset (&src6, 0, sizeof src6);
13438   memset (&dst6, 0, sizeof dst6);
13439
13440   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13441     {
13442       if (unformat (line_input, "del"))
13443         is_add = 0;
13444       else if (unformat (line_input, "instance %d", &instance))
13445         ;
13446       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13447         {
13448           src_set = 1;
13449           ipv4_set = 1;
13450         }
13451       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13452         {
13453           dst_set = 1;
13454           ipv4_set = 1;
13455         }
13456       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13457         {
13458           src_set = 1;
13459           ipv6_set = 1;
13460         }
13461       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13462         {
13463           dst_set = 1;
13464           ipv6_set = 1;
13465         }
13466       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13467         ;
13468       else if (unformat (line_input, "teb"))
13469         t_type = GRE_TUNNEL_TYPE_TEB;
13470       else if (unformat (line_input, "erspan %d", &session_id))
13471         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13472       else
13473         {
13474           errmsg ("parse error '%U'", format_unformat_error, line_input);
13475           return -99;
13476         }
13477     }
13478
13479   if (src_set == 0)
13480     {
13481       errmsg ("tunnel src address not specified");
13482       return -99;
13483     }
13484   if (dst_set == 0)
13485     {
13486       errmsg ("tunnel dst address not specified");
13487       return -99;
13488     }
13489   if (ipv4_set && ipv6_set)
13490     {
13491       errmsg ("both IPv4 and IPv6 addresses specified");
13492       return -99;
13493     }
13494
13495
13496   M (GRE_ADD_DEL_TUNNEL, mp);
13497
13498   if (ipv4_set)
13499     {
13500       clib_memcpy (&mp->src_address, &src4, 4);
13501       clib_memcpy (&mp->dst_address, &dst4, 4);
13502     }
13503   else
13504     {
13505       clib_memcpy (&mp->src_address, &src6, 16);
13506       clib_memcpy (&mp->dst_address, &dst6, 16);
13507     }
13508   mp->instance = htonl (instance);
13509   mp->outer_fib_id = htonl (outer_fib_id);
13510   mp->is_add = is_add;
13511   mp->session_id = htons ((u16) session_id);
13512   mp->tunnel_type = t_type;
13513   mp->is_ipv6 = ipv6_set;
13514
13515   S (mp);
13516   W (ret);
13517   return ret;
13518 }
13519
13520 static void vl_api_gre_tunnel_details_t_handler
13521   (vl_api_gre_tunnel_details_t * mp)
13522 {
13523   vat_main_t *vam = &vat_main;
13524   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13525   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13526
13527   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13528          ntohl (mp->sw_if_index),
13529          ntohl (mp->instance),
13530          format_ip46_address, &src, IP46_TYPE_ANY,
13531          format_ip46_address, &dst, IP46_TYPE_ANY,
13532          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13533 }
13534
13535 static void vl_api_gre_tunnel_details_t_handler_json
13536   (vl_api_gre_tunnel_details_t * mp)
13537 {
13538   vat_main_t *vam = &vat_main;
13539   vat_json_node_t *node = NULL;
13540   struct in_addr ip4;
13541   struct in6_addr ip6;
13542
13543   if (VAT_JSON_ARRAY != vam->json_tree.type)
13544     {
13545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13546       vat_json_init_array (&vam->json_tree);
13547     }
13548   node = vat_json_array_add (&vam->json_tree);
13549
13550   vat_json_init_object (node);
13551   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13552   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13553   if (!mp->is_ipv6)
13554     {
13555       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13556       vat_json_object_add_ip4 (node, "src_address", ip4);
13557       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13558       vat_json_object_add_ip4 (node, "dst_address", ip4);
13559     }
13560   else
13561     {
13562       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13563       vat_json_object_add_ip6 (node, "src_address", ip6);
13564       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13565       vat_json_object_add_ip6 (node, "dst_address", ip6);
13566     }
13567   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13568   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13569   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13570   vat_json_object_add_uint (node, "session_id", mp->session_id);
13571 }
13572
13573 static int
13574 api_gre_tunnel_dump (vat_main_t * vam)
13575 {
13576   unformat_input_t *i = vam->input;
13577   vl_api_gre_tunnel_dump_t *mp;
13578   vl_api_control_ping_t *mp_ping;
13579   u32 sw_if_index;
13580   u8 sw_if_index_set = 0;
13581   int ret;
13582
13583   /* Parse args required to build the message */
13584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13585     {
13586       if (unformat (i, "sw_if_index %d", &sw_if_index))
13587         sw_if_index_set = 1;
13588       else
13589         break;
13590     }
13591
13592   if (sw_if_index_set == 0)
13593     {
13594       sw_if_index = ~0;
13595     }
13596
13597   if (!vam->json_output)
13598     {
13599       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13600              "sw_if_index", "instance", "src_address", "dst_address",
13601              "tunnel_type", "outer_fib_id", "session_id");
13602     }
13603
13604   /* Get list of gre-tunnel interfaces */
13605   M (GRE_TUNNEL_DUMP, mp);
13606
13607   mp->sw_if_index = htonl (sw_if_index);
13608
13609   S (mp);
13610
13611   /* Use a control ping for synchronization */
13612   MPING (CONTROL_PING, mp_ping);
13613   S (mp_ping);
13614
13615   W (ret);
13616   return ret;
13617 }
13618
13619 static int
13620 api_l2_fib_clear_table (vat_main_t * vam)
13621 {
13622 //  unformat_input_t * i = vam->input;
13623   vl_api_l2_fib_clear_table_t *mp;
13624   int ret;
13625
13626   M (L2_FIB_CLEAR_TABLE, mp);
13627
13628   S (mp);
13629   W (ret);
13630   return ret;
13631 }
13632
13633 static int
13634 api_l2_interface_efp_filter (vat_main_t * vam)
13635 {
13636   unformat_input_t *i = vam->input;
13637   vl_api_l2_interface_efp_filter_t *mp;
13638   u32 sw_if_index;
13639   u8 enable = 1;
13640   u8 sw_if_index_set = 0;
13641   int ret;
13642
13643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13644     {
13645       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13646         sw_if_index_set = 1;
13647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13648         sw_if_index_set = 1;
13649       else if (unformat (i, "enable"))
13650         enable = 1;
13651       else if (unformat (i, "disable"))
13652         enable = 0;
13653       else
13654         {
13655           clib_warning ("parse error '%U'", format_unformat_error, i);
13656           return -99;
13657         }
13658     }
13659
13660   if (sw_if_index_set == 0)
13661     {
13662       errmsg ("missing sw_if_index");
13663       return -99;
13664     }
13665
13666   M (L2_INTERFACE_EFP_FILTER, mp);
13667
13668   mp->sw_if_index = ntohl (sw_if_index);
13669   mp->enable_disable = enable;
13670
13671   S (mp);
13672   W (ret);
13673   return ret;
13674 }
13675
13676 #define foreach_vtr_op                          \
13677 _("disable",  L2_VTR_DISABLED)                  \
13678 _("push-1",  L2_VTR_PUSH_1)                     \
13679 _("push-2",  L2_VTR_PUSH_2)                     \
13680 _("pop-1",  L2_VTR_POP_1)                       \
13681 _("pop-2",  L2_VTR_POP_2)                       \
13682 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13683 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13684 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13685 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13686
13687 static int
13688 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13689 {
13690   unformat_input_t *i = vam->input;
13691   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13692   u32 sw_if_index;
13693   u8 sw_if_index_set = 0;
13694   u8 vtr_op_set = 0;
13695   u32 vtr_op = 0;
13696   u32 push_dot1q = 1;
13697   u32 tag1 = ~0;
13698   u32 tag2 = ~0;
13699   int ret;
13700
13701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13702     {
13703       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13704         sw_if_index_set = 1;
13705       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13706         sw_if_index_set = 1;
13707       else if (unformat (i, "vtr_op %d", &vtr_op))
13708         vtr_op_set = 1;
13709 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13710       foreach_vtr_op
13711 #undef _
13712         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13713         ;
13714       else if (unformat (i, "tag1 %d", &tag1))
13715         ;
13716       else if (unformat (i, "tag2 %d", &tag2))
13717         ;
13718       else
13719         {
13720           clib_warning ("parse error '%U'", format_unformat_error, i);
13721           return -99;
13722         }
13723     }
13724
13725   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13726     {
13727       errmsg ("missing vtr operation or sw_if_index");
13728       return -99;
13729     }
13730
13731   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13732   mp->sw_if_index = ntohl (sw_if_index);
13733   mp->vtr_op = ntohl (vtr_op);
13734   mp->push_dot1q = ntohl (push_dot1q);
13735   mp->tag1 = ntohl (tag1);
13736   mp->tag2 = ntohl (tag2);
13737
13738   S (mp);
13739   W (ret);
13740   return ret;
13741 }
13742
13743 static int
13744 api_create_vhost_user_if (vat_main_t * vam)
13745 {
13746   unformat_input_t *i = vam->input;
13747   vl_api_create_vhost_user_if_t *mp;
13748   u8 *file_name;
13749   u8 is_server = 0;
13750   u8 file_name_set = 0;
13751   u32 custom_dev_instance = ~0;
13752   u8 hwaddr[6];
13753   u8 use_custom_mac = 0;
13754   u8 *tag = 0;
13755   int ret;
13756
13757   /* Shut up coverity */
13758   memset (hwaddr, 0, sizeof (hwaddr));
13759
13760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13761     {
13762       if (unformat (i, "socket %s", &file_name))
13763         {
13764           file_name_set = 1;
13765         }
13766       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13767         ;
13768       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13769         use_custom_mac = 1;
13770       else if (unformat (i, "server"))
13771         is_server = 1;
13772       else if (unformat (i, "tag %s", &tag))
13773         ;
13774       else
13775         break;
13776     }
13777
13778   if (file_name_set == 0)
13779     {
13780       errmsg ("missing socket file name");
13781       return -99;
13782     }
13783
13784   if (vec_len (file_name) > 255)
13785     {
13786       errmsg ("socket file name too long");
13787       return -99;
13788     }
13789   vec_add1 (file_name, 0);
13790
13791   M (CREATE_VHOST_USER_IF, mp);
13792
13793   mp->is_server = is_server;
13794   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13795   vec_free (file_name);
13796   if (custom_dev_instance != ~0)
13797     {
13798       mp->renumber = 1;
13799       mp->custom_dev_instance = ntohl (custom_dev_instance);
13800     }
13801   mp->use_custom_mac = use_custom_mac;
13802   clib_memcpy (mp->mac_address, hwaddr, 6);
13803   if (tag)
13804     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13805   vec_free (tag);
13806
13807   S (mp);
13808   W (ret);
13809   return ret;
13810 }
13811
13812 static int
13813 api_modify_vhost_user_if (vat_main_t * vam)
13814 {
13815   unformat_input_t *i = vam->input;
13816   vl_api_modify_vhost_user_if_t *mp;
13817   u8 *file_name;
13818   u8 is_server = 0;
13819   u8 file_name_set = 0;
13820   u32 custom_dev_instance = ~0;
13821   u8 sw_if_index_set = 0;
13822   u32 sw_if_index = (u32) ~ 0;
13823   int ret;
13824
13825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13826     {
13827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13828         sw_if_index_set = 1;
13829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13830         sw_if_index_set = 1;
13831       else if (unformat (i, "socket %s", &file_name))
13832         {
13833           file_name_set = 1;
13834         }
13835       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13836         ;
13837       else if (unformat (i, "server"))
13838         is_server = 1;
13839       else
13840         break;
13841     }
13842
13843   if (sw_if_index_set == 0)
13844     {
13845       errmsg ("missing sw_if_index or interface name");
13846       return -99;
13847     }
13848
13849   if (file_name_set == 0)
13850     {
13851       errmsg ("missing socket file name");
13852       return -99;
13853     }
13854
13855   if (vec_len (file_name) > 255)
13856     {
13857       errmsg ("socket file name too long");
13858       return -99;
13859     }
13860   vec_add1 (file_name, 0);
13861
13862   M (MODIFY_VHOST_USER_IF, mp);
13863
13864   mp->sw_if_index = ntohl (sw_if_index);
13865   mp->is_server = is_server;
13866   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13867   vec_free (file_name);
13868   if (custom_dev_instance != ~0)
13869     {
13870       mp->renumber = 1;
13871       mp->custom_dev_instance = ntohl (custom_dev_instance);
13872     }
13873
13874   S (mp);
13875   W (ret);
13876   return ret;
13877 }
13878
13879 static int
13880 api_delete_vhost_user_if (vat_main_t * vam)
13881 {
13882   unformat_input_t *i = vam->input;
13883   vl_api_delete_vhost_user_if_t *mp;
13884   u32 sw_if_index = ~0;
13885   u8 sw_if_index_set = 0;
13886   int ret;
13887
13888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13889     {
13890       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13891         sw_if_index_set = 1;
13892       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13893         sw_if_index_set = 1;
13894       else
13895         break;
13896     }
13897
13898   if (sw_if_index_set == 0)
13899     {
13900       errmsg ("missing sw_if_index or interface name");
13901       return -99;
13902     }
13903
13904
13905   M (DELETE_VHOST_USER_IF, mp);
13906
13907   mp->sw_if_index = ntohl (sw_if_index);
13908
13909   S (mp);
13910   W (ret);
13911   return ret;
13912 }
13913
13914 static void vl_api_sw_interface_vhost_user_details_t_handler
13915   (vl_api_sw_interface_vhost_user_details_t * mp)
13916 {
13917   vat_main_t *vam = &vat_main;
13918
13919   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13920          (char *) mp->interface_name,
13921          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13922          clib_net_to_host_u64 (mp->features), mp->is_server,
13923          ntohl (mp->num_regions), (char *) mp->sock_filename);
13924   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13925 }
13926
13927 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13928   (vl_api_sw_interface_vhost_user_details_t * mp)
13929 {
13930   vat_main_t *vam = &vat_main;
13931   vat_json_node_t *node = NULL;
13932
13933   if (VAT_JSON_ARRAY != vam->json_tree.type)
13934     {
13935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13936       vat_json_init_array (&vam->json_tree);
13937     }
13938   node = vat_json_array_add (&vam->json_tree);
13939
13940   vat_json_init_object (node);
13941   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13942   vat_json_object_add_string_copy (node, "interface_name",
13943                                    mp->interface_name);
13944   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13945                             ntohl (mp->virtio_net_hdr_sz));
13946   vat_json_object_add_uint (node, "features",
13947                             clib_net_to_host_u64 (mp->features));
13948   vat_json_object_add_uint (node, "is_server", mp->is_server);
13949   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13950   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13951   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13952 }
13953
13954 static int
13955 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13956 {
13957   vl_api_sw_interface_vhost_user_dump_t *mp;
13958   vl_api_control_ping_t *mp_ping;
13959   int ret;
13960   print (vam->ofp,
13961          "Interface name            idx hdr_sz features server regions filename");
13962
13963   /* Get list of vhost-user interfaces */
13964   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13965   S (mp);
13966
13967   /* Use a control ping for synchronization */
13968   MPING (CONTROL_PING, mp_ping);
13969   S (mp_ping);
13970
13971   W (ret);
13972   return ret;
13973 }
13974
13975 static int
13976 api_show_version (vat_main_t * vam)
13977 {
13978   vl_api_show_version_t *mp;
13979   int ret;
13980
13981   M (SHOW_VERSION, mp);
13982
13983   S (mp);
13984   W (ret);
13985   return ret;
13986 }
13987
13988
13989 static int
13990 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13991 {
13992   unformat_input_t *line_input = vam->input;
13993   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13994   ip4_address_t local4, remote4;
13995   ip6_address_t local6, remote6;
13996   u8 is_add = 1;
13997   u8 ipv4_set = 0, ipv6_set = 0;
13998   u8 local_set = 0;
13999   u8 remote_set = 0;
14000   u8 grp_set = 0;
14001   u32 mcast_sw_if_index = ~0;
14002   u32 encap_vrf_id = 0;
14003   u32 decap_vrf_id = 0;
14004   u8 protocol = ~0;
14005   u32 vni;
14006   u8 vni_set = 0;
14007   int ret;
14008
14009   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14010   memset (&local4, 0, sizeof local4);
14011   memset (&remote4, 0, sizeof remote4);
14012   memset (&local6, 0, sizeof local6);
14013   memset (&remote6, 0, sizeof remote6);
14014
14015   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14016     {
14017       if (unformat (line_input, "del"))
14018         is_add = 0;
14019       else if (unformat (line_input, "local %U",
14020                          unformat_ip4_address, &local4))
14021         {
14022           local_set = 1;
14023           ipv4_set = 1;
14024         }
14025       else if (unformat (line_input, "remote %U",
14026                          unformat_ip4_address, &remote4))
14027         {
14028           remote_set = 1;
14029           ipv4_set = 1;
14030         }
14031       else if (unformat (line_input, "local %U",
14032                          unformat_ip6_address, &local6))
14033         {
14034           local_set = 1;
14035           ipv6_set = 1;
14036         }
14037       else if (unformat (line_input, "remote %U",
14038                          unformat_ip6_address, &remote6))
14039         {
14040           remote_set = 1;
14041           ipv6_set = 1;
14042         }
14043       else if (unformat (line_input, "group %U %U",
14044                          unformat_ip4_address, &remote4,
14045                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14046         {
14047           grp_set = remote_set = 1;
14048           ipv4_set = 1;
14049         }
14050       else if (unformat (line_input, "group %U",
14051                          unformat_ip4_address, &remote4))
14052         {
14053           grp_set = remote_set = 1;
14054           ipv4_set = 1;
14055         }
14056       else if (unformat (line_input, "group %U %U",
14057                          unformat_ip6_address, &remote6,
14058                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14059         {
14060           grp_set = remote_set = 1;
14061           ipv6_set = 1;
14062         }
14063       else if (unformat (line_input, "group %U",
14064                          unformat_ip6_address, &remote6))
14065         {
14066           grp_set = remote_set = 1;
14067           ipv6_set = 1;
14068         }
14069       else
14070         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14071         ;
14072       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14073         ;
14074       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14075         ;
14076       else if (unformat (line_input, "vni %d", &vni))
14077         vni_set = 1;
14078       else if (unformat (line_input, "next-ip4"))
14079         protocol = 1;
14080       else if (unformat (line_input, "next-ip6"))
14081         protocol = 2;
14082       else if (unformat (line_input, "next-ethernet"))
14083         protocol = 3;
14084       else if (unformat (line_input, "next-nsh"))
14085         protocol = 4;
14086       else
14087         {
14088           errmsg ("parse error '%U'", format_unformat_error, line_input);
14089           return -99;
14090         }
14091     }
14092
14093   if (local_set == 0)
14094     {
14095       errmsg ("tunnel local address not specified");
14096       return -99;
14097     }
14098   if (remote_set == 0)
14099     {
14100       errmsg ("tunnel remote address not specified");
14101       return -99;
14102     }
14103   if (grp_set && mcast_sw_if_index == ~0)
14104     {
14105       errmsg ("tunnel nonexistent multicast device");
14106       return -99;
14107     }
14108   if (ipv4_set && ipv6_set)
14109     {
14110       errmsg ("both IPv4 and IPv6 addresses specified");
14111       return -99;
14112     }
14113
14114   if (vni_set == 0)
14115     {
14116       errmsg ("vni not specified");
14117       return -99;
14118     }
14119
14120   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14121
14122
14123   if (ipv6_set)
14124     {
14125       clib_memcpy (&mp->local, &local6, sizeof (local6));
14126       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14127     }
14128   else
14129     {
14130       clib_memcpy (&mp->local, &local4, sizeof (local4));
14131       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14132     }
14133
14134   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14135   mp->encap_vrf_id = ntohl (encap_vrf_id);
14136   mp->decap_vrf_id = ntohl (decap_vrf_id);
14137   mp->protocol = protocol;
14138   mp->vni = ntohl (vni);
14139   mp->is_add = is_add;
14140   mp->is_ipv6 = ipv6_set;
14141
14142   S (mp);
14143   W (ret);
14144   return ret;
14145 }
14146
14147 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14148   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14149 {
14150   vat_main_t *vam = &vat_main;
14151   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14152   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14153
14154   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14155          ntohl (mp->sw_if_index),
14156          format_ip46_address, &local, IP46_TYPE_ANY,
14157          format_ip46_address, &remote, IP46_TYPE_ANY,
14158          ntohl (mp->vni), mp->protocol,
14159          ntohl (mp->mcast_sw_if_index),
14160          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14161 }
14162
14163
14164 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14165   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14166 {
14167   vat_main_t *vam = &vat_main;
14168   vat_json_node_t *node = NULL;
14169   struct in_addr ip4;
14170   struct in6_addr ip6;
14171
14172   if (VAT_JSON_ARRAY != vam->json_tree.type)
14173     {
14174       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14175       vat_json_init_array (&vam->json_tree);
14176     }
14177   node = vat_json_array_add (&vam->json_tree);
14178
14179   vat_json_init_object (node);
14180   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14181   if (mp->is_ipv6)
14182     {
14183       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14184       vat_json_object_add_ip6 (node, "local", ip6);
14185       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14186       vat_json_object_add_ip6 (node, "remote", ip6);
14187     }
14188   else
14189     {
14190       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14191       vat_json_object_add_ip4 (node, "local", ip4);
14192       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14193       vat_json_object_add_ip4 (node, "remote", ip4);
14194     }
14195   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14196   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14197   vat_json_object_add_uint (node, "mcast_sw_if_index",
14198                             ntohl (mp->mcast_sw_if_index));
14199   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14200   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14201   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14202 }
14203
14204 static int
14205 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14206 {
14207   unformat_input_t *i = vam->input;
14208   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14209   vl_api_control_ping_t *mp_ping;
14210   u32 sw_if_index;
14211   u8 sw_if_index_set = 0;
14212   int ret;
14213
14214   /* Parse args required to build the message */
14215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14216     {
14217       if (unformat (i, "sw_if_index %d", &sw_if_index))
14218         sw_if_index_set = 1;
14219       else
14220         break;
14221     }
14222
14223   if (sw_if_index_set == 0)
14224     {
14225       sw_if_index = ~0;
14226     }
14227
14228   if (!vam->json_output)
14229     {
14230       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14231              "sw_if_index", "local", "remote", "vni",
14232              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14233     }
14234
14235   /* Get list of vxlan-tunnel interfaces */
14236   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14237
14238   mp->sw_if_index = htonl (sw_if_index);
14239
14240   S (mp);
14241
14242   /* Use a control ping for synchronization */
14243   MPING (CONTROL_PING, mp_ping);
14244   S (mp_ping);
14245
14246   W (ret);
14247   return ret;
14248 }
14249
14250 static void vl_api_l2_fib_table_details_t_handler
14251   (vl_api_l2_fib_table_details_t * mp)
14252 {
14253   vat_main_t *vam = &vat_main;
14254
14255   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14256          "       %d       %d     %d",
14257          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14258          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14259          mp->bvi_mac);
14260 }
14261
14262 static void vl_api_l2_fib_table_details_t_handler_json
14263   (vl_api_l2_fib_table_details_t * mp)
14264 {
14265   vat_main_t *vam = &vat_main;
14266   vat_json_node_t *node = NULL;
14267
14268   if (VAT_JSON_ARRAY != vam->json_tree.type)
14269     {
14270       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14271       vat_json_init_array (&vam->json_tree);
14272     }
14273   node = vat_json_array_add (&vam->json_tree);
14274
14275   vat_json_init_object (node);
14276   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14277   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14278   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14279   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14280   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14281   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14282 }
14283
14284 static int
14285 api_l2_fib_table_dump (vat_main_t * vam)
14286 {
14287   unformat_input_t *i = vam->input;
14288   vl_api_l2_fib_table_dump_t *mp;
14289   vl_api_control_ping_t *mp_ping;
14290   u32 bd_id;
14291   u8 bd_id_set = 0;
14292   int ret;
14293
14294   /* Parse args required to build the message */
14295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14296     {
14297       if (unformat (i, "bd_id %d", &bd_id))
14298         bd_id_set = 1;
14299       else
14300         break;
14301     }
14302
14303   if (bd_id_set == 0)
14304     {
14305       errmsg ("missing bridge domain");
14306       return -99;
14307     }
14308
14309   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14310
14311   /* Get list of l2 fib entries */
14312   M (L2_FIB_TABLE_DUMP, mp);
14313
14314   mp->bd_id = ntohl (bd_id);
14315   S (mp);
14316
14317   /* Use a control ping for synchronization */
14318   MPING (CONTROL_PING, mp_ping);
14319   S (mp_ping);
14320
14321   W (ret);
14322   return ret;
14323 }
14324
14325
14326 static int
14327 api_interface_name_renumber (vat_main_t * vam)
14328 {
14329   unformat_input_t *line_input = vam->input;
14330   vl_api_interface_name_renumber_t *mp;
14331   u32 sw_if_index = ~0;
14332   u32 new_show_dev_instance = ~0;
14333   int ret;
14334
14335   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14336     {
14337       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14338                     &sw_if_index))
14339         ;
14340       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14341         ;
14342       else if (unformat (line_input, "new_show_dev_instance %d",
14343                          &new_show_dev_instance))
14344         ;
14345       else
14346         break;
14347     }
14348
14349   if (sw_if_index == ~0)
14350     {
14351       errmsg ("missing interface name or sw_if_index");
14352       return -99;
14353     }
14354
14355   if (new_show_dev_instance == ~0)
14356     {
14357       errmsg ("missing new_show_dev_instance");
14358       return -99;
14359     }
14360
14361   M (INTERFACE_NAME_RENUMBER, mp);
14362
14363   mp->sw_if_index = ntohl (sw_if_index);
14364   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14365
14366   S (mp);
14367   W (ret);
14368   return ret;
14369 }
14370
14371 static int
14372 api_ip_probe_neighbor (vat_main_t * vam)
14373 {
14374   unformat_input_t *i = vam->input;
14375   vl_api_ip_probe_neighbor_t *mp;
14376   u8 int_set = 0;
14377   u8 adr_set = 0;
14378   u8 is_ipv6 = 0;
14379   u8 dst_adr[16];
14380   u32 sw_if_index;
14381   int ret;
14382
14383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14384     {
14385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14386         int_set = 1;
14387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14388         int_set = 1;
14389       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14390         adr_set = 1;
14391       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14392         {
14393           adr_set = 1;
14394           is_ipv6 = 1;
14395         }
14396       else
14397         break;
14398     }
14399
14400   if (int_set == 0)
14401     {
14402       errmsg ("missing interface");
14403       return -99;
14404     }
14405
14406   if (adr_set == 0)
14407     {
14408       errmsg ("missing addresses");
14409       return -99;
14410     }
14411
14412   M (IP_PROBE_NEIGHBOR, mp);
14413
14414   mp->sw_if_index = ntohl (sw_if_index);
14415   mp->is_ipv6 = is_ipv6;
14416   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14417
14418   S (mp);
14419   W (ret);
14420   return ret;
14421 }
14422
14423 static int
14424 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14425 {
14426   unformat_input_t *i = vam->input;
14427   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14428   u8 mode = IP_SCAN_V46_NEIGHBORS;
14429   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14430   int ret;
14431
14432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14433     {
14434       if (unformat (i, "ip4"))
14435         mode = IP_SCAN_V4_NEIGHBORS;
14436       else if (unformat (i, "ip6"))
14437         mode = IP_SCAN_V6_NEIGHBORS;
14438       if (unformat (i, "both"))
14439         mode = IP_SCAN_V46_NEIGHBORS;
14440       else if (unformat (i, "disable"))
14441         mode = IP_SCAN_DISABLED;
14442       else if (unformat (i, "interval %d", &interval))
14443         ;
14444       else if (unformat (i, "max-time %d", &time))
14445         ;
14446       else if (unformat (i, "max-update %d", &update))
14447         ;
14448       else if (unformat (i, "delay %d", &delay))
14449         ;
14450       else if (unformat (i, "stale %d", &stale))
14451         ;
14452       else
14453         break;
14454     }
14455
14456   if (interval > 255)
14457     {
14458       errmsg ("interval cannot exceed 255 minutes.");
14459       return -99;
14460     }
14461   if (time > 255)
14462     {
14463       errmsg ("max-time cannot exceed 255 usec.");
14464       return -99;
14465     }
14466   if (update > 255)
14467     {
14468       errmsg ("max-update cannot exceed 255.");
14469       return -99;
14470     }
14471   if (delay > 255)
14472     {
14473       errmsg ("delay cannot exceed 255 msec.");
14474       return -99;
14475     }
14476   if (stale > 255)
14477     {
14478       errmsg ("stale cannot exceed 255 minutes.");
14479       return -99;
14480     }
14481
14482   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14483   mp->mode = mode;
14484   mp->scan_interval = interval;
14485   mp->max_proc_time = time;
14486   mp->max_update = update;
14487   mp->scan_int_delay = delay;
14488   mp->stale_threshold = stale;
14489
14490   S (mp);
14491   W (ret);
14492   return ret;
14493 }
14494
14495 static int
14496 api_want_ip4_arp_events (vat_main_t * vam)
14497 {
14498   unformat_input_t *line_input = vam->input;
14499   vl_api_want_ip4_arp_events_t *mp;
14500   ip4_address_t address;
14501   int address_set = 0;
14502   u32 enable_disable = 1;
14503   int ret;
14504
14505   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14506     {
14507       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14508         address_set = 1;
14509       else if (unformat (line_input, "del"))
14510         enable_disable = 0;
14511       else
14512         break;
14513     }
14514
14515   if (address_set == 0)
14516     {
14517       errmsg ("missing addresses");
14518       return -99;
14519     }
14520
14521   M (WANT_IP4_ARP_EVENTS, mp);
14522   mp->enable_disable = enable_disable;
14523   mp->pid = htonl (getpid ());
14524   mp->address = address.as_u32;
14525
14526   S (mp);
14527   W (ret);
14528   return ret;
14529 }
14530
14531 static int
14532 api_want_ip6_nd_events (vat_main_t * vam)
14533 {
14534   unformat_input_t *line_input = vam->input;
14535   vl_api_want_ip6_nd_events_t *mp;
14536   ip6_address_t address;
14537   int address_set = 0;
14538   u32 enable_disable = 1;
14539   int ret;
14540
14541   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14542     {
14543       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14544         address_set = 1;
14545       else if (unformat (line_input, "del"))
14546         enable_disable = 0;
14547       else
14548         break;
14549     }
14550
14551   if (address_set == 0)
14552     {
14553       errmsg ("missing addresses");
14554       return -99;
14555     }
14556
14557   M (WANT_IP6_ND_EVENTS, mp);
14558   mp->enable_disable = enable_disable;
14559   mp->pid = htonl (getpid ());
14560   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14561
14562   S (mp);
14563   W (ret);
14564   return ret;
14565 }
14566
14567 static int
14568 api_want_l2_macs_events (vat_main_t * vam)
14569 {
14570   unformat_input_t *line_input = vam->input;
14571   vl_api_want_l2_macs_events_t *mp;
14572   u8 enable_disable = 1;
14573   u32 scan_delay = 0;
14574   u32 max_macs_in_event = 0;
14575   u32 learn_limit = 0;
14576   int ret;
14577
14578   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14579     {
14580       if (unformat (line_input, "learn-limit %d", &learn_limit))
14581         ;
14582       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14583         ;
14584       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14585         ;
14586       else if (unformat (line_input, "disable"))
14587         enable_disable = 0;
14588       else
14589         break;
14590     }
14591
14592   M (WANT_L2_MACS_EVENTS, mp);
14593   mp->enable_disable = enable_disable;
14594   mp->pid = htonl (getpid ());
14595   mp->learn_limit = htonl (learn_limit);
14596   mp->scan_delay = (u8) scan_delay;
14597   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14598   S (mp);
14599   W (ret);
14600   return ret;
14601 }
14602
14603 static int
14604 api_input_acl_set_interface (vat_main_t * vam)
14605 {
14606   unformat_input_t *i = vam->input;
14607   vl_api_input_acl_set_interface_t *mp;
14608   u32 sw_if_index;
14609   int sw_if_index_set;
14610   u32 ip4_table_index = ~0;
14611   u32 ip6_table_index = ~0;
14612   u32 l2_table_index = ~0;
14613   u8 is_add = 1;
14614   int ret;
14615
14616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14617     {
14618       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14619         sw_if_index_set = 1;
14620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14621         sw_if_index_set = 1;
14622       else if (unformat (i, "del"))
14623         is_add = 0;
14624       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14625         ;
14626       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14627         ;
14628       else if (unformat (i, "l2-table %d", &l2_table_index))
14629         ;
14630       else
14631         {
14632           clib_warning ("parse error '%U'", format_unformat_error, i);
14633           return -99;
14634         }
14635     }
14636
14637   if (sw_if_index_set == 0)
14638     {
14639       errmsg ("missing interface name or sw_if_index");
14640       return -99;
14641     }
14642
14643   M (INPUT_ACL_SET_INTERFACE, mp);
14644
14645   mp->sw_if_index = ntohl (sw_if_index);
14646   mp->ip4_table_index = ntohl (ip4_table_index);
14647   mp->ip6_table_index = ntohl (ip6_table_index);
14648   mp->l2_table_index = ntohl (l2_table_index);
14649   mp->is_add = is_add;
14650
14651   S (mp);
14652   W (ret);
14653   return ret;
14654 }
14655
14656 static int
14657 api_output_acl_set_interface (vat_main_t * vam)
14658 {
14659   unformat_input_t *i = vam->input;
14660   vl_api_output_acl_set_interface_t *mp;
14661   u32 sw_if_index;
14662   int sw_if_index_set;
14663   u32 ip4_table_index = ~0;
14664   u32 ip6_table_index = ~0;
14665   u32 l2_table_index = ~0;
14666   u8 is_add = 1;
14667   int ret;
14668
14669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14670     {
14671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14672         sw_if_index_set = 1;
14673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14674         sw_if_index_set = 1;
14675       else if (unformat (i, "del"))
14676         is_add = 0;
14677       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14678         ;
14679       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14680         ;
14681       else if (unformat (i, "l2-table %d", &l2_table_index))
14682         ;
14683       else
14684         {
14685           clib_warning ("parse error '%U'", format_unformat_error, i);
14686           return -99;
14687         }
14688     }
14689
14690   if (sw_if_index_set == 0)
14691     {
14692       errmsg ("missing interface name or sw_if_index");
14693       return -99;
14694     }
14695
14696   M (OUTPUT_ACL_SET_INTERFACE, mp);
14697
14698   mp->sw_if_index = ntohl (sw_if_index);
14699   mp->ip4_table_index = ntohl (ip4_table_index);
14700   mp->ip6_table_index = ntohl (ip6_table_index);
14701   mp->l2_table_index = ntohl (l2_table_index);
14702   mp->is_add = is_add;
14703
14704   S (mp);
14705   W (ret);
14706   return ret;
14707 }
14708
14709 static int
14710 api_ip_address_dump (vat_main_t * vam)
14711 {
14712   unformat_input_t *i = vam->input;
14713   vl_api_ip_address_dump_t *mp;
14714   vl_api_control_ping_t *mp_ping;
14715   u32 sw_if_index = ~0;
14716   u8 sw_if_index_set = 0;
14717   u8 ipv4_set = 0;
14718   u8 ipv6_set = 0;
14719   int ret;
14720
14721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14722     {
14723       if (unformat (i, "sw_if_index %d", &sw_if_index))
14724         sw_if_index_set = 1;
14725       else
14726         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14727         sw_if_index_set = 1;
14728       else if (unformat (i, "ipv4"))
14729         ipv4_set = 1;
14730       else if (unformat (i, "ipv6"))
14731         ipv6_set = 1;
14732       else
14733         break;
14734     }
14735
14736   if (ipv4_set && ipv6_set)
14737     {
14738       errmsg ("ipv4 and ipv6 flags cannot be both set");
14739       return -99;
14740     }
14741
14742   if ((!ipv4_set) && (!ipv6_set))
14743     {
14744       errmsg ("no ipv4 nor ipv6 flag set");
14745       return -99;
14746     }
14747
14748   if (sw_if_index_set == 0)
14749     {
14750       errmsg ("missing interface name or sw_if_index");
14751       return -99;
14752     }
14753
14754   vam->current_sw_if_index = sw_if_index;
14755   vam->is_ipv6 = ipv6_set;
14756
14757   M (IP_ADDRESS_DUMP, mp);
14758   mp->sw_if_index = ntohl (sw_if_index);
14759   mp->is_ipv6 = ipv6_set;
14760   S (mp);
14761
14762   /* Use a control ping for synchronization */
14763   MPING (CONTROL_PING, mp_ping);
14764   S (mp_ping);
14765
14766   W (ret);
14767   return ret;
14768 }
14769
14770 static int
14771 api_ip_dump (vat_main_t * vam)
14772 {
14773   vl_api_ip_dump_t *mp;
14774   vl_api_control_ping_t *mp_ping;
14775   unformat_input_t *in = vam->input;
14776   int ipv4_set = 0;
14777   int ipv6_set = 0;
14778   int is_ipv6;
14779   int i;
14780   int ret;
14781
14782   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14783     {
14784       if (unformat (in, "ipv4"))
14785         ipv4_set = 1;
14786       else if (unformat (in, "ipv6"))
14787         ipv6_set = 1;
14788       else
14789         break;
14790     }
14791
14792   if (ipv4_set && ipv6_set)
14793     {
14794       errmsg ("ipv4 and ipv6 flags cannot be both set");
14795       return -99;
14796     }
14797
14798   if ((!ipv4_set) && (!ipv6_set))
14799     {
14800       errmsg ("no ipv4 nor ipv6 flag set");
14801       return -99;
14802     }
14803
14804   is_ipv6 = ipv6_set;
14805   vam->is_ipv6 = is_ipv6;
14806
14807   /* free old data */
14808   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14809     {
14810       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14811     }
14812   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14813
14814   M (IP_DUMP, mp);
14815   mp->is_ipv6 = ipv6_set;
14816   S (mp);
14817
14818   /* Use a control ping for synchronization */
14819   MPING (CONTROL_PING, mp_ping);
14820   S (mp_ping);
14821
14822   W (ret);
14823   return ret;
14824 }
14825
14826 static int
14827 api_ipsec_spd_add_del (vat_main_t * vam)
14828 {
14829   unformat_input_t *i = vam->input;
14830   vl_api_ipsec_spd_add_del_t *mp;
14831   u32 spd_id = ~0;
14832   u8 is_add = 1;
14833   int ret;
14834
14835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14836     {
14837       if (unformat (i, "spd_id %d", &spd_id))
14838         ;
14839       else if (unformat (i, "del"))
14840         is_add = 0;
14841       else
14842         {
14843           clib_warning ("parse error '%U'", format_unformat_error, i);
14844           return -99;
14845         }
14846     }
14847   if (spd_id == ~0)
14848     {
14849       errmsg ("spd_id must be set");
14850       return -99;
14851     }
14852
14853   M (IPSEC_SPD_ADD_DEL, mp);
14854
14855   mp->spd_id = ntohl (spd_id);
14856   mp->is_add = is_add;
14857
14858   S (mp);
14859   W (ret);
14860   return ret;
14861 }
14862
14863 static int
14864 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14865 {
14866   unformat_input_t *i = vam->input;
14867   vl_api_ipsec_interface_add_del_spd_t *mp;
14868   u32 sw_if_index;
14869   u8 sw_if_index_set = 0;
14870   u32 spd_id = (u32) ~ 0;
14871   u8 is_add = 1;
14872   int ret;
14873
14874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14875     {
14876       if (unformat (i, "del"))
14877         is_add = 0;
14878       else if (unformat (i, "spd_id %d", &spd_id))
14879         ;
14880       else
14881         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14882         sw_if_index_set = 1;
14883       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14884         sw_if_index_set = 1;
14885       else
14886         {
14887           clib_warning ("parse error '%U'", format_unformat_error, i);
14888           return -99;
14889         }
14890
14891     }
14892
14893   if (spd_id == (u32) ~ 0)
14894     {
14895       errmsg ("spd_id must be set");
14896       return -99;
14897     }
14898
14899   if (sw_if_index_set == 0)
14900     {
14901       errmsg ("missing interface name or sw_if_index");
14902       return -99;
14903     }
14904
14905   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14906
14907   mp->spd_id = ntohl (spd_id);
14908   mp->sw_if_index = ntohl (sw_if_index);
14909   mp->is_add = is_add;
14910
14911   S (mp);
14912   W (ret);
14913   return ret;
14914 }
14915
14916 static int
14917 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14918 {
14919   unformat_input_t *i = vam->input;
14920   vl_api_ipsec_spd_add_del_entry_t *mp;
14921   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14922   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14923   i32 priority = 0;
14924   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14925   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14926   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14927   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14928   int ret;
14929
14930   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14931   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14932   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14933   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14934   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14935   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14936
14937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14938     {
14939       if (unformat (i, "del"))
14940         is_add = 0;
14941       if (unformat (i, "outbound"))
14942         is_outbound = 1;
14943       if (unformat (i, "inbound"))
14944         is_outbound = 0;
14945       else if (unformat (i, "spd_id %d", &spd_id))
14946         ;
14947       else if (unformat (i, "sa_id %d", &sa_id))
14948         ;
14949       else if (unformat (i, "priority %d", &priority))
14950         ;
14951       else if (unformat (i, "protocol %d", &protocol))
14952         ;
14953       else if (unformat (i, "lport_start %d", &lport_start))
14954         ;
14955       else if (unformat (i, "lport_stop %d", &lport_stop))
14956         ;
14957       else if (unformat (i, "rport_start %d", &rport_start))
14958         ;
14959       else if (unformat (i, "rport_stop %d", &rport_stop))
14960         ;
14961       else
14962         if (unformat
14963             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14964         {
14965           is_ipv6 = 0;
14966           is_ip_any = 0;
14967         }
14968       else
14969         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14970         {
14971           is_ipv6 = 0;
14972           is_ip_any = 0;
14973         }
14974       else
14975         if (unformat
14976             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14977         {
14978           is_ipv6 = 0;
14979           is_ip_any = 0;
14980         }
14981       else
14982         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14983         {
14984           is_ipv6 = 0;
14985           is_ip_any = 0;
14986         }
14987       else
14988         if (unformat
14989             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14990         {
14991           is_ipv6 = 1;
14992           is_ip_any = 0;
14993         }
14994       else
14995         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14996         {
14997           is_ipv6 = 1;
14998           is_ip_any = 0;
14999         }
15000       else
15001         if (unformat
15002             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15003         {
15004           is_ipv6 = 1;
15005           is_ip_any = 0;
15006         }
15007       else
15008         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15009         {
15010           is_ipv6 = 1;
15011           is_ip_any = 0;
15012         }
15013       else
15014         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15015         {
15016           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15017             {
15018               clib_warning ("unsupported action: 'resolve'");
15019               return -99;
15020             }
15021         }
15022       else
15023         {
15024           clib_warning ("parse error '%U'", format_unformat_error, i);
15025           return -99;
15026         }
15027
15028     }
15029
15030   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15031
15032   mp->spd_id = ntohl (spd_id);
15033   mp->priority = ntohl (priority);
15034   mp->is_outbound = is_outbound;
15035
15036   mp->is_ipv6 = is_ipv6;
15037   if (is_ipv6 || is_ip_any)
15038     {
15039       clib_memcpy (mp->remote_address_start, &raddr6_start,
15040                    sizeof (ip6_address_t));
15041       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15042                    sizeof (ip6_address_t));
15043       clib_memcpy (mp->local_address_start, &laddr6_start,
15044                    sizeof (ip6_address_t));
15045       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15046                    sizeof (ip6_address_t));
15047     }
15048   else
15049     {
15050       clib_memcpy (mp->remote_address_start, &raddr4_start,
15051                    sizeof (ip4_address_t));
15052       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15053                    sizeof (ip4_address_t));
15054       clib_memcpy (mp->local_address_start, &laddr4_start,
15055                    sizeof (ip4_address_t));
15056       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15057                    sizeof (ip4_address_t));
15058     }
15059   mp->protocol = (u8) protocol;
15060   mp->local_port_start = ntohs ((u16) lport_start);
15061   mp->local_port_stop = ntohs ((u16) lport_stop);
15062   mp->remote_port_start = ntohs ((u16) rport_start);
15063   mp->remote_port_stop = ntohs ((u16) rport_stop);
15064   mp->policy = (u8) policy;
15065   mp->sa_id = ntohl (sa_id);
15066   mp->is_add = is_add;
15067   mp->is_ip_any = is_ip_any;
15068   S (mp);
15069   W (ret);
15070   return ret;
15071 }
15072
15073 static int
15074 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15075 {
15076   unformat_input_t *i = vam->input;
15077   vl_api_ipsec_sad_add_del_entry_t *mp;
15078   u32 sad_id = 0, spi = 0;
15079   u8 *ck = 0, *ik = 0;
15080   u8 is_add = 1;
15081
15082   u8 protocol = IPSEC_PROTOCOL_AH;
15083   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15084   u32 crypto_alg = 0, integ_alg = 0;
15085   ip4_address_t tun_src4;
15086   ip4_address_t tun_dst4;
15087   ip6_address_t tun_src6;
15088   ip6_address_t tun_dst6;
15089   int ret;
15090
15091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15092     {
15093       if (unformat (i, "del"))
15094         is_add = 0;
15095       else if (unformat (i, "sad_id %d", &sad_id))
15096         ;
15097       else if (unformat (i, "spi %d", &spi))
15098         ;
15099       else if (unformat (i, "esp"))
15100         protocol = IPSEC_PROTOCOL_ESP;
15101       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15102         {
15103           is_tunnel = 1;
15104           is_tunnel_ipv6 = 0;
15105         }
15106       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15107         {
15108           is_tunnel = 1;
15109           is_tunnel_ipv6 = 0;
15110         }
15111       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15112         {
15113           is_tunnel = 1;
15114           is_tunnel_ipv6 = 1;
15115         }
15116       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15117         {
15118           is_tunnel = 1;
15119           is_tunnel_ipv6 = 1;
15120         }
15121       else
15122         if (unformat
15123             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15124         {
15125           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15126               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15127             {
15128               clib_warning ("unsupported crypto-alg: '%U'",
15129                             format_ipsec_crypto_alg, crypto_alg);
15130               return -99;
15131             }
15132         }
15133       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15134         ;
15135       else
15136         if (unformat
15137             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15138         {
15139           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15140               integ_alg >= IPSEC_INTEG_N_ALG)
15141             {
15142               clib_warning ("unsupported integ-alg: '%U'",
15143                             format_ipsec_integ_alg, integ_alg);
15144               return -99;
15145             }
15146         }
15147       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15148         ;
15149       else
15150         {
15151           clib_warning ("parse error '%U'", format_unformat_error, i);
15152           return -99;
15153         }
15154
15155     }
15156
15157   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15158
15159   mp->sad_id = ntohl (sad_id);
15160   mp->is_add = is_add;
15161   mp->protocol = protocol;
15162   mp->spi = ntohl (spi);
15163   mp->is_tunnel = is_tunnel;
15164   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15165   mp->crypto_algorithm = crypto_alg;
15166   mp->integrity_algorithm = integ_alg;
15167   mp->crypto_key_length = vec_len (ck);
15168   mp->integrity_key_length = vec_len (ik);
15169
15170   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15171     mp->crypto_key_length = sizeof (mp->crypto_key);
15172
15173   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15174     mp->integrity_key_length = sizeof (mp->integrity_key);
15175
15176   if (ck)
15177     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15178   if (ik)
15179     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15180
15181   if (is_tunnel)
15182     {
15183       if (is_tunnel_ipv6)
15184         {
15185           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15186                        sizeof (ip6_address_t));
15187           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15188                        sizeof (ip6_address_t));
15189         }
15190       else
15191         {
15192           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15193                        sizeof (ip4_address_t));
15194           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15195                        sizeof (ip4_address_t));
15196         }
15197     }
15198
15199   S (mp);
15200   W (ret);
15201   return ret;
15202 }
15203
15204 static int
15205 api_ipsec_sa_set_key (vat_main_t * vam)
15206 {
15207   unformat_input_t *i = vam->input;
15208   vl_api_ipsec_sa_set_key_t *mp;
15209   u32 sa_id;
15210   u8 *ck = 0, *ik = 0;
15211   int ret;
15212
15213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15214     {
15215       if (unformat (i, "sa_id %d", &sa_id))
15216         ;
15217       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15218         ;
15219       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15220         ;
15221       else
15222         {
15223           clib_warning ("parse error '%U'", format_unformat_error, i);
15224           return -99;
15225         }
15226     }
15227
15228   M (IPSEC_SA_SET_KEY, mp);
15229
15230   mp->sa_id = ntohl (sa_id);
15231   mp->crypto_key_length = vec_len (ck);
15232   mp->integrity_key_length = vec_len (ik);
15233
15234   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15235     mp->crypto_key_length = sizeof (mp->crypto_key);
15236
15237   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15238     mp->integrity_key_length = sizeof (mp->integrity_key);
15239
15240   if (ck)
15241     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15242   if (ik)
15243     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15244
15245   S (mp);
15246   W (ret);
15247   return ret;
15248 }
15249
15250 static int
15251 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15252 {
15253   unformat_input_t *i = vam->input;
15254   vl_api_ipsec_tunnel_if_add_del_t *mp;
15255   u32 local_spi = 0, remote_spi = 0;
15256   u32 crypto_alg = 0, integ_alg = 0;
15257   u8 *lck = NULL, *rck = NULL;
15258   u8 *lik = NULL, *rik = NULL;
15259   ip4_address_t local_ip = { {0} };
15260   ip4_address_t remote_ip = { {0} };
15261   u8 is_add = 1;
15262   u8 esn = 0;
15263   u8 anti_replay = 0;
15264   u8 renumber = 0;
15265   u32 instance = ~0;
15266   int ret;
15267
15268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15269     {
15270       if (unformat (i, "del"))
15271         is_add = 0;
15272       else if (unformat (i, "esn"))
15273         esn = 1;
15274       else if (unformat (i, "anti_replay"))
15275         anti_replay = 1;
15276       else if (unformat (i, "local_spi %d", &local_spi))
15277         ;
15278       else if (unformat (i, "remote_spi %d", &remote_spi))
15279         ;
15280       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15281         ;
15282       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15283         ;
15284       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15285         ;
15286       else
15287         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15288         ;
15289       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15290         ;
15291       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15292         ;
15293       else
15294         if (unformat
15295             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15296         {
15297           if (crypto_alg < IPSEC_CRYPTO_ALG_NONE ||
15298               crypto_alg >= IPSEC_CRYPTO_N_ALG)
15299             {
15300               errmsg ("unsupported crypto-alg: '%U'\n",
15301                       format_ipsec_crypto_alg, crypto_alg);
15302               return -99;
15303             }
15304         }
15305       else
15306         if (unformat
15307             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15308         {
15309           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
15310               integ_alg >= IPSEC_INTEG_N_ALG)
15311             {
15312               errmsg ("unsupported integ-alg: '%U'\n",
15313                       format_ipsec_integ_alg, integ_alg);
15314               return -99;
15315             }
15316         }
15317       else if (unformat (i, "instance %u", &instance))
15318         renumber = 1;
15319       else
15320         {
15321           errmsg ("parse error '%U'\n", format_unformat_error, i);
15322           return -99;
15323         }
15324     }
15325
15326   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15327
15328   mp->is_add = is_add;
15329   mp->esn = esn;
15330   mp->anti_replay = anti_replay;
15331
15332   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15333   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15334
15335   mp->local_spi = htonl (local_spi);
15336   mp->remote_spi = htonl (remote_spi);
15337   mp->crypto_alg = (u8) crypto_alg;
15338
15339   mp->local_crypto_key_len = 0;
15340   if (lck)
15341     {
15342       mp->local_crypto_key_len = vec_len (lck);
15343       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15344         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15345       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15346     }
15347
15348   mp->remote_crypto_key_len = 0;
15349   if (rck)
15350     {
15351       mp->remote_crypto_key_len = vec_len (rck);
15352       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15353         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15354       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15355     }
15356
15357   mp->integ_alg = (u8) integ_alg;
15358
15359   mp->local_integ_key_len = 0;
15360   if (lik)
15361     {
15362       mp->local_integ_key_len = vec_len (lik);
15363       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15364         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15365       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15366     }
15367
15368   mp->remote_integ_key_len = 0;
15369   if (rik)
15370     {
15371       mp->remote_integ_key_len = vec_len (rik);
15372       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15373         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15374       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15375     }
15376
15377   if (renumber)
15378     {
15379       mp->renumber = renumber;
15380       mp->show_instance = ntohl (instance);
15381     }
15382
15383   S (mp);
15384   W (ret);
15385   return ret;
15386 }
15387
15388 static void
15389 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15390 {
15391   vat_main_t *vam = &vat_main;
15392
15393   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15394          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15395          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15396          "tunnel_src_addr %U tunnel_dst_addr %U "
15397          "salt %u seq_outbound %lu last_seq_inbound %lu "
15398          "replay_window %lu total_data_size %lu\n",
15399          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15400          mp->protocol,
15401          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15402          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15403          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15404          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15405          mp->tunnel_src_addr,
15406          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15407          mp->tunnel_dst_addr,
15408          ntohl (mp->salt),
15409          clib_net_to_host_u64 (mp->seq_outbound),
15410          clib_net_to_host_u64 (mp->last_seq_inbound),
15411          clib_net_to_host_u64 (mp->replay_window),
15412          clib_net_to_host_u64 (mp->total_data_size));
15413 }
15414
15415 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15416 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15417
15418 static void vl_api_ipsec_sa_details_t_handler_json
15419   (vl_api_ipsec_sa_details_t * mp)
15420 {
15421   vat_main_t *vam = &vat_main;
15422   vat_json_node_t *node = NULL;
15423   struct in_addr src_ip4, dst_ip4;
15424   struct in6_addr src_ip6, dst_ip6;
15425
15426   if (VAT_JSON_ARRAY != vam->json_tree.type)
15427     {
15428       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15429       vat_json_init_array (&vam->json_tree);
15430     }
15431   node = vat_json_array_add (&vam->json_tree);
15432
15433   vat_json_init_object (node);
15434   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15435   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15436   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15437   vat_json_object_add_uint (node, "proto", mp->protocol);
15438   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15439   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15440   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15441   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15442   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15443   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15444   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15445                              mp->crypto_key_len);
15446   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15447                              mp->integ_key_len);
15448   if (mp->is_tunnel_ip6)
15449     {
15450       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15451       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15452       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15453       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15454     }
15455   else
15456     {
15457       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15458       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15459       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15460       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15461     }
15462   vat_json_object_add_uint (node, "replay_window",
15463                             clib_net_to_host_u64 (mp->replay_window));
15464   vat_json_object_add_uint (node, "total_data_size",
15465                             clib_net_to_host_u64 (mp->total_data_size));
15466
15467 }
15468
15469 static int
15470 api_ipsec_sa_dump (vat_main_t * vam)
15471 {
15472   unformat_input_t *i = vam->input;
15473   vl_api_ipsec_sa_dump_t *mp;
15474   vl_api_control_ping_t *mp_ping;
15475   u32 sa_id = ~0;
15476   int ret;
15477
15478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15479     {
15480       if (unformat (i, "sa_id %d", &sa_id))
15481         ;
15482       else
15483         {
15484           clib_warning ("parse error '%U'", format_unformat_error, i);
15485           return -99;
15486         }
15487     }
15488
15489   M (IPSEC_SA_DUMP, mp);
15490
15491   mp->sa_id = ntohl (sa_id);
15492
15493   S (mp);
15494
15495   /* Use a control ping for synchronization */
15496   M (CONTROL_PING, mp_ping);
15497   S (mp_ping);
15498
15499   W (ret);
15500   return ret;
15501 }
15502
15503 static int
15504 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15505 {
15506   unformat_input_t *i = vam->input;
15507   vl_api_ipsec_tunnel_if_set_key_t *mp;
15508   u32 sw_if_index = ~0;
15509   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15510   u8 *key = 0;
15511   u32 alg = ~0;
15512   int ret;
15513
15514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15515     {
15516       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15517         ;
15518       else
15519         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15520         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15521       else
15522         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15523         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15524       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15525         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15526       else
15527         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15528         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15529       else if (unformat (i, "%U", unformat_hex_string, &key))
15530         ;
15531       else
15532         {
15533           clib_warning ("parse error '%U'", format_unformat_error, i);
15534           return -99;
15535         }
15536     }
15537
15538   if (sw_if_index == ~0)
15539     {
15540       errmsg ("interface must be specified");
15541       return -99;
15542     }
15543
15544   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15545     {
15546       errmsg ("key type must be specified");
15547       return -99;
15548     }
15549
15550   if (alg == ~0)
15551     {
15552       errmsg ("algorithm must be specified");
15553       return -99;
15554     }
15555
15556   if (vec_len (key) == 0)
15557     {
15558       errmsg ("key must be specified");
15559       return -99;
15560     }
15561
15562   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15563
15564   mp->sw_if_index = htonl (sw_if_index);
15565   mp->alg = alg;
15566   mp->key_type = key_type;
15567   mp->key_len = vec_len (key);
15568   clib_memcpy (mp->key, key, vec_len (key));
15569
15570   S (mp);
15571   W (ret);
15572
15573   return ret;
15574 }
15575
15576 static int
15577 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15578 {
15579   unformat_input_t *i = vam->input;
15580   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15581   u32 sw_if_index = ~0;
15582   u32 sa_id = ~0;
15583   u8 is_outbound = (u8) ~ 0;
15584   int ret;
15585
15586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15587     {
15588       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15589         ;
15590       else if (unformat (i, "sa_id %d", &sa_id))
15591         ;
15592       else if (unformat (i, "outbound"))
15593         is_outbound = 1;
15594       else if (unformat (i, "inbound"))
15595         is_outbound = 0;
15596       else
15597         {
15598           clib_warning ("parse error '%U'", format_unformat_error, i);
15599           return -99;
15600         }
15601     }
15602
15603   if (sw_if_index == ~0)
15604     {
15605       errmsg ("interface must be specified");
15606       return -99;
15607     }
15608
15609   if (sa_id == ~0)
15610     {
15611       errmsg ("SA ID must be specified");
15612       return -99;
15613     }
15614
15615   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15616
15617   mp->sw_if_index = htonl (sw_if_index);
15618   mp->sa_id = htonl (sa_id);
15619   mp->is_outbound = is_outbound;
15620
15621   S (mp);
15622   W (ret);
15623
15624   return ret;
15625 }
15626
15627 static int
15628 api_ikev2_profile_add_del (vat_main_t * vam)
15629 {
15630   unformat_input_t *i = vam->input;
15631   vl_api_ikev2_profile_add_del_t *mp;
15632   u8 is_add = 1;
15633   u8 *name = 0;
15634   int ret;
15635
15636   const char *valid_chars = "a-zA-Z0-9_";
15637
15638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15639     {
15640       if (unformat (i, "del"))
15641         is_add = 0;
15642       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15643         vec_add1 (name, 0);
15644       else
15645         {
15646           errmsg ("parse error '%U'", format_unformat_error, i);
15647           return -99;
15648         }
15649     }
15650
15651   if (!vec_len (name))
15652     {
15653       errmsg ("profile name must be specified");
15654       return -99;
15655     }
15656
15657   if (vec_len (name) > 64)
15658     {
15659       errmsg ("profile name too long");
15660       return -99;
15661     }
15662
15663   M (IKEV2_PROFILE_ADD_DEL, mp);
15664
15665   clib_memcpy (mp->name, name, vec_len (name));
15666   mp->is_add = is_add;
15667   vec_free (name);
15668
15669   S (mp);
15670   W (ret);
15671   return ret;
15672 }
15673
15674 static int
15675 api_ikev2_profile_set_auth (vat_main_t * vam)
15676 {
15677   unformat_input_t *i = vam->input;
15678   vl_api_ikev2_profile_set_auth_t *mp;
15679   u8 *name = 0;
15680   u8 *data = 0;
15681   u32 auth_method = 0;
15682   u8 is_hex = 0;
15683   int ret;
15684
15685   const char *valid_chars = "a-zA-Z0-9_";
15686
15687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15688     {
15689       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15690         vec_add1 (name, 0);
15691       else if (unformat (i, "auth_method %U",
15692                          unformat_ikev2_auth_method, &auth_method))
15693         ;
15694       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15695         is_hex = 1;
15696       else if (unformat (i, "auth_data %v", &data))
15697         ;
15698       else
15699         {
15700           errmsg ("parse error '%U'", format_unformat_error, i);
15701           return -99;
15702         }
15703     }
15704
15705   if (!vec_len (name))
15706     {
15707       errmsg ("profile name must be specified");
15708       return -99;
15709     }
15710
15711   if (vec_len (name) > 64)
15712     {
15713       errmsg ("profile name too long");
15714       return -99;
15715     }
15716
15717   if (!vec_len (data))
15718     {
15719       errmsg ("auth_data must be specified");
15720       return -99;
15721     }
15722
15723   if (!auth_method)
15724     {
15725       errmsg ("auth_method must be specified");
15726       return -99;
15727     }
15728
15729   M (IKEV2_PROFILE_SET_AUTH, mp);
15730
15731   mp->is_hex = is_hex;
15732   mp->auth_method = (u8) auth_method;
15733   mp->data_len = vec_len (data);
15734   clib_memcpy (mp->name, name, vec_len (name));
15735   clib_memcpy (mp->data, data, vec_len (data));
15736   vec_free (name);
15737   vec_free (data);
15738
15739   S (mp);
15740   W (ret);
15741   return ret;
15742 }
15743
15744 static int
15745 api_ikev2_profile_set_id (vat_main_t * vam)
15746 {
15747   unformat_input_t *i = vam->input;
15748   vl_api_ikev2_profile_set_id_t *mp;
15749   u8 *name = 0;
15750   u8 *data = 0;
15751   u8 is_local = 0;
15752   u32 id_type = 0;
15753   ip4_address_t ip4;
15754   int ret;
15755
15756   const char *valid_chars = "a-zA-Z0-9_";
15757
15758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15759     {
15760       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15761         vec_add1 (name, 0);
15762       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15763         ;
15764       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15765         {
15766           data = vec_new (u8, 4);
15767           clib_memcpy (data, ip4.as_u8, 4);
15768         }
15769       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15770         ;
15771       else if (unformat (i, "id_data %v", &data))
15772         ;
15773       else if (unformat (i, "local"))
15774         is_local = 1;
15775       else if (unformat (i, "remote"))
15776         is_local = 0;
15777       else
15778         {
15779           errmsg ("parse error '%U'", format_unformat_error, i);
15780           return -99;
15781         }
15782     }
15783
15784   if (!vec_len (name))
15785     {
15786       errmsg ("profile name must be specified");
15787       return -99;
15788     }
15789
15790   if (vec_len (name) > 64)
15791     {
15792       errmsg ("profile name too long");
15793       return -99;
15794     }
15795
15796   if (!vec_len (data))
15797     {
15798       errmsg ("id_data must be specified");
15799       return -99;
15800     }
15801
15802   if (!id_type)
15803     {
15804       errmsg ("id_type must be specified");
15805       return -99;
15806     }
15807
15808   M (IKEV2_PROFILE_SET_ID, mp);
15809
15810   mp->is_local = is_local;
15811   mp->id_type = (u8) id_type;
15812   mp->data_len = vec_len (data);
15813   clib_memcpy (mp->name, name, vec_len (name));
15814   clib_memcpy (mp->data, data, vec_len (data));
15815   vec_free (name);
15816   vec_free (data);
15817
15818   S (mp);
15819   W (ret);
15820   return ret;
15821 }
15822
15823 static int
15824 api_ikev2_profile_set_ts (vat_main_t * vam)
15825 {
15826   unformat_input_t *i = vam->input;
15827   vl_api_ikev2_profile_set_ts_t *mp;
15828   u8 *name = 0;
15829   u8 is_local = 0;
15830   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15831   ip4_address_t start_addr, end_addr;
15832
15833   const char *valid_chars = "a-zA-Z0-9_";
15834   int ret;
15835
15836   start_addr.as_u32 = 0;
15837   end_addr.as_u32 = (u32) ~ 0;
15838
15839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15840     {
15841       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15842         vec_add1 (name, 0);
15843       else if (unformat (i, "protocol %d", &proto))
15844         ;
15845       else if (unformat (i, "start_port %d", &start_port))
15846         ;
15847       else if (unformat (i, "end_port %d", &end_port))
15848         ;
15849       else
15850         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15851         ;
15852       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15853         ;
15854       else if (unformat (i, "local"))
15855         is_local = 1;
15856       else if (unformat (i, "remote"))
15857         is_local = 0;
15858       else
15859         {
15860           errmsg ("parse error '%U'", format_unformat_error, i);
15861           return -99;
15862         }
15863     }
15864
15865   if (!vec_len (name))
15866     {
15867       errmsg ("profile name must be specified");
15868       return -99;
15869     }
15870
15871   if (vec_len (name) > 64)
15872     {
15873       errmsg ("profile name too long");
15874       return -99;
15875     }
15876
15877   M (IKEV2_PROFILE_SET_TS, mp);
15878
15879   mp->is_local = is_local;
15880   mp->proto = (u8) proto;
15881   mp->start_port = (u16) start_port;
15882   mp->end_port = (u16) end_port;
15883   mp->start_addr = start_addr.as_u32;
15884   mp->end_addr = end_addr.as_u32;
15885   clib_memcpy (mp->name, name, vec_len (name));
15886   vec_free (name);
15887
15888   S (mp);
15889   W (ret);
15890   return ret;
15891 }
15892
15893 static int
15894 api_ikev2_set_local_key (vat_main_t * vam)
15895 {
15896   unformat_input_t *i = vam->input;
15897   vl_api_ikev2_set_local_key_t *mp;
15898   u8 *file = 0;
15899   int ret;
15900
15901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15902     {
15903       if (unformat (i, "file %v", &file))
15904         vec_add1 (file, 0);
15905       else
15906         {
15907           errmsg ("parse error '%U'", format_unformat_error, i);
15908           return -99;
15909         }
15910     }
15911
15912   if (!vec_len (file))
15913     {
15914       errmsg ("RSA key file must be specified");
15915       return -99;
15916     }
15917
15918   if (vec_len (file) > 256)
15919     {
15920       errmsg ("file name too long");
15921       return -99;
15922     }
15923
15924   M (IKEV2_SET_LOCAL_KEY, mp);
15925
15926   clib_memcpy (mp->key_file, file, vec_len (file));
15927   vec_free (file);
15928
15929   S (mp);
15930   W (ret);
15931   return ret;
15932 }
15933
15934 static int
15935 api_ikev2_set_responder (vat_main_t * vam)
15936 {
15937   unformat_input_t *i = vam->input;
15938   vl_api_ikev2_set_responder_t *mp;
15939   int ret;
15940   u8 *name = 0;
15941   u32 sw_if_index = ~0;
15942   ip4_address_t address;
15943
15944   const char *valid_chars = "a-zA-Z0-9_";
15945
15946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15947     {
15948       if (unformat
15949           (i, "%U interface %d address %U", unformat_token, valid_chars,
15950            &name, &sw_if_index, unformat_ip4_address, &address))
15951         vec_add1 (name, 0);
15952       else
15953         {
15954           errmsg ("parse error '%U'", format_unformat_error, i);
15955           return -99;
15956         }
15957     }
15958
15959   if (!vec_len (name))
15960     {
15961       errmsg ("profile name must be specified");
15962       return -99;
15963     }
15964
15965   if (vec_len (name) > 64)
15966     {
15967       errmsg ("profile name too long");
15968       return -99;
15969     }
15970
15971   M (IKEV2_SET_RESPONDER, mp);
15972
15973   clib_memcpy (mp->name, name, vec_len (name));
15974   vec_free (name);
15975
15976   mp->sw_if_index = sw_if_index;
15977   clib_memcpy (mp->address, &address, sizeof (address));
15978
15979   S (mp);
15980   W (ret);
15981   return ret;
15982 }
15983
15984 static int
15985 api_ikev2_set_ike_transforms (vat_main_t * vam)
15986 {
15987   unformat_input_t *i = vam->input;
15988   vl_api_ikev2_set_ike_transforms_t *mp;
15989   int ret;
15990   u8 *name = 0;
15991   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15992
15993   const char *valid_chars = "a-zA-Z0-9_";
15994
15995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15996     {
15997       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15998                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15999         vec_add1 (name, 0);
16000       else
16001         {
16002           errmsg ("parse error '%U'", format_unformat_error, i);
16003           return -99;
16004         }
16005     }
16006
16007   if (!vec_len (name))
16008     {
16009       errmsg ("profile name must be specified");
16010       return -99;
16011     }
16012
16013   if (vec_len (name) > 64)
16014     {
16015       errmsg ("profile name too long");
16016       return -99;
16017     }
16018
16019   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16020
16021   clib_memcpy (mp->name, name, vec_len (name));
16022   vec_free (name);
16023   mp->crypto_alg = crypto_alg;
16024   mp->crypto_key_size = crypto_key_size;
16025   mp->integ_alg = integ_alg;
16026   mp->dh_group = dh_group;
16027
16028   S (mp);
16029   W (ret);
16030   return ret;
16031 }
16032
16033
16034 static int
16035 api_ikev2_set_esp_transforms (vat_main_t * vam)
16036 {
16037   unformat_input_t *i = vam->input;
16038   vl_api_ikev2_set_esp_transforms_t *mp;
16039   int ret;
16040   u8 *name = 0;
16041   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16042
16043   const char *valid_chars = "a-zA-Z0-9_";
16044
16045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16046     {
16047       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16048                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16049         vec_add1 (name, 0);
16050       else
16051         {
16052           errmsg ("parse error '%U'", format_unformat_error, i);
16053           return -99;
16054         }
16055     }
16056
16057   if (!vec_len (name))
16058     {
16059       errmsg ("profile name must be specified");
16060       return -99;
16061     }
16062
16063   if (vec_len (name) > 64)
16064     {
16065       errmsg ("profile name too long");
16066       return -99;
16067     }
16068
16069   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16070
16071   clib_memcpy (mp->name, name, vec_len (name));
16072   vec_free (name);
16073   mp->crypto_alg = crypto_alg;
16074   mp->crypto_key_size = crypto_key_size;
16075   mp->integ_alg = integ_alg;
16076   mp->dh_group = dh_group;
16077
16078   S (mp);
16079   W (ret);
16080   return ret;
16081 }
16082
16083 static int
16084 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16085 {
16086   unformat_input_t *i = vam->input;
16087   vl_api_ikev2_set_sa_lifetime_t *mp;
16088   int ret;
16089   u8 *name = 0;
16090   u64 lifetime, lifetime_maxdata;
16091   u32 lifetime_jitter, handover;
16092
16093   const char *valid_chars = "a-zA-Z0-9_";
16094
16095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16096     {
16097       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16098                     &lifetime, &lifetime_jitter, &handover,
16099                     &lifetime_maxdata))
16100         vec_add1 (name, 0);
16101       else
16102         {
16103           errmsg ("parse error '%U'", format_unformat_error, i);
16104           return -99;
16105         }
16106     }
16107
16108   if (!vec_len (name))
16109     {
16110       errmsg ("profile name must be specified");
16111       return -99;
16112     }
16113
16114   if (vec_len (name) > 64)
16115     {
16116       errmsg ("profile name too long");
16117       return -99;
16118     }
16119
16120   M (IKEV2_SET_SA_LIFETIME, mp);
16121
16122   clib_memcpy (mp->name, name, vec_len (name));
16123   vec_free (name);
16124   mp->lifetime = lifetime;
16125   mp->lifetime_jitter = lifetime_jitter;
16126   mp->handover = handover;
16127   mp->lifetime_maxdata = lifetime_maxdata;
16128
16129   S (mp);
16130   W (ret);
16131   return ret;
16132 }
16133
16134 static int
16135 api_ikev2_initiate_sa_init (vat_main_t * vam)
16136 {
16137   unformat_input_t *i = vam->input;
16138   vl_api_ikev2_initiate_sa_init_t *mp;
16139   int ret;
16140   u8 *name = 0;
16141
16142   const char *valid_chars = "a-zA-Z0-9_";
16143
16144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16145     {
16146       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16147         vec_add1 (name, 0);
16148       else
16149         {
16150           errmsg ("parse error '%U'", format_unformat_error, i);
16151           return -99;
16152         }
16153     }
16154
16155   if (!vec_len (name))
16156     {
16157       errmsg ("profile name must be specified");
16158       return -99;
16159     }
16160
16161   if (vec_len (name) > 64)
16162     {
16163       errmsg ("profile name too long");
16164       return -99;
16165     }
16166
16167   M (IKEV2_INITIATE_SA_INIT, mp);
16168
16169   clib_memcpy (mp->name, name, vec_len (name));
16170   vec_free (name);
16171
16172   S (mp);
16173   W (ret);
16174   return ret;
16175 }
16176
16177 static int
16178 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16179 {
16180   unformat_input_t *i = vam->input;
16181   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16182   int ret;
16183   u64 ispi;
16184
16185
16186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16187     {
16188       if (unformat (i, "%lx", &ispi))
16189         ;
16190       else
16191         {
16192           errmsg ("parse error '%U'", format_unformat_error, i);
16193           return -99;
16194         }
16195     }
16196
16197   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16198
16199   mp->ispi = ispi;
16200
16201   S (mp);
16202   W (ret);
16203   return ret;
16204 }
16205
16206 static int
16207 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16208 {
16209   unformat_input_t *i = vam->input;
16210   vl_api_ikev2_initiate_del_child_sa_t *mp;
16211   int ret;
16212   u32 ispi;
16213
16214
16215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16216     {
16217       if (unformat (i, "%x", &ispi))
16218         ;
16219       else
16220         {
16221           errmsg ("parse error '%U'", format_unformat_error, i);
16222           return -99;
16223         }
16224     }
16225
16226   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16227
16228   mp->ispi = ispi;
16229
16230   S (mp);
16231   W (ret);
16232   return ret;
16233 }
16234
16235 static int
16236 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16237 {
16238   unformat_input_t *i = vam->input;
16239   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16240   int ret;
16241   u32 ispi;
16242
16243
16244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat (i, "%x", &ispi))
16247         ;
16248       else
16249         {
16250           errmsg ("parse error '%U'", format_unformat_error, i);
16251           return -99;
16252         }
16253     }
16254
16255   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16256
16257   mp->ispi = ispi;
16258
16259   S (mp);
16260   W (ret);
16261   return ret;
16262 }
16263
16264 /*
16265  * MAP
16266  */
16267 static int
16268 api_map_add_domain (vat_main_t * vam)
16269 {
16270   unformat_input_t *i = vam->input;
16271   vl_api_map_add_domain_t *mp;
16272
16273   ip4_address_t ip4_prefix;
16274   ip6_address_t ip6_prefix;
16275   ip6_address_t ip6_src;
16276   u32 num_m_args = 0;
16277   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
16278     0, psid_length = 0;
16279   u8 is_translation = 0;
16280   u32 mtu = 0;
16281   u32 ip6_src_len = 128;
16282   int ret;
16283
16284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16285     {
16286       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
16287                     &ip4_prefix, &ip4_prefix_len))
16288         num_m_args++;
16289       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
16290                          &ip6_prefix, &ip6_prefix_len))
16291         num_m_args++;
16292       else
16293         if (unformat
16294             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
16295              &ip6_src_len))
16296         num_m_args++;
16297       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
16298         num_m_args++;
16299       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
16300         num_m_args++;
16301       else if (unformat (i, "psid-offset %d", &psid_offset))
16302         num_m_args++;
16303       else if (unformat (i, "psid-len %d", &psid_length))
16304         num_m_args++;
16305       else if (unformat (i, "mtu %d", &mtu))
16306         num_m_args++;
16307       else if (unformat (i, "map-t"))
16308         is_translation = 1;
16309       else
16310         {
16311           clib_warning ("parse error '%U'", format_unformat_error, i);
16312           return -99;
16313         }
16314     }
16315
16316   if (num_m_args < 3)
16317     {
16318       errmsg ("mandatory argument(s) missing");
16319       return -99;
16320     }
16321
16322   /* Construct the API message */
16323   M (MAP_ADD_DOMAIN, mp);
16324
16325   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
16326   mp->ip4_prefix_len = ip4_prefix_len;
16327
16328   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
16329   mp->ip6_prefix_len = ip6_prefix_len;
16330
16331   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
16332   mp->ip6_src_prefix_len = ip6_src_len;
16333
16334   mp->ea_bits_len = ea_bits_len;
16335   mp->psid_offset = psid_offset;
16336   mp->psid_length = psid_length;
16337   mp->is_translation = is_translation;
16338   mp->mtu = htons (mtu);
16339
16340   /* send it... */
16341   S (mp);
16342
16343   /* Wait for a reply, return good/bad news  */
16344   W (ret);
16345   return ret;
16346 }
16347
16348 static int
16349 api_map_del_domain (vat_main_t * vam)
16350 {
16351   unformat_input_t *i = vam->input;
16352   vl_api_map_del_domain_t *mp;
16353
16354   u32 num_m_args = 0;
16355   u32 index;
16356   int ret;
16357
16358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16359     {
16360       if (unformat (i, "index %d", &index))
16361         num_m_args++;
16362       else
16363         {
16364           clib_warning ("parse error '%U'", format_unformat_error, i);
16365           return -99;
16366         }
16367     }
16368
16369   if (num_m_args != 1)
16370     {
16371       errmsg ("mandatory argument(s) missing");
16372       return -99;
16373     }
16374
16375   /* Construct the API message */
16376   M (MAP_DEL_DOMAIN, mp);
16377
16378   mp->index = ntohl (index);
16379
16380   /* send it... */
16381   S (mp);
16382
16383   /* Wait for a reply, return good/bad news  */
16384   W (ret);
16385   return ret;
16386 }
16387
16388 static int
16389 api_map_add_del_rule (vat_main_t * vam)
16390 {
16391   unformat_input_t *i = vam->input;
16392   vl_api_map_add_del_rule_t *mp;
16393   u8 is_add = 1;
16394   ip6_address_t ip6_dst;
16395   u32 num_m_args = 0, index, psid = 0;
16396   int ret;
16397
16398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16399     {
16400       if (unformat (i, "index %d", &index))
16401         num_m_args++;
16402       else if (unformat (i, "psid %d", &psid))
16403         num_m_args++;
16404       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
16405         num_m_args++;
16406       else if (unformat (i, "del"))
16407         {
16408           is_add = 0;
16409         }
16410       else
16411         {
16412           clib_warning ("parse error '%U'", format_unformat_error, i);
16413           return -99;
16414         }
16415     }
16416
16417   /* Construct the API message */
16418   M (MAP_ADD_DEL_RULE, mp);
16419
16420   mp->index = ntohl (index);
16421   mp->is_add = is_add;
16422   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
16423   mp->psid = ntohs (psid);
16424
16425   /* send it... */
16426   S (mp);
16427
16428   /* Wait for a reply, return good/bad news  */
16429   W (ret);
16430   return ret;
16431 }
16432
16433 static int
16434 api_map_domain_dump (vat_main_t * vam)
16435 {
16436   vl_api_map_domain_dump_t *mp;
16437   vl_api_control_ping_t *mp_ping;
16438   int ret;
16439
16440   /* Construct the API message */
16441   M (MAP_DOMAIN_DUMP, mp);
16442
16443   /* send it... */
16444   S (mp);
16445
16446   /* Use a control ping for synchronization */
16447   MPING (CONTROL_PING, mp_ping);
16448   S (mp_ping);
16449
16450   W (ret);
16451   return ret;
16452 }
16453
16454 static int
16455 api_map_rule_dump (vat_main_t * vam)
16456 {
16457   unformat_input_t *i = vam->input;
16458   vl_api_map_rule_dump_t *mp;
16459   vl_api_control_ping_t *mp_ping;
16460   u32 domain_index = ~0;
16461   int ret;
16462
16463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16464     {
16465       if (unformat (i, "index %u", &domain_index))
16466         ;
16467       else
16468         break;
16469     }
16470
16471   if (domain_index == ~0)
16472     {
16473       clib_warning ("parse error: domain index expected");
16474       return -99;
16475     }
16476
16477   /* Construct the API message */
16478   M (MAP_RULE_DUMP, mp);
16479
16480   mp->domain_index = htonl (domain_index);
16481
16482   /* send it... */
16483   S (mp);
16484
16485   /* Use a control ping for synchronization */
16486   MPING (CONTROL_PING, mp_ping);
16487   S (mp_ping);
16488
16489   W (ret);
16490   return ret;
16491 }
16492
16493 static void vl_api_map_add_domain_reply_t_handler
16494   (vl_api_map_add_domain_reply_t * mp)
16495 {
16496   vat_main_t *vam = &vat_main;
16497   i32 retval = ntohl (mp->retval);
16498
16499   if (vam->async_mode)
16500     {
16501       vam->async_errors += (retval < 0);
16502     }
16503   else
16504     {
16505       vam->retval = retval;
16506       vam->result_ready = 1;
16507     }
16508 }
16509
16510 static void vl_api_map_add_domain_reply_t_handler_json
16511   (vl_api_map_add_domain_reply_t * mp)
16512 {
16513   vat_main_t *vam = &vat_main;
16514   vat_json_node_t node;
16515
16516   vat_json_init_object (&node);
16517   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
16518   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
16519
16520   vat_json_print (vam->ofp, &node);
16521   vat_json_free (&node);
16522
16523   vam->retval = ntohl (mp->retval);
16524   vam->result_ready = 1;
16525 }
16526
16527 static int
16528 api_get_first_msg_id (vat_main_t * vam)
16529 {
16530   vl_api_get_first_msg_id_t *mp;
16531   unformat_input_t *i = vam->input;
16532   u8 *name;
16533   u8 name_set = 0;
16534   int ret;
16535
16536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16537     {
16538       if (unformat (i, "client %s", &name))
16539         name_set = 1;
16540       else
16541         break;
16542     }
16543
16544   if (name_set == 0)
16545     {
16546       errmsg ("missing client name");
16547       return -99;
16548     }
16549   vec_add1 (name, 0);
16550
16551   if (vec_len (name) > 63)
16552     {
16553       errmsg ("client name too long");
16554       return -99;
16555     }
16556
16557   M (GET_FIRST_MSG_ID, mp);
16558   clib_memcpy (mp->name, name, vec_len (name));
16559   S (mp);
16560   W (ret);
16561   return ret;
16562 }
16563
16564 static int
16565 api_cop_interface_enable_disable (vat_main_t * vam)
16566 {
16567   unformat_input_t *line_input = vam->input;
16568   vl_api_cop_interface_enable_disable_t *mp;
16569   u32 sw_if_index = ~0;
16570   u8 enable_disable = 1;
16571   int ret;
16572
16573   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16574     {
16575       if (unformat (line_input, "disable"))
16576         enable_disable = 0;
16577       if (unformat (line_input, "enable"))
16578         enable_disable = 1;
16579       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16580                          vam, &sw_if_index))
16581         ;
16582       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16583         ;
16584       else
16585         break;
16586     }
16587
16588   if (sw_if_index == ~0)
16589     {
16590       errmsg ("missing interface name or sw_if_index");
16591       return -99;
16592     }
16593
16594   /* Construct the API message */
16595   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16596   mp->sw_if_index = ntohl (sw_if_index);
16597   mp->enable_disable = enable_disable;
16598
16599   /* send it... */
16600   S (mp);
16601   /* Wait for the reply */
16602   W (ret);
16603   return ret;
16604 }
16605
16606 static int
16607 api_cop_whitelist_enable_disable (vat_main_t * vam)
16608 {
16609   unformat_input_t *line_input = vam->input;
16610   vl_api_cop_whitelist_enable_disable_t *mp;
16611   u32 sw_if_index = ~0;
16612   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16613   u32 fib_id = 0;
16614   int ret;
16615
16616   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16617     {
16618       if (unformat (line_input, "ip4"))
16619         ip4 = 1;
16620       else if (unformat (line_input, "ip6"))
16621         ip6 = 1;
16622       else if (unformat (line_input, "default"))
16623         default_cop = 1;
16624       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16625                          vam, &sw_if_index))
16626         ;
16627       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16628         ;
16629       else if (unformat (line_input, "fib-id %d", &fib_id))
16630         ;
16631       else
16632         break;
16633     }
16634
16635   if (sw_if_index == ~0)
16636     {
16637       errmsg ("missing interface name or sw_if_index");
16638       return -99;
16639     }
16640
16641   /* Construct the API message */
16642   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16643   mp->sw_if_index = ntohl (sw_if_index);
16644   mp->fib_id = ntohl (fib_id);
16645   mp->ip4 = ip4;
16646   mp->ip6 = ip6;
16647   mp->default_cop = default_cop;
16648
16649   /* send it... */
16650   S (mp);
16651   /* Wait for the reply */
16652   W (ret);
16653   return ret;
16654 }
16655
16656 static int
16657 api_get_node_graph (vat_main_t * vam)
16658 {
16659   vl_api_get_node_graph_t *mp;
16660   int ret;
16661
16662   M (GET_NODE_GRAPH, mp);
16663
16664   /* send it... */
16665   S (mp);
16666   /* Wait for the reply */
16667   W (ret);
16668   return ret;
16669 }
16670
16671 /* *INDENT-OFF* */
16672 /** Used for parsing LISP eids */
16673 typedef CLIB_PACKED(struct{
16674   u8 addr[16];   /**< eid address */
16675   u32 len;       /**< prefix length if IP */
16676   u8 type;      /**< type of eid */
16677 }) lisp_eid_vat_t;
16678 /* *INDENT-ON* */
16679
16680 static uword
16681 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16682 {
16683   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16684
16685   memset (a, 0, sizeof (a[0]));
16686
16687   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16688     {
16689       a->type = 0;              /* ipv4 type */
16690     }
16691   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16692     {
16693       a->type = 1;              /* ipv6 type */
16694     }
16695   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16696     {
16697       a->type = 2;              /* mac type */
16698     }
16699   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16700     {
16701       a->type = 3;              /* NSH type */
16702       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16703       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16704     }
16705   else
16706     {
16707       return 0;
16708     }
16709
16710   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16711     {
16712       return 0;
16713     }
16714
16715   return 1;
16716 }
16717
16718 static int
16719 lisp_eid_size_vat (u8 type)
16720 {
16721   switch (type)
16722     {
16723     case 0:
16724       return 4;
16725     case 1:
16726       return 16;
16727     case 2:
16728       return 6;
16729     case 3:
16730       return 5;
16731     }
16732   return 0;
16733 }
16734
16735 static void
16736 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16737 {
16738   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16739 }
16740
16741 static int
16742 api_one_add_del_locator_set (vat_main_t * vam)
16743 {
16744   unformat_input_t *input = vam->input;
16745   vl_api_one_add_del_locator_set_t *mp;
16746   u8 is_add = 1;
16747   u8 *locator_set_name = NULL;
16748   u8 locator_set_name_set = 0;
16749   vl_api_local_locator_t locator, *locators = 0;
16750   u32 sw_if_index, priority, weight;
16751   u32 data_len = 0;
16752
16753   int ret;
16754   /* Parse args required to build the message */
16755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16756     {
16757       if (unformat (input, "del"))
16758         {
16759           is_add = 0;
16760         }
16761       else if (unformat (input, "locator-set %s", &locator_set_name))
16762         {
16763           locator_set_name_set = 1;
16764         }
16765       else if (unformat (input, "sw_if_index %u p %u w %u",
16766                          &sw_if_index, &priority, &weight))
16767         {
16768           locator.sw_if_index = htonl (sw_if_index);
16769           locator.priority = priority;
16770           locator.weight = weight;
16771           vec_add1 (locators, locator);
16772         }
16773       else
16774         if (unformat
16775             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16776              &sw_if_index, &priority, &weight))
16777         {
16778           locator.sw_if_index = htonl (sw_if_index);
16779           locator.priority = priority;
16780           locator.weight = weight;
16781           vec_add1 (locators, locator);
16782         }
16783       else
16784         break;
16785     }
16786
16787   if (locator_set_name_set == 0)
16788     {
16789       errmsg ("missing locator-set name");
16790       vec_free (locators);
16791       return -99;
16792     }
16793
16794   if (vec_len (locator_set_name) > 64)
16795     {
16796       errmsg ("locator-set name too long");
16797       vec_free (locator_set_name);
16798       vec_free (locators);
16799       return -99;
16800     }
16801   vec_add1 (locator_set_name, 0);
16802
16803   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16804
16805   /* Construct the API message */
16806   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16807
16808   mp->is_add = is_add;
16809   clib_memcpy (mp->locator_set_name, locator_set_name,
16810                vec_len (locator_set_name));
16811   vec_free (locator_set_name);
16812
16813   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16814   if (locators)
16815     clib_memcpy (mp->locators, locators, data_len);
16816   vec_free (locators);
16817
16818   /* send it... */
16819   S (mp);
16820
16821   /* Wait for a reply... */
16822   W (ret);
16823   return ret;
16824 }
16825
16826 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16827
16828 static int
16829 api_one_add_del_locator (vat_main_t * vam)
16830 {
16831   unformat_input_t *input = vam->input;
16832   vl_api_one_add_del_locator_t *mp;
16833   u32 tmp_if_index = ~0;
16834   u32 sw_if_index = ~0;
16835   u8 sw_if_index_set = 0;
16836   u8 sw_if_index_if_name_set = 0;
16837   u32 priority = ~0;
16838   u8 priority_set = 0;
16839   u32 weight = ~0;
16840   u8 weight_set = 0;
16841   u8 is_add = 1;
16842   u8 *locator_set_name = NULL;
16843   u8 locator_set_name_set = 0;
16844   int ret;
16845
16846   /* Parse args required to build the message */
16847   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16848     {
16849       if (unformat (input, "del"))
16850         {
16851           is_add = 0;
16852         }
16853       else if (unformat (input, "locator-set %s", &locator_set_name))
16854         {
16855           locator_set_name_set = 1;
16856         }
16857       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16858                          &tmp_if_index))
16859         {
16860           sw_if_index_if_name_set = 1;
16861           sw_if_index = tmp_if_index;
16862         }
16863       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16864         {
16865           sw_if_index_set = 1;
16866           sw_if_index = tmp_if_index;
16867         }
16868       else if (unformat (input, "p %d", &priority))
16869         {
16870           priority_set = 1;
16871         }
16872       else if (unformat (input, "w %d", &weight))
16873         {
16874           weight_set = 1;
16875         }
16876       else
16877         break;
16878     }
16879
16880   if (locator_set_name_set == 0)
16881     {
16882       errmsg ("missing locator-set name");
16883       return -99;
16884     }
16885
16886   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16887     {
16888       errmsg ("missing sw_if_index");
16889       vec_free (locator_set_name);
16890       return -99;
16891     }
16892
16893   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16894     {
16895       errmsg ("cannot use both params interface name and sw_if_index");
16896       vec_free (locator_set_name);
16897       return -99;
16898     }
16899
16900   if (priority_set == 0)
16901     {
16902       errmsg ("missing locator-set priority");
16903       vec_free (locator_set_name);
16904       return -99;
16905     }
16906
16907   if (weight_set == 0)
16908     {
16909       errmsg ("missing locator-set weight");
16910       vec_free (locator_set_name);
16911       return -99;
16912     }
16913
16914   if (vec_len (locator_set_name) > 64)
16915     {
16916       errmsg ("locator-set name too long");
16917       vec_free (locator_set_name);
16918       return -99;
16919     }
16920   vec_add1 (locator_set_name, 0);
16921
16922   /* Construct the API message */
16923   M (ONE_ADD_DEL_LOCATOR, mp);
16924
16925   mp->is_add = is_add;
16926   mp->sw_if_index = ntohl (sw_if_index);
16927   mp->priority = priority;
16928   mp->weight = weight;
16929   clib_memcpy (mp->locator_set_name, locator_set_name,
16930                vec_len (locator_set_name));
16931   vec_free (locator_set_name);
16932
16933   /* send it... */
16934   S (mp);
16935
16936   /* Wait for a reply... */
16937   W (ret);
16938   return ret;
16939 }
16940
16941 #define api_lisp_add_del_locator api_one_add_del_locator
16942
16943 uword
16944 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16945 {
16946   u32 *key_id = va_arg (*args, u32 *);
16947   u8 *s = 0;
16948
16949   if (unformat (input, "%s", &s))
16950     {
16951       if (!strcmp ((char *) s, "sha1"))
16952         key_id[0] = HMAC_SHA_1_96;
16953       else if (!strcmp ((char *) s, "sha256"))
16954         key_id[0] = HMAC_SHA_256_128;
16955       else
16956         {
16957           clib_warning ("invalid key_id: '%s'", s);
16958           key_id[0] = HMAC_NO_KEY;
16959         }
16960     }
16961   else
16962     return 0;
16963
16964   vec_free (s);
16965   return 1;
16966 }
16967
16968 static int
16969 api_one_add_del_local_eid (vat_main_t * vam)
16970 {
16971   unformat_input_t *input = vam->input;
16972   vl_api_one_add_del_local_eid_t *mp;
16973   u8 is_add = 1;
16974   u8 eid_set = 0;
16975   lisp_eid_vat_t _eid, *eid = &_eid;
16976   u8 *locator_set_name = 0;
16977   u8 locator_set_name_set = 0;
16978   u32 vni = 0;
16979   u16 key_id = 0;
16980   u8 *key = 0;
16981   int ret;
16982
16983   /* Parse args required to build the message */
16984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16985     {
16986       if (unformat (input, "del"))
16987         {
16988           is_add = 0;
16989         }
16990       else if (unformat (input, "vni %d", &vni))
16991         {
16992           ;
16993         }
16994       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16995         {
16996           eid_set = 1;
16997         }
16998       else if (unformat (input, "locator-set %s", &locator_set_name))
16999         {
17000           locator_set_name_set = 1;
17001         }
17002       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17003         ;
17004       else if (unformat (input, "secret-key %_%v%_", &key))
17005         ;
17006       else
17007         break;
17008     }
17009
17010   if (locator_set_name_set == 0)
17011     {
17012       errmsg ("missing locator-set name");
17013       return -99;
17014     }
17015
17016   if (0 == eid_set)
17017     {
17018       errmsg ("EID address not set!");
17019       vec_free (locator_set_name);
17020       return -99;
17021     }
17022
17023   if (key && (0 == key_id))
17024     {
17025       errmsg ("invalid key_id!");
17026       return -99;
17027     }
17028
17029   if (vec_len (key) > 64)
17030     {
17031       errmsg ("key too long");
17032       vec_free (key);
17033       return -99;
17034     }
17035
17036   if (vec_len (locator_set_name) > 64)
17037     {
17038       errmsg ("locator-set name too long");
17039       vec_free (locator_set_name);
17040       return -99;
17041     }
17042   vec_add1 (locator_set_name, 0);
17043
17044   /* Construct the API message */
17045   M (ONE_ADD_DEL_LOCAL_EID, mp);
17046
17047   mp->is_add = is_add;
17048   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17049   mp->eid_type = eid->type;
17050   mp->prefix_len = eid->len;
17051   mp->vni = clib_host_to_net_u32 (vni);
17052   mp->key_id = clib_host_to_net_u16 (key_id);
17053   clib_memcpy (mp->locator_set_name, locator_set_name,
17054                vec_len (locator_set_name));
17055   clib_memcpy (mp->key, key, vec_len (key));
17056
17057   vec_free (locator_set_name);
17058   vec_free (key);
17059
17060   /* send it... */
17061   S (mp);
17062
17063   /* Wait for a reply... */
17064   W (ret);
17065   return ret;
17066 }
17067
17068 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17069
17070 static int
17071 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17072 {
17073   u32 dp_table = 0, vni = 0;;
17074   unformat_input_t *input = vam->input;
17075   vl_api_gpe_add_del_fwd_entry_t *mp;
17076   u8 is_add = 1;
17077   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17078   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17079   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17080   u32 action = ~0, w;
17081   ip4_address_t rmt_rloc4, lcl_rloc4;
17082   ip6_address_t rmt_rloc6, lcl_rloc6;
17083   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17084   int ret;
17085
17086   memset (&rloc, 0, sizeof (rloc));
17087
17088   /* Parse args required to build the message */
17089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17090     {
17091       if (unformat (input, "del"))
17092         is_add = 0;
17093       else if (unformat (input, "add"))
17094         is_add = 1;
17095       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17096         {
17097           rmt_eid_set = 1;
17098         }
17099       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17100         {
17101           lcl_eid_set = 1;
17102         }
17103       else if (unformat (input, "vrf %d", &dp_table))
17104         ;
17105       else if (unformat (input, "bd %d", &dp_table))
17106         ;
17107       else if (unformat (input, "vni %d", &vni))
17108         ;
17109       else if (unformat (input, "w %d", &w))
17110         {
17111           if (!curr_rloc)
17112             {
17113               errmsg ("No RLOC configured for setting priority/weight!");
17114               return -99;
17115             }
17116           curr_rloc->weight = w;
17117         }
17118       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17119                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17120         {
17121           rloc.is_ip4 = 1;
17122
17123           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17124           rloc.weight = 0;
17125           vec_add1 (lcl_locs, rloc);
17126
17127           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17128           vec_add1 (rmt_locs, rloc);
17129           /* weight saved in rmt loc */
17130           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17131         }
17132       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17133                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17134         {
17135           rloc.is_ip4 = 0;
17136           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17137           rloc.weight = 0;
17138           vec_add1 (lcl_locs, rloc);
17139
17140           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17141           vec_add1 (rmt_locs, rloc);
17142           /* weight saved in rmt loc */
17143           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17144         }
17145       else if (unformat (input, "action %d", &action))
17146         {
17147           ;
17148         }
17149       else
17150         {
17151           clib_warning ("parse error '%U'", format_unformat_error, input);
17152           return -99;
17153         }
17154     }
17155
17156   if (!rmt_eid_set)
17157     {
17158       errmsg ("remote eid addresses not set");
17159       return -99;
17160     }
17161
17162   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17163     {
17164       errmsg ("eid types don't match");
17165       return -99;
17166     }
17167
17168   if (0 == rmt_locs && (u32) ~ 0 == action)
17169     {
17170       errmsg ("action not set for negative mapping");
17171       return -99;
17172     }
17173
17174   /* Construct the API message */
17175   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17176       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17177
17178   mp->is_add = is_add;
17179   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17180   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17181   mp->eid_type = rmt_eid->type;
17182   mp->dp_table = clib_host_to_net_u32 (dp_table);
17183   mp->vni = clib_host_to_net_u32 (vni);
17184   mp->rmt_len = rmt_eid->len;
17185   mp->lcl_len = lcl_eid->len;
17186   mp->action = action;
17187
17188   if (0 != rmt_locs && 0 != lcl_locs)
17189     {
17190       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17191       clib_memcpy (mp->locs, lcl_locs,
17192                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17193
17194       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17195       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17196                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17197     }
17198   vec_free (lcl_locs);
17199   vec_free (rmt_locs);
17200
17201   /* send it... */
17202   S (mp);
17203
17204   /* Wait for a reply... */
17205   W (ret);
17206   return ret;
17207 }
17208
17209 static int
17210 api_one_add_del_map_server (vat_main_t * vam)
17211 {
17212   unformat_input_t *input = vam->input;
17213   vl_api_one_add_del_map_server_t *mp;
17214   u8 is_add = 1;
17215   u8 ipv4_set = 0;
17216   u8 ipv6_set = 0;
17217   ip4_address_t ipv4;
17218   ip6_address_t ipv6;
17219   int ret;
17220
17221   /* Parse args required to build the message */
17222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17223     {
17224       if (unformat (input, "del"))
17225         {
17226           is_add = 0;
17227         }
17228       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17229         {
17230           ipv4_set = 1;
17231         }
17232       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17233         {
17234           ipv6_set = 1;
17235         }
17236       else
17237         break;
17238     }
17239
17240   if (ipv4_set && ipv6_set)
17241     {
17242       errmsg ("both eid v4 and v6 addresses set");
17243       return -99;
17244     }
17245
17246   if (!ipv4_set && !ipv6_set)
17247     {
17248       errmsg ("eid addresses not set");
17249       return -99;
17250     }
17251
17252   /* Construct the API message */
17253   M (ONE_ADD_DEL_MAP_SERVER, mp);
17254
17255   mp->is_add = is_add;
17256   if (ipv6_set)
17257     {
17258       mp->is_ipv6 = 1;
17259       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17260     }
17261   else
17262     {
17263       mp->is_ipv6 = 0;
17264       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17265     }
17266
17267   /* send it... */
17268   S (mp);
17269
17270   /* Wait for a reply... */
17271   W (ret);
17272   return ret;
17273 }
17274
17275 #define api_lisp_add_del_map_server api_one_add_del_map_server
17276
17277 static int
17278 api_one_add_del_map_resolver (vat_main_t * vam)
17279 {
17280   unformat_input_t *input = vam->input;
17281   vl_api_one_add_del_map_resolver_t *mp;
17282   u8 is_add = 1;
17283   u8 ipv4_set = 0;
17284   u8 ipv6_set = 0;
17285   ip4_address_t ipv4;
17286   ip6_address_t ipv6;
17287   int ret;
17288
17289   /* Parse args required to build the message */
17290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17291     {
17292       if (unformat (input, "del"))
17293         {
17294           is_add = 0;
17295         }
17296       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17297         {
17298           ipv4_set = 1;
17299         }
17300       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17301         {
17302           ipv6_set = 1;
17303         }
17304       else
17305         break;
17306     }
17307
17308   if (ipv4_set && ipv6_set)
17309     {
17310       errmsg ("both eid v4 and v6 addresses set");
17311       return -99;
17312     }
17313
17314   if (!ipv4_set && !ipv6_set)
17315     {
17316       errmsg ("eid addresses not set");
17317       return -99;
17318     }
17319
17320   /* Construct the API message */
17321   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17322
17323   mp->is_add = is_add;
17324   if (ipv6_set)
17325     {
17326       mp->is_ipv6 = 1;
17327       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17328     }
17329   else
17330     {
17331       mp->is_ipv6 = 0;
17332       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17333     }
17334
17335   /* send it... */
17336   S (mp);
17337
17338   /* Wait for a reply... */
17339   W (ret);
17340   return ret;
17341 }
17342
17343 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17344
17345 static int
17346 api_lisp_gpe_enable_disable (vat_main_t * vam)
17347 {
17348   unformat_input_t *input = vam->input;
17349   vl_api_gpe_enable_disable_t *mp;
17350   u8 is_set = 0;
17351   u8 is_en = 1;
17352   int ret;
17353
17354   /* Parse args required to build the message */
17355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17356     {
17357       if (unformat (input, "enable"))
17358         {
17359           is_set = 1;
17360           is_en = 1;
17361         }
17362       else if (unformat (input, "disable"))
17363         {
17364           is_set = 1;
17365           is_en = 0;
17366         }
17367       else
17368         break;
17369     }
17370
17371   if (is_set == 0)
17372     {
17373       errmsg ("Value not set");
17374       return -99;
17375     }
17376
17377   /* Construct the API message */
17378   M (GPE_ENABLE_DISABLE, mp);
17379
17380   mp->is_en = is_en;
17381
17382   /* send it... */
17383   S (mp);
17384
17385   /* Wait for a reply... */
17386   W (ret);
17387   return ret;
17388 }
17389
17390 static int
17391 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17392 {
17393   unformat_input_t *input = vam->input;
17394   vl_api_one_rloc_probe_enable_disable_t *mp;
17395   u8 is_set = 0;
17396   u8 is_en = 0;
17397   int ret;
17398
17399   /* Parse args required to build the message */
17400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17401     {
17402       if (unformat (input, "enable"))
17403         {
17404           is_set = 1;
17405           is_en = 1;
17406         }
17407       else if (unformat (input, "disable"))
17408         is_set = 1;
17409       else
17410         break;
17411     }
17412
17413   if (!is_set)
17414     {
17415       errmsg ("Value not set");
17416       return -99;
17417     }
17418
17419   /* Construct the API message */
17420   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17421
17422   mp->is_enabled = is_en;
17423
17424   /* send it... */
17425   S (mp);
17426
17427   /* Wait for a reply... */
17428   W (ret);
17429   return ret;
17430 }
17431
17432 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17433
17434 static int
17435 api_one_map_register_enable_disable (vat_main_t * vam)
17436 {
17437   unformat_input_t *input = vam->input;
17438   vl_api_one_map_register_enable_disable_t *mp;
17439   u8 is_set = 0;
17440   u8 is_en = 0;
17441   int ret;
17442
17443   /* Parse args required to build the message */
17444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17445     {
17446       if (unformat (input, "enable"))
17447         {
17448           is_set = 1;
17449           is_en = 1;
17450         }
17451       else if (unformat (input, "disable"))
17452         is_set = 1;
17453       else
17454         break;
17455     }
17456
17457   if (!is_set)
17458     {
17459       errmsg ("Value not set");
17460       return -99;
17461     }
17462
17463   /* Construct the API message */
17464   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17465
17466   mp->is_enabled = is_en;
17467
17468   /* send it... */
17469   S (mp);
17470
17471   /* Wait for a reply... */
17472   W (ret);
17473   return ret;
17474 }
17475
17476 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17477
17478 static int
17479 api_one_enable_disable (vat_main_t * vam)
17480 {
17481   unformat_input_t *input = vam->input;
17482   vl_api_one_enable_disable_t *mp;
17483   u8 is_set = 0;
17484   u8 is_en = 0;
17485   int ret;
17486
17487   /* Parse args required to build the message */
17488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17489     {
17490       if (unformat (input, "enable"))
17491         {
17492           is_set = 1;
17493           is_en = 1;
17494         }
17495       else if (unformat (input, "disable"))
17496         {
17497           is_set = 1;
17498         }
17499       else
17500         break;
17501     }
17502
17503   if (!is_set)
17504     {
17505       errmsg ("Value not set");
17506       return -99;
17507     }
17508
17509   /* Construct the API message */
17510   M (ONE_ENABLE_DISABLE, mp);
17511
17512   mp->is_en = is_en;
17513
17514   /* send it... */
17515   S (mp);
17516
17517   /* Wait for a reply... */
17518   W (ret);
17519   return ret;
17520 }
17521
17522 #define api_lisp_enable_disable api_one_enable_disable
17523
17524 static int
17525 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17526 {
17527   unformat_input_t *input = vam->input;
17528   vl_api_one_enable_disable_xtr_mode_t *mp;
17529   u8 is_set = 0;
17530   u8 is_en = 0;
17531   int ret;
17532
17533   /* Parse args required to build the message */
17534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17535     {
17536       if (unformat (input, "enable"))
17537         {
17538           is_set = 1;
17539           is_en = 1;
17540         }
17541       else if (unformat (input, "disable"))
17542         {
17543           is_set = 1;
17544         }
17545       else
17546         break;
17547     }
17548
17549   if (!is_set)
17550     {
17551       errmsg ("Value not set");
17552       return -99;
17553     }
17554
17555   /* Construct the API message */
17556   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17557
17558   mp->is_en = is_en;
17559
17560   /* send it... */
17561   S (mp);
17562
17563   /* Wait for a reply... */
17564   W (ret);
17565   return ret;
17566 }
17567
17568 static int
17569 api_one_show_xtr_mode (vat_main_t * vam)
17570 {
17571   vl_api_one_show_xtr_mode_t *mp;
17572   int ret;
17573
17574   /* Construct the API message */
17575   M (ONE_SHOW_XTR_MODE, mp);
17576
17577   /* send it... */
17578   S (mp);
17579
17580   /* Wait for a reply... */
17581   W (ret);
17582   return ret;
17583 }
17584
17585 static int
17586 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17587 {
17588   unformat_input_t *input = vam->input;
17589   vl_api_one_enable_disable_pitr_mode_t *mp;
17590   u8 is_set = 0;
17591   u8 is_en = 0;
17592   int ret;
17593
17594   /* Parse args required to build the message */
17595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17596     {
17597       if (unformat (input, "enable"))
17598         {
17599           is_set = 1;
17600           is_en = 1;
17601         }
17602       else if (unformat (input, "disable"))
17603         {
17604           is_set = 1;
17605         }
17606       else
17607         break;
17608     }
17609
17610   if (!is_set)
17611     {
17612       errmsg ("Value not set");
17613       return -99;
17614     }
17615
17616   /* Construct the API message */
17617   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17618
17619   mp->is_en = is_en;
17620
17621   /* send it... */
17622   S (mp);
17623
17624   /* Wait for a reply... */
17625   W (ret);
17626   return ret;
17627 }
17628
17629 static int
17630 api_one_show_pitr_mode (vat_main_t * vam)
17631 {
17632   vl_api_one_show_pitr_mode_t *mp;
17633   int ret;
17634
17635   /* Construct the API message */
17636   M (ONE_SHOW_PITR_MODE, mp);
17637
17638   /* send it... */
17639   S (mp);
17640
17641   /* Wait for a reply... */
17642   W (ret);
17643   return ret;
17644 }
17645
17646 static int
17647 api_one_enable_disable_petr_mode (vat_main_t * vam)
17648 {
17649   unformat_input_t *input = vam->input;
17650   vl_api_one_enable_disable_petr_mode_t *mp;
17651   u8 is_set = 0;
17652   u8 is_en = 0;
17653   int ret;
17654
17655   /* Parse args required to build the message */
17656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17657     {
17658       if (unformat (input, "enable"))
17659         {
17660           is_set = 1;
17661           is_en = 1;
17662         }
17663       else if (unformat (input, "disable"))
17664         {
17665           is_set = 1;
17666         }
17667       else
17668         break;
17669     }
17670
17671   if (!is_set)
17672     {
17673       errmsg ("Value not set");
17674       return -99;
17675     }
17676
17677   /* Construct the API message */
17678   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17679
17680   mp->is_en = is_en;
17681
17682   /* send it... */
17683   S (mp);
17684
17685   /* Wait for a reply... */
17686   W (ret);
17687   return ret;
17688 }
17689
17690 static int
17691 api_one_show_petr_mode (vat_main_t * vam)
17692 {
17693   vl_api_one_show_petr_mode_t *mp;
17694   int ret;
17695
17696   /* Construct the API message */
17697   M (ONE_SHOW_PETR_MODE, mp);
17698
17699   /* send it... */
17700   S (mp);
17701
17702   /* Wait for a reply... */
17703   W (ret);
17704   return ret;
17705 }
17706
17707 static int
17708 api_show_one_map_register_state (vat_main_t * vam)
17709 {
17710   vl_api_show_one_map_register_state_t *mp;
17711   int ret;
17712
17713   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17714
17715   /* send */
17716   S (mp);
17717
17718   /* wait for reply */
17719   W (ret);
17720   return ret;
17721 }
17722
17723 #define api_show_lisp_map_register_state api_show_one_map_register_state
17724
17725 static int
17726 api_show_one_rloc_probe_state (vat_main_t * vam)
17727 {
17728   vl_api_show_one_rloc_probe_state_t *mp;
17729   int ret;
17730
17731   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17732
17733   /* send */
17734   S (mp);
17735
17736   /* wait for reply */
17737   W (ret);
17738   return ret;
17739 }
17740
17741 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17742
17743 static int
17744 api_one_add_del_ndp_entry (vat_main_t * vam)
17745 {
17746   vl_api_one_add_del_ndp_entry_t *mp;
17747   unformat_input_t *input = vam->input;
17748   u8 is_add = 1;
17749   u8 mac_set = 0;
17750   u8 bd_set = 0;
17751   u8 ip_set = 0;
17752   u8 mac[6] = { 0, };
17753   u8 ip6[16] = { 0, };
17754   u32 bd = ~0;
17755   int ret;
17756
17757   /* Parse args required to build the message */
17758   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17759     {
17760       if (unformat (input, "del"))
17761         is_add = 0;
17762       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17763         mac_set = 1;
17764       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17765         ip_set = 1;
17766       else if (unformat (input, "bd %d", &bd))
17767         bd_set = 1;
17768       else
17769         {
17770           errmsg ("parse error '%U'", format_unformat_error, input);
17771           return -99;
17772         }
17773     }
17774
17775   if (!bd_set || !ip_set || (!mac_set && is_add))
17776     {
17777       errmsg ("Missing BD, IP or MAC!");
17778       return -99;
17779     }
17780
17781   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17782   mp->is_add = is_add;
17783   clib_memcpy (mp->mac, mac, 6);
17784   mp->bd = clib_host_to_net_u32 (bd);
17785   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17786
17787   /* send */
17788   S (mp);
17789
17790   /* wait for reply */
17791   W (ret);
17792   return ret;
17793 }
17794
17795 static int
17796 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17797 {
17798   vl_api_one_add_del_l2_arp_entry_t *mp;
17799   unformat_input_t *input = vam->input;
17800   u8 is_add = 1;
17801   u8 mac_set = 0;
17802   u8 bd_set = 0;
17803   u8 ip_set = 0;
17804   u8 mac[6] = { 0, };
17805   u32 ip4 = 0, bd = ~0;
17806   int ret;
17807
17808   /* Parse args required to build the message */
17809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17810     {
17811       if (unformat (input, "del"))
17812         is_add = 0;
17813       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17814         mac_set = 1;
17815       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17816         ip_set = 1;
17817       else if (unformat (input, "bd %d", &bd))
17818         bd_set = 1;
17819       else
17820         {
17821           errmsg ("parse error '%U'", format_unformat_error, input);
17822           return -99;
17823         }
17824     }
17825
17826   if (!bd_set || !ip_set || (!mac_set && is_add))
17827     {
17828       errmsg ("Missing BD, IP or MAC!");
17829       return -99;
17830     }
17831
17832   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17833   mp->is_add = is_add;
17834   clib_memcpy (mp->mac, mac, 6);
17835   mp->bd = clib_host_to_net_u32 (bd);
17836   mp->ip4 = ip4;
17837
17838   /* send */
17839   S (mp);
17840
17841   /* wait for reply */
17842   W (ret);
17843   return ret;
17844 }
17845
17846 static int
17847 api_one_ndp_bd_get (vat_main_t * vam)
17848 {
17849   vl_api_one_ndp_bd_get_t *mp;
17850   int ret;
17851
17852   M (ONE_NDP_BD_GET, mp);
17853
17854   /* send */
17855   S (mp);
17856
17857   /* wait for reply */
17858   W (ret);
17859   return ret;
17860 }
17861
17862 static int
17863 api_one_ndp_entries_get (vat_main_t * vam)
17864 {
17865   vl_api_one_ndp_entries_get_t *mp;
17866   unformat_input_t *input = vam->input;
17867   u8 bd_set = 0;
17868   u32 bd = ~0;
17869   int ret;
17870
17871   /* Parse args required to build the message */
17872   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17873     {
17874       if (unformat (input, "bd %d", &bd))
17875         bd_set = 1;
17876       else
17877         {
17878           errmsg ("parse error '%U'", format_unformat_error, input);
17879           return -99;
17880         }
17881     }
17882
17883   if (!bd_set)
17884     {
17885       errmsg ("Expected bridge domain!");
17886       return -99;
17887     }
17888
17889   M (ONE_NDP_ENTRIES_GET, mp);
17890   mp->bd = clib_host_to_net_u32 (bd);
17891
17892   /* send */
17893   S (mp);
17894
17895   /* wait for reply */
17896   W (ret);
17897   return ret;
17898 }
17899
17900 static int
17901 api_one_l2_arp_bd_get (vat_main_t * vam)
17902 {
17903   vl_api_one_l2_arp_bd_get_t *mp;
17904   int ret;
17905
17906   M (ONE_L2_ARP_BD_GET, mp);
17907
17908   /* send */
17909   S (mp);
17910
17911   /* wait for reply */
17912   W (ret);
17913   return ret;
17914 }
17915
17916 static int
17917 api_one_l2_arp_entries_get (vat_main_t * vam)
17918 {
17919   vl_api_one_l2_arp_entries_get_t *mp;
17920   unformat_input_t *input = vam->input;
17921   u8 bd_set = 0;
17922   u32 bd = ~0;
17923   int ret;
17924
17925   /* Parse args required to build the message */
17926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17927     {
17928       if (unformat (input, "bd %d", &bd))
17929         bd_set = 1;
17930       else
17931         {
17932           errmsg ("parse error '%U'", format_unformat_error, input);
17933           return -99;
17934         }
17935     }
17936
17937   if (!bd_set)
17938     {
17939       errmsg ("Expected bridge domain!");
17940       return -99;
17941     }
17942
17943   M (ONE_L2_ARP_ENTRIES_GET, mp);
17944   mp->bd = clib_host_to_net_u32 (bd);
17945
17946   /* send */
17947   S (mp);
17948
17949   /* wait for reply */
17950   W (ret);
17951   return ret;
17952 }
17953
17954 static int
17955 api_one_stats_enable_disable (vat_main_t * vam)
17956 {
17957   vl_api_one_stats_enable_disable_t *mp;
17958   unformat_input_t *input = vam->input;
17959   u8 is_set = 0;
17960   u8 is_en = 0;
17961   int ret;
17962
17963   /* Parse args required to build the message */
17964   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17965     {
17966       if (unformat (input, "enable"))
17967         {
17968           is_set = 1;
17969           is_en = 1;
17970         }
17971       else if (unformat (input, "disable"))
17972         {
17973           is_set = 1;
17974         }
17975       else
17976         break;
17977     }
17978
17979   if (!is_set)
17980     {
17981       errmsg ("Value not set");
17982       return -99;
17983     }
17984
17985   M (ONE_STATS_ENABLE_DISABLE, mp);
17986   mp->is_en = is_en;
17987
17988   /* send */
17989   S (mp);
17990
17991   /* wait for reply */
17992   W (ret);
17993   return ret;
17994 }
17995
17996 static int
17997 api_show_one_stats_enable_disable (vat_main_t * vam)
17998 {
17999   vl_api_show_one_stats_enable_disable_t *mp;
18000   int ret;
18001
18002   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18003
18004   /* send */
18005   S (mp);
18006
18007   /* wait for reply */
18008   W (ret);
18009   return ret;
18010 }
18011
18012 static int
18013 api_show_one_map_request_mode (vat_main_t * vam)
18014 {
18015   vl_api_show_one_map_request_mode_t *mp;
18016   int ret;
18017
18018   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18019
18020   /* send */
18021   S (mp);
18022
18023   /* wait for reply */
18024   W (ret);
18025   return ret;
18026 }
18027
18028 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18029
18030 static int
18031 api_one_map_request_mode (vat_main_t * vam)
18032 {
18033   unformat_input_t *input = vam->input;
18034   vl_api_one_map_request_mode_t *mp;
18035   u8 mode = 0;
18036   int ret;
18037
18038   /* Parse args required to build the message */
18039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18040     {
18041       if (unformat (input, "dst-only"))
18042         mode = 0;
18043       else if (unformat (input, "src-dst"))
18044         mode = 1;
18045       else
18046         {
18047           errmsg ("parse error '%U'", format_unformat_error, input);
18048           return -99;
18049         }
18050     }
18051
18052   M (ONE_MAP_REQUEST_MODE, mp);
18053
18054   mp->mode = mode;
18055
18056   /* send */
18057   S (mp);
18058
18059   /* wait for reply */
18060   W (ret);
18061   return ret;
18062 }
18063
18064 #define api_lisp_map_request_mode api_one_map_request_mode
18065
18066 /**
18067  * Enable/disable ONE proxy ITR.
18068  *
18069  * @param vam vpp API test context
18070  * @return return code
18071  */
18072 static int
18073 api_one_pitr_set_locator_set (vat_main_t * vam)
18074 {
18075   u8 ls_name_set = 0;
18076   unformat_input_t *input = vam->input;
18077   vl_api_one_pitr_set_locator_set_t *mp;
18078   u8 is_add = 1;
18079   u8 *ls_name = 0;
18080   int ret;
18081
18082   /* Parse args required to build the message */
18083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18084     {
18085       if (unformat (input, "del"))
18086         is_add = 0;
18087       else if (unformat (input, "locator-set %s", &ls_name))
18088         ls_name_set = 1;
18089       else
18090         {
18091           errmsg ("parse error '%U'", format_unformat_error, input);
18092           return -99;
18093         }
18094     }
18095
18096   if (!ls_name_set)
18097     {
18098       errmsg ("locator-set name not set!");
18099       return -99;
18100     }
18101
18102   M (ONE_PITR_SET_LOCATOR_SET, mp);
18103
18104   mp->is_add = is_add;
18105   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18106   vec_free (ls_name);
18107
18108   /* send */
18109   S (mp);
18110
18111   /* wait for reply */
18112   W (ret);
18113   return ret;
18114 }
18115
18116 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18117
18118 static int
18119 api_one_nsh_set_locator_set (vat_main_t * vam)
18120 {
18121   u8 ls_name_set = 0;
18122   unformat_input_t *input = vam->input;
18123   vl_api_one_nsh_set_locator_set_t *mp;
18124   u8 is_add = 1;
18125   u8 *ls_name = 0;
18126   int ret;
18127
18128   /* Parse args required to build the message */
18129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18130     {
18131       if (unformat (input, "del"))
18132         is_add = 0;
18133       else if (unformat (input, "ls %s", &ls_name))
18134         ls_name_set = 1;
18135       else
18136         {
18137           errmsg ("parse error '%U'", format_unformat_error, input);
18138           return -99;
18139         }
18140     }
18141
18142   if (!ls_name_set && is_add)
18143     {
18144       errmsg ("locator-set name not set!");
18145       return -99;
18146     }
18147
18148   M (ONE_NSH_SET_LOCATOR_SET, mp);
18149
18150   mp->is_add = is_add;
18151   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18152   vec_free (ls_name);
18153
18154   /* send */
18155   S (mp);
18156
18157   /* wait for reply */
18158   W (ret);
18159   return ret;
18160 }
18161
18162 static int
18163 api_show_one_pitr (vat_main_t * vam)
18164 {
18165   vl_api_show_one_pitr_t *mp;
18166   int ret;
18167
18168   if (!vam->json_output)
18169     {
18170       print (vam->ofp, "%=20s", "lisp status:");
18171     }
18172
18173   M (SHOW_ONE_PITR, mp);
18174   /* send it... */
18175   S (mp);
18176
18177   /* Wait for a reply... */
18178   W (ret);
18179   return ret;
18180 }
18181
18182 #define api_show_lisp_pitr api_show_one_pitr
18183
18184 static int
18185 api_one_use_petr (vat_main_t * vam)
18186 {
18187   unformat_input_t *input = vam->input;
18188   vl_api_one_use_petr_t *mp;
18189   u8 is_add = 0;
18190   ip_address_t ip;
18191   int ret;
18192
18193   memset (&ip, 0, sizeof (ip));
18194
18195   /* Parse args required to build the message */
18196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18197     {
18198       if (unformat (input, "disable"))
18199         is_add = 0;
18200       else
18201         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18202         {
18203           is_add = 1;
18204           ip_addr_version (&ip) = IP4;
18205         }
18206       else
18207         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18208         {
18209           is_add = 1;
18210           ip_addr_version (&ip) = IP6;
18211         }
18212       else
18213         {
18214           errmsg ("parse error '%U'", format_unformat_error, input);
18215           return -99;
18216         }
18217     }
18218
18219   M (ONE_USE_PETR, mp);
18220
18221   mp->is_add = is_add;
18222   if (is_add)
18223     {
18224       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18225       if (mp->is_ip4)
18226         clib_memcpy (mp->address, &ip, 4);
18227       else
18228         clib_memcpy (mp->address, &ip, 16);
18229     }
18230
18231   /* send */
18232   S (mp);
18233
18234   /* wait for reply */
18235   W (ret);
18236   return ret;
18237 }
18238
18239 #define api_lisp_use_petr api_one_use_petr
18240
18241 static int
18242 api_show_one_nsh_mapping (vat_main_t * vam)
18243 {
18244   vl_api_show_one_use_petr_t *mp;
18245   int ret;
18246
18247   if (!vam->json_output)
18248     {
18249       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18250     }
18251
18252   M (SHOW_ONE_NSH_MAPPING, mp);
18253   /* send it... */
18254   S (mp);
18255
18256   /* Wait for a reply... */
18257   W (ret);
18258   return ret;
18259 }
18260
18261 static int
18262 api_show_one_use_petr (vat_main_t * vam)
18263 {
18264   vl_api_show_one_use_petr_t *mp;
18265   int ret;
18266
18267   if (!vam->json_output)
18268     {
18269       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18270     }
18271
18272   M (SHOW_ONE_USE_PETR, mp);
18273   /* send it... */
18274   S (mp);
18275
18276   /* Wait for a reply... */
18277   W (ret);
18278   return ret;
18279 }
18280
18281 #define api_show_lisp_use_petr api_show_one_use_petr
18282
18283 /**
18284  * Add/delete mapping between vni and vrf
18285  */
18286 static int
18287 api_one_eid_table_add_del_map (vat_main_t * vam)
18288 {
18289   unformat_input_t *input = vam->input;
18290   vl_api_one_eid_table_add_del_map_t *mp;
18291   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18292   u32 vni, vrf, bd_index;
18293   int ret;
18294
18295   /* Parse args required to build the message */
18296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18297     {
18298       if (unformat (input, "del"))
18299         is_add = 0;
18300       else if (unformat (input, "vrf %d", &vrf))
18301         vrf_set = 1;
18302       else if (unformat (input, "bd_index %d", &bd_index))
18303         bd_index_set = 1;
18304       else if (unformat (input, "vni %d", &vni))
18305         vni_set = 1;
18306       else
18307         break;
18308     }
18309
18310   if (!vni_set || (!vrf_set && !bd_index_set))
18311     {
18312       errmsg ("missing arguments!");
18313       return -99;
18314     }
18315
18316   if (vrf_set && bd_index_set)
18317     {
18318       errmsg ("error: both vrf and bd entered!");
18319       return -99;
18320     }
18321
18322   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18323
18324   mp->is_add = is_add;
18325   mp->vni = htonl (vni);
18326   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18327   mp->is_l2 = bd_index_set;
18328
18329   /* send */
18330   S (mp);
18331
18332   /* wait for reply */
18333   W (ret);
18334   return ret;
18335 }
18336
18337 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18338
18339 uword
18340 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18341 {
18342   u32 *action = va_arg (*args, u32 *);
18343   u8 *s = 0;
18344
18345   if (unformat (input, "%s", &s))
18346     {
18347       if (!strcmp ((char *) s, "no-action"))
18348         action[0] = 0;
18349       else if (!strcmp ((char *) s, "natively-forward"))
18350         action[0] = 1;
18351       else if (!strcmp ((char *) s, "send-map-request"))
18352         action[0] = 2;
18353       else if (!strcmp ((char *) s, "drop"))
18354         action[0] = 3;
18355       else
18356         {
18357           clib_warning ("invalid action: '%s'", s);
18358           action[0] = 3;
18359         }
18360     }
18361   else
18362     return 0;
18363
18364   vec_free (s);
18365   return 1;
18366 }
18367
18368 /**
18369  * Add/del remote mapping to/from ONE control plane
18370  *
18371  * @param vam vpp API test context
18372  * @return return code
18373  */
18374 static int
18375 api_one_add_del_remote_mapping (vat_main_t * vam)
18376 {
18377   unformat_input_t *input = vam->input;
18378   vl_api_one_add_del_remote_mapping_t *mp;
18379   u32 vni = 0;
18380   lisp_eid_vat_t _eid, *eid = &_eid;
18381   lisp_eid_vat_t _seid, *seid = &_seid;
18382   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18383   u32 action = ~0, p, w, data_len;
18384   ip4_address_t rloc4;
18385   ip6_address_t rloc6;
18386   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18387   int ret;
18388
18389   memset (&rloc, 0, sizeof (rloc));
18390
18391   /* Parse args required to build the message */
18392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18393     {
18394       if (unformat (input, "del-all"))
18395         {
18396           del_all = 1;
18397         }
18398       else if (unformat (input, "del"))
18399         {
18400           is_add = 0;
18401         }
18402       else if (unformat (input, "add"))
18403         {
18404           is_add = 1;
18405         }
18406       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18407         {
18408           eid_set = 1;
18409         }
18410       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18411         {
18412           seid_set = 1;
18413         }
18414       else if (unformat (input, "vni %d", &vni))
18415         {
18416           ;
18417         }
18418       else if (unformat (input, "p %d w %d", &p, &w))
18419         {
18420           if (!curr_rloc)
18421             {
18422               errmsg ("No RLOC configured for setting priority/weight!");
18423               return -99;
18424             }
18425           curr_rloc->priority = p;
18426           curr_rloc->weight = w;
18427         }
18428       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18429         {
18430           rloc.is_ip4 = 1;
18431           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18432           vec_add1 (rlocs, rloc);
18433           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18434         }
18435       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18436         {
18437           rloc.is_ip4 = 0;
18438           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18439           vec_add1 (rlocs, rloc);
18440           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18441         }
18442       else if (unformat (input, "action %U",
18443                          unformat_negative_mapping_action, &action))
18444         {
18445           ;
18446         }
18447       else
18448         {
18449           clib_warning ("parse error '%U'", format_unformat_error, input);
18450           return -99;
18451         }
18452     }
18453
18454   if (0 == eid_set)
18455     {
18456       errmsg ("missing params!");
18457       return -99;
18458     }
18459
18460   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18461     {
18462       errmsg ("no action set for negative map-reply!");
18463       return -99;
18464     }
18465
18466   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18467
18468   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18469   mp->is_add = is_add;
18470   mp->vni = htonl (vni);
18471   mp->action = (u8) action;
18472   mp->is_src_dst = seid_set;
18473   mp->eid_len = eid->len;
18474   mp->seid_len = seid->len;
18475   mp->del_all = del_all;
18476   mp->eid_type = eid->type;
18477   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18478   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18479
18480   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18481   clib_memcpy (mp->rlocs, rlocs, data_len);
18482   vec_free (rlocs);
18483
18484   /* send it... */
18485   S (mp);
18486
18487   /* Wait for a reply... */
18488   W (ret);
18489   return ret;
18490 }
18491
18492 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18493
18494 /**
18495  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18496  * forwarding entries in data-plane accordingly.
18497  *
18498  * @param vam vpp API test context
18499  * @return return code
18500  */
18501 static int
18502 api_one_add_del_adjacency (vat_main_t * vam)
18503 {
18504   unformat_input_t *input = vam->input;
18505   vl_api_one_add_del_adjacency_t *mp;
18506   u32 vni = 0;
18507   ip4_address_t leid4, reid4;
18508   ip6_address_t leid6, reid6;
18509   u8 reid_mac[6] = { 0 };
18510   u8 leid_mac[6] = { 0 };
18511   u8 reid_type, leid_type;
18512   u32 leid_len = 0, reid_len = 0, len;
18513   u8 is_add = 1;
18514   int ret;
18515
18516   leid_type = reid_type = (u8) ~ 0;
18517
18518   /* Parse args required to build the message */
18519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18520     {
18521       if (unformat (input, "del"))
18522         {
18523           is_add = 0;
18524         }
18525       else if (unformat (input, "add"))
18526         {
18527           is_add = 1;
18528         }
18529       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18530                          &reid4, &len))
18531         {
18532           reid_type = 0;        /* ipv4 */
18533           reid_len = len;
18534         }
18535       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18536                          &reid6, &len))
18537         {
18538           reid_type = 1;        /* ipv6 */
18539           reid_len = len;
18540         }
18541       else if (unformat (input, "reid %U", unformat_ethernet_address,
18542                          reid_mac))
18543         {
18544           reid_type = 2;        /* mac */
18545         }
18546       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18547                          &leid4, &len))
18548         {
18549           leid_type = 0;        /* ipv4 */
18550           leid_len = len;
18551         }
18552       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18553                          &leid6, &len))
18554         {
18555           leid_type = 1;        /* ipv6 */
18556           leid_len = len;
18557         }
18558       else if (unformat (input, "leid %U", unformat_ethernet_address,
18559                          leid_mac))
18560         {
18561           leid_type = 2;        /* mac */
18562         }
18563       else if (unformat (input, "vni %d", &vni))
18564         {
18565           ;
18566         }
18567       else
18568         {
18569           errmsg ("parse error '%U'", format_unformat_error, input);
18570           return -99;
18571         }
18572     }
18573
18574   if ((u8) ~ 0 == reid_type)
18575     {
18576       errmsg ("missing params!");
18577       return -99;
18578     }
18579
18580   if (leid_type != reid_type)
18581     {
18582       errmsg ("remote and local EIDs are of different types!");
18583       return -99;
18584     }
18585
18586   M (ONE_ADD_DEL_ADJACENCY, mp);
18587   mp->is_add = is_add;
18588   mp->vni = htonl (vni);
18589   mp->leid_len = leid_len;
18590   mp->reid_len = reid_len;
18591   mp->eid_type = reid_type;
18592
18593   switch (mp->eid_type)
18594     {
18595     case 0:
18596       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18597       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18598       break;
18599     case 1:
18600       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18601       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18602       break;
18603     case 2:
18604       clib_memcpy (mp->leid, leid_mac, 6);
18605       clib_memcpy (mp->reid, reid_mac, 6);
18606       break;
18607     default:
18608       errmsg ("unknown EID type %d!", mp->eid_type);
18609       return 0;
18610     }
18611
18612   /* send it... */
18613   S (mp);
18614
18615   /* Wait for a reply... */
18616   W (ret);
18617   return ret;
18618 }
18619
18620 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18621
18622 uword
18623 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18624 {
18625   u32 *mode = va_arg (*args, u32 *);
18626
18627   if (unformat (input, "lisp"))
18628     *mode = 0;
18629   else if (unformat (input, "vxlan"))
18630     *mode = 1;
18631   else
18632     return 0;
18633
18634   return 1;
18635 }
18636
18637 static int
18638 api_gpe_get_encap_mode (vat_main_t * vam)
18639 {
18640   vl_api_gpe_get_encap_mode_t *mp;
18641   int ret;
18642
18643   /* Construct the API message */
18644   M (GPE_GET_ENCAP_MODE, mp);
18645
18646   /* send it... */
18647   S (mp);
18648
18649   /* Wait for a reply... */
18650   W (ret);
18651   return ret;
18652 }
18653
18654 static int
18655 api_gpe_set_encap_mode (vat_main_t * vam)
18656 {
18657   unformat_input_t *input = vam->input;
18658   vl_api_gpe_set_encap_mode_t *mp;
18659   int ret;
18660   u32 mode = 0;
18661
18662   /* Parse args required to build the message */
18663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18664     {
18665       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18666         ;
18667       else
18668         break;
18669     }
18670
18671   /* Construct the API message */
18672   M (GPE_SET_ENCAP_MODE, mp);
18673
18674   mp->mode = mode;
18675
18676   /* send it... */
18677   S (mp);
18678
18679   /* Wait for a reply... */
18680   W (ret);
18681   return ret;
18682 }
18683
18684 static int
18685 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18686 {
18687   unformat_input_t *input = vam->input;
18688   vl_api_gpe_add_del_iface_t *mp;
18689   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18690   u32 dp_table = 0, vni = 0;
18691   int ret;
18692
18693   /* Parse args required to build the message */
18694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18695     {
18696       if (unformat (input, "up"))
18697         {
18698           action_set = 1;
18699           is_add = 1;
18700         }
18701       else if (unformat (input, "down"))
18702         {
18703           action_set = 1;
18704           is_add = 0;
18705         }
18706       else if (unformat (input, "table_id %d", &dp_table))
18707         {
18708           dp_table_set = 1;
18709         }
18710       else if (unformat (input, "bd_id %d", &dp_table))
18711         {
18712           dp_table_set = 1;
18713           is_l2 = 1;
18714         }
18715       else if (unformat (input, "vni %d", &vni))
18716         {
18717           vni_set = 1;
18718         }
18719       else
18720         break;
18721     }
18722
18723   if (action_set == 0)
18724     {
18725       errmsg ("Action not set");
18726       return -99;
18727     }
18728   if (dp_table_set == 0 || vni_set == 0)
18729     {
18730       errmsg ("vni and dp_table must be set");
18731       return -99;
18732     }
18733
18734   /* Construct the API message */
18735   M (GPE_ADD_DEL_IFACE, mp);
18736
18737   mp->is_add = is_add;
18738   mp->dp_table = clib_host_to_net_u32 (dp_table);
18739   mp->is_l2 = is_l2;
18740   mp->vni = clib_host_to_net_u32 (vni);
18741
18742   /* send it... */
18743   S (mp);
18744
18745   /* Wait for a reply... */
18746   W (ret);
18747   return ret;
18748 }
18749
18750 static int
18751 api_one_map_register_fallback_threshold (vat_main_t * vam)
18752 {
18753   unformat_input_t *input = vam->input;
18754   vl_api_one_map_register_fallback_threshold_t *mp;
18755   u32 value = 0;
18756   u8 is_set = 0;
18757   int ret;
18758
18759   /* Parse args required to build the message */
18760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18761     {
18762       if (unformat (input, "%u", &value))
18763         is_set = 1;
18764       else
18765         {
18766           clib_warning ("parse error '%U'", format_unformat_error, input);
18767           return -99;
18768         }
18769     }
18770
18771   if (!is_set)
18772     {
18773       errmsg ("fallback threshold value is missing!");
18774       return -99;
18775     }
18776
18777   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18778   mp->value = clib_host_to_net_u32 (value);
18779
18780   /* send it... */
18781   S (mp);
18782
18783   /* Wait for a reply... */
18784   W (ret);
18785   return ret;
18786 }
18787
18788 static int
18789 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18790 {
18791   vl_api_show_one_map_register_fallback_threshold_t *mp;
18792   int ret;
18793
18794   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18795
18796   /* send it... */
18797   S (mp);
18798
18799   /* Wait for a reply... */
18800   W (ret);
18801   return ret;
18802 }
18803
18804 uword
18805 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18806 {
18807   u32 *proto = va_arg (*args, u32 *);
18808
18809   if (unformat (input, "udp"))
18810     *proto = 1;
18811   else if (unformat (input, "api"))
18812     *proto = 2;
18813   else
18814     return 0;
18815
18816   return 1;
18817 }
18818
18819 static int
18820 api_one_set_transport_protocol (vat_main_t * vam)
18821 {
18822   unformat_input_t *input = vam->input;
18823   vl_api_one_set_transport_protocol_t *mp;
18824   u8 is_set = 0;
18825   u32 protocol = 0;
18826   int ret;
18827
18828   /* Parse args required to build the message */
18829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18830     {
18831       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18832         is_set = 1;
18833       else
18834         {
18835           clib_warning ("parse error '%U'", format_unformat_error, input);
18836           return -99;
18837         }
18838     }
18839
18840   if (!is_set)
18841     {
18842       errmsg ("Transport protocol missing!");
18843       return -99;
18844     }
18845
18846   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18847   mp->protocol = (u8) protocol;
18848
18849   /* send it... */
18850   S (mp);
18851
18852   /* Wait for a reply... */
18853   W (ret);
18854   return ret;
18855 }
18856
18857 static int
18858 api_one_get_transport_protocol (vat_main_t * vam)
18859 {
18860   vl_api_one_get_transport_protocol_t *mp;
18861   int ret;
18862
18863   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18864
18865   /* send it... */
18866   S (mp);
18867
18868   /* Wait for a reply... */
18869   W (ret);
18870   return ret;
18871 }
18872
18873 static int
18874 api_one_map_register_set_ttl (vat_main_t * vam)
18875 {
18876   unformat_input_t *input = vam->input;
18877   vl_api_one_map_register_set_ttl_t *mp;
18878   u32 ttl = 0;
18879   u8 is_set = 0;
18880   int ret;
18881
18882   /* Parse args required to build the message */
18883   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18884     {
18885       if (unformat (input, "%u", &ttl))
18886         is_set = 1;
18887       else
18888         {
18889           clib_warning ("parse error '%U'", format_unformat_error, input);
18890           return -99;
18891         }
18892     }
18893
18894   if (!is_set)
18895     {
18896       errmsg ("TTL value missing!");
18897       return -99;
18898     }
18899
18900   M (ONE_MAP_REGISTER_SET_TTL, mp);
18901   mp->ttl = clib_host_to_net_u32 (ttl);
18902
18903   /* send it... */
18904   S (mp);
18905
18906   /* Wait for a reply... */
18907   W (ret);
18908   return ret;
18909 }
18910
18911 static int
18912 api_show_one_map_register_ttl (vat_main_t * vam)
18913 {
18914   vl_api_show_one_map_register_ttl_t *mp;
18915   int ret;
18916
18917   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18918
18919   /* send it... */
18920   S (mp);
18921
18922   /* Wait for a reply... */
18923   W (ret);
18924   return ret;
18925 }
18926
18927 /**
18928  * Add/del map request itr rlocs from ONE control plane and updates
18929  *
18930  * @param vam vpp API test context
18931  * @return return code
18932  */
18933 static int
18934 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18935 {
18936   unformat_input_t *input = vam->input;
18937   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18938   u8 *locator_set_name = 0;
18939   u8 locator_set_name_set = 0;
18940   u8 is_add = 1;
18941   int ret;
18942
18943   /* Parse args required to build the message */
18944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18945     {
18946       if (unformat (input, "del"))
18947         {
18948           is_add = 0;
18949         }
18950       else if (unformat (input, "%_%v%_", &locator_set_name))
18951         {
18952           locator_set_name_set = 1;
18953         }
18954       else
18955         {
18956           clib_warning ("parse error '%U'", format_unformat_error, input);
18957           return -99;
18958         }
18959     }
18960
18961   if (is_add && !locator_set_name_set)
18962     {
18963       errmsg ("itr-rloc is not set!");
18964       return -99;
18965     }
18966
18967   if (is_add && vec_len (locator_set_name) > 64)
18968     {
18969       errmsg ("itr-rloc locator-set name too long");
18970       vec_free (locator_set_name);
18971       return -99;
18972     }
18973
18974   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18975   mp->is_add = is_add;
18976   if (is_add)
18977     {
18978       clib_memcpy (mp->locator_set_name, locator_set_name,
18979                    vec_len (locator_set_name));
18980     }
18981   else
18982     {
18983       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18984     }
18985   vec_free (locator_set_name);
18986
18987   /* send it... */
18988   S (mp);
18989
18990   /* Wait for a reply... */
18991   W (ret);
18992   return ret;
18993 }
18994
18995 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18996
18997 static int
18998 api_one_locator_dump (vat_main_t * vam)
18999 {
19000   unformat_input_t *input = vam->input;
19001   vl_api_one_locator_dump_t *mp;
19002   vl_api_control_ping_t *mp_ping;
19003   u8 is_index_set = 0, is_name_set = 0;
19004   u8 *ls_name = 0;
19005   u32 ls_index = ~0;
19006   int ret;
19007
19008   /* Parse args required to build the message */
19009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19010     {
19011       if (unformat (input, "ls_name %_%v%_", &ls_name))
19012         {
19013           is_name_set = 1;
19014         }
19015       else if (unformat (input, "ls_index %d", &ls_index))
19016         {
19017           is_index_set = 1;
19018         }
19019       else
19020         {
19021           errmsg ("parse error '%U'", format_unformat_error, input);
19022           return -99;
19023         }
19024     }
19025
19026   if (!is_index_set && !is_name_set)
19027     {
19028       errmsg ("error: expected one of index or name!");
19029       return -99;
19030     }
19031
19032   if (is_index_set && is_name_set)
19033     {
19034       errmsg ("error: only one param expected!");
19035       return -99;
19036     }
19037
19038   if (vec_len (ls_name) > 62)
19039     {
19040       errmsg ("error: locator set name too long!");
19041       return -99;
19042     }
19043
19044   if (!vam->json_output)
19045     {
19046       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19047     }
19048
19049   M (ONE_LOCATOR_DUMP, mp);
19050   mp->is_index_set = is_index_set;
19051
19052   if (is_index_set)
19053     mp->ls_index = clib_host_to_net_u32 (ls_index);
19054   else
19055     {
19056       vec_add1 (ls_name, 0);
19057       strncpy ((char *) mp->ls_name, (char *) ls_name,
19058                sizeof (mp->ls_name) - 1);
19059     }
19060
19061   /* send it... */
19062   S (mp);
19063
19064   /* Use a control ping for synchronization */
19065   MPING (CONTROL_PING, mp_ping);
19066   S (mp_ping);
19067
19068   /* Wait for a reply... */
19069   W (ret);
19070   return ret;
19071 }
19072
19073 #define api_lisp_locator_dump api_one_locator_dump
19074
19075 static int
19076 api_one_locator_set_dump (vat_main_t * vam)
19077 {
19078   vl_api_one_locator_set_dump_t *mp;
19079   vl_api_control_ping_t *mp_ping;
19080   unformat_input_t *input = vam->input;
19081   u8 filter = 0;
19082   int ret;
19083
19084   /* Parse args required to build the message */
19085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19086     {
19087       if (unformat (input, "local"))
19088         {
19089           filter = 1;
19090         }
19091       else if (unformat (input, "remote"))
19092         {
19093           filter = 2;
19094         }
19095       else
19096         {
19097           errmsg ("parse error '%U'", format_unformat_error, input);
19098           return -99;
19099         }
19100     }
19101
19102   if (!vam->json_output)
19103     {
19104       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19105     }
19106
19107   M (ONE_LOCATOR_SET_DUMP, mp);
19108
19109   mp->filter = filter;
19110
19111   /* send it... */
19112   S (mp);
19113
19114   /* Use a control ping for synchronization */
19115   MPING (CONTROL_PING, mp_ping);
19116   S (mp_ping);
19117
19118   /* Wait for a reply... */
19119   W (ret);
19120   return ret;
19121 }
19122
19123 #define api_lisp_locator_set_dump api_one_locator_set_dump
19124
19125 static int
19126 api_one_eid_table_map_dump (vat_main_t * vam)
19127 {
19128   u8 is_l2 = 0;
19129   u8 mode_set = 0;
19130   unformat_input_t *input = vam->input;
19131   vl_api_one_eid_table_map_dump_t *mp;
19132   vl_api_control_ping_t *mp_ping;
19133   int ret;
19134
19135   /* Parse args required to build the message */
19136   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19137     {
19138       if (unformat (input, "l2"))
19139         {
19140           is_l2 = 1;
19141           mode_set = 1;
19142         }
19143       else if (unformat (input, "l3"))
19144         {
19145           is_l2 = 0;
19146           mode_set = 1;
19147         }
19148       else
19149         {
19150           errmsg ("parse error '%U'", format_unformat_error, input);
19151           return -99;
19152         }
19153     }
19154
19155   if (!mode_set)
19156     {
19157       errmsg ("expected one of 'l2' or 'l3' parameter!");
19158       return -99;
19159     }
19160
19161   if (!vam->json_output)
19162     {
19163       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19164     }
19165
19166   M (ONE_EID_TABLE_MAP_DUMP, mp);
19167   mp->is_l2 = is_l2;
19168
19169   /* send it... */
19170   S (mp);
19171
19172   /* Use a control ping for synchronization */
19173   MPING (CONTROL_PING, mp_ping);
19174   S (mp_ping);
19175
19176   /* Wait for a reply... */
19177   W (ret);
19178   return ret;
19179 }
19180
19181 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19182
19183 static int
19184 api_one_eid_table_vni_dump (vat_main_t * vam)
19185 {
19186   vl_api_one_eid_table_vni_dump_t *mp;
19187   vl_api_control_ping_t *mp_ping;
19188   int ret;
19189
19190   if (!vam->json_output)
19191     {
19192       print (vam->ofp, "VNI");
19193     }
19194
19195   M (ONE_EID_TABLE_VNI_DUMP, mp);
19196
19197   /* send it... */
19198   S (mp);
19199
19200   /* Use a control ping for synchronization */
19201   MPING (CONTROL_PING, mp_ping);
19202   S (mp_ping);
19203
19204   /* Wait for a reply... */
19205   W (ret);
19206   return ret;
19207 }
19208
19209 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19210
19211 static int
19212 api_one_eid_table_dump (vat_main_t * vam)
19213 {
19214   unformat_input_t *i = vam->input;
19215   vl_api_one_eid_table_dump_t *mp;
19216   vl_api_control_ping_t *mp_ping;
19217   struct in_addr ip4;
19218   struct in6_addr ip6;
19219   u8 mac[6];
19220   u8 eid_type = ~0, eid_set = 0;
19221   u32 prefix_length = ~0, t, vni = 0;
19222   u8 filter = 0;
19223   int ret;
19224   lisp_nsh_api_t nsh;
19225
19226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19227     {
19228       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19229         {
19230           eid_set = 1;
19231           eid_type = 0;
19232           prefix_length = t;
19233         }
19234       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19235         {
19236           eid_set = 1;
19237           eid_type = 1;
19238           prefix_length = t;
19239         }
19240       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19241         {
19242           eid_set = 1;
19243           eid_type = 2;
19244         }
19245       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19246         {
19247           eid_set = 1;
19248           eid_type = 3;
19249         }
19250       else if (unformat (i, "vni %d", &t))
19251         {
19252           vni = t;
19253         }
19254       else if (unformat (i, "local"))
19255         {
19256           filter = 1;
19257         }
19258       else if (unformat (i, "remote"))
19259         {
19260           filter = 2;
19261         }
19262       else
19263         {
19264           errmsg ("parse error '%U'", format_unformat_error, i);
19265           return -99;
19266         }
19267     }
19268
19269   if (!vam->json_output)
19270     {
19271       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19272              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19273     }
19274
19275   M (ONE_EID_TABLE_DUMP, mp);
19276
19277   mp->filter = filter;
19278   if (eid_set)
19279     {
19280       mp->eid_set = 1;
19281       mp->vni = htonl (vni);
19282       mp->eid_type = eid_type;
19283       switch (eid_type)
19284         {
19285         case 0:
19286           mp->prefix_length = prefix_length;
19287           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19288           break;
19289         case 1:
19290           mp->prefix_length = prefix_length;
19291           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19292           break;
19293         case 2:
19294           clib_memcpy (mp->eid, mac, sizeof (mac));
19295           break;
19296         case 3:
19297           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19298           break;
19299         default:
19300           errmsg ("unknown EID type %d!", eid_type);
19301           return -99;
19302         }
19303     }
19304
19305   /* send it... */
19306   S (mp);
19307
19308   /* Use a control ping for synchronization */
19309   MPING (CONTROL_PING, mp_ping);
19310   S (mp_ping);
19311
19312   /* Wait for a reply... */
19313   W (ret);
19314   return ret;
19315 }
19316
19317 #define api_lisp_eid_table_dump api_one_eid_table_dump
19318
19319 static int
19320 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19321 {
19322   unformat_input_t *i = vam->input;
19323   vl_api_gpe_fwd_entries_get_t *mp;
19324   u8 vni_set = 0;
19325   u32 vni = ~0;
19326   int ret;
19327
19328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19329     {
19330       if (unformat (i, "vni %d", &vni))
19331         {
19332           vni_set = 1;
19333         }
19334       else
19335         {
19336           errmsg ("parse error '%U'", format_unformat_error, i);
19337           return -99;
19338         }
19339     }
19340
19341   if (!vni_set)
19342     {
19343       errmsg ("vni not set!");
19344       return -99;
19345     }
19346
19347   if (!vam->json_output)
19348     {
19349       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19350              "leid", "reid");
19351     }
19352
19353   M (GPE_FWD_ENTRIES_GET, mp);
19354   mp->vni = clib_host_to_net_u32 (vni);
19355
19356   /* send it... */
19357   S (mp);
19358
19359   /* Wait for a reply... */
19360   W (ret);
19361   return ret;
19362 }
19363
19364 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19365 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19366 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19367 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19368 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19369 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19370 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19371 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19372
19373 static int
19374 api_one_adjacencies_get (vat_main_t * vam)
19375 {
19376   unformat_input_t *i = vam->input;
19377   vl_api_one_adjacencies_get_t *mp;
19378   u8 vni_set = 0;
19379   u32 vni = ~0;
19380   int ret;
19381
19382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19383     {
19384       if (unformat (i, "vni %d", &vni))
19385         {
19386           vni_set = 1;
19387         }
19388       else
19389         {
19390           errmsg ("parse error '%U'", format_unformat_error, i);
19391           return -99;
19392         }
19393     }
19394
19395   if (!vni_set)
19396     {
19397       errmsg ("vni not set!");
19398       return -99;
19399     }
19400
19401   if (!vam->json_output)
19402     {
19403       print (vam->ofp, "%s %40s", "leid", "reid");
19404     }
19405
19406   M (ONE_ADJACENCIES_GET, mp);
19407   mp->vni = clib_host_to_net_u32 (vni);
19408
19409   /* send it... */
19410   S (mp);
19411
19412   /* Wait for a reply... */
19413   W (ret);
19414   return ret;
19415 }
19416
19417 #define api_lisp_adjacencies_get api_one_adjacencies_get
19418
19419 static int
19420 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19421 {
19422   unformat_input_t *i = vam->input;
19423   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19424   int ret;
19425   u8 ip_family_set = 0, is_ip4 = 1;
19426
19427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19428     {
19429       if (unformat (i, "ip4"))
19430         {
19431           ip_family_set = 1;
19432           is_ip4 = 1;
19433         }
19434       else if (unformat (i, "ip6"))
19435         {
19436           ip_family_set = 1;
19437           is_ip4 = 0;
19438         }
19439       else
19440         {
19441           errmsg ("parse error '%U'", format_unformat_error, i);
19442           return -99;
19443         }
19444     }
19445
19446   if (!ip_family_set)
19447     {
19448       errmsg ("ip family not set!");
19449       return -99;
19450     }
19451
19452   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19453   mp->is_ip4 = is_ip4;
19454
19455   /* send it... */
19456   S (mp);
19457
19458   /* Wait for a reply... */
19459   W (ret);
19460   return ret;
19461 }
19462
19463 static int
19464 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19465 {
19466   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19467   int ret;
19468
19469   if (!vam->json_output)
19470     {
19471       print (vam->ofp, "VNIs");
19472     }
19473
19474   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19475
19476   /* send it... */
19477   S (mp);
19478
19479   /* Wait for a reply... */
19480   W (ret);
19481   return ret;
19482 }
19483
19484 static int
19485 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19486 {
19487   unformat_input_t *i = vam->input;
19488   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19489   int ret = 0;
19490   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19491   struct in_addr ip4;
19492   struct in6_addr ip6;
19493   u32 table_id = 0, nh_sw_if_index = ~0;
19494
19495   memset (&ip4, 0, sizeof (ip4));
19496   memset (&ip6, 0, sizeof (ip6));
19497
19498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19499     {
19500       if (unformat (i, "del"))
19501         is_add = 0;
19502       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19503                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19504         {
19505           ip_set = 1;
19506           is_ip4 = 1;
19507         }
19508       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19509                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19510         {
19511           ip_set = 1;
19512           is_ip4 = 0;
19513         }
19514       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19515         {
19516           ip_set = 1;
19517           is_ip4 = 1;
19518           nh_sw_if_index = ~0;
19519         }
19520       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19521         {
19522           ip_set = 1;
19523           is_ip4 = 0;
19524           nh_sw_if_index = ~0;
19525         }
19526       else if (unformat (i, "table %d", &table_id))
19527         ;
19528       else
19529         {
19530           errmsg ("parse error '%U'", format_unformat_error, i);
19531           return -99;
19532         }
19533     }
19534
19535   if (!ip_set)
19536     {
19537       errmsg ("nh addr not set!");
19538       return -99;
19539     }
19540
19541   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19542   mp->is_add = is_add;
19543   mp->table_id = clib_host_to_net_u32 (table_id);
19544   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19545   mp->is_ip4 = is_ip4;
19546   if (is_ip4)
19547     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19548   else
19549     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19550
19551   /* send it... */
19552   S (mp);
19553
19554   /* Wait for a reply... */
19555   W (ret);
19556   return ret;
19557 }
19558
19559 static int
19560 api_one_map_server_dump (vat_main_t * vam)
19561 {
19562   vl_api_one_map_server_dump_t *mp;
19563   vl_api_control_ping_t *mp_ping;
19564   int ret;
19565
19566   if (!vam->json_output)
19567     {
19568       print (vam->ofp, "%=20s", "Map server");
19569     }
19570
19571   M (ONE_MAP_SERVER_DUMP, mp);
19572   /* send it... */
19573   S (mp);
19574
19575   /* Use a control ping for synchronization */
19576   MPING (CONTROL_PING, mp_ping);
19577   S (mp_ping);
19578
19579   /* Wait for a reply... */
19580   W (ret);
19581   return ret;
19582 }
19583
19584 #define api_lisp_map_server_dump api_one_map_server_dump
19585
19586 static int
19587 api_one_map_resolver_dump (vat_main_t * vam)
19588 {
19589   vl_api_one_map_resolver_dump_t *mp;
19590   vl_api_control_ping_t *mp_ping;
19591   int ret;
19592
19593   if (!vam->json_output)
19594     {
19595       print (vam->ofp, "%=20s", "Map resolver");
19596     }
19597
19598   M (ONE_MAP_RESOLVER_DUMP, mp);
19599   /* send it... */
19600   S (mp);
19601
19602   /* Use a control ping for synchronization */
19603   MPING (CONTROL_PING, mp_ping);
19604   S (mp_ping);
19605
19606   /* Wait for a reply... */
19607   W (ret);
19608   return ret;
19609 }
19610
19611 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19612
19613 static int
19614 api_one_stats_flush (vat_main_t * vam)
19615 {
19616   vl_api_one_stats_flush_t *mp;
19617   int ret = 0;
19618
19619   M (ONE_STATS_FLUSH, mp);
19620   S (mp);
19621   W (ret);
19622   return ret;
19623 }
19624
19625 static int
19626 api_one_stats_dump (vat_main_t * vam)
19627 {
19628   vl_api_one_stats_dump_t *mp;
19629   vl_api_control_ping_t *mp_ping;
19630   int ret;
19631
19632   M (ONE_STATS_DUMP, mp);
19633   /* send it... */
19634   S (mp);
19635
19636   /* Use a control ping for synchronization */
19637   MPING (CONTROL_PING, mp_ping);
19638   S (mp_ping);
19639
19640   /* Wait for a reply... */
19641   W (ret);
19642   return ret;
19643 }
19644
19645 static int
19646 api_show_one_status (vat_main_t * vam)
19647 {
19648   vl_api_show_one_status_t *mp;
19649   int ret;
19650
19651   if (!vam->json_output)
19652     {
19653       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19654     }
19655
19656   M (SHOW_ONE_STATUS, mp);
19657   /* send it... */
19658   S (mp);
19659   /* Wait for a reply... */
19660   W (ret);
19661   return ret;
19662 }
19663
19664 #define api_show_lisp_status api_show_one_status
19665
19666 static int
19667 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19668 {
19669   vl_api_gpe_fwd_entry_path_dump_t *mp;
19670   vl_api_control_ping_t *mp_ping;
19671   unformat_input_t *i = vam->input;
19672   u32 fwd_entry_index = ~0;
19673   int ret;
19674
19675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19676     {
19677       if (unformat (i, "index %d", &fwd_entry_index))
19678         ;
19679       else
19680         break;
19681     }
19682
19683   if (~0 == fwd_entry_index)
19684     {
19685       errmsg ("no index specified!");
19686       return -99;
19687     }
19688
19689   if (!vam->json_output)
19690     {
19691       print (vam->ofp, "first line");
19692     }
19693
19694   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19695
19696   /* send it... */
19697   S (mp);
19698   /* Use a control ping for synchronization */
19699   MPING (CONTROL_PING, mp_ping);
19700   S (mp_ping);
19701
19702   /* Wait for a reply... */
19703   W (ret);
19704   return ret;
19705 }
19706
19707 static int
19708 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19709 {
19710   vl_api_one_get_map_request_itr_rlocs_t *mp;
19711   int ret;
19712
19713   if (!vam->json_output)
19714     {
19715       print (vam->ofp, "%=20s", "itr-rlocs:");
19716     }
19717
19718   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19719   /* send it... */
19720   S (mp);
19721   /* Wait for a reply... */
19722   W (ret);
19723   return ret;
19724 }
19725
19726 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19727
19728 static int
19729 api_af_packet_create (vat_main_t * vam)
19730 {
19731   unformat_input_t *i = vam->input;
19732   vl_api_af_packet_create_t *mp;
19733   u8 *host_if_name = 0;
19734   u8 hw_addr[6];
19735   u8 random_hw_addr = 1;
19736   int ret;
19737
19738   memset (hw_addr, 0, sizeof (hw_addr));
19739
19740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19741     {
19742       if (unformat (i, "name %s", &host_if_name))
19743         vec_add1 (host_if_name, 0);
19744       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19745         random_hw_addr = 0;
19746       else
19747         break;
19748     }
19749
19750   if (!vec_len (host_if_name))
19751     {
19752       errmsg ("host-interface name must be specified");
19753       return -99;
19754     }
19755
19756   if (vec_len (host_if_name) > 64)
19757     {
19758       errmsg ("host-interface name too long");
19759       return -99;
19760     }
19761
19762   M (AF_PACKET_CREATE, mp);
19763
19764   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19765   clib_memcpy (mp->hw_addr, hw_addr, 6);
19766   mp->use_random_hw_addr = random_hw_addr;
19767   vec_free (host_if_name);
19768
19769   S (mp);
19770
19771   /* *INDENT-OFF* */
19772   W2 (ret,
19773       ({
19774         if (ret == 0)
19775           fprintf (vam->ofp ? vam->ofp : stderr,
19776                    " new sw_if_index = %d\n", vam->sw_if_index);
19777       }));
19778   /* *INDENT-ON* */
19779   return ret;
19780 }
19781
19782 static int
19783 api_af_packet_delete (vat_main_t * vam)
19784 {
19785   unformat_input_t *i = vam->input;
19786   vl_api_af_packet_delete_t *mp;
19787   u8 *host_if_name = 0;
19788   int ret;
19789
19790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19791     {
19792       if (unformat (i, "name %s", &host_if_name))
19793         vec_add1 (host_if_name, 0);
19794       else
19795         break;
19796     }
19797
19798   if (!vec_len (host_if_name))
19799     {
19800       errmsg ("host-interface name must be specified");
19801       return -99;
19802     }
19803
19804   if (vec_len (host_if_name) > 64)
19805     {
19806       errmsg ("host-interface name too long");
19807       return -99;
19808     }
19809
19810   M (AF_PACKET_DELETE, mp);
19811
19812   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19813   vec_free (host_if_name);
19814
19815   S (mp);
19816   W (ret);
19817   return ret;
19818 }
19819
19820 static void vl_api_af_packet_details_t_handler
19821   (vl_api_af_packet_details_t * mp)
19822 {
19823   vat_main_t *vam = &vat_main;
19824
19825   print (vam->ofp, "%-16s %d",
19826          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19827 }
19828
19829 static void vl_api_af_packet_details_t_handler_json
19830   (vl_api_af_packet_details_t * mp)
19831 {
19832   vat_main_t *vam = &vat_main;
19833   vat_json_node_t *node = NULL;
19834
19835   if (VAT_JSON_ARRAY != vam->json_tree.type)
19836     {
19837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19838       vat_json_init_array (&vam->json_tree);
19839     }
19840   node = vat_json_array_add (&vam->json_tree);
19841
19842   vat_json_init_object (node);
19843   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19844   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19845 }
19846
19847 static int
19848 api_af_packet_dump (vat_main_t * vam)
19849 {
19850   vl_api_af_packet_dump_t *mp;
19851   vl_api_control_ping_t *mp_ping;
19852   int ret;
19853
19854   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19855   /* Get list of tap interfaces */
19856   M (AF_PACKET_DUMP, mp);
19857   S (mp);
19858
19859   /* Use a control ping for synchronization */
19860   MPING (CONTROL_PING, mp_ping);
19861   S (mp_ping);
19862
19863   W (ret);
19864   return ret;
19865 }
19866
19867 static int
19868 api_policer_add_del (vat_main_t * vam)
19869 {
19870   unformat_input_t *i = vam->input;
19871   vl_api_policer_add_del_t *mp;
19872   u8 is_add = 1;
19873   u8 *name = 0;
19874   u32 cir = 0;
19875   u32 eir = 0;
19876   u64 cb = 0;
19877   u64 eb = 0;
19878   u8 rate_type = 0;
19879   u8 round_type = 0;
19880   u8 type = 0;
19881   u8 color_aware = 0;
19882   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19883   int ret;
19884
19885   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19886   conform_action.dscp = 0;
19887   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19888   exceed_action.dscp = 0;
19889   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19890   violate_action.dscp = 0;
19891
19892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19893     {
19894       if (unformat (i, "del"))
19895         is_add = 0;
19896       else if (unformat (i, "name %s", &name))
19897         vec_add1 (name, 0);
19898       else if (unformat (i, "cir %u", &cir))
19899         ;
19900       else if (unformat (i, "eir %u", &eir))
19901         ;
19902       else if (unformat (i, "cb %u", &cb))
19903         ;
19904       else if (unformat (i, "eb %u", &eb))
19905         ;
19906       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19907                          &rate_type))
19908         ;
19909       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19910                          &round_type))
19911         ;
19912       else if (unformat (i, "type %U", unformat_policer_type, &type))
19913         ;
19914       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19915                          &conform_action))
19916         ;
19917       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19918                          &exceed_action))
19919         ;
19920       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19921                          &violate_action))
19922         ;
19923       else if (unformat (i, "color-aware"))
19924         color_aware = 1;
19925       else
19926         break;
19927     }
19928
19929   if (!vec_len (name))
19930     {
19931       errmsg ("policer name must be specified");
19932       return -99;
19933     }
19934
19935   if (vec_len (name) > 64)
19936     {
19937       errmsg ("policer name too long");
19938       return -99;
19939     }
19940
19941   M (POLICER_ADD_DEL, mp);
19942
19943   clib_memcpy (mp->name, name, vec_len (name));
19944   vec_free (name);
19945   mp->is_add = is_add;
19946   mp->cir = ntohl (cir);
19947   mp->eir = ntohl (eir);
19948   mp->cb = clib_net_to_host_u64 (cb);
19949   mp->eb = clib_net_to_host_u64 (eb);
19950   mp->rate_type = rate_type;
19951   mp->round_type = round_type;
19952   mp->type = type;
19953   mp->conform_action_type = conform_action.action_type;
19954   mp->conform_dscp = conform_action.dscp;
19955   mp->exceed_action_type = exceed_action.action_type;
19956   mp->exceed_dscp = exceed_action.dscp;
19957   mp->violate_action_type = violate_action.action_type;
19958   mp->violate_dscp = violate_action.dscp;
19959   mp->color_aware = color_aware;
19960
19961   S (mp);
19962   W (ret);
19963   return ret;
19964 }
19965
19966 static int
19967 api_policer_dump (vat_main_t * vam)
19968 {
19969   unformat_input_t *i = vam->input;
19970   vl_api_policer_dump_t *mp;
19971   vl_api_control_ping_t *mp_ping;
19972   u8 *match_name = 0;
19973   u8 match_name_valid = 0;
19974   int ret;
19975
19976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19977     {
19978       if (unformat (i, "name %s", &match_name))
19979         {
19980           vec_add1 (match_name, 0);
19981           match_name_valid = 1;
19982         }
19983       else
19984         break;
19985     }
19986
19987   M (POLICER_DUMP, mp);
19988   mp->match_name_valid = match_name_valid;
19989   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19990   vec_free (match_name);
19991   /* send it... */
19992   S (mp);
19993
19994   /* Use a control ping for synchronization */
19995   MPING (CONTROL_PING, mp_ping);
19996   S (mp_ping);
19997
19998   /* Wait for a reply... */
19999   W (ret);
20000   return ret;
20001 }
20002
20003 static int
20004 api_policer_classify_set_interface (vat_main_t * vam)
20005 {
20006   unformat_input_t *i = vam->input;
20007   vl_api_policer_classify_set_interface_t *mp;
20008   u32 sw_if_index;
20009   int sw_if_index_set;
20010   u32 ip4_table_index = ~0;
20011   u32 ip6_table_index = ~0;
20012   u32 l2_table_index = ~0;
20013   u8 is_add = 1;
20014   int ret;
20015
20016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20017     {
20018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20019         sw_if_index_set = 1;
20020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20021         sw_if_index_set = 1;
20022       else if (unformat (i, "del"))
20023         is_add = 0;
20024       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20025         ;
20026       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20027         ;
20028       else if (unformat (i, "l2-table %d", &l2_table_index))
20029         ;
20030       else
20031         {
20032           clib_warning ("parse error '%U'", format_unformat_error, i);
20033           return -99;
20034         }
20035     }
20036
20037   if (sw_if_index_set == 0)
20038     {
20039       errmsg ("missing interface name or sw_if_index");
20040       return -99;
20041     }
20042
20043   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20044
20045   mp->sw_if_index = ntohl (sw_if_index);
20046   mp->ip4_table_index = ntohl (ip4_table_index);
20047   mp->ip6_table_index = ntohl (ip6_table_index);
20048   mp->l2_table_index = ntohl (l2_table_index);
20049   mp->is_add = is_add;
20050
20051   S (mp);
20052   W (ret);
20053   return ret;
20054 }
20055
20056 static int
20057 api_policer_classify_dump (vat_main_t * vam)
20058 {
20059   unformat_input_t *i = vam->input;
20060   vl_api_policer_classify_dump_t *mp;
20061   vl_api_control_ping_t *mp_ping;
20062   u8 type = POLICER_CLASSIFY_N_TABLES;
20063   int ret;
20064
20065   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20066     ;
20067   else
20068     {
20069       errmsg ("classify table type must be specified");
20070       return -99;
20071     }
20072
20073   if (!vam->json_output)
20074     {
20075       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20076     }
20077
20078   M (POLICER_CLASSIFY_DUMP, mp);
20079   mp->type = type;
20080   /* send it... */
20081   S (mp);
20082
20083   /* Use a control ping for synchronization */
20084   MPING (CONTROL_PING, mp_ping);
20085   S (mp_ping);
20086
20087   /* Wait for a reply... */
20088   W (ret);
20089   return ret;
20090 }
20091
20092 static int
20093 api_netmap_create (vat_main_t * vam)
20094 {
20095   unformat_input_t *i = vam->input;
20096   vl_api_netmap_create_t *mp;
20097   u8 *if_name = 0;
20098   u8 hw_addr[6];
20099   u8 random_hw_addr = 1;
20100   u8 is_pipe = 0;
20101   u8 is_master = 0;
20102   int ret;
20103
20104   memset (hw_addr, 0, sizeof (hw_addr));
20105
20106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20107     {
20108       if (unformat (i, "name %s", &if_name))
20109         vec_add1 (if_name, 0);
20110       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20111         random_hw_addr = 0;
20112       else if (unformat (i, "pipe"))
20113         is_pipe = 1;
20114       else if (unformat (i, "master"))
20115         is_master = 1;
20116       else if (unformat (i, "slave"))
20117         is_master = 0;
20118       else
20119         break;
20120     }
20121
20122   if (!vec_len (if_name))
20123     {
20124       errmsg ("interface name must be specified");
20125       return -99;
20126     }
20127
20128   if (vec_len (if_name) > 64)
20129     {
20130       errmsg ("interface name too long");
20131       return -99;
20132     }
20133
20134   M (NETMAP_CREATE, mp);
20135
20136   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20137   clib_memcpy (mp->hw_addr, hw_addr, 6);
20138   mp->use_random_hw_addr = random_hw_addr;
20139   mp->is_pipe = is_pipe;
20140   mp->is_master = is_master;
20141   vec_free (if_name);
20142
20143   S (mp);
20144   W (ret);
20145   return ret;
20146 }
20147
20148 static int
20149 api_netmap_delete (vat_main_t * vam)
20150 {
20151   unformat_input_t *i = vam->input;
20152   vl_api_netmap_delete_t *mp;
20153   u8 *if_name = 0;
20154   int ret;
20155
20156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20157     {
20158       if (unformat (i, "name %s", &if_name))
20159         vec_add1 (if_name, 0);
20160       else
20161         break;
20162     }
20163
20164   if (!vec_len (if_name))
20165     {
20166       errmsg ("interface name must be specified");
20167       return -99;
20168     }
20169
20170   if (vec_len (if_name) > 64)
20171     {
20172       errmsg ("interface name too long");
20173       return -99;
20174     }
20175
20176   M (NETMAP_DELETE, mp);
20177
20178   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20179   vec_free (if_name);
20180
20181   S (mp);
20182   W (ret);
20183   return ret;
20184 }
20185
20186 static void
20187 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20188 {
20189   if (fp->afi == IP46_TYPE_IP6)
20190     print (vam->ofp,
20191            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20192            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20193            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20194            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20195            format_ip6_address, fp->next_hop);
20196   else if (fp->afi == IP46_TYPE_IP4)
20197     print (vam->ofp,
20198            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20199            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20200            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20201            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20202            format_ip4_address, fp->next_hop);
20203 }
20204
20205 static void
20206 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20207                                  vl_api_fib_path_t * fp)
20208 {
20209   struct in_addr ip4;
20210   struct in6_addr ip6;
20211
20212   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20213   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20214   vat_json_object_add_uint (node, "is_local", fp->is_local);
20215   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20216   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20217   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20218   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20219   if (fp->afi == IP46_TYPE_IP4)
20220     {
20221       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20222       vat_json_object_add_ip4 (node, "next_hop", ip4);
20223     }
20224   else if (fp->afi == IP46_TYPE_IP6)
20225     {
20226       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20227       vat_json_object_add_ip6 (node, "next_hop", ip6);
20228     }
20229 }
20230
20231 static void
20232 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20233 {
20234   vat_main_t *vam = &vat_main;
20235   int count = ntohl (mp->mt_count);
20236   vl_api_fib_path_t *fp;
20237   i32 i;
20238
20239   print (vam->ofp, "[%d]: sw_if_index %d via:",
20240          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20241   fp = mp->mt_paths;
20242   for (i = 0; i < count; i++)
20243     {
20244       vl_api_mpls_fib_path_print (vam, fp);
20245       fp++;
20246     }
20247
20248   print (vam->ofp, "");
20249 }
20250
20251 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20252 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20253
20254 static void
20255 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20256 {
20257   vat_main_t *vam = &vat_main;
20258   vat_json_node_t *node = NULL;
20259   int count = ntohl (mp->mt_count);
20260   vl_api_fib_path_t *fp;
20261   i32 i;
20262
20263   if (VAT_JSON_ARRAY != vam->json_tree.type)
20264     {
20265       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20266       vat_json_init_array (&vam->json_tree);
20267     }
20268   node = vat_json_array_add (&vam->json_tree);
20269
20270   vat_json_init_object (node);
20271   vat_json_object_add_uint (node, "tunnel_index",
20272                             ntohl (mp->mt_tunnel_index));
20273   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20274
20275   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20276
20277   fp = mp->mt_paths;
20278   for (i = 0; i < count; i++)
20279     {
20280       vl_api_mpls_fib_path_json_print (node, fp);
20281       fp++;
20282     }
20283 }
20284
20285 static int
20286 api_mpls_tunnel_dump (vat_main_t * vam)
20287 {
20288   vl_api_mpls_tunnel_dump_t *mp;
20289   vl_api_control_ping_t *mp_ping;
20290   i32 index = -1;
20291   int ret;
20292
20293   /* Parse args required to build the message */
20294   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20295     {
20296       if (!unformat (vam->input, "tunnel_index %d", &index))
20297         {
20298           index = -1;
20299           break;
20300         }
20301     }
20302
20303   print (vam->ofp, "  tunnel_index %d", index);
20304
20305   M (MPLS_TUNNEL_DUMP, mp);
20306   mp->tunnel_index = htonl (index);
20307   S (mp);
20308
20309   /* Use a control ping for synchronization */
20310   MPING (CONTROL_PING, mp_ping);
20311   S (mp_ping);
20312
20313   W (ret);
20314   return ret;
20315 }
20316
20317 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20318 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20319
20320
20321 static void
20322 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20323 {
20324   vat_main_t *vam = &vat_main;
20325   int count = ntohl (mp->count);
20326   vl_api_fib_path_t *fp;
20327   int i;
20328
20329   print (vam->ofp,
20330          "table-id %d, label %u, ess_bit %u",
20331          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20332   fp = mp->path;
20333   for (i = 0; i < count; i++)
20334     {
20335       vl_api_mpls_fib_path_print (vam, fp);
20336       fp++;
20337     }
20338 }
20339
20340 static void vl_api_mpls_fib_details_t_handler_json
20341   (vl_api_mpls_fib_details_t * mp)
20342 {
20343   vat_main_t *vam = &vat_main;
20344   int count = ntohl (mp->count);
20345   vat_json_node_t *node = NULL;
20346   vl_api_fib_path_t *fp;
20347   int i;
20348
20349   if (VAT_JSON_ARRAY != vam->json_tree.type)
20350     {
20351       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20352       vat_json_init_array (&vam->json_tree);
20353     }
20354   node = vat_json_array_add (&vam->json_tree);
20355
20356   vat_json_init_object (node);
20357   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20358   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20359   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20360   vat_json_object_add_uint (node, "path_count", count);
20361   fp = mp->path;
20362   for (i = 0; i < count; i++)
20363     {
20364       vl_api_mpls_fib_path_json_print (node, fp);
20365       fp++;
20366     }
20367 }
20368
20369 static int
20370 api_mpls_fib_dump (vat_main_t * vam)
20371 {
20372   vl_api_mpls_fib_dump_t *mp;
20373   vl_api_control_ping_t *mp_ping;
20374   int ret;
20375
20376   M (MPLS_FIB_DUMP, mp);
20377   S (mp);
20378
20379   /* Use a control ping for synchronization */
20380   MPING (CONTROL_PING, mp_ping);
20381   S (mp_ping);
20382
20383   W (ret);
20384   return ret;
20385 }
20386
20387 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20388 #define vl_api_ip_fib_details_t_print vl_noop_handler
20389
20390 static void
20391 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20392 {
20393   vat_main_t *vam = &vat_main;
20394   int count = ntohl (mp->count);
20395   vl_api_fib_path_t *fp;
20396   int i;
20397
20398   print (vam->ofp,
20399          "table-id %d, prefix %U/%d",
20400          ntohl (mp->table_id), format_ip4_address, mp->address,
20401          mp->address_length);
20402   fp = mp->path;
20403   for (i = 0; i < count; i++)
20404     {
20405       if (fp->afi == IP46_TYPE_IP6)
20406         print (vam->ofp,
20407                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20408                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20409                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20410                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20411                format_ip6_address, fp->next_hop);
20412       else if (fp->afi == IP46_TYPE_IP4)
20413         print (vam->ofp,
20414                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20415                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20416                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20417                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20418                format_ip4_address, fp->next_hop);
20419       fp++;
20420     }
20421 }
20422
20423 static void vl_api_ip_fib_details_t_handler_json
20424   (vl_api_ip_fib_details_t * mp)
20425 {
20426   vat_main_t *vam = &vat_main;
20427   int count = ntohl (mp->count);
20428   vat_json_node_t *node = NULL;
20429   struct in_addr ip4;
20430   struct in6_addr ip6;
20431   vl_api_fib_path_t *fp;
20432   int i;
20433
20434   if (VAT_JSON_ARRAY != vam->json_tree.type)
20435     {
20436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20437       vat_json_init_array (&vam->json_tree);
20438     }
20439   node = vat_json_array_add (&vam->json_tree);
20440
20441   vat_json_init_object (node);
20442   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20443   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20444   vat_json_object_add_ip4 (node, "prefix", ip4);
20445   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20446   vat_json_object_add_uint (node, "path_count", count);
20447   fp = mp->path;
20448   for (i = 0; i < count; i++)
20449     {
20450       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20451       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20452       vat_json_object_add_uint (node, "is_local", fp->is_local);
20453       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20454       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20455       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20456       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20457       if (fp->afi == IP46_TYPE_IP4)
20458         {
20459           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20460           vat_json_object_add_ip4 (node, "next_hop", ip4);
20461         }
20462       else if (fp->afi == IP46_TYPE_IP6)
20463         {
20464           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20465           vat_json_object_add_ip6 (node, "next_hop", ip6);
20466         }
20467     }
20468 }
20469
20470 static int
20471 api_ip_fib_dump (vat_main_t * vam)
20472 {
20473   vl_api_ip_fib_dump_t *mp;
20474   vl_api_control_ping_t *mp_ping;
20475   int ret;
20476
20477   M (IP_FIB_DUMP, mp);
20478   S (mp);
20479
20480   /* Use a control ping for synchronization */
20481   MPING (CONTROL_PING, mp_ping);
20482   S (mp_ping);
20483
20484   W (ret);
20485   return ret;
20486 }
20487
20488 static int
20489 api_ip_mfib_dump (vat_main_t * vam)
20490 {
20491   vl_api_ip_mfib_dump_t *mp;
20492   vl_api_control_ping_t *mp_ping;
20493   int ret;
20494
20495   M (IP_MFIB_DUMP, mp);
20496   S (mp);
20497
20498   /* Use a control ping for synchronization */
20499   MPING (CONTROL_PING, mp_ping);
20500   S (mp_ping);
20501
20502   W (ret);
20503   return ret;
20504 }
20505
20506 static void vl_api_ip_neighbor_details_t_handler
20507   (vl_api_ip_neighbor_details_t * mp)
20508 {
20509   vat_main_t *vam = &vat_main;
20510
20511   print (vam->ofp, "%c %U %U",
20512          (mp->is_static) ? 'S' : 'D',
20513          format_ethernet_address, &mp->mac_address,
20514          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20515          &mp->ip_address);
20516 }
20517
20518 static void vl_api_ip_neighbor_details_t_handler_json
20519   (vl_api_ip_neighbor_details_t * mp)
20520 {
20521
20522   vat_main_t *vam = &vat_main;
20523   vat_json_node_t *node;
20524   struct in_addr ip4;
20525   struct in6_addr ip6;
20526
20527   if (VAT_JSON_ARRAY != vam->json_tree.type)
20528     {
20529       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20530       vat_json_init_array (&vam->json_tree);
20531     }
20532   node = vat_json_array_add (&vam->json_tree);
20533
20534   vat_json_init_object (node);
20535   vat_json_object_add_string_copy (node, "flag",
20536                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20537                                    "dynamic");
20538
20539   vat_json_object_add_string_copy (node, "link_layer",
20540                                    format (0, "%U", format_ethernet_address,
20541                                            &mp->mac_address));
20542
20543   if (mp->is_ipv6)
20544     {
20545       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20546       vat_json_object_add_ip6 (node, "ip_address", ip6);
20547     }
20548   else
20549     {
20550       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20551       vat_json_object_add_ip4 (node, "ip_address", ip4);
20552     }
20553 }
20554
20555 static int
20556 api_ip_neighbor_dump (vat_main_t * vam)
20557 {
20558   unformat_input_t *i = vam->input;
20559   vl_api_ip_neighbor_dump_t *mp;
20560   vl_api_control_ping_t *mp_ping;
20561   u8 is_ipv6 = 0;
20562   u32 sw_if_index = ~0;
20563   int ret;
20564
20565   /* Parse args required to build the message */
20566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20567     {
20568       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20569         ;
20570       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20571         ;
20572       else if (unformat (i, "ip6"))
20573         is_ipv6 = 1;
20574       else
20575         break;
20576     }
20577
20578   if (sw_if_index == ~0)
20579     {
20580       errmsg ("missing interface name or sw_if_index");
20581       return -99;
20582     }
20583
20584   M (IP_NEIGHBOR_DUMP, mp);
20585   mp->is_ipv6 = (u8) is_ipv6;
20586   mp->sw_if_index = ntohl (sw_if_index);
20587   S (mp);
20588
20589   /* Use a control ping for synchronization */
20590   MPING (CONTROL_PING, mp_ping);
20591   S (mp_ping);
20592
20593   W (ret);
20594   return ret;
20595 }
20596
20597 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20598 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20599
20600 static void
20601 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20602 {
20603   vat_main_t *vam = &vat_main;
20604   int count = ntohl (mp->count);
20605   vl_api_fib_path_t *fp;
20606   int i;
20607
20608   print (vam->ofp,
20609          "table-id %d, prefix %U/%d",
20610          ntohl (mp->table_id), format_ip6_address, mp->address,
20611          mp->address_length);
20612   fp = mp->path;
20613   for (i = 0; i < count; i++)
20614     {
20615       if (fp->afi == IP46_TYPE_IP6)
20616         print (vam->ofp,
20617                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20618                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20619                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20620                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20621                format_ip6_address, fp->next_hop);
20622       else if (fp->afi == IP46_TYPE_IP4)
20623         print (vam->ofp,
20624                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20625                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20626                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20627                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20628                format_ip4_address, fp->next_hop);
20629       fp++;
20630     }
20631 }
20632
20633 static void vl_api_ip6_fib_details_t_handler_json
20634   (vl_api_ip6_fib_details_t * mp)
20635 {
20636   vat_main_t *vam = &vat_main;
20637   int count = ntohl (mp->count);
20638   vat_json_node_t *node = NULL;
20639   struct in_addr ip4;
20640   struct in6_addr ip6;
20641   vl_api_fib_path_t *fp;
20642   int i;
20643
20644   if (VAT_JSON_ARRAY != vam->json_tree.type)
20645     {
20646       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20647       vat_json_init_array (&vam->json_tree);
20648     }
20649   node = vat_json_array_add (&vam->json_tree);
20650
20651   vat_json_init_object (node);
20652   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20653   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20654   vat_json_object_add_ip6 (node, "prefix", ip6);
20655   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20656   vat_json_object_add_uint (node, "path_count", count);
20657   fp = mp->path;
20658   for (i = 0; i < count; i++)
20659     {
20660       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20661       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20662       vat_json_object_add_uint (node, "is_local", fp->is_local);
20663       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20664       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20665       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20666       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20667       if (fp->afi == IP46_TYPE_IP4)
20668         {
20669           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20670           vat_json_object_add_ip4 (node, "next_hop", ip4);
20671         }
20672       else if (fp->afi == IP46_TYPE_IP6)
20673         {
20674           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20675           vat_json_object_add_ip6 (node, "next_hop", ip6);
20676         }
20677     }
20678 }
20679
20680 static int
20681 api_ip6_fib_dump (vat_main_t * vam)
20682 {
20683   vl_api_ip6_fib_dump_t *mp;
20684   vl_api_control_ping_t *mp_ping;
20685   int ret;
20686
20687   M (IP6_FIB_DUMP, mp);
20688   S (mp);
20689
20690   /* Use a control ping for synchronization */
20691   MPING (CONTROL_PING, mp_ping);
20692   S (mp_ping);
20693
20694   W (ret);
20695   return ret;
20696 }
20697
20698 static int
20699 api_ip6_mfib_dump (vat_main_t * vam)
20700 {
20701   vl_api_ip6_mfib_dump_t *mp;
20702   vl_api_control_ping_t *mp_ping;
20703   int ret;
20704
20705   M (IP6_MFIB_DUMP, mp);
20706   S (mp);
20707
20708   /* Use a control ping for synchronization */
20709   MPING (CONTROL_PING, mp_ping);
20710   S (mp_ping);
20711
20712   W (ret);
20713   return ret;
20714 }
20715
20716 int
20717 api_classify_table_ids (vat_main_t * vam)
20718 {
20719   vl_api_classify_table_ids_t *mp;
20720   int ret;
20721
20722   /* Construct the API message */
20723   M (CLASSIFY_TABLE_IDS, mp);
20724   mp->context = 0;
20725
20726   S (mp);
20727   W (ret);
20728   return ret;
20729 }
20730
20731 int
20732 api_classify_table_by_interface (vat_main_t * vam)
20733 {
20734   unformat_input_t *input = vam->input;
20735   vl_api_classify_table_by_interface_t *mp;
20736
20737   u32 sw_if_index = ~0;
20738   int ret;
20739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20740     {
20741       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20742         ;
20743       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20744         ;
20745       else
20746         break;
20747     }
20748   if (sw_if_index == ~0)
20749     {
20750       errmsg ("missing interface name or sw_if_index");
20751       return -99;
20752     }
20753
20754   /* Construct the API message */
20755   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20756   mp->context = 0;
20757   mp->sw_if_index = ntohl (sw_if_index);
20758
20759   S (mp);
20760   W (ret);
20761   return ret;
20762 }
20763
20764 int
20765 api_classify_table_info (vat_main_t * vam)
20766 {
20767   unformat_input_t *input = vam->input;
20768   vl_api_classify_table_info_t *mp;
20769
20770   u32 table_id = ~0;
20771   int ret;
20772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20773     {
20774       if (unformat (input, "table_id %d", &table_id))
20775         ;
20776       else
20777         break;
20778     }
20779   if (table_id == ~0)
20780     {
20781       errmsg ("missing table id");
20782       return -99;
20783     }
20784
20785   /* Construct the API message */
20786   M (CLASSIFY_TABLE_INFO, mp);
20787   mp->context = 0;
20788   mp->table_id = ntohl (table_id);
20789
20790   S (mp);
20791   W (ret);
20792   return ret;
20793 }
20794
20795 int
20796 api_classify_session_dump (vat_main_t * vam)
20797 {
20798   unformat_input_t *input = vam->input;
20799   vl_api_classify_session_dump_t *mp;
20800   vl_api_control_ping_t *mp_ping;
20801
20802   u32 table_id = ~0;
20803   int ret;
20804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20805     {
20806       if (unformat (input, "table_id %d", &table_id))
20807         ;
20808       else
20809         break;
20810     }
20811   if (table_id == ~0)
20812     {
20813       errmsg ("missing table id");
20814       return -99;
20815     }
20816
20817   /* Construct the API message */
20818   M (CLASSIFY_SESSION_DUMP, mp);
20819   mp->context = 0;
20820   mp->table_id = ntohl (table_id);
20821   S (mp);
20822
20823   /* Use a control ping for synchronization */
20824   MPING (CONTROL_PING, mp_ping);
20825   S (mp_ping);
20826
20827   W (ret);
20828   return ret;
20829 }
20830
20831 static void
20832 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20833 {
20834   vat_main_t *vam = &vat_main;
20835
20836   print (vam->ofp, "collector_address %U, collector_port %d, "
20837          "src_address %U, vrf_id %d, path_mtu %u, "
20838          "template_interval %u, udp_checksum %d",
20839          format_ip4_address, mp->collector_address,
20840          ntohs (mp->collector_port),
20841          format_ip4_address, mp->src_address,
20842          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20843          ntohl (mp->template_interval), mp->udp_checksum);
20844
20845   vam->retval = 0;
20846   vam->result_ready = 1;
20847 }
20848
20849 static void
20850   vl_api_ipfix_exporter_details_t_handler_json
20851   (vl_api_ipfix_exporter_details_t * mp)
20852 {
20853   vat_main_t *vam = &vat_main;
20854   vat_json_node_t node;
20855   struct in_addr collector_address;
20856   struct in_addr src_address;
20857
20858   vat_json_init_object (&node);
20859   clib_memcpy (&collector_address, &mp->collector_address,
20860                sizeof (collector_address));
20861   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20862   vat_json_object_add_uint (&node, "collector_port",
20863                             ntohs (mp->collector_port));
20864   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20865   vat_json_object_add_ip4 (&node, "src_address", src_address);
20866   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20867   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20868   vat_json_object_add_uint (&node, "template_interval",
20869                             ntohl (mp->template_interval));
20870   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20871
20872   vat_json_print (vam->ofp, &node);
20873   vat_json_free (&node);
20874   vam->retval = 0;
20875   vam->result_ready = 1;
20876 }
20877
20878 int
20879 api_ipfix_exporter_dump (vat_main_t * vam)
20880 {
20881   vl_api_ipfix_exporter_dump_t *mp;
20882   int ret;
20883
20884   /* Construct the API message */
20885   M (IPFIX_EXPORTER_DUMP, mp);
20886   mp->context = 0;
20887
20888   S (mp);
20889   W (ret);
20890   return ret;
20891 }
20892
20893 static int
20894 api_ipfix_classify_stream_dump (vat_main_t * vam)
20895 {
20896   vl_api_ipfix_classify_stream_dump_t *mp;
20897   int ret;
20898
20899   /* Construct the API message */
20900   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20901   mp->context = 0;
20902
20903   S (mp);
20904   W (ret);
20905   return ret;
20906   /* NOTREACHED */
20907   return 0;
20908 }
20909
20910 static void
20911   vl_api_ipfix_classify_stream_details_t_handler
20912   (vl_api_ipfix_classify_stream_details_t * mp)
20913 {
20914   vat_main_t *vam = &vat_main;
20915   print (vam->ofp, "domain_id %d, src_port %d",
20916          ntohl (mp->domain_id), ntohs (mp->src_port));
20917   vam->retval = 0;
20918   vam->result_ready = 1;
20919 }
20920
20921 static void
20922   vl_api_ipfix_classify_stream_details_t_handler_json
20923   (vl_api_ipfix_classify_stream_details_t * mp)
20924 {
20925   vat_main_t *vam = &vat_main;
20926   vat_json_node_t node;
20927
20928   vat_json_init_object (&node);
20929   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20930   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20931
20932   vat_json_print (vam->ofp, &node);
20933   vat_json_free (&node);
20934   vam->retval = 0;
20935   vam->result_ready = 1;
20936 }
20937
20938 static int
20939 api_ipfix_classify_table_dump (vat_main_t * vam)
20940 {
20941   vl_api_ipfix_classify_table_dump_t *mp;
20942   vl_api_control_ping_t *mp_ping;
20943   int ret;
20944
20945   if (!vam->json_output)
20946     {
20947       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20948              "transport_protocol");
20949     }
20950
20951   /* Construct the API message */
20952   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20953
20954   /* send it... */
20955   S (mp);
20956
20957   /* Use a control ping for synchronization */
20958   MPING (CONTROL_PING, mp_ping);
20959   S (mp_ping);
20960
20961   W (ret);
20962   return ret;
20963 }
20964
20965 static void
20966   vl_api_ipfix_classify_table_details_t_handler
20967   (vl_api_ipfix_classify_table_details_t * mp)
20968 {
20969   vat_main_t *vam = &vat_main;
20970   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20971          mp->transport_protocol);
20972 }
20973
20974 static void
20975   vl_api_ipfix_classify_table_details_t_handler_json
20976   (vl_api_ipfix_classify_table_details_t * mp)
20977 {
20978   vat_json_node_t *node = NULL;
20979   vat_main_t *vam = &vat_main;
20980
20981   if (VAT_JSON_ARRAY != vam->json_tree.type)
20982     {
20983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20984       vat_json_init_array (&vam->json_tree);
20985     }
20986
20987   node = vat_json_array_add (&vam->json_tree);
20988   vat_json_init_object (node);
20989
20990   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20991   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20992   vat_json_object_add_uint (node, "transport_protocol",
20993                             mp->transport_protocol);
20994 }
20995
20996 static int
20997 api_sw_interface_span_enable_disable (vat_main_t * vam)
20998 {
20999   unformat_input_t *i = vam->input;
21000   vl_api_sw_interface_span_enable_disable_t *mp;
21001   u32 src_sw_if_index = ~0;
21002   u32 dst_sw_if_index = ~0;
21003   u8 state = 3;
21004   int ret;
21005   u8 is_l2 = 0;
21006
21007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21008     {
21009       if (unformat
21010           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21011         ;
21012       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21013         ;
21014       else
21015         if (unformat
21016             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21017         ;
21018       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21019         ;
21020       else if (unformat (i, "disable"))
21021         state = 0;
21022       else if (unformat (i, "rx"))
21023         state = 1;
21024       else if (unformat (i, "tx"))
21025         state = 2;
21026       else if (unformat (i, "both"))
21027         state = 3;
21028       else if (unformat (i, "l2"))
21029         is_l2 = 1;
21030       else
21031         break;
21032     }
21033
21034   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21035
21036   mp->sw_if_index_from = htonl (src_sw_if_index);
21037   mp->sw_if_index_to = htonl (dst_sw_if_index);
21038   mp->state = state;
21039   mp->is_l2 = is_l2;
21040
21041   S (mp);
21042   W (ret);
21043   return ret;
21044 }
21045
21046 static void
21047 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21048                                             * mp)
21049 {
21050   vat_main_t *vam = &vat_main;
21051   u8 *sw_if_from_name = 0;
21052   u8 *sw_if_to_name = 0;
21053   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21054   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21055   char *states[] = { "none", "rx", "tx", "both" };
21056   hash_pair_t *p;
21057
21058   /* *INDENT-OFF* */
21059   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21060   ({
21061     if ((u32) p->value[0] == sw_if_index_from)
21062       {
21063         sw_if_from_name = (u8 *)(p->key);
21064         if (sw_if_to_name)
21065           break;
21066       }
21067     if ((u32) p->value[0] == sw_if_index_to)
21068       {
21069         sw_if_to_name = (u8 *)(p->key);
21070         if (sw_if_from_name)
21071           break;
21072       }
21073   }));
21074   /* *INDENT-ON* */
21075   print (vam->ofp, "%20s => %20s (%s) %s",
21076          sw_if_from_name, sw_if_to_name, states[mp->state],
21077          mp->is_l2 ? "l2" : "device");
21078 }
21079
21080 static void
21081   vl_api_sw_interface_span_details_t_handler_json
21082   (vl_api_sw_interface_span_details_t * mp)
21083 {
21084   vat_main_t *vam = &vat_main;
21085   vat_json_node_t *node = NULL;
21086   u8 *sw_if_from_name = 0;
21087   u8 *sw_if_to_name = 0;
21088   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21089   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21090   hash_pair_t *p;
21091
21092   /* *INDENT-OFF* */
21093   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21094   ({
21095     if ((u32) p->value[0] == sw_if_index_from)
21096       {
21097         sw_if_from_name = (u8 *)(p->key);
21098         if (sw_if_to_name)
21099           break;
21100       }
21101     if ((u32) p->value[0] == sw_if_index_to)
21102       {
21103         sw_if_to_name = (u8 *)(p->key);
21104         if (sw_if_from_name)
21105           break;
21106       }
21107   }));
21108   /* *INDENT-ON* */
21109
21110   if (VAT_JSON_ARRAY != vam->json_tree.type)
21111     {
21112       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21113       vat_json_init_array (&vam->json_tree);
21114     }
21115   node = vat_json_array_add (&vam->json_tree);
21116
21117   vat_json_init_object (node);
21118   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21119   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21120   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21121   if (0 != sw_if_to_name)
21122     {
21123       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21124     }
21125   vat_json_object_add_uint (node, "state", mp->state);
21126   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21127 }
21128
21129 static int
21130 api_sw_interface_span_dump (vat_main_t * vam)
21131 {
21132   unformat_input_t *input = vam->input;
21133   vl_api_sw_interface_span_dump_t *mp;
21134   vl_api_control_ping_t *mp_ping;
21135   u8 is_l2 = 0;
21136   int ret;
21137
21138   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21139     {
21140       if (unformat (input, "l2"))
21141         is_l2 = 1;
21142       else
21143         break;
21144     }
21145
21146   M (SW_INTERFACE_SPAN_DUMP, mp);
21147   mp->is_l2 = is_l2;
21148   S (mp);
21149
21150   /* Use a control ping for synchronization */
21151   MPING (CONTROL_PING, mp_ping);
21152   S (mp_ping);
21153
21154   W (ret);
21155   return ret;
21156 }
21157
21158 int
21159 api_pg_create_interface (vat_main_t * vam)
21160 {
21161   unformat_input_t *input = vam->input;
21162   vl_api_pg_create_interface_t *mp;
21163
21164   u32 if_id = ~0;
21165   int ret;
21166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21167     {
21168       if (unformat (input, "if_id %d", &if_id))
21169         ;
21170       else
21171         break;
21172     }
21173   if (if_id == ~0)
21174     {
21175       errmsg ("missing pg interface index");
21176       return -99;
21177     }
21178
21179   /* Construct the API message */
21180   M (PG_CREATE_INTERFACE, mp);
21181   mp->context = 0;
21182   mp->interface_id = ntohl (if_id);
21183
21184   S (mp);
21185   W (ret);
21186   return ret;
21187 }
21188
21189 int
21190 api_pg_capture (vat_main_t * vam)
21191 {
21192   unformat_input_t *input = vam->input;
21193   vl_api_pg_capture_t *mp;
21194
21195   u32 if_id = ~0;
21196   u8 enable = 1;
21197   u32 count = 1;
21198   u8 pcap_file_set = 0;
21199   u8 *pcap_file = 0;
21200   int ret;
21201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21202     {
21203       if (unformat (input, "if_id %d", &if_id))
21204         ;
21205       else if (unformat (input, "pcap %s", &pcap_file))
21206         pcap_file_set = 1;
21207       else if (unformat (input, "count %d", &count))
21208         ;
21209       else if (unformat (input, "disable"))
21210         enable = 0;
21211       else
21212         break;
21213     }
21214   if (if_id == ~0)
21215     {
21216       errmsg ("missing pg interface index");
21217       return -99;
21218     }
21219   if (pcap_file_set > 0)
21220     {
21221       if (vec_len (pcap_file) > 255)
21222         {
21223           errmsg ("pcap file name is too long");
21224           return -99;
21225         }
21226     }
21227
21228   u32 name_len = vec_len (pcap_file);
21229   /* Construct the API message */
21230   M (PG_CAPTURE, mp);
21231   mp->context = 0;
21232   mp->interface_id = ntohl (if_id);
21233   mp->is_enabled = enable;
21234   mp->count = ntohl (count);
21235   mp->pcap_name_length = ntohl (name_len);
21236   if (pcap_file_set != 0)
21237     {
21238       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21239     }
21240   vec_free (pcap_file);
21241
21242   S (mp);
21243   W (ret);
21244   return ret;
21245 }
21246
21247 int
21248 api_pg_enable_disable (vat_main_t * vam)
21249 {
21250   unformat_input_t *input = vam->input;
21251   vl_api_pg_enable_disable_t *mp;
21252
21253   u8 enable = 1;
21254   u8 stream_name_set = 0;
21255   u8 *stream_name = 0;
21256   int ret;
21257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21258     {
21259       if (unformat (input, "stream %s", &stream_name))
21260         stream_name_set = 1;
21261       else if (unformat (input, "disable"))
21262         enable = 0;
21263       else
21264         break;
21265     }
21266
21267   if (stream_name_set > 0)
21268     {
21269       if (vec_len (stream_name) > 255)
21270         {
21271           errmsg ("stream name too long");
21272           return -99;
21273         }
21274     }
21275
21276   u32 name_len = vec_len (stream_name);
21277   /* Construct the API message */
21278   M (PG_ENABLE_DISABLE, mp);
21279   mp->context = 0;
21280   mp->is_enabled = enable;
21281   if (stream_name_set != 0)
21282     {
21283       mp->stream_name_length = ntohl (name_len);
21284       clib_memcpy (mp->stream_name, stream_name, name_len);
21285     }
21286   vec_free (stream_name);
21287
21288   S (mp);
21289   W (ret);
21290   return ret;
21291 }
21292
21293 int
21294 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21295 {
21296   unformat_input_t *input = vam->input;
21297   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21298
21299   u16 *low_ports = 0;
21300   u16 *high_ports = 0;
21301   u16 this_low;
21302   u16 this_hi;
21303   ip4_address_t ip4_addr;
21304   ip6_address_t ip6_addr;
21305   u32 length;
21306   u32 tmp, tmp2;
21307   u8 prefix_set = 0;
21308   u32 vrf_id = ~0;
21309   u8 is_add = 1;
21310   u8 is_ipv6 = 0;
21311   int ret;
21312
21313   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21314     {
21315       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21316         {
21317           prefix_set = 1;
21318         }
21319       else
21320         if (unformat
21321             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21322         {
21323           prefix_set = 1;
21324           is_ipv6 = 1;
21325         }
21326       else if (unformat (input, "vrf %d", &vrf_id))
21327         ;
21328       else if (unformat (input, "del"))
21329         is_add = 0;
21330       else if (unformat (input, "port %d", &tmp))
21331         {
21332           if (tmp == 0 || tmp > 65535)
21333             {
21334               errmsg ("port %d out of range", tmp);
21335               return -99;
21336             }
21337           this_low = tmp;
21338           this_hi = this_low + 1;
21339           vec_add1 (low_ports, this_low);
21340           vec_add1 (high_ports, this_hi);
21341         }
21342       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21343         {
21344           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21345             {
21346               errmsg ("incorrect range parameters");
21347               return -99;
21348             }
21349           this_low = tmp;
21350           /* Note: in debug CLI +1 is added to high before
21351              passing to real fn that does "the work"
21352              (ip_source_and_port_range_check_add_del).
21353              This fn is a wrapper around the binary API fn a
21354              control plane will call, which expects this increment
21355              to have occurred. Hence letting the binary API control
21356              plane fn do the increment for consistency between VAT
21357              and other control planes.
21358            */
21359           this_hi = tmp2;
21360           vec_add1 (low_ports, this_low);
21361           vec_add1 (high_ports, this_hi);
21362         }
21363       else
21364         break;
21365     }
21366
21367   if (prefix_set == 0)
21368     {
21369       errmsg ("<address>/<mask> not specified");
21370       return -99;
21371     }
21372
21373   if (vrf_id == ~0)
21374     {
21375       errmsg ("VRF ID required, not specified");
21376       return -99;
21377     }
21378
21379   if (vrf_id == 0)
21380     {
21381       errmsg
21382         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21383       return -99;
21384     }
21385
21386   if (vec_len (low_ports) == 0)
21387     {
21388       errmsg ("At least one port or port range required");
21389       return -99;
21390     }
21391
21392   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21393
21394   mp->is_add = is_add;
21395
21396   if (is_ipv6)
21397     {
21398       mp->is_ipv6 = 1;
21399       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21400     }
21401   else
21402     {
21403       mp->is_ipv6 = 0;
21404       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21405     }
21406
21407   mp->mask_length = length;
21408   mp->number_of_ranges = vec_len (low_ports);
21409
21410   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21411   vec_free (low_ports);
21412
21413   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21414   vec_free (high_ports);
21415
21416   mp->vrf_id = ntohl (vrf_id);
21417
21418   S (mp);
21419   W (ret);
21420   return ret;
21421 }
21422
21423 int
21424 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21425 {
21426   unformat_input_t *input = vam->input;
21427   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21428   u32 sw_if_index = ~0;
21429   int vrf_set = 0;
21430   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21431   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21432   u8 is_add = 1;
21433   int ret;
21434
21435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21436     {
21437       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21438         ;
21439       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21440         ;
21441       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21442         vrf_set = 1;
21443       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21444         vrf_set = 1;
21445       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21446         vrf_set = 1;
21447       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21448         vrf_set = 1;
21449       else if (unformat (input, "del"))
21450         is_add = 0;
21451       else
21452         break;
21453     }
21454
21455   if (sw_if_index == ~0)
21456     {
21457       errmsg ("Interface required but not specified");
21458       return -99;
21459     }
21460
21461   if (vrf_set == 0)
21462     {
21463       errmsg ("VRF ID required but not specified");
21464       return -99;
21465     }
21466
21467   if (tcp_out_vrf_id == 0
21468       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21469     {
21470       errmsg
21471         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21472       return -99;
21473     }
21474
21475   /* Construct the API message */
21476   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21477
21478   mp->sw_if_index = ntohl (sw_if_index);
21479   mp->is_add = is_add;
21480   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21481   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21482   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21483   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21484
21485   /* send it... */
21486   S (mp);
21487
21488   /* Wait for a reply... */
21489   W (ret);
21490   return ret;
21491 }
21492
21493 static int
21494 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21495 {
21496   unformat_input_t *i = vam->input;
21497   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21498   u32 local_sa_id = 0;
21499   u32 remote_sa_id = 0;
21500   ip4_address_t src_address;
21501   ip4_address_t dst_address;
21502   u8 is_add = 1;
21503   int ret;
21504
21505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21506     {
21507       if (unformat (i, "local_sa %d", &local_sa_id))
21508         ;
21509       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21510         ;
21511       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21512         ;
21513       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21514         ;
21515       else if (unformat (i, "del"))
21516         is_add = 0;
21517       else
21518         {
21519           clib_warning ("parse error '%U'", format_unformat_error, i);
21520           return -99;
21521         }
21522     }
21523
21524   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21525
21526   mp->local_sa_id = ntohl (local_sa_id);
21527   mp->remote_sa_id = ntohl (remote_sa_id);
21528   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21529   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21530   mp->is_add = is_add;
21531
21532   S (mp);
21533   W (ret);
21534   return ret;
21535 }
21536
21537 static int
21538 api_punt (vat_main_t * vam)
21539 {
21540   unformat_input_t *i = vam->input;
21541   vl_api_punt_t *mp;
21542   u32 ipv = ~0;
21543   u32 protocol = ~0;
21544   u32 port = ~0;
21545   int is_add = 1;
21546   int ret;
21547
21548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21549     {
21550       if (unformat (i, "ip %d", &ipv))
21551         ;
21552       else if (unformat (i, "protocol %d", &protocol))
21553         ;
21554       else if (unformat (i, "port %d", &port))
21555         ;
21556       else if (unformat (i, "del"))
21557         is_add = 0;
21558       else
21559         {
21560           clib_warning ("parse error '%U'", format_unformat_error, i);
21561           return -99;
21562         }
21563     }
21564
21565   M (PUNT, mp);
21566
21567   mp->is_add = (u8) is_add;
21568   mp->ipv = (u8) ipv;
21569   mp->l4_protocol = (u8) protocol;
21570   mp->l4_port = htons ((u16) port);
21571
21572   S (mp);
21573   W (ret);
21574   return ret;
21575 }
21576
21577 static void vl_api_ipsec_gre_tunnel_details_t_handler
21578   (vl_api_ipsec_gre_tunnel_details_t * mp)
21579 {
21580   vat_main_t *vam = &vat_main;
21581
21582   print (vam->ofp, "%11d%15U%15U%14d%14d",
21583          ntohl (mp->sw_if_index),
21584          format_ip4_address, &mp->src_address,
21585          format_ip4_address, &mp->dst_address,
21586          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21587 }
21588
21589 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21590   (vl_api_ipsec_gre_tunnel_details_t * mp)
21591 {
21592   vat_main_t *vam = &vat_main;
21593   vat_json_node_t *node = NULL;
21594   struct in_addr ip4;
21595
21596   if (VAT_JSON_ARRAY != vam->json_tree.type)
21597     {
21598       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21599       vat_json_init_array (&vam->json_tree);
21600     }
21601   node = vat_json_array_add (&vam->json_tree);
21602
21603   vat_json_init_object (node);
21604   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21605   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21606   vat_json_object_add_ip4 (node, "src_address", ip4);
21607   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21608   vat_json_object_add_ip4 (node, "dst_address", ip4);
21609   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21610   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21611 }
21612
21613 static int
21614 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21615 {
21616   unformat_input_t *i = vam->input;
21617   vl_api_ipsec_gre_tunnel_dump_t *mp;
21618   vl_api_control_ping_t *mp_ping;
21619   u32 sw_if_index;
21620   u8 sw_if_index_set = 0;
21621   int ret;
21622
21623   /* Parse args required to build the message */
21624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21625     {
21626       if (unformat (i, "sw_if_index %d", &sw_if_index))
21627         sw_if_index_set = 1;
21628       else
21629         break;
21630     }
21631
21632   if (sw_if_index_set == 0)
21633     {
21634       sw_if_index = ~0;
21635     }
21636
21637   if (!vam->json_output)
21638     {
21639       print (vam->ofp, "%11s%15s%15s%14s%14s",
21640              "sw_if_index", "src_address", "dst_address",
21641              "local_sa_id", "remote_sa_id");
21642     }
21643
21644   /* Get list of gre-tunnel interfaces */
21645   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21646
21647   mp->sw_if_index = htonl (sw_if_index);
21648
21649   S (mp);
21650
21651   /* Use a control ping for synchronization */
21652   MPING (CONTROL_PING, mp_ping);
21653   S (mp_ping);
21654
21655   W (ret);
21656   return ret;
21657 }
21658
21659 static int
21660 api_delete_subif (vat_main_t * vam)
21661 {
21662   unformat_input_t *i = vam->input;
21663   vl_api_delete_subif_t *mp;
21664   u32 sw_if_index = ~0;
21665   int ret;
21666
21667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21668     {
21669       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21670         ;
21671       if (unformat (i, "sw_if_index %d", &sw_if_index))
21672         ;
21673       else
21674         break;
21675     }
21676
21677   if (sw_if_index == ~0)
21678     {
21679       errmsg ("missing sw_if_index");
21680       return -99;
21681     }
21682
21683   /* Construct the API message */
21684   M (DELETE_SUBIF, mp);
21685   mp->sw_if_index = ntohl (sw_if_index);
21686
21687   S (mp);
21688   W (ret);
21689   return ret;
21690 }
21691
21692 #define foreach_pbb_vtr_op      \
21693 _("disable",  L2_VTR_DISABLED)  \
21694 _("pop",  L2_VTR_POP_2)         \
21695 _("push",  L2_VTR_PUSH_2)
21696
21697 static int
21698 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21699 {
21700   unformat_input_t *i = vam->input;
21701   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21702   u32 sw_if_index = ~0, vtr_op = ~0;
21703   u16 outer_tag = ~0;
21704   u8 dmac[6], smac[6];
21705   u8 dmac_set = 0, smac_set = 0;
21706   u16 vlanid = 0;
21707   u32 sid = ~0;
21708   u32 tmp;
21709   int ret;
21710
21711   /* Shut up coverity */
21712   memset (dmac, 0, sizeof (dmac));
21713   memset (smac, 0, sizeof (smac));
21714
21715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21716     {
21717       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21718         ;
21719       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21720         ;
21721       else if (unformat (i, "vtr_op %d", &vtr_op))
21722         ;
21723 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21724       foreach_pbb_vtr_op
21725 #undef _
21726         else if (unformat (i, "translate_pbb_stag"))
21727         {
21728           if (unformat (i, "%d", &tmp))
21729             {
21730               vtr_op = L2_VTR_TRANSLATE_2_1;
21731               outer_tag = tmp;
21732             }
21733           else
21734             {
21735               errmsg
21736                 ("translate_pbb_stag operation requires outer tag definition");
21737               return -99;
21738             }
21739         }
21740       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21741         dmac_set++;
21742       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21743         smac_set++;
21744       else if (unformat (i, "sid %d", &sid))
21745         ;
21746       else if (unformat (i, "vlanid %d", &tmp))
21747         vlanid = tmp;
21748       else
21749         {
21750           clib_warning ("parse error '%U'", format_unformat_error, i);
21751           return -99;
21752         }
21753     }
21754
21755   if ((sw_if_index == ~0) || (vtr_op == ~0))
21756     {
21757       errmsg ("missing sw_if_index or vtr operation");
21758       return -99;
21759     }
21760   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21761       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21762     {
21763       errmsg
21764         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21765       return -99;
21766     }
21767
21768   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21769   mp->sw_if_index = ntohl (sw_if_index);
21770   mp->vtr_op = ntohl (vtr_op);
21771   mp->outer_tag = ntohs (outer_tag);
21772   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21773   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21774   mp->b_vlanid = ntohs (vlanid);
21775   mp->i_sid = ntohl (sid);
21776
21777   S (mp);
21778   W (ret);
21779   return ret;
21780 }
21781
21782 static int
21783 api_flow_classify_set_interface (vat_main_t * vam)
21784 {
21785   unformat_input_t *i = vam->input;
21786   vl_api_flow_classify_set_interface_t *mp;
21787   u32 sw_if_index;
21788   int sw_if_index_set;
21789   u32 ip4_table_index = ~0;
21790   u32 ip6_table_index = ~0;
21791   u8 is_add = 1;
21792   int ret;
21793
21794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21795     {
21796       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21797         sw_if_index_set = 1;
21798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21799         sw_if_index_set = 1;
21800       else if (unformat (i, "del"))
21801         is_add = 0;
21802       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21803         ;
21804       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21805         ;
21806       else
21807         {
21808           clib_warning ("parse error '%U'", format_unformat_error, i);
21809           return -99;
21810         }
21811     }
21812
21813   if (sw_if_index_set == 0)
21814     {
21815       errmsg ("missing interface name or sw_if_index");
21816       return -99;
21817     }
21818
21819   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21820
21821   mp->sw_if_index = ntohl (sw_if_index);
21822   mp->ip4_table_index = ntohl (ip4_table_index);
21823   mp->ip6_table_index = ntohl (ip6_table_index);
21824   mp->is_add = is_add;
21825
21826   S (mp);
21827   W (ret);
21828   return ret;
21829 }
21830
21831 static int
21832 api_flow_classify_dump (vat_main_t * vam)
21833 {
21834   unformat_input_t *i = vam->input;
21835   vl_api_flow_classify_dump_t *mp;
21836   vl_api_control_ping_t *mp_ping;
21837   u8 type = FLOW_CLASSIFY_N_TABLES;
21838   int ret;
21839
21840   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21841     ;
21842   else
21843     {
21844       errmsg ("classify table type must be specified");
21845       return -99;
21846     }
21847
21848   if (!vam->json_output)
21849     {
21850       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21851     }
21852
21853   M (FLOW_CLASSIFY_DUMP, mp);
21854   mp->type = type;
21855   /* send it... */
21856   S (mp);
21857
21858   /* Use a control ping for synchronization */
21859   MPING (CONTROL_PING, mp_ping);
21860   S (mp_ping);
21861
21862   /* Wait for a reply... */
21863   W (ret);
21864   return ret;
21865 }
21866
21867 static int
21868 api_feature_enable_disable (vat_main_t * vam)
21869 {
21870   unformat_input_t *i = vam->input;
21871   vl_api_feature_enable_disable_t *mp;
21872   u8 *arc_name = 0;
21873   u8 *feature_name = 0;
21874   u32 sw_if_index = ~0;
21875   u8 enable = 1;
21876   int ret;
21877
21878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21879     {
21880       if (unformat (i, "arc_name %s", &arc_name))
21881         ;
21882       else if (unformat (i, "feature_name %s", &feature_name))
21883         ;
21884       else
21885         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21886         ;
21887       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21888         ;
21889       else if (unformat (i, "disable"))
21890         enable = 0;
21891       else
21892         break;
21893     }
21894
21895   if (arc_name == 0)
21896     {
21897       errmsg ("missing arc name");
21898       return -99;
21899     }
21900   if (vec_len (arc_name) > 63)
21901     {
21902       errmsg ("arc name too long");
21903     }
21904
21905   if (feature_name == 0)
21906     {
21907       errmsg ("missing feature name");
21908       return -99;
21909     }
21910   if (vec_len (feature_name) > 63)
21911     {
21912       errmsg ("feature name too long");
21913     }
21914
21915   if (sw_if_index == ~0)
21916     {
21917       errmsg ("missing interface name or sw_if_index");
21918       return -99;
21919     }
21920
21921   /* Construct the API message */
21922   M (FEATURE_ENABLE_DISABLE, mp);
21923   mp->sw_if_index = ntohl (sw_if_index);
21924   mp->enable = enable;
21925   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21926   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21927   vec_free (arc_name);
21928   vec_free (feature_name);
21929
21930   S (mp);
21931   W (ret);
21932   return ret;
21933 }
21934
21935 static int
21936 api_sw_interface_tag_add_del (vat_main_t * vam)
21937 {
21938   unformat_input_t *i = vam->input;
21939   vl_api_sw_interface_tag_add_del_t *mp;
21940   u32 sw_if_index = ~0;
21941   u8 *tag = 0;
21942   u8 enable = 1;
21943   int ret;
21944
21945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21946     {
21947       if (unformat (i, "tag %s", &tag))
21948         ;
21949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21950         ;
21951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21952         ;
21953       else if (unformat (i, "del"))
21954         enable = 0;
21955       else
21956         break;
21957     }
21958
21959   if (sw_if_index == ~0)
21960     {
21961       errmsg ("missing interface name or sw_if_index");
21962       return -99;
21963     }
21964
21965   if (enable && (tag == 0))
21966     {
21967       errmsg ("no tag specified");
21968       return -99;
21969     }
21970
21971   /* Construct the API message */
21972   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21973   mp->sw_if_index = ntohl (sw_if_index);
21974   mp->is_add = enable;
21975   if (enable)
21976     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21977   vec_free (tag);
21978
21979   S (mp);
21980   W (ret);
21981   return ret;
21982 }
21983
21984 static void vl_api_l2_xconnect_details_t_handler
21985   (vl_api_l2_xconnect_details_t * mp)
21986 {
21987   vat_main_t *vam = &vat_main;
21988
21989   print (vam->ofp, "%15d%15d",
21990          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21991 }
21992
21993 static void vl_api_l2_xconnect_details_t_handler_json
21994   (vl_api_l2_xconnect_details_t * mp)
21995 {
21996   vat_main_t *vam = &vat_main;
21997   vat_json_node_t *node = NULL;
21998
21999   if (VAT_JSON_ARRAY != vam->json_tree.type)
22000     {
22001       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22002       vat_json_init_array (&vam->json_tree);
22003     }
22004   node = vat_json_array_add (&vam->json_tree);
22005
22006   vat_json_init_object (node);
22007   vat_json_object_add_uint (node, "rx_sw_if_index",
22008                             ntohl (mp->rx_sw_if_index));
22009   vat_json_object_add_uint (node, "tx_sw_if_index",
22010                             ntohl (mp->tx_sw_if_index));
22011 }
22012
22013 static int
22014 api_l2_xconnect_dump (vat_main_t * vam)
22015 {
22016   vl_api_l2_xconnect_dump_t *mp;
22017   vl_api_control_ping_t *mp_ping;
22018   int ret;
22019
22020   if (!vam->json_output)
22021     {
22022       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22023     }
22024
22025   M (L2_XCONNECT_DUMP, mp);
22026
22027   S (mp);
22028
22029   /* Use a control ping for synchronization */
22030   MPING (CONTROL_PING, mp_ping);
22031   S (mp_ping);
22032
22033   W (ret);
22034   return ret;
22035 }
22036
22037 static int
22038 api_sw_interface_set_mtu (vat_main_t * vam)
22039 {
22040   unformat_input_t *i = vam->input;
22041   vl_api_sw_interface_set_mtu_t *mp;
22042   u32 sw_if_index = ~0;
22043   u32 mtu = 0;
22044   int ret;
22045
22046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22047     {
22048       if (unformat (i, "mtu %d", &mtu))
22049         ;
22050       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22051         ;
22052       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22053         ;
22054       else
22055         break;
22056     }
22057
22058   if (sw_if_index == ~0)
22059     {
22060       errmsg ("missing interface name or sw_if_index");
22061       return -99;
22062     }
22063
22064   if (mtu == 0)
22065     {
22066       errmsg ("no mtu specified");
22067       return -99;
22068     }
22069
22070   /* Construct the API message */
22071   M (SW_INTERFACE_SET_MTU, mp);
22072   mp->sw_if_index = ntohl (sw_if_index);
22073   mp->mtu = ntohs ((u16) mtu);
22074
22075   S (mp);
22076   W (ret);
22077   return ret;
22078 }
22079
22080 static int
22081 api_p2p_ethernet_add (vat_main_t * vam)
22082 {
22083   unformat_input_t *i = vam->input;
22084   vl_api_p2p_ethernet_add_t *mp;
22085   u32 parent_if_index = ~0;
22086   u32 sub_id = ~0;
22087   u8 remote_mac[6];
22088   u8 mac_set = 0;
22089   int ret;
22090
22091   memset (remote_mac, 0, sizeof (remote_mac));
22092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22093     {
22094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22095         ;
22096       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22097         ;
22098       else
22099         if (unformat
22100             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22101         mac_set++;
22102       else if (unformat (i, "sub_id %d", &sub_id))
22103         ;
22104       else
22105         {
22106           clib_warning ("parse error '%U'", format_unformat_error, i);
22107           return -99;
22108         }
22109     }
22110
22111   if (parent_if_index == ~0)
22112     {
22113       errmsg ("missing interface name or sw_if_index");
22114       return -99;
22115     }
22116   if (mac_set == 0)
22117     {
22118       errmsg ("missing remote mac address");
22119       return -99;
22120     }
22121   if (sub_id == ~0)
22122     {
22123       errmsg ("missing sub-interface id");
22124       return -99;
22125     }
22126
22127   M (P2P_ETHERNET_ADD, mp);
22128   mp->parent_if_index = ntohl (parent_if_index);
22129   mp->subif_id = ntohl (sub_id);
22130   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22131
22132   S (mp);
22133   W (ret);
22134   return ret;
22135 }
22136
22137 static int
22138 api_p2p_ethernet_del (vat_main_t * vam)
22139 {
22140   unformat_input_t *i = vam->input;
22141   vl_api_p2p_ethernet_del_t *mp;
22142   u32 parent_if_index = ~0;
22143   u8 remote_mac[6];
22144   u8 mac_set = 0;
22145   int ret;
22146
22147   memset (remote_mac, 0, sizeof (remote_mac));
22148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22149     {
22150       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22151         ;
22152       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22153         ;
22154       else
22155         if (unformat
22156             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22157         mac_set++;
22158       else
22159         {
22160           clib_warning ("parse error '%U'", format_unformat_error, i);
22161           return -99;
22162         }
22163     }
22164
22165   if (parent_if_index == ~0)
22166     {
22167       errmsg ("missing interface name or sw_if_index");
22168       return -99;
22169     }
22170   if (mac_set == 0)
22171     {
22172       errmsg ("missing remote mac address");
22173       return -99;
22174     }
22175
22176   M (P2P_ETHERNET_DEL, mp);
22177   mp->parent_if_index = ntohl (parent_if_index);
22178   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22179
22180   S (mp);
22181   W (ret);
22182   return ret;
22183 }
22184
22185 static int
22186 api_lldp_config (vat_main_t * vam)
22187 {
22188   unformat_input_t *i = vam->input;
22189   vl_api_lldp_config_t *mp;
22190   int tx_hold = 0;
22191   int tx_interval = 0;
22192   u8 *sys_name = NULL;
22193   int ret;
22194
22195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22196     {
22197       if (unformat (i, "system-name %s", &sys_name))
22198         ;
22199       else if (unformat (i, "tx-hold %d", &tx_hold))
22200         ;
22201       else if (unformat (i, "tx-interval %d", &tx_interval))
22202         ;
22203       else
22204         {
22205           clib_warning ("parse error '%U'", format_unformat_error, i);
22206           return -99;
22207         }
22208     }
22209
22210   vec_add1 (sys_name, 0);
22211
22212   M (LLDP_CONFIG, mp);
22213   mp->tx_hold = htonl (tx_hold);
22214   mp->tx_interval = htonl (tx_interval);
22215   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22216   vec_free (sys_name);
22217
22218   S (mp);
22219   W (ret);
22220   return ret;
22221 }
22222
22223 static int
22224 api_sw_interface_set_lldp (vat_main_t * vam)
22225 {
22226   unformat_input_t *i = vam->input;
22227   vl_api_sw_interface_set_lldp_t *mp;
22228   u32 sw_if_index = ~0;
22229   u32 enable = 1;
22230   u8 *port_desc = NULL, *mgmt_oid = NULL;
22231   ip4_address_t ip4_addr;
22232   ip6_address_t ip6_addr;
22233   int ret;
22234
22235   memset (&ip4_addr, 0, sizeof (ip4_addr));
22236   memset (&ip6_addr, 0, sizeof (ip6_addr));
22237
22238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22239     {
22240       if (unformat (i, "disable"))
22241         enable = 0;
22242       else
22243         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22244         ;
22245       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22246         ;
22247       else if (unformat (i, "port-desc %s", &port_desc))
22248         ;
22249       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22250         ;
22251       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22252         ;
22253       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22254         ;
22255       else
22256         break;
22257     }
22258
22259   if (sw_if_index == ~0)
22260     {
22261       errmsg ("missing interface name or sw_if_index");
22262       return -99;
22263     }
22264
22265   /* Construct the API message */
22266   vec_add1 (port_desc, 0);
22267   vec_add1 (mgmt_oid, 0);
22268   M (SW_INTERFACE_SET_LLDP, mp);
22269   mp->sw_if_index = ntohl (sw_if_index);
22270   mp->enable = enable;
22271   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22272   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22273   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22274   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22275   vec_free (port_desc);
22276   vec_free (mgmt_oid);
22277
22278   S (mp);
22279   W (ret);
22280   return ret;
22281 }
22282
22283 static int
22284 api_tcp_configure_src_addresses (vat_main_t * vam)
22285 {
22286   vl_api_tcp_configure_src_addresses_t *mp;
22287   unformat_input_t *i = vam->input;
22288   ip4_address_t v4first, v4last;
22289   ip6_address_t v6first, v6last;
22290   u8 range_set = 0;
22291   u32 vrf_id = 0;
22292   int ret;
22293
22294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22295     {
22296       if (unformat (i, "%U - %U",
22297                     unformat_ip4_address, &v4first,
22298                     unformat_ip4_address, &v4last))
22299         {
22300           if (range_set)
22301             {
22302               errmsg ("one range per message (range already set)");
22303               return -99;
22304             }
22305           range_set = 1;
22306         }
22307       else if (unformat (i, "%U - %U",
22308                          unformat_ip6_address, &v6first,
22309                          unformat_ip6_address, &v6last))
22310         {
22311           if (range_set)
22312             {
22313               errmsg ("one range per message (range already set)");
22314               return -99;
22315             }
22316           range_set = 2;
22317         }
22318       else if (unformat (i, "vrf %d", &vrf_id))
22319         ;
22320       else
22321         break;
22322     }
22323
22324   if (range_set == 0)
22325     {
22326       errmsg ("address range not set");
22327       return -99;
22328     }
22329
22330   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22331   mp->vrf_id = ntohl (vrf_id);
22332   /* ipv6? */
22333   if (range_set == 2)
22334     {
22335       mp->is_ipv6 = 1;
22336       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22337       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22338     }
22339   else
22340     {
22341       mp->is_ipv6 = 0;
22342       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22343       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22344     }
22345   S (mp);
22346   W (ret);
22347   return ret;
22348 }
22349
22350 static void vl_api_app_namespace_add_del_reply_t_handler
22351   (vl_api_app_namespace_add_del_reply_t * mp)
22352 {
22353   vat_main_t *vam = &vat_main;
22354   i32 retval = ntohl (mp->retval);
22355   if (vam->async_mode)
22356     {
22357       vam->async_errors += (retval < 0);
22358     }
22359   else
22360     {
22361       vam->retval = retval;
22362       if (retval == 0)
22363         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22364       vam->result_ready = 1;
22365     }
22366 }
22367
22368 static void vl_api_app_namespace_add_del_reply_t_handler_json
22369   (vl_api_app_namespace_add_del_reply_t * mp)
22370 {
22371   vat_main_t *vam = &vat_main;
22372   vat_json_node_t node;
22373
22374   vat_json_init_object (&node);
22375   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22376   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22377
22378   vat_json_print (vam->ofp, &node);
22379   vat_json_free (&node);
22380
22381   vam->retval = ntohl (mp->retval);
22382   vam->result_ready = 1;
22383 }
22384
22385 static int
22386 api_app_namespace_add_del (vat_main_t * vam)
22387 {
22388   vl_api_app_namespace_add_del_t *mp;
22389   unformat_input_t *i = vam->input;
22390   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22391   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22392   u64 secret;
22393   int ret;
22394
22395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22396     {
22397       if (unformat (i, "id %_%v%_", &ns_id))
22398         ;
22399       else if (unformat (i, "secret %lu", &secret))
22400         secret_set = 1;
22401       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22402         sw_if_index_set = 1;
22403       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22404         ;
22405       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22406         ;
22407       else
22408         break;
22409     }
22410   if (!ns_id || !secret_set || !sw_if_index_set)
22411     {
22412       errmsg ("namespace id, secret and sw_if_index must be set");
22413       return -99;
22414     }
22415   if (vec_len (ns_id) > 64)
22416     {
22417       errmsg ("namespace id too long");
22418       return -99;
22419     }
22420   M (APP_NAMESPACE_ADD_DEL, mp);
22421
22422   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22423   mp->namespace_id_len = vec_len (ns_id);
22424   mp->secret = clib_host_to_net_u64 (secret);
22425   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22426   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22427   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22428   vec_free (ns_id);
22429   S (mp);
22430   W (ret);
22431   return ret;
22432 }
22433
22434 static int
22435 api_sock_init_shm (vat_main_t * vam)
22436 {
22437 #if VPP_API_TEST_BUILTIN == 0
22438   unformat_input_t *i = vam->input;
22439   vl_api_shm_elem_config_t *config = 0;
22440   u64 size = 64 << 20;
22441   int rv;
22442
22443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22444     {
22445       if (unformat (i, "size %U", unformat_memory_size, &size))
22446         ;
22447       else
22448         break;
22449     }
22450
22451   /*
22452    * Canned custom ring allocator config.
22453    * Should probably parse all of this
22454    */
22455   vec_validate (config, 6);
22456   config[0].type = VL_API_VLIB_RING;
22457   config[0].size = 256;
22458   config[0].count = 32;
22459
22460   config[1].type = VL_API_VLIB_RING;
22461   config[1].size = 1024;
22462   config[1].count = 16;
22463
22464   config[2].type = VL_API_VLIB_RING;
22465   config[2].size = 4096;
22466   config[2].count = 2;
22467
22468   config[3].type = VL_API_CLIENT_RING;
22469   config[3].size = 256;
22470   config[3].count = 32;
22471
22472   config[4].type = VL_API_CLIENT_RING;
22473   config[4].size = 1024;
22474   config[4].count = 16;
22475
22476   config[5].type = VL_API_CLIENT_RING;
22477   config[5].size = 4096;
22478   config[5].count = 2;
22479
22480   config[6].type = VL_API_QUEUE;
22481   config[6].count = 128;
22482   config[6].size = sizeof (uword);
22483
22484   rv = vl_socket_client_init_shm (config);
22485   if (!rv)
22486     vam->client_index_invalid = 1;
22487   return rv;
22488 #else
22489   return -99;
22490 #endif
22491 }
22492
22493 static int
22494 api_dns_enable_disable (vat_main_t * vam)
22495 {
22496   unformat_input_t *line_input = vam->input;
22497   vl_api_dns_enable_disable_t *mp;
22498   u8 enable_disable = 1;
22499   int ret;
22500
22501   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22502     {
22503       if (unformat (line_input, "disable"))
22504         enable_disable = 0;
22505       if (unformat (line_input, "enable"))
22506         enable_disable = 1;
22507       else
22508         break;
22509     }
22510
22511   /* Construct the API message */
22512   M (DNS_ENABLE_DISABLE, mp);
22513   mp->enable = enable_disable;
22514
22515   /* send it... */
22516   S (mp);
22517   /* Wait for the reply */
22518   W (ret);
22519   return ret;
22520 }
22521
22522 static int
22523 api_dns_resolve_name (vat_main_t * vam)
22524 {
22525   unformat_input_t *line_input = vam->input;
22526   vl_api_dns_resolve_name_t *mp;
22527   u8 *name = 0;
22528   int ret;
22529
22530   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22531     {
22532       if (unformat (line_input, "%s", &name))
22533         ;
22534       else
22535         break;
22536     }
22537
22538   if (vec_len (name) > 127)
22539     {
22540       errmsg ("name too long");
22541       return -99;
22542     }
22543
22544   /* Construct the API message */
22545   M (DNS_RESOLVE_NAME, mp);
22546   memcpy (mp->name, name, vec_len (name));
22547   vec_free (name);
22548
22549   /* send it... */
22550   S (mp);
22551   /* Wait for the reply */
22552   W (ret);
22553   return ret;
22554 }
22555
22556 static int
22557 api_dns_resolve_ip (vat_main_t * vam)
22558 {
22559   unformat_input_t *line_input = vam->input;
22560   vl_api_dns_resolve_ip_t *mp;
22561   int is_ip6 = -1;
22562   ip4_address_t addr4;
22563   ip6_address_t addr6;
22564   int ret;
22565
22566   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22567     {
22568       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22569         is_ip6 = 1;
22570       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22571         is_ip6 = 0;
22572       else
22573         break;
22574     }
22575
22576   if (is_ip6 == -1)
22577     {
22578       errmsg ("missing address");
22579       return -99;
22580     }
22581
22582   /* Construct the API message */
22583   M (DNS_RESOLVE_IP, mp);
22584   mp->is_ip6 = is_ip6;
22585   if (is_ip6)
22586     memcpy (mp->address, &addr6, sizeof (addr6));
22587   else
22588     memcpy (mp->address, &addr4, sizeof (addr4));
22589
22590   /* send it... */
22591   S (mp);
22592   /* Wait for the reply */
22593   W (ret);
22594   return ret;
22595 }
22596
22597 static int
22598 api_dns_name_server_add_del (vat_main_t * vam)
22599 {
22600   unformat_input_t *i = vam->input;
22601   vl_api_dns_name_server_add_del_t *mp;
22602   u8 is_add = 1;
22603   ip6_address_t ip6_server;
22604   ip4_address_t ip4_server;
22605   int ip6_set = 0;
22606   int ip4_set = 0;
22607   int ret = 0;
22608
22609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22610     {
22611       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22612         ip6_set = 1;
22613       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22614         ip4_set = 1;
22615       else if (unformat (i, "del"))
22616         is_add = 0;
22617       else
22618         {
22619           clib_warning ("parse error '%U'", format_unformat_error, i);
22620           return -99;
22621         }
22622     }
22623
22624   if (ip4_set && ip6_set)
22625     {
22626       errmsg ("Only one server address allowed per message");
22627       return -99;
22628     }
22629   if ((ip4_set + ip6_set) == 0)
22630     {
22631       errmsg ("Server address required");
22632       return -99;
22633     }
22634
22635   /* Construct the API message */
22636   M (DNS_NAME_SERVER_ADD_DEL, mp);
22637
22638   if (ip6_set)
22639     {
22640       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22641       mp->is_ip6 = 1;
22642     }
22643   else
22644     {
22645       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22646       mp->is_ip6 = 0;
22647     }
22648
22649   mp->is_add = is_add;
22650
22651   /* send it... */
22652   S (mp);
22653
22654   /* Wait for a reply, return good/bad news  */
22655   W (ret);
22656   return ret;
22657 }
22658
22659 static void
22660 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22661 {
22662   vat_main_t *vam = &vat_main;
22663
22664   if (mp->is_ip4)
22665     {
22666       print (vam->ofp,
22667              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22668              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22669              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22670              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22671              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22672              clib_net_to_host_u32 (mp->action_index), mp->tag);
22673     }
22674   else
22675     {
22676       print (vam->ofp,
22677              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22678              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22679              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22680              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22681              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22682              clib_net_to_host_u32 (mp->action_index), mp->tag);
22683     }
22684 }
22685
22686 static void
22687 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22688                                              mp)
22689 {
22690   vat_main_t *vam = &vat_main;
22691   vat_json_node_t *node = NULL;
22692   struct in6_addr ip6;
22693   struct in_addr ip4;
22694
22695   if (VAT_JSON_ARRAY != vam->json_tree.type)
22696     {
22697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22698       vat_json_init_array (&vam->json_tree);
22699     }
22700   node = vat_json_array_add (&vam->json_tree);
22701   vat_json_init_object (node);
22702
22703   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22704   vat_json_object_add_uint (node, "appns_index",
22705                             clib_net_to_host_u32 (mp->appns_index));
22706   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22707   vat_json_object_add_uint (node, "scope", mp->scope);
22708   vat_json_object_add_uint (node, "action_index",
22709                             clib_net_to_host_u32 (mp->action_index));
22710   vat_json_object_add_uint (node, "lcl_port",
22711                             clib_net_to_host_u16 (mp->lcl_port));
22712   vat_json_object_add_uint (node, "rmt_port",
22713                             clib_net_to_host_u16 (mp->rmt_port));
22714   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22715   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22716   vat_json_object_add_string_copy (node, "tag", mp->tag);
22717   if (mp->is_ip4)
22718     {
22719       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22720       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22721       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22722       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22723     }
22724   else
22725     {
22726       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22727       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22728       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22729       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22730     }
22731 }
22732
22733 static int
22734 api_session_rule_add_del (vat_main_t * vam)
22735 {
22736   vl_api_session_rule_add_del_t *mp;
22737   unformat_input_t *i = vam->input;
22738   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22739   u32 appns_index = 0, scope = 0;
22740   ip4_address_t lcl_ip4, rmt_ip4;
22741   ip6_address_t lcl_ip6, rmt_ip6;
22742   u8 is_ip4 = 1, conn_set = 0;
22743   u8 is_add = 1, *tag = 0;
22744   int ret;
22745
22746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22747     {
22748       if (unformat (i, "del"))
22749         is_add = 0;
22750       else if (unformat (i, "add"))
22751         ;
22752       else if (unformat (i, "proto tcp"))
22753         proto = 0;
22754       else if (unformat (i, "proto udp"))
22755         proto = 1;
22756       else if (unformat (i, "appns %d", &appns_index))
22757         ;
22758       else if (unformat (i, "scope %d", &scope))
22759         ;
22760       else if (unformat (i, "tag %_%v%_", &tag))
22761         ;
22762       else
22763         if (unformat
22764             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22765              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22766              &rmt_port))
22767         {
22768           is_ip4 = 1;
22769           conn_set = 1;
22770         }
22771       else
22772         if (unformat
22773             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22774              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22775              &rmt_port))
22776         {
22777           is_ip4 = 0;
22778           conn_set = 1;
22779         }
22780       else if (unformat (i, "action %d", &action))
22781         ;
22782       else
22783         break;
22784     }
22785   if (proto == ~0 || !conn_set || action == ~0)
22786     {
22787       errmsg ("transport proto, connection and action must be set");
22788       return -99;
22789     }
22790
22791   if (scope > 3)
22792     {
22793       errmsg ("scope should be 0-3");
22794       return -99;
22795     }
22796
22797   M (SESSION_RULE_ADD_DEL, mp);
22798
22799   mp->is_ip4 = is_ip4;
22800   mp->transport_proto = proto;
22801   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22802   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22803   mp->lcl_plen = lcl_plen;
22804   mp->rmt_plen = rmt_plen;
22805   mp->action_index = clib_host_to_net_u32 (action);
22806   mp->appns_index = clib_host_to_net_u32 (appns_index);
22807   mp->scope = scope;
22808   mp->is_add = is_add;
22809   if (is_ip4)
22810     {
22811       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22812       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22813     }
22814   else
22815     {
22816       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22817       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22818     }
22819   if (tag)
22820     {
22821       clib_memcpy (mp->tag, tag, vec_len (tag));
22822       vec_free (tag);
22823     }
22824
22825   S (mp);
22826   W (ret);
22827   return ret;
22828 }
22829
22830 static int
22831 api_session_rules_dump (vat_main_t * vam)
22832 {
22833   vl_api_session_rules_dump_t *mp;
22834   vl_api_control_ping_t *mp_ping;
22835   int ret;
22836
22837   if (!vam->json_output)
22838     {
22839       print (vam->ofp, "%=20s", "Session Rules");
22840     }
22841
22842   M (SESSION_RULES_DUMP, mp);
22843   /* send it... */
22844   S (mp);
22845
22846   /* Use a control ping for synchronization */
22847   MPING (CONTROL_PING, mp_ping);
22848   S (mp_ping);
22849
22850   /* Wait for a reply... */
22851   W (ret);
22852   return ret;
22853 }
22854
22855 static int
22856 api_ip_container_proxy_add_del (vat_main_t * vam)
22857 {
22858   vl_api_ip_container_proxy_add_del_t *mp;
22859   unformat_input_t *i = vam->input;
22860   u32 plen = ~0, sw_if_index = ~0;
22861   ip4_address_t ip4;
22862   ip6_address_t ip6;
22863   u8 is_ip4 = 1;
22864   u8 is_add = 1;
22865   int ret;
22866
22867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22868     {
22869       if (unformat (i, "del"))
22870         is_add = 0;
22871       else if (unformat (i, "add"))
22872         ;
22873       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22874         {
22875           is_ip4 = 1;
22876           plen = 32;
22877         }
22878       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22879         {
22880           is_ip4 = 0;
22881           plen = 128;
22882         }
22883       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22884         ;
22885       else
22886         break;
22887     }
22888   if (sw_if_index == ~0 || plen == ~0)
22889     {
22890       errmsg ("address and sw_if_index must be set");
22891       return -99;
22892     }
22893
22894   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22895
22896   mp->is_ip4 = is_ip4;
22897   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22898   mp->plen = plen;
22899   mp->is_add = is_add;
22900   if (is_ip4)
22901     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22902   else
22903     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22904
22905   S (mp);
22906   W (ret);
22907   return ret;
22908 }
22909
22910 static int
22911 api_qos_record_enable_disable (vat_main_t * vam)
22912 {
22913   unformat_input_t *i = vam->input;
22914   vl_api_qos_record_enable_disable_t *mp;
22915   u32 sw_if_index, qs = 0xff;
22916   u8 sw_if_index_set = 0;
22917   u8 enable = 1;
22918   int ret;
22919
22920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22921     {
22922       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22923         sw_if_index_set = 1;
22924       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22925         sw_if_index_set = 1;
22926       else if (unformat (i, "%U", unformat_qos_source, &qs))
22927         ;
22928       else if (unformat (i, "disable"))
22929         enable = 0;
22930       else
22931         {
22932           clib_warning ("parse error '%U'", format_unformat_error, i);
22933           return -99;
22934         }
22935     }
22936
22937   if (sw_if_index_set == 0)
22938     {
22939       errmsg ("missing interface name or sw_if_index");
22940       return -99;
22941     }
22942   if (qs == 0xff)
22943     {
22944       errmsg ("input location must be specified");
22945       return -99;
22946     }
22947
22948   M (QOS_RECORD_ENABLE_DISABLE, mp);
22949
22950   mp->sw_if_index = ntohl (sw_if_index);
22951   mp->input_source = qs;
22952   mp->enable = enable;
22953
22954   S (mp);
22955   W (ret);
22956   return ret;
22957 }
22958
22959 static int
22960 q_or_quit (vat_main_t * vam)
22961 {
22962 #if VPP_API_TEST_BUILTIN == 0
22963   longjmp (vam->jump_buf, 1);
22964 #endif
22965   return 0;                     /* not so much */
22966 }
22967
22968 static int
22969 q (vat_main_t * vam)
22970 {
22971   return q_or_quit (vam);
22972 }
22973
22974 static int
22975 quit (vat_main_t * vam)
22976 {
22977   return q_or_quit (vam);
22978 }
22979
22980 static int
22981 comment (vat_main_t * vam)
22982 {
22983   return 0;
22984 }
22985
22986 static int
22987 cmd_cmp (void *a1, void *a2)
22988 {
22989   u8 **c1 = a1;
22990   u8 **c2 = a2;
22991
22992   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22993 }
22994
22995 static int
22996 help (vat_main_t * vam)
22997 {
22998   u8 **cmds = 0;
22999   u8 *name = 0;
23000   hash_pair_t *p;
23001   unformat_input_t *i = vam->input;
23002   int j;
23003
23004   if (unformat (i, "%s", &name))
23005     {
23006       uword *hs;
23007
23008       vec_add1 (name, 0);
23009
23010       hs = hash_get_mem (vam->help_by_name, name);
23011       if (hs)
23012         print (vam->ofp, "usage: %s %s", name, hs[0]);
23013       else
23014         print (vam->ofp, "No such msg / command '%s'", name);
23015       vec_free (name);
23016       return 0;
23017     }
23018
23019   print (vam->ofp, "Help is available for the following:");
23020
23021     /* *INDENT-OFF* */
23022     hash_foreach_pair (p, vam->function_by_name,
23023     ({
23024       vec_add1 (cmds, (u8 *)(p->key));
23025     }));
23026     /* *INDENT-ON* */
23027
23028   vec_sort_with_function (cmds, cmd_cmp);
23029
23030   for (j = 0; j < vec_len (cmds); j++)
23031     print (vam->ofp, "%s", cmds[j]);
23032
23033   vec_free (cmds);
23034   return 0;
23035 }
23036
23037 static int
23038 set (vat_main_t * vam)
23039 {
23040   u8 *name = 0, *value = 0;
23041   unformat_input_t *i = vam->input;
23042
23043   if (unformat (i, "%s", &name))
23044     {
23045       /* The input buffer is a vector, not a string. */
23046       value = vec_dup (i->buffer);
23047       vec_delete (value, i->index, 0);
23048       /* Almost certainly has a trailing newline */
23049       if (value[vec_len (value) - 1] == '\n')
23050         value[vec_len (value) - 1] = 0;
23051       /* Make sure it's a proper string, one way or the other */
23052       vec_add1 (value, 0);
23053       (void) clib_macro_set_value (&vam->macro_main,
23054                                    (char *) name, (char *) value);
23055     }
23056   else
23057     errmsg ("usage: set <name> <value>");
23058
23059   vec_free (name);
23060   vec_free (value);
23061   return 0;
23062 }
23063
23064 static int
23065 unset (vat_main_t * vam)
23066 {
23067   u8 *name = 0;
23068
23069   if (unformat (vam->input, "%s", &name))
23070     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23071       errmsg ("unset: %s wasn't set", name);
23072   vec_free (name);
23073   return 0;
23074 }
23075
23076 typedef struct
23077 {
23078   u8 *name;
23079   u8 *value;
23080 } macro_sort_t;
23081
23082
23083 static int
23084 macro_sort_cmp (void *a1, void *a2)
23085 {
23086   macro_sort_t *s1 = a1;
23087   macro_sort_t *s2 = a2;
23088
23089   return strcmp ((char *) (s1->name), (char *) (s2->name));
23090 }
23091
23092 static int
23093 dump_macro_table (vat_main_t * vam)
23094 {
23095   macro_sort_t *sort_me = 0, *sm;
23096   int i;
23097   hash_pair_t *p;
23098
23099     /* *INDENT-OFF* */
23100     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23101     ({
23102       vec_add2 (sort_me, sm, 1);
23103       sm->name = (u8 *)(p->key);
23104       sm->value = (u8 *) (p->value[0]);
23105     }));
23106     /* *INDENT-ON* */
23107
23108   vec_sort_with_function (sort_me, macro_sort_cmp);
23109
23110   if (vec_len (sort_me))
23111     print (vam->ofp, "%-15s%s", "Name", "Value");
23112   else
23113     print (vam->ofp, "The macro table is empty...");
23114
23115   for (i = 0; i < vec_len (sort_me); i++)
23116     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23117   return 0;
23118 }
23119
23120 static int
23121 dump_node_table (vat_main_t * vam)
23122 {
23123   int i, j;
23124   vlib_node_t *node, *next_node;
23125
23126   if (vec_len (vam->graph_nodes) == 0)
23127     {
23128       print (vam->ofp, "Node table empty, issue get_node_graph...");
23129       return 0;
23130     }
23131
23132   for (i = 0; i < vec_len (vam->graph_nodes); i++)
23133     {
23134       node = vam->graph_nodes[i];
23135       print (vam->ofp, "[%d] %s", i, node->name);
23136       for (j = 0; j < vec_len (node->next_nodes); j++)
23137         {
23138           if (node->next_nodes[j] != ~0)
23139             {
23140               next_node = vam->graph_nodes[node->next_nodes[j]];
23141               print (vam->ofp, "  [%d] %s", j, next_node->name);
23142             }
23143         }
23144     }
23145   return 0;
23146 }
23147
23148 static int
23149 value_sort_cmp (void *a1, void *a2)
23150 {
23151   name_sort_t *n1 = a1;
23152   name_sort_t *n2 = a2;
23153
23154   if (n1->value < n2->value)
23155     return -1;
23156   if (n1->value > n2->value)
23157     return 1;
23158   return 0;
23159 }
23160
23161
23162 static int
23163 dump_msg_api_table (vat_main_t * vam)
23164 {
23165   api_main_t *am = &api_main;
23166   name_sort_t *nses = 0, *ns;
23167   hash_pair_t *hp;
23168   int i;
23169
23170   /* *INDENT-OFF* */
23171   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23172   ({
23173     vec_add2 (nses, ns, 1);
23174     ns->name = (u8 *)(hp->key);
23175     ns->value = (u32) hp->value[0];
23176   }));
23177   /* *INDENT-ON* */
23178
23179   vec_sort_with_function (nses, value_sort_cmp);
23180
23181   for (i = 0; i < vec_len (nses); i++)
23182     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23183   vec_free (nses);
23184   return 0;
23185 }
23186
23187 static int
23188 get_msg_id (vat_main_t * vam)
23189 {
23190   u8 *name_and_crc;
23191   u32 message_index;
23192
23193   if (unformat (vam->input, "%s", &name_and_crc))
23194     {
23195       message_index = vl_msg_api_get_msg_index (name_and_crc);
23196       if (message_index == ~0)
23197         {
23198           print (vam->ofp, " '%s' not found", name_and_crc);
23199           return 0;
23200         }
23201       print (vam->ofp, " '%s' has message index %d",
23202              name_and_crc, message_index);
23203       return 0;
23204     }
23205   errmsg ("name_and_crc required...");
23206   return 0;
23207 }
23208
23209 static int
23210 search_node_table (vat_main_t * vam)
23211 {
23212   unformat_input_t *line_input = vam->input;
23213   u8 *node_to_find;
23214   int j;
23215   vlib_node_t *node, *next_node;
23216   uword *p;
23217
23218   if (vam->graph_node_index_by_name == 0)
23219     {
23220       print (vam->ofp, "Node table empty, issue get_node_graph...");
23221       return 0;
23222     }
23223
23224   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23225     {
23226       if (unformat (line_input, "%s", &node_to_find))
23227         {
23228           vec_add1 (node_to_find, 0);
23229           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23230           if (p == 0)
23231             {
23232               print (vam->ofp, "%s not found...", node_to_find);
23233               goto out;
23234             }
23235           node = vam->graph_nodes[p[0]];
23236           print (vam->ofp, "[%d] %s", p[0], node->name);
23237           for (j = 0; j < vec_len (node->next_nodes); j++)
23238             {
23239               if (node->next_nodes[j] != ~0)
23240                 {
23241                   next_node = vam->graph_nodes[node->next_nodes[j]];
23242                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23243                 }
23244             }
23245         }
23246
23247       else
23248         {
23249           clib_warning ("parse error '%U'", format_unformat_error,
23250                         line_input);
23251           return -99;
23252         }
23253
23254     out:
23255       vec_free (node_to_find);
23256
23257     }
23258
23259   return 0;
23260 }
23261
23262
23263 static int
23264 script (vat_main_t * vam)
23265 {
23266 #if (VPP_API_TEST_BUILTIN==0)
23267   u8 *s = 0;
23268   char *save_current_file;
23269   unformat_input_t save_input;
23270   jmp_buf save_jump_buf;
23271   u32 save_line_number;
23272
23273   FILE *new_fp, *save_ifp;
23274
23275   if (unformat (vam->input, "%s", &s))
23276     {
23277       new_fp = fopen ((char *) s, "r");
23278       if (new_fp == 0)
23279         {
23280           errmsg ("Couldn't open script file %s", s);
23281           vec_free (s);
23282           return -99;
23283         }
23284     }
23285   else
23286     {
23287       errmsg ("Missing script name");
23288       return -99;
23289     }
23290
23291   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23292   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23293   save_ifp = vam->ifp;
23294   save_line_number = vam->input_line_number;
23295   save_current_file = (char *) vam->current_file;
23296
23297   vam->input_line_number = 0;
23298   vam->ifp = new_fp;
23299   vam->current_file = s;
23300   do_one_file (vam);
23301
23302   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23303   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23304   vam->ifp = save_ifp;
23305   vam->input_line_number = save_line_number;
23306   vam->current_file = (u8 *) save_current_file;
23307   vec_free (s);
23308
23309   return 0;
23310 #else
23311   clib_warning ("use the exec command...");
23312   return -99;
23313 #endif
23314 }
23315
23316 static int
23317 echo (vat_main_t * vam)
23318 {
23319   print (vam->ofp, "%v", vam->input->buffer);
23320   return 0;
23321 }
23322
23323 /* List of API message constructors, CLI names map to api_xxx */
23324 #define foreach_vpe_api_msg                                             \
23325 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23326 _(sw_interface_dump,"")                                                 \
23327 _(sw_interface_set_flags,                                               \
23328   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23329 _(sw_interface_add_del_address,                                         \
23330   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23331 _(sw_interface_set_rx_mode,                                             \
23332   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23333 _(sw_interface_set_table,                                               \
23334   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23335 _(sw_interface_set_mpls_enable,                                         \
23336   "<intfc> | sw_if_index [disable | dis]")                              \
23337 _(sw_interface_set_vpath,                                               \
23338   "<intfc> | sw_if_index <id> enable | disable")                        \
23339 _(sw_interface_set_vxlan_bypass,                                        \
23340   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23341 _(sw_interface_set_geneve_bypass,                                       \
23342   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23343 _(sw_interface_set_l2_xconnect,                                         \
23344   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23345   "enable | disable")                                                   \
23346 _(sw_interface_set_l2_bridge,                                           \
23347   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23348   "[shg <split-horizon-group>] [bvi]\n"                                 \
23349   "enable | disable")                                                   \
23350 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23351 _(bridge_domain_add_del,                                                \
23352   "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") \
23353 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23354 _(l2fib_add_del,                                                        \
23355   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23356 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23357 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23358 _(l2_flags,                                                             \
23359   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23360 _(bridge_flags,                                                         \
23361   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23362 _(tap_connect,                                                          \
23363   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23364 _(tap_modify,                                                           \
23365   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23366 _(tap_delete,                                                           \
23367   "<vpp-if-name> | sw_if_index <id>")                                   \
23368 _(sw_interface_tap_dump, "")                                            \
23369 _(tap_create_v2,                                                        \
23370   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23371 _(tap_delete_v2,                                                        \
23372   "<vpp-if-name> | sw_if_index <id>")                                   \
23373 _(sw_interface_tap_v2_dump, "")                                         \
23374 _(bond_create,                                                          \
23375   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23376   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23377 _(bond_delete,                                                          \
23378   "<vpp-if-name> | sw_if_index <id>")                                   \
23379 _(bond_enslave,                                                         \
23380   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23381 _(bond_detach_slave,                                                    \
23382   "sw_if_index <n>")                                                    \
23383 _(sw_interface_bond_dump, "")                                           \
23384 _(sw_interface_slave_dump,                                              \
23385   "<vpp-if-name> | sw_if_index <id>")                                   \
23386 _(ip_table_add_del,                                                     \
23387   "table-id <n> [ipv6]\n")                                              \
23388 _(ip_add_del_route,                                                     \
23389   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23390   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23391   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23392   "[multipath] [count <n>]")                                            \
23393 _(ip_mroute_add_del,                                                    \
23394   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23395   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23396 _(mpls_table_add_del,                                                   \
23397   "table-id <n>\n")                                                     \
23398 _(mpls_route_add_del,                                                   \
23399   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23400   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23401   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23402   "[multipath] [count <n>]")                                            \
23403 _(mpls_ip_bind_unbind,                                                  \
23404   "<label> <addr/len>")                                                 \
23405 _(mpls_tunnel_add_del,                                                  \
23406   " via <addr> [table-id <n>]\n"                                        \
23407   "sw_if_index <id>] [l2]  [del]")                                      \
23408 _(bier_table_add_del,                                                   \
23409   "<label> <sub-domain> <set> <bsl> [del]")                             \
23410 _(bier_route_add_del,                                                   \
23411   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23412   "[<intfc> | sw_if_index <id>]"                                        \
23413   "[weight <n>] [del] [multipath]")                                     \
23414 _(proxy_arp_add_del,                                                    \
23415   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23416 _(proxy_arp_intfc_enable_disable,                                       \
23417   "<intfc> | sw_if_index <id> enable | disable")                        \
23418 _(sw_interface_set_unnumbered,                                          \
23419   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23420 _(ip_neighbor_add_del,                                                  \
23421   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23422   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23423 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23424 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23425   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23426   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23427   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23428 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23429 _(reset_fib, "vrf <n> [ipv6]")                                          \
23430 _(dhcp_proxy_config,                                                    \
23431   "svr <v46-address> src <v46-address>\n"                               \
23432    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23433 _(dhcp_proxy_set_vss,                                                   \
23434   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23435 _(dhcp_proxy_dump, "ip6")                                               \
23436 _(dhcp_client_config,                                                   \
23437   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23438 _(set_ip_flow_hash,                                                     \
23439   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23440 _(sw_interface_ip6_enable_disable,                                      \
23441   "<intfc> | sw_if_index <id> enable | disable")                        \
23442 _(sw_interface_ip6_set_link_local_address,                              \
23443   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23444 _(ip6nd_proxy_add_del,                                                  \
23445   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23446 _(ip6nd_proxy_dump, "")                                                 \
23447 _(sw_interface_ip6nd_ra_prefix,                                         \
23448   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23449   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23450   "[nolink] [isno]")                                                    \
23451 _(sw_interface_ip6nd_ra_config,                                         \
23452   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23453   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23454   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23455 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23456 _(l2_patch_add_del,                                                     \
23457   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23458   "enable | disable")                                                   \
23459 _(sr_localsid_add_del,                                                  \
23460   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23461   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23462 _(classify_add_del_table,                                               \
23463   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23464   " [del] [del-chain] mask <mask-value>\n"                              \
23465   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23466   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23467 _(classify_add_del_session,                                             \
23468   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23469   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23470   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23471   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23472 _(classify_set_interface_ip_table,                                      \
23473   "<intfc> | sw_if_index <nn> table <nn>")                              \
23474 _(classify_set_interface_l2_tables,                                     \
23475   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23476   "  [other-table <nn>]")                                               \
23477 _(get_node_index, "node <node-name")                                    \
23478 _(add_node_next, "node <node-name> next <next-node-name>")              \
23479 _(l2tpv3_create_tunnel,                                                 \
23480   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23481   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23482   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23483 _(l2tpv3_set_tunnel_cookies,                                            \
23484   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23485   "[new_remote_cookie <nn>]\n")                                         \
23486 _(l2tpv3_interface_enable_disable,                                      \
23487   "<intfc> | sw_if_index <nn> enable | disable")                        \
23488 _(l2tpv3_set_lookup_key,                                                \
23489   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23490 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23491 _(vxlan_add_del_tunnel,                                                 \
23492   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23493   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23494   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23495 _(geneve_add_del_tunnel,                                                \
23496   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23497   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23498   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23499 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23500 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23501 _(gre_add_del_tunnel,                                                   \
23502   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23503   "[teb | erspan <session-id>] [del]")                                  \
23504 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23505 _(l2_fib_clear_table, "")                                               \
23506 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23507 _(l2_interface_vlan_tag_rewrite,                                        \
23508   "<intfc> | sw_if_index <nn> \n"                                       \
23509   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23510   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23511 _(create_vhost_user_if,                                                 \
23512         "socket <filename> [server] [renumber <dev_instance>] "         \
23513         "[mac <mac_address>]")                                          \
23514 _(modify_vhost_user_if,                                                 \
23515         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23516         "[server] [renumber <dev_instance>]")                           \
23517 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23518 _(sw_interface_vhost_user_dump, "")                                     \
23519 _(show_version, "")                                                     \
23520 _(vxlan_gpe_add_del_tunnel,                                             \
23521   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23522   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23523   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23524   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23525 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23526 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23527 _(interface_name_renumber,                                              \
23528   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23529 _(input_acl_set_interface,                                              \
23530   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23531   "  [l2-table <nn>] [del]")                                            \
23532 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23533 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23534   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23535 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23536 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23537 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23538 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23539 _(ip_dump, "ipv4 | ipv6")                                               \
23540 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23541 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23542   "  spid_id <n> ")                                                     \
23543 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23544   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23545   "  integ_alg <alg> integ_key <hex>")                                  \
23546 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23547   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23548   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23549   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23550 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23551 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23552   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23553   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23554   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23555   "  [instance <n>]")     \
23556 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23557 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23558   "  <alg> <hex>\n")                                                    \
23559 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23560 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23561 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23562   "(auth_data 0x<data> | auth_data <data>)")                            \
23563 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23564   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23565 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23566   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23567   "(local|remote)")                                                     \
23568 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23569 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23570 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23571 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23572 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23573 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23574 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23575 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23576 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23577 _(delete_loopback,"sw_if_index <nn>")                                   \
23578 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23579 _(map_add_domain,                                                       \
23580   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
23581   "ip6-src <ip6addr> "                                                  \
23582   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
23583 _(map_del_domain, "index <n>")                                          \
23584 _(map_add_del_rule,                                                     \
23585   "index <n> psid <n> dst <ip6addr> [del]")                             \
23586 _(map_domain_dump, "")                                                  \
23587 _(map_rule_dump, "index <map-domain>")                                  \
23588 _(want_interface_events,  "enable|disable")                             \
23589 _(want_stats,"enable|disable")                                          \
23590 _(get_first_msg_id, "client <name>")                                    \
23591 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23592 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23593   "fib-id <nn> [ip4][ip6][default]")                                    \
23594 _(get_node_graph, " ")                                                  \
23595 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23596 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23597 _(ioam_disable, "")                                                     \
23598 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23599                             " sw_if_index <sw_if_index> p <priority> "  \
23600                             "w <weight>] [del]")                        \
23601 _(one_add_del_locator, "locator-set <locator_name> "                    \
23602                         "iface <intf> | sw_if_index <sw_if_index> "     \
23603                         "p <priority> w <weight> [del]")                \
23604 _(one_add_del_local_eid,"vni <vni> eid "                                \
23605                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23606                          "locator-set <locator_name> [del]"             \
23607                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23608 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23609 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23610 _(one_enable_disable, "enable|disable")                                 \
23611 _(one_map_register_enable_disable, "enable|disable")                    \
23612 _(one_map_register_fallback_threshold, "<value>")                       \
23613 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23614 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23615                                "[seid <seid>] "                         \
23616                                "rloc <locator> p <prio> "               \
23617                                "w <weight> [rloc <loc> ... ] "          \
23618                                "action <action> [del-all]")             \
23619 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23620                           "<local-eid>")                                \
23621 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23622 _(one_use_petr, "ip-address> | disable")                                \
23623 _(one_map_request_mode, "src-dst|dst-only")                             \
23624 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23625 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23626 _(one_locator_set_dump, "[local | remote]")                             \
23627 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23628 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23629                        "[local] | [remote]")                            \
23630 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23631 _(one_ndp_bd_get, "")                                                   \
23632 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23633 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23634 _(one_l2_arp_bd_get, "")                                                \
23635 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23636 _(one_stats_enable_disable, "enable|disalbe")                           \
23637 _(show_one_stats_enable_disable, "")                                    \
23638 _(one_eid_table_vni_dump, "")                                           \
23639 _(one_eid_table_map_dump, "l2|l3")                                      \
23640 _(one_map_resolver_dump, "")                                            \
23641 _(one_map_server_dump, "")                                              \
23642 _(one_adjacencies_get, "vni <vni>")                                     \
23643 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23644 _(show_one_rloc_probe_state, "")                                        \
23645 _(show_one_map_register_state, "")                                      \
23646 _(show_one_status, "")                                                  \
23647 _(one_stats_dump, "")                                                   \
23648 _(one_stats_flush, "")                                                  \
23649 _(one_get_map_request_itr_rlocs, "")                                    \
23650 _(one_map_register_set_ttl, "<ttl>")                                    \
23651 _(one_set_transport_protocol, "udp|api")                                \
23652 _(one_get_transport_protocol, "")                                       \
23653 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23654 _(one_show_xtr_mode, "")                                                \
23655 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23656 _(one_show_pitr_mode, "")                                               \
23657 _(one_enable_disable_petr_mode, "enable|disable")                       \
23658 _(one_show_petr_mode, "")                                               \
23659 _(show_one_nsh_mapping, "")                                             \
23660 _(show_one_pitr, "")                                                    \
23661 _(show_one_use_petr, "")                                                \
23662 _(show_one_map_request_mode, "")                                        \
23663 _(show_one_map_register_ttl, "")                                        \
23664 _(show_one_map_register_fallback_threshold, "")                         \
23665 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23666                             " sw_if_index <sw_if_index> p <priority> "  \
23667                             "w <weight>] [del]")                        \
23668 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23669                         "iface <intf> | sw_if_index <sw_if_index> "     \
23670                         "p <priority> w <weight> [del]")                \
23671 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23672                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23673                          "locator-set <locator_name> [del]"             \
23674                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23675 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23676 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23677 _(lisp_enable_disable, "enable|disable")                                \
23678 _(lisp_map_register_enable_disable, "enable|disable")                   \
23679 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23680 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23681                                "[seid <seid>] "                         \
23682                                "rloc <locator> p <prio> "               \
23683                                "w <weight> [rloc <loc> ... ] "          \
23684                                "action <action> [del-all]")             \
23685 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23686                           "<local-eid>")                                \
23687 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23688 _(lisp_use_petr, "<ip-address> | disable")                              \
23689 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23690 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23691 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23692 _(lisp_locator_set_dump, "[local | remote]")                            \
23693 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23694 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23695                        "[local] | [remote]")                            \
23696 _(lisp_eid_table_vni_dump, "")                                          \
23697 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23698 _(lisp_map_resolver_dump, "")                                           \
23699 _(lisp_map_server_dump, "")                                             \
23700 _(lisp_adjacencies_get, "vni <vni>")                                    \
23701 _(gpe_fwd_entry_vnis_get, "")                                           \
23702 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23703 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23704                                 "[table <table-id>]")                   \
23705 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23706 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23707 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23708 _(gpe_get_encap_mode, "")                                               \
23709 _(lisp_gpe_add_del_iface, "up|down")                                    \
23710 _(lisp_gpe_enable_disable, "enable|disable")                            \
23711 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23712   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23713 _(show_lisp_rloc_probe_state, "")                                       \
23714 _(show_lisp_map_register_state, "")                                     \
23715 _(show_lisp_status, "")                                                 \
23716 _(lisp_get_map_request_itr_rlocs, "")                                   \
23717 _(show_lisp_pitr, "")                                                   \
23718 _(show_lisp_use_petr, "")                                               \
23719 _(show_lisp_map_request_mode, "")                                       \
23720 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23721 _(af_packet_delete, "name <host interface name>")                       \
23722 _(af_packet_dump, "")                                                   \
23723 _(policer_add_del, "name <policer name> <params> [del]")                \
23724 _(policer_dump, "[name <policer name>]")                                \
23725 _(policer_classify_set_interface,                                       \
23726   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23727   "  [l2-table <nn>] [del]")                                            \
23728 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23729 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23730     "[master|slave]")                                                   \
23731 _(netmap_delete, "name <interface name>")                               \
23732 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23733 _(mpls_fib_dump, "")                                                    \
23734 _(classify_table_ids, "")                                               \
23735 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23736 _(classify_table_info, "table_id <nn>")                                 \
23737 _(classify_session_dump, "table_id <nn>")                               \
23738 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23739     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23740     "[template_interval <nn>] [udp_checksum]")                          \
23741 _(ipfix_exporter_dump, "")                                              \
23742 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23743 _(ipfix_classify_stream_dump, "")                                       \
23744 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23745 _(ipfix_classify_table_dump, "")                                        \
23746 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23747 _(sw_interface_span_dump, "[l2]")                                           \
23748 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23749 _(pg_create_interface, "if_id <nn>")                                    \
23750 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23751 _(pg_enable_disable, "[stream <id>] disable")                           \
23752 _(ip_source_and_port_range_check_add_del,                               \
23753   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23754 _(ip_source_and_port_range_check_interface_add_del,                     \
23755   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23756   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23757 _(ipsec_gre_add_del_tunnel,                                             \
23758   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23759 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23760 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23761 _(l2_interface_pbb_tag_rewrite,                                         \
23762   "<intfc> | sw_if_index <nn> \n"                                       \
23763   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23764   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23765 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23766 _(flow_classify_set_interface,                                          \
23767   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23768 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23769 _(ip_fib_dump, "")                                                      \
23770 _(ip_mfib_dump, "")                                                     \
23771 _(ip6_fib_dump, "")                                                     \
23772 _(ip6_mfib_dump, "")                                                    \
23773 _(feature_enable_disable, "arc_name <arc_name> "                        \
23774   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23775 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23776 "[disable]")                                                            \
23777 _(l2_xconnect_dump, "")                                                 \
23778 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
23779 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23780 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23781 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23782 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23783 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23784 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23785   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23786 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23787 _(sock_init_shm, "size <nnn>")                                          \
23788 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23789 _(dns_enable_disable, "[enable][disable]")                              \
23790 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23791 _(dns_resolve_name, "<hostname>")                                       \
23792 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23793 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23794 _(dns_resolve_name, "<hostname>")                                       \
23795 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23796   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23797 _(session_rules_dump, "")                                               \
23798 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23799 _(output_acl_set_interface,                                             \
23800   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23801   "  [l2-table <nn>] [del]")                                            \
23802 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23803
23804 /* List of command functions, CLI names map directly to functions */
23805 #define foreach_cli_function                                    \
23806 _(comment, "usage: comment <ignore-rest-of-line>")              \
23807 _(dump_interface_table, "usage: dump_interface_table")          \
23808 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23809 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23810 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23811 _(dump_stats_table, "usage: dump_stats_table")                  \
23812 _(dump_macro_table, "usage: dump_macro_table ")                 \
23813 _(dump_node_table, "usage: dump_node_table")                    \
23814 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23815 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23816 _(echo, "usage: echo <message>")                                \
23817 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23818 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23819 _(help, "usage: help")                                          \
23820 _(q, "usage: quit")                                             \
23821 _(quit, "usage: quit")                                          \
23822 _(search_node_table, "usage: search_node_table <name>...")      \
23823 _(set, "usage: set <variable-name> <value>")                    \
23824 _(script, "usage: script <file-name>")                          \
23825 _(unset, "usage: unset <variable-name>")
23826 #define _(N,n)                                  \
23827     static void vl_api_##n##_t_handler_uni      \
23828     (vl_api_##n##_t * mp)                       \
23829     {                                           \
23830         vat_main_t * vam = &vat_main;           \
23831         if (vam->json_output) {                 \
23832             vl_api_##n##_t_handler_json(mp);    \
23833         } else {                                \
23834             vl_api_##n##_t_handler(mp);         \
23835         }                                       \
23836     }
23837 foreach_vpe_api_reply_msg;
23838 #if VPP_API_TEST_BUILTIN == 0
23839 foreach_standalone_reply_msg;
23840 #endif
23841 #undef _
23842
23843 void
23844 vat_api_hookup (vat_main_t * vam)
23845 {
23846 #define _(N,n)                                                  \
23847     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23848                            vl_api_##n##_t_handler_uni,          \
23849                            vl_noop_handler,                     \
23850                            vl_api_##n##_t_endian,               \
23851                            vl_api_##n##_t_print,                \
23852                            sizeof(vl_api_##n##_t), 1);
23853   foreach_vpe_api_reply_msg;
23854 #if VPP_API_TEST_BUILTIN == 0
23855   foreach_standalone_reply_msg;
23856 #endif
23857 #undef _
23858
23859 #if (VPP_API_TEST_BUILTIN==0)
23860   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23861
23862   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23863
23864   vam->function_by_name = hash_create_string (0, sizeof (uword));
23865
23866   vam->help_by_name = hash_create_string (0, sizeof (uword));
23867 #endif
23868
23869   /* API messages we can send */
23870 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23871   foreach_vpe_api_msg;
23872 #undef _
23873
23874   /* Help strings */
23875 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23876   foreach_vpe_api_msg;
23877 #undef _
23878
23879   /* CLI functions */
23880 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23881   foreach_cli_function;
23882 #undef _
23883
23884   /* Help strings */
23885 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23886   foreach_cli_function;
23887 #undef _
23888 }
23889
23890 #if VPP_API_TEST_BUILTIN
23891 static clib_error_t *
23892 vat_api_hookup_shim (vlib_main_t * vm)
23893 {
23894   vat_api_hookup (&vat_main);
23895   return 0;
23896 }
23897
23898 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23899 #endif
23900
23901 /*
23902  * fd.io coding-style-patch-verification: ON
23903  *
23904  * Local Variables:
23905  * eval: (c-set-style "gnu")
23906  * End:
23907  */