lisp: API cleanup
[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 <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 #include <vnet/format_fns.h>
89
90 void vl_api_set_elog_main (elog_main_t * m);
91 int vl_api_set_elog_trace_api_messages (int enable);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 #include <netdb.h>
95
96 u32
97 vl (void *p)
98 {
99   return vec_len (p);
100 }
101
102 int
103 vat_socket_connect (vat_main_t * vam)
104 {
105   int rv;
106   api_main_t *am = vlibapi_get_main ();
107   vam->socket_client_main = &socket_client_main;
108   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
109                                       "vpp_api_test",
110                                       0 /* default socket rx, tx buffer */ )))
111     return rv;
112
113   /* vpp expects the client index in network order */
114   vam->my_client_index = htonl (socket_client_main.client_index);
115   am->my_client_index = vam->my_client_index;
116   return 0;
117 }
118 #else /* vpp built-in case, we don't do sockets... */
119 int
120 vat_socket_connect (vat_main_t * vam)
121 {
122   return 0;
123 }
124
125 int
126 vl_socket_client_read (int wait)
127 {
128   return -1;
129 };
130
131 int
132 vl_socket_client_write ()
133 {
134   return -1;
135 };
136
137 void *
138 vl_socket_client_msg_alloc (int nbytes)
139 {
140   return 0;
141 }
142 #endif
143
144
145 f64
146 vat_time_now (vat_main_t * vam)
147 {
148 #if VPP_API_TEST_BUILTIN
149   return vlib_time_now (vam->vlib_main);
150 #else
151   return clib_time_now (&vam->clib_time);
152 #endif
153 }
154
155 void
156 errmsg (char *fmt, ...)
157 {
158   vat_main_t *vam = &vat_main;
159   va_list va;
160   u8 *s;
161
162   va_start (va, fmt);
163   s = va_format (0, fmt, &va);
164   va_end (va);
165
166   vec_add1 (s, 0);
167
168 #if VPP_API_TEST_BUILTIN
169   vlib_cli_output (vam->vlib_main, (char *) s);
170 #else
171   {
172     if (vam->ifp != stdin)
173       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
174                vam->input_line_number);
175     else
176       fformat (vam->ofp, "%s\n", (char *) s);
177     fflush (vam->ofp);
178   }
179 #endif
180
181   vec_free (s);
182 }
183
184 #if VPP_API_TEST_BUILTIN == 0
185 static uword
186 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
187 {
188   vat_main_t *vam = va_arg (*args, vat_main_t *);
189   u32 *result = va_arg (*args, u32 *);
190   u8 *if_name;
191   uword *p;
192
193   if (!unformat (input, "%s", &if_name))
194     return 0;
195
196   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
197   if (p == 0)
198     return 0;
199   *result = p[0];
200   return 1;
201 }
202
203 static uword
204 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
205 {
206   return 0;
207 }
208
209 /* Parse an IP4 address %d.%d.%d.%d. */
210 uword
211 unformat_ip4_address (unformat_input_t * input, va_list * args)
212 {
213   u8 *result = va_arg (*args, u8 *);
214   unsigned a[4];
215
216   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
217     return 0;
218
219   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
220     return 0;
221
222   result[0] = a[0];
223   result[1] = a[1];
224   result[2] = a[2];
225   result[3] = a[3];
226
227   return 1;
228 }
229
230 uword
231 unformat_ethernet_address (unformat_input_t * input, va_list * args)
232 {
233   u8 *result = va_arg (*args, u8 *);
234   u32 i, a[6];
235
236   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
237                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
238     return 0;
239
240   /* Check range. */
241   for (i = 0; i < 6; i++)
242     if (a[i] >= (1 << 8))
243       return 0;
244
245   for (i = 0; i < 6; i++)
246     result[i] = a[i];
247
248   return 1;
249 }
250
251 /* Returns ethernet type as an int in host byte order. */
252 uword
253 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
254                                         va_list * args)
255 {
256   u16 *result = va_arg (*args, u16 *);
257   int type;
258
259   /* Numeric type. */
260   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
261     {
262       if (type >= (1 << 16))
263         return 0;
264       *result = type;
265       return 1;
266     }
267   return 0;
268 }
269
270 /* Parse an IP46 address. */
271 uword
272 unformat_ip46_address (unformat_input_t * input, va_list * args)
273 {
274   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
275   ip46_type_t type = va_arg (*args, ip46_type_t);
276   if ((type != IP46_TYPE_IP6) &&
277       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
278     {
279       ip46_address_mask_ip4 (ip46);
280       return 1;
281     }
282   else if ((type != IP46_TYPE_IP4) &&
283            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
284     {
285       return 1;
286     }
287   return 0;
288 }
289
290 /* Parse an IP6 address. */
291 uword
292 unformat_ip6_address (unformat_input_t * input, va_list * args)
293 {
294   ip6_address_t *result = va_arg (*args, ip6_address_t *);
295   u16 hex_quads[8];
296   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
297   uword c, n_colon, double_colon_index;
298
299   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
300   double_colon_index = ARRAY_LEN (hex_quads);
301   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
302     {
303       hex_digit = 16;
304       if (c >= '0' && c <= '9')
305         hex_digit = c - '0';
306       else if (c >= 'a' && c <= 'f')
307         hex_digit = c + 10 - 'a';
308       else if (c >= 'A' && c <= 'F')
309         hex_digit = c + 10 - 'A';
310       else if (c == ':' && n_colon < 2)
311         n_colon++;
312       else
313         {
314           unformat_put_input (input);
315           break;
316         }
317
318       /* Too many hex quads. */
319       if (n_hex_quads >= ARRAY_LEN (hex_quads))
320         return 0;
321
322       if (hex_digit < 16)
323         {
324           hex_quad = (hex_quad << 4) | hex_digit;
325
326           /* Hex quad must fit in 16 bits. */
327           if (n_hex_digits >= 4)
328             return 0;
329
330           n_colon = 0;
331           n_hex_digits++;
332         }
333
334       /* Save position of :: */
335       if (n_colon == 2)
336         {
337           /* More than one :: ? */
338           if (double_colon_index < ARRAY_LEN (hex_quads))
339             return 0;
340           double_colon_index = n_hex_quads;
341         }
342
343       if (n_colon > 0 && n_hex_digits > 0)
344         {
345           hex_quads[n_hex_quads++] = hex_quad;
346           hex_quad = 0;
347           n_hex_digits = 0;
348         }
349     }
350
351   if (n_hex_digits > 0)
352     hex_quads[n_hex_quads++] = hex_quad;
353
354   {
355     word i;
356
357     /* Expand :: to appropriate number of zero hex quads. */
358     if (double_colon_index < ARRAY_LEN (hex_quads))
359       {
360         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
361
362         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
363           hex_quads[n_zero + i] = hex_quads[i];
364
365         for (i = 0; i < n_zero; i++)
366           hex_quads[double_colon_index + i] = 0;
367
368         n_hex_quads = ARRAY_LEN (hex_quads);
369       }
370
371     /* Too few hex quads given. */
372     if (n_hex_quads < ARRAY_LEN (hex_quads))
373       return 0;
374
375     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
376       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
377
378     return 1;
379   }
380 }
381
382 uword
383 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
384 {
385   u32 *r = va_arg (*args, u32 *);
386
387   if (0);
388 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
389   foreach_ipsec_policy_action
390 #undef _
391     else
392     return 0;
393   return 1;
394 }
395
396 u8 *
397 format_ipsec_crypto_alg (u8 * s, va_list * args)
398 {
399   u32 i = va_arg (*args, u32);
400   u8 *t = 0;
401
402   switch (i)
403     {
404 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
405       foreach_ipsec_crypto_alg
406 #undef _
407     default:
408       return format (s, "unknown");
409     }
410   return format (s, "%s", t);
411 }
412
413 u8 *
414 format_ipsec_integ_alg (u8 * s, va_list * args)
415 {
416   u32 i = va_arg (*args, u32);
417   u8 *t = 0;
418
419   switch (i)
420     {
421 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
422       foreach_ipsec_integ_alg
423 #undef _
424     default:
425       return format (s, "unknown");
426     }
427   return format (s, "%s", t);
428 }
429
430 #else /* VPP_API_TEST_BUILTIN == 1 */
431 static uword
432 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
433 {
434   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
435   vnet_main_t *vnm = vnet_get_main ();
436   u32 *result = va_arg (*args, u32 *);
437
438   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
439 }
440
441 static uword
442 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
443 {
444   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
445   vnet_main_t *vnm = vnet_get_main ();
446   u32 *result = va_arg (*args, u32 *);
447
448   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
449 }
450
451 #endif /* VPP_API_TEST_BUILTIN */
452
453 uword
454 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
455 {
456   u32 *r = va_arg (*args, u32 *);
457
458   if (0);
459 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
460   foreach_ipsec_crypto_alg
461 #undef _
462     else
463     return 0;
464   return 1;
465 }
466
467 uword
468 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
469 {
470   u32 *r = va_arg (*args, u32 *);
471
472   if (0);
473 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
474   foreach_ipsec_integ_alg
475 #undef _
476     else
477     return 0;
478   return 1;
479 }
480
481 static uword
482 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
483 {
484   u8 *r = va_arg (*args, u8 *);
485
486   if (unformat (input, "kbps"))
487     *r = SSE2_QOS_RATE_KBPS;
488   else if (unformat (input, "pps"))
489     *r = SSE2_QOS_RATE_PPS;
490   else
491     return 0;
492   return 1;
493 }
494
495 static uword
496 unformat_policer_round_type (unformat_input_t * input, va_list * args)
497 {
498   u8 *r = va_arg (*args, u8 *);
499
500   if (unformat (input, "closest"))
501     *r = SSE2_QOS_ROUND_TO_CLOSEST;
502   else if (unformat (input, "up"))
503     *r = SSE2_QOS_ROUND_TO_UP;
504   else if (unformat (input, "down"))
505     *r = SSE2_QOS_ROUND_TO_DOWN;
506   else
507     return 0;
508   return 1;
509 }
510
511 static uword
512 unformat_policer_type (unformat_input_t * input, va_list * args)
513 {
514   u8 *r = va_arg (*args, u8 *);
515
516   if (unformat (input, "1r2c"))
517     *r = SSE2_QOS_POLICER_TYPE_1R2C;
518   else if (unformat (input, "1r3c"))
519     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
520   else if (unformat (input, "2r3c-2698"))
521     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
522   else if (unformat (input, "2r3c-4115"))
523     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
524   else if (unformat (input, "2r3c-mef5cf1"))
525     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
526   else
527     return 0;
528   return 1;
529 }
530
531 static uword
532 unformat_dscp (unformat_input_t * input, va_list * va)
533 {
534   u8 *r = va_arg (*va, u8 *);
535
536   if (0);
537 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
538   foreach_vnet_dscp
539 #undef _
540     else
541     return 0;
542   return 1;
543 }
544
545 static uword
546 unformat_policer_action_type (unformat_input_t * input, va_list * va)
547 {
548   sse2_qos_pol_action_params_st *a
549     = va_arg (*va, sse2_qos_pol_action_params_st *);
550
551   if (unformat (input, "drop"))
552     a->action_type = SSE2_QOS_ACTION_DROP;
553   else if (unformat (input, "transmit"))
554     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
555   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
556     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
557   else
558     return 0;
559   return 1;
560 }
561
562 static uword
563 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
564 {
565   u32 *r = va_arg (*va, u32 *);
566   u32 tid;
567
568   if (unformat (input, "ip4"))
569     tid = POLICER_CLASSIFY_TABLE_IP4;
570   else if (unformat (input, "ip6"))
571     tid = POLICER_CLASSIFY_TABLE_IP6;
572   else if (unformat (input, "l2"))
573     tid = POLICER_CLASSIFY_TABLE_L2;
574   else
575     return 0;
576
577   *r = tid;
578   return 1;
579 }
580
581 static uword
582 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
583 {
584   u32 *r = va_arg (*va, u32 *);
585   u32 tid;
586
587   if (unformat (input, "ip4"))
588     tid = FLOW_CLASSIFY_TABLE_IP4;
589   else if (unformat (input, "ip6"))
590     tid = FLOW_CLASSIFY_TABLE_IP6;
591   else
592     return 0;
593
594   *r = tid;
595   return 1;
596 }
597
598 #if (VPP_API_TEST_BUILTIN==0)
599
600 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
601 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
602 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
603 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
604
605 uword
606 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
607 {
608   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
609   mfib_itf_attribute_t attr;
610
611   old = *iflags;
612   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
613   {
614     if (unformat (input, mfib_itf_flag_long_names[attr]))
615       *iflags |= (1 << attr);
616   }
617   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
618   {
619     if (unformat (input, mfib_itf_flag_names[attr]))
620       *iflags |= (1 << attr);
621   }
622
623   return (old == *iflags ? 0 : 1);
624 }
625
626 uword
627 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
628 {
629   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
630   mfib_entry_attribute_t attr;
631
632   old = *eflags;
633   FOR_EACH_MFIB_ATTRIBUTE (attr)
634   {
635     if (unformat (input, mfib_flag_long_names[attr]))
636       *eflags |= (1 << attr);
637   }
638   FOR_EACH_MFIB_ATTRIBUTE (attr)
639   {
640     if (unformat (input, mfib_flag_names[attr]))
641       *eflags |= (1 << attr);
642   }
643
644   return (old == *eflags ? 0 : 1);
645 }
646
647 u8 *
648 format_ip4_address (u8 * s, va_list * args)
649 {
650   u8 *a = va_arg (*args, u8 *);
651   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
652 }
653
654 u8 *
655 format_ip6_address (u8 * s, va_list * args)
656 {
657   ip6_address_t *a = va_arg (*args, ip6_address_t *);
658   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
659
660   i_max_n_zero = ARRAY_LEN (a->as_u16);
661   max_n_zeros = 0;
662   i_first_zero = i_max_n_zero;
663   n_zeros = 0;
664   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
665     {
666       u32 is_zero = a->as_u16[i] == 0;
667       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
668         {
669           i_first_zero = i;
670           n_zeros = 0;
671         }
672       n_zeros += is_zero;
673       if ((!is_zero && n_zeros > max_n_zeros)
674           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
675         {
676           i_max_n_zero = i_first_zero;
677           max_n_zeros = n_zeros;
678           i_first_zero = ARRAY_LEN (a->as_u16);
679           n_zeros = 0;
680         }
681     }
682
683   last_double_colon = 0;
684   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
685     {
686       if (i == i_max_n_zero && max_n_zeros > 1)
687         {
688           s = format (s, "::");
689           i += max_n_zeros - 1;
690           last_double_colon = 1;
691         }
692       else
693         {
694           s = format (s, "%s%x",
695                       (last_double_colon || i == 0) ? "" : ":",
696                       clib_net_to_host_u16 (a->as_u16[i]));
697           last_double_colon = 0;
698         }
699     }
700
701   return s;
702 }
703
704 /* Format an IP46 address. */
705 u8 *
706 format_ip46_address (u8 * s, va_list * args)
707 {
708   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
709   ip46_type_t type = va_arg (*args, ip46_type_t);
710   int is_ip4 = 1;
711
712   switch (type)
713     {
714     case IP46_TYPE_ANY:
715       is_ip4 = ip46_address_is_ip4 (ip46);
716       break;
717     case IP46_TYPE_IP4:
718       is_ip4 = 1;
719       break;
720     case IP46_TYPE_IP6:
721       is_ip4 = 0;
722       break;
723     }
724
725   return is_ip4 ?
726     format (s, "%U", format_ip4_address, &ip46->ip4) :
727     format (s, "%U", format_ip6_address, &ip46->ip6);
728 }
729
730 u8 *
731 format_ethernet_address (u8 * s, va_list * args)
732 {
733   u8 *a = va_arg (*args, u8 *);
734
735   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
736                  a[0], a[1], a[2], a[3], a[4], a[5]);
737 }
738 #endif
739
740 static void
741 increment_v4_address (vl_api_ip4_address_t * i)
742 {
743   ip4_address_t *a = (ip4_address_t *) i;
744   u32 v;
745
746   v = ntohl (a->as_u32) + 1;
747   a->as_u32 = ntohl (v);
748 }
749
750 static void
751 increment_v6_address (vl_api_ip6_address_t * i)
752 {
753   ip6_address_t *a = (ip6_address_t *) i;
754   u64 v0, v1;
755
756   v0 = clib_net_to_host_u64 (a->as_u64[0]);
757   v1 = clib_net_to_host_u64 (a->as_u64[1]);
758
759   v1 += 1;
760   if (v1 == 0)
761     v0 += 1;
762   a->as_u64[0] = clib_net_to_host_u64 (v0);
763   a->as_u64[1] = clib_net_to_host_u64 (v1);
764 }
765
766 static void
767 increment_address (vl_api_address_t * a)
768 {
769   if (a->af == ADDRESS_IP4)
770     increment_v4_address (&a->un.ip4);
771   else if (a->af == ADDRESS_IP6)
772     increment_v6_address (&a->un.ip6);
773 }
774
775 static void
776 set_ip4_address (vl_api_address_t * a, u32 v)
777 {
778   if (a->af == ADDRESS_IP4)
779     {
780       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
781       i->as_u32 = v;
782     }
783 }
784
785 void
786 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
787 {
788   if (is_ip4)
789     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
790   else
791     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
792                       sizeof (ip6_address_t));
793 }
794
795 static void
796 increment_mac_address (u8 * mac)
797 {
798   u64 tmp = *((u64 *) mac);
799   tmp = clib_net_to_host_u64 (tmp);
800   tmp += 1 << 16;               /* skip unused (least significant) octets */
801   tmp = clib_host_to_net_u64 (tmp);
802
803   clib_memcpy (mac, &tmp, 6);
804 }
805
806 static void
807 vat_json_object_add_address (vat_json_node_t * node,
808                              const char *str, const vl_api_address_t * addr)
809 {
810   if (ADDRESS_IP6 == addr->af)
811     {
812       struct in6_addr ip6;
813
814       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
815       vat_json_object_add_ip6 (node, str, ip6);
816     }
817   else
818     {
819       struct in_addr ip4;
820
821       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
822       vat_json_object_add_ip4 (node, str, ip4);
823     }
824 }
825
826 static void
827 vat_json_object_add_prefix (vat_json_node_t * node,
828                             const vl_api_prefix_t * prefix)
829 {
830   vat_json_object_add_uint (node, "len", prefix->len);
831   vat_json_object_add_address (node, "address", &prefix->address);
832 }
833
834 static void vl_api_create_loopback_reply_t_handler
835   (vl_api_create_loopback_reply_t * mp)
836 {
837   vat_main_t *vam = &vat_main;
838   i32 retval = ntohl (mp->retval);
839
840   vam->retval = retval;
841   vam->regenerate_interface_table = 1;
842   vam->sw_if_index = ntohl (mp->sw_if_index);
843   vam->result_ready = 1;
844 }
845
846 static void vl_api_create_loopback_reply_t_handler_json
847   (vl_api_create_loopback_reply_t * mp)
848 {
849   vat_main_t *vam = &vat_main;
850   vat_json_node_t node;
851
852   vat_json_init_object (&node);
853   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
854   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
855
856   vat_json_print (vam->ofp, &node);
857   vat_json_free (&node);
858   vam->retval = ntohl (mp->retval);
859   vam->result_ready = 1;
860 }
861
862 static void vl_api_create_loopback_instance_reply_t_handler
863   (vl_api_create_loopback_instance_reply_t * mp)
864 {
865   vat_main_t *vam = &vat_main;
866   i32 retval = ntohl (mp->retval);
867
868   vam->retval = retval;
869   vam->regenerate_interface_table = 1;
870   vam->sw_if_index = ntohl (mp->sw_if_index);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_create_loopback_instance_reply_t_handler_json
875   (vl_api_create_loopback_instance_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   vat_json_node_t node;
879
880   vat_json_init_object (&node);
881   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
882   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
883
884   vat_json_print (vam->ofp, &node);
885   vat_json_free (&node);
886   vam->retval = ntohl (mp->retval);
887   vam->result_ready = 1;
888 }
889
890 static void vl_api_af_packet_create_reply_t_handler
891   (vl_api_af_packet_create_reply_t * mp)
892 {
893   vat_main_t *vam = &vat_main;
894   i32 retval = ntohl (mp->retval);
895
896   vam->retval = retval;
897   vam->regenerate_interface_table = 1;
898   vam->sw_if_index = ntohl (mp->sw_if_index);
899   vam->result_ready = 1;
900 }
901
902 static void vl_api_af_packet_create_reply_t_handler_json
903   (vl_api_af_packet_create_reply_t * mp)
904 {
905   vat_main_t *vam = &vat_main;
906   vat_json_node_t node;
907
908   vat_json_init_object (&node);
909   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
910   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
911
912   vat_json_print (vam->ofp, &node);
913   vat_json_free (&node);
914
915   vam->retval = ntohl (mp->retval);
916   vam->result_ready = 1;
917 }
918
919 static void vl_api_create_vlan_subif_reply_t_handler
920   (vl_api_create_vlan_subif_reply_t * mp)
921 {
922   vat_main_t *vam = &vat_main;
923   i32 retval = ntohl (mp->retval);
924
925   vam->retval = retval;
926   vam->regenerate_interface_table = 1;
927   vam->sw_if_index = ntohl (mp->sw_if_index);
928   vam->result_ready = 1;
929 }
930
931 static void vl_api_create_vlan_subif_reply_t_handler_json
932   (vl_api_create_vlan_subif_reply_t * mp)
933 {
934   vat_main_t *vam = &vat_main;
935   vat_json_node_t node;
936
937   vat_json_init_object (&node);
938   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
939   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
940
941   vat_json_print (vam->ofp, &node);
942   vat_json_free (&node);
943
944   vam->retval = ntohl (mp->retval);
945   vam->result_ready = 1;
946 }
947
948 static void vl_api_create_subif_reply_t_handler
949   (vl_api_create_subif_reply_t * mp)
950 {
951   vat_main_t *vam = &vat_main;
952   i32 retval = ntohl (mp->retval);
953
954   vam->retval = retval;
955   vam->regenerate_interface_table = 1;
956   vam->sw_if_index = ntohl (mp->sw_if_index);
957   vam->result_ready = 1;
958 }
959
960 static void vl_api_create_subif_reply_t_handler_json
961   (vl_api_create_subif_reply_t * mp)
962 {
963   vat_main_t *vam = &vat_main;
964   vat_json_node_t node;
965
966   vat_json_init_object (&node);
967   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
968   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
969
970   vat_json_print (vam->ofp, &node);
971   vat_json_free (&node);
972
973   vam->retval = ntohl (mp->retval);
974   vam->result_ready = 1;
975 }
976
977 static void vl_api_interface_name_renumber_reply_t_handler
978   (vl_api_interface_name_renumber_reply_t * mp)
979 {
980   vat_main_t *vam = &vat_main;
981   i32 retval = ntohl (mp->retval);
982
983   vam->retval = retval;
984   vam->regenerate_interface_table = 1;
985   vam->result_ready = 1;
986 }
987
988 static void vl_api_interface_name_renumber_reply_t_handler_json
989   (vl_api_interface_name_renumber_reply_t * mp)
990 {
991   vat_main_t *vam = &vat_main;
992   vat_json_node_t node;
993
994   vat_json_init_object (&node);
995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
996
997   vat_json_print (vam->ofp, &node);
998   vat_json_free (&node);
999
1000   vam->retval = ntohl (mp->retval);
1001   vam->result_ready = 1;
1002 }
1003
1004 /*
1005  * Special-case: build the interface table, maintain
1006  * the next loopback sw_if_index vbl.
1007  */
1008 static void vl_api_sw_interface_details_t_handler
1009   (vl_api_sw_interface_details_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1013
1014   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1015                 ntohl (mp->sw_if_index));
1016
1017   /* In sub interface case, fill the sub interface table entry */
1018   if (mp->sw_if_index != mp->sup_sw_if_index)
1019     {
1020       sw_interface_subif_t *sub = NULL;
1021
1022       vec_add2 (vam->sw_if_subif_table, sub, 1);
1023
1024       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1025       strncpy ((char *) sub->interface_name, (char *) s,
1026                vec_len (sub->interface_name));
1027       sub->sw_if_index = ntohl (mp->sw_if_index);
1028       sub->sub_id = ntohl (mp->sub_id);
1029
1030       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1031
1032       sub->sub_number_of_tags = mp->sub_number_of_tags;
1033       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1034       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1035
1036       /* vlan tag rewrite */
1037       sub->vtr_op = ntohl (mp->vtr_op);
1038       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1039       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1040       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1041     }
1042 }
1043
1044 static void vl_api_sw_interface_details_t_handler_json
1045   (vl_api_sw_interface_details_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t *node = NULL;
1049
1050   if (VAT_JSON_ARRAY != vam->json_tree.type)
1051     {
1052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1053       vat_json_init_array (&vam->json_tree);
1054     }
1055   node = vat_json_array_add (&vam->json_tree);
1056
1057   vat_json_init_object (node);
1058   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1059   vat_json_object_add_uint (node, "sup_sw_if_index",
1060                             ntohl (mp->sup_sw_if_index));
1061   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1062                              sizeof (mp->l2_address));
1063   vat_json_object_add_string_copy (node, "interface_name",
1064                                    mp->interface_name);
1065   vat_json_object_add_string_copy (node, "interface_dev_type",
1066                                    mp->interface_dev_type);
1067   vat_json_object_add_uint (node, "flags", mp->flags);
1068   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1069   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1070   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1071   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1072   vat_json_object_add_uint (node, "sub_number_of_tags",
1073                             mp->sub_number_of_tags);
1074   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1075                             ntohs (mp->sub_outer_vlan_id));
1076   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1077                             ntohs (mp->sub_inner_vlan_id));
1078   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1079   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1080   vat_json_object_add_uint (node, "vtr_push_dot1q",
1081                             ntohl (mp->vtr_push_dot1q));
1082   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1083   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1084   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1085     {
1086       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1087                                        format (0, "%U",
1088                                                format_ethernet_address,
1089                                                &mp->b_dmac));
1090       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1091                                        format (0, "%U",
1092                                                format_ethernet_address,
1093                                                &mp->b_smac));
1094       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1095       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1096     }
1097 }
1098
1099 #if VPP_API_TEST_BUILTIN == 0
1100 static void vl_api_sw_interface_event_t_handler
1101   (vl_api_sw_interface_event_t * mp)
1102 {
1103   vat_main_t *vam = &vat_main;
1104   if (vam->interface_event_display)
1105     errmsg ("interface flags: sw_if_index %d %s %s",
1106             ntohl (mp->sw_if_index),
1107             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1108             "admin-up" : "admin-down",
1109             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1110             "link-up" : "link-down");
1111 }
1112 #endif
1113
1114 __clib_unused static void
1115 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1116 {
1117   /* JSON output not supported */
1118 }
1119
1120 static void
1121 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1122 {
1123   vat_main_t *vam = &vat_main;
1124   i32 retval = ntohl (mp->retval);
1125
1126   vam->retval = retval;
1127   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1128   vam->result_ready = 1;
1129 }
1130
1131 static void
1132 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   vat_json_node_t node;
1136   void *oldheap;
1137   u8 *reply;
1138
1139   vat_json_init_object (&node);
1140   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1141   vat_json_object_add_uint (&node, "reply_in_shmem",
1142                             ntohl (mp->reply_in_shmem));
1143   /* Toss the shared-memory original... */
1144   oldheap = vl_msg_push_heap ();
1145
1146   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1147   vec_free (reply);
1148
1149   vl_msg_pop_heap (oldheap);
1150
1151   vat_json_print (vam->ofp, &node);
1152   vat_json_free (&node);
1153
1154   vam->retval = ntohl (mp->retval);
1155   vam->result_ready = 1;
1156 }
1157
1158 static void
1159 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1160 {
1161   vat_main_t *vam = &vat_main;
1162   i32 retval = ntohl (mp->retval);
1163
1164   vec_reset_length (vam->cmd_reply);
1165
1166   vam->retval = retval;
1167   if (retval == 0)
1168     vam->cmd_reply = vl_api_from_api_to_new_vec (&mp->reply);
1169   vam->result_ready = 1;
1170 }
1171
1172 static void
1173 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1174 {
1175   vat_main_t *vam = &vat_main;
1176   vat_json_node_t node;
1177   u8 *reply = 0;                /* reply vector */
1178
1179   reply = vl_api_from_api_to_new_vec (&mp->reply);
1180   vec_reset_length (vam->cmd_reply);
1181
1182   vat_json_init_object (&node);
1183   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1184   vat_json_object_add_string_copy (&node, "reply", reply);
1185
1186   vat_json_print (vam->ofp, &node);
1187   vat_json_free (&node);
1188   vec_free (reply);
1189
1190   vam->retval = ntohl (mp->retval);
1191   vam->result_ready = 1;
1192 }
1193
1194 static void vl_api_classify_add_del_table_reply_t_handler
1195   (vl_api_classify_add_del_table_reply_t * mp)
1196 {
1197   vat_main_t *vam = &vat_main;
1198   i32 retval = ntohl (mp->retval);
1199   if (vam->async_mode)
1200     {
1201       vam->async_errors += (retval < 0);
1202     }
1203   else
1204     {
1205       vam->retval = retval;
1206       if (retval == 0 &&
1207           ((mp->new_table_index != 0xFFFFFFFF) ||
1208            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1209            (mp->match_n_vectors != 0xFFFFFFFF)))
1210         /*
1211          * Note: this is just barely thread-safe, depends on
1212          * the main thread spinning waiting for an answer...
1213          */
1214         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1215                 ntohl (mp->new_table_index),
1216                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1217       vam->result_ready = 1;
1218     }
1219 }
1220
1221 static void vl_api_classify_add_del_table_reply_t_handler_json
1222   (vl_api_classify_add_del_table_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, "new_table_index",
1230                             ntohl (mp->new_table_index));
1231   vat_json_object_add_uint (&node, "skip_n_vectors",
1232                             ntohl (mp->skip_n_vectors));
1233   vat_json_object_add_uint (&node, "match_n_vectors",
1234                             ntohl (mp->match_n_vectors));
1235
1236   vat_json_print (vam->ofp, &node);
1237   vat_json_free (&node);
1238
1239   vam->retval = ntohl (mp->retval);
1240   vam->result_ready = 1;
1241 }
1242
1243 static void vl_api_get_node_index_reply_t_handler
1244   (vl_api_get_node_index_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   i32 retval = ntohl (mp->retval);
1248   if (vam->async_mode)
1249     {
1250       vam->async_errors += (retval < 0);
1251     }
1252   else
1253     {
1254       vam->retval = retval;
1255       if (retval == 0)
1256         errmsg ("node index %d", ntohl (mp->node_index));
1257       vam->result_ready = 1;
1258     }
1259 }
1260
1261 static void vl_api_get_node_index_reply_t_handler_json
1262   (vl_api_get_node_index_reply_t * mp)
1263 {
1264   vat_main_t *vam = &vat_main;
1265   vat_json_node_t node;
1266
1267   vat_json_init_object (&node);
1268   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1269   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1270
1271   vat_json_print (vam->ofp, &node);
1272   vat_json_free (&node);
1273
1274   vam->retval = ntohl (mp->retval);
1275   vam->result_ready = 1;
1276 }
1277
1278 static void vl_api_get_next_index_reply_t_handler
1279   (vl_api_get_next_index_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       if (retval == 0)
1291         errmsg ("next node index %d", ntohl (mp->next_index));
1292       vam->result_ready = 1;
1293     }
1294 }
1295
1296 static void vl_api_get_next_index_reply_t_handler_json
1297   (vl_api_get_next_index_reply_t * mp)
1298 {
1299   vat_main_t *vam = &vat_main;
1300   vat_json_node_t node;
1301
1302   vat_json_init_object (&node);
1303   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1304   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1305
1306   vat_json_print (vam->ofp, &node);
1307   vat_json_free (&node);
1308
1309   vam->retval = ntohl (mp->retval);
1310   vam->result_ready = 1;
1311 }
1312
1313 static void vl_api_add_node_next_reply_t_handler
1314   (vl_api_add_node_next_reply_t * mp)
1315 {
1316   vat_main_t *vam = &vat_main;
1317   i32 retval = ntohl (mp->retval);
1318   if (vam->async_mode)
1319     {
1320       vam->async_errors += (retval < 0);
1321     }
1322   else
1323     {
1324       vam->retval = retval;
1325       if (retval == 0)
1326         errmsg ("next index %d", ntohl (mp->next_index));
1327       vam->result_ready = 1;
1328     }
1329 }
1330
1331 static void vl_api_add_node_next_reply_t_handler_json
1332   (vl_api_add_node_next_reply_t * mp)
1333 {
1334   vat_main_t *vam = &vat_main;
1335   vat_json_node_t node;
1336
1337   vat_json_init_object (&node);
1338   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1339   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1340
1341   vat_json_print (vam->ofp, &node);
1342   vat_json_free (&node);
1343
1344   vam->retval = ntohl (mp->retval);
1345   vam->result_ready = 1;
1346 }
1347
1348 static void vl_api_show_version_reply_t_handler
1349   (vl_api_show_version_reply_t * mp)
1350 {
1351   vat_main_t *vam = &vat_main;
1352   i32 retval = ntohl (mp->retval);
1353
1354   if (retval >= 0)
1355     {
1356       errmsg ("        program: %s", mp->program);
1357       errmsg ("        version: %s", mp->version);
1358       errmsg ("     build date: %s", mp->build_date);
1359       errmsg ("build directory: %s", mp->build_directory);
1360     }
1361   vam->retval = retval;
1362   vam->result_ready = 1;
1363 }
1364
1365 static void vl_api_show_version_reply_t_handler_json
1366   (vl_api_show_version_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t node;
1370
1371   vat_json_init_object (&node);
1372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1373   vat_json_object_add_string_copy (&node, "program", mp->program);
1374   vat_json_object_add_string_copy (&node, "version", mp->version);
1375   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1376   vat_json_object_add_string_copy (&node, "build_directory",
1377                                    mp->build_directory);
1378
1379   vat_json_print (vam->ofp, &node);
1380   vat_json_free (&node);
1381
1382   vam->retval = ntohl (mp->retval);
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_show_threads_reply_t_handler
1387   (vl_api_show_threads_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   int i, count = 0;
1392
1393   if (retval >= 0)
1394     count = ntohl (mp->count);
1395
1396   for (i = 0; i < count; i++)
1397     print (vam->ofp,
1398            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1399            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1400            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1401            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1402            ntohl (mp->thread_data[i].cpu_socket));
1403
1404   vam->retval = retval;
1405   vam->result_ready = 1;
1406 }
1407
1408 static void vl_api_show_threads_reply_t_handler_json
1409   (vl_api_show_threads_reply_t * mp)
1410 {
1411   vat_main_t *vam = &vat_main;
1412   vat_json_node_t node;
1413   vl_api_thread_data_t *td;
1414   i32 retval = ntohl (mp->retval);
1415   int i, count = 0;
1416
1417   if (retval >= 0)
1418     count = ntohl (mp->count);
1419
1420   vat_json_init_object (&node);
1421   vat_json_object_add_int (&node, "retval", retval);
1422   vat_json_object_add_uint (&node, "count", count);
1423
1424   for (i = 0; i < count; i++)
1425     {
1426       td = &mp->thread_data[i];
1427       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1428       vat_json_object_add_string_copy (&node, "name", td->name);
1429       vat_json_object_add_string_copy (&node, "type", td->type);
1430       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1431       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1432       vat_json_object_add_int (&node, "core", ntohl (td->id));
1433       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1434     }
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = retval;
1440   vam->result_ready = 1;
1441 }
1442
1443 static int
1444 api_show_threads (vat_main_t * vam)
1445 {
1446   vl_api_show_threads_t *mp;
1447   int ret;
1448
1449   print (vam->ofp,
1450          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1451          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1452
1453   M (SHOW_THREADS, mp);
1454
1455   S (mp);
1456   W (ret);
1457   return ret;
1458 }
1459
1460 static void
1461 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1462 {
1463   u32 n_macs = ntohl (mp->n_macs);
1464   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1465           ntohl (mp->pid), mp->client_index, n_macs);
1466   int i;
1467   for (i = 0; i < n_macs; i++)
1468     {
1469       vl_api_mac_entry_t *mac = &mp->mac[i];
1470       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1471               i + 1, ntohl (mac->sw_if_index),
1472               format_ethernet_address, mac->mac_addr, mac->action);
1473       if (i == 1000)
1474         break;
1475     }
1476 }
1477
1478 static void
1479 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1480 {
1481   /* JSON output not supported */
1482 }
1483
1484 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1485 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1486
1487 /*
1488  * Special-case: build the bridge domain table, maintain
1489  * the next bd id vbl.
1490  */
1491 static void vl_api_bridge_domain_details_t_handler
1492   (vl_api_bridge_domain_details_t * mp)
1493 {
1494   vat_main_t *vam = &vat_main;
1495   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1496   int i;
1497
1498   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1499          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1500
1501   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1502          ntohl (mp->bd_id), mp->learn, mp->forward,
1503          mp->flood, ntohl (mp->bvi_sw_if_index),
1504          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1505
1506   if (n_sw_ifs)
1507     {
1508       vl_api_bridge_domain_sw_if_t *sw_ifs;
1509       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1510              "Interface Name");
1511
1512       sw_ifs = mp->sw_if_details;
1513       for (i = 0; i < n_sw_ifs; i++)
1514         {
1515           u8 *sw_if_name = 0;
1516           u32 sw_if_index;
1517           hash_pair_t *p;
1518
1519           sw_if_index = ntohl (sw_ifs->sw_if_index);
1520
1521           /* *INDENT-OFF* */
1522           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1523                              ({
1524                                if ((u32) p->value[0] == sw_if_index)
1525                                  {
1526                                    sw_if_name = (u8 *)(p->key);
1527                                    break;
1528                                  }
1529                              }));
1530           /* *INDENT-ON* */
1531           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1532                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1533                  "sw_if_index not found!");
1534
1535           sw_ifs++;
1536         }
1537     }
1538 }
1539
1540 static void vl_api_bridge_domain_details_t_handler_json
1541   (vl_api_bridge_domain_details_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   vat_json_node_t *node, *array = NULL;
1545   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1546
1547   if (VAT_JSON_ARRAY != vam->json_tree.type)
1548     {
1549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1550       vat_json_init_array (&vam->json_tree);
1551     }
1552   node = vat_json_array_add (&vam->json_tree);
1553
1554   vat_json_init_object (node);
1555   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1556   vat_json_object_add_uint (node, "flood", mp->flood);
1557   vat_json_object_add_uint (node, "forward", mp->forward);
1558   vat_json_object_add_uint (node, "learn", mp->learn);
1559   vat_json_object_add_uint (node, "bvi_sw_if_index",
1560                             ntohl (mp->bvi_sw_if_index));
1561   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1562   array = vat_json_object_add (node, "sw_if");
1563   vat_json_init_array (array);
1564
1565
1566
1567   if (n_sw_ifs)
1568     {
1569       vl_api_bridge_domain_sw_if_t *sw_ifs;
1570       int i;
1571
1572       sw_ifs = mp->sw_if_details;
1573       for (i = 0; i < n_sw_ifs; i++)
1574         {
1575           node = vat_json_array_add (array);
1576           vat_json_init_object (node);
1577           vat_json_object_add_uint (node, "sw_if_index",
1578                                     ntohl (sw_ifs->sw_if_index));
1579           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1580           sw_ifs++;
1581         }
1582     }
1583 }
1584
1585 static void vl_api_control_ping_reply_t_handler
1586   (vl_api_control_ping_reply_t * mp)
1587 {
1588   vat_main_t *vam = &vat_main;
1589   i32 retval = ntohl (mp->retval);
1590   if (vam->async_mode)
1591     {
1592       vam->async_errors += (retval < 0);
1593     }
1594   else
1595     {
1596       vam->retval = retval;
1597       vam->result_ready = 1;
1598     }
1599   if (vam->socket_client_main)
1600     vam->socket_client_main->control_pings_outstanding--;
1601 }
1602
1603 static void vl_api_control_ping_reply_t_handler_json
1604   (vl_api_control_ping_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   i32 retval = ntohl (mp->retval);
1608
1609   if (VAT_JSON_NONE != vam->json_tree.type)
1610     {
1611       vat_json_print (vam->ofp, &vam->json_tree);
1612       vat_json_free (&vam->json_tree);
1613       vam->json_tree.type = VAT_JSON_NONE;
1614     }
1615   else
1616     {
1617       /* just print [] */
1618       vat_json_init_array (&vam->json_tree);
1619       vat_json_print (vam->ofp, &vam->json_tree);
1620       vam->json_tree.type = VAT_JSON_NONE;
1621     }
1622
1623   vam->retval = retval;
1624   vam->result_ready = 1;
1625 }
1626
1627 static void
1628   vl_api_bridge_domain_set_mac_age_reply_t_handler
1629   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   i32 retval = ntohl (mp->retval);
1633   if (vam->async_mode)
1634     {
1635       vam->async_errors += (retval < 0);
1636     }
1637   else
1638     {
1639       vam->retval = retval;
1640       vam->result_ready = 1;
1641     }
1642 }
1643
1644 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1645   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   vat_json_node_t node;
1649
1650   vat_json_init_object (&node);
1651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void
1661 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->result_ready = 1;
1673     }
1674 }
1675
1676 static void vl_api_l2_flags_reply_t_handler_json
1677   (vl_api_l2_flags_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   vat_json_node_t node;
1681
1682   vat_json_init_object (&node);
1683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1685                             ntohl (mp->resulting_feature_bitmap));
1686
1687   vat_json_print (vam->ofp, &node);
1688   vat_json_free (&node);
1689
1690   vam->retval = ntohl (mp->retval);
1691   vam->result_ready = 1;
1692 }
1693
1694 static void vl_api_bridge_flags_reply_t_handler
1695   (vl_api_bridge_flags_reply_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   i32 retval = ntohl (mp->retval);
1699   if (vam->async_mode)
1700     {
1701       vam->async_errors += (retval < 0);
1702     }
1703   else
1704     {
1705       vam->retval = retval;
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_bridge_flags_reply_t_handler_json
1711   (vl_api_bridge_flags_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1719                             ntohl (mp->resulting_feature_bitmap));
1720
1721   vat_json_print (vam->ofp, &node);
1722   vat_json_free (&node);
1723
1724   vam->retval = ntohl (mp->retval);
1725   vam->result_ready = 1;
1726 }
1727
1728 static void
1729 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   i32 retval = ntohl (mp->retval);
1733   if (vam->async_mode)
1734     {
1735       vam->async_errors += (retval < 0);
1736     }
1737   else
1738     {
1739       vam->retval = retval;
1740       vam->sw_if_index = ntohl (mp->sw_if_index);
1741       vam->result_ready = 1;
1742     }
1743
1744 }
1745
1746 static void vl_api_tap_create_v2_reply_t_handler_json
1747   (vl_api_tap_create_v2_reply_t * mp)
1748 {
1749   vat_main_t *vam = &vat_main;
1750   vat_json_node_t node;
1751
1752   vat_json_init_object (&node);
1753   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1754   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1755
1756   vat_json_print (vam->ofp, &node);
1757   vat_json_free (&node);
1758
1759   vam->retval = ntohl (mp->retval);
1760   vam->result_ready = 1;
1761
1762 }
1763
1764 static void
1765 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->result_ready = 1;
1777     }
1778 }
1779
1780 static void vl_api_tap_delete_v2_reply_t_handler_json
1781   (vl_api_tap_delete_v2_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   vat_json_node_t node;
1785
1786   vat_json_init_object (&node);
1787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1788
1789   vat_json_print (vam->ofp, &node);
1790   vat_json_free (&node);
1791
1792   vam->retval = ntohl (mp->retval);
1793   vam->result_ready = 1;
1794 }
1795
1796 static void
1797 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1798                                           mp)
1799 {
1800   vat_main_t *vam = &vat_main;
1801   i32 retval = ntohl (mp->retval);
1802   if (vam->async_mode)
1803     {
1804       vam->async_errors += (retval < 0);
1805     }
1806   else
1807     {
1808       vam->retval = retval;
1809       vam->sw_if_index = ntohl (mp->sw_if_index);
1810       vam->result_ready = 1;
1811     }
1812 }
1813
1814 static void vl_api_virtio_pci_create_reply_t_handler_json
1815   (vl_api_virtio_pci_create_reply_t * mp)
1816 {
1817   vat_main_t *vam = &vat_main;
1818   vat_json_node_t node;
1819
1820   vat_json_init_object (&node);
1821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1822   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1823
1824   vat_json_print (vam->ofp, &node);
1825   vat_json_free (&node);
1826
1827   vam->retval = ntohl (mp->retval);
1828   vam->result_ready = 1;
1829
1830 }
1831
1832 static void
1833 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1834                                           mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   i32 retval = ntohl (mp->retval);
1838   if (vam->async_mode)
1839     {
1840       vam->async_errors += (retval < 0);
1841     }
1842   else
1843     {
1844       vam->retval = retval;
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_virtio_pci_delete_reply_t_handler_json
1850   (vl_api_virtio_pci_delete_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857
1858   vat_json_print (vam->ofp, &node);
1859   vat_json_free (&node);
1860
1861   vam->retval = ntohl (mp->retval);
1862   vam->result_ready = 1;
1863 }
1864
1865 static void
1866 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1867 {
1868   vat_main_t *vam = &vat_main;
1869   i32 retval = ntohl (mp->retval);
1870
1871   if (vam->async_mode)
1872     {
1873       vam->async_errors += (retval < 0);
1874     }
1875   else
1876     {
1877       vam->retval = retval;
1878       vam->sw_if_index = ntohl (mp->sw_if_index);
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_bond_create_reply_t_handler_json
1884   (vl_api_bond_create_reply_t * mp)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   vat_json_node_t node;
1888
1889   vat_json_init_object (&node);
1890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1892
1893   vat_json_print (vam->ofp, &node);
1894   vat_json_free (&node);
1895
1896   vam->retval = ntohl (mp->retval);
1897   vam->result_ready = 1;
1898 }
1899
1900 static void
1901 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1902 {
1903   vat_main_t *vam = &vat_main;
1904   i32 retval = ntohl (mp->retval);
1905
1906   if (vam->async_mode)
1907     {
1908       vam->async_errors += (retval < 0);
1909     }
1910   else
1911     {
1912       vam->retval = retval;
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_bond_delete_reply_t_handler_json
1918   (vl_api_bond_delete_reply_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   vat_json_node_t node;
1922
1923   vat_json_init_object (&node);
1924   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1925
1926   vat_json_print (vam->ofp, &node);
1927   vat_json_free (&node);
1928
1929   vam->retval = ntohl (mp->retval);
1930   vam->result_ready = 1;
1931 }
1932
1933 static void
1934 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1935 {
1936   vat_main_t *vam = &vat_main;
1937   i32 retval = ntohl (mp->retval);
1938
1939   if (vam->async_mode)
1940     {
1941       vam->async_errors += (retval < 0);
1942     }
1943   else
1944     {
1945       vam->retval = retval;
1946       vam->result_ready = 1;
1947     }
1948 }
1949
1950 static void vl_api_bond_enslave_reply_t_handler_json
1951   (vl_api_bond_enslave_reply_t * mp)
1952 {
1953   vat_main_t *vam = &vat_main;
1954   vat_json_node_t node;
1955
1956   vat_json_init_object (&node);
1957   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1958
1959   vat_json_print (vam->ofp, &node);
1960   vat_json_free (&node);
1961
1962   vam->retval = ntohl (mp->retval);
1963   vam->result_ready = 1;
1964 }
1965
1966 static void
1967 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1968                                           mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   i32 retval = ntohl (mp->retval);
1972
1973   if (vam->async_mode)
1974     {
1975       vam->async_errors += (retval < 0);
1976     }
1977   else
1978     {
1979       vam->retval = retval;
1980       vam->result_ready = 1;
1981     }
1982 }
1983
1984 static void vl_api_bond_detach_slave_reply_t_handler_json
1985   (vl_api_bond_detach_slave_reply_t * mp)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   vat_json_node_t node;
1989
1990   vat_json_init_object (&node);
1991   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1992
1993   vat_json_print (vam->ofp, &node);
1994   vat_json_free (&node);
1995
1996   vam->retval = ntohl (mp->retval);
1997   vam->result_ready = 1;
1998 }
1999
2000 static int
2001 api_sw_interface_set_bond_weight (vat_main_t * vam)
2002 {
2003   unformat_input_t *i = vam->input;
2004   vl_api_sw_interface_set_bond_weight_t *mp;
2005   u32 sw_if_index = ~0;
2006   u32 weight = 0;
2007   u8 weight_enter = 0;
2008   int ret;
2009
2010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2011     {
2012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2013         ;
2014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2015         ;
2016       else if (unformat (i, "weight %u", &weight))
2017         weight_enter = 1;
2018       else
2019         break;
2020     }
2021
2022   if (sw_if_index == ~0)
2023     {
2024       errmsg ("missing interface name or sw_if_index");
2025       return -99;
2026     }
2027   if (weight_enter == 0)
2028     {
2029       errmsg ("missing valid weight");
2030       return -99;
2031     }
2032
2033   /* Construct the API message */
2034   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2035   mp->sw_if_index = ntohl (sw_if_index);
2036   mp->weight = ntohl (weight);
2037
2038   S (mp);
2039   W (ret);
2040   return ret;
2041 }
2042
2043 static void vl_api_sw_interface_bond_details_t_handler
2044   (vl_api_sw_interface_bond_details_t * mp)
2045 {
2046   vat_main_t *vam = &vat_main;
2047
2048   print (vam->ofp,
2049          "%-16s %-12d %-12U %-13U %-14u %-14u",
2050          mp->interface_name, ntohl (mp->sw_if_index),
2051          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2052          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2053 }
2054
2055 static void vl_api_sw_interface_bond_details_t_handler_json
2056   (vl_api_sw_interface_bond_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   vat_json_node_t *node = NULL;
2060
2061   if (VAT_JSON_ARRAY != vam->json_tree.type)
2062     {
2063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2064       vat_json_init_array (&vam->json_tree);
2065     }
2066   node = vat_json_array_add (&vam->json_tree);
2067
2068   vat_json_init_object (node);
2069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2070   vat_json_object_add_string_copy (node, "interface_name",
2071                                    mp->interface_name);
2072   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2073   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2074   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2075   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2076 }
2077
2078 static int
2079 api_sw_interface_bond_dump (vat_main_t * vam)
2080 {
2081   vl_api_sw_interface_bond_dump_t *mp;
2082   vl_api_control_ping_t *mp_ping;
2083   int ret;
2084
2085   print (vam->ofp,
2086          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2087          "interface name", "sw_if_index", "mode", "load balance",
2088          "active slaves", "slaves");
2089
2090   /* Get list of bond interfaces */
2091   M (SW_INTERFACE_BOND_DUMP, mp);
2092   S (mp);
2093
2094   /* Use a control ping for synchronization */
2095   MPING (CONTROL_PING, mp_ping);
2096   S (mp_ping);
2097
2098   W (ret);
2099   return ret;
2100 }
2101
2102 static void vl_api_sw_interface_slave_details_t_handler
2103   (vl_api_sw_interface_slave_details_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106
2107   print (vam->ofp,
2108          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2109          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2110          ntohl (mp->weight), mp->is_local_numa);
2111 }
2112
2113 static void vl_api_sw_interface_slave_details_t_handler_json
2114   (vl_api_sw_interface_slave_details_t * mp)
2115 {
2116   vat_main_t *vam = &vat_main;
2117   vat_json_node_t *node = NULL;
2118
2119   if (VAT_JSON_ARRAY != vam->json_tree.type)
2120     {
2121       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2122       vat_json_init_array (&vam->json_tree);
2123     }
2124   node = vat_json_array_add (&vam->json_tree);
2125
2126   vat_json_init_object (node);
2127   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2128   vat_json_object_add_string_copy (node, "interface_name",
2129                                    mp->interface_name);
2130   vat_json_object_add_uint (node, "passive", mp->is_passive);
2131   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2132   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2133   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2134 }
2135
2136 static int
2137 api_sw_interface_slave_dump (vat_main_t * vam)
2138 {
2139   unformat_input_t *i = vam->input;
2140   vl_api_sw_interface_slave_dump_t *mp;
2141   vl_api_control_ping_t *mp_ping;
2142   u32 sw_if_index = ~0;
2143   u8 sw_if_index_set = 0;
2144   int ret;
2145
2146   /* Parse args required to build the message */
2147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2148     {
2149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2150         sw_if_index_set = 1;
2151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2152         sw_if_index_set = 1;
2153       else
2154         break;
2155     }
2156
2157   if (sw_if_index_set == 0)
2158     {
2159       errmsg ("missing vpp interface name. ");
2160       return -99;
2161     }
2162
2163   print (vam->ofp,
2164          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2165          "slave interface name", "sw_if_index", "passive", "long_timeout",
2166          "weight", "local numa");
2167
2168   /* Get list of bond interfaces */
2169   M (SW_INTERFACE_SLAVE_DUMP, mp);
2170   mp->sw_if_index = ntohl (sw_if_index);
2171   S (mp);
2172
2173   /* Use a control ping for synchronization */
2174   MPING (CONTROL_PING, mp_ping);
2175   S (mp_ping);
2176
2177   W (ret);
2178   return ret;
2179 }
2180
2181 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2182   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   i32 retval = ntohl (mp->retval);
2186   if (vam->async_mode)
2187     {
2188       vam->async_errors += (retval < 0);
2189     }
2190   else
2191     {
2192       vam->retval = retval;
2193       vam->sw_if_index = ntohl (mp->sw_if_index);
2194       vam->result_ready = 1;
2195     }
2196   vam->regenerate_interface_table = 1;
2197 }
2198
2199 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2200   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   vat_json_node_t node;
2204
2205   vat_json_init_object (&node);
2206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2207   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2208                             ntohl (mp->sw_if_index));
2209
2210   vat_json_print (vam->ofp, &node);
2211   vat_json_free (&node);
2212
2213   vam->retval = ntohl (mp->retval);
2214   vam->result_ready = 1;
2215 }
2216
2217 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2218   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2219 {
2220   vat_main_t *vam = &vat_main;
2221   i32 retval = ntohl (mp->retval);
2222   if (vam->async_mode)
2223     {
2224       vam->async_errors += (retval < 0);
2225     }
2226   else
2227     {
2228       vam->retval = retval;
2229       vam->sw_if_index = ntohl (mp->sw_if_index);
2230       vam->result_ready = 1;
2231     }
2232 }
2233
2234 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2235   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2236 {
2237   vat_main_t *vam = &vat_main;
2238   vat_json_node_t node;
2239
2240   vat_json_init_object (&node);
2241   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2242   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2243
2244   vat_json_print (vam->ofp, &node);
2245   vat_json_free (&node);
2246
2247   vam->retval = ntohl (mp->retval);
2248   vam->result_ready = 1;
2249 }
2250
2251 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2252   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2253 {
2254   vat_main_t *vam = &vat_main;
2255   i32 retval = ntohl (mp->retval);
2256   if (vam->async_mode)
2257     {
2258       vam->async_errors += (retval < 0);
2259     }
2260   else
2261     {
2262       vam->retval = retval;
2263       vam->result_ready = 1;
2264     }
2265 }
2266
2267 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2268   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2269 {
2270   vat_main_t *vam = &vat_main;
2271   vat_json_node_t node;
2272
2273   vat_json_init_object (&node);
2274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2275   vat_json_object_add_uint (&node, "fwd_entry_index",
2276                             clib_net_to_host_u32 (mp->fwd_entry_index));
2277
2278   vat_json_print (vam->ofp, &node);
2279   vat_json_free (&node);
2280
2281   vam->retval = ntohl (mp->retval);
2282   vam->result_ready = 1;
2283 }
2284
2285 u8 *
2286 format_lisp_transport_protocol (u8 * s, va_list * args)
2287 {
2288   u32 proto = va_arg (*args, u32);
2289
2290   switch (proto)
2291     {
2292     case 1:
2293       return format (s, "udp");
2294     case 2:
2295       return format (s, "api");
2296     default:
2297       return 0;
2298     }
2299   return 0;
2300 }
2301
2302 static void vl_api_one_get_transport_protocol_reply_t_handler
2303   (vl_api_one_get_transport_protocol_reply_t * mp)
2304 {
2305   vat_main_t *vam = &vat_main;
2306   i32 retval = ntohl (mp->retval);
2307   if (vam->async_mode)
2308     {
2309       vam->async_errors += (retval < 0);
2310     }
2311   else
2312     {
2313       u32 proto = mp->protocol;
2314       print (vam->ofp, "Transport protocol: %U",
2315              format_lisp_transport_protocol, proto);
2316       vam->retval = retval;
2317       vam->result_ready = 1;
2318     }
2319 }
2320
2321 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2322   (vl_api_one_get_transport_protocol_reply_t * mp)
2323 {
2324   vat_main_t *vam = &vat_main;
2325   vat_json_node_t node;
2326   u8 *s;
2327
2328   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2329   vec_add1 (s, 0);
2330
2331   vat_json_init_object (&node);
2332   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2333   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2334
2335   vec_free (s);
2336   vat_json_print (vam->ofp, &node);
2337   vat_json_free (&node);
2338
2339   vam->retval = ntohl (mp->retval);
2340   vam->result_ready = 1;
2341 }
2342
2343 static void vl_api_one_add_del_locator_set_reply_t_handler
2344   (vl_api_one_add_del_locator_set_reply_t * mp)
2345 {
2346   vat_main_t *vam = &vat_main;
2347   i32 retval = ntohl (mp->retval);
2348   if (vam->async_mode)
2349     {
2350       vam->async_errors += (retval < 0);
2351     }
2352   else
2353     {
2354       vam->retval = retval;
2355       vam->result_ready = 1;
2356     }
2357 }
2358
2359 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2360   (vl_api_one_add_del_locator_set_reply_t * mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   vat_json_node_t node;
2364
2365   vat_json_init_object (&node);
2366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2367   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2368
2369   vat_json_print (vam->ofp, &node);
2370   vat_json_free (&node);
2371
2372   vam->retval = ntohl (mp->retval);
2373   vam->result_ready = 1;
2374 }
2375
2376 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2377   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380   i32 retval = ntohl (mp->retval);
2381   if (vam->async_mode)
2382     {
2383       vam->async_errors += (retval < 0);
2384     }
2385   else
2386     {
2387       vam->retval = retval;
2388       vam->sw_if_index = ntohl (mp->sw_if_index);
2389       vam->result_ready = 1;
2390     }
2391   vam->regenerate_interface_table = 1;
2392 }
2393
2394 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2395   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2396 {
2397   vat_main_t *vam = &vat_main;
2398   vat_json_node_t node;
2399
2400   vat_json_init_object (&node);
2401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2403
2404   vat_json_print (vam->ofp, &node);
2405   vat_json_free (&node);
2406
2407   vam->retval = ntohl (mp->retval);
2408   vam->result_ready = 1;
2409 }
2410
2411 static void vl_api_vxlan_offload_rx_reply_t_handler
2412   (vl_api_vxlan_offload_rx_reply_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   i32 retval = ntohl (mp->retval);
2416   if (vam->async_mode)
2417     {
2418       vam->async_errors += (retval < 0);
2419     }
2420   else
2421     {
2422       vam->retval = retval;
2423       vam->result_ready = 1;
2424     }
2425 }
2426
2427 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2428   (vl_api_vxlan_offload_rx_reply_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   vat_json_node_t node;
2432
2433   vat_json_init_object (&node);
2434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2435
2436   vat_json_print (vam->ofp, &node);
2437   vat_json_free (&node);
2438
2439   vam->retval = ntohl (mp->retval);
2440   vam->result_ready = 1;
2441 }
2442
2443 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2444   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447   i32 retval = ntohl (mp->retval);
2448   if (vam->async_mode)
2449     {
2450       vam->async_errors += (retval < 0);
2451     }
2452   else
2453     {
2454       vam->retval = retval;
2455       vam->sw_if_index = ntohl (mp->sw_if_index);
2456       vam->result_ready = 1;
2457     }
2458 }
2459
2460 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2461   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464   vat_json_node_t node;
2465
2466   vat_json_init_object (&node);
2467   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2468   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2469
2470   vat_json_print (vam->ofp, &node);
2471   vat_json_free (&node);
2472
2473   vam->retval = ntohl (mp->retval);
2474   vam->result_ready = 1;
2475 }
2476
2477 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2478   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   i32 retval = ntohl (mp->retval);
2482   if (vam->async_mode)
2483     {
2484       vam->async_errors += (retval < 0);
2485     }
2486   else
2487     {
2488       vam->retval = retval;
2489       vam->sw_if_index = ntohl (mp->sw_if_index);
2490       vam->result_ready = 1;
2491     }
2492   vam->regenerate_interface_table = 1;
2493 }
2494
2495 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2496   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t node;
2500
2501   vat_json_init_object (&node);
2502   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2503   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2504
2505   vat_json_print (vam->ofp, &node);
2506   vat_json_free (&node);
2507
2508   vam->retval = ntohl (mp->retval);
2509   vam->result_ready = 1;
2510 }
2511
2512 static void vl_api_gre_tunnel_add_del_reply_t_handler
2513   (vl_api_gre_tunnel_add_del_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   i32 retval = ntohl (mp->retval);
2517   if (vam->async_mode)
2518     {
2519       vam->async_errors += (retval < 0);
2520     }
2521   else
2522     {
2523       vam->retval = retval;
2524       vam->sw_if_index = ntohl (mp->sw_if_index);
2525       vam->result_ready = 1;
2526     }
2527 }
2528
2529 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2530   (vl_api_gre_tunnel_add_del_reply_t * mp)
2531 {
2532   vat_main_t *vam = &vat_main;
2533   vat_json_node_t node;
2534
2535   vat_json_init_object (&node);
2536   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2537   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2538
2539   vat_json_print (vam->ofp, &node);
2540   vat_json_free (&node);
2541
2542   vam->retval = ntohl (mp->retval);
2543   vam->result_ready = 1;
2544 }
2545
2546 static void vl_api_create_vhost_user_if_reply_t_handler
2547   (vl_api_create_vhost_user_if_reply_t * mp)
2548 {
2549   vat_main_t *vam = &vat_main;
2550   i32 retval = ntohl (mp->retval);
2551   if (vam->async_mode)
2552     {
2553       vam->async_errors += (retval < 0);
2554     }
2555   else
2556     {
2557       vam->retval = retval;
2558       vam->sw_if_index = ntohl (mp->sw_if_index);
2559       vam->result_ready = 1;
2560     }
2561   vam->regenerate_interface_table = 1;
2562 }
2563
2564 static void vl_api_create_vhost_user_if_reply_t_handler_json
2565   (vl_api_create_vhost_user_if_reply_t * mp)
2566 {
2567   vat_main_t *vam = &vat_main;
2568   vat_json_node_t node;
2569
2570   vat_json_init_object (&node);
2571   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2572   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2573
2574   vat_json_print (vam->ofp, &node);
2575   vat_json_free (&node);
2576
2577   vam->retval = ntohl (mp->retval);
2578   vam->result_ready = 1;
2579 }
2580
2581 static void vl_api_ip_address_details_t_handler
2582   (vl_api_ip_address_details_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   static ip_address_details_t empty_ip_address_details = { {0} };
2586   ip_address_details_t *address = NULL;
2587   ip_details_t *current_ip_details = NULL;
2588   ip_details_t *details = NULL;
2589
2590   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2591
2592   if (!details || vam->current_sw_if_index >= vec_len (details)
2593       || !details[vam->current_sw_if_index].present)
2594     {
2595       errmsg ("ip address details arrived but not stored");
2596       errmsg ("ip_dump should be called first");
2597       return;
2598     }
2599
2600   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2601
2602 #define addresses (current_ip_details->addr)
2603
2604   vec_validate_init_empty (addresses, vec_len (addresses),
2605                            empty_ip_address_details);
2606
2607   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2608
2609   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2610   address->prefix_length = mp->prefix.len;
2611 #undef addresses
2612 }
2613
2614 static void vl_api_ip_address_details_t_handler_json
2615   (vl_api_ip_address_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618   vat_json_node_t *node = NULL;
2619
2620   if (VAT_JSON_ARRAY != vam->json_tree.type)
2621     {
2622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2623       vat_json_init_array (&vam->json_tree);
2624     }
2625   node = vat_json_array_add (&vam->json_tree);
2626
2627   vat_json_init_object (node);
2628   vat_json_object_add_prefix (node, &mp->prefix);
2629 }
2630
2631 static void
2632 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2633 {
2634   vat_main_t *vam = &vat_main;
2635   static ip_details_t empty_ip_details = { 0 };
2636   ip_details_t *ip = NULL;
2637   u32 sw_if_index = ~0;
2638
2639   sw_if_index = ntohl (mp->sw_if_index);
2640
2641   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2642                            sw_if_index, empty_ip_details);
2643
2644   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2645                          sw_if_index);
2646
2647   ip->present = 1;
2648 }
2649
2650 static void
2651 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2652 {
2653   vat_main_t *vam = &vat_main;
2654
2655   if (VAT_JSON_ARRAY != vam->json_tree.type)
2656     {
2657       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2658       vat_json_init_array (&vam->json_tree);
2659     }
2660   vat_json_array_add_uint (&vam->json_tree,
2661                            clib_net_to_host_u32 (mp->sw_if_index));
2662 }
2663
2664 static void vl_api_get_first_msg_id_reply_t_handler
2665   (vl_api_get_first_msg_id_reply_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   i32 retval = ntohl (mp->retval);
2669
2670   if (vam->async_mode)
2671     {
2672       vam->async_errors += (retval < 0);
2673     }
2674   else
2675     {
2676       vam->retval = retval;
2677       vam->result_ready = 1;
2678     }
2679   if (retval >= 0)
2680     {
2681       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2682     }
2683 }
2684
2685 static void vl_api_get_first_msg_id_reply_t_handler_json
2686   (vl_api_get_first_msg_id_reply_t * mp)
2687 {
2688   vat_main_t *vam = &vat_main;
2689   vat_json_node_t node;
2690
2691   vat_json_init_object (&node);
2692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2693   vat_json_object_add_uint (&node, "first_msg_id",
2694                             (uint) ntohs (mp->first_msg_id));
2695
2696   vat_json_print (vam->ofp, &node);
2697   vat_json_free (&node);
2698
2699   vam->retval = ntohl (mp->retval);
2700   vam->result_ready = 1;
2701 }
2702
2703 static void vl_api_get_node_graph_reply_t_handler
2704   (vl_api_get_node_graph_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   i32 retval = ntohl (mp->retval);
2708   u8 *pvt_copy, *reply;
2709   void *oldheap;
2710   vlib_node_t *node;
2711   int i;
2712
2713   if (vam->async_mode)
2714     {
2715       vam->async_errors += (retval < 0);
2716     }
2717   else
2718     {
2719       vam->retval = retval;
2720       vam->result_ready = 1;
2721     }
2722
2723   /* "Should never happen..." */
2724   if (retval != 0)
2725     return;
2726
2727   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2728   pvt_copy = vec_dup (reply);
2729
2730   /* Toss the shared-memory original... */
2731   oldheap = vl_msg_push_heap ();
2732
2733   vec_free (reply);
2734
2735   vl_msg_pop_heap (oldheap);
2736
2737   if (vam->graph_nodes)
2738     {
2739       hash_free (vam->graph_node_index_by_name);
2740
2741       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2742         {
2743           node = vam->graph_nodes[0][i];
2744           vec_free (node->name);
2745           vec_free (node->next_nodes);
2746           vec_free (node);
2747         }
2748       vec_free (vam->graph_nodes[0]);
2749       vec_free (vam->graph_nodes);
2750     }
2751
2752   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2753   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2754   vec_free (pvt_copy);
2755
2756   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2757     {
2758       node = vam->graph_nodes[0][i];
2759       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2760     }
2761 }
2762
2763 static void vl_api_get_node_graph_reply_t_handler_json
2764   (vl_api_get_node_graph_reply_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   void *oldheap;
2768   vat_json_node_t node;
2769   u8 *reply;
2770
2771   /* $$$$ make this real? */
2772   vat_json_init_object (&node);
2773   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2774   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2775
2776   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2777
2778   /* Toss the shared-memory original... */
2779   oldheap = vl_msg_push_heap ();
2780
2781   vec_free (reply);
2782
2783   vl_msg_pop_heap (oldheap);
2784
2785   vat_json_print (vam->ofp, &node);
2786   vat_json_free (&node);
2787
2788   vam->retval = ntohl (mp->retval);
2789   vam->result_ready = 1;
2790 }
2791
2792 static void
2793 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   u8 *s = 0;
2797
2798   if (mp->local)
2799     {
2800       s = format (s, "%=16d%=16d%=16d",
2801                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2802     }
2803   else
2804     {
2805       s = format (s, "%=16U%=16d%=16d",
2806                   format_ip46_address,
2807                   mp->ip_address, mp->priority, mp->weight);
2808     }
2809
2810   print (vam->ofp, "%v", s);
2811   vec_free (s);
2812 }
2813
2814 static void
2815 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2816 {
2817   vat_main_t *vam = &vat_main;
2818   vat_json_node_t *node = NULL;
2819   struct in6_addr ip6;
2820   struct in_addr ip4;
2821
2822   if (VAT_JSON_ARRAY != vam->json_tree.type)
2823     {
2824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2825       vat_json_init_array (&vam->json_tree);
2826     }
2827   node = vat_json_array_add (&vam->json_tree);
2828   vat_json_init_object (node);
2829
2830   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2831   vat_json_object_add_uint (node, "priority", mp->priority);
2832   vat_json_object_add_uint (node, "weight", mp->weight);
2833
2834   if (mp->local)
2835     vat_json_object_add_uint (node, "sw_if_index",
2836                               clib_net_to_host_u32 (mp->sw_if_index));
2837   else
2838     {
2839       if (mp->ip_address.af)
2840         {
2841           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2842           vat_json_object_add_ip6 (node, "address", ip6);
2843         }
2844       else
2845         {
2846           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2847           vat_json_object_add_ip4 (node, "address", ip4);
2848         }
2849     }
2850 }
2851
2852 static void
2853 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2854                                           mp)
2855 {
2856   vat_main_t *vam = &vat_main;
2857   u8 *ls_name = 0;
2858
2859   ls_name = format (0, "%s", mp->ls_name);
2860
2861   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2862          ls_name);
2863   vec_free (ls_name);
2864 }
2865
2866 static void
2867   vl_api_one_locator_set_details_t_handler_json
2868   (vl_api_one_locator_set_details_t * mp)
2869 {
2870   vat_main_t *vam = &vat_main;
2871   vat_json_node_t *node = 0;
2872   u8 *ls_name = 0;
2873
2874   ls_name = format (0, "%s", mp->ls_name);
2875   vec_add1 (ls_name, 0);
2876
2877   if (VAT_JSON_ARRAY != vam->json_tree.type)
2878     {
2879       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2880       vat_json_init_array (&vam->json_tree);
2881     }
2882   node = vat_json_array_add (&vam->json_tree);
2883
2884   vat_json_init_object (node);
2885   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2886   vat_json_object_add_uint (node, "ls_index",
2887                             clib_net_to_host_u32 (mp->ls_index));
2888   vec_free (ls_name);
2889 }
2890
2891 typedef struct
2892 {
2893   u32 spi;
2894   u8 si;
2895 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2896
2897 uword
2898 unformat_nsh_address (unformat_input_t * input, va_list * args)
2899 {
2900   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2901   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2902 }
2903
2904 u8 *
2905 format_nsh_address_vat (u8 * s, va_list * args)
2906 {
2907   nsh_t *a = va_arg (*args, nsh_t *);
2908   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2909 }
2910
2911 static u8 *
2912 format_lisp_flat_eid (u8 * s, va_list * args)
2913 {
2914   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2915
2916   switch (eid->type)
2917     {
2918     case EID_TYPE_API_PREFIX:
2919       if (eid->address.prefix.address.af)
2920         return format (s, "%U/%d", format_ip6_address,
2921                        eid->address.prefix.address.un.ip6,
2922                        eid->address.prefix.len);
2923       return format (s, "%U/%d", format_ip4_address,
2924                      eid->address.prefix.address.un.ip4,
2925                      eid->address.prefix.len);
2926     case EID_TYPE_API_MAC:
2927       return format (s, "%U", format_ethernet_address, eid->address.mac);
2928     case EID_TYPE_API_NSH:
2929       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2930     }
2931   return 0;
2932 }
2933
2934 static u8 *
2935 format_lisp_eid_vat (u8 * s, va_list * args)
2936 {
2937   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2938   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2939   u8 is_src_dst = (u8) va_arg (*args, int);
2940
2941   if (is_src_dst)
2942     s = format (s, "%U|", format_lisp_flat_eid, seid);
2943
2944   s = format (s, "%U", format_lisp_flat_eid, deid);
2945
2946   return s;
2947 }
2948
2949 static void
2950 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2951 {
2952   vat_main_t *vam = &vat_main;
2953   u8 *s = 0, *eid = 0;
2954
2955   if (~0 == mp->locator_set_index)
2956     s = format (0, "action: %d", mp->action);
2957   else
2958     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2959
2960   eid = format (0, "%U", format_lisp_eid_vat,
2961                 mp->deid, mp->seid, mp->is_src_dst);
2962   vec_add1 (eid, 0);
2963
2964   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2965          clib_net_to_host_u32 (mp->vni),
2966          eid,
2967          mp->is_local ? "local" : "remote",
2968          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2969          clib_net_to_host_u16 (mp->key.id), mp->key.key);
2970
2971   vec_free (s);
2972   vec_free (eid);
2973 }
2974
2975 static void
2976 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2977                                              * mp)
2978 {
2979   vat_main_t *vam = &vat_main;
2980   vat_json_node_t *node = 0;
2981   u8 *eid = 0;
2982
2983   if (VAT_JSON_ARRAY != vam->json_tree.type)
2984     {
2985       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2986       vat_json_init_array (&vam->json_tree);
2987     }
2988   node = vat_json_array_add (&vam->json_tree);
2989
2990   vat_json_init_object (node);
2991   if (~0 == mp->locator_set_index)
2992     vat_json_object_add_uint (node, "action", mp->action);
2993   else
2994     vat_json_object_add_uint (node, "locator_set_index",
2995                               clib_net_to_host_u32 (mp->locator_set_index));
2996
2997   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2998   if (mp->deid.type == 3)
2999     {
3000       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3001       vat_json_init_object (nsh_json);
3002       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3003       vat_json_object_add_uint (nsh_json, "spi",
3004                                 clib_net_to_host_u32 (nsh->spi));
3005       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3006     }
3007   else
3008     {
3009       eid = format (0, "%U", format_lisp_eid_vat,
3010                     mp->deid, mp->seid, mp->is_src_dst);
3011       vec_add1 (eid, 0);
3012       vat_json_object_add_string_copy (node, "eid", eid);
3013       vec_free (eid);
3014     }
3015   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3016   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3017   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3018
3019   if (mp->key.id)
3020     {
3021       vat_json_object_add_uint (node, "key_id",
3022                                 clib_net_to_host_u16 (mp->key.id));
3023       vat_json_object_add_string_copy (node, "key", mp->key.key);
3024     }
3025 }
3026
3027 static void
3028 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3029 {
3030   vat_main_t *vam = &vat_main;
3031   u8 *seid = 0, *deid = 0;
3032   ip46_address_t lloc, rloc;
3033
3034   deid = format (0, "%U", format_lisp_eid_vat, mp->deid, 0);
3035
3036   seid = format (0, "%U", format_lisp_eid_vat, mp->seid, 0);
3037
3038   vec_add1 (deid, 0);
3039   vec_add1 (seid, 0);
3040
3041   if (mp->lloc.af)
3042     {
3043       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3044       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3045     }
3046   else
3047     {
3048       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3049       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3050     }
3051
3052
3053   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3054          clib_net_to_host_u32 (mp->vni),
3055          seid, deid,
3056          format_ip46_address, lloc,
3057          format_ip46_address, rloc,
3058          clib_net_to_host_u32 (mp->pkt_count),
3059          clib_net_to_host_u32 (mp->bytes));
3060
3061   vec_free (deid);
3062   vec_free (seid);
3063 }
3064
3065 static void
3066 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3067 {
3068   struct in6_addr ip6;
3069   struct in_addr ip4;
3070   vat_main_t *vam = &vat_main;
3071   vat_json_node_t *node = 0;
3072   u8 *deid = 0, *seid = 0;
3073
3074   if (VAT_JSON_ARRAY != vam->json_tree.type)
3075     {
3076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3077       vat_json_init_array (&vam->json_tree);
3078     }
3079   node = vat_json_array_add (&vam->json_tree);
3080
3081   vat_json_init_object (node);
3082   deid = format (0, "%U", format_lisp_eid_vat, mp->deid, 0);
3083
3084   seid = format (0, "%U", format_lisp_eid_vat, mp->seid, 0);
3085
3086   vec_add1 (deid, 0);
3087   vec_add1 (seid, 0);
3088
3089   vat_json_object_add_string_copy (node, "seid", seid);
3090   vat_json_object_add_string_copy (node, "deid", deid);
3091   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3092
3093   if (mp->lloc.af)
3094     {
3095       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3096       vat_json_object_add_ip6 (node, "lloc", ip6);
3097       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3098       vat_json_object_add_ip6 (node, "rloc", ip6);
3099
3100     }
3101   else
3102     {
3103       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3104       vat_json_object_add_ip4 (node, "lloc", ip4);
3105       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3106       vat_json_object_add_ip4 (node, "rloc", ip4);
3107     }
3108   vat_json_object_add_uint (node, "pkt_count",
3109                             clib_net_to_host_u32 (mp->pkt_count));
3110   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3111
3112   vec_free (deid);
3113   vec_free (seid);
3114 }
3115
3116 static void
3117   vl_api_one_eid_table_map_details_t_handler
3118   (vl_api_one_eid_table_map_details_t * mp)
3119 {
3120   vat_main_t *vam = &vat_main;
3121
3122   u8 *line = format (0, "%=10d%=10d",
3123                      clib_net_to_host_u32 (mp->vni),
3124                      clib_net_to_host_u32 (mp->dp_table));
3125   print (vam->ofp, "%v", line);
3126   vec_free (line);
3127 }
3128
3129 static void
3130   vl_api_one_eid_table_map_details_t_handler_json
3131   (vl_api_one_eid_table_map_details_t * mp)
3132 {
3133   vat_main_t *vam = &vat_main;
3134   vat_json_node_t *node = NULL;
3135
3136   if (VAT_JSON_ARRAY != vam->json_tree.type)
3137     {
3138       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3139       vat_json_init_array (&vam->json_tree);
3140     }
3141   node = vat_json_array_add (&vam->json_tree);
3142   vat_json_init_object (node);
3143   vat_json_object_add_uint (node, "dp_table",
3144                             clib_net_to_host_u32 (mp->dp_table));
3145   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3146 }
3147
3148 static void
3149   vl_api_one_eid_table_vni_details_t_handler
3150   (vl_api_one_eid_table_vni_details_t * mp)
3151 {
3152   vat_main_t *vam = &vat_main;
3153
3154   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3155   print (vam->ofp, "%v", line);
3156   vec_free (line);
3157 }
3158
3159 static void
3160   vl_api_one_eid_table_vni_details_t_handler_json
3161   (vl_api_one_eid_table_vni_details_t * mp)
3162 {
3163   vat_main_t *vam = &vat_main;
3164   vat_json_node_t *node = NULL;
3165
3166   if (VAT_JSON_ARRAY != vam->json_tree.type)
3167     {
3168       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3169       vat_json_init_array (&vam->json_tree);
3170     }
3171   node = vat_json_array_add (&vam->json_tree);
3172   vat_json_init_object (node);
3173   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3174 }
3175
3176 static void
3177   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3178   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   int retval = clib_net_to_host_u32 (mp->retval);
3182
3183   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3184   print (vam->ofp, "fallback threshold value: %d", mp->value);
3185
3186   vam->retval = retval;
3187   vam->result_ready = 1;
3188 }
3189
3190 static void
3191   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3192   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3193 {
3194   vat_main_t *vam = &vat_main;
3195   vat_json_node_t _node, *node = &_node;
3196   int retval = clib_net_to_host_u32 (mp->retval);
3197
3198   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3199   vat_json_init_object (node);
3200   vat_json_object_add_uint (node, "value", mp->value);
3201
3202   vat_json_print (vam->ofp, node);
3203   vat_json_free (node);
3204
3205   vam->retval = retval;
3206   vam->result_ready = 1;
3207 }
3208
3209 static void
3210   vl_api_show_one_map_register_state_reply_t_handler
3211   (vl_api_show_one_map_register_state_reply_t * mp)
3212 {
3213   vat_main_t *vam = &vat_main;
3214   int retval = clib_net_to_host_u32 (mp->retval);
3215
3216   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3217
3218   vam->retval = retval;
3219   vam->result_ready = 1;
3220 }
3221
3222 static void
3223   vl_api_show_one_map_register_state_reply_t_handler_json
3224   (vl_api_show_one_map_register_state_reply_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227   vat_json_node_t _node, *node = &_node;
3228   int retval = clib_net_to_host_u32 (mp->retval);
3229
3230   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3231
3232   vat_json_init_object (node);
3233   vat_json_object_add_string_copy (node, "state", s);
3234
3235   vat_json_print (vam->ofp, node);
3236   vat_json_free (node);
3237
3238   vam->retval = retval;
3239   vam->result_ready = 1;
3240   vec_free (s);
3241 }
3242
3243 static void
3244   vl_api_show_one_rloc_probe_state_reply_t_handler
3245   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3246 {
3247   vat_main_t *vam = &vat_main;
3248   int retval = clib_net_to_host_u32 (mp->retval);
3249
3250   if (retval)
3251     goto end;
3252
3253   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3254 end:
3255   vam->retval = retval;
3256   vam->result_ready = 1;
3257 }
3258
3259 static void
3260   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3261   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   vat_json_node_t _node, *node = &_node;
3265   int retval = clib_net_to_host_u32 (mp->retval);
3266
3267   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3268   vat_json_init_object (node);
3269   vat_json_object_add_string_copy (node, "state", s);
3270
3271   vat_json_print (vam->ofp, node);
3272   vat_json_free (node);
3273
3274   vam->retval = retval;
3275   vam->result_ready = 1;
3276   vec_free (s);
3277 }
3278
3279 static void
3280   vl_api_show_one_stats_enable_disable_reply_t_handler
3281   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3282 {
3283   vat_main_t *vam = &vat_main;
3284   int retval = clib_net_to_host_u32 (mp->retval);
3285
3286   if (retval)
3287     goto end;
3288
3289   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3290 end:
3291   vam->retval = retval;
3292   vam->result_ready = 1;
3293 }
3294
3295 static void
3296   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3297   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300   vat_json_node_t _node, *node = &_node;
3301   int retval = clib_net_to_host_u32 (mp->retval);
3302
3303   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3304   vat_json_init_object (node);
3305   vat_json_object_add_string_copy (node, "state", s);
3306
3307   vat_json_print (vam->ofp, node);
3308   vat_json_free (node);
3309
3310   vam->retval = retval;
3311   vam->result_ready = 1;
3312   vec_free (s);
3313 }
3314
3315 static void
3316 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3317 {
3318   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3319   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3320   e->vni = clib_net_to_host_u32 (e->vni);
3321 }
3322
3323 static void
3324   gpe_fwd_entries_get_reply_t_net_to_host
3325   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3326 {
3327   u32 i;
3328
3329   mp->count = clib_net_to_host_u32 (mp->count);
3330   for (i = 0; i < mp->count; i++)
3331     {
3332       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3333     }
3334 }
3335
3336 static u8 *
3337 format_gpe_encap_mode (u8 * s, va_list * args)
3338 {
3339   u32 mode = va_arg (*args, u32);
3340
3341   switch (mode)
3342     {
3343     case 0:
3344       return format (s, "lisp");
3345     case 1:
3346       return format (s, "vxlan");
3347     }
3348   return 0;
3349 }
3350
3351 static void
3352   vl_api_gpe_get_encap_mode_reply_t_handler
3353   (vl_api_gpe_get_encap_mode_reply_t * mp)
3354 {
3355   vat_main_t *vam = &vat_main;
3356
3357   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3358   vam->retval = ntohl (mp->retval);
3359   vam->result_ready = 1;
3360 }
3361
3362 static void
3363   vl_api_gpe_get_encap_mode_reply_t_handler_json
3364   (vl_api_gpe_get_encap_mode_reply_t * mp)
3365 {
3366   vat_main_t *vam = &vat_main;
3367   vat_json_node_t node;
3368
3369   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3370   vec_add1 (encap_mode, 0);
3371
3372   vat_json_init_object (&node);
3373   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3374
3375   vec_free (encap_mode);
3376   vat_json_print (vam->ofp, &node);
3377   vat_json_free (&node);
3378
3379   vam->retval = ntohl (mp->retval);
3380   vam->result_ready = 1;
3381 }
3382
3383 static void
3384   vl_api_gpe_fwd_entry_path_details_t_handler
3385   (vl_api_gpe_fwd_entry_path_details_t * mp)
3386 {
3387   vat_main_t *vam = &vat_main;
3388   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3389
3390   if (mp->lcl_loc.addr.af)
3391     format_ip_address_fcn = format_ip6_address;
3392   else
3393     format_ip_address_fcn = format_ip4_address;
3394
3395   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3396          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3397          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3398 }
3399
3400 static void
3401 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3402 {
3403   struct in6_addr ip6;
3404   struct in_addr ip4;
3405
3406   if (loc->addr.af)
3407     {
3408       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3409       vat_json_object_add_ip6 (n, "address", ip6);
3410     }
3411   else
3412     {
3413       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3414       vat_json_object_add_ip4 (n, "address", ip4);
3415     }
3416   vat_json_object_add_uint (n, "weight", loc->weight);
3417 }
3418
3419 static void
3420   vl_api_gpe_fwd_entry_path_details_t_handler_json
3421   (vl_api_gpe_fwd_entry_path_details_t * mp)
3422 {
3423   vat_main_t *vam = &vat_main;
3424   vat_json_node_t *node = NULL;
3425   vat_json_node_t *loc_node;
3426
3427   if (VAT_JSON_ARRAY != vam->json_tree.type)
3428     {
3429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3430       vat_json_init_array (&vam->json_tree);
3431     }
3432   node = vat_json_array_add (&vam->json_tree);
3433   vat_json_init_object (node);
3434
3435   loc_node = vat_json_object_add (node, "local_locator");
3436   vat_json_init_object (loc_node);
3437   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3438
3439   loc_node = vat_json_object_add (node, "remote_locator");
3440   vat_json_init_object (loc_node);
3441   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3442 }
3443
3444 static void
3445   vl_api_gpe_fwd_entries_get_reply_t_handler
3446   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3447 {
3448   vat_main_t *vam = &vat_main;
3449   u32 i;
3450   int retval = clib_net_to_host_u32 (mp->retval);
3451   vl_api_gpe_fwd_entry_t *e;
3452
3453   if (retval)
3454     goto end;
3455
3456   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3457
3458   for (i = 0; i < mp->count; i++)
3459     {
3460       e = &mp->entries[i];
3461       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3462              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3463     }
3464
3465 end:
3466   vam->retval = retval;
3467   vam->result_ready = 1;
3468 }
3469
3470 static void
3471   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3472   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3473 {
3474   u8 *s = 0;
3475   vat_main_t *vam = &vat_main;
3476   vat_json_node_t *e = 0, root;
3477   u32 i;
3478   int retval = clib_net_to_host_u32 (mp->retval);
3479   vl_api_gpe_fwd_entry_t *fwd;
3480
3481   if (retval)
3482     goto end;
3483
3484   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3485   vat_json_init_array (&root);
3486
3487   for (i = 0; i < mp->count; i++)
3488     {
3489       e = vat_json_array_add (&root);
3490       fwd = &mp->entries[i];
3491
3492       vat_json_init_object (e);
3493       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3494       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3495       vat_json_object_add_int (e, "vni", fwd->vni);
3496       vat_json_object_add_int (e, "action", fwd->action);
3497
3498       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3499       vec_add1 (s, 0);
3500       vat_json_object_add_string_copy (e, "leid", s);
3501       vec_free (s);
3502
3503       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3504       vec_add1 (s, 0);
3505       vat_json_object_add_string_copy (e, "reid", s);
3506       vec_free (s);
3507     }
3508
3509   vat_json_print (vam->ofp, &root);
3510   vat_json_free (&root);
3511
3512 end:
3513   vam->retval = retval;
3514   vam->result_ready = 1;
3515 }
3516
3517 static void
3518   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3519   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3520 {
3521   vat_main_t *vam = &vat_main;
3522   u32 i, n;
3523   int retval = clib_net_to_host_u32 (mp->retval);
3524   vl_api_gpe_native_fwd_rpath_t *r;
3525
3526   if (retval)
3527     goto end;
3528
3529   n = clib_net_to_host_u32 (mp->count);
3530
3531   for (i = 0; i < n; i++)
3532     {
3533       r = &mp->entries[i];
3534       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3535              clib_net_to_host_u32 (r->fib_index),
3536              clib_net_to_host_u32 (r->nh_sw_if_index),
3537              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3538              r->nh_addr.un);
3539     }
3540
3541 end:
3542   vam->retval = retval;
3543   vam->result_ready = 1;
3544 }
3545
3546 static void
3547   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3548   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3549 {
3550   vat_main_t *vam = &vat_main;
3551   vat_json_node_t root, *e;
3552   u32 i, n;
3553   int retval = clib_net_to_host_u32 (mp->retval);
3554   vl_api_gpe_native_fwd_rpath_t *r;
3555   u8 *s;
3556
3557   if (retval)
3558     goto end;
3559
3560   n = clib_net_to_host_u32 (mp->count);
3561   vat_json_init_array (&root);
3562
3563   for (i = 0; i < n; i++)
3564     {
3565       e = vat_json_array_add (&root);
3566       vat_json_init_object (e);
3567       r = &mp->entries[i];
3568       s =
3569         format (0, "%U",
3570                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3571                 r->nh_addr.un);
3572       vec_add1 (s, 0);
3573       vat_json_object_add_string_copy (e, "ip4", s);
3574       vec_free (s);
3575
3576       vat_json_object_add_uint (e, "fib_index",
3577                                 clib_net_to_host_u32 (r->fib_index));
3578       vat_json_object_add_uint (e, "nh_sw_if_index",
3579                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3580     }
3581
3582   vat_json_print (vam->ofp, &root);
3583   vat_json_free (&root);
3584
3585 end:
3586   vam->retval = retval;
3587   vam->result_ready = 1;
3588 }
3589
3590 static void
3591   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3592   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3593 {
3594   vat_main_t *vam = &vat_main;
3595   u32 i, n;
3596   int retval = clib_net_to_host_u32 (mp->retval);
3597
3598   if (retval)
3599     goto end;
3600
3601   n = clib_net_to_host_u32 (mp->count);
3602
3603   for (i = 0; i < n; i++)
3604     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3605
3606 end:
3607   vam->retval = retval;
3608   vam->result_ready = 1;
3609 }
3610
3611 static void
3612   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3613   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3614 {
3615   vat_main_t *vam = &vat_main;
3616   vat_json_node_t root;
3617   u32 i, n;
3618   int retval = clib_net_to_host_u32 (mp->retval);
3619
3620   if (retval)
3621     goto end;
3622
3623   n = clib_net_to_host_u32 (mp->count);
3624   vat_json_init_array (&root);
3625
3626   for (i = 0; i < n; i++)
3627     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3628
3629   vat_json_print (vam->ofp, &root);
3630   vat_json_free (&root);
3631
3632 end:
3633   vam->retval = retval;
3634   vam->result_ready = 1;
3635 }
3636
3637 static void
3638   vl_api_one_ndp_entries_get_reply_t_handler
3639   (vl_api_one_ndp_entries_get_reply_t * mp)
3640 {
3641   vat_main_t *vam = &vat_main;
3642   u32 i, n;
3643   int retval = clib_net_to_host_u32 (mp->retval);
3644
3645   if (retval)
3646     goto end;
3647
3648   n = clib_net_to_host_u32 (mp->count);
3649
3650   for (i = 0; i < n; i++)
3651     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3652            format_ethernet_address, mp->entries[i].mac);
3653
3654 end:
3655   vam->retval = retval;
3656   vam->result_ready = 1;
3657 }
3658
3659 static void
3660   vl_api_one_ndp_entries_get_reply_t_handler_json
3661   (vl_api_one_ndp_entries_get_reply_t * mp)
3662 {
3663   u8 *s = 0;
3664   vat_main_t *vam = &vat_main;
3665   vat_json_node_t *e = 0, root;
3666   u32 i, n;
3667   int retval = clib_net_to_host_u32 (mp->retval);
3668   vl_api_one_ndp_entry_t *arp_entry;
3669
3670   if (retval)
3671     goto end;
3672
3673   n = clib_net_to_host_u32 (mp->count);
3674   vat_json_init_array (&root);
3675
3676   for (i = 0; i < n; i++)
3677     {
3678       e = vat_json_array_add (&root);
3679       arp_entry = &mp->entries[i];
3680
3681       vat_json_init_object (e);
3682       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3683       vec_add1 (s, 0);
3684
3685       vat_json_object_add_string_copy (e, "mac", s);
3686       vec_free (s);
3687
3688       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3689       vec_add1 (s, 0);
3690       vat_json_object_add_string_copy (e, "ip6", s);
3691       vec_free (s);
3692     }
3693
3694   vat_json_print (vam->ofp, &root);
3695   vat_json_free (&root);
3696
3697 end:
3698   vam->retval = retval;
3699   vam->result_ready = 1;
3700 }
3701
3702 static void
3703   vl_api_one_l2_arp_entries_get_reply_t_handler
3704   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3705 {
3706   vat_main_t *vam = &vat_main;
3707   u32 i, n;
3708   int retval = clib_net_to_host_u32 (mp->retval);
3709
3710   if (retval)
3711     goto end;
3712
3713   n = clib_net_to_host_u32 (mp->count);
3714
3715   for (i = 0; i < n; i++)
3716     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3717            format_ethernet_address, mp->entries[i].mac);
3718
3719 end:
3720   vam->retval = retval;
3721   vam->result_ready = 1;
3722 }
3723
3724 static void
3725   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3726   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3727 {
3728   u8 *s = 0;
3729   vat_main_t *vam = &vat_main;
3730   vat_json_node_t *e = 0, root;
3731   u32 i, n;
3732   int retval = clib_net_to_host_u32 (mp->retval);
3733   vl_api_one_l2_arp_entry_t *arp_entry;
3734
3735   if (retval)
3736     goto end;
3737
3738   n = clib_net_to_host_u32 (mp->count);
3739   vat_json_init_array (&root);
3740
3741   for (i = 0; i < n; i++)
3742     {
3743       e = vat_json_array_add (&root);
3744       arp_entry = &mp->entries[i];
3745
3746       vat_json_init_object (e);
3747       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3748       vec_add1 (s, 0);
3749
3750       vat_json_object_add_string_copy (e, "mac", s);
3751       vec_free (s);
3752
3753       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3754       vec_add1 (s, 0);
3755       vat_json_object_add_string_copy (e, "ip4", s);
3756       vec_free (s);
3757     }
3758
3759   vat_json_print (vam->ofp, &root);
3760   vat_json_free (&root);
3761
3762 end:
3763   vam->retval = retval;
3764   vam->result_ready = 1;
3765 }
3766
3767 static void
3768 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3769 {
3770   vat_main_t *vam = &vat_main;
3771   u32 i, n;
3772   int retval = clib_net_to_host_u32 (mp->retval);
3773
3774   if (retval)
3775     goto end;
3776
3777   n = clib_net_to_host_u32 (mp->count);
3778
3779   for (i = 0; i < n; i++)
3780     {
3781       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3782     }
3783
3784 end:
3785   vam->retval = retval;
3786   vam->result_ready = 1;
3787 }
3788
3789 static void
3790   vl_api_one_ndp_bd_get_reply_t_handler_json
3791   (vl_api_one_ndp_bd_get_reply_t * mp)
3792 {
3793   vat_main_t *vam = &vat_main;
3794   vat_json_node_t root;
3795   u32 i, n;
3796   int retval = clib_net_to_host_u32 (mp->retval);
3797
3798   if (retval)
3799     goto end;
3800
3801   n = clib_net_to_host_u32 (mp->count);
3802   vat_json_init_array (&root);
3803
3804   for (i = 0; i < n; i++)
3805     {
3806       vat_json_array_add_uint (&root,
3807                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3808     }
3809
3810   vat_json_print (vam->ofp, &root);
3811   vat_json_free (&root);
3812
3813 end:
3814   vam->retval = retval;
3815   vam->result_ready = 1;
3816 }
3817
3818 static void
3819   vl_api_one_l2_arp_bd_get_reply_t_handler
3820   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3821 {
3822   vat_main_t *vam = &vat_main;
3823   u32 i, n;
3824   int retval = clib_net_to_host_u32 (mp->retval);
3825
3826   if (retval)
3827     goto end;
3828
3829   n = clib_net_to_host_u32 (mp->count);
3830
3831   for (i = 0; i < n; i++)
3832     {
3833       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3834     }
3835
3836 end:
3837   vam->retval = retval;
3838   vam->result_ready = 1;
3839 }
3840
3841 static void
3842   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3843   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3844 {
3845   vat_main_t *vam = &vat_main;
3846   vat_json_node_t root;
3847   u32 i, n;
3848   int retval = clib_net_to_host_u32 (mp->retval);
3849
3850   if (retval)
3851     goto end;
3852
3853   n = clib_net_to_host_u32 (mp->count);
3854   vat_json_init_array (&root);
3855
3856   for (i = 0; i < n; i++)
3857     {
3858       vat_json_array_add_uint (&root,
3859                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3860     }
3861
3862   vat_json_print (vam->ofp, &root);
3863   vat_json_free (&root);
3864
3865 end:
3866   vam->retval = retval;
3867   vam->result_ready = 1;
3868 }
3869
3870 static void
3871   vl_api_one_adjacencies_get_reply_t_handler
3872   (vl_api_one_adjacencies_get_reply_t * mp)
3873 {
3874   vat_main_t *vam = &vat_main;
3875   u32 i, n;
3876   int retval = clib_net_to_host_u32 (mp->retval);
3877   vl_api_one_adjacency_t *a;
3878
3879   if (retval)
3880     goto end;
3881
3882   n = clib_net_to_host_u32 (mp->count);
3883
3884   for (i = 0; i < n; i++)
3885     {
3886       a = &mp->adjacencies[i];
3887       print (vam->ofp, "%U %40U",
3888              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3889     }
3890
3891 end:
3892   vam->retval = retval;
3893   vam->result_ready = 1;
3894 }
3895
3896 static void
3897   vl_api_one_adjacencies_get_reply_t_handler_json
3898   (vl_api_one_adjacencies_get_reply_t * mp)
3899 {
3900   u8 *s = 0;
3901   vat_main_t *vam = &vat_main;
3902   vat_json_node_t *e = 0, root;
3903   u32 i, n;
3904   int retval = clib_net_to_host_u32 (mp->retval);
3905   vl_api_one_adjacency_t *a;
3906
3907   if (retval)
3908     goto end;
3909
3910   n = clib_net_to_host_u32 (mp->count);
3911   vat_json_init_array (&root);
3912
3913   for (i = 0; i < n; i++)
3914     {
3915       e = vat_json_array_add (&root);
3916       a = &mp->adjacencies[i];
3917
3918       vat_json_init_object (e);
3919       s = format (0, "%U", format_lisp_flat_eid, a->leid);
3920       vec_add1 (s, 0);
3921       vat_json_object_add_string_copy (e, "leid", s);
3922       vec_free (s);
3923
3924       s = format (0, "%U", format_lisp_flat_eid, a->reid);
3925       vec_add1 (s, 0);
3926       vat_json_object_add_string_copy (e, "reid", s);
3927       vec_free (s);
3928     }
3929
3930   vat_json_print (vam->ofp, &root);
3931   vat_json_free (&root);
3932
3933 end:
3934   vam->retval = retval;
3935   vam->result_ready = 1;
3936 }
3937
3938 static void
3939 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942
3943   print (vam->ofp, "%=20U",
3944          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3945          mp->ip_address.un);
3946 }
3947
3948 static void
3949   vl_api_one_map_server_details_t_handler_json
3950   (vl_api_one_map_server_details_t * mp)
3951 {
3952   vat_main_t *vam = &vat_main;
3953   vat_json_node_t *node = NULL;
3954   struct in6_addr ip6;
3955   struct in_addr ip4;
3956
3957   if (VAT_JSON_ARRAY != vam->json_tree.type)
3958     {
3959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3960       vat_json_init_array (&vam->json_tree);
3961     }
3962   node = vat_json_array_add (&vam->json_tree);
3963
3964   vat_json_init_object (node);
3965   if (mp->ip_address.af)
3966     {
3967       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
3968       vat_json_object_add_ip6 (node, "map-server", ip6);
3969     }
3970   else
3971     {
3972       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
3973       vat_json_object_add_ip4 (node, "map-server", ip4);
3974     }
3975 }
3976
3977 static void
3978 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3979                                            * mp)
3980 {
3981   vat_main_t *vam = &vat_main;
3982
3983   print (vam->ofp, "%=20U",
3984          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3985          mp->ip_address.un);
3986 }
3987
3988 static void
3989   vl_api_one_map_resolver_details_t_handler_json
3990   (vl_api_one_map_resolver_details_t * mp)
3991 {
3992   vat_main_t *vam = &vat_main;
3993   vat_json_node_t *node = NULL;
3994   struct in6_addr ip6;
3995   struct in_addr ip4;
3996
3997   if (VAT_JSON_ARRAY != vam->json_tree.type)
3998     {
3999       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4000       vat_json_init_array (&vam->json_tree);
4001     }
4002   node = vat_json_array_add (&vam->json_tree);
4003
4004   vat_json_init_object (node);
4005   if (mp->ip_address.af)
4006     {
4007       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4008       vat_json_object_add_ip6 (node, "map resolver", ip6);
4009     }
4010   else
4011     {
4012       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4013       vat_json_object_add_ip4 (node, "map resolver", ip4);
4014     }
4015 }
4016
4017 static void
4018 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4019 {
4020   vat_main_t *vam = &vat_main;
4021   i32 retval = ntohl (mp->retval);
4022
4023   if (0 <= retval)
4024     {
4025       print (vam->ofp, "feature: %s\ngpe: %s",
4026              mp->feature_status ? "enabled" : "disabled",
4027              mp->gpe_status ? "enabled" : "disabled");
4028     }
4029
4030   vam->retval = retval;
4031   vam->result_ready = 1;
4032 }
4033
4034 static void
4035   vl_api_show_one_status_reply_t_handler_json
4036   (vl_api_show_one_status_reply_t * mp)
4037 {
4038   vat_main_t *vam = &vat_main;
4039   vat_json_node_t node;
4040   u8 *gpe_status = NULL;
4041   u8 *feature_status = NULL;
4042
4043   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4044   feature_status = format (0, "%s",
4045                            mp->feature_status ? "enabled" : "disabled");
4046   vec_add1 (gpe_status, 0);
4047   vec_add1 (feature_status, 0);
4048
4049   vat_json_init_object (&node);
4050   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4051   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4052
4053   vec_free (gpe_status);
4054   vec_free (feature_status);
4055
4056   vat_json_print (vam->ofp, &node);
4057   vat_json_free (&node);
4058
4059   vam->retval = ntohl (mp->retval);
4060   vam->result_ready = 1;
4061 }
4062
4063 static void
4064   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4065   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4066 {
4067   vat_main_t *vam = &vat_main;
4068   i32 retval = ntohl (mp->retval);
4069
4070   if (retval >= 0)
4071     {
4072       print (vam->ofp, "%=20s", mp->locator_set_name);
4073     }
4074
4075   vam->retval = retval;
4076   vam->result_ready = 1;
4077 }
4078
4079 static void
4080   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4081   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4082 {
4083   vat_main_t *vam = &vat_main;
4084   vat_json_node_t *node = NULL;
4085
4086   if (VAT_JSON_ARRAY != vam->json_tree.type)
4087     {
4088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4089       vat_json_init_array (&vam->json_tree);
4090     }
4091   node = vat_json_array_add (&vam->json_tree);
4092
4093   vat_json_init_object (node);
4094   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4095
4096   vat_json_print (vam->ofp, node);
4097   vat_json_free (node);
4098
4099   vam->retval = ntohl (mp->retval);
4100   vam->result_ready = 1;
4101 }
4102
4103 static u8 *
4104 format_lisp_map_request_mode (u8 * s, va_list * args)
4105 {
4106   u32 mode = va_arg (*args, u32);
4107
4108   switch (mode)
4109     {
4110     case 0:
4111       return format (0, "dst-only");
4112     case 1:
4113       return format (0, "src-dst");
4114     }
4115   return 0;
4116 }
4117
4118 static void
4119   vl_api_show_one_map_request_mode_reply_t_handler
4120   (vl_api_show_one_map_request_mode_reply_t * mp)
4121 {
4122   vat_main_t *vam = &vat_main;
4123   i32 retval = ntohl (mp->retval);
4124
4125   if (0 <= retval)
4126     {
4127       u32 mode = mp->mode;
4128       print (vam->ofp, "map_request_mode: %U",
4129              format_lisp_map_request_mode, mode);
4130     }
4131
4132   vam->retval = retval;
4133   vam->result_ready = 1;
4134 }
4135
4136 static void
4137   vl_api_show_one_map_request_mode_reply_t_handler_json
4138   (vl_api_show_one_map_request_mode_reply_t * mp)
4139 {
4140   vat_main_t *vam = &vat_main;
4141   vat_json_node_t node;
4142   u8 *s = 0;
4143   u32 mode;
4144
4145   mode = mp->mode;
4146   s = format (0, "%U", format_lisp_map_request_mode, mode);
4147   vec_add1 (s, 0);
4148
4149   vat_json_init_object (&node);
4150   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4151   vat_json_print (vam->ofp, &node);
4152   vat_json_free (&node);
4153
4154   vec_free (s);
4155   vam->retval = ntohl (mp->retval);
4156   vam->result_ready = 1;
4157 }
4158
4159 static void
4160   vl_api_one_show_xtr_mode_reply_t_handler
4161   (vl_api_one_show_xtr_mode_reply_t * mp)
4162 {
4163   vat_main_t *vam = &vat_main;
4164   i32 retval = ntohl (mp->retval);
4165
4166   if (0 <= retval)
4167     {
4168       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4169     }
4170
4171   vam->retval = retval;
4172   vam->result_ready = 1;
4173 }
4174
4175 static void
4176   vl_api_one_show_xtr_mode_reply_t_handler_json
4177   (vl_api_one_show_xtr_mode_reply_t * mp)
4178 {
4179   vat_main_t *vam = &vat_main;
4180   vat_json_node_t node;
4181   u8 *status = 0;
4182
4183   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4184   vec_add1 (status, 0);
4185
4186   vat_json_init_object (&node);
4187   vat_json_object_add_string_copy (&node, "status", status);
4188
4189   vec_free (status);
4190
4191   vat_json_print (vam->ofp, &node);
4192   vat_json_free (&node);
4193
4194   vam->retval = ntohl (mp->retval);
4195   vam->result_ready = 1;
4196 }
4197
4198 static void
4199   vl_api_one_show_pitr_mode_reply_t_handler
4200   (vl_api_one_show_pitr_mode_reply_t * mp)
4201 {
4202   vat_main_t *vam = &vat_main;
4203   i32 retval = ntohl (mp->retval);
4204
4205   if (0 <= retval)
4206     {
4207       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4208     }
4209
4210   vam->retval = retval;
4211   vam->result_ready = 1;
4212 }
4213
4214 static void
4215   vl_api_one_show_pitr_mode_reply_t_handler_json
4216   (vl_api_one_show_pitr_mode_reply_t * mp)
4217 {
4218   vat_main_t *vam = &vat_main;
4219   vat_json_node_t node;
4220   u8 *status = 0;
4221
4222   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4223   vec_add1 (status, 0);
4224
4225   vat_json_init_object (&node);
4226   vat_json_object_add_string_copy (&node, "status", status);
4227
4228   vec_free (status);
4229
4230   vat_json_print (vam->ofp, &node);
4231   vat_json_free (&node);
4232
4233   vam->retval = ntohl (mp->retval);
4234   vam->result_ready = 1;
4235 }
4236
4237 static void
4238   vl_api_one_show_petr_mode_reply_t_handler
4239   (vl_api_one_show_petr_mode_reply_t * mp)
4240 {
4241   vat_main_t *vam = &vat_main;
4242   i32 retval = ntohl (mp->retval);
4243
4244   if (0 <= retval)
4245     {
4246       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4247     }
4248
4249   vam->retval = retval;
4250   vam->result_ready = 1;
4251 }
4252
4253 static void
4254   vl_api_one_show_petr_mode_reply_t_handler_json
4255   (vl_api_one_show_petr_mode_reply_t * mp)
4256 {
4257   vat_main_t *vam = &vat_main;
4258   vat_json_node_t node;
4259   u8 *status = 0;
4260
4261   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4262   vec_add1 (status, 0);
4263
4264   vat_json_init_object (&node);
4265   vat_json_object_add_string_copy (&node, "status", status);
4266
4267   vec_free (status);
4268
4269   vat_json_print (vam->ofp, &node);
4270   vat_json_free (&node);
4271
4272   vam->retval = ntohl (mp->retval);
4273   vam->result_ready = 1;
4274 }
4275
4276 static void
4277   vl_api_show_one_use_petr_reply_t_handler
4278   (vl_api_show_one_use_petr_reply_t * mp)
4279 {
4280   vat_main_t *vam = &vat_main;
4281   i32 retval = ntohl (mp->retval);
4282
4283   if (0 <= retval)
4284     {
4285       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4286       if (mp->status)
4287         {
4288           print (vam->ofp, "Proxy-ETR address; %U",
4289                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4290                  mp->ip_address.un);
4291         }
4292     }
4293
4294   vam->retval = retval;
4295   vam->result_ready = 1;
4296 }
4297
4298 static void
4299   vl_api_show_one_use_petr_reply_t_handler_json
4300   (vl_api_show_one_use_petr_reply_t * mp)
4301 {
4302   vat_main_t *vam = &vat_main;
4303   vat_json_node_t node;
4304   u8 *status = 0;
4305   struct in_addr ip4;
4306   struct in6_addr ip6;
4307
4308   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4309   vec_add1 (status, 0);
4310
4311   vat_json_init_object (&node);
4312   vat_json_object_add_string_copy (&node, "status", status);
4313   if (mp->status)
4314     {
4315       if (mp->ip_address.af)
4316         {
4317           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4318           vat_json_object_add_ip6 (&node, "address", ip6);
4319         }
4320       else
4321         {
4322           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4323           vat_json_object_add_ip4 (&node, "address", ip4);
4324         }
4325     }
4326
4327   vec_free (status);
4328
4329   vat_json_print (vam->ofp, &node);
4330   vat_json_free (&node);
4331
4332   vam->retval = ntohl (mp->retval);
4333   vam->result_ready = 1;
4334 }
4335
4336 static void
4337   vl_api_show_one_nsh_mapping_reply_t_handler
4338   (vl_api_show_one_nsh_mapping_reply_t * mp)
4339 {
4340   vat_main_t *vam = &vat_main;
4341   i32 retval = ntohl (mp->retval);
4342
4343   if (0 <= retval)
4344     {
4345       print (vam->ofp, "%-20s%-16s",
4346              mp->is_set ? "set" : "not-set",
4347              mp->is_set ? (char *) mp->locator_set_name : "");
4348     }
4349
4350   vam->retval = retval;
4351   vam->result_ready = 1;
4352 }
4353
4354 static void
4355   vl_api_show_one_nsh_mapping_reply_t_handler_json
4356   (vl_api_show_one_nsh_mapping_reply_t * mp)
4357 {
4358   vat_main_t *vam = &vat_main;
4359   vat_json_node_t node;
4360   u8 *status = 0;
4361
4362   status = format (0, "%s", mp->is_set ? "yes" : "no");
4363   vec_add1 (status, 0);
4364
4365   vat_json_init_object (&node);
4366   vat_json_object_add_string_copy (&node, "is_set", status);
4367   if (mp->is_set)
4368     {
4369       vat_json_object_add_string_copy (&node, "locator_set",
4370                                        mp->locator_set_name);
4371     }
4372
4373   vec_free (status);
4374
4375   vat_json_print (vam->ofp, &node);
4376   vat_json_free (&node);
4377
4378   vam->retval = ntohl (mp->retval);
4379   vam->result_ready = 1;
4380 }
4381
4382 static void
4383   vl_api_show_one_map_register_ttl_reply_t_handler
4384   (vl_api_show_one_map_register_ttl_reply_t * mp)
4385 {
4386   vat_main_t *vam = &vat_main;
4387   i32 retval = ntohl (mp->retval);
4388
4389   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4390
4391   if (0 <= retval)
4392     {
4393       print (vam->ofp, "ttl: %u", mp->ttl);
4394     }
4395
4396   vam->retval = retval;
4397   vam->result_ready = 1;
4398 }
4399
4400 static void
4401   vl_api_show_one_map_register_ttl_reply_t_handler_json
4402   (vl_api_show_one_map_register_ttl_reply_t * mp)
4403 {
4404   vat_main_t *vam = &vat_main;
4405   vat_json_node_t node;
4406
4407   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4408   vat_json_init_object (&node);
4409   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4410
4411   vat_json_print (vam->ofp, &node);
4412   vat_json_free (&node);
4413
4414   vam->retval = ntohl (mp->retval);
4415   vam->result_ready = 1;
4416 }
4417
4418 static void
4419 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4420 {
4421   vat_main_t *vam = &vat_main;
4422   i32 retval = ntohl (mp->retval);
4423
4424   if (0 <= retval)
4425     {
4426       print (vam->ofp, "%-20s%-16s",
4427              mp->status ? "enabled" : "disabled",
4428              mp->status ? (char *) mp->locator_set_name : "");
4429     }
4430
4431   vam->retval = retval;
4432   vam->result_ready = 1;
4433 }
4434
4435 static void
4436 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4437 {
4438   vat_main_t *vam = &vat_main;
4439   vat_json_node_t node;
4440   u8 *status = 0;
4441
4442   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4443   vec_add1 (status, 0);
4444
4445   vat_json_init_object (&node);
4446   vat_json_object_add_string_copy (&node, "status", status);
4447   if (mp->status)
4448     {
4449       vat_json_object_add_string_copy (&node, "locator_set",
4450                                        mp->locator_set_name);
4451     }
4452
4453   vec_free (status);
4454
4455   vat_json_print (vam->ofp, &node);
4456   vat_json_free (&node);
4457
4458   vam->retval = ntohl (mp->retval);
4459   vam->result_ready = 1;
4460 }
4461
4462 static u8 *
4463 format_policer_type (u8 * s, va_list * va)
4464 {
4465   u32 i = va_arg (*va, u32);
4466
4467   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4468     s = format (s, "1r2c");
4469   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4470     s = format (s, "1r3c");
4471   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4472     s = format (s, "2r3c-2698");
4473   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4474     s = format (s, "2r3c-4115");
4475   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4476     s = format (s, "2r3c-mef5cf1");
4477   else
4478     s = format (s, "ILLEGAL");
4479   return s;
4480 }
4481
4482 static u8 *
4483 format_policer_rate_type (u8 * s, va_list * va)
4484 {
4485   u32 i = va_arg (*va, u32);
4486
4487   if (i == SSE2_QOS_RATE_KBPS)
4488     s = format (s, "kbps");
4489   else if (i == SSE2_QOS_RATE_PPS)
4490     s = format (s, "pps");
4491   else
4492     s = format (s, "ILLEGAL");
4493   return s;
4494 }
4495
4496 static u8 *
4497 format_policer_round_type (u8 * s, va_list * va)
4498 {
4499   u32 i = va_arg (*va, u32);
4500
4501   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4502     s = format (s, "closest");
4503   else if (i == SSE2_QOS_ROUND_TO_UP)
4504     s = format (s, "up");
4505   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4506     s = format (s, "down");
4507   else
4508     s = format (s, "ILLEGAL");
4509   return s;
4510 }
4511
4512 static u8 *
4513 format_policer_action_type (u8 * s, va_list * va)
4514 {
4515   u32 i = va_arg (*va, u32);
4516
4517   if (i == SSE2_QOS_ACTION_DROP)
4518     s = format (s, "drop");
4519   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4520     s = format (s, "transmit");
4521   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4522     s = format (s, "mark-and-transmit");
4523   else
4524     s = format (s, "ILLEGAL");
4525   return s;
4526 }
4527
4528 static u8 *
4529 format_dscp (u8 * s, va_list * va)
4530 {
4531   u32 i = va_arg (*va, u32);
4532   char *t = 0;
4533
4534   switch (i)
4535     {
4536 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4537       foreach_vnet_dscp
4538 #undef _
4539     default:
4540       return format (s, "ILLEGAL");
4541     }
4542   s = format (s, "%s", t);
4543   return s;
4544 }
4545
4546 static void
4547 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4548 {
4549   vat_main_t *vam = &vat_main;
4550   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4551
4552   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4553     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4554   else
4555     conform_dscp_str = format (0, "");
4556
4557   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4558     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4559   else
4560     exceed_dscp_str = format (0, "");
4561
4562   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4563     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4564   else
4565     violate_dscp_str = format (0, "");
4566
4567   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4568          "rate type %U, round type %U, %s rate, %s color-aware, "
4569          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4570          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4571          "conform action %U%s, exceed action %U%s, violate action %U%s",
4572          mp->name,
4573          format_policer_type, mp->type,
4574          ntohl (mp->cir),
4575          ntohl (mp->eir),
4576          clib_net_to_host_u64 (mp->cb),
4577          clib_net_to_host_u64 (mp->eb),
4578          format_policer_rate_type, mp->rate_type,
4579          format_policer_round_type, mp->round_type,
4580          mp->single_rate ? "single" : "dual",
4581          mp->color_aware ? "is" : "not",
4582          ntohl (mp->cir_tokens_per_period),
4583          ntohl (mp->pir_tokens_per_period),
4584          ntohl (mp->scale),
4585          ntohl (mp->current_limit),
4586          ntohl (mp->current_bucket),
4587          ntohl (mp->extended_limit),
4588          ntohl (mp->extended_bucket),
4589          clib_net_to_host_u64 (mp->last_update_time),
4590          format_policer_action_type, mp->conform_action.type,
4591          conform_dscp_str,
4592          format_policer_action_type, mp->exceed_action.type,
4593          exceed_dscp_str,
4594          format_policer_action_type, mp->violate_action.type,
4595          violate_dscp_str);
4596
4597   vec_free (conform_dscp_str);
4598   vec_free (exceed_dscp_str);
4599   vec_free (violate_dscp_str);
4600 }
4601
4602 static void vl_api_policer_details_t_handler_json
4603   (vl_api_policer_details_t * mp)
4604 {
4605   vat_main_t *vam = &vat_main;
4606   vat_json_node_t *node;
4607   u8 *rate_type_str, *round_type_str, *type_str;
4608   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4609
4610   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4611   round_type_str =
4612     format (0, "%U", format_policer_round_type, mp->round_type);
4613   type_str = format (0, "%U", format_policer_type, mp->type);
4614   conform_action_str = format (0, "%U", format_policer_action_type,
4615                                mp->conform_action.type);
4616   exceed_action_str = format (0, "%U", format_policer_action_type,
4617                               mp->exceed_action.type);
4618   violate_action_str = format (0, "%U", format_policer_action_type,
4619                                mp->violate_action.type);
4620
4621   if (VAT_JSON_ARRAY != vam->json_tree.type)
4622     {
4623       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4624       vat_json_init_array (&vam->json_tree);
4625     }
4626   node = vat_json_array_add (&vam->json_tree);
4627
4628   vat_json_init_object (node);
4629   vat_json_object_add_string_copy (node, "name", mp->name);
4630   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4631   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4632   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4633   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4634   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4635   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4636   vat_json_object_add_string_copy (node, "type", type_str);
4637   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4638   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4639   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4640   vat_json_object_add_uint (node, "cir_tokens_per_period",
4641                             ntohl (mp->cir_tokens_per_period));
4642   vat_json_object_add_uint (node, "eir_tokens_per_period",
4643                             ntohl (mp->pir_tokens_per_period));
4644   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4645   vat_json_object_add_uint (node, "current_bucket",
4646                             ntohl (mp->current_bucket));
4647   vat_json_object_add_uint (node, "extended_limit",
4648                             ntohl (mp->extended_limit));
4649   vat_json_object_add_uint (node, "extended_bucket",
4650                             ntohl (mp->extended_bucket));
4651   vat_json_object_add_uint (node, "last_update_time",
4652                             ntohl (mp->last_update_time));
4653   vat_json_object_add_string_copy (node, "conform_action",
4654                                    conform_action_str);
4655   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4656     {
4657       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4658       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4659       vec_free (dscp_str);
4660     }
4661   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4662   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4663     {
4664       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4665       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4666       vec_free (dscp_str);
4667     }
4668   vat_json_object_add_string_copy (node, "violate_action",
4669                                    violate_action_str);
4670   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4671     {
4672       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4673       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4674       vec_free (dscp_str);
4675     }
4676
4677   vec_free (rate_type_str);
4678   vec_free (round_type_str);
4679   vec_free (type_str);
4680   vec_free (conform_action_str);
4681   vec_free (exceed_action_str);
4682   vec_free (violate_action_str);
4683 }
4684
4685 static void
4686 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4687                                            mp)
4688 {
4689   vat_main_t *vam = &vat_main;
4690   int i, count = ntohl (mp->count);
4691
4692   if (count > 0)
4693     print (vam->ofp, "classify table ids (%d) : ", count);
4694   for (i = 0; i < count; i++)
4695     {
4696       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4697       print (vam->ofp, (i < count - 1) ? "," : "");
4698     }
4699   vam->retval = ntohl (mp->retval);
4700   vam->result_ready = 1;
4701 }
4702
4703 static void
4704   vl_api_classify_table_ids_reply_t_handler_json
4705   (vl_api_classify_table_ids_reply_t * mp)
4706 {
4707   vat_main_t *vam = &vat_main;
4708   int i, count = ntohl (mp->count);
4709
4710   if (count > 0)
4711     {
4712       vat_json_node_t node;
4713
4714       vat_json_init_object (&node);
4715       for (i = 0; i < count; i++)
4716         {
4717           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4718         }
4719       vat_json_print (vam->ofp, &node);
4720       vat_json_free (&node);
4721     }
4722   vam->retval = ntohl (mp->retval);
4723   vam->result_ready = 1;
4724 }
4725
4726 static void
4727   vl_api_classify_table_by_interface_reply_t_handler
4728   (vl_api_classify_table_by_interface_reply_t * mp)
4729 {
4730   vat_main_t *vam = &vat_main;
4731   u32 table_id;
4732
4733   table_id = ntohl (mp->l2_table_id);
4734   if (table_id != ~0)
4735     print (vam->ofp, "l2 table id : %d", table_id);
4736   else
4737     print (vam->ofp, "l2 table id : No input ACL tables configured");
4738   table_id = ntohl (mp->ip4_table_id);
4739   if (table_id != ~0)
4740     print (vam->ofp, "ip4 table id : %d", table_id);
4741   else
4742     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4743   table_id = ntohl (mp->ip6_table_id);
4744   if (table_id != ~0)
4745     print (vam->ofp, "ip6 table id : %d", table_id);
4746   else
4747     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4748   vam->retval = ntohl (mp->retval);
4749   vam->result_ready = 1;
4750 }
4751
4752 static void
4753   vl_api_classify_table_by_interface_reply_t_handler_json
4754   (vl_api_classify_table_by_interface_reply_t * mp)
4755 {
4756   vat_main_t *vam = &vat_main;
4757   vat_json_node_t node;
4758
4759   vat_json_init_object (&node);
4760
4761   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4762   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4763   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4764
4765   vat_json_print (vam->ofp, &node);
4766   vat_json_free (&node);
4767
4768   vam->retval = ntohl (mp->retval);
4769   vam->result_ready = 1;
4770 }
4771
4772 static void vl_api_policer_add_del_reply_t_handler
4773   (vl_api_policer_add_del_reply_t * mp)
4774 {
4775   vat_main_t *vam = &vat_main;
4776   i32 retval = ntohl (mp->retval);
4777   if (vam->async_mode)
4778     {
4779       vam->async_errors += (retval < 0);
4780     }
4781   else
4782     {
4783       vam->retval = retval;
4784       vam->result_ready = 1;
4785       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4786         /*
4787          * Note: this is just barely thread-safe, depends on
4788          * the main thread spinning waiting for an answer...
4789          */
4790         errmsg ("policer index %d", ntohl (mp->policer_index));
4791     }
4792 }
4793
4794 static void vl_api_policer_add_del_reply_t_handler_json
4795   (vl_api_policer_add_del_reply_t * mp)
4796 {
4797   vat_main_t *vam = &vat_main;
4798   vat_json_node_t node;
4799
4800   vat_json_init_object (&node);
4801   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4802   vat_json_object_add_uint (&node, "policer_index",
4803                             ntohl (mp->policer_index));
4804
4805   vat_json_print (vam->ofp, &node);
4806   vat_json_free (&node);
4807
4808   vam->retval = ntohl (mp->retval);
4809   vam->result_ready = 1;
4810 }
4811
4812 /* Format hex dump. */
4813 u8 *
4814 format_hex_bytes (u8 * s, va_list * va)
4815 {
4816   u8 *bytes = va_arg (*va, u8 *);
4817   int n_bytes = va_arg (*va, int);
4818   uword i;
4819
4820   /* Print short or long form depending on byte count. */
4821   uword short_form = n_bytes <= 32;
4822   u32 indent = format_get_indent (s);
4823
4824   if (n_bytes == 0)
4825     return s;
4826
4827   for (i = 0; i < n_bytes; i++)
4828     {
4829       if (!short_form && (i % 32) == 0)
4830         s = format (s, "%08x: ", i);
4831       s = format (s, "%02x", bytes[i]);
4832       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4833         s = format (s, "\n%U", format_white_space, indent);
4834     }
4835
4836   return s;
4837 }
4838
4839 static void
4840 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4841                                             * mp)
4842 {
4843   vat_main_t *vam = &vat_main;
4844   i32 retval = ntohl (mp->retval);
4845   if (retval == 0)
4846     {
4847       print (vam->ofp, "classify table info :");
4848       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4849              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4850              ntohl (mp->miss_next_index));
4851       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4852              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4853              ntohl (mp->match_n_vectors));
4854       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4855              ntohl (mp->mask_length));
4856     }
4857   vam->retval = retval;
4858   vam->result_ready = 1;
4859 }
4860
4861 static void
4862   vl_api_classify_table_info_reply_t_handler_json
4863   (vl_api_classify_table_info_reply_t * mp)
4864 {
4865   vat_main_t *vam = &vat_main;
4866   vat_json_node_t node;
4867
4868   i32 retval = ntohl (mp->retval);
4869   if (retval == 0)
4870     {
4871       vat_json_init_object (&node);
4872
4873       vat_json_object_add_int (&node, "sessions",
4874                                ntohl (mp->active_sessions));
4875       vat_json_object_add_int (&node, "nexttbl",
4876                                ntohl (mp->next_table_index));
4877       vat_json_object_add_int (&node, "nextnode",
4878                                ntohl (mp->miss_next_index));
4879       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4880       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4881       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4882       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4883                       ntohl (mp->mask_length), 0);
4884       vat_json_object_add_string_copy (&node, "mask", s);
4885
4886       vat_json_print (vam->ofp, &node);
4887       vat_json_free (&node);
4888     }
4889   vam->retval = ntohl (mp->retval);
4890   vam->result_ready = 1;
4891 }
4892
4893 static void
4894 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4895                                            mp)
4896 {
4897   vat_main_t *vam = &vat_main;
4898
4899   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4900          ntohl (mp->hit_next_index), ntohl (mp->advance),
4901          ntohl (mp->opaque_index));
4902   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4903          ntohl (mp->match_length));
4904 }
4905
4906 static void
4907   vl_api_classify_session_details_t_handler_json
4908   (vl_api_classify_session_details_t * mp)
4909 {
4910   vat_main_t *vam = &vat_main;
4911   vat_json_node_t *node = NULL;
4912
4913   if (VAT_JSON_ARRAY != vam->json_tree.type)
4914     {
4915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4916       vat_json_init_array (&vam->json_tree);
4917     }
4918   node = vat_json_array_add (&vam->json_tree);
4919
4920   vat_json_init_object (node);
4921   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4922   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4923   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4924   u8 *s =
4925     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4926             0);
4927   vat_json_object_add_string_copy (node, "match", s);
4928 }
4929
4930 static void vl_api_pg_create_interface_reply_t_handler
4931   (vl_api_pg_create_interface_reply_t * mp)
4932 {
4933   vat_main_t *vam = &vat_main;
4934
4935   vam->retval = ntohl (mp->retval);
4936   vam->result_ready = 1;
4937 }
4938
4939 static void vl_api_pg_create_interface_reply_t_handler_json
4940   (vl_api_pg_create_interface_reply_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943   vat_json_node_t node;
4944
4945   i32 retval = ntohl (mp->retval);
4946   if (retval == 0)
4947     {
4948       vat_json_init_object (&node);
4949
4950       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4951
4952       vat_json_print (vam->ofp, &node);
4953       vat_json_free (&node);
4954     }
4955   vam->retval = ntohl (mp->retval);
4956   vam->result_ready = 1;
4957 }
4958
4959 static void vl_api_policer_classify_details_t_handler
4960   (vl_api_policer_classify_details_t * mp)
4961 {
4962   vat_main_t *vam = &vat_main;
4963
4964   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4965          ntohl (mp->table_index));
4966 }
4967
4968 static void vl_api_policer_classify_details_t_handler_json
4969   (vl_api_policer_classify_details_t * mp)
4970 {
4971   vat_main_t *vam = &vat_main;
4972   vat_json_node_t *node;
4973
4974   if (VAT_JSON_ARRAY != vam->json_tree.type)
4975     {
4976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4977       vat_json_init_array (&vam->json_tree);
4978     }
4979   node = vat_json_array_add (&vam->json_tree);
4980
4981   vat_json_init_object (node);
4982   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4983   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4984 }
4985
4986 static void vl_api_flow_classify_details_t_handler
4987   (vl_api_flow_classify_details_t * mp)
4988 {
4989   vat_main_t *vam = &vat_main;
4990
4991   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4992          ntohl (mp->table_index));
4993 }
4994
4995 static void vl_api_flow_classify_details_t_handler_json
4996   (vl_api_flow_classify_details_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999   vat_json_node_t *node;
5000
5001   if (VAT_JSON_ARRAY != vam->json_tree.type)
5002     {
5003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5004       vat_json_init_array (&vam->json_tree);
5005     }
5006   node = vat_json_array_add (&vam->json_tree);
5007
5008   vat_json_init_object (node);
5009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5010   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5011 }
5012
5013 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5014 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5015 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5016 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5017 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5018 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5019 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5020 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5021 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5022 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5023
5024 /*
5025  * Generate boilerplate reply handlers, which
5026  * dig the return value out of the xxx_reply_t API message,
5027  * stick it into vam->retval, and set vam->result_ready
5028  *
5029  * Could also do this by pointing N message decode slots at
5030  * a single function, but that could break in subtle ways.
5031  */
5032
5033 #define foreach_standard_reply_retval_handler           \
5034 _(sw_interface_set_flags_reply)                         \
5035 _(sw_interface_add_del_address_reply)                   \
5036 _(sw_interface_set_rx_mode_reply)                       \
5037 _(sw_interface_set_rx_placement_reply)                  \
5038 _(sw_interface_set_table_reply)                         \
5039 _(sw_interface_set_mpls_enable_reply)                   \
5040 _(sw_interface_set_vpath_reply)                         \
5041 _(sw_interface_set_vxlan_bypass_reply)                  \
5042 _(sw_interface_set_geneve_bypass_reply)                 \
5043 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5044 _(sw_interface_set_l2_bridge_reply)                     \
5045 _(sw_interface_set_bond_weight_reply)                   \
5046 _(bridge_domain_add_del_reply)                          \
5047 _(sw_interface_set_l2_xconnect_reply)                   \
5048 _(l2fib_add_del_reply)                                  \
5049 _(l2fib_flush_int_reply)                                \
5050 _(l2fib_flush_bd_reply)                                 \
5051 _(ip_route_add_del_reply)                               \
5052 _(ip_table_add_del_reply)                               \
5053 _(ip_table_replace_begin_reply)                         \
5054 _(ip_table_flush_reply)                                 \
5055 _(ip_table_replace_end_reply)                           \
5056 _(ip_mroute_add_del_reply)                              \
5057 _(mpls_route_add_del_reply)                             \
5058 _(mpls_table_add_del_reply)                             \
5059 _(mpls_ip_bind_unbind_reply)                            \
5060 _(bier_route_add_del_reply)                             \
5061 _(bier_table_add_del_reply)                             \
5062 _(sw_interface_set_unnumbered_reply)                    \
5063 _(set_ip_flow_hash_reply)                               \
5064 _(sw_interface_ip6_enable_disable_reply)                \
5065 _(l2_patch_add_del_reply)                               \
5066 _(sr_mpls_policy_add_reply)                             \
5067 _(sr_mpls_policy_mod_reply)                             \
5068 _(sr_mpls_policy_del_reply)                             \
5069 _(sr_policy_add_reply)                                  \
5070 _(sr_policy_mod_reply)                                  \
5071 _(sr_policy_del_reply)                                  \
5072 _(sr_localsid_add_del_reply)                            \
5073 _(sr_steering_add_del_reply)                            \
5074 _(classify_add_del_session_reply)                       \
5075 _(classify_set_interface_ip_table_reply)                \
5076 _(classify_set_interface_l2_tables_reply)               \
5077 _(l2tpv3_set_tunnel_cookies_reply)                      \
5078 _(l2tpv3_interface_enable_disable_reply)                \
5079 _(l2tpv3_set_lookup_key_reply)                          \
5080 _(l2_fib_clear_table_reply)                             \
5081 _(l2_interface_efp_filter_reply)                        \
5082 _(l2_interface_vlan_tag_rewrite_reply)                  \
5083 _(modify_vhost_user_if_reply)                           \
5084 _(delete_vhost_user_if_reply)                           \
5085 _(want_l2_macs_events_reply)                            \
5086 _(input_acl_set_interface_reply)                        \
5087 _(ipsec_spd_add_del_reply)                              \
5088 _(ipsec_interface_add_del_spd_reply)                    \
5089 _(ipsec_spd_entry_add_del_reply)                        \
5090 _(ipsec_sad_entry_add_del_reply)                        \
5091 _(ipsec_tunnel_if_add_del_reply)                        \
5092 _(ipsec_tunnel_if_set_sa_reply)                         \
5093 _(delete_loopback_reply)                                \
5094 _(bd_ip_mac_add_del_reply)                              \
5095 _(bd_ip_mac_flush_reply)                                \
5096 _(want_interface_events_reply)                          \
5097 _(cop_interface_enable_disable_reply)                   \
5098 _(cop_whitelist_enable_disable_reply)                   \
5099 _(sw_interface_clear_stats_reply)                       \
5100 _(ioam_enable_reply)                                    \
5101 _(ioam_disable_reply)                                   \
5102 _(one_add_del_locator_reply)                            \
5103 _(one_add_del_local_eid_reply)                          \
5104 _(one_add_del_remote_mapping_reply)                     \
5105 _(one_add_del_adjacency_reply)                          \
5106 _(one_add_del_map_resolver_reply)                       \
5107 _(one_add_del_map_server_reply)                         \
5108 _(one_enable_disable_reply)                             \
5109 _(one_rloc_probe_enable_disable_reply)                  \
5110 _(one_map_register_enable_disable_reply)                \
5111 _(one_map_register_set_ttl_reply)                       \
5112 _(one_set_transport_protocol_reply)                     \
5113 _(one_map_register_fallback_threshold_reply)            \
5114 _(one_pitr_set_locator_set_reply)                       \
5115 _(one_map_request_mode_reply)                           \
5116 _(one_add_del_map_request_itr_rlocs_reply)              \
5117 _(one_eid_table_add_del_map_reply)                      \
5118 _(one_use_petr_reply)                                   \
5119 _(one_stats_enable_disable_reply)                       \
5120 _(one_add_del_l2_arp_entry_reply)                       \
5121 _(one_add_del_ndp_entry_reply)                          \
5122 _(one_stats_flush_reply)                                \
5123 _(one_enable_disable_xtr_mode_reply)                    \
5124 _(one_enable_disable_pitr_mode_reply)                   \
5125 _(one_enable_disable_petr_mode_reply)                   \
5126 _(gpe_enable_disable_reply)                             \
5127 _(gpe_set_encap_mode_reply)                             \
5128 _(gpe_add_del_iface_reply)                              \
5129 _(gpe_add_del_native_fwd_rpath_reply)                   \
5130 _(af_packet_delete_reply)                               \
5131 _(policer_classify_set_interface_reply)                 \
5132 _(set_ipfix_exporter_reply)                             \
5133 _(set_ipfix_classify_stream_reply)                      \
5134 _(ipfix_classify_table_add_del_reply)                   \
5135 _(flow_classify_set_interface_reply)                    \
5136 _(sw_interface_span_enable_disable_reply)               \
5137 _(pg_capture_reply)                                     \
5138 _(pg_enable_disable_reply)                              \
5139 _(ip_source_and_port_range_check_add_del_reply)         \
5140 _(ip_source_and_port_range_check_interface_add_del_reply)\
5141 _(delete_subif_reply)                                   \
5142 _(l2_interface_pbb_tag_rewrite_reply)                   \
5143 _(set_punt_reply)                                       \
5144 _(feature_enable_disable_reply)                         \
5145 _(feature_gso_enable_disable_reply)                     \
5146 _(sw_interface_tag_add_del_reply)                       \
5147 _(sw_interface_add_del_mac_address_reply)               \
5148 _(hw_interface_set_mtu_reply)                           \
5149 _(p2p_ethernet_add_reply)                               \
5150 _(p2p_ethernet_del_reply)                               \
5151 _(lldp_config_reply)                                    \
5152 _(sw_interface_set_lldp_reply)                          \
5153 _(tcp_configure_src_addresses_reply)                    \
5154 _(session_rule_add_del_reply)                           \
5155 _(ip_container_proxy_add_del_reply)                     \
5156 _(output_acl_set_interface_reply)                       \
5157 _(qos_record_enable_disable_reply)
5158
5159 #define _(n)                                    \
5160     static void vl_api_##n##_t_handler          \
5161     (vl_api_##n##_t * mp)                       \
5162     {                                           \
5163         vat_main_t * vam = &vat_main;           \
5164         i32 retval = ntohl(mp->retval);         \
5165         if (vam->async_mode) {                  \
5166             vam->async_errors += (retval < 0);  \
5167         } else {                                \
5168             vam->retval = retval;               \
5169             vam->result_ready = 1;              \
5170         }                                       \
5171     }
5172 foreach_standard_reply_retval_handler;
5173 #undef _
5174
5175 #define _(n)                                    \
5176     static void vl_api_##n##_t_handler_json     \
5177     (vl_api_##n##_t * mp)                       \
5178     {                                           \
5179         vat_main_t * vam = &vat_main;           \
5180         vat_json_node_t node;                   \
5181         vat_json_init_object(&node);            \
5182         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5183         vat_json_print(vam->ofp, &node);        \
5184         vam->retval = ntohl(mp->retval);        \
5185         vam->result_ready = 1;                  \
5186     }
5187 foreach_standard_reply_retval_handler;
5188 #undef _
5189
5190 /*
5191  * Table of message reply handlers, must include boilerplate handlers
5192  * we just generated
5193  */
5194
5195 #define foreach_vpe_api_reply_msg                                       \
5196 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5197 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5198 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5199 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5200 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5201 _(CLI_REPLY, cli_reply)                                                 \
5202 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5203 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5204   sw_interface_add_del_address_reply)                                   \
5205 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5206 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5207 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5208 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5209 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5210 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5211 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5212 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5213 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5214 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5215   sw_interface_set_l2_xconnect_reply)                                   \
5216 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5217   sw_interface_set_l2_bridge_reply)                                     \
5218 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5219 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5220 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5221 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5222 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5223 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5224 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5225 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5226 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5227 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5228 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5229 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5230 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5231 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5232 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5233 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5234 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5235 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5236 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5237 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5238 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5239 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5240 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5241 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5242 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5243 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5244 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5245 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5246 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5247 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5248 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5249 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5250 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5251 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5252   sw_interface_set_unnumbered_reply)                                    \
5253 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5254 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5255 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5256 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5257   sw_interface_ip6_enable_disable_reply)                                \
5258 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5259 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5260 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5261 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5262 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5263 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5264 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5265 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5266 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5267 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5268 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5269 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5270 classify_set_interface_ip_table_reply)                                  \
5271 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5272   classify_set_interface_l2_tables_reply)                               \
5273 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5274 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5275 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5276 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5277 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5278   l2tpv3_interface_enable_disable_reply)                                \
5279 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5280 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5281 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5282 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5283 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5284 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5285 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5286 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5287 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5288 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5289 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5290 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5291 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5292 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5293 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5294 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5295 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5296 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5297 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5298 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5299 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5300 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5301 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5302 _(L2_MACS_EVENT, l2_macs_event)                                         \
5303 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5304 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5305 _(IP_DETAILS, ip_details)                                               \
5306 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5307 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5308 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5309 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5310 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5311 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5312 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5313 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5314 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5315 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5316 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5317 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5318 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5319 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5320 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5321 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5322 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5323 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5324 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5325 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5326 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5327 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5328 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5329 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5330 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5331 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5332 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5333 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5334   one_map_register_enable_disable_reply)                                \
5335 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5336 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5337 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5338 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5339   one_map_register_fallback_threshold_reply)                            \
5340 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5341   one_rloc_probe_enable_disable_reply)                                  \
5342 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5343 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5344 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5345 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5346 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5347 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5348 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5349 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5350 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5351 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5352 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5353 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5354 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5355 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5356 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5357 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5358   show_one_stats_enable_disable_reply)                                  \
5359 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5360 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5361 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5362 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5363 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5364 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5365 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5366 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5367   one_enable_disable_pitr_mode_reply)                                   \
5368 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5369   one_enable_disable_petr_mode_reply)                                   \
5370 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5371 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5372 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5373 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5374 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5375 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5376 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5377 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5378 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5379 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5380 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5381 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5382   gpe_add_del_native_fwd_rpath_reply)                                   \
5383 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5384   gpe_fwd_entry_path_details)                                           \
5385 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5386 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5387   one_add_del_map_request_itr_rlocs_reply)                              \
5388 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5389   one_get_map_request_itr_rlocs_reply)                                  \
5390 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5391 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5392 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5393 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5394 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5395 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5396   show_one_map_register_state_reply)                                    \
5397 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5398 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5399   show_one_map_register_fallback_threshold_reply)                       \
5400 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5401 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5402 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5403 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5404 _(POLICER_DETAILS, policer_details)                                     \
5405 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5406 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5407 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5408 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5409 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5410 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5411 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5412 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5413 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5414 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5415 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5416 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5417 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5418 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5419 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5420 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5421 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5422 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5423 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5424 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5425 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5426 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5427 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5428 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5429  ip_source_and_port_range_check_add_del_reply)                          \
5430 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5431  ip_source_and_port_range_check_interface_add_del_reply)                \
5432 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5433 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5434 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5435 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5436 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5437 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5438 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5439 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5440 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5441 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5442 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5443 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5444 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5445 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5446 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5447 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5448 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5449 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5450 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5451 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5452 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5453 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5454 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5455
5456 #define foreach_standalone_reply_msg                                    \
5457 _(SW_INTERFACE_EVENT, sw_interface_event)
5458
5459 typedef struct
5460 {
5461   u8 *name;
5462   u32 value;
5463 } name_sort_t;
5464
5465 #define STR_VTR_OP_CASE(op)     \
5466     case L2_VTR_ ## op:         \
5467         return "" # op;
5468
5469 static const char *
5470 str_vtr_op (u32 vtr_op)
5471 {
5472   switch (vtr_op)
5473     {
5474       STR_VTR_OP_CASE (DISABLED);
5475       STR_VTR_OP_CASE (PUSH_1);
5476       STR_VTR_OP_CASE (PUSH_2);
5477       STR_VTR_OP_CASE (POP_1);
5478       STR_VTR_OP_CASE (POP_2);
5479       STR_VTR_OP_CASE (TRANSLATE_1_1);
5480       STR_VTR_OP_CASE (TRANSLATE_1_2);
5481       STR_VTR_OP_CASE (TRANSLATE_2_1);
5482       STR_VTR_OP_CASE (TRANSLATE_2_2);
5483     }
5484
5485   return "UNKNOWN";
5486 }
5487
5488 static int
5489 dump_sub_interface_table (vat_main_t * vam)
5490 {
5491   const sw_interface_subif_t *sub = NULL;
5492
5493   if (vam->json_output)
5494     {
5495       clib_warning
5496         ("JSON output supported only for VPE API calls and dump_stats_table");
5497       return -99;
5498     }
5499
5500   print (vam->ofp,
5501          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5502          "Interface", "sw_if_index",
5503          "sub id", "dot1ad", "tags", "outer id",
5504          "inner id", "exact", "default", "outer any", "inner any");
5505
5506   vec_foreach (sub, vam->sw_if_subif_table)
5507   {
5508     print (vam->ofp,
5509            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5510            sub->interface_name,
5511            sub->sw_if_index,
5512            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5513            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5514            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5515            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5516     if (sub->vtr_op != L2_VTR_DISABLED)
5517       {
5518         print (vam->ofp,
5519                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5520                "tag1: %d tag2: %d ]",
5521                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5522                sub->vtr_tag1, sub->vtr_tag2);
5523       }
5524   }
5525
5526   return 0;
5527 }
5528
5529 static int
5530 name_sort_cmp (void *a1, void *a2)
5531 {
5532   name_sort_t *n1 = a1;
5533   name_sort_t *n2 = a2;
5534
5535   return strcmp ((char *) n1->name, (char *) n2->name);
5536 }
5537
5538 static int
5539 dump_interface_table (vat_main_t * vam)
5540 {
5541   hash_pair_t *p;
5542   name_sort_t *nses = 0, *ns;
5543
5544   if (vam->json_output)
5545     {
5546       clib_warning
5547         ("JSON output supported only for VPE API calls and dump_stats_table");
5548       return -99;
5549     }
5550
5551   /* *INDENT-OFF* */
5552   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5553   ({
5554     vec_add2 (nses, ns, 1);
5555     ns->name = (u8 *)(p->key);
5556     ns->value = (u32) p->value[0];
5557   }));
5558   /* *INDENT-ON* */
5559
5560   vec_sort_with_function (nses, name_sort_cmp);
5561
5562   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5563   vec_foreach (ns, nses)
5564   {
5565     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5566   }
5567   vec_free (nses);
5568   return 0;
5569 }
5570
5571 static int
5572 dump_ip_table (vat_main_t * vam, int is_ipv6)
5573 {
5574   const ip_details_t *det = NULL;
5575   const ip_address_details_t *address = NULL;
5576   u32 i = ~0;
5577
5578   print (vam->ofp, "%-12s", "sw_if_index");
5579
5580   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5581   {
5582     i++;
5583     if (!det->present)
5584       {
5585         continue;
5586       }
5587     print (vam->ofp, "%-12d", i);
5588     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5589     if (!det->addr)
5590       {
5591         continue;
5592       }
5593     vec_foreach (address, det->addr)
5594     {
5595       print (vam->ofp,
5596              "            %-30U%-13d",
5597              is_ipv6 ? format_ip6_address : format_ip4_address,
5598              address->ip, address->prefix_length);
5599     }
5600   }
5601
5602   return 0;
5603 }
5604
5605 static int
5606 dump_ipv4_table (vat_main_t * vam)
5607 {
5608   if (vam->json_output)
5609     {
5610       clib_warning
5611         ("JSON output supported only for VPE API calls and dump_stats_table");
5612       return -99;
5613     }
5614
5615   return dump_ip_table (vam, 0);
5616 }
5617
5618 static int
5619 dump_ipv6_table (vat_main_t * vam)
5620 {
5621   if (vam->json_output)
5622     {
5623       clib_warning
5624         ("JSON output supported only for VPE API calls and dump_stats_table");
5625       return -99;
5626     }
5627
5628   return dump_ip_table (vam, 1);
5629 }
5630
5631 /*
5632  * Pass CLI buffers directly in the CLI_INBAND API message,
5633  * instead of an additional shared memory area.
5634  */
5635 static int
5636 exec_inband (vat_main_t * vam)
5637 {
5638   vl_api_cli_inband_t *mp;
5639   unformat_input_t *i = vam->input;
5640   int ret;
5641
5642   if (vec_len (i->buffer) == 0)
5643     return -1;
5644
5645   if (vam->exec_mode == 0 && unformat (i, "mode"))
5646     {
5647       vam->exec_mode = 1;
5648       return 0;
5649     }
5650   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5651     {
5652       vam->exec_mode = 0;
5653       return 0;
5654     }
5655
5656   /*
5657    * In order for the CLI command to work, it
5658    * must be a vector ending in \n, not a C-string ending
5659    * in \n\0.
5660    */
5661   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5662   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5663
5664   S (mp);
5665   W (ret);
5666   /* json responses may or may not include a useful reply... */
5667   if (vec_len (vam->cmd_reply))
5668     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5669   return ret;
5670 }
5671
5672 int
5673 exec (vat_main_t * vam)
5674 {
5675   return exec_inband (vam);
5676 }
5677
5678 static int
5679 api_create_loopback (vat_main_t * vam)
5680 {
5681   unformat_input_t *i = vam->input;
5682   vl_api_create_loopback_t *mp;
5683   vl_api_create_loopback_instance_t *mp_lbi;
5684   u8 mac_address[6];
5685   u8 mac_set = 0;
5686   u8 is_specified = 0;
5687   u32 user_instance = 0;
5688   int ret;
5689
5690   clib_memset (mac_address, 0, sizeof (mac_address));
5691
5692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5693     {
5694       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5695         mac_set = 1;
5696       if (unformat (i, "instance %d", &user_instance))
5697         is_specified = 1;
5698       else
5699         break;
5700     }
5701
5702   if (is_specified)
5703     {
5704       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5705       mp_lbi->is_specified = is_specified;
5706       if (is_specified)
5707         mp_lbi->user_instance = htonl (user_instance);
5708       if (mac_set)
5709         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5710       S (mp_lbi);
5711     }
5712   else
5713     {
5714       /* Construct the API message */
5715       M (CREATE_LOOPBACK, mp);
5716       if (mac_set)
5717         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5718       S (mp);
5719     }
5720
5721   W (ret);
5722   return ret;
5723 }
5724
5725 static int
5726 api_delete_loopback (vat_main_t * vam)
5727 {
5728   unformat_input_t *i = vam->input;
5729   vl_api_delete_loopback_t *mp;
5730   u32 sw_if_index = ~0;
5731   int ret;
5732
5733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5734     {
5735       if (unformat (i, "sw_if_index %d", &sw_if_index))
5736         ;
5737       else
5738         break;
5739     }
5740
5741   if (sw_if_index == ~0)
5742     {
5743       errmsg ("missing sw_if_index");
5744       return -99;
5745     }
5746
5747   /* Construct the API message */
5748   M (DELETE_LOOPBACK, mp);
5749   mp->sw_if_index = ntohl (sw_if_index);
5750
5751   S (mp);
5752   W (ret);
5753   return ret;
5754 }
5755
5756 static int
5757 api_want_interface_events (vat_main_t * vam)
5758 {
5759   unformat_input_t *i = vam->input;
5760   vl_api_want_interface_events_t *mp;
5761   int enable = -1;
5762   int ret;
5763
5764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5765     {
5766       if (unformat (i, "enable"))
5767         enable = 1;
5768       else if (unformat (i, "disable"))
5769         enable = 0;
5770       else
5771         break;
5772     }
5773
5774   if (enable == -1)
5775     {
5776       errmsg ("missing enable|disable");
5777       return -99;
5778     }
5779
5780   M (WANT_INTERFACE_EVENTS, mp);
5781   mp->enable_disable = enable;
5782
5783   vam->interface_event_display = enable;
5784
5785   S (mp);
5786   W (ret);
5787   return ret;
5788 }
5789
5790
5791 /* Note: non-static, called once to set up the initial intfc table */
5792 int
5793 api_sw_interface_dump (vat_main_t * vam)
5794 {
5795   vl_api_sw_interface_dump_t *mp;
5796   vl_api_control_ping_t *mp_ping;
5797   hash_pair_t *p;
5798   name_sort_t *nses = 0, *ns;
5799   sw_interface_subif_t *sub = NULL;
5800   int ret;
5801
5802   /* Toss the old name table */
5803   /* *INDENT-OFF* */
5804   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5805   ({
5806     vec_add2 (nses, ns, 1);
5807     ns->name = (u8 *)(p->key);
5808     ns->value = (u32) p->value[0];
5809   }));
5810   /* *INDENT-ON* */
5811
5812   hash_free (vam->sw_if_index_by_interface_name);
5813
5814   vec_foreach (ns, nses) vec_free (ns->name);
5815
5816   vec_free (nses);
5817
5818   vec_foreach (sub, vam->sw_if_subif_table)
5819   {
5820     vec_free (sub->interface_name);
5821   }
5822   vec_free (vam->sw_if_subif_table);
5823
5824   /* recreate the interface name hash table */
5825   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5826
5827   /*
5828    * Ask for all interface names. Otherwise, the epic catalog of
5829    * name filters becomes ridiculously long, and vat ends up needing
5830    * to be taught about new interface types.
5831    */
5832   M (SW_INTERFACE_DUMP, mp);
5833   S (mp);
5834
5835   /* Use a control ping for synchronization */
5836   MPING (CONTROL_PING, mp_ping);
5837   S (mp_ping);
5838
5839   W (ret);
5840   return ret;
5841 }
5842
5843 static int
5844 api_sw_interface_set_flags (vat_main_t * vam)
5845 {
5846   unformat_input_t *i = vam->input;
5847   vl_api_sw_interface_set_flags_t *mp;
5848   u32 sw_if_index;
5849   u8 sw_if_index_set = 0;
5850   u8 admin_up = 0;
5851   int ret;
5852
5853   /* Parse args required to build the message */
5854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5855     {
5856       if (unformat (i, "admin-up"))
5857         admin_up = 1;
5858       else if (unformat (i, "admin-down"))
5859         admin_up = 0;
5860       else
5861         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5862         sw_if_index_set = 1;
5863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5864         sw_if_index_set = 1;
5865       else
5866         break;
5867     }
5868
5869   if (sw_if_index_set == 0)
5870     {
5871       errmsg ("missing interface name or sw_if_index");
5872       return -99;
5873     }
5874
5875   /* Construct the API message */
5876   M (SW_INTERFACE_SET_FLAGS, mp);
5877   mp->sw_if_index = ntohl (sw_if_index);
5878   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5879
5880   /* send it... */
5881   S (mp);
5882
5883   /* Wait for a reply, return the good/bad news... */
5884   W (ret);
5885   return ret;
5886 }
5887
5888 static int
5889 api_sw_interface_set_rx_mode (vat_main_t * vam)
5890 {
5891   unformat_input_t *i = vam->input;
5892   vl_api_sw_interface_set_rx_mode_t *mp;
5893   u32 sw_if_index;
5894   u8 sw_if_index_set = 0;
5895   int ret;
5896   u8 queue_id_valid = 0;
5897   u32 queue_id;
5898   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5899
5900   /* Parse args required to build the message */
5901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5902     {
5903       if (unformat (i, "queue %d", &queue_id))
5904         queue_id_valid = 1;
5905       else if (unformat (i, "polling"))
5906         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5907       else if (unformat (i, "interrupt"))
5908         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5909       else if (unformat (i, "adaptive"))
5910         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5911       else
5912         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5913         sw_if_index_set = 1;
5914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5915         sw_if_index_set = 1;
5916       else
5917         break;
5918     }
5919
5920   if (sw_if_index_set == 0)
5921     {
5922       errmsg ("missing interface name or sw_if_index");
5923       return -99;
5924     }
5925   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5926     {
5927       errmsg ("missing rx-mode");
5928       return -99;
5929     }
5930
5931   /* Construct the API message */
5932   M (SW_INTERFACE_SET_RX_MODE, mp);
5933   mp->sw_if_index = ntohl (sw_if_index);
5934   mp->mode = (vl_api_rx_mode_t) mode;
5935   mp->queue_id_valid = queue_id_valid;
5936   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5937
5938   /* send it... */
5939   S (mp);
5940
5941   /* Wait for a reply, return the good/bad news... */
5942   W (ret);
5943   return ret;
5944 }
5945
5946 static int
5947 api_sw_interface_set_rx_placement (vat_main_t * vam)
5948 {
5949   unformat_input_t *i = vam->input;
5950   vl_api_sw_interface_set_rx_placement_t *mp;
5951   u32 sw_if_index;
5952   u8 sw_if_index_set = 0;
5953   int ret;
5954   u8 is_main = 0;
5955   u32 queue_id, thread_index;
5956
5957   /* Parse args required to build the message */
5958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5959     {
5960       if (unformat (i, "queue %d", &queue_id))
5961         ;
5962       else if (unformat (i, "main"))
5963         is_main = 1;
5964       else if (unformat (i, "worker %d", &thread_index))
5965         ;
5966       else
5967         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5968         sw_if_index_set = 1;
5969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5970         sw_if_index_set = 1;
5971       else
5972         break;
5973     }
5974
5975   if (sw_if_index_set == 0)
5976     {
5977       errmsg ("missing interface name or sw_if_index");
5978       return -99;
5979     }
5980
5981   if (is_main)
5982     thread_index = 0;
5983   /* Construct the API message */
5984   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5985   mp->sw_if_index = ntohl (sw_if_index);
5986   mp->worker_id = ntohl (thread_index);
5987   mp->queue_id = ntohl (queue_id);
5988   mp->is_main = is_main;
5989
5990   /* send it... */
5991   S (mp);
5992   /* Wait for a reply, return the good/bad news... */
5993   W (ret);
5994   return ret;
5995 }
5996
5997 static void vl_api_sw_interface_rx_placement_details_t_handler
5998   (vl_api_sw_interface_rx_placement_details_t * mp)
5999 {
6000   vat_main_t *vam = &vat_main;
6001   u32 worker_id = ntohl (mp->worker_id);
6002
6003   print (vam->ofp,
6004          "\n%-11d %-11s %-6d %-5d %-9s",
6005          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6006          worker_id, ntohl (mp->queue_id),
6007          (mp->mode ==
6008           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6009 }
6010
6011 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6012   (vl_api_sw_interface_rx_placement_details_t * mp)
6013 {
6014   vat_main_t *vam = &vat_main;
6015   vat_json_node_t *node = NULL;
6016
6017   if (VAT_JSON_ARRAY != vam->json_tree.type)
6018     {
6019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6020       vat_json_init_array (&vam->json_tree);
6021     }
6022   node = vat_json_array_add (&vam->json_tree);
6023
6024   vat_json_init_object (node);
6025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6026   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6027   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6028   vat_json_object_add_uint (node, "mode", mp->mode);
6029 }
6030
6031 static int
6032 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6033 {
6034   unformat_input_t *i = vam->input;
6035   vl_api_sw_interface_rx_placement_dump_t *mp;
6036   vl_api_control_ping_t *mp_ping;
6037   int ret;
6038   u32 sw_if_index;
6039   u8 sw_if_index_set = 0;
6040
6041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6042     {
6043       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6044         sw_if_index_set++;
6045       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6046         sw_if_index_set++;
6047       else
6048         break;
6049     }
6050
6051   print (vam->ofp,
6052          "\n%-11s %-11s %-6s %-5s %-4s",
6053          "sw_if_index", "main/worker", "thread", "queue", "mode");
6054
6055   /* Dump Interface rx placement */
6056   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6057
6058   if (sw_if_index_set)
6059     mp->sw_if_index = htonl (sw_if_index);
6060   else
6061     mp->sw_if_index = ~0;
6062
6063   S (mp);
6064
6065   /* Use a control ping for synchronization */
6066   MPING (CONTROL_PING, mp_ping);
6067   S (mp_ping);
6068
6069   W (ret);
6070   return ret;
6071 }
6072
6073 static int
6074 api_sw_interface_clear_stats (vat_main_t * vam)
6075 {
6076   unformat_input_t *i = vam->input;
6077   vl_api_sw_interface_clear_stats_t *mp;
6078   u32 sw_if_index;
6079   u8 sw_if_index_set = 0;
6080   int ret;
6081
6082   /* Parse args required to build the message */
6083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6084     {
6085       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6086         sw_if_index_set = 1;
6087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6088         sw_if_index_set = 1;
6089       else
6090         break;
6091     }
6092
6093   /* Construct the API message */
6094   M (SW_INTERFACE_CLEAR_STATS, mp);
6095
6096   if (sw_if_index_set == 1)
6097     mp->sw_if_index = ntohl (sw_if_index);
6098   else
6099     mp->sw_if_index = ~0;
6100
6101   /* send it... */
6102   S (mp);
6103
6104   /* Wait for a reply, return the good/bad news... */
6105   W (ret);
6106   return ret;
6107 }
6108
6109 static int
6110 api_sw_interface_add_del_address (vat_main_t * vam)
6111 {
6112   unformat_input_t *i = vam->input;
6113   vl_api_sw_interface_add_del_address_t *mp;
6114   u32 sw_if_index;
6115   u8 sw_if_index_set = 0;
6116   u8 is_add = 1, del_all = 0;
6117   u32 address_length = 0;
6118   u8 v4_address_set = 0;
6119   u8 v6_address_set = 0;
6120   ip4_address_t v4address;
6121   ip6_address_t v6address;
6122   int ret;
6123
6124   /* Parse args required to build the message */
6125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6126     {
6127       if (unformat (i, "del-all"))
6128         del_all = 1;
6129       else if (unformat (i, "del"))
6130         is_add = 0;
6131       else
6132         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6133         sw_if_index_set = 1;
6134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6135         sw_if_index_set = 1;
6136       else if (unformat (i, "%U/%d",
6137                          unformat_ip4_address, &v4address, &address_length))
6138         v4_address_set = 1;
6139       else if (unformat (i, "%U/%d",
6140                          unformat_ip6_address, &v6address, &address_length))
6141         v6_address_set = 1;
6142       else
6143         break;
6144     }
6145
6146   if (sw_if_index_set == 0)
6147     {
6148       errmsg ("missing interface name or sw_if_index");
6149       return -99;
6150     }
6151   if (v4_address_set && v6_address_set)
6152     {
6153       errmsg ("both v4 and v6 addresses set");
6154       return -99;
6155     }
6156   if (!v4_address_set && !v6_address_set && !del_all)
6157     {
6158       errmsg ("no addresses set");
6159       return -99;
6160     }
6161
6162   /* Construct the API message */
6163   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6164
6165   mp->sw_if_index = ntohl (sw_if_index);
6166   mp->is_add = is_add;
6167   mp->del_all = del_all;
6168   if (v6_address_set)
6169     {
6170       mp->prefix.address.af = ADDRESS_IP6;
6171       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6172     }
6173   else
6174     {
6175       mp->prefix.address.af = ADDRESS_IP4;
6176       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6177     }
6178   mp->prefix.len = address_length;
6179
6180   /* send it... */
6181   S (mp);
6182
6183   /* Wait for a reply, return good/bad news  */
6184   W (ret);
6185   return ret;
6186 }
6187
6188 static int
6189 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6190 {
6191   unformat_input_t *i = vam->input;
6192   vl_api_sw_interface_set_mpls_enable_t *mp;
6193   u32 sw_if_index;
6194   u8 sw_if_index_set = 0;
6195   u8 enable = 1;
6196   int ret;
6197
6198   /* Parse args required to build the message */
6199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6200     {
6201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6202         sw_if_index_set = 1;
6203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6204         sw_if_index_set = 1;
6205       else if (unformat (i, "disable"))
6206         enable = 0;
6207       else if (unformat (i, "dis"))
6208         enable = 0;
6209       else
6210         break;
6211     }
6212
6213   if (sw_if_index_set == 0)
6214     {
6215       errmsg ("missing interface name or sw_if_index");
6216       return -99;
6217     }
6218
6219   /* Construct the API message */
6220   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6221
6222   mp->sw_if_index = ntohl (sw_if_index);
6223   mp->enable = enable;
6224
6225   /* send it... */
6226   S (mp);
6227
6228   /* Wait for a reply... */
6229   W (ret);
6230   return ret;
6231 }
6232
6233 static int
6234 api_sw_interface_set_table (vat_main_t * vam)
6235 {
6236   unformat_input_t *i = vam->input;
6237   vl_api_sw_interface_set_table_t *mp;
6238   u32 sw_if_index, vrf_id = 0;
6239   u8 sw_if_index_set = 0;
6240   u8 is_ipv6 = 0;
6241   int ret;
6242
6243   /* Parse args required to build the message */
6244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6245     {
6246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6247         sw_if_index_set = 1;
6248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6249         sw_if_index_set = 1;
6250       else if (unformat (i, "vrf %d", &vrf_id))
6251         ;
6252       else if (unformat (i, "ipv6"))
6253         is_ipv6 = 1;
6254       else
6255         break;
6256     }
6257
6258   if (sw_if_index_set == 0)
6259     {
6260       errmsg ("missing interface name or sw_if_index");
6261       return -99;
6262     }
6263
6264   /* Construct the API message */
6265   M (SW_INTERFACE_SET_TABLE, mp);
6266
6267   mp->sw_if_index = ntohl (sw_if_index);
6268   mp->is_ipv6 = is_ipv6;
6269   mp->vrf_id = ntohl (vrf_id);
6270
6271   /* send it... */
6272   S (mp);
6273
6274   /* Wait for a reply... */
6275   W (ret);
6276   return ret;
6277 }
6278
6279 static void vl_api_sw_interface_get_table_reply_t_handler
6280   (vl_api_sw_interface_get_table_reply_t * mp)
6281 {
6282   vat_main_t *vam = &vat_main;
6283
6284   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6285
6286   vam->retval = ntohl (mp->retval);
6287   vam->result_ready = 1;
6288
6289 }
6290
6291 static void vl_api_sw_interface_get_table_reply_t_handler_json
6292   (vl_api_sw_interface_get_table_reply_t * mp)
6293 {
6294   vat_main_t *vam = &vat_main;
6295   vat_json_node_t node;
6296
6297   vat_json_init_object (&node);
6298   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6299   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6300
6301   vat_json_print (vam->ofp, &node);
6302   vat_json_free (&node);
6303
6304   vam->retval = ntohl (mp->retval);
6305   vam->result_ready = 1;
6306 }
6307
6308 static int
6309 api_sw_interface_get_table (vat_main_t * vam)
6310 {
6311   unformat_input_t *i = vam->input;
6312   vl_api_sw_interface_get_table_t *mp;
6313   u32 sw_if_index;
6314   u8 sw_if_index_set = 0;
6315   u8 is_ipv6 = 0;
6316   int ret;
6317
6318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6319     {
6320       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6321         sw_if_index_set = 1;
6322       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6323         sw_if_index_set = 1;
6324       else if (unformat (i, "ipv6"))
6325         is_ipv6 = 1;
6326       else
6327         break;
6328     }
6329
6330   if (sw_if_index_set == 0)
6331     {
6332       errmsg ("missing interface name or sw_if_index");
6333       return -99;
6334     }
6335
6336   M (SW_INTERFACE_GET_TABLE, mp);
6337   mp->sw_if_index = htonl (sw_if_index);
6338   mp->is_ipv6 = is_ipv6;
6339
6340   S (mp);
6341   W (ret);
6342   return ret;
6343 }
6344
6345 static int
6346 api_sw_interface_set_vpath (vat_main_t * vam)
6347 {
6348   unformat_input_t *i = vam->input;
6349   vl_api_sw_interface_set_vpath_t *mp;
6350   u32 sw_if_index = 0;
6351   u8 sw_if_index_set = 0;
6352   u8 is_enable = 0;
6353   int ret;
6354
6355   /* Parse args required to build the message */
6356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6357     {
6358       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6359         sw_if_index_set = 1;
6360       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6361         sw_if_index_set = 1;
6362       else if (unformat (i, "enable"))
6363         is_enable = 1;
6364       else if (unformat (i, "disable"))
6365         is_enable = 0;
6366       else
6367         break;
6368     }
6369
6370   if (sw_if_index_set == 0)
6371     {
6372       errmsg ("missing interface name or sw_if_index");
6373       return -99;
6374     }
6375
6376   /* Construct the API message */
6377   M (SW_INTERFACE_SET_VPATH, mp);
6378
6379   mp->sw_if_index = ntohl (sw_if_index);
6380   mp->enable = is_enable;
6381
6382   /* send it... */
6383   S (mp);
6384
6385   /* Wait for a reply... */
6386   W (ret);
6387   return ret;
6388 }
6389
6390 static int
6391 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6392 {
6393   unformat_input_t *i = vam->input;
6394   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6395   u32 sw_if_index = 0;
6396   u8 sw_if_index_set = 0;
6397   u8 is_enable = 1;
6398   u8 is_ipv6 = 0;
6399   int ret;
6400
6401   /* Parse args required to build the message */
6402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6403     {
6404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6405         sw_if_index_set = 1;
6406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6407         sw_if_index_set = 1;
6408       else if (unformat (i, "enable"))
6409         is_enable = 1;
6410       else if (unformat (i, "disable"))
6411         is_enable = 0;
6412       else if (unformat (i, "ip4"))
6413         is_ipv6 = 0;
6414       else if (unformat (i, "ip6"))
6415         is_ipv6 = 1;
6416       else
6417         break;
6418     }
6419
6420   if (sw_if_index_set == 0)
6421     {
6422       errmsg ("missing interface name or sw_if_index");
6423       return -99;
6424     }
6425
6426   /* Construct the API message */
6427   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6428
6429   mp->sw_if_index = ntohl (sw_if_index);
6430   mp->enable = is_enable;
6431   mp->is_ipv6 = is_ipv6;
6432
6433   /* send it... */
6434   S (mp);
6435
6436   /* Wait for a reply... */
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_sw_interface_set_geneve_bypass_t *mp;
6446   u32 sw_if_index = 0;
6447   u8 sw_if_index_set = 0;
6448   u8 is_enable = 1;
6449   u8 is_ipv6 = 0;
6450   int ret;
6451
6452   /* Parse args required to build the message */
6453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6454     {
6455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6456         sw_if_index_set = 1;
6457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "enable"))
6460         is_enable = 1;
6461       else if (unformat (i, "disable"))
6462         is_enable = 0;
6463       else if (unformat (i, "ip4"))
6464         is_ipv6 = 0;
6465       else if (unformat (i, "ip6"))
6466         is_ipv6 = 1;
6467       else
6468         break;
6469     }
6470
6471   if (sw_if_index_set == 0)
6472     {
6473       errmsg ("missing interface name or sw_if_index");
6474       return -99;
6475     }
6476
6477   /* Construct the API message */
6478   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6479
6480   mp->sw_if_index = ntohl (sw_if_index);
6481   mp->enable = is_enable;
6482   mp->is_ipv6 = is_ipv6;
6483
6484   /* send it... */
6485   S (mp);
6486
6487   /* Wait for a reply... */
6488   W (ret);
6489   return ret;
6490 }
6491
6492 static int
6493 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6494 {
6495   unformat_input_t *i = vam->input;
6496   vl_api_sw_interface_set_l2_xconnect_t *mp;
6497   u32 rx_sw_if_index;
6498   u8 rx_sw_if_index_set = 0;
6499   u32 tx_sw_if_index;
6500   u8 tx_sw_if_index_set = 0;
6501   u8 enable = 1;
6502   int ret;
6503
6504   /* Parse args required to build the message */
6505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6506     {
6507       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6508         rx_sw_if_index_set = 1;
6509       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6510         tx_sw_if_index_set = 1;
6511       else if (unformat (i, "rx"))
6512         {
6513           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6514             {
6515               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6516                             &rx_sw_if_index))
6517                 rx_sw_if_index_set = 1;
6518             }
6519           else
6520             break;
6521         }
6522       else if (unformat (i, "tx"))
6523         {
6524           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6525             {
6526               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6527                             &tx_sw_if_index))
6528                 tx_sw_if_index_set = 1;
6529             }
6530           else
6531             break;
6532         }
6533       else if (unformat (i, "enable"))
6534         enable = 1;
6535       else if (unformat (i, "disable"))
6536         enable = 0;
6537       else
6538         break;
6539     }
6540
6541   if (rx_sw_if_index_set == 0)
6542     {
6543       errmsg ("missing rx interface name or rx_sw_if_index");
6544       return -99;
6545     }
6546
6547   if (enable && (tx_sw_if_index_set == 0))
6548     {
6549       errmsg ("missing tx interface name or tx_sw_if_index");
6550       return -99;
6551     }
6552
6553   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6554
6555   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6556   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6557   mp->enable = enable;
6558
6559   S (mp);
6560   W (ret);
6561   return ret;
6562 }
6563
6564 static int
6565 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6566 {
6567   unformat_input_t *i = vam->input;
6568   vl_api_sw_interface_set_l2_bridge_t *mp;
6569   vl_api_l2_port_type_t port_type;
6570   u32 rx_sw_if_index;
6571   u8 rx_sw_if_index_set = 0;
6572   u32 bd_id;
6573   u8 bd_id_set = 0;
6574   u32 shg = 0;
6575   u8 enable = 1;
6576   int ret;
6577
6578   port_type = L2_API_PORT_TYPE_NORMAL;
6579
6580   /* Parse args required to build the message */
6581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6582     {
6583       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6584         rx_sw_if_index_set = 1;
6585       else if (unformat (i, "bd_id %d", &bd_id))
6586         bd_id_set = 1;
6587       else
6588         if (unformat
6589             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6590         rx_sw_if_index_set = 1;
6591       else if (unformat (i, "shg %d", &shg))
6592         ;
6593       else if (unformat (i, "bvi"))
6594         port_type = L2_API_PORT_TYPE_BVI;
6595       else if (unformat (i, "uu-fwd"))
6596         port_type = L2_API_PORT_TYPE_UU_FWD;
6597       else if (unformat (i, "enable"))
6598         enable = 1;
6599       else if (unformat (i, "disable"))
6600         enable = 0;
6601       else
6602         break;
6603     }
6604
6605   if (rx_sw_if_index_set == 0)
6606     {
6607       errmsg ("missing rx interface name or sw_if_index");
6608       return -99;
6609     }
6610
6611   if (enable && (bd_id_set == 0))
6612     {
6613       errmsg ("missing bridge domain");
6614       return -99;
6615     }
6616
6617   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6618
6619   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6620   mp->bd_id = ntohl (bd_id);
6621   mp->shg = (u8) shg;
6622   mp->port_type = ntohl (port_type);
6623   mp->enable = enable;
6624
6625   S (mp);
6626   W (ret);
6627   return ret;
6628 }
6629
6630 static int
6631 api_bridge_domain_dump (vat_main_t * vam)
6632 {
6633   unformat_input_t *i = vam->input;
6634   vl_api_bridge_domain_dump_t *mp;
6635   vl_api_control_ping_t *mp_ping;
6636   u32 bd_id = ~0;
6637   int ret;
6638
6639   /* Parse args required to build the message */
6640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6641     {
6642       if (unformat (i, "bd_id %d", &bd_id))
6643         ;
6644       else
6645         break;
6646     }
6647
6648   M (BRIDGE_DOMAIN_DUMP, mp);
6649   mp->bd_id = ntohl (bd_id);
6650   S (mp);
6651
6652   /* Use a control ping for synchronization */
6653   MPING (CONTROL_PING, mp_ping);
6654   S (mp_ping);
6655
6656   W (ret);
6657   return ret;
6658 }
6659
6660 static int
6661 api_bridge_domain_add_del (vat_main_t * vam)
6662 {
6663   unformat_input_t *i = vam->input;
6664   vl_api_bridge_domain_add_del_t *mp;
6665   u32 bd_id = ~0;
6666   u8 is_add = 1;
6667   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6668   u8 *bd_tag = NULL;
6669   u32 mac_age = 0;
6670   int ret;
6671
6672   /* Parse args required to build the message */
6673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6674     {
6675       if (unformat (i, "bd_id %d", &bd_id))
6676         ;
6677       else if (unformat (i, "flood %d", &flood))
6678         ;
6679       else if (unformat (i, "uu-flood %d", &uu_flood))
6680         ;
6681       else if (unformat (i, "forward %d", &forward))
6682         ;
6683       else if (unformat (i, "learn %d", &learn))
6684         ;
6685       else if (unformat (i, "arp-term %d", &arp_term))
6686         ;
6687       else if (unformat (i, "mac-age %d", &mac_age))
6688         ;
6689       else if (unformat (i, "bd-tag %s", &bd_tag))
6690         ;
6691       else if (unformat (i, "del"))
6692         {
6693           is_add = 0;
6694           flood = uu_flood = forward = learn = 0;
6695         }
6696       else
6697         break;
6698     }
6699
6700   if (bd_id == ~0)
6701     {
6702       errmsg ("missing bridge domain");
6703       ret = -99;
6704       goto done;
6705     }
6706
6707   if (mac_age > 255)
6708     {
6709       errmsg ("mac age must be less than 256 ");
6710       ret = -99;
6711       goto done;
6712     }
6713
6714   if ((bd_tag) && (vec_len (bd_tag) > 63))
6715     {
6716       errmsg ("bd-tag cannot be longer than 63");
6717       ret = -99;
6718       goto done;
6719     }
6720
6721   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6722
6723   mp->bd_id = ntohl (bd_id);
6724   mp->flood = flood;
6725   mp->uu_flood = uu_flood;
6726   mp->forward = forward;
6727   mp->learn = learn;
6728   mp->arp_term = arp_term;
6729   mp->is_add = is_add;
6730   mp->mac_age = (u8) mac_age;
6731   if (bd_tag)
6732     {
6733       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6734       mp->bd_tag[vec_len (bd_tag)] = 0;
6735     }
6736   S (mp);
6737   W (ret);
6738
6739 done:
6740   vec_free (bd_tag);
6741   return ret;
6742 }
6743
6744 static int
6745 api_l2fib_flush_bd (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_l2fib_flush_bd_t *mp;
6749   u32 bd_id = ~0;
6750   int ret;
6751
6752   /* Parse args required to build the message */
6753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6754     {
6755       if (unformat (i, "bd_id %d", &bd_id));
6756       else
6757         break;
6758     }
6759
6760   if (bd_id == ~0)
6761     {
6762       errmsg ("missing bridge domain");
6763       return -99;
6764     }
6765
6766   M (L2FIB_FLUSH_BD, mp);
6767
6768   mp->bd_id = htonl (bd_id);
6769
6770   S (mp);
6771   W (ret);
6772   return ret;
6773 }
6774
6775 static int
6776 api_l2fib_flush_int (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_l2fib_flush_int_t *mp;
6780   u32 sw_if_index = ~0;
6781   int ret;
6782
6783   /* Parse args required to build the message */
6784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6785     {
6786       if (unformat (i, "sw_if_index %d", &sw_if_index));
6787       else
6788         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6789       else
6790         break;
6791     }
6792
6793   if (sw_if_index == ~0)
6794     {
6795       errmsg ("missing interface name or sw_if_index");
6796       return -99;
6797     }
6798
6799   M (L2FIB_FLUSH_INT, mp);
6800
6801   mp->sw_if_index = ntohl (sw_if_index);
6802
6803   S (mp);
6804   W (ret);
6805   return ret;
6806 }
6807
6808 static int
6809 api_l2fib_add_del (vat_main_t * vam)
6810 {
6811   unformat_input_t *i = vam->input;
6812   vl_api_l2fib_add_del_t *mp;
6813   f64 timeout;
6814   u8 mac[6] = { 0 };
6815   u8 mac_set = 0;
6816   u32 bd_id;
6817   u8 bd_id_set = 0;
6818   u32 sw_if_index = 0;
6819   u8 sw_if_index_set = 0;
6820   u8 is_add = 1;
6821   u8 static_mac = 0;
6822   u8 filter_mac = 0;
6823   u8 bvi_mac = 0;
6824   int count = 1;
6825   f64 before = 0;
6826   int j;
6827
6828   /* Parse args required to build the message */
6829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6830     {
6831       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6832         mac_set = 1;
6833       else if (unformat (i, "bd_id %d", &bd_id))
6834         bd_id_set = 1;
6835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6836         sw_if_index_set = 1;
6837       else if (unformat (i, "sw_if"))
6838         {
6839           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6840             {
6841               if (unformat
6842                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6843                 sw_if_index_set = 1;
6844             }
6845           else
6846             break;
6847         }
6848       else if (unformat (i, "static"))
6849         static_mac = 1;
6850       else if (unformat (i, "filter"))
6851         {
6852           filter_mac = 1;
6853           static_mac = 1;
6854         }
6855       else if (unformat (i, "bvi"))
6856         {
6857           bvi_mac = 1;
6858           static_mac = 1;
6859         }
6860       else if (unformat (i, "del"))
6861         is_add = 0;
6862       else if (unformat (i, "count %d", &count))
6863         ;
6864       else
6865         break;
6866     }
6867
6868   if (mac_set == 0)
6869     {
6870       errmsg ("missing mac address");
6871       return -99;
6872     }
6873
6874   if (bd_id_set == 0)
6875     {
6876       errmsg ("missing bridge domain");
6877       return -99;
6878     }
6879
6880   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6881     {
6882       errmsg ("missing interface name or sw_if_index");
6883       return -99;
6884     }
6885
6886   if (count > 1)
6887     {
6888       /* Turn on async mode */
6889       vam->async_mode = 1;
6890       vam->async_errors = 0;
6891       before = vat_time_now (vam);
6892     }
6893
6894   for (j = 0; j < count; j++)
6895     {
6896       M (L2FIB_ADD_DEL, mp);
6897
6898       clib_memcpy (mp->mac, mac, 6);
6899       mp->bd_id = ntohl (bd_id);
6900       mp->is_add = is_add;
6901       mp->sw_if_index = ntohl (sw_if_index);
6902
6903       if (is_add)
6904         {
6905           mp->static_mac = static_mac;
6906           mp->filter_mac = filter_mac;
6907           mp->bvi_mac = bvi_mac;
6908         }
6909       increment_mac_address (mac);
6910       /* send it... */
6911       S (mp);
6912     }
6913
6914   if (count > 1)
6915     {
6916       vl_api_control_ping_t *mp_ping;
6917       f64 after;
6918
6919       /* Shut off async mode */
6920       vam->async_mode = 0;
6921
6922       MPING (CONTROL_PING, mp_ping);
6923       S (mp_ping);
6924
6925       timeout = vat_time_now (vam) + 1.0;
6926       while (vat_time_now (vam) < timeout)
6927         if (vam->result_ready == 1)
6928           goto out;
6929       vam->retval = -99;
6930
6931     out:
6932       if (vam->retval == -99)
6933         errmsg ("timeout");
6934
6935       if (vam->async_errors > 0)
6936         {
6937           errmsg ("%d asynchronous errors", vam->async_errors);
6938           vam->retval = -98;
6939         }
6940       vam->async_errors = 0;
6941       after = vat_time_now (vam);
6942
6943       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6944              count, after - before, count / (after - before));
6945     }
6946   else
6947     {
6948       int ret;
6949
6950       /* Wait for a reply... */
6951       W (ret);
6952       return ret;
6953     }
6954   /* Return the good/bad news */
6955   return (vam->retval);
6956 }
6957
6958 static int
6959 api_bridge_domain_set_mac_age (vat_main_t * vam)
6960 {
6961   unformat_input_t *i = vam->input;
6962   vl_api_bridge_domain_set_mac_age_t *mp;
6963   u32 bd_id = ~0;
6964   u32 mac_age = 0;
6965   int ret;
6966
6967   /* Parse args required to build the message */
6968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6969     {
6970       if (unformat (i, "bd_id %d", &bd_id));
6971       else if (unformat (i, "mac-age %d", &mac_age));
6972       else
6973         break;
6974     }
6975
6976   if (bd_id == ~0)
6977     {
6978       errmsg ("missing bridge domain");
6979       return -99;
6980     }
6981
6982   if (mac_age > 255)
6983     {
6984       errmsg ("mac age must be less than 256 ");
6985       return -99;
6986     }
6987
6988   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6989
6990   mp->bd_id = htonl (bd_id);
6991   mp->mac_age = (u8) mac_age;
6992
6993   S (mp);
6994   W (ret);
6995   return ret;
6996 }
6997
6998 static int
6999 api_l2_flags (vat_main_t * vam)
7000 {
7001   unformat_input_t *i = vam->input;
7002   vl_api_l2_flags_t *mp;
7003   u32 sw_if_index;
7004   u32 flags = 0;
7005   u8 sw_if_index_set = 0;
7006   u8 is_set = 0;
7007   int ret;
7008
7009   /* Parse args required to build the message */
7010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7011     {
7012       if (unformat (i, "sw_if_index %d", &sw_if_index))
7013         sw_if_index_set = 1;
7014       else if (unformat (i, "sw_if"))
7015         {
7016           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017             {
7018               if (unformat
7019                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7020                 sw_if_index_set = 1;
7021             }
7022           else
7023             break;
7024         }
7025       else if (unformat (i, "learn"))
7026         flags |= L2_LEARN;
7027       else if (unformat (i, "forward"))
7028         flags |= L2_FWD;
7029       else if (unformat (i, "flood"))
7030         flags |= L2_FLOOD;
7031       else if (unformat (i, "uu-flood"))
7032         flags |= L2_UU_FLOOD;
7033       else if (unformat (i, "arp-term"))
7034         flags |= L2_ARP_TERM;
7035       else if (unformat (i, "off"))
7036         is_set = 0;
7037       else if (unformat (i, "disable"))
7038         is_set = 0;
7039       else
7040         break;
7041     }
7042
7043   if (sw_if_index_set == 0)
7044     {
7045       errmsg ("missing interface name or sw_if_index");
7046       return -99;
7047     }
7048
7049   M (L2_FLAGS, mp);
7050
7051   mp->sw_if_index = ntohl (sw_if_index);
7052   mp->feature_bitmap = ntohl (flags);
7053   mp->is_set = is_set;
7054
7055   S (mp);
7056   W (ret);
7057   return ret;
7058 }
7059
7060 static int
7061 api_bridge_flags (vat_main_t * vam)
7062 {
7063   unformat_input_t *i = vam->input;
7064   vl_api_bridge_flags_t *mp;
7065   u32 bd_id;
7066   u8 bd_id_set = 0;
7067   u8 is_set = 1;
7068   bd_flags_t flags = 0;
7069   int ret;
7070
7071   /* Parse args required to build the message */
7072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7073     {
7074       if (unformat (i, "bd_id %d", &bd_id))
7075         bd_id_set = 1;
7076       else if (unformat (i, "learn"))
7077         flags |= BRIDGE_API_FLAG_LEARN;
7078       else if (unformat (i, "forward"))
7079         flags |= BRIDGE_API_FLAG_FWD;
7080       else if (unformat (i, "flood"))
7081         flags |= BRIDGE_API_FLAG_FLOOD;
7082       else if (unformat (i, "uu-flood"))
7083         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7084       else if (unformat (i, "arp-term"))
7085         flags |= BRIDGE_API_FLAG_ARP_TERM;
7086       else if (unformat (i, "off"))
7087         is_set = 0;
7088       else if (unformat (i, "disable"))
7089         is_set = 0;
7090       else
7091         break;
7092     }
7093
7094   if (bd_id_set == 0)
7095     {
7096       errmsg ("missing bridge domain");
7097       return -99;
7098     }
7099
7100   M (BRIDGE_FLAGS, mp);
7101
7102   mp->bd_id = ntohl (bd_id);
7103   mp->flags = ntohl (flags);
7104   mp->is_set = is_set;
7105
7106   S (mp);
7107   W (ret);
7108   return ret;
7109 }
7110
7111 static int
7112 api_bd_ip_mac_add_del (vat_main_t * vam)
7113 {
7114   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7115   vl_api_mac_address_t mac = { 0 };
7116   unformat_input_t *i = vam->input;
7117   vl_api_bd_ip_mac_add_del_t *mp;
7118   u32 bd_id;
7119   u8 is_add = 1;
7120   u8 bd_id_set = 0;
7121   u8 ip_set = 0;
7122   u8 mac_set = 0;
7123   int ret;
7124
7125
7126   /* Parse args required to build the message */
7127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7128     {
7129       if (unformat (i, "bd_id %d", &bd_id))
7130         {
7131           bd_id_set++;
7132         }
7133       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7134         {
7135           ip_set++;
7136         }
7137       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7138         {
7139           mac_set++;
7140         }
7141       else if (unformat (i, "del"))
7142         is_add = 0;
7143       else
7144         break;
7145     }
7146
7147   if (bd_id_set == 0)
7148     {
7149       errmsg ("missing bridge domain");
7150       return -99;
7151     }
7152   else if (ip_set == 0)
7153     {
7154       errmsg ("missing IP address");
7155       return -99;
7156     }
7157   else if (mac_set == 0)
7158     {
7159       errmsg ("missing MAC address");
7160       return -99;
7161     }
7162
7163   M (BD_IP_MAC_ADD_DEL, mp);
7164
7165   mp->entry.bd_id = ntohl (bd_id);
7166   mp->is_add = is_add;
7167
7168   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7169   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7170
7171   S (mp);
7172   W (ret);
7173   return ret;
7174 }
7175
7176 static int
7177 api_bd_ip_mac_flush (vat_main_t * vam)
7178 {
7179   unformat_input_t *i = vam->input;
7180   vl_api_bd_ip_mac_flush_t *mp;
7181   u32 bd_id;
7182   u8 bd_id_set = 0;
7183   int ret;
7184
7185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7186     {
7187       if (unformat (i, "bd_id %d", &bd_id))
7188         {
7189           bd_id_set++;
7190         }
7191       else
7192         break;
7193     }
7194
7195   if (bd_id_set == 0)
7196     {
7197       errmsg ("missing bridge domain");
7198       return -99;
7199     }
7200
7201   M (BD_IP_MAC_FLUSH, mp);
7202
7203   mp->bd_id = ntohl (bd_id);
7204
7205   S (mp);
7206   W (ret);
7207   return ret;
7208 }
7209
7210 static void vl_api_bd_ip_mac_details_t_handler
7211   (vl_api_bd_ip_mac_details_t * mp)
7212 {
7213   vat_main_t *vam = &vat_main;
7214
7215   print (vam->ofp,
7216          "\n%-5d %U %U",
7217          ntohl (mp->entry.bd_id),
7218          format_vl_api_mac_address, mp->entry.mac,
7219          format_vl_api_address, &mp->entry.ip);
7220 }
7221
7222 static void vl_api_bd_ip_mac_details_t_handler_json
7223   (vl_api_bd_ip_mac_details_t * mp)
7224 {
7225   vat_main_t *vam = &vat_main;
7226   vat_json_node_t *node = NULL;
7227
7228   if (VAT_JSON_ARRAY != vam->json_tree.type)
7229     {
7230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7231       vat_json_init_array (&vam->json_tree);
7232     }
7233   node = vat_json_array_add (&vam->json_tree);
7234
7235   vat_json_init_object (node);
7236   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7237   vat_json_object_add_string_copy (node, "mac_address",
7238                                    format (0, "%U", format_vl_api_mac_address,
7239                                            &mp->entry.mac));
7240   u8 *ip = 0;
7241
7242   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7243   vat_json_object_add_string_copy (node, "ip_address", ip);
7244   vec_free (ip);
7245 }
7246
7247 static int
7248 api_bd_ip_mac_dump (vat_main_t * vam)
7249 {
7250   unformat_input_t *i = vam->input;
7251   vl_api_bd_ip_mac_dump_t *mp;
7252   vl_api_control_ping_t *mp_ping;
7253   int ret;
7254   u32 bd_id;
7255   u8 bd_id_set = 0;
7256
7257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7258     {
7259       if (unformat (i, "bd_id %d", &bd_id))
7260         {
7261           bd_id_set++;
7262         }
7263       else
7264         break;
7265     }
7266
7267   print (vam->ofp,
7268          "\n%-5s %-7s %-20s %-30s",
7269          "bd_id", "is_ipv6", "mac_address", "ip_address");
7270
7271   /* Dump Bridge Domain Ip to Mac entries */
7272   M (BD_IP_MAC_DUMP, mp);
7273
7274   if (bd_id_set)
7275     mp->bd_id = htonl (bd_id);
7276   else
7277     mp->bd_id = ~0;
7278
7279   S (mp);
7280
7281   /* Use a control ping for synchronization */
7282   MPING (CONTROL_PING, mp_ping);
7283   S (mp_ping);
7284
7285   W (ret);
7286   return ret;
7287 }
7288
7289 static int
7290 api_tap_create_v2 (vat_main_t * vam)
7291 {
7292   unformat_input_t *i = vam->input;
7293   vl_api_tap_create_v2_t *mp;
7294   u8 mac_address[6];
7295   u8 random_mac = 1;
7296   u32 id = ~0;
7297   u32 num_rx_queues = 0;
7298   u8 *host_if_name = 0;
7299   u8 host_if_name_set = 0;
7300   u8 *host_ns = 0;
7301   u8 host_ns_set = 0;
7302   u8 host_mac_addr[6];
7303   u8 host_mac_addr_set = 0;
7304   u8 *host_bridge = 0;
7305   u8 host_bridge_set = 0;
7306   u8 host_ip4_prefix_set = 0;
7307   u8 host_ip6_prefix_set = 0;
7308   ip4_address_t host_ip4_addr;
7309   ip4_address_t host_ip4_gw;
7310   u8 host_ip4_gw_set = 0;
7311   u32 host_ip4_prefix_len = 0;
7312   ip6_address_t host_ip6_addr;
7313   ip6_address_t host_ip6_gw;
7314   u8 host_ip6_gw_set = 0;
7315   u32 host_ip6_prefix_len = 0;
7316   u32 host_mtu_size = 0;
7317   u8 host_mtu_set = 0;
7318   u32 tap_flags = 0;
7319   int ret;
7320   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7321
7322   clib_memset (mac_address, 0, sizeof (mac_address));
7323
7324   /* Parse args required to build the message */
7325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7326     {
7327       if (unformat (i, "id %u", &id))
7328         ;
7329       else
7330         if (unformat
7331             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7332         random_mac = 0;
7333       else if (unformat (i, "host-if-name %s", &host_if_name))
7334         host_if_name_set = 1;
7335       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7336         ;
7337       else if (unformat (i, "host-ns %s", &host_ns))
7338         host_ns_set = 1;
7339       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7340                          host_mac_addr))
7341         host_mac_addr_set = 1;
7342       else if (unformat (i, "host-bridge %s", &host_bridge))
7343         host_bridge_set = 1;
7344       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7345                          &host_ip4_addr, &host_ip4_prefix_len))
7346         host_ip4_prefix_set = 1;
7347       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7348                          &host_ip6_addr, &host_ip6_prefix_len))
7349         host_ip6_prefix_set = 1;
7350       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7351                          &host_ip4_gw))
7352         host_ip4_gw_set = 1;
7353       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7354                          &host_ip6_gw))
7355         host_ip6_gw_set = 1;
7356       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7357         ;
7358       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7359         ;
7360       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7361         host_mtu_set = 1;
7362       else if (unformat (i, "no-gso"))
7363         tap_flags &= ~TAP_FLAG_GSO;
7364       else if (unformat (i, "gso"))
7365         tap_flags |= TAP_FLAG_GSO;
7366       else if (unformat (i, "csum-offload"))
7367         tap_flags |= TAP_FLAG_CSUM_OFFLOAD;
7368       else if (unformat (i, "persist"))
7369         tap_flags |= TAP_FLAG_PERSIST;
7370       else if (unformat (i, "attach"))
7371         tap_flags |= TAP_FLAG_ATTACH;
7372       else
7373         break;
7374     }
7375
7376   if (vec_len (host_if_name) > 63)
7377     {
7378       errmsg ("tap name too long. ");
7379       return -99;
7380     }
7381   if (vec_len (host_ns) > 63)
7382     {
7383       errmsg ("host name space too long. ");
7384       return -99;
7385     }
7386   if (vec_len (host_bridge) > 63)
7387     {
7388       errmsg ("host bridge name too long. ");
7389       return -99;
7390     }
7391   if (host_ip4_prefix_len > 32)
7392     {
7393       errmsg ("host ip4 prefix length not valid. ");
7394       return -99;
7395     }
7396   if (host_ip6_prefix_len > 128)
7397     {
7398       errmsg ("host ip6 prefix length not valid. ");
7399       return -99;
7400     }
7401   if (!is_pow2 (rx_ring_sz))
7402     {
7403       errmsg ("rx ring size must be power of 2. ");
7404       return -99;
7405     }
7406   if (rx_ring_sz > 32768)
7407     {
7408       errmsg ("rx ring size must be 32768 or lower. ");
7409       return -99;
7410     }
7411   if (!is_pow2 (tx_ring_sz))
7412     {
7413       errmsg ("tx ring size must be power of 2. ");
7414       return -99;
7415     }
7416   if (tx_ring_sz > 32768)
7417     {
7418       errmsg ("tx ring size must be 32768 or lower. ");
7419       return -99;
7420     }
7421   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7422     {
7423       errmsg ("host MTU size must be in between 64 and 65355. ");
7424       return -99;
7425     }
7426
7427   /* Construct the API message */
7428   M (TAP_CREATE_V2, mp);
7429
7430   mp->id = ntohl (id);
7431   mp->use_random_mac = random_mac;
7432   mp->num_rx_queues = (u8) num_rx_queues;
7433   mp->tx_ring_sz = ntohs (tx_ring_sz);
7434   mp->rx_ring_sz = ntohs (rx_ring_sz);
7435   mp->host_mtu_set = host_mtu_set;
7436   mp->host_mtu_size = ntohl (host_mtu_size);
7437   mp->host_mac_addr_set = host_mac_addr_set;
7438   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7439   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7440   mp->host_ip4_gw_set = host_ip4_gw_set;
7441   mp->host_ip6_gw_set = host_ip6_gw_set;
7442   mp->tap_flags = ntohl (tap_flags);
7443   mp->host_namespace_set = host_ns_set;
7444   mp->host_if_name_set = host_if_name_set;
7445   mp->host_bridge_set = host_bridge_set;
7446
7447   if (random_mac == 0)
7448     clib_memcpy (mp->mac_address, mac_address, 6);
7449   if (host_mac_addr_set)
7450     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7451   if (host_if_name_set)
7452     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7453   if (host_ns_set)
7454     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7455   if (host_bridge_set)
7456     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7457   if (host_ip4_prefix_set)
7458     {
7459       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7460       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7461     }
7462   if (host_ip6_prefix_set)
7463     {
7464       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7465       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7466     }
7467   if (host_ip4_gw_set)
7468     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7469   if (host_ip6_gw_set)
7470     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7471
7472   vec_free (host_ns);
7473   vec_free (host_if_name);
7474   vec_free (host_bridge);
7475
7476   /* send it... */
7477   S (mp);
7478
7479   /* Wait for a reply... */
7480   W (ret);
7481   return ret;
7482 }
7483
7484 static int
7485 api_tap_delete_v2 (vat_main_t * vam)
7486 {
7487   unformat_input_t *i = vam->input;
7488   vl_api_tap_delete_v2_t *mp;
7489   u32 sw_if_index = ~0;
7490   u8 sw_if_index_set = 0;
7491   int ret;
7492
7493   /* Parse args required to build the message */
7494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7495     {
7496       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7497         sw_if_index_set = 1;
7498       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7499         sw_if_index_set = 1;
7500       else
7501         break;
7502     }
7503
7504   if (sw_if_index_set == 0)
7505     {
7506       errmsg ("missing vpp interface name. ");
7507       return -99;
7508     }
7509
7510   /* Construct the API message */
7511   M (TAP_DELETE_V2, mp);
7512
7513   mp->sw_if_index = ntohl (sw_if_index);
7514
7515   /* send it... */
7516   S (mp);
7517
7518   /* Wait for a reply... */
7519   W (ret);
7520   return ret;
7521 }
7522
7523 uword
7524 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7525 {
7526   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7527   u32 x[4];
7528
7529   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7530     return 0;
7531
7532   addr->domain = x[0];
7533   addr->bus = x[1];
7534   addr->slot = x[2];
7535   addr->function = x[3];
7536
7537   return 1;
7538 }
7539
7540 static int
7541 api_virtio_pci_create (vat_main_t * vam)
7542 {
7543   unformat_input_t *i = vam->input;
7544   vl_api_virtio_pci_create_t *mp;
7545   u8 mac_address[6];
7546   u8 random_mac = 1;
7547   u8 gso_enabled = 0;
7548   u8 checksum_offload_enabled = 0;
7549   u32 pci_addr = 0;
7550   u64 features = (u64) ~ (0ULL);
7551   int ret;
7552
7553   clib_memset (mac_address, 0, sizeof (mac_address));
7554
7555   /* Parse args required to build the message */
7556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7557     {
7558       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7559         {
7560           random_mac = 0;
7561         }
7562       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7563         ;
7564       else if (unformat (i, "features 0x%llx", &features))
7565         ;
7566       else if (unformat (i, "gso-enabled"))
7567         gso_enabled = 1;
7568       else if (unformat (i, "csum-offload-enabled"))
7569         checksum_offload_enabled = 1;
7570       else
7571         break;
7572     }
7573
7574   if (pci_addr == 0)
7575     {
7576       errmsg ("pci address must be non zero. ");
7577       return -99;
7578     }
7579
7580   /* Construct the API message */
7581   M (VIRTIO_PCI_CREATE, mp);
7582
7583   mp->use_random_mac = random_mac;
7584
7585   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7586   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7587   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7588   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7589
7590   mp->features = clib_host_to_net_u64 (features);
7591   mp->gso_enabled = gso_enabled;
7592   mp->checksum_offload_enabled = checksum_offload_enabled;
7593
7594   if (random_mac == 0)
7595     clib_memcpy (mp->mac_address, mac_address, 6);
7596
7597   /* send it... */
7598   S (mp);
7599
7600   /* Wait for a reply... */
7601   W (ret);
7602   return ret;
7603 }
7604
7605 static int
7606 api_virtio_pci_delete (vat_main_t * vam)
7607 {
7608   unformat_input_t *i = vam->input;
7609   vl_api_virtio_pci_delete_t *mp;
7610   u32 sw_if_index = ~0;
7611   u8 sw_if_index_set = 0;
7612   int ret;
7613
7614   /* Parse args required to build the message */
7615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7616     {
7617       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7618         sw_if_index_set = 1;
7619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7620         sw_if_index_set = 1;
7621       else
7622         break;
7623     }
7624
7625   if (sw_if_index_set == 0)
7626     {
7627       errmsg ("missing vpp interface name. ");
7628       return -99;
7629     }
7630
7631   /* Construct the API message */
7632   M (VIRTIO_PCI_DELETE, mp);
7633
7634   mp->sw_if_index = htonl (sw_if_index);
7635
7636   /* send it... */
7637   S (mp);
7638
7639   /* Wait for a reply... */
7640   W (ret);
7641   return ret;
7642 }
7643
7644 static int
7645 api_bond_create (vat_main_t * vam)
7646 {
7647   unformat_input_t *i = vam->input;
7648   vl_api_bond_create_t *mp;
7649   u8 mac_address[6];
7650   u8 custom_mac = 0;
7651   int ret;
7652   u8 mode;
7653   u8 lb;
7654   u8 mode_is_set = 0;
7655   u32 id = ~0;
7656   u8 numa_only = 0;
7657
7658   clib_memset (mac_address, 0, sizeof (mac_address));
7659   lb = BOND_LB_L2;
7660
7661   /* Parse args required to build the message */
7662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7663     {
7664       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7665         mode_is_set = 1;
7666       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7667                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7668         ;
7669       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7670                          mac_address))
7671         custom_mac = 1;
7672       else if (unformat (i, "numa-only"))
7673         numa_only = 1;
7674       else if (unformat (i, "id %u", &id))
7675         ;
7676       else
7677         break;
7678     }
7679
7680   if (mode_is_set == 0)
7681     {
7682       errmsg ("Missing bond mode. ");
7683       return -99;
7684     }
7685
7686   /* Construct the API message */
7687   M (BOND_CREATE, mp);
7688
7689   mp->use_custom_mac = custom_mac;
7690
7691   mp->mode = htonl (mode);
7692   mp->lb = htonl (lb);
7693   mp->id = htonl (id);
7694   mp->numa_only = numa_only;
7695
7696   if (custom_mac)
7697     clib_memcpy (mp->mac_address, mac_address, 6);
7698
7699   /* send it... */
7700   S (mp);
7701
7702   /* Wait for a reply... */
7703   W (ret);
7704   return ret;
7705 }
7706
7707 static int
7708 api_bond_delete (vat_main_t * vam)
7709 {
7710   unformat_input_t *i = vam->input;
7711   vl_api_bond_delete_t *mp;
7712   u32 sw_if_index = ~0;
7713   u8 sw_if_index_set = 0;
7714   int ret;
7715
7716   /* Parse args required to build the message */
7717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7718     {
7719       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7720         sw_if_index_set = 1;
7721       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7722         sw_if_index_set = 1;
7723       else
7724         break;
7725     }
7726
7727   if (sw_if_index_set == 0)
7728     {
7729       errmsg ("missing vpp interface name. ");
7730       return -99;
7731     }
7732
7733   /* Construct the API message */
7734   M (BOND_DELETE, mp);
7735
7736   mp->sw_if_index = ntohl (sw_if_index);
7737
7738   /* send it... */
7739   S (mp);
7740
7741   /* Wait for a reply... */
7742   W (ret);
7743   return ret;
7744 }
7745
7746 static int
7747 api_bond_enslave (vat_main_t * vam)
7748 {
7749   unformat_input_t *i = vam->input;
7750   vl_api_bond_enslave_t *mp;
7751   u32 bond_sw_if_index;
7752   int ret;
7753   u8 is_passive;
7754   u8 is_long_timeout;
7755   u32 bond_sw_if_index_is_set = 0;
7756   u32 sw_if_index;
7757   u8 sw_if_index_is_set = 0;
7758
7759   /* Parse args required to build the message */
7760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7761     {
7762       if (unformat (i, "sw_if_index %d", &sw_if_index))
7763         sw_if_index_is_set = 1;
7764       else if (unformat (i, "bond %u", &bond_sw_if_index))
7765         bond_sw_if_index_is_set = 1;
7766       else if (unformat (i, "passive %d", &is_passive))
7767         ;
7768       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7769         ;
7770       else
7771         break;
7772     }
7773
7774   if (bond_sw_if_index_is_set == 0)
7775     {
7776       errmsg ("Missing bond sw_if_index. ");
7777       return -99;
7778     }
7779   if (sw_if_index_is_set == 0)
7780     {
7781       errmsg ("Missing slave sw_if_index. ");
7782       return -99;
7783     }
7784
7785   /* Construct the API message */
7786   M (BOND_ENSLAVE, mp);
7787
7788   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7789   mp->sw_if_index = ntohl (sw_if_index);
7790   mp->is_long_timeout = is_long_timeout;
7791   mp->is_passive = is_passive;
7792
7793   /* send it... */
7794   S (mp);
7795
7796   /* Wait for a reply... */
7797   W (ret);
7798   return ret;
7799 }
7800
7801 static int
7802 api_bond_detach_slave (vat_main_t * vam)
7803 {
7804   unformat_input_t *i = vam->input;
7805   vl_api_bond_detach_slave_t *mp;
7806   u32 sw_if_index = ~0;
7807   u8 sw_if_index_set = 0;
7808   int ret;
7809
7810   /* Parse args required to build the message */
7811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7812     {
7813       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7814         sw_if_index_set = 1;
7815       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7816         sw_if_index_set = 1;
7817       else
7818         break;
7819     }
7820
7821   if (sw_if_index_set == 0)
7822     {
7823       errmsg ("missing vpp interface name. ");
7824       return -99;
7825     }
7826
7827   /* Construct the API message */
7828   M (BOND_DETACH_SLAVE, mp);
7829
7830   mp->sw_if_index = ntohl (sw_if_index);
7831
7832   /* send it... */
7833   S (mp);
7834
7835   /* Wait for a reply... */
7836   W (ret);
7837   return ret;
7838 }
7839
7840 static int
7841 api_ip_table_add_del (vat_main_t * vam)
7842 {
7843   unformat_input_t *i = vam->input;
7844   vl_api_ip_table_add_del_t *mp;
7845   u32 table_id = ~0;
7846   u8 is_ipv6 = 0;
7847   u8 is_add = 1;
7848   int ret = 0;
7849
7850   /* Parse args required to build the message */
7851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7852     {
7853       if (unformat (i, "ipv6"))
7854         is_ipv6 = 1;
7855       else if (unformat (i, "del"))
7856         is_add = 0;
7857       else if (unformat (i, "add"))
7858         is_add = 1;
7859       else if (unformat (i, "table %d", &table_id))
7860         ;
7861       else
7862         {
7863           clib_warning ("parse error '%U'", format_unformat_error, i);
7864           return -99;
7865         }
7866     }
7867
7868   if (~0 == table_id)
7869     {
7870       errmsg ("missing table-ID");
7871       return -99;
7872     }
7873
7874   /* Construct the API message */
7875   M (IP_TABLE_ADD_DEL, mp);
7876
7877   mp->table.table_id = ntohl (table_id);
7878   mp->table.is_ip6 = is_ipv6;
7879   mp->is_add = is_add;
7880
7881   /* send it... */
7882   S (mp);
7883
7884   /* Wait for a reply... */
7885   W (ret);
7886
7887   return ret;
7888 }
7889
7890 uword
7891 unformat_fib_path (unformat_input_t * input, va_list * args)
7892 {
7893   vat_main_t *vam = va_arg (*args, vat_main_t *);
7894   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7895   u32 weight, preference;
7896   mpls_label_t out_label;
7897
7898   clib_memset (path, 0, sizeof (*path));
7899   path->weight = 1;
7900   path->sw_if_index = ~0;
7901   path->rpf_id = ~0;
7902   path->n_labels = 0;
7903
7904   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7905     {
7906       if (unformat (input, "%U %U",
7907                     unformat_vl_api_ip4_address,
7908                     &path->nh.address.ip4,
7909                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7910         {
7911           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7912         }
7913       else if (unformat (input, "%U %U",
7914                          unformat_vl_api_ip6_address,
7915                          &path->nh.address.ip6,
7916                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7917         {
7918           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7919         }
7920       else if (unformat (input, "weight %u", &weight))
7921         {
7922           path->weight = weight;
7923         }
7924       else if (unformat (input, "preference %u", &preference))
7925         {
7926           path->preference = preference;
7927         }
7928       else if (unformat (input, "%U next-hop-table %d",
7929                          unformat_vl_api_ip4_address,
7930                          &path->nh.address.ip4, &path->table_id))
7931         {
7932           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7933         }
7934       else if (unformat (input, "%U next-hop-table %d",
7935                          unformat_vl_api_ip6_address,
7936                          &path->nh.address.ip6, &path->table_id))
7937         {
7938           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7939         }
7940       else if (unformat (input, "%U",
7941                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7942         {
7943           /*
7944            * the recursive next-hops are by default in the default table
7945            */
7946           path->table_id = 0;
7947           path->sw_if_index = ~0;
7948           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7949         }
7950       else if (unformat (input, "%U",
7951                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7952         {
7953           /*
7954            * the recursive next-hops are by default in the default table
7955            */
7956           path->table_id = 0;
7957           path->sw_if_index = ~0;
7958           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7959         }
7960       else if (unformat (input, "resolve-via-host"))
7961         {
7962           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7963         }
7964       else if (unformat (input, "resolve-via-attached"))
7965         {
7966           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7967         }
7968       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7969         {
7970           path->type = FIB_API_PATH_TYPE_LOCAL;
7971           path->sw_if_index = ~0;
7972           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7973         }
7974       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7975         {
7976           path->type = FIB_API_PATH_TYPE_LOCAL;
7977           path->sw_if_index = ~0;
7978           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7979         }
7980       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7981         ;
7982       else if (unformat (input, "via-label %d", &path->nh.via_label))
7983         {
7984           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7985           path->sw_if_index = ~0;
7986         }
7987       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7988         {
7989           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7990           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7991         }
7992       else if (unformat (input, "local"))
7993         {
7994           path->type = FIB_API_PATH_TYPE_LOCAL;
7995         }
7996       else if (unformat (input, "out-labels"))
7997         {
7998           while (unformat (input, "%d", &out_label))
7999             {
8000               path->label_stack[path->n_labels].label = out_label;
8001               path->label_stack[path->n_labels].is_uniform = 0;
8002               path->label_stack[path->n_labels].ttl = 64;
8003               path->n_labels++;
8004             }
8005         }
8006       else if (unformat (input, "via"))
8007         {
8008           /* new path, back up and return */
8009           unformat_put_input (input);
8010           unformat_put_input (input);
8011           unformat_put_input (input);
8012           unformat_put_input (input);
8013           break;
8014         }
8015       else
8016         {
8017           return (0);
8018         }
8019     }
8020
8021   path->proto = ntohl (path->proto);
8022   path->type = ntohl (path->type);
8023   path->flags = ntohl (path->flags);
8024   path->table_id = ntohl (path->table_id);
8025   path->sw_if_index = ntohl (path->sw_if_index);
8026
8027   return (1);
8028 }
8029
8030 static int
8031 api_ip_route_add_del (vat_main_t * vam)
8032 {
8033   unformat_input_t *i = vam->input;
8034   vl_api_ip_route_add_del_t *mp;
8035   u32 vrf_id = 0;
8036   u8 is_add = 1;
8037   u8 is_multipath = 0;
8038   u8 prefix_set = 0;
8039   u8 path_count = 0;
8040   vl_api_prefix_t pfx = { };
8041   vl_api_fib_path_t paths[8];
8042   int count = 1;
8043   int j;
8044   f64 before = 0;
8045   u32 random_add_del = 0;
8046   u32 *random_vector = 0;
8047   u32 random_seed = 0xdeaddabe;
8048
8049   /* Parse args required to build the message */
8050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8051     {
8052       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8053         prefix_set = 1;
8054       else if (unformat (i, "del"))
8055         is_add = 0;
8056       else if (unformat (i, "add"))
8057         is_add = 1;
8058       else if (unformat (i, "vrf %d", &vrf_id))
8059         ;
8060       else if (unformat (i, "count %d", &count))
8061         ;
8062       else if (unformat (i, "random"))
8063         random_add_del = 1;
8064       else if (unformat (i, "multipath"))
8065         is_multipath = 1;
8066       else if (unformat (i, "seed %d", &random_seed))
8067         ;
8068       else
8069         if (unformat
8070             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8071         {
8072           path_count++;
8073           if (8 == path_count)
8074             {
8075               errmsg ("max 8 paths");
8076               return -99;
8077             }
8078         }
8079       else
8080         {
8081           clib_warning ("parse error '%U'", format_unformat_error, i);
8082           return -99;
8083         }
8084     }
8085
8086   if (!path_count)
8087     {
8088       errmsg ("specify a path; via ...");
8089       return -99;
8090     }
8091   if (prefix_set == 0)
8092     {
8093       errmsg ("missing prefix");
8094       return -99;
8095     }
8096
8097   /* Generate a pile of unique, random routes */
8098   if (random_add_del)
8099     {
8100       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8101       u32 this_random_address;
8102       uword *random_hash;
8103
8104       random_hash = hash_create (count, sizeof (uword));
8105
8106       hash_set (random_hash, i->as_u32, 1);
8107       for (j = 0; j <= count; j++)
8108         {
8109           do
8110             {
8111               this_random_address = random_u32 (&random_seed);
8112               this_random_address =
8113                 clib_host_to_net_u32 (this_random_address);
8114             }
8115           while (hash_get (random_hash, this_random_address));
8116           vec_add1 (random_vector, this_random_address);
8117           hash_set (random_hash, this_random_address, 1);
8118         }
8119       hash_free (random_hash);
8120       set_ip4_address (&pfx.address, random_vector[0]);
8121     }
8122
8123   if (count > 1)
8124     {
8125       /* Turn on async mode */
8126       vam->async_mode = 1;
8127       vam->async_errors = 0;
8128       before = vat_time_now (vam);
8129     }
8130
8131   for (j = 0; j < count; j++)
8132     {
8133       /* Construct the API message */
8134       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8135
8136       mp->is_add = is_add;
8137       mp->is_multipath = is_multipath;
8138
8139       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8140       mp->route.table_id = ntohl (vrf_id);
8141       mp->route.n_paths = path_count;
8142
8143       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8144
8145       if (random_add_del)
8146         set_ip4_address (&pfx.address, random_vector[j + 1]);
8147       else
8148         increment_address (&pfx.address);
8149       /* send it... */
8150       S (mp);
8151       /* If we receive SIGTERM, stop now... */
8152       if (vam->do_exit)
8153         break;
8154     }
8155
8156   /* When testing multiple add/del ops, use a control-ping to sync */
8157   if (count > 1)
8158     {
8159       vl_api_control_ping_t *mp_ping;
8160       f64 after;
8161       f64 timeout;
8162
8163       /* Shut off async mode */
8164       vam->async_mode = 0;
8165
8166       MPING (CONTROL_PING, mp_ping);
8167       S (mp_ping);
8168
8169       timeout = vat_time_now (vam) + 1.0;
8170       while (vat_time_now (vam) < timeout)
8171         if (vam->result_ready == 1)
8172           goto out;
8173       vam->retval = -99;
8174
8175     out:
8176       if (vam->retval == -99)
8177         errmsg ("timeout");
8178
8179       if (vam->async_errors > 0)
8180         {
8181           errmsg ("%d asynchronous errors", vam->async_errors);
8182           vam->retval = -98;
8183         }
8184       vam->async_errors = 0;
8185       after = vat_time_now (vam);
8186
8187       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8188       if (j > 0)
8189         count = j;
8190
8191       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8192              count, after - before, count / (after - before));
8193     }
8194   else
8195     {
8196       int ret;
8197
8198       /* Wait for a reply... */
8199       W (ret);
8200       return ret;
8201     }
8202
8203   /* Return the good/bad news */
8204   return (vam->retval);
8205 }
8206
8207 static int
8208 api_ip_mroute_add_del (vat_main_t * vam)
8209 {
8210   unformat_input_t *i = vam->input;
8211   u8 path_set = 0, prefix_set = 0, is_add = 1;
8212   vl_api_ip_mroute_add_del_t *mp;
8213   mfib_entry_flags_t eflags = 0;
8214   vl_api_mfib_path_t path;
8215   vl_api_mprefix_t pfx = { };
8216   u32 vrf_id = 0;
8217   int ret;
8218
8219   /* Parse args required to build the message */
8220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8221     {
8222       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8223         {
8224           prefix_set = 1;
8225           pfx.grp_address_length = htons (pfx.grp_address_length);
8226         }
8227       else if (unformat (i, "del"))
8228         is_add = 0;
8229       else if (unformat (i, "add"))
8230         is_add = 1;
8231       else if (unformat (i, "vrf %d", &vrf_id))
8232         ;
8233       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8234         path.itf_flags = htonl (path.itf_flags);
8235       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8236         ;
8237       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8238         path_set = 1;
8239       else
8240         {
8241           clib_warning ("parse error '%U'", format_unformat_error, i);
8242           return -99;
8243         }
8244     }
8245
8246   if (prefix_set == 0)
8247     {
8248       errmsg ("missing addresses\n");
8249       return -99;
8250     }
8251   if (path_set == 0)
8252     {
8253       errmsg ("missing path\n");
8254       return -99;
8255     }
8256
8257   /* Construct the API message */
8258   M (IP_MROUTE_ADD_DEL, mp);
8259
8260   mp->is_add = is_add;
8261   mp->is_multipath = 1;
8262
8263   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8264   mp->route.table_id = htonl (vrf_id);
8265   mp->route.n_paths = 1;
8266   mp->route.entry_flags = htonl (eflags);
8267
8268   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8269
8270   /* send it... */
8271   S (mp);
8272   /* Wait for a reply... */
8273   W (ret);
8274   return ret;
8275 }
8276
8277 static int
8278 api_mpls_table_add_del (vat_main_t * vam)
8279 {
8280   unformat_input_t *i = vam->input;
8281   vl_api_mpls_table_add_del_t *mp;
8282   u32 table_id = ~0;
8283   u8 is_add = 1;
8284   int ret = 0;
8285
8286   /* Parse args required to build the message */
8287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8288     {
8289       if (unformat (i, "table %d", &table_id))
8290         ;
8291       else if (unformat (i, "del"))
8292         is_add = 0;
8293       else if (unformat (i, "add"))
8294         is_add = 1;
8295       else
8296         {
8297           clib_warning ("parse error '%U'", format_unformat_error, i);
8298           return -99;
8299         }
8300     }
8301
8302   if (~0 == table_id)
8303     {
8304       errmsg ("missing table-ID");
8305       return -99;
8306     }
8307
8308   /* Construct the API message */
8309   M (MPLS_TABLE_ADD_DEL, mp);
8310
8311   mp->mt_table.mt_table_id = ntohl (table_id);
8312   mp->mt_is_add = is_add;
8313
8314   /* send it... */
8315   S (mp);
8316
8317   /* Wait for a reply... */
8318   W (ret);
8319
8320   return ret;
8321 }
8322
8323 static int
8324 api_mpls_route_add_del (vat_main_t * vam)
8325 {
8326   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8327   mpls_label_t local_label = MPLS_LABEL_INVALID;
8328   unformat_input_t *i = vam->input;
8329   vl_api_mpls_route_add_del_t *mp;
8330   vl_api_fib_path_t paths[8];
8331   int count = 1, j;
8332   f64 before = 0;
8333
8334   /* Parse args required to build the message */
8335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8336     {
8337       if (unformat (i, "%d", &local_label))
8338         ;
8339       else if (unformat (i, "eos"))
8340         is_eos = 1;
8341       else if (unformat (i, "non-eos"))
8342         is_eos = 0;
8343       else if (unformat (i, "del"))
8344         is_add = 0;
8345       else if (unformat (i, "add"))
8346         is_add = 1;
8347       else if (unformat (i, "multipath"))
8348         is_multipath = 1;
8349       else if (unformat (i, "count %d", &count))
8350         ;
8351       else
8352         if (unformat
8353             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8354         {
8355           path_count++;
8356           if (8 == path_count)
8357             {
8358               errmsg ("max 8 paths");
8359               return -99;
8360             }
8361         }
8362       else
8363         {
8364           clib_warning ("parse error '%U'", format_unformat_error, i);
8365           return -99;
8366         }
8367     }
8368
8369   if (!path_count)
8370     {
8371       errmsg ("specify a path; via ...");
8372       return -99;
8373     }
8374
8375   if (MPLS_LABEL_INVALID == local_label)
8376     {
8377       errmsg ("missing label");
8378       return -99;
8379     }
8380
8381   if (count > 1)
8382     {
8383       /* Turn on async mode */
8384       vam->async_mode = 1;
8385       vam->async_errors = 0;
8386       before = vat_time_now (vam);
8387     }
8388
8389   for (j = 0; j < count; j++)
8390     {
8391       /* Construct the API message */
8392       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8393
8394       mp->mr_is_add = is_add;
8395       mp->mr_is_multipath = is_multipath;
8396
8397       mp->mr_route.mr_label = local_label;
8398       mp->mr_route.mr_eos = is_eos;
8399       mp->mr_route.mr_table_id = 0;
8400       mp->mr_route.mr_n_paths = path_count;
8401
8402       clib_memcpy (&mp->mr_route.mr_paths, paths,
8403                    sizeof (paths[0]) * path_count);
8404
8405       local_label++;
8406
8407       /* send it... */
8408       S (mp);
8409       /* If we receive SIGTERM, stop now... */
8410       if (vam->do_exit)
8411         break;
8412     }
8413
8414   /* When testing multiple add/del ops, use a control-ping to sync */
8415   if (count > 1)
8416     {
8417       vl_api_control_ping_t *mp_ping;
8418       f64 after;
8419       f64 timeout;
8420
8421       /* Shut off async mode */
8422       vam->async_mode = 0;
8423
8424       MPING (CONTROL_PING, mp_ping);
8425       S (mp_ping);
8426
8427       timeout = vat_time_now (vam) + 1.0;
8428       while (vat_time_now (vam) < timeout)
8429         if (vam->result_ready == 1)
8430           goto out;
8431       vam->retval = -99;
8432
8433     out:
8434       if (vam->retval == -99)
8435         errmsg ("timeout");
8436
8437       if (vam->async_errors > 0)
8438         {
8439           errmsg ("%d asynchronous errors", vam->async_errors);
8440           vam->retval = -98;
8441         }
8442       vam->async_errors = 0;
8443       after = vat_time_now (vam);
8444
8445       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8446       if (j > 0)
8447         count = j;
8448
8449       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8450              count, after - before, count / (after - before));
8451     }
8452   else
8453     {
8454       int ret;
8455
8456       /* Wait for a reply... */
8457       W (ret);
8458       return ret;
8459     }
8460
8461   /* Return the good/bad news */
8462   return (vam->retval);
8463   return (0);
8464 }
8465
8466 static int
8467 api_mpls_ip_bind_unbind (vat_main_t * vam)
8468 {
8469   unformat_input_t *i = vam->input;
8470   vl_api_mpls_ip_bind_unbind_t *mp;
8471   u32 ip_table_id = 0;
8472   u8 is_bind = 1;
8473   vl_api_prefix_t pfx;
8474   u8 prefix_set = 0;
8475   mpls_label_t local_label = MPLS_LABEL_INVALID;
8476   int ret;
8477
8478   /* Parse args required to build the message */
8479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8480     {
8481       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8482         prefix_set = 1;
8483       else if (unformat (i, "%d", &local_label))
8484         ;
8485       else if (unformat (i, "table-id %d", &ip_table_id))
8486         ;
8487       else if (unformat (i, "unbind"))
8488         is_bind = 0;
8489       else if (unformat (i, "bind"))
8490         is_bind = 1;
8491       else
8492         {
8493           clib_warning ("parse error '%U'", format_unformat_error, i);
8494           return -99;
8495         }
8496     }
8497
8498   if (!prefix_set)
8499     {
8500       errmsg ("IP prefix not set");
8501       return -99;
8502     }
8503
8504   if (MPLS_LABEL_INVALID == local_label)
8505     {
8506       errmsg ("missing label");
8507       return -99;
8508     }
8509
8510   /* Construct the API message */
8511   M (MPLS_IP_BIND_UNBIND, mp);
8512
8513   mp->mb_is_bind = is_bind;
8514   mp->mb_ip_table_id = ntohl (ip_table_id);
8515   mp->mb_mpls_table_id = 0;
8516   mp->mb_label = ntohl (local_label);
8517   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8518
8519   /* send it... */
8520   S (mp);
8521
8522   /* Wait for a reply... */
8523   W (ret);
8524   return ret;
8525   return (0);
8526 }
8527
8528 static int
8529 api_sr_mpls_policy_add (vat_main_t * vam)
8530 {
8531   unformat_input_t *i = vam->input;
8532   vl_api_sr_mpls_policy_add_t *mp;
8533   u32 bsid = 0;
8534   u32 weight = 1;
8535   u8 type = 0;
8536   u8 n_segments = 0;
8537   u32 sid;
8538   u32 *segments = NULL;
8539   int ret;
8540
8541   /* Parse args required to build the message */
8542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8543     {
8544       if (unformat (i, "bsid %d", &bsid))
8545         ;
8546       else if (unformat (i, "weight %d", &weight))
8547         ;
8548       else if (unformat (i, "spray"))
8549         type = 1;
8550       else if (unformat (i, "next %d", &sid))
8551         {
8552           n_segments += 1;
8553           vec_add1 (segments, htonl (sid));
8554         }
8555       else
8556         {
8557           clib_warning ("parse error '%U'", format_unformat_error, i);
8558           return -99;
8559         }
8560     }
8561
8562   if (bsid == 0)
8563     {
8564       errmsg ("bsid not set");
8565       return -99;
8566     }
8567
8568   if (n_segments == 0)
8569     {
8570       errmsg ("no sid in segment stack");
8571       return -99;
8572     }
8573
8574   /* Construct the API message */
8575   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8576
8577   mp->bsid = htonl (bsid);
8578   mp->weight = htonl (weight);
8579   mp->is_spray = type;
8580   mp->n_segments = n_segments;
8581   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8582   vec_free (segments);
8583
8584   /* send it... */
8585   S (mp);
8586
8587   /* Wait for a reply... */
8588   W (ret);
8589   return ret;
8590 }
8591
8592 static int
8593 api_sr_mpls_policy_del (vat_main_t * vam)
8594 {
8595   unformat_input_t *i = vam->input;
8596   vl_api_sr_mpls_policy_del_t *mp;
8597   u32 bsid = 0;
8598   int ret;
8599
8600   /* Parse args required to build the message */
8601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8602     {
8603       if (unformat (i, "bsid %d", &bsid))
8604         ;
8605       else
8606         {
8607           clib_warning ("parse error '%U'", format_unformat_error, i);
8608           return -99;
8609         }
8610     }
8611
8612   if (bsid == 0)
8613     {
8614       errmsg ("bsid not set");
8615       return -99;
8616     }
8617
8618   /* Construct the API message */
8619   M (SR_MPLS_POLICY_DEL, mp);
8620
8621   mp->bsid = htonl (bsid);
8622
8623   /* send it... */
8624   S (mp);
8625
8626   /* Wait for a reply... */
8627   W (ret);
8628   return ret;
8629 }
8630
8631 static int
8632 api_bier_table_add_del (vat_main_t * vam)
8633 {
8634   unformat_input_t *i = vam->input;
8635   vl_api_bier_table_add_del_t *mp;
8636   u8 is_add = 1;
8637   u32 set = 0, sub_domain = 0, hdr_len = 3;
8638   mpls_label_t local_label = MPLS_LABEL_INVALID;
8639   int ret;
8640
8641   /* Parse args required to build the message */
8642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8643     {
8644       if (unformat (i, "sub-domain %d", &sub_domain))
8645         ;
8646       else if (unformat (i, "set %d", &set))
8647         ;
8648       else if (unformat (i, "label %d", &local_label))
8649         ;
8650       else if (unformat (i, "hdr-len %d", &hdr_len))
8651         ;
8652       else if (unformat (i, "add"))
8653         is_add = 1;
8654       else if (unformat (i, "del"))
8655         is_add = 0;
8656       else
8657         {
8658           clib_warning ("parse error '%U'", format_unformat_error, i);
8659           return -99;
8660         }
8661     }
8662
8663   if (MPLS_LABEL_INVALID == local_label)
8664     {
8665       errmsg ("missing label\n");
8666       return -99;
8667     }
8668
8669   /* Construct the API message */
8670   M (BIER_TABLE_ADD_DEL, mp);
8671
8672   mp->bt_is_add = is_add;
8673   mp->bt_label = ntohl (local_label);
8674   mp->bt_tbl_id.bt_set = set;
8675   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8676   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8677
8678   /* send it... */
8679   S (mp);
8680
8681   /* Wait for a reply... */
8682   W (ret);
8683
8684   return (ret);
8685 }
8686
8687 static int
8688 api_bier_route_add_del (vat_main_t * vam)
8689 {
8690   unformat_input_t *i = vam->input;
8691   vl_api_bier_route_add_del_t *mp;
8692   u8 is_add = 1;
8693   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8694   ip4_address_t v4_next_hop_address;
8695   ip6_address_t v6_next_hop_address;
8696   u8 next_hop_set = 0;
8697   u8 next_hop_proto_is_ip4 = 1;
8698   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8699   int ret;
8700
8701   /* Parse args required to build the message */
8702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8703     {
8704       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8705         {
8706           next_hop_proto_is_ip4 = 1;
8707           next_hop_set = 1;
8708         }
8709       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8710         {
8711           next_hop_proto_is_ip4 = 0;
8712           next_hop_set = 1;
8713         }
8714       if (unformat (i, "sub-domain %d", &sub_domain))
8715         ;
8716       else if (unformat (i, "set %d", &set))
8717         ;
8718       else if (unformat (i, "hdr-len %d", &hdr_len))
8719         ;
8720       else if (unformat (i, "bp %d", &bp))
8721         ;
8722       else if (unformat (i, "add"))
8723         is_add = 1;
8724       else if (unformat (i, "del"))
8725         is_add = 0;
8726       else if (unformat (i, "out-label %d", &next_hop_out_label))
8727         ;
8728       else
8729         {
8730           clib_warning ("parse error '%U'", format_unformat_error, i);
8731           return -99;
8732         }
8733     }
8734
8735   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8736     {
8737       errmsg ("next hop / label set\n");
8738       return -99;
8739     }
8740   if (0 == bp)
8741     {
8742       errmsg ("bit=position not set\n");
8743       return -99;
8744     }
8745
8746   /* Construct the API message */
8747   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8748
8749   mp->br_is_add = is_add;
8750   mp->br_route.br_tbl_id.bt_set = set;
8751   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8752   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8753   mp->br_route.br_bp = ntohs (bp);
8754   mp->br_route.br_n_paths = 1;
8755   mp->br_route.br_paths[0].n_labels = 1;
8756   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8757   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8758                                     FIB_API_PATH_NH_PROTO_IP4 :
8759                                     FIB_API_PATH_NH_PROTO_IP6);
8760
8761   if (next_hop_proto_is_ip4)
8762     {
8763       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8764                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8765     }
8766   else
8767     {
8768       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8769                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8770     }
8771
8772   /* send it... */
8773   S (mp);
8774
8775   /* Wait for a reply... */
8776   W (ret);
8777
8778   return (ret);
8779 }
8780
8781 static int
8782 api_mpls_tunnel_add_del (vat_main_t * vam)
8783 {
8784   unformat_input_t *i = vam->input;
8785   vl_api_mpls_tunnel_add_del_t *mp;
8786
8787   vl_api_fib_path_t paths[8];
8788   u32 sw_if_index = ~0;
8789   u8 path_count = 0;
8790   u8 l2_only = 0;
8791   u8 is_add = 1;
8792   int ret;
8793
8794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8795     {
8796       if (unformat (i, "add"))
8797         is_add = 1;
8798       else
8799         if (unformat
8800             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8801         is_add = 0;
8802       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8803         is_add = 0;
8804       else if (unformat (i, "l2-only"))
8805         l2_only = 1;
8806       else
8807         if (unformat
8808             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8809         {
8810           path_count++;
8811           if (8 == path_count)
8812             {
8813               errmsg ("max 8 paths");
8814               return -99;
8815             }
8816         }
8817       else
8818         {
8819           clib_warning ("parse error '%U'", format_unformat_error, i);
8820           return -99;
8821         }
8822     }
8823
8824   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8825
8826   mp->mt_is_add = is_add;
8827   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8828   mp->mt_tunnel.mt_l2_only = l2_only;
8829   mp->mt_tunnel.mt_is_multicast = 0;
8830   mp->mt_tunnel.mt_n_paths = path_count;
8831
8832   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8833                sizeof (paths[0]) * path_count);
8834
8835   S (mp);
8836   W (ret);
8837   return ret;
8838 }
8839
8840 static int
8841 api_sw_interface_set_unnumbered (vat_main_t * vam)
8842 {
8843   unformat_input_t *i = vam->input;
8844   vl_api_sw_interface_set_unnumbered_t *mp;
8845   u32 sw_if_index;
8846   u32 unnum_sw_index = ~0;
8847   u8 is_add = 1;
8848   u8 sw_if_index_set = 0;
8849   int ret;
8850
8851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8852     {
8853       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8854         sw_if_index_set = 1;
8855       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8856         sw_if_index_set = 1;
8857       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8858         ;
8859       else if (unformat (i, "del"))
8860         is_add = 0;
8861       else
8862         {
8863           clib_warning ("parse error '%U'", format_unformat_error, i);
8864           return -99;
8865         }
8866     }
8867
8868   if (sw_if_index_set == 0)
8869     {
8870       errmsg ("missing interface name or sw_if_index");
8871       return -99;
8872     }
8873
8874   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8875
8876   mp->sw_if_index = ntohl (sw_if_index);
8877   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8878   mp->is_add = is_add;
8879
8880   S (mp);
8881   W (ret);
8882   return ret;
8883 }
8884
8885
8886 static int
8887 api_create_vlan_subif (vat_main_t * vam)
8888 {
8889   unformat_input_t *i = vam->input;
8890   vl_api_create_vlan_subif_t *mp;
8891   u32 sw_if_index;
8892   u8 sw_if_index_set = 0;
8893   u32 vlan_id;
8894   u8 vlan_id_set = 0;
8895   int ret;
8896
8897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8898     {
8899       if (unformat (i, "sw_if_index %d", &sw_if_index))
8900         sw_if_index_set = 1;
8901       else
8902         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8903         sw_if_index_set = 1;
8904       else if (unformat (i, "vlan %d", &vlan_id))
8905         vlan_id_set = 1;
8906       else
8907         {
8908           clib_warning ("parse error '%U'", format_unformat_error, i);
8909           return -99;
8910         }
8911     }
8912
8913   if (sw_if_index_set == 0)
8914     {
8915       errmsg ("missing interface name or sw_if_index");
8916       return -99;
8917     }
8918
8919   if (vlan_id_set == 0)
8920     {
8921       errmsg ("missing vlan_id");
8922       return -99;
8923     }
8924   M (CREATE_VLAN_SUBIF, mp);
8925
8926   mp->sw_if_index = ntohl (sw_if_index);
8927   mp->vlan_id = ntohl (vlan_id);
8928
8929   S (mp);
8930   W (ret);
8931   return ret;
8932 }
8933
8934 #define foreach_create_subif_bit                \
8935 _(no_tags)                                      \
8936 _(one_tag)                                      \
8937 _(two_tags)                                     \
8938 _(dot1ad)                                       \
8939 _(exact_match)                                  \
8940 _(default_sub)                                  \
8941 _(outer_vlan_id_any)                            \
8942 _(inner_vlan_id_any)
8943
8944 #define foreach_create_subif_flag               \
8945 _(0, "no_tags")                                 \
8946 _(1, "one_tag")                                 \
8947 _(2, "two_tags")                                \
8948 _(3, "dot1ad")                                  \
8949 _(4, "exact_match")                             \
8950 _(5, "default_sub")                             \
8951 _(6, "outer_vlan_id_any")                       \
8952 _(7, "inner_vlan_id_any")
8953
8954 static int
8955 api_create_subif (vat_main_t * vam)
8956 {
8957   unformat_input_t *i = vam->input;
8958   vl_api_create_subif_t *mp;
8959   u32 sw_if_index;
8960   u8 sw_if_index_set = 0;
8961   u32 sub_id;
8962   u8 sub_id_set = 0;
8963   u32 __attribute__ ((unused)) no_tags = 0;
8964   u32 __attribute__ ((unused)) one_tag = 0;
8965   u32 __attribute__ ((unused)) two_tags = 0;
8966   u32 __attribute__ ((unused)) dot1ad = 0;
8967   u32 __attribute__ ((unused)) exact_match = 0;
8968   u32 __attribute__ ((unused)) default_sub = 0;
8969   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8970   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8971   u32 tmp;
8972   u16 outer_vlan_id = 0;
8973   u16 inner_vlan_id = 0;
8974   int ret;
8975
8976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8977     {
8978       if (unformat (i, "sw_if_index %d", &sw_if_index))
8979         sw_if_index_set = 1;
8980       else
8981         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8982         sw_if_index_set = 1;
8983       else if (unformat (i, "sub_id %d", &sub_id))
8984         sub_id_set = 1;
8985       else if (unformat (i, "outer_vlan_id %d", &tmp))
8986         outer_vlan_id = tmp;
8987       else if (unformat (i, "inner_vlan_id %d", &tmp))
8988         inner_vlan_id = tmp;
8989
8990 #define _(a) else if (unformat (i, #a)) a = 1 ;
8991       foreach_create_subif_bit
8992 #undef _
8993         else
8994         {
8995           clib_warning ("parse error '%U'", format_unformat_error, i);
8996           return -99;
8997         }
8998     }
8999
9000   if (sw_if_index_set == 0)
9001     {
9002       errmsg ("missing interface name or sw_if_index");
9003       return -99;
9004     }
9005
9006   if (sub_id_set == 0)
9007     {
9008       errmsg ("missing sub_id");
9009       return -99;
9010     }
9011   M (CREATE_SUBIF, mp);
9012
9013   mp->sw_if_index = ntohl (sw_if_index);
9014   mp->sub_id = ntohl (sub_id);
9015
9016 #define _(a,b) mp->sub_if_flags |= (1 << a);
9017   foreach_create_subif_flag;
9018 #undef _
9019
9020   mp->outer_vlan_id = ntohs (outer_vlan_id);
9021   mp->inner_vlan_id = ntohs (inner_vlan_id);
9022
9023   S (mp);
9024   W (ret);
9025   return ret;
9026 }
9027
9028 static int
9029 api_ip_table_replace_begin (vat_main_t * vam)
9030 {
9031   unformat_input_t *i = vam->input;
9032   vl_api_ip_table_replace_begin_t *mp;
9033   u32 table_id = 0;
9034   u8 is_ipv6 = 0;
9035
9036   int ret;
9037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9038     {
9039       if (unformat (i, "table %d", &table_id))
9040         ;
9041       else if (unformat (i, "ipv6"))
9042         is_ipv6 = 1;
9043       else
9044         {
9045           clib_warning ("parse error '%U'", format_unformat_error, i);
9046           return -99;
9047         }
9048     }
9049
9050   M (IP_TABLE_REPLACE_BEGIN, mp);
9051
9052   mp->table.table_id = ntohl (table_id);
9053   mp->table.is_ip6 = is_ipv6;
9054
9055   S (mp);
9056   W (ret);
9057   return ret;
9058 }
9059
9060 static int
9061 api_ip_table_flush (vat_main_t * vam)
9062 {
9063   unformat_input_t *i = vam->input;
9064   vl_api_ip_table_flush_t *mp;
9065   u32 table_id = 0;
9066   u8 is_ipv6 = 0;
9067
9068   int ret;
9069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9070     {
9071       if (unformat (i, "table %d", &table_id))
9072         ;
9073       else if (unformat (i, "ipv6"))
9074         is_ipv6 = 1;
9075       else
9076         {
9077           clib_warning ("parse error '%U'", format_unformat_error, i);
9078           return -99;
9079         }
9080     }
9081
9082   M (IP_TABLE_FLUSH, mp);
9083
9084   mp->table.table_id = ntohl (table_id);
9085   mp->table.is_ip6 = is_ipv6;
9086
9087   S (mp);
9088   W (ret);
9089   return ret;
9090 }
9091
9092 static int
9093 api_ip_table_replace_end (vat_main_t * vam)
9094 {
9095   unformat_input_t *i = vam->input;
9096   vl_api_ip_table_replace_end_t *mp;
9097   u32 table_id = 0;
9098   u8 is_ipv6 = 0;
9099
9100   int ret;
9101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9102     {
9103       if (unformat (i, "table %d", &table_id))
9104         ;
9105       else if (unformat (i, "ipv6"))
9106         is_ipv6 = 1;
9107       else
9108         {
9109           clib_warning ("parse error '%U'", format_unformat_error, i);
9110           return -99;
9111         }
9112     }
9113
9114   M (IP_TABLE_REPLACE_END, mp);
9115
9116   mp->table.table_id = ntohl (table_id);
9117   mp->table.is_ip6 = is_ipv6;
9118
9119   S (mp);
9120   W (ret);
9121   return ret;
9122 }
9123
9124 static int
9125 api_set_ip_flow_hash (vat_main_t * vam)
9126 {
9127   unformat_input_t *i = vam->input;
9128   vl_api_set_ip_flow_hash_t *mp;
9129   u32 vrf_id = 0;
9130   u8 is_ipv6 = 0;
9131   u8 vrf_id_set = 0;
9132   u8 src = 0;
9133   u8 dst = 0;
9134   u8 sport = 0;
9135   u8 dport = 0;
9136   u8 proto = 0;
9137   u8 reverse = 0;
9138   int ret;
9139
9140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9141     {
9142       if (unformat (i, "vrf %d", &vrf_id))
9143         vrf_id_set = 1;
9144       else if (unformat (i, "ipv6"))
9145         is_ipv6 = 1;
9146       else if (unformat (i, "src"))
9147         src = 1;
9148       else if (unformat (i, "dst"))
9149         dst = 1;
9150       else if (unformat (i, "sport"))
9151         sport = 1;
9152       else if (unformat (i, "dport"))
9153         dport = 1;
9154       else if (unformat (i, "proto"))
9155         proto = 1;
9156       else if (unformat (i, "reverse"))
9157         reverse = 1;
9158
9159       else
9160         {
9161           clib_warning ("parse error '%U'", format_unformat_error, i);
9162           return -99;
9163         }
9164     }
9165
9166   if (vrf_id_set == 0)
9167     {
9168       errmsg ("missing vrf id");
9169       return -99;
9170     }
9171
9172   M (SET_IP_FLOW_HASH, mp);
9173   mp->src = src;
9174   mp->dst = dst;
9175   mp->sport = sport;
9176   mp->dport = dport;
9177   mp->proto = proto;
9178   mp->reverse = reverse;
9179   mp->vrf_id = ntohl (vrf_id);
9180   mp->is_ipv6 = is_ipv6;
9181
9182   S (mp);
9183   W (ret);
9184   return ret;
9185 }
9186
9187 static int
9188 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9189 {
9190   unformat_input_t *i = vam->input;
9191   vl_api_sw_interface_ip6_enable_disable_t *mp;
9192   u32 sw_if_index;
9193   u8 sw_if_index_set = 0;
9194   u8 enable = 0;
9195   int ret;
9196
9197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9198     {
9199       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9200         sw_if_index_set = 1;
9201       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9202         sw_if_index_set = 1;
9203       else if (unformat (i, "enable"))
9204         enable = 1;
9205       else if (unformat (i, "disable"))
9206         enable = 0;
9207       else
9208         {
9209           clib_warning ("parse error '%U'", format_unformat_error, i);
9210           return -99;
9211         }
9212     }
9213
9214   if (sw_if_index_set == 0)
9215     {
9216       errmsg ("missing interface name or sw_if_index");
9217       return -99;
9218     }
9219
9220   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9221
9222   mp->sw_if_index = ntohl (sw_if_index);
9223   mp->enable = enable;
9224
9225   S (mp);
9226   W (ret);
9227   return ret;
9228 }
9229
9230
9231 static int
9232 api_l2_patch_add_del (vat_main_t * vam)
9233 {
9234   unformat_input_t *i = vam->input;
9235   vl_api_l2_patch_add_del_t *mp;
9236   u32 rx_sw_if_index;
9237   u8 rx_sw_if_index_set = 0;
9238   u32 tx_sw_if_index;
9239   u8 tx_sw_if_index_set = 0;
9240   u8 is_add = 1;
9241   int ret;
9242
9243   /* Parse args required to build the message */
9244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9245     {
9246       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9247         rx_sw_if_index_set = 1;
9248       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9249         tx_sw_if_index_set = 1;
9250       else if (unformat (i, "rx"))
9251         {
9252           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9253             {
9254               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9255                             &rx_sw_if_index))
9256                 rx_sw_if_index_set = 1;
9257             }
9258           else
9259             break;
9260         }
9261       else if (unformat (i, "tx"))
9262         {
9263           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9264             {
9265               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9266                             &tx_sw_if_index))
9267                 tx_sw_if_index_set = 1;
9268             }
9269           else
9270             break;
9271         }
9272       else if (unformat (i, "del"))
9273         is_add = 0;
9274       else
9275         break;
9276     }
9277
9278   if (rx_sw_if_index_set == 0)
9279     {
9280       errmsg ("missing rx interface name or rx_sw_if_index");
9281       return -99;
9282     }
9283
9284   if (tx_sw_if_index_set == 0)
9285     {
9286       errmsg ("missing tx interface name or tx_sw_if_index");
9287       return -99;
9288     }
9289
9290   M (L2_PATCH_ADD_DEL, mp);
9291
9292   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9293   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9294   mp->is_add = is_add;
9295
9296   S (mp);
9297   W (ret);
9298   return ret;
9299 }
9300
9301 u8 is_del;
9302 u8 localsid_addr[16];
9303 u8 end_psp;
9304 u8 behavior;
9305 u32 sw_if_index;
9306 u32 vlan_index;
9307 u32 fib_table;
9308 u8 nh_addr[16];
9309
9310 static int
9311 api_sr_localsid_add_del (vat_main_t * vam)
9312 {
9313   unformat_input_t *i = vam->input;
9314   vl_api_sr_localsid_add_del_t *mp;
9315
9316   u8 is_del;
9317   ip6_address_t localsid;
9318   u8 end_psp = 0;
9319   u8 behavior = ~0;
9320   u32 sw_if_index;
9321   u32 fib_table = ~(u32) 0;
9322   ip46_address_t nh_addr;
9323   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9324
9325   bool nexthop_set = 0;
9326
9327   int ret;
9328
9329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9330     {
9331       if (unformat (i, "del"))
9332         is_del = 1;
9333       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9334       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9335         nexthop_set = 1;
9336       else if (unformat (i, "behavior %u", &behavior));
9337       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9338       else if (unformat (i, "fib-table %u", &fib_table));
9339       else if (unformat (i, "end.psp %u", &behavior));
9340       else
9341         break;
9342     }
9343
9344   M (SR_LOCALSID_ADD_DEL, mp);
9345
9346   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9347
9348   if (nexthop_set)
9349     {
9350       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9351     }
9352   mp->behavior = behavior;
9353   mp->sw_if_index = ntohl (sw_if_index);
9354   mp->fib_table = ntohl (fib_table);
9355   mp->end_psp = end_psp;
9356   mp->is_del = is_del;
9357
9358   S (mp);
9359   W (ret);
9360   return ret;
9361 }
9362
9363 static int
9364 api_ioam_enable (vat_main_t * vam)
9365 {
9366   unformat_input_t *input = vam->input;
9367   vl_api_ioam_enable_t *mp;
9368   u32 id = 0;
9369   int has_trace_option = 0;
9370   int has_pot_option = 0;
9371   int has_seqno_option = 0;
9372   int has_analyse_option = 0;
9373   int ret;
9374
9375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9376     {
9377       if (unformat (input, "trace"))
9378         has_trace_option = 1;
9379       else if (unformat (input, "pot"))
9380         has_pot_option = 1;
9381       else if (unformat (input, "seqno"))
9382         has_seqno_option = 1;
9383       else if (unformat (input, "analyse"))
9384         has_analyse_option = 1;
9385       else
9386         break;
9387     }
9388   M (IOAM_ENABLE, mp);
9389   mp->id = htons (id);
9390   mp->seqno = has_seqno_option;
9391   mp->analyse = has_analyse_option;
9392   mp->pot_enable = has_pot_option;
9393   mp->trace_enable = has_trace_option;
9394
9395   S (mp);
9396   W (ret);
9397   return ret;
9398 }
9399
9400
9401 static int
9402 api_ioam_disable (vat_main_t * vam)
9403 {
9404   vl_api_ioam_disable_t *mp;
9405   int ret;
9406
9407   M (IOAM_DISABLE, mp);
9408   S (mp);
9409   W (ret);
9410   return ret;
9411 }
9412
9413 #define foreach_tcp_proto_field                 \
9414 _(src_port)                                     \
9415 _(dst_port)
9416
9417 #define foreach_udp_proto_field                 \
9418 _(src_port)                                     \
9419 _(dst_port)
9420
9421 #define foreach_ip4_proto_field                 \
9422 _(src_address)                                  \
9423 _(dst_address)                                  \
9424 _(tos)                                          \
9425 _(length)                                       \
9426 _(fragment_id)                                  \
9427 _(ttl)                                          \
9428 _(protocol)                                     \
9429 _(checksum)
9430
9431 typedef struct
9432 {
9433   u16 src_port, dst_port;
9434 } tcpudp_header_t;
9435
9436 #if VPP_API_TEST_BUILTIN == 0
9437 uword
9438 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9439 {
9440   u8 **maskp = va_arg (*args, u8 **);
9441   u8 *mask = 0;
9442   u8 found_something = 0;
9443   tcp_header_t *tcp;
9444
9445 #define _(a) u8 a=0;
9446   foreach_tcp_proto_field;
9447 #undef _
9448
9449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9450     {
9451       if (0);
9452 #define _(a) else if (unformat (input, #a)) a=1;
9453       foreach_tcp_proto_field
9454 #undef _
9455         else
9456         break;
9457     }
9458
9459 #define _(a) found_something += a;
9460   foreach_tcp_proto_field;
9461 #undef _
9462
9463   if (found_something == 0)
9464     return 0;
9465
9466   vec_validate (mask, sizeof (*tcp) - 1);
9467
9468   tcp = (tcp_header_t *) mask;
9469
9470 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9471   foreach_tcp_proto_field;
9472 #undef _
9473
9474   *maskp = mask;
9475   return 1;
9476 }
9477
9478 uword
9479 unformat_udp_mask (unformat_input_t * input, va_list * args)
9480 {
9481   u8 **maskp = va_arg (*args, u8 **);
9482   u8 *mask = 0;
9483   u8 found_something = 0;
9484   udp_header_t *udp;
9485
9486 #define _(a) u8 a=0;
9487   foreach_udp_proto_field;
9488 #undef _
9489
9490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9491     {
9492       if (0);
9493 #define _(a) else if (unformat (input, #a)) a=1;
9494       foreach_udp_proto_field
9495 #undef _
9496         else
9497         break;
9498     }
9499
9500 #define _(a) found_something += a;
9501   foreach_udp_proto_field;
9502 #undef _
9503
9504   if (found_something == 0)
9505     return 0;
9506
9507   vec_validate (mask, sizeof (*udp) - 1);
9508
9509   udp = (udp_header_t *) mask;
9510
9511 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9512   foreach_udp_proto_field;
9513 #undef _
9514
9515   *maskp = mask;
9516   return 1;
9517 }
9518
9519 uword
9520 unformat_l4_mask (unformat_input_t * input, va_list * args)
9521 {
9522   u8 **maskp = va_arg (*args, u8 **);
9523   u16 src_port = 0, dst_port = 0;
9524   tcpudp_header_t *tcpudp;
9525
9526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9527     {
9528       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9529         return 1;
9530       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9531         return 1;
9532       else if (unformat (input, "src_port"))
9533         src_port = 0xFFFF;
9534       else if (unformat (input, "dst_port"))
9535         dst_port = 0xFFFF;
9536       else
9537         return 0;
9538     }
9539
9540   if (!src_port && !dst_port)
9541     return 0;
9542
9543   u8 *mask = 0;
9544   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9545
9546   tcpudp = (tcpudp_header_t *) mask;
9547   tcpudp->src_port = src_port;
9548   tcpudp->dst_port = dst_port;
9549
9550   *maskp = mask;
9551
9552   return 1;
9553 }
9554
9555 uword
9556 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9557 {
9558   u8 **maskp = va_arg (*args, u8 **);
9559   u8 *mask = 0;
9560   u8 found_something = 0;
9561   ip4_header_t *ip;
9562
9563 #define _(a) u8 a=0;
9564   foreach_ip4_proto_field;
9565 #undef _
9566   u8 version = 0;
9567   u8 hdr_length = 0;
9568
9569
9570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9571     {
9572       if (unformat (input, "version"))
9573         version = 1;
9574       else if (unformat (input, "hdr_length"))
9575         hdr_length = 1;
9576       else if (unformat (input, "src"))
9577         src_address = 1;
9578       else if (unformat (input, "dst"))
9579         dst_address = 1;
9580       else if (unformat (input, "proto"))
9581         protocol = 1;
9582
9583 #define _(a) else if (unformat (input, #a)) a=1;
9584       foreach_ip4_proto_field
9585 #undef _
9586         else
9587         break;
9588     }
9589
9590 #define _(a) found_something += a;
9591   foreach_ip4_proto_field;
9592 #undef _
9593
9594   if (found_something == 0)
9595     return 0;
9596
9597   vec_validate (mask, sizeof (*ip) - 1);
9598
9599   ip = (ip4_header_t *) mask;
9600
9601 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9602   foreach_ip4_proto_field;
9603 #undef _
9604
9605   ip->ip_version_and_header_length = 0;
9606
9607   if (version)
9608     ip->ip_version_and_header_length |= 0xF0;
9609
9610   if (hdr_length)
9611     ip->ip_version_and_header_length |= 0x0F;
9612
9613   *maskp = mask;
9614   return 1;
9615 }
9616
9617 #define foreach_ip6_proto_field                 \
9618 _(src_address)                                  \
9619 _(dst_address)                                  \
9620 _(payload_length)                               \
9621 _(hop_limit)                                    \
9622 _(protocol)
9623
9624 uword
9625 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9626 {
9627   u8 **maskp = va_arg (*args, u8 **);
9628   u8 *mask = 0;
9629   u8 found_something = 0;
9630   ip6_header_t *ip;
9631   u32 ip_version_traffic_class_and_flow_label;
9632
9633 #define _(a) u8 a=0;
9634   foreach_ip6_proto_field;
9635 #undef _
9636   u8 version = 0;
9637   u8 traffic_class = 0;
9638   u8 flow_label = 0;
9639
9640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9641     {
9642       if (unformat (input, "version"))
9643         version = 1;
9644       else if (unformat (input, "traffic-class"))
9645         traffic_class = 1;
9646       else if (unformat (input, "flow-label"))
9647         flow_label = 1;
9648       else if (unformat (input, "src"))
9649         src_address = 1;
9650       else if (unformat (input, "dst"))
9651         dst_address = 1;
9652       else if (unformat (input, "proto"))
9653         protocol = 1;
9654
9655 #define _(a) else if (unformat (input, #a)) a=1;
9656       foreach_ip6_proto_field
9657 #undef _
9658         else
9659         break;
9660     }
9661
9662 #define _(a) found_something += a;
9663   foreach_ip6_proto_field;
9664 #undef _
9665
9666   if (found_something == 0)
9667     return 0;
9668
9669   vec_validate (mask, sizeof (*ip) - 1);
9670
9671   ip = (ip6_header_t *) mask;
9672
9673 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9674   foreach_ip6_proto_field;
9675 #undef _
9676
9677   ip_version_traffic_class_and_flow_label = 0;
9678
9679   if (version)
9680     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9681
9682   if (traffic_class)
9683     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9684
9685   if (flow_label)
9686     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9687
9688   ip->ip_version_traffic_class_and_flow_label =
9689     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9690
9691   *maskp = mask;
9692   return 1;
9693 }
9694
9695 uword
9696 unformat_l3_mask (unformat_input_t * input, va_list * args)
9697 {
9698   u8 **maskp = va_arg (*args, u8 **);
9699
9700   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9701     {
9702       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9703         return 1;
9704       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9705         return 1;
9706       else
9707         break;
9708     }
9709   return 0;
9710 }
9711
9712 uword
9713 unformat_l2_mask (unformat_input_t * input, va_list * args)
9714 {
9715   u8 **maskp = va_arg (*args, u8 **);
9716   u8 *mask = 0;
9717   u8 src = 0;
9718   u8 dst = 0;
9719   u8 proto = 0;
9720   u8 tag1 = 0;
9721   u8 tag2 = 0;
9722   u8 ignore_tag1 = 0;
9723   u8 ignore_tag2 = 0;
9724   u8 cos1 = 0;
9725   u8 cos2 = 0;
9726   u8 dot1q = 0;
9727   u8 dot1ad = 0;
9728   int len = 14;
9729
9730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9731     {
9732       if (unformat (input, "src"))
9733         src = 1;
9734       else if (unformat (input, "dst"))
9735         dst = 1;
9736       else if (unformat (input, "proto"))
9737         proto = 1;
9738       else if (unformat (input, "tag1"))
9739         tag1 = 1;
9740       else if (unformat (input, "tag2"))
9741         tag2 = 1;
9742       else if (unformat (input, "ignore-tag1"))
9743         ignore_tag1 = 1;
9744       else if (unformat (input, "ignore-tag2"))
9745         ignore_tag2 = 1;
9746       else if (unformat (input, "cos1"))
9747         cos1 = 1;
9748       else if (unformat (input, "cos2"))
9749         cos2 = 1;
9750       else if (unformat (input, "dot1q"))
9751         dot1q = 1;
9752       else if (unformat (input, "dot1ad"))
9753         dot1ad = 1;
9754       else
9755         break;
9756     }
9757   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9758        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9759     return 0;
9760
9761   if (tag1 || ignore_tag1 || cos1 || dot1q)
9762     len = 18;
9763   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9764     len = 22;
9765
9766   vec_validate (mask, len - 1);
9767
9768   if (dst)
9769     clib_memset (mask, 0xff, 6);
9770
9771   if (src)
9772     clib_memset (mask + 6, 0xff, 6);
9773
9774   if (tag2 || dot1ad)
9775     {
9776       /* inner vlan tag */
9777       if (tag2)
9778         {
9779           mask[19] = 0xff;
9780           mask[18] = 0x0f;
9781         }
9782       if (cos2)
9783         mask[18] |= 0xe0;
9784       if (proto)
9785         mask[21] = mask[20] = 0xff;
9786       if (tag1)
9787         {
9788           mask[15] = 0xff;
9789           mask[14] = 0x0f;
9790         }
9791       if (cos1)
9792         mask[14] |= 0xe0;
9793       *maskp = mask;
9794       return 1;
9795     }
9796   if (tag1 | dot1q)
9797     {
9798       if (tag1)
9799         {
9800           mask[15] = 0xff;
9801           mask[14] = 0x0f;
9802         }
9803       if (cos1)
9804         mask[14] |= 0xe0;
9805       if (proto)
9806         mask[16] = mask[17] = 0xff;
9807
9808       *maskp = mask;
9809       return 1;
9810     }
9811   if (cos2)
9812     mask[18] |= 0xe0;
9813   if (cos1)
9814     mask[14] |= 0xe0;
9815   if (proto)
9816     mask[12] = mask[13] = 0xff;
9817
9818   *maskp = mask;
9819   return 1;
9820 }
9821
9822 uword
9823 unformat_classify_mask (unformat_input_t * input, va_list * args)
9824 {
9825   u8 **maskp = va_arg (*args, u8 **);
9826   u32 *skipp = va_arg (*args, u32 *);
9827   u32 *matchp = va_arg (*args, u32 *);
9828   u32 match;
9829   u8 *mask = 0;
9830   u8 *l2 = 0;
9831   u8 *l3 = 0;
9832   u8 *l4 = 0;
9833   int i;
9834
9835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9836     {
9837       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9838         ;
9839       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9840         ;
9841       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9842         ;
9843       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9844         ;
9845       else
9846         break;
9847     }
9848
9849   if (l4 && !l3)
9850     {
9851       vec_free (mask);
9852       vec_free (l2);
9853       vec_free (l4);
9854       return 0;
9855     }
9856
9857   if (mask || l2 || l3 || l4)
9858     {
9859       if (l2 || l3 || l4)
9860         {
9861           /* "With a free Ethernet header in every package" */
9862           if (l2 == 0)
9863             vec_validate (l2, 13);
9864           mask = l2;
9865           if (vec_len (l3))
9866             {
9867               vec_append (mask, l3);
9868               vec_free (l3);
9869             }
9870           if (vec_len (l4))
9871             {
9872               vec_append (mask, l4);
9873               vec_free (l4);
9874             }
9875         }
9876
9877       /* Scan forward looking for the first significant mask octet */
9878       for (i = 0; i < vec_len (mask); i++)
9879         if (mask[i])
9880           break;
9881
9882       /* compute (skip, match) params */
9883       *skipp = i / sizeof (u32x4);
9884       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9885
9886       /* Pad mask to an even multiple of the vector size */
9887       while (vec_len (mask) % sizeof (u32x4))
9888         vec_add1 (mask, 0);
9889
9890       match = vec_len (mask) / sizeof (u32x4);
9891
9892       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9893         {
9894           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9895           if (*tmp || *(tmp + 1))
9896             break;
9897           match--;
9898         }
9899       if (match == 0)
9900         clib_warning ("BUG: match 0");
9901
9902       _vec_len (mask) = match * sizeof (u32x4);
9903
9904       *matchp = match;
9905       *maskp = mask;
9906
9907       return 1;
9908     }
9909
9910   return 0;
9911 }
9912 #endif /* VPP_API_TEST_BUILTIN */
9913
9914 #define foreach_l2_next                         \
9915 _(drop, DROP)                                   \
9916 _(ethernet, ETHERNET_INPUT)                     \
9917 _(ip4, IP4_INPUT)                               \
9918 _(ip6, IP6_INPUT)
9919
9920 uword
9921 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9922 {
9923   u32 *miss_next_indexp = va_arg (*args, u32 *);
9924   u32 next_index = 0;
9925   u32 tmp;
9926
9927 #define _(n,N) \
9928   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9929   foreach_l2_next;
9930 #undef _
9931
9932   if (unformat (input, "%d", &tmp))
9933     {
9934       next_index = tmp;
9935       goto out;
9936     }
9937
9938   return 0;
9939
9940 out:
9941   *miss_next_indexp = next_index;
9942   return 1;
9943 }
9944
9945 #define foreach_ip_next                         \
9946 _(drop, DROP)                                   \
9947 _(local, LOCAL)                                 \
9948 _(rewrite, REWRITE)
9949
9950 uword
9951 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9952 {
9953   u32 *miss_next_indexp = va_arg (*args, u32 *);
9954   u32 next_index = 0;
9955   u32 tmp;
9956
9957 #define _(n,N) \
9958   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9959   foreach_ip_next;
9960 #undef _
9961
9962   if (unformat (input, "%d", &tmp))
9963     {
9964       next_index = tmp;
9965       goto out;
9966     }
9967
9968   return 0;
9969
9970 out:
9971   *miss_next_indexp = next_index;
9972   return 1;
9973 }
9974
9975 #define foreach_acl_next                        \
9976 _(deny, DENY)
9977
9978 uword
9979 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9980 {
9981   u32 *miss_next_indexp = va_arg (*args, u32 *);
9982   u32 next_index = 0;
9983   u32 tmp;
9984
9985 #define _(n,N) \
9986   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9987   foreach_acl_next;
9988 #undef _
9989
9990   if (unformat (input, "permit"))
9991     {
9992       next_index = ~0;
9993       goto out;
9994     }
9995   else if (unformat (input, "%d", &tmp))
9996     {
9997       next_index = tmp;
9998       goto out;
9999     }
10000
10001   return 0;
10002
10003 out:
10004   *miss_next_indexp = next_index;
10005   return 1;
10006 }
10007
10008 uword
10009 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10010 {
10011   u32 *r = va_arg (*args, u32 *);
10012
10013   if (unformat (input, "conform-color"))
10014     *r = POLICE_CONFORM;
10015   else if (unformat (input, "exceed-color"))
10016     *r = POLICE_EXCEED;
10017   else
10018     return 0;
10019
10020   return 1;
10021 }
10022
10023 static int
10024 api_classify_add_del_table (vat_main_t * vam)
10025 {
10026   unformat_input_t *i = vam->input;
10027   vl_api_classify_add_del_table_t *mp;
10028
10029   u32 nbuckets = 2;
10030   u32 skip = ~0;
10031   u32 match = ~0;
10032   int is_add = 1;
10033   int del_chain = 0;
10034   u32 table_index = ~0;
10035   u32 next_table_index = ~0;
10036   u32 miss_next_index = ~0;
10037   u32 memory_size = 32 << 20;
10038   u8 *mask = 0;
10039   u32 current_data_flag = 0;
10040   int current_data_offset = 0;
10041   int ret;
10042
10043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10044     {
10045       if (unformat (i, "del"))
10046         is_add = 0;
10047       else if (unformat (i, "del-chain"))
10048         {
10049           is_add = 0;
10050           del_chain = 1;
10051         }
10052       else if (unformat (i, "buckets %d", &nbuckets))
10053         ;
10054       else if (unformat (i, "memory_size %d", &memory_size))
10055         ;
10056       else if (unformat (i, "skip %d", &skip))
10057         ;
10058       else if (unformat (i, "match %d", &match))
10059         ;
10060       else if (unformat (i, "table %d", &table_index))
10061         ;
10062       else if (unformat (i, "mask %U", unformat_classify_mask,
10063                          &mask, &skip, &match))
10064         ;
10065       else if (unformat (i, "next-table %d", &next_table_index))
10066         ;
10067       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10068                          &miss_next_index))
10069         ;
10070       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10071                          &miss_next_index))
10072         ;
10073       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10074                          &miss_next_index))
10075         ;
10076       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10077         ;
10078       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10079         ;
10080       else
10081         break;
10082     }
10083
10084   if (is_add && mask == 0)
10085     {
10086       errmsg ("Mask required");
10087       return -99;
10088     }
10089
10090   if (is_add && skip == ~0)
10091     {
10092       errmsg ("skip count required");
10093       return -99;
10094     }
10095
10096   if (is_add && match == ~0)
10097     {
10098       errmsg ("match count required");
10099       return -99;
10100     }
10101
10102   if (!is_add && table_index == ~0)
10103     {
10104       errmsg ("table index required for delete");
10105       return -99;
10106     }
10107
10108   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10109
10110   mp->is_add = is_add;
10111   mp->del_chain = del_chain;
10112   mp->table_index = ntohl (table_index);
10113   mp->nbuckets = ntohl (nbuckets);
10114   mp->memory_size = ntohl (memory_size);
10115   mp->skip_n_vectors = ntohl (skip);
10116   mp->match_n_vectors = ntohl (match);
10117   mp->next_table_index = ntohl (next_table_index);
10118   mp->miss_next_index = ntohl (miss_next_index);
10119   mp->current_data_flag = ntohl (current_data_flag);
10120   mp->current_data_offset = ntohl (current_data_offset);
10121   mp->mask_len = ntohl (vec_len (mask));
10122   clib_memcpy (mp->mask, mask, vec_len (mask));
10123
10124   vec_free (mask);
10125
10126   S (mp);
10127   W (ret);
10128   return ret;
10129 }
10130
10131 #if VPP_API_TEST_BUILTIN == 0
10132 uword
10133 unformat_l4_match (unformat_input_t * input, va_list * args)
10134 {
10135   u8 **matchp = va_arg (*args, u8 **);
10136
10137   u8 *proto_header = 0;
10138   int src_port = 0;
10139   int dst_port = 0;
10140
10141   tcpudp_header_t h;
10142
10143   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (input, "src_port %d", &src_port))
10146         ;
10147       else if (unformat (input, "dst_port %d", &dst_port))
10148         ;
10149       else
10150         return 0;
10151     }
10152
10153   h.src_port = clib_host_to_net_u16 (src_port);
10154   h.dst_port = clib_host_to_net_u16 (dst_port);
10155   vec_validate (proto_header, sizeof (h) - 1);
10156   memcpy (proto_header, &h, sizeof (h));
10157
10158   *matchp = proto_header;
10159
10160   return 1;
10161 }
10162
10163 uword
10164 unformat_ip4_match (unformat_input_t * input, va_list * args)
10165 {
10166   u8 **matchp = va_arg (*args, u8 **);
10167   u8 *match = 0;
10168   ip4_header_t *ip;
10169   int version = 0;
10170   u32 version_val;
10171   int hdr_length = 0;
10172   u32 hdr_length_val;
10173   int src = 0, dst = 0;
10174   ip4_address_t src_val, dst_val;
10175   int proto = 0;
10176   u32 proto_val;
10177   int tos = 0;
10178   u32 tos_val;
10179   int length = 0;
10180   u32 length_val;
10181   int fragment_id = 0;
10182   u32 fragment_id_val;
10183   int ttl = 0;
10184   int ttl_val;
10185   int checksum = 0;
10186   u32 checksum_val;
10187
10188   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10189     {
10190       if (unformat (input, "version %d", &version_val))
10191         version = 1;
10192       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10193         hdr_length = 1;
10194       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10195         src = 1;
10196       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10197         dst = 1;
10198       else if (unformat (input, "proto %d", &proto_val))
10199         proto = 1;
10200       else if (unformat (input, "tos %d", &tos_val))
10201         tos = 1;
10202       else if (unformat (input, "length %d", &length_val))
10203         length = 1;
10204       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10205         fragment_id = 1;
10206       else if (unformat (input, "ttl %d", &ttl_val))
10207         ttl = 1;
10208       else if (unformat (input, "checksum %d", &checksum_val))
10209         checksum = 1;
10210       else
10211         break;
10212     }
10213
10214   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10215       + ttl + checksum == 0)
10216     return 0;
10217
10218   /*
10219    * Aligned because we use the real comparison functions
10220    */
10221   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10222
10223   ip = (ip4_header_t *) match;
10224
10225   /* These are realistically matched in practice */
10226   if (src)
10227     ip->src_address.as_u32 = src_val.as_u32;
10228
10229   if (dst)
10230     ip->dst_address.as_u32 = dst_val.as_u32;
10231
10232   if (proto)
10233     ip->protocol = proto_val;
10234
10235
10236   /* These are not, but they're included for completeness */
10237   if (version)
10238     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10239
10240   if (hdr_length)
10241     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10242
10243   if (tos)
10244     ip->tos = tos_val;
10245
10246   if (length)
10247     ip->length = clib_host_to_net_u16 (length_val);
10248
10249   if (ttl)
10250     ip->ttl = ttl_val;
10251
10252   if (checksum)
10253     ip->checksum = clib_host_to_net_u16 (checksum_val);
10254
10255   *matchp = match;
10256   return 1;
10257 }
10258
10259 uword
10260 unformat_ip6_match (unformat_input_t * input, va_list * args)
10261 {
10262   u8 **matchp = va_arg (*args, u8 **);
10263   u8 *match = 0;
10264   ip6_header_t *ip;
10265   int version = 0;
10266   u32 version_val;
10267   u8 traffic_class = 0;
10268   u32 traffic_class_val = 0;
10269   u8 flow_label = 0;
10270   u8 flow_label_val;
10271   int src = 0, dst = 0;
10272   ip6_address_t src_val, dst_val;
10273   int proto = 0;
10274   u32 proto_val;
10275   int payload_length = 0;
10276   u32 payload_length_val;
10277   int hop_limit = 0;
10278   int hop_limit_val;
10279   u32 ip_version_traffic_class_and_flow_label;
10280
10281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10282     {
10283       if (unformat (input, "version %d", &version_val))
10284         version = 1;
10285       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10286         traffic_class = 1;
10287       else if (unformat (input, "flow_label %d", &flow_label_val))
10288         flow_label = 1;
10289       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10290         src = 1;
10291       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10292         dst = 1;
10293       else if (unformat (input, "proto %d", &proto_val))
10294         proto = 1;
10295       else if (unformat (input, "payload_length %d", &payload_length_val))
10296         payload_length = 1;
10297       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10298         hop_limit = 1;
10299       else
10300         break;
10301     }
10302
10303   if (version + traffic_class + flow_label + src + dst + proto +
10304       payload_length + hop_limit == 0)
10305     return 0;
10306
10307   /*
10308    * Aligned because we use the real comparison functions
10309    */
10310   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10311
10312   ip = (ip6_header_t *) match;
10313
10314   if (src)
10315     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10316
10317   if (dst)
10318     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10319
10320   if (proto)
10321     ip->protocol = proto_val;
10322
10323   ip_version_traffic_class_and_flow_label = 0;
10324
10325   if (version)
10326     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10327
10328   if (traffic_class)
10329     ip_version_traffic_class_and_flow_label |=
10330       (traffic_class_val & 0xFF) << 20;
10331
10332   if (flow_label)
10333     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10334
10335   ip->ip_version_traffic_class_and_flow_label =
10336     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10337
10338   if (payload_length)
10339     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10340
10341   if (hop_limit)
10342     ip->hop_limit = hop_limit_val;
10343
10344   *matchp = match;
10345   return 1;
10346 }
10347
10348 uword
10349 unformat_l3_match (unformat_input_t * input, va_list * args)
10350 {
10351   u8 **matchp = va_arg (*args, u8 **);
10352
10353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10354     {
10355       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10356         return 1;
10357       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10358         return 1;
10359       else
10360         break;
10361     }
10362   return 0;
10363 }
10364
10365 uword
10366 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10367 {
10368   u8 *tagp = va_arg (*args, u8 *);
10369   u32 tag;
10370
10371   if (unformat (input, "%d", &tag))
10372     {
10373       tagp[0] = (tag >> 8) & 0x0F;
10374       tagp[1] = tag & 0xFF;
10375       return 1;
10376     }
10377
10378   return 0;
10379 }
10380
10381 uword
10382 unformat_l2_match (unformat_input_t * input, va_list * args)
10383 {
10384   u8 **matchp = va_arg (*args, u8 **);
10385   u8 *match = 0;
10386   u8 src = 0;
10387   u8 src_val[6];
10388   u8 dst = 0;
10389   u8 dst_val[6];
10390   u8 proto = 0;
10391   u16 proto_val;
10392   u8 tag1 = 0;
10393   u8 tag1_val[2];
10394   u8 tag2 = 0;
10395   u8 tag2_val[2];
10396   int len = 14;
10397   u8 ignore_tag1 = 0;
10398   u8 ignore_tag2 = 0;
10399   u8 cos1 = 0;
10400   u8 cos2 = 0;
10401   u32 cos1_val = 0;
10402   u32 cos2_val = 0;
10403
10404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10405     {
10406       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10407         src = 1;
10408       else
10409         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10410         dst = 1;
10411       else if (unformat (input, "proto %U",
10412                          unformat_ethernet_type_host_byte_order, &proto_val))
10413         proto = 1;
10414       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10415         tag1 = 1;
10416       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10417         tag2 = 1;
10418       else if (unformat (input, "ignore-tag1"))
10419         ignore_tag1 = 1;
10420       else if (unformat (input, "ignore-tag2"))
10421         ignore_tag2 = 1;
10422       else if (unformat (input, "cos1 %d", &cos1_val))
10423         cos1 = 1;
10424       else if (unformat (input, "cos2 %d", &cos2_val))
10425         cos2 = 1;
10426       else
10427         break;
10428     }
10429   if ((src + dst + proto + tag1 + tag2 +
10430        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10431     return 0;
10432
10433   if (tag1 || ignore_tag1 || cos1)
10434     len = 18;
10435   if (tag2 || ignore_tag2 || cos2)
10436     len = 22;
10437
10438   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10439
10440   if (dst)
10441     clib_memcpy (match, dst_val, 6);
10442
10443   if (src)
10444     clib_memcpy (match + 6, src_val, 6);
10445
10446   if (tag2)
10447     {
10448       /* inner vlan tag */
10449       match[19] = tag2_val[1];
10450       match[18] = tag2_val[0];
10451       if (cos2)
10452         match[18] |= (cos2_val & 0x7) << 5;
10453       if (proto)
10454         {
10455           match[21] = proto_val & 0xff;
10456           match[20] = proto_val >> 8;
10457         }
10458       if (tag1)
10459         {
10460           match[15] = tag1_val[1];
10461           match[14] = tag1_val[0];
10462         }
10463       if (cos1)
10464         match[14] |= (cos1_val & 0x7) << 5;
10465       *matchp = match;
10466       return 1;
10467     }
10468   if (tag1)
10469     {
10470       match[15] = tag1_val[1];
10471       match[14] = tag1_val[0];
10472       if (proto)
10473         {
10474           match[17] = proto_val & 0xff;
10475           match[16] = proto_val >> 8;
10476         }
10477       if (cos1)
10478         match[14] |= (cos1_val & 0x7) << 5;
10479
10480       *matchp = match;
10481       return 1;
10482     }
10483   if (cos2)
10484     match[18] |= (cos2_val & 0x7) << 5;
10485   if (cos1)
10486     match[14] |= (cos1_val & 0x7) << 5;
10487   if (proto)
10488     {
10489       match[13] = proto_val & 0xff;
10490       match[12] = proto_val >> 8;
10491     }
10492
10493   *matchp = match;
10494   return 1;
10495 }
10496
10497 uword
10498 unformat_qos_source (unformat_input_t * input, va_list * args)
10499 {
10500   int *qs = va_arg (*args, int *);
10501
10502   if (unformat (input, "ip"))
10503     *qs = QOS_SOURCE_IP;
10504   else if (unformat (input, "mpls"))
10505     *qs = QOS_SOURCE_MPLS;
10506   else if (unformat (input, "ext"))
10507     *qs = QOS_SOURCE_EXT;
10508   else if (unformat (input, "vlan"))
10509     *qs = QOS_SOURCE_VLAN;
10510   else
10511     return 0;
10512
10513   return 1;
10514 }
10515 #endif
10516
10517 uword
10518 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10519 {
10520   u8 **matchp = va_arg (*args, u8 **);
10521   u32 skip_n_vectors = va_arg (*args, u32);
10522   u32 match_n_vectors = va_arg (*args, u32);
10523
10524   u8 *match = 0;
10525   u8 *l2 = 0;
10526   u8 *l3 = 0;
10527   u8 *l4 = 0;
10528
10529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10530     {
10531       if (unformat (input, "hex %U", unformat_hex_string, &match))
10532         ;
10533       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10534         ;
10535       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10536         ;
10537       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10538         ;
10539       else
10540         break;
10541     }
10542
10543   if (l4 && !l3)
10544     {
10545       vec_free (match);
10546       vec_free (l2);
10547       vec_free (l4);
10548       return 0;
10549     }
10550
10551   if (match || l2 || l3 || l4)
10552     {
10553       if (l2 || l3 || l4)
10554         {
10555           /* "Win a free Ethernet header in every packet" */
10556           if (l2 == 0)
10557             vec_validate_aligned (l2, 13, sizeof (u32x4));
10558           match = l2;
10559           if (vec_len (l3))
10560             {
10561               vec_append_aligned (match, l3, sizeof (u32x4));
10562               vec_free (l3);
10563             }
10564           if (vec_len (l4))
10565             {
10566               vec_append_aligned (match, l4, sizeof (u32x4));
10567               vec_free (l4);
10568             }
10569         }
10570
10571       /* Make sure the vector is big enough even if key is all 0's */
10572       vec_validate_aligned
10573         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10574          sizeof (u32x4));
10575
10576       /* Set size, include skipped vectors */
10577       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10578
10579       *matchp = match;
10580
10581       return 1;
10582     }
10583
10584   return 0;
10585 }
10586
10587 static int
10588 api_classify_add_del_session (vat_main_t * vam)
10589 {
10590   unformat_input_t *i = vam->input;
10591   vl_api_classify_add_del_session_t *mp;
10592   int is_add = 1;
10593   u32 table_index = ~0;
10594   u32 hit_next_index = ~0;
10595   u32 opaque_index = ~0;
10596   u8 *match = 0;
10597   i32 advance = 0;
10598   u32 skip_n_vectors = 0;
10599   u32 match_n_vectors = 0;
10600   u32 action = 0;
10601   u32 metadata = 0;
10602   int ret;
10603
10604   /*
10605    * Warning: you have to supply skip_n and match_n
10606    * because the API client cant simply look at the classify
10607    * table object.
10608    */
10609
10610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10611     {
10612       if (unformat (i, "del"))
10613         is_add = 0;
10614       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10615                          &hit_next_index))
10616         ;
10617       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10618                          &hit_next_index))
10619         ;
10620       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10621                          &hit_next_index))
10622         ;
10623       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10624         ;
10625       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10626         ;
10627       else if (unformat (i, "opaque-index %d", &opaque_index))
10628         ;
10629       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10630         ;
10631       else if (unformat (i, "match_n %d", &match_n_vectors))
10632         ;
10633       else if (unformat (i, "match %U", api_unformat_classify_match,
10634                          &match, skip_n_vectors, match_n_vectors))
10635         ;
10636       else if (unformat (i, "advance %d", &advance))
10637         ;
10638       else if (unformat (i, "table-index %d", &table_index))
10639         ;
10640       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10641         action = 1;
10642       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10643         action = 2;
10644       else if (unformat (i, "action %d", &action))
10645         ;
10646       else if (unformat (i, "metadata %d", &metadata))
10647         ;
10648       else
10649         break;
10650     }
10651
10652   if (table_index == ~0)
10653     {
10654       errmsg ("Table index required");
10655       return -99;
10656     }
10657
10658   if (is_add && match == 0)
10659     {
10660       errmsg ("Match value required");
10661       return -99;
10662     }
10663
10664   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10665
10666   mp->is_add = is_add;
10667   mp->table_index = ntohl (table_index);
10668   mp->hit_next_index = ntohl (hit_next_index);
10669   mp->opaque_index = ntohl (opaque_index);
10670   mp->advance = ntohl (advance);
10671   mp->action = action;
10672   mp->metadata = ntohl (metadata);
10673   mp->match_len = ntohl (vec_len (match));
10674   clib_memcpy (mp->match, match, vec_len (match));
10675   vec_free (match);
10676
10677   S (mp);
10678   W (ret);
10679   return ret;
10680 }
10681
10682 static int
10683 api_classify_set_interface_ip_table (vat_main_t * vam)
10684 {
10685   unformat_input_t *i = vam->input;
10686   vl_api_classify_set_interface_ip_table_t *mp;
10687   u32 sw_if_index;
10688   int sw_if_index_set;
10689   u32 table_index = ~0;
10690   u8 is_ipv6 = 0;
10691   int ret;
10692
10693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10694     {
10695       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10696         sw_if_index_set = 1;
10697       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10698         sw_if_index_set = 1;
10699       else if (unformat (i, "table %d", &table_index))
10700         ;
10701       else
10702         {
10703           clib_warning ("parse error '%U'", format_unformat_error, i);
10704           return -99;
10705         }
10706     }
10707
10708   if (sw_if_index_set == 0)
10709     {
10710       errmsg ("missing interface name or sw_if_index");
10711       return -99;
10712     }
10713
10714
10715   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10716
10717   mp->sw_if_index = ntohl (sw_if_index);
10718   mp->table_index = ntohl (table_index);
10719   mp->is_ipv6 = is_ipv6;
10720
10721   S (mp);
10722   W (ret);
10723   return ret;
10724 }
10725
10726 static int
10727 api_classify_set_interface_l2_tables (vat_main_t * vam)
10728 {
10729   unformat_input_t *i = vam->input;
10730   vl_api_classify_set_interface_l2_tables_t *mp;
10731   u32 sw_if_index;
10732   int sw_if_index_set;
10733   u32 ip4_table_index = ~0;
10734   u32 ip6_table_index = ~0;
10735   u32 other_table_index = ~0;
10736   u32 is_input = 1;
10737   int ret;
10738
10739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10740     {
10741       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10742         sw_if_index_set = 1;
10743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10744         sw_if_index_set = 1;
10745       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10746         ;
10747       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10748         ;
10749       else if (unformat (i, "other-table %d", &other_table_index))
10750         ;
10751       else if (unformat (i, "is-input %d", &is_input))
10752         ;
10753       else
10754         {
10755           clib_warning ("parse error '%U'", format_unformat_error, i);
10756           return -99;
10757         }
10758     }
10759
10760   if (sw_if_index_set == 0)
10761     {
10762       errmsg ("missing interface name or sw_if_index");
10763       return -99;
10764     }
10765
10766
10767   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10768
10769   mp->sw_if_index = ntohl (sw_if_index);
10770   mp->ip4_table_index = ntohl (ip4_table_index);
10771   mp->ip6_table_index = ntohl (ip6_table_index);
10772   mp->other_table_index = ntohl (other_table_index);
10773   mp->is_input = (u8) is_input;
10774
10775   S (mp);
10776   W (ret);
10777   return ret;
10778 }
10779
10780 static int
10781 api_set_ipfix_exporter (vat_main_t * vam)
10782 {
10783   unformat_input_t *i = vam->input;
10784   vl_api_set_ipfix_exporter_t *mp;
10785   ip4_address_t collector_address;
10786   u8 collector_address_set = 0;
10787   u32 collector_port = ~0;
10788   ip4_address_t src_address;
10789   u8 src_address_set = 0;
10790   u32 vrf_id = ~0;
10791   u32 path_mtu = ~0;
10792   u32 template_interval = ~0;
10793   u8 udp_checksum = 0;
10794   int ret;
10795
10796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10797     {
10798       if (unformat (i, "collector_address %U", unformat_ip4_address,
10799                     &collector_address))
10800         collector_address_set = 1;
10801       else if (unformat (i, "collector_port %d", &collector_port))
10802         ;
10803       else if (unformat (i, "src_address %U", unformat_ip4_address,
10804                          &src_address))
10805         src_address_set = 1;
10806       else if (unformat (i, "vrf_id %d", &vrf_id))
10807         ;
10808       else if (unformat (i, "path_mtu %d", &path_mtu))
10809         ;
10810       else if (unformat (i, "template_interval %d", &template_interval))
10811         ;
10812       else if (unformat (i, "udp_checksum"))
10813         udp_checksum = 1;
10814       else
10815         break;
10816     }
10817
10818   if (collector_address_set == 0)
10819     {
10820       errmsg ("collector_address required");
10821       return -99;
10822     }
10823
10824   if (src_address_set == 0)
10825     {
10826       errmsg ("src_address required");
10827       return -99;
10828     }
10829
10830   M (SET_IPFIX_EXPORTER, mp);
10831
10832   memcpy (mp->collector_address.un.ip4, collector_address.data,
10833           sizeof (collector_address.data));
10834   mp->collector_port = htons ((u16) collector_port);
10835   memcpy (mp->src_address.un.ip4, src_address.data,
10836           sizeof (src_address.data));
10837   mp->vrf_id = htonl (vrf_id);
10838   mp->path_mtu = htonl (path_mtu);
10839   mp->template_interval = htonl (template_interval);
10840   mp->udp_checksum = udp_checksum;
10841
10842   S (mp);
10843   W (ret);
10844   return ret;
10845 }
10846
10847 static int
10848 api_set_ipfix_classify_stream (vat_main_t * vam)
10849 {
10850   unformat_input_t *i = vam->input;
10851   vl_api_set_ipfix_classify_stream_t *mp;
10852   u32 domain_id = 0;
10853   u32 src_port = UDP_DST_PORT_ipfix;
10854   int ret;
10855
10856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10857     {
10858       if (unformat (i, "domain %d", &domain_id))
10859         ;
10860       else if (unformat (i, "src_port %d", &src_port))
10861         ;
10862       else
10863         {
10864           errmsg ("unknown input `%U'", format_unformat_error, i);
10865           return -99;
10866         }
10867     }
10868
10869   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10870
10871   mp->domain_id = htonl (domain_id);
10872   mp->src_port = htons ((u16) src_port);
10873
10874   S (mp);
10875   W (ret);
10876   return ret;
10877 }
10878
10879 static int
10880 api_ipfix_classify_table_add_del (vat_main_t * vam)
10881 {
10882   unformat_input_t *i = vam->input;
10883   vl_api_ipfix_classify_table_add_del_t *mp;
10884   int is_add = -1;
10885   u32 classify_table_index = ~0;
10886   u8 ip_version = 0;
10887   u8 transport_protocol = 255;
10888   int ret;
10889
10890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10891     {
10892       if (unformat (i, "add"))
10893         is_add = 1;
10894       else if (unformat (i, "del"))
10895         is_add = 0;
10896       else if (unformat (i, "table %d", &classify_table_index))
10897         ;
10898       else if (unformat (i, "ip4"))
10899         ip_version = 4;
10900       else if (unformat (i, "ip6"))
10901         ip_version = 6;
10902       else if (unformat (i, "tcp"))
10903         transport_protocol = 6;
10904       else if (unformat (i, "udp"))
10905         transport_protocol = 17;
10906       else
10907         {
10908           errmsg ("unknown input `%U'", format_unformat_error, i);
10909           return -99;
10910         }
10911     }
10912
10913   if (is_add == -1)
10914     {
10915       errmsg ("expecting: add|del");
10916       return -99;
10917     }
10918   if (classify_table_index == ~0)
10919     {
10920       errmsg ("classifier table not specified");
10921       return -99;
10922     }
10923   if (ip_version == 0)
10924     {
10925       errmsg ("IP version not specified");
10926       return -99;
10927     }
10928
10929   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10930
10931   mp->is_add = is_add;
10932   mp->table_id = htonl (classify_table_index);
10933   mp->ip_version = ip_version;
10934   mp->transport_protocol = transport_protocol;
10935
10936   S (mp);
10937   W (ret);
10938   return ret;
10939 }
10940
10941 static int
10942 api_get_node_index (vat_main_t * vam)
10943 {
10944   unformat_input_t *i = vam->input;
10945   vl_api_get_node_index_t *mp;
10946   u8 *name = 0;
10947   int ret;
10948
10949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10950     {
10951       if (unformat (i, "node %s", &name))
10952         ;
10953       else
10954         break;
10955     }
10956   if (name == 0)
10957     {
10958       errmsg ("node name required");
10959       return -99;
10960     }
10961   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10962     {
10963       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10964       return -99;
10965     }
10966
10967   M (GET_NODE_INDEX, mp);
10968   clib_memcpy (mp->node_name, name, vec_len (name));
10969   vec_free (name);
10970
10971   S (mp);
10972   W (ret);
10973   return ret;
10974 }
10975
10976 static int
10977 api_get_next_index (vat_main_t * vam)
10978 {
10979   unformat_input_t *i = vam->input;
10980   vl_api_get_next_index_t *mp;
10981   u8 *node_name = 0, *next_node_name = 0;
10982   int ret;
10983
10984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10985     {
10986       if (unformat (i, "node-name %s", &node_name))
10987         ;
10988       else if (unformat (i, "next-node-name %s", &next_node_name))
10989         break;
10990     }
10991
10992   if (node_name == 0)
10993     {
10994       errmsg ("node name required");
10995       return -99;
10996     }
10997   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10998     {
10999       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11000       return -99;
11001     }
11002
11003   if (next_node_name == 0)
11004     {
11005       errmsg ("next node name required");
11006       return -99;
11007     }
11008   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11009     {
11010       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11011       return -99;
11012     }
11013
11014   M (GET_NEXT_INDEX, mp);
11015   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11016   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11017   vec_free (node_name);
11018   vec_free (next_node_name);
11019
11020   S (mp);
11021   W (ret);
11022   return ret;
11023 }
11024
11025 static int
11026 api_add_node_next (vat_main_t * vam)
11027 {
11028   unformat_input_t *i = vam->input;
11029   vl_api_add_node_next_t *mp;
11030   u8 *name = 0;
11031   u8 *next = 0;
11032   int ret;
11033
11034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11035     {
11036       if (unformat (i, "node %s", &name))
11037         ;
11038       else if (unformat (i, "next %s", &next))
11039         ;
11040       else
11041         break;
11042     }
11043   if (name == 0)
11044     {
11045       errmsg ("node name required");
11046       return -99;
11047     }
11048   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11049     {
11050       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11051       return -99;
11052     }
11053   if (next == 0)
11054     {
11055       errmsg ("next node required");
11056       return -99;
11057     }
11058   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11059     {
11060       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11061       return -99;
11062     }
11063
11064   M (ADD_NODE_NEXT, mp);
11065   clib_memcpy (mp->node_name, name, vec_len (name));
11066   clib_memcpy (mp->next_name, next, vec_len (next));
11067   vec_free (name);
11068   vec_free (next);
11069
11070   S (mp);
11071   W (ret);
11072   return ret;
11073 }
11074
11075 static int
11076 api_l2tpv3_create_tunnel (vat_main_t * vam)
11077 {
11078   unformat_input_t *i = vam->input;
11079   ip6_address_t client_address, our_address;
11080   int client_address_set = 0;
11081   int our_address_set = 0;
11082   u32 local_session_id = 0;
11083   u32 remote_session_id = 0;
11084   u64 local_cookie = 0;
11085   u64 remote_cookie = 0;
11086   u8 l2_sublayer_present = 0;
11087   vl_api_l2tpv3_create_tunnel_t *mp;
11088   int ret;
11089
11090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11091     {
11092       if (unformat (i, "client_address %U", unformat_ip6_address,
11093                     &client_address))
11094         client_address_set = 1;
11095       else if (unformat (i, "our_address %U", unformat_ip6_address,
11096                          &our_address))
11097         our_address_set = 1;
11098       else if (unformat (i, "local_session_id %d", &local_session_id))
11099         ;
11100       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11101         ;
11102       else if (unformat (i, "local_cookie %lld", &local_cookie))
11103         ;
11104       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11105         ;
11106       else if (unformat (i, "l2-sublayer-present"))
11107         l2_sublayer_present = 1;
11108       else
11109         break;
11110     }
11111
11112   if (client_address_set == 0)
11113     {
11114       errmsg ("client_address required");
11115       return -99;
11116     }
11117
11118   if (our_address_set == 0)
11119     {
11120       errmsg ("our_address required");
11121       return -99;
11122     }
11123
11124   M (L2TPV3_CREATE_TUNNEL, mp);
11125
11126   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11127                sizeof (ip6_address_t));
11128
11129   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11130                sizeof (ip6_address_t));
11131
11132   mp->local_session_id = ntohl (local_session_id);
11133   mp->remote_session_id = ntohl (remote_session_id);
11134   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11135   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11136   mp->l2_sublayer_present = l2_sublayer_present;
11137
11138   S (mp);
11139   W (ret);
11140   return ret;
11141 }
11142
11143 static int
11144 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11145 {
11146   unformat_input_t *i = vam->input;
11147   u32 sw_if_index;
11148   u8 sw_if_index_set = 0;
11149   u64 new_local_cookie = 0;
11150   u64 new_remote_cookie = 0;
11151   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11152   int ret;
11153
11154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11155     {
11156       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11157         sw_if_index_set = 1;
11158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11159         sw_if_index_set = 1;
11160       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11161         ;
11162       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11163         ;
11164       else
11165         break;
11166     }
11167
11168   if (sw_if_index_set == 0)
11169     {
11170       errmsg ("missing interface name or sw_if_index");
11171       return -99;
11172     }
11173
11174   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11175
11176   mp->sw_if_index = ntohl (sw_if_index);
11177   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11178   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11179
11180   S (mp);
11181   W (ret);
11182   return ret;
11183 }
11184
11185 static int
11186 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11187 {
11188   unformat_input_t *i = vam->input;
11189   vl_api_l2tpv3_interface_enable_disable_t *mp;
11190   u32 sw_if_index;
11191   u8 sw_if_index_set = 0;
11192   u8 enable_disable = 1;
11193   int ret;
11194
11195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11196     {
11197       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11198         sw_if_index_set = 1;
11199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11200         sw_if_index_set = 1;
11201       else if (unformat (i, "enable"))
11202         enable_disable = 1;
11203       else if (unformat (i, "disable"))
11204         enable_disable = 0;
11205       else
11206         break;
11207     }
11208
11209   if (sw_if_index_set == 0)
11210     {
11211       errmsg ("missing interface name or sw_if_index");
11212       return -99;
11213     }
11214
11215   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11216
11217   mp->sw_if_index = ntohl (sw_if_index);
11218   mp->enable_disable = enable_disable;
11219
11220   S (mp);
11221   W (ret);
11222   return ret;
11223 }
11224
11225 static int
11226 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11227 {
11228   unformat_input_t *i = vam->input;
11229   vl_api_l2tpv3_set_lookup_key_t *mp;
11230   u8 key = ~0;
11231   int ret;
11232
11233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11234     {
11235       if (unformat (i, "lookup_v6_src"))
11236         key = L2T_LOOKUP_SRC_ADDRESS;
11237       else if (unformat (i, "lookup_v6_dst"))
11238         key = L2T_LOOKUP_DST_ADDRESS;
11239       else if (unformat (i, "lookup_session_id"))
11240         key = L2T_LOOKUP_SESSION_ID;
11241       else
11242         break;
11243     }
11244
11245   if (key == (u8) ~ 0)
11246     {
11247       errmsg ("l2tp session lookup key unset");
11248       return -99;
11249     }
11250
11251   M (L2TPV3_SET_LOOKUP_KEY, mp);
11252
11253   mp->key = key;
11254
11255   S (mp);
11256   W (ret);
11257   return ret;
11258 }
11259
11260 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11261   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11262 {
11263   vat_main_t *vam = &vat_main;
11264
11265   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11266          format_ip6_address, mp->our_address,
11267          format_ip6_address, mp->client_address,
11268          clib_net_to_host_u32 (mp->sw_if_index));
11269
11270   print (vam->ofp,
11271          "   local cookies %016llx %016llx remote cookie %016llx",
11272          clib_net_to_host_u64 (mp->local_cookie[0]),
11273          clib_net_to_host_u64 (mp->local_cookie[1]),
11274          clib_net_to_host_u64 (mp->remote_cookie));
11275
11276   print (vam->ofp, "   local session-id %d remote session-id %d",
11277          clib_net_to_host_u32 (mp->local_session_id),
11278          clib_net_to_host_u32 (mp->remote_session_id));
11279
11280   print (vam->ofp, "   l2 specific sublayer %s\n",
11281          mp->l2_sublayer_present ? "preset" : "absent");
11282
11283 }
11284
11285 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11286   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11287 {
11288   vat_main_t *vam = &vat_main;
11289   vat_json_node_t *node = NULL;
11290   struct in6_addr addr;
11291
11292   if (VAT_JSON_ARRAY != vam->json_tree.type)
11293     {
11294       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11295       vat_json_init_array (&vam->json_tree);
11296     }
11297   node = vat_json_array_add (&vam->json_tree);
11298
11299   vat_json_init_object (node);
11300
11301   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11302   vat_json_object_add_ip6 (node, "our_address", addr);
11303   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11304   vat_json_object_add_ip6 (node, "client_address", addr);
11305
11306   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11307   vat_json_init_array (lc);
11308   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11309   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11310   vat_json_object_add_uint (node, "remote_cookie",
11311                             clib_net_to_host_u64 (mp->remote_cookie));
11312
11313   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11314   vat_json_object_add_uint (node, "local_session_id",
11315                             clib_net_to_host_u32 (mp->local_session_id));
11316   vat_json_object_add_uint (node, "remote_session_id",
11317                             clib_net_to_host_u32 (mp->remote_session_id));
11318   vat_json_object_add_string_copy (node, "l2_sublayer",
11319                                    mp->l2_sublayer_present ? (u8 *) "present"
11320                                    : (u8 *) "absent");
11321 }
11322
11323 static int
11324 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11325 {
11326   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11327   vl_api_control_ping_t *mp_ping;
11328   int ret;
11329
11330   /* Get list of l2tpv3-tunnel interfaces */
11331   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11332   S (mp);
11333
11334   /* Use a control ping for synchronization */
11335   MPING (CONTROL_PING, mp_ping);
11336   S (mp_ping);
11337
11338   W (ret);
11339   return ret;
11340 }
11341
11342
11343 static void vl_api_sw_interface_tap_v2_details_t_handler
11344   (vl_api_sw_interface_tap_v2_details_t * mp)
11345 {
11346   vat_main_t *vam = &vat_main;
11347
11348   u8 *ip4 =
11349     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11350             mp->host_ip4_prefix.len);
11351   u8 *ip6 =
11352     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11353             mp->host_ip6_prefix.len);
11354
11355   print (vam->ofp,
11356          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11357          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11358          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11359          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11360          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11361
11362   vec_free (ip4);
11363   vec_free (ip6);
11364 }
11365
11366 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11367   (vl_api_sw_interface_tap_v2_details_t * mp)
11368 {
11369   vat_main_t *vam = &vat_main;
11370   vat_json_node_t *node = NULL;
11371
11372   if (VAT_JSON_ARRAY != vam->json_tree.type)
11373     {
11374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11375       vat_json_init_array (&vam->json_tree);
11376     }
11377   node = vat_json_array_add (&vam->json_tree);
11378
11379   vat_json_init_object (node);
11380   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11381   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11382   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11383   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11384   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11385   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11386   vat_json_object_add_string_copy (node, "host_mac_addr",
11387                                    format (0, "%U", format_ethernet_address,
11388                                            &mp->host_mac_addr));
11389   vat_json_object_add_string_copy (node, "host_namespace",
11390                                    mp->host_namespace);
11391   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11392   vat_json_object_add_string_copy (node, "host_ip4_addr",
11393                                    format (0, "%U/%d", format_ip4_address,
11394                                            mp->host_ip4_prefix.address,
11395                                            mp->host_ip4_prefix.len));
11396   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11397                                    format (0, "%U/%d", format_ip6_address,
11398                                            mp->host_ip6_prefix.address,
11399                                            mp->host_ip6_prefix.len));
11400
11401 }
11402
11403 static int
11404 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11405 {
11406   vl_api_sw_interface_tap_v2_dump_t *mp;
11407   vl_api_control_ping_t *mp_ping;
11408   int ret;
11409
11410   print (vam->ofp,
11411          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11412          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11413          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11414          "host_ip6_addr");
11415
11416   /* Get list of tap interfaces */
11417   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11418   S (mp);
11419
11420   /* Use a control ping for synchronization */
11421   MPING (CONTROL_PING, mp_ping);
11422   S (mp_ping);
11423
11424   W (ret);
11425   return ret;
11426 }
11427
11428 static void vl_api_sw_interface_virtio_pci_details_t_handler
11429   (vl_api_sw_interface_virtio_pci_details_t * mp)
11430 {
11431   vat_main_t *vam = &vat_main;
11432
11433   typedef union
11434   {
11435     struct
11436     {
11437       u16 domain;
11438       u8 bus;
11439       u8 slot:5;
11440       u8 function:3;
11441     };
11442     u32 as_u32;
11443   } pci_addr_t;
11444   pci_addr_t addr;
11445
11446   addr.domain = ntohs (mp->pci_addr.domain);
11447   addr.bus = mp->pci_addr.bus;
11448   addr.slot = mp->pci_addr.slot;
11449   addr.function = mp->pci_addr.function;
11450
11451   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11452                          addr.slot, addr.function);
11453
11454   print (vam->ofp,
11455          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11456          pci_addr, ntohl (mp->sw_if_index),
11457          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11458          format_ethernet_address, mp->mac_addr,
11459          clib_net_to_host_u64 (mp->features));
11460   vec_free (pci_addr);
11461 }
11462
11463 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11464   (vl_api_sw_interface_virtio_pci_details_t * mp)
11465 {
11466   vat_main_t *vam = &vat_main;
11467   vat_json_node_t *node = NULL;
11468   vlib_pci_addr_t pci_addr;
11469
11470   if (VAT_JSON_ARRAY != vam->json_tree.type)
11471     {
11472       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11473       vat_json_init_array (&vam->json_tree);
11474     }
11475   node = vat_json_array_add (&vam->json_tree);
11476
11477   pci_addr.domain = ntohs (mp->pci_addr.domain);
11478   pci_addr.bus = mp->pci_addr.bus;
11479   pci_addr.slot = mp->pci_addr.slot;
11480   pci_addr.function = mp->pci_addr.function;
11481
11482   vat_json_init_object (node);
11483   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11484   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11485   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11486   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11487   vat_json_object_add_uint (node, "features",
11488                             clib_net_to_host_u64 (mp->features));
11489   vat_json_object_add_string_copy (node, "mac_addr",
11490                                    format (0, "%U", format_ethernet_address,
11491                                            &mp->mac_addr));
11492 }
11493
11494 static int
11495 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11496 {
11497   vl_api_sw_interface_virtio_pci_dump_t *mp;
11498   vl_api_control_ping_t *mp_ping;
11499   int ret;
11500
11501   print (vam->ofp,
11502          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11503          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11504          "mac_addr", "features");
11505
11506   /* Get list of tap interfaces */
11507   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11508   S (mp);
11509
11510   /* Use a control ping for synchronization */
11511   MPING (CONTROL_PING, mp_ping);
11512   S (mp_ping);
11513
11514   W (ret);
11515   return ret;
11516 }
11517
11518 static int
11519 api_vxlan_offload_rx (vat_main_t * vam)
11520 {
11521   unformat_input_t *line_input = vam->input;
11522   vl_api_vxlan_offload_rx_t *mp;
11523   u32 hw_if_index = ~0, rx_if_index = ~0;
11524   u8 is_add = 1;
11525   int ret;
11526
11527   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11528     {
11529       if (unformat (line_input, "del"))
11530         is_add = 0;
11531       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11532                          &hw_if_index))
11533         ;
11534       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11535         ;
11536       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11537                          &rx_if_index))
11538         ;
11539       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11540         ;
11541       else
11542         {
11543           errmsg ("parse error '%U'", format_unformat_error, line_input);
11544           return -99;
11545         }
11546     }
11547
11548   if (hw_if_index == ~0)
11549     {
11550       errmsg ("no hw interface");
11551       return -99;
11552     }
11553
11554   if (rx_if_index == ~0)
11555     {
11556       errmsg ("no rx tunnel");
11557       return -99;
11558     }
11559
11560   M (VXLAN_OFFLOAD_RX, mp);
11561
11562   mp->hw_if_index = ntohl (hw_if_index);
11563   mp->sw_if_index = ntohl (rx_if_index);
11564   mp->enable = is_add;
11565
11566   S (mp);
11567   W (ret);
11568   return ret;
11569 }
11570
11571 static uword unformat_vxlan_decap_next
11572   (unformat_input_t * input, va_list * args)
11573 {
11574   u32 *result = va_arg (*args, u32 *);
11575   u32 tmp;
11576
11577   if (unformat (input, "l2"))
11578     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11579   else if (unformat (input, "%d", &tmp))
11580     *result = tmp;
11581   else
11582     return 0;
11583   return 1;
11584 }
11585
11586 static int
11587 api_vxlan_add_del_tunnel (vat_main_t * vam)
11588 {
11589   unformat_input_t *line_input = vam->input;
11590   vl_api_vxlan_add_del_tunnel_t *mp;
11591   ip46_address_t src, dst;
11592   u8 is_add = 1;
11593   u8 ipv4_set = 0, ipv6_set = 0;
11594   u8 src_set = 0;
11595   u8 dst_set = 0;
11596   u8 grp_set = 0;
11597   u32 instance = ~0;
11598   u32 mcast_sw_if_index = ~0;
11599   u32 encap_vrf_id = 0;
11600   u32 decap_next_index = ~0;
11601   u32 vni = 0;
11602   int ret;
11603
11604   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11605   clib_memset (&src, 0, sizeof src);
11606   clib_memset (&dst, 0, sizeof dst);
11607
11608   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11609     {
11610       if (unformat (line_input, "del"))
11611         is_add = 0;
11612       else if (unformat (line_input, "instance %d", &instance))
11613         ;
11614       else
11615         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11616         {
11617           ipv4_set = 1;
11618           src_set = 1;
11619         }
11620       else
11621         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11622         {
11623           ipv4_set = 1;
11624           dst_set = 1;
11625         }
11626       else
11627         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11628         {
11629           ipv6_set = 1;
11630           src_set = 1;
11631         }
11632       else
11633         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11634         {
11635           ipv6_set = 1;
11636           dst_set = 1;
11637         }
11638       else if (unformat (line_input, "group %U %U",
11639                          unformat_ip4_address, &dst.ip4,
11640                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11641         {
11642           grp_set = dst_set = 1;
11643           ipv4_set = 1;
11644         }
11645       else if (unformat (line_input, "group %U",
11646                          unformat_ip4_address, &dst.ip4))
11647         {
11648           grp_set = dst_set = 1;
11649           ipv4_set = 1;
11650         }
11651       else if (unformat (line_input, "group %U %U",
11652                          unformat_ip6_address, &dst.ip6,
11653                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11654         {
11655           grp_set = dst_set = 1;
11656           ipv6_set = 1;
11657         }
11658       else if (unformat (line_input, "group %U",
11659                          unformat_ip6_address, &dst.ip6))
11660         {
11661           grp_set = dst_set = 1;
11662           ipv6_set = 1;
11663         }
11664       else
11665         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11666         ;
11667       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11668         ;
11669       else if (unformat (line_input, "decap-next %U",
11670                          unformat_vxlan_decap_next, &decap_next_index))
11671         ;
11672       else if (unformat (line_input, "vni %d", &vni))
11673         ;
11674       else
11675         {
11676           errmsg ("parse error '%U'", format_unformat_error, line_input);
11677           return -99;
11678         }
11679     }
11680
11681   if (src_set == 0)
11682     {
11683       errmsg ("tunnel src address not specified");
11684       return -99;
11685     }
11686   if (dst_set == 0)
11687     {
11688       errmsg ("tunnel dst address not specified");
11689       return -99;
11690     }
11691
11692   if (grp_set && !ip46_address_is_multicast (&dst))
11693     {
11694       errmsg ("tunnel group address not multicast");
11695       return -99;
11696     }
11697   if (grp_set && mcast_sw_if_index == ~0)
11698     {
11699       errmsg ("tunnel nonexistent multicast device");
11700       return -99;
11701     }
11702   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11703     {
11704       errmsg ("tunnel dst address must be unicast");
11705       return -99;
11706     }
11707
11708
11709   if (ipv4_set && ipv6_set)
11710     {
11711       errmsg ("both IPv4 and IPv6 addresses specified");
11712       return -99;
11713     }
11714
11715   if ((vni == 0) || (vni >> 24))
11716     {
11717       errmsg ("vni not specified or out of range");
11718       return -99;
11719     }
11720
11721   M (VXLAN_ADD_DEL_TUNNEL, mp);
11722
11723   if (ipv6_set)
11724     {
11725       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11726       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11727     }
11728   else
11729     {
11730       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11731       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11732     }
11733   mp->src_address.af = ipv6_set;
11734   mp->dst_address.af = ipv6_set;
11735
11736   mp->instance = htonl (instance);
11737   mp->encap_vrf_id = ntohl (encap_vrf_id);
11738   mp->decap_next_index = ntohl (decap_next_index);
11739   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11740   mp->vni = ntohl (vni);
11741   mp->is_add = is_add;
11742
11743   S (mp);
11744   W (ret);
11745   return ret;
11746 }
11747
11748 static void vl_api_vxlan_tunnel_details_t_handler
11749   (vl_api_vxlan_tunnel_details_t * mp)
11750 {
11751   vat_main_t *vam = &vat_main;
11752   ip46_address_t src =
11753     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11754   ip46_address_t dst =
11755     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11756
11757   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11758          ntohl (mp->sw_if_index),
11759          ntohl (mp->instance),
11760          format_ip46_address, &src, IP46_TYPE_ANY,
11761          format_ip46_address, &dst, IP46_TYPE_ANY,
11762          ntohl (mp->encap_vrf_id),
11763          ntohl (mp->decap_next_index), ntohl (mp->vni),
11764          ntohl (mp->mcast_sw_if_index));
11765 }
11766
11767 static void vl_api_vxlan_tunnel_details_t_handler_json
11768   (vl_api_vxlan_tunnel_details_t * mp)
11769 {
11770   vat_main_t *vam = &vat_main;
11771   vat_json_node_t *node = NULL;
11772
11773   if (VAT_JSON_ARRAY != vam->json_tree.type)
11774     {
11775       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11776       vat_json_init_array (&vam->json_tree);
11777     }
11778   node = vat_json_array_add (&vam->json_tree);
11779
11780   vat_json_init_object (node);
11781   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11782
11783   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11784
11785   if (mp->src_address.af)
11786     {
11787       struct in6_addr ip6;
11788
11789       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11790       vat_json_object_add_ip6 (node, "src_address", ip6);
11791       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11792       vat_json_object_add_ip6 (node, "dst_address", ip6);
11793     }
11794   else
11795     {
11796       struct in_addr ip4;
11797
11798       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11799       vat_json_object_add_ip4 (node, "src_address", ip4);
11800       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11801       vat_json_object_add_ip4 (node, "dst_address", ip4);
11802     }
11803   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11804   vat_json_object_add_uint (node, "decap_next_index",
11805                             ntohl (mp->decap_next_index));
11806   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11807   vat_json_object_add_uint (node, "mcast_sw_if_index",
11808                             ntohl (mp->mcast_sw_if_index));
11809 }
11810
11811 static int
11812 api_vxlan_tunnel_dump (vat_main_t * vam)
11813 {
11814   unformat_input_t *i = vam->input;
11815   vl_api_vxlan_tunnel_dump_t *mp;
11816   vl_api_control_ping_t *mp_ping;
11817   u32 sw_if_index;
11818   u8 sw_if_index_set = 0;
11819   int ret;
11820
11821   /* Parse args required to build the message */
11822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11823     {
11824       if (unformat (i, "sw_if_index %d", &sw_if_index))
11825         sw_if_index_set = 1;
11826       else
11827         break;
11828     }
11829
11830   if (sw_if_index_set == 0)
11831     {
11832       sw_if_index = ~0;
11833     }
11834
11835   if (!vam->json_output)
11836     {
11837       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11838              "sw_if_index", "instance", "src_address", "dst_address",
11839              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11840     }
11841
11842   /* Get list of vxlan-tunnel interfaces */
11843   M (VXLAN_TUNNEL_DUMP, mp);
11844
11845   mp->sw_if_index = htonl (sw_if_index);
11846
11847   S (mp);
11848
11849   /* Use a control ping for synchronization */
11850   MPING (CONTROL_PING, mp_ping);
11851   S (mp_ping);
11852
11853   W (ret);
11854   return ret;
11855 }
11856
11857 static uword unformat_geneve_decap_next
11858   (unformat_input_t * input, va_list * args)
11859 {
11860   u32 *result = va_arg (*args, u32 *);
11861   u32 tmp;
11862
11863   if (unformat (input, "l2"))
11864     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11865   else if (unformat (input, "%d", &tmp))
11866     *result = tmp;
11867   else
11868     return 0;
11869   return 1;
11870 }
11871
11872 static int
11873 api_geneve_add_del_tunnel (vat_main_t * vam)
11874 {
11875   unformat_input_t *line_input = vam->input;
11876   vl_api_geneve_add_del_tunnel_t *mp;
11877   ip46_address_t src, dst;
11878   u8 is_add = 1;
11879   u8 ipv4_set = 0, ipv6_set = 0;
11880   u8 src_set = 0;
11881   u8 dst_set = 0;
11882   u8 grp_set = 0;
11883   u32 mcast_sw_if_index = ~0;
11884   u32 encap_vrf_id = 0;
11885   u32 decap_next_index = ~0;
11886   u32 vni = 0;
11887   int ret;
11888
11889   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11890   clib_memset (&src, 0, sizeof src);
11891   clib_memset (&dst, 0, sizeof dst);
11892
11893   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11894     {
11895       if (unformat (line_input, "del"))
11896         is_add = 0;
11897       else
11898         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11899         {
11900           ipv4_set = 1;
11901           src_set = 1;
11902         }
11903       else
11904         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11905         {
11906           ipv4_set = 1;
11907           dst_set = 1;
11908         }
11909       else
11910         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11911         {
11912           ipv6_set = 1;
11913           src_set = 1;
11914         }
11915       else
11916         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11917         {
11918           ipv6_set = 1;
11919           dst_set = 1;
11920         }
11921       else if (unformat (line_input, "group %U %U",
11922                          unformat_ip4_address, &dst.ip4,
11923                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11924         {
11925           grp_set = dst_set = 1;
11926           ipv4_set = 1;
11927         }
11928       else if (unformat (line_input, "group %U",
11929                          unformat_ip4_address, &dst.ip4))
11930         {
11931           grp_set = dst_set = 1;
11932           ipv4_set = 1;
11933         }
11934       else if (unformat (line_input, "group %U %U",
11935                          unformat_ip6_address, &dst.ip6,
11936                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11937         {
11938           grp_set = dst_set = 1;
11939           ipv6_set = 1;
11940         }
11941       else if (unformat (line_input, "group %U",
11942                          unformat_ip6_address, &dst.ip6))
11943         {
11944           grp_set = dst_set = 1;
11945           ipv6_set = 1;
11946         }
11947       else
11948         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11949         ;
11950       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11951         ;
11952       else if (unformat (line_input, "decap-next %U",
11953                          unformat_geneve_decap_next, &decap_next_index))
11954         ;
11955       else if (unformat (line_input, "vni %d", &vni))
11956         ;
11957       else
11958         {
11959           errmsg ("parse error '%U'", format_unformat_error, line_input);
11960           return -99;
11961         }
11962     }
11963
11964   if (src_set == 0)
11965     {
11966       errmsg ("tunnel src address not specified");
11967       return -99;
11968     }
11969   if (dst_set == 0)
11970     {
11971       errmsg ("tunnel dst address not specified");
11972       return -99;
11973     }
11974
11975   if (grp_set && !ip46_address_is_multicast (&dst))
11976     {
11977       errmsg ("tunnel group address not multicast");
11978       return -99;
11979     }
11980   if (grp_set && mcast_sw_if_index == ~0)
11981     {
11982       errmsg ("tunnel nonexistent multicast device");
11983       return -99;
11984     }
11985   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11986     {
11987       errmsg ("tunnel dst address must be unicast");
11988       return -99;
11989     }
11990
11991
11992   if (ipv4_set && ipv6_set)
11993     {
11994       errmsg ("both IPv4 and IPv6 addresses specified");
11995       return -99;
11996     }
11997
11998   if ((vni == 0) || (vni >> 24))
11999     {
12000       errmsg ("vni not specified or out of range");
12001       return -99;
12002     }
12003
12004   M (GENEVE_ADD_DEL_TUNNEL, mp);
12005
12006   if (ipv6_set)
12007     {
12008       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12009       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12010     }
12011   else
12012     {
12013       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12014       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12015     }
12016   mp->encap_vrf_id = ntohl (encap_vrf_id);
12017   mp->decap_next_index = ntohl (decap_next_index);
12018   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12019   mp->vni = ntohl (vni);
12020   mp->is_add = is_add;
12021
12022   S (mp);
12023   W (ret);
12024   return ret;
12025 }
12026
12027 static void vl_api_geneve_tunnel_details_t_handler
12028   (vl_api_geneve_tunnel_details_t * mp)
12029 {
12030   vat_main_t *vam = &vat_main;
12031   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12032   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12033
12034   if (mp->src_address.af == ADDRESS_IP6)
12035     {
12036       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12037       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12038     }
12039   else
12040     {
12041       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12042       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12043     }
12044
12045   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12046          ntohl (mp->sw_if_index),
12047          format_ip46_address, &src, IP46_TYPE_ANY,
12048          format_ip46_address, &dst, IP46_TYPE_ANY,
12049          ntohl (mp->encap_vrf_id),
12050          ntohl (mp->decap_next_index), ntohl (mp->vni),
12051          ntohl (mp->mcast_sw_if_index));
12052 }
12053
12054 static void vl_api_geneve_tunnel_details_t_handler_json
12055   (vl_api_geneve_tunnel_details_t * mp)
12056 {
12057   vat_main_t *vam = &vat_main;
12058   vat_json_node_t *node = NULL;
12059   bool is_ipv6;
12060
12061   if (VAT_JSON_ARRAY != vam->json_tree.type)
12062     {
12063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12064       vat_json_init_array (&vam->json_tree);
12065     }
12066   node = vat_json_array_add (&vam->json_tree);
12067
12068   vat_json_init_object (node);
12069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12070   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12071   if (is_ipv6)
12072     {
12073       struct in6_addr ip6;
12074
12075       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12076       vat_json_object_add_ip6 (node, "src_address", ip6);
12077       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12078       vat_json_object_add_ip6 (node, "dst_address", ip6);
12079     }
12080   else
12081     {
12082       struct in_addr ip4;
12083
12084       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12085       vat_json_object_add_ip4 (node, "src_address", ip4);
12086       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12087       vat_json_object_add_ip4 (node, "dst_address", ip4);
12088     }
12089   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12090   vat_json_object_add_uint (node, "decap_next_index",
12091                             ntohl (mp->decap_next_index));
12092   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12093   vat_json_object_add_uint (node, "mcast_sw_if_index",
12094                             ntohl (mp->mcast_sw_if_index));
12095 }
12096
12097 static int
12098 api_geneve_tunnel_dump (vat_main_t * vam)
12099 {
12100   unformat_input_t *i = vam->input;
12101   vl_api_geneve_tunnel_dump_t *mp;
12102   vl_api_control_ping_t *mp_ping;
12103   u32 sw_if_index;
12104   u8 sw_if_index_set = 0;
12105   int ret;
12106
12107   /* Parse args required to build the message */
12108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12109     {
12110       if (unformat (i, "sw_if_index %d", &sw_if_index))
12111         sw_if_index_set = 1;
12112       else
12113         break;
12114     }
12115
12116   if (sw_if_index_set == 0)
12117     {
12118       sw_if_index = ~0;
12119     }
12120
12121   if (!vam->json_output)
12122     {
12123       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12124              "sw_if_index", "local_address", "remote_address",
12125              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12126     }
12127
12128   /* Get list of geneve-tunnel interfaces */
12129   M (GENEVE_TUNNEL_DUMP, mp);
12130
12131   mp->sw_if_index = htonl (sw_if_index);
12132
12133   S (mp);
12134
12135   /* Use a control ping for synchronization */
12136   M (CONTROL_PING, mp_ping);
12137   S (mp_ping);
12138
12139   W (ret);
12140   return ret;
12141 }
12142
12143 static int
12144 api_gre_tunnel_add_del (vat_main_t * vam)
12145 {
12146   unformat_input_t *line_input = vam->input;
12147   vl_api_address_t src = { }, dst =
12148   {
12149   };
12150   vl_api_gre_tunnel_add_del_t *mp;
12151   vl_api_gre_tunnel_type_t t_type;
12152   u8 is_add = 1;
12153   u8 src_set = 0;
12154   u8 dst_set = 0;
12155   u32 outer_table_id = 0;
12156   u32 session_id = 0;
12157   u32 instance = ~0;
12158   int ret;
12159
12160   t_type = GRE_API_TUNNEL_TYPE_L3;
12161
12162   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12163     {
12164       if (unformat (line_input, "del"))
12165         is_add = 0;
12166       else if (unformat (line_input, "instance %d", &instance))
12167         ;
12168       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12169         {
12170           src_set = 1;
12171         }
12172       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12173         {
12174           dst_set = 1;
12175         }
12176       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12177         ;
12178       else if (unformat (line_input, "teb"))
12179         t_type = GRE_API_TUNNEL_TYPE_TEB;
12180       else if (unformat (line_input, "erspan %d", &session_id))
12181         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12182       else
12183         {
12184           errmsg ("parse error '%U'", format_unformat_error, line_input);
12185           return -99;
12186         }
12187     }
12188
12189   if (src_set == 0)
12190     {
12191       errmsg ("tunnel src address not specified");
12192       return -99;
12193     }
12194   if (dst_set == 0)
12195     {
12196       errmsg ("tunnel dst address not specified");
12197       return -99;
12198     }
12199
12200   M (GRE_TUNNEL_ADD_DEL, mp);
12201
12202   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12203   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12204
12205   mp->tunnel.instance = htonl (instance);
12206   mp->tunnel.outer_table_id = htonl (outer_table_id);
12207   mp->is_add = is_add;
12208   mp->tunnel.session_id = htons ((u16) session_id);
12209   mp->tunnel.type = htonl (t_type);
12210
12211   S (mp);
12212   W (ret);
12213   return ret;
12214 }
12215
12216 static void vl_api_gre_tunnel_details_t_handler
12217   (vl_api_gre_tunnel_details_t * mp)
12218 {
12219   vat_main_t *vam = &vat_main;
12220
12221   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12222          ntohl (mp->tunnel.sw_if_index),
12223          ntohl (mp->tunnel.instance),
12224          format_vl_api_address, &mp->tunnel.src,
12225          format_vl_api_address, &mp->tunnel.dst,
12226          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12227          ntohl (mp->tunnel.session_id));
12228 }
12229
12230 static void vl_api_gre_tunnel_details_t_handler_json
12231   (vl_api_gre_tunnel_details_t * mp)
12232 {
12233   vat_main_t *vam = &vat_main;
12234   vat_json_node_t *node = NULL;
12235
12236   if (VAT_JSON_ARRAY != vam->json_tree.type)
12237     {
12238       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12239       vat_json_init_array (&vam->json_tree);
12240     }
12241   node = vat_json_array_add (&vam->json_tree);
12242
12243   vat_json_init_object (node);
12244   vat_json_object_add_uint (node, "sw_if_index",
12245                             ntohl (mp->tunnel.sw_if_index));
12246   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12247
12248   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12249   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12250   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12251   vat_json_object_add_uint (node, "outer_table_id",
12252                             ntohl (mp->tunnel.outer_table_id));
12253   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12254 }
12255
12256 static int
12257 api_gre_tunnel_dump (vat_main_t * vam)
12258 {
12259   unformat_input_t *i = vam->input;
12260   vl_api_gre_tunnel_dump_t *mp;
12261   vl_api_control_ping_t *mp_ping;
12262   u32 sw_if_index;
12263   u8 sw_if_index_set = 0;
12264   int ret;
12265
12266   /* Parse args required to build the message */
12267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12268     {
12269       if (unformat (i, "sw_if_index %d", &sw_if_index))
12270         sw_if_index_set = 1;
12271       else
12272         break;
12273     }
12274
12275   if (sw_if_index_set == 0)
12276     {
12277       sw_if_index = ~0;
12278     }
12279
12280   if (!vam->json_output)
12281     {
12282       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12283              "sw_if_index", "instance", "src_address", "dst_address",
12284              "tunnel_type", "outer_fib_id", "session_id");
12285     }
12286
12287   /* Get list of gre-tunnel interfaces */
12288   M (GRE_TUNNEL_DUMP, mp);
12289
12290   mp->sw_if_index = htonl (sw_if_index);
12291
12292   S (mp);
12293
12294   /* Use a control ping for synchronization */
12295   MPING (CONTROL_PING, mp_ping);
12296   S (mp_ping);
12297
12298   W (ret);
12299   return ret;
12300 }
12301
12302 static int
12303 api_l2_fib_clear_table (vat_main_t * vam)
12304 {
12305 //  unformat_input_t * i = vam->input;
12306   vl_api_l2_fib_clear_table_t *mp;
12307   int ret;
12308
12309   M (L2_FIB_CLEAR_TABLE, mp);
12310
12311   S (mp);
12312   W (ret);
12313   return ret;
12314 }
12315
12316 static int
12317 api_l2_interface_efp_filter (vat_main_t * vam)
12318 {
12319   unformat_input_t *i = vam->input;
12320   vl_api_l2_interface_efp_filter_t *mp;
12321   u32 sw_if_index;
12322   u8 enable = 1;
12323   u8 sw_if_index_set = 0;
12324   int ret;
12325
12326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12327     {
12328       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12329         sw_if_index_set = 1;
12330       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12331         sw_if_index_set = 1;
12332       else if (unformat (i, "enable"))
12333         enable = 1;
12334       else if (unformat (i, "disable"))
12335         enable = 0;
12336       else
12337         {
12338           clib_warning ("parse error '%U'", format_unformat_error, i);
12339           return -99;
12340         }
12341     }
12342
12343   if (sw_if_index_set == 0)
12344     {
12345       errmsg ("missing sw_if_index");
12346       return -99;
12347     }
12348
12349   M (L2_INTERFACE_EFP_FILTER, mp);
12350
12351   mp->sw_if_index = ntohl (sw_if_index);
12352   mp->enable_disable = enable;
12353
12354   S (mp);
12355   W (ret);
12356   return ret;
12357 }
12358
12359 #define foreach_vtr_op                          \
12360 _("disable",  L2_VTR_DISABLED)                  \
12361 _("push-1",  L2_VTR_PUSH_1)                     \
12362 _("push-2",  L2_VTR_PUSH_2)                     \
12363 _("pop-1",  L2_VTR_POP_1)                       \
12364 _("pop-2",  L2_VTR_POP_2)                       \
12365 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12366 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12367 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12368 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12369
12370 static int
12371 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12372 {
12373   unformat_input_t *i = vam->input;
12374   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12375   u32 sw_if_index;
12376   u8 sw_if_index_set = 0;
12377   u8 vtr_op_set = 0;
12378   u32 vtr_op = 0;
12379   u32 push_dot1q = 1;
12380   u32 tag1 = ~0;
12381   u32 tag2 = ~0;
12382   int ret;
12383
12384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12385     {
12386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12387         sw_if_index_set = 1;
12388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12389         sw_if_index_set = 1;
12390       else if (unformat (i, "vtr_op %d", &vtr_op))
12391         vtr_op_set = 1;
12392 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12393       foreach_vtr_op
12394 #undef _
12395         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12396         ;
12397       else if (unformat (i, "tag1 %d", &tag1))
12398         ;
12399       else if (unformat (i, "tag2 %d", &tag2))
12400         ;
12401       else
12402         {
12403           clib_warning ("parse error '%U'", format_unformat_error, i);
12404           return -99;
12405         }
12406     }
12407
12408   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12409     {
12410       errmsg ("missing vtr operation or sw_if_index");
12411       return -99;
12412     }
12413
12414   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12415   mp->sw_if_index = ntohl (sw_if_index);
12416   mp->vtr_op = ntohl (vtr_op);
12417   mp->push_dot1q = ntohl (push_dot1q);
12418   mp->tag1 = ntohl (tag1);
12419   mp->tag2 = ntohl (tag2);
12420
12421   S (mp);
12422   W (ret);
12423   return ret;
12424 }
12425
12426 static int
12427 api_create_vhost_user_if (vat_main_t * vam)
12428 {
12429   unformat_input_t *i = vam->input;
12430   vl_api_create_vhost_user_if_t *mp;
12431   u8 *file_name;
12432   u8 is_server = 0;
12433   u8 file_name_set = 0;
12434   u32 custom_dev_instance = ~0;
12435   u8 hwaddr[6];
12436   u8 use_custom_mac = 0;
12437   u8 disable_mrg_rxbuf = 0;
12438   u8 disable_indirect_desc = 0;
12439   u8 *tag = 0;
12440   u8 enable_gso = 0;
12441   u8 enable_packed = 0;
12442   int ret;
12443
12444   /* Shut up coverity */
12445   clib_memset (hwaddr, 0, sizeof (hwaddr));
12446
12447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12448     {
12449       if (unformat (i, "socket %s", &file_name))
12450         {
12451           file_name_set = 1;
12452         }
12453       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12454         ;
12455       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12456         use_custom_mac = 1;
12457       else if (unformat (i, "server"))
12458         is_server = 1;
12459       else if (unformat (i, "disable_mrg_rxbuf"))
12460         disable_mrg_rxbuf = 1;
12461       else if (unformat (i, "disable_indirect_desc"))
12462         disable_indirect_desc = 1;
12463       else if (unformat (i, "gso"))
12464         enable_gso = 1;
12465       else if (unformat (i, "packed"))
12466         enable_packed = 1;
12467       else if (unformat (i, "tag %s", &tag))
12468         ;
12469       else
12470         break;
12471     }
12472
12473   if (file_name_set == 0)
12474     {
12475       errmsg ("missing socket file name");
12476       return -99;
12477     }
12478
12479   if (vec_len (file_name) > 255)
12480     {
12481       errmsg ("socket file name too long");
12482       return -99;
12483     }
12484   vec_add1 (file_name, 0);
12485
12486   M (CREATE_VHOST_USER_IF, mp);
12487
12488   mp->is_server = is_server;
12489   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12490   mp->disable_indirect_desc = disable_indirect_desc;
12491   mp->enable_gso = enable_gso;
12492   mp->enable_packed = enable_packed;
12493   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12494   vec_free (file_name);
12495   if (custom_dev_instance != ~0)
12496     {
12497       mp->renumber = 1;
12498       mp->custom_dev_instance = ntohl (custom_dev_instance);
12499     }
12500
12501   mp->use_custom_mac = use_custom_mac;
12502   clib_memcpy (mp->mac_address, hwaddr, 6);
12503   if (tag)
12504     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12505   vec_free (tag);
12506
12507   S (mp);
12508   W (ret);
12509   return ret;
12510 }
12511
12512 static int
12513 api_modify_vhost_user_if (vat_main_t * vam)
12514 {
12515   unformat_input_t *i = vam->input;
12516   vl_api_modify_vhost_user_if_t *mp;
12517   u8 *file_name;
12518   u8 is_server = 0;
12519   u8 file_name_set = 0;
12520   u32 custom_dev_instance = ~0;
12521   u8 sw_if_index_set = 0;
12522   u32 sw_if_index = (u32) ~ 0;
12523   u8 enable_gso = 0;
12524   u8 enable_packed = 0;
12525   int ret;
12526
12527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12528     {
12529       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12530         sw_if_index_set = 1;
12531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12532         sw_if_index_set = 1;
12533       else if (unformat (i, "socket %s", &file_name))
12534         {
12535           file_name_set = 1;
12536         }
12537       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12538         ;
12539       else if (unformat (i, "server"))
12540         is_server = 1;
12541       else if (unformat (i, "gso"))
12542         enable_gso = 1;
12543       else if (unformat (i, "packed"))
12544         enable_packed = 1;
12545       else
12546         break;
12547     }
12548
12549   if (sw_if_index_set == 0)
12550     {
12551       errmsg ("missing sw_if_index or interface name");
12552       return -99;
12553     }
12554
12555   if (file_name_set == 0)
12556     {
12557       errmsg ("missing socket file name");
12558       return -99;
12559     }
12560
12561   if (vec_len (file_name) > 255)
12562     {
12563       errmsg ("socket file name too long");
12564       return -99;
12565     }
12566   vec_add1 (file_name, 0);
12567
12568   M (MODIFY_VHOST_USER_IF, mp);
12569
12570   mp->sw_if_index = ntohl (sw_if_index);
12571   mp->is_server = is_server;
12572   mp->enable_gso = enable_gso;
12573   mp->enable_packed = enable_packed;
12574   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12575   vec_free (file_name);
12576   if (custom_dev_instance != ~0)
12577     {
12578       mp->renumber = 1;
12579       mp->custom_dev_instance = ntohl (custom_dev_instance);
12580     }
12581
12582   S (mp);
12583   W (ret);
12584   return ret;
12585 }
12586
12587 static int
12588 api_delete_vhost_user_if (vat_main_t * vam)
12589 {
12590   unformat_input_t *i = vam->input;
12591   vl_api_delete_vhost_user_if_t *mp;
12592   u32 sw_if_index = ~0;
12593   u8 sw_if_index_set = 0;
12594   int ret;
12595
12596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12597     {
12598       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12599         sw_if_index_set = 1;
12600       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12601         sw_if_index_set = 1;
12602       else
12603         break;
12604     }
12605
12606   if (sw_if_index_set == 0)
12607     {
12608       errmsg ("missing sw_if_index or interface name");
12609       return -99;
12610     }
12611
12612
12613   M (DELETE_VHOST_USER_IF, mp);
12614
12615   mp->sw_if_index = ntohl (sw_if_index);
12616
12617   S (mp);
12618   W (ret);
12619   return ret;
12620 }
12621
12622 static void vl_api_sw_interface_vhost_user_details_t_handler
12623   (vl_api_sw_interface_vhost_user_details_t * mp)
12624 {
12625   vat_main_t *vam = &vat_main;
12626   u64 features;
12627
12628   features =
12629     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12630                                                     clib_net_to_host_u32
12631                                                     (mp->features_last_32) <<
12632                                                     32);
12633
12634   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12635          (char *) mp->interface_name,
12636          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12637          features, mp->is_server,
12638          ntohl (mp->num_regions), (char *) mp->sock_filename);
12639   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12640 }
12641
12642 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12643   (vl_api_sw_interface_vhost_user_details_t * mp)
12644 {
12645   vat_main_t *vam = &vat_main;
12646   vat_json_node_t *node = NULL;
12647
12648   if (VAT_JSON_ARRAY != vam->json_tree.type)
12649     {
12650       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12651       vat_json_init_array (&vam->json_tree);
12652     }
12653   node = vat_json_array_add (&vam->json_tree);
12654
12655   vat_json_init_object (node);
12656   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12657   vat_json_object_add_string_copy (node, "interface_name",
12658                                    mp->interface_name);
12659   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12660                             ntohl (mp->virtio_net_hdr_sz));
12661   vat_json_object_add_uint (node, "features_first_32",
12662                             clib_net_to_host_u32 (mp->features_first_32));
12663   vat_json_object_add_uint (node, "features_last_32",
12664                             clib_net_to_host_u32 (mp->features_last_32));
12665   vat_json_object_add_uint (node, "is_server", mp->is_server);
12666   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12667   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12668   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12669 }
12670
12671 static int
12672 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12673 {
12674   vl_api_sw_interface_vhost_user_dump_t *mp;
12675   vl_api_control_ping_t *mp_ping;
12676   int ret;
12677   print (vam->ofp,
12678          "Interface name            idx hdr_sz features server regions filename");
12679
12680   /* Get list of vhost-user interfaces */
12681   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12682   mp->sw_if_index = ntohl (~0);
12683   S (mp);
12684
12685   /* Use a control ping for synchronization */
12686   MPING (CONTROL_PING, mp_ping);
12687   S (mp_ping);
12688
12689   W (ret);
12690   return ret;
12691 }
12692
12693 static int
12694 api_show_version (vat_main_t * vam)
12695 {
12696   vl_api_show_version_t *mp;
12697   int ret;
12698
12699   M (SHOW_VERSION, mp);
12700
12701   S (mp);
12702   W (ret);
12703   return ret;
12704 }
12705
12706
12707 static int
12708 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12709 {
12710   unformat_input_t *line_input = vam->input;
12711   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12712   ip46_address_t local, remote;
12713   u8 is_add = 1;
12714   u8 local_set = 0;
12715   u8 remote_set = 0;
12716   u8 grp_set = 0;
12717   u32 mcast_sw_if_index = ~0;
12718   u32 encap_vrf_id = 0;
12719   u32 decap_vrf_id = 0;
12720   u8 protocol = ~0;
12721   u32 vni;
12722   u8 vni_set = 0;
12723   int ret;
12724
12725   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12726     {
12727       if (unformat (line_input, "del"))
12728         is_add = 0;
12729       else if (unformat (line_input, "local %U",
12730                          unformat_ip46_address, &local))
12731         {
12732           local_set = 1;
12733         }
12734       else if (unformat (line_input, "remote %U",
12735                          unformat_ip46_address, &remote))
12736         {
12737           remote_set = 1;
12738         }
12739       else if (unformat (line_input, "group %U %U",
12740                          unformat_ip46_address, &remote,
12741                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12742         {
12743           grp_set = remote_set = 1;
12744         }
12745       else if (unformat (line_input, "group %U",
12746                          unformat_ip46_address, &remote))
12747         {
12748           grp_set = remote_set = 1;
12749         }
12750       else
12751         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12752         ;
12753       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12754         ;
12755       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12756         ;
12757       else if (unformat (line_input, "vni %d", &vni))
12758         vni_set = 1;
12759       else if (unformat (line_input, "next-ip4"))
12760         protocol = 1;
12761       else if (unformat (line_input, "next-ip6"))
12762         protocol = 2;
12763       else if (unformat (line_input, "next-ethernet"))
12764         protocol = 3;
12765       else if (unformat (line_input, "next-nsh"))
12766         protocol = 4;
12767       else
12768         {
12769           errmsg ("parse error '%U'", format_unformat_error, line_input);
12770           return -99;
12771         }
12772     }
12773
12774   if (local_set == 0)
12775     {
12776       errmsg ("tunnel local address not specified");
12777       return -99;
12778     }
12779   if (remote_set == 0)
12780     {
12781       errmsg ("tunnel remote address not specified");
12782       return -99;
12783     }
12784   if (grp_set && mcast_sw_if_index == ~0)
12785     {
12786       errmsg ("tunnel nonexistent multicast device");
12787       return -99;
12788     }
12789   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12790     {
12791       errmsg ("both IPv4 and IPv6 addresses specified");
12792       return -99;
12793     }
12794
12795   if (vni_set == 0)
12796     {
12797       errmsg ("vni not specified");
12798       return -99;
12799     }
12800
12801   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12802
12803   ip_address_encode (&local,
12804                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12805                      IP46_TYPE_IP6, &mp->local);
12806   ip_address_encode (&remote,
12807                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12808                      IP46_TYPE_IP6, &mp->remote);
12809
12810   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12811   mp->encap_vrf_id = ntohl (encap_vrf_id);
12812   mp->decap_vrf_id = ntohl (decap_vrf_id);
12813   mp->protocol = protocol;
12814   mp->vni = ntohl (vni);
12815   mp->is_add = is_add;
12816
12817   S (mp);
12818   W (ret);
12819   return ret;
12820 }
12821
12822 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12823   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12824 {
12825   vat_main_t *vam = &vat_main;
12826   ip46_address_t local, remote;
12827
12828   ip_address_decode (&mp->local, &local);
12829   ip_address_decode (&mp->remote, &remote);
12830
12831   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12832          ntohl (mp->sw_if_index),
12833          format_ip46_address, &local, IP46_TYPE_ANY,
12834          format_ip46_address, &remote, IP46_TYPE_ANY,
12835          ntohl (mp->vni), mp->protocol,
12836          ntohl (mp->mcast_sw_if_index),
12837          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12838 }
12839
12840
12841 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12842   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12843 {
12844   vat_main_t *vam = &vat_main;
12845   vat_json_node_t *node = NULL;
12846   struct in_addr ip4;
12847   struct in6_addr ip6;
12848   ip46_address_t local, remote;
12849
12850   ip_address_decode (&mp->local, &local);
12851   ip_address_decode (&mp->remote, &remote);
12852
12853   if (VAT_JSON_ARRAY != vam->json_tree.type)
12854     {
12855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12856       vat_json_init_array (&vam->json_tree);
12857     }
12858   node = vat_json_array_add (&vam->json_tree);
12859
12860   vat_json_init_object (node);
12861   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12862   if (ip46_address_is_ip4 (&local))
12863     {
12864       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12865       vat_json_object_add_ip4 (node, "local", ip4);
12866       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12867       vat_json_object_add_ip4 (node, "remote", ip4);
12868     }
12869   else
12870     {
12871       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12872       vat_json_object_add_ip6 (node, "local", ip6);
12873       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12874       vat_json_object_add_ip6 (node, "remote", ip6);
12875     }
12876   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12877   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12878   vat_json_object_add_uint (node, "mcast_sw_if_index",
12879                             ntohl (mp->mcast_sw_if_index));
12880   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12881   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12882   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12883 }
12884
12885 static int
12886 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12887 {
12888   unformat_input_t *i = vam->input;
12889   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12890   vl_api_control_ping_t *mp_ping;
12891   u32 sw_if_index;
12892   u8 sw_if_index_set = 0;
12893   int ret;
12894
12895   /* Parse args required to build the message */
12896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12897     {
12898       if (unformat (i, "sw_if_index %d", &sw_if_index))
12899         sw_if_index_set = 1;
12900       else
12901         break;
12902     }
12903
12904   if (sw_if_index_set == 0)
12905     {
12906       sw_if_index = ~0;
12907     }
12908
12909   if (!vam->json_output)
12910     {
12911       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12912              "sw_if_index", "local", "remote", "vni",
12913              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12914     }
12915
12916   /* Get list of vxlan-tunnel interfaces */
12917   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12918
12919   mp->sw_if_index = htonl (sw_if_index);
12920
12921   S (mp);
12922
12923   /* Use a control ping for synchronization */
12924   MPING (CONTROL_PING, mp_ping);
12925   S (mp_ping);
12926
12927   W (ret);
12928   return ret;
12929 }
12930
12931 static void vl_api_l2_fib_table_details_t_handler
12932   (vl_api_l2_fib_table_details_t * mp)
12933 {
12934   vat_main_t *vam = &vat_main;
12935
12936   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12937          "       %d       %d     %d",
12938          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12939          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12940          mp->bvi_mac);
12941 }
12942
12943 static void vl_api_l2_fib_table_details_t_handler_json
12944   (vl_api_l2_fib_table_details_t * mp)
12945 {
12946   vat_main_t *vam = &vat_main;
12947   vat_json_node_t *node = NULL;
12948
12949   if (VAT_JSON_ARRAY != vam->json_tree.type)
12950     {
12951       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12952       vat_json_init_array (&vam->json_tree);
12953     }
12954   node = vat_json_array_add (&vam->json_tree);
12955
12956   vat_json_init_object (node);
12957   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12958   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12959   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12960   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12961   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12962   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12963 }
12964
12965 static int
12966 api_l2_fib_table_dump (vat_main_t * vam)
12967 {
12968   unformat_input_t *i = vam->input;
12969   vl_api_l2_fib_table_dump_t *mp;
12970   vl_api_control_ping_t *mp_ping;
12971   u32 bd_id;
12972   u8 bd_id_set = 0;
12973   int ret;
12974
12975   /* Parse args required to build the message */
12976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12977     {
12978       if (unformat (i, "bd_id %d", &bd_id))
12979         bd_id_set = 1;
12980       else
12981         break;
12982     }
12983
12984   if (bd_id_set == 0)
12985     {
12986       errmsg ("missing bridge domain");
12987       return -99;
12988     }
12989
12990   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12991
12992   /* Get list of l2 fib entries */
12993   M (L2_FIB_TABLE_DUMP, mp);
12994
12995   mp->bd_id = ntohl (bd_id);
12996   S (mp);
12997
12998   /* Use a control ping for synchronization */
12999   MPING (CONTROL_PING, mp_ping);
13000   S (mp_ping);
13001
13002   W (ret);
13003   return ret;
13004 }
13005
13006
13007 static int
13008 api_interface_name_renumber (vat_main_t * vam)
13009 {
13010   unformat_input_t *line_input = vam->input;
13011   vl_api_interface_name_renumber_t *mp;
13012   u32 sw_if_index = ~0;
13013   u32 new_show_dev_instance = ~0;
13014   int ret;
13015
13016   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13017     {
13018       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13019                     &sw_if_index))
13020         ;
13021       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13022         ;
13023       else if (unformat (line_input, "new_show_dev_instance %d",
13024                          &new_show_dev_instance))
13025         ;
13026       else
13027         break;
13028     }
13029
13030   if (sw_if_index == ~0)
13031     {
13032       errmsg ("missing interface name or sw_if_index");
13033       return -99;
13034     }
13035
13036   if (new_show_dev_instance == ~0)
13037     {
13038       errmsg ("missing new_show_dev_instance");
13039       return -99;
13040     }
13041
13042   M (INTERFACE_NAME_RENUMBER, mp);
13043
13044   mp->sw_if_index = ntohl (sw_if_index);
13045   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13046
13047   S (mp);
13048   W (ret);
13049   return ret;
13050 }
13051
13052 static int
13053 api_want_l2_macs_events (vat_main_t * vam)
13054 {
13055   unformat_input_t *line_input = vam->input;
13056   vl_api_want_l2_macs_events_t *mp;
13057   u8 enable_disable = 1;
13058   u32 scan_delay = 0;
13059   u32 max_macs_in_event = 0;
13060   u32 learn_limit = 0;
13061   int ret;
13062
13063   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13064     {
13065       if (unformat (line_input, "learn-limit %d", &learn_limit))
13066         ;
13067       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13068         ;
13069       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13070         ;
13071       else if (unformat (line_input, "disable"))
13072         enable_disable = 0;
13073       else
13074         break;
13075     }
13076
13077   M (WANT_L2_MACS_EVENTS, mp);
13078   mp->enable_disable = enable_disable;
13079   mp->pid = htonl (getpid ());
13080   mp->learn_limit = htonl (learn_limit);
13081   mp->scan_delay = (u8) scan_delay;
13082   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13083   S (mp);
13084   W (ret);
13085   return ret;
13086 }
13087
13088 static int
13089 api_input_acl_set_interface (vat_main_t * vam)
13090 {
13091   unformat_input_t *i = vam->input;
13092   vl_api_input_acl_set_interface_t *mp;
13093   u32 sw_if_index;
13094   int sw_if_index_set;
13095   u32 ip4_table_index = ~0;
13096   u32 ip6_table_index = ~0;
13097   u32 l2_table_index = ~0;
13098   u8 is_add = 1;
13099   int ret;
13100
13101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13102     {
13103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13104         sw_if_index_set = 1;
13105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13106         sw_if_index_set = 1;
13107       else if (unformat (i, "del"))
13108         is_add = 0;
13109       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13110         ;
13111       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13112         ;
13113       else if (unformat (i, "l2-table %d", &l2_table_index))
13114         ;
13115       else
13116         {
13117           clib_warning ("parse error '%U'", format_unformat_error, i);
13118           return -99;
13119         }
13120     }
13121
13122   if (sw_if_index_set == 0)
13123     {
13124       errmsg ("missing interface name or sw_if_index");
13125       return -99;
13126     }
13127
13128   M (INPUT_ACL_SET_INTERFACE, mp);
13129
13130   mp->sw_if_index = ntohl (sw_if_index);
13131   mp->ip4_table_index = ntohl (ip4_table_index);
13132   mp->ip6_table_index = ntohl (ip6_table_index);
13133   mp->l2_table_index = ntohl (l2_table_index);
13134   mp->is_add = is_add;
13135
13136   S (mp);
13137   W (ret);
13138   return ret;
13139 }
13140
13141 static int
13142 api_output_acl_set_interface (vat_main_t * vam)
13143 {
13144   unformat_input_t *i = vam->input;
13145   vl_api_output_acl_set_interface_t *mp;
13146   u32 sw_if_index;
13147   int sw_if_index_set;
13148   u32 ip4_table_index = ~0;
13149   u32 ip6_table_index = ~0;
13150   u32 l2_table_index = ~0;
13151   u8 is_add = 1;
13152   int ret;
13153
13154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13155     {
13156       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13157         sw_if_index_set = 1;
13158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13159         sw_if_index_set = 1;
13160       else if (unformat (i, "del"))
13161         is_add = 0;
13162       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13163         ;
13164       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13165         ;
13166       else if (unformat (i, "l2-table %d", &l2_table_index))
13167         ;
13168       else
13169         {
13170           clib_warning ("parse error '%U'", format_unformat_error, i);
13171           return -99;
13172         }
13173     }
13174
13175   if (sw_if_index_set == 0)
13176     {
13177       errmsg ("missing interface name or sw_if_index");
13178       return -99;
13179     }
13180
13181   M (OUTPUT_ACL_SET_INTERFACE, mp);
13182
13183   mp->sw_if_index = ntohl (sw_if_index);
13184   mp->ip4_table_index = ntohl (ip4_table_index);
13185   mp->ip6_table_index = ntohl (ip6_table_index);
13186   mp->l2_table_index = ntohl (l2_table_index);
13187   mp->is_add = is_add;
13188
13189   S (mp);
13190   W (ret);
13191   return ret;
13192 }
13193
13194 static int
13195 api_ip_address_dump (vat_main_t * vam)
13196 {
13197   unformat_input_t *i = vam->input;
13198   vl_api_ip_address_dump_t *mp;
13199   vl_api_control_ping_t *mp_ping;
13200   u32 sw_if_index = ~0;
13201   u8 sw_if_index_set = 0;
13202   u8 ipv4_set = 0;
13203   u8 ipv6_set = 0;
13204   int ret;
13205
13206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13207     {
13208       if (unformat (i, "sw_if_index %d", &sw_if_index))
13209         sw_if_index_set = 1;
13210       else
13211         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13212         sw_if_index_set = 1;
13213       else if (unformat (i, "ipv4"))
13214         ipv4_set = 1;
13215       else if (unformat (i, "ipv6"))
13216         ipv6_set = 1;
13217       else
13218         break;
13219     }
13220
13221   if (ipv4_set && ipv6_set)
13222     {
13223       errmsg ("ipv4 and ipv6 flags cannot be both set");
13224       return -99;
13225     }
13226
13227   if ((!ipv4_set) && (!ipv6_set))
13228     {
13229       errmsg ("no ipv4 nor ipv6 flag set");
13230       return -99;
13231     }
13232
13233   if (sw_if_index_set == 0)
13234     {
13235       errmsg ("missing interface name or sw_if_index");
13236       return -99;
13237     }
13238
13239   vam->current_sw_if_index = sw_if_index;
13240   vam->is_ipv6 = ipv6_set;
13241
13242   M (IP_ADDRESS_DUMP, mp);
13243   mp->sw_if_index = ntohl (sw_if_index);
13244   mp->is_ipv6 = ipv6_set;
13245   S (mp);
13246
13247   /* Use a control ping for synchronization */
13248   MPING (CONTROL_PING, mp_ping);
13249   S (mp_ping);
13250
13251   W (ret);
13252   return ret;
13253 }
13254
13255 static int
13256 api_ip_dump (vat_main_t * vam)
13257 {
13258   vl_api_ip_dump_t *mp;
13259   vl_api_control_ping_t *mp_ping;
13260   unformat_input_t *in = vam->input;
13261   int ipv4_set = 0;
13262   int ipv6_set = 0;
13263   int is_ipv6;
13264   int i;
13265   int ret;
13266
13267   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13268     {
13269       if (unformat (in, "ipv4"))
13270         ipv4_set = 1;
13271       else if (unformat (in, "ipv6"))
13272         ipv6_set = 1;
13273       else
13274         break;
13275     }
13276
13277   if (ipv4_set && ipv6_set)
13278     {
13279       errmsg ("ipv4 and ipv6 flags cannot be both set");
13280       return -99;
13281     }
13282
13283   if ((!ipv4_set) && (!ipv6_set))
13284     {
13285       errmsg ("no ipv4 nor ipv6 flag set");
13286       return -99;
13287     }
13288
13289   is_ipv6 = ipv6_set;
13290   vam->is_ipv6 = is_ipv6;
13291
13292   /* free old data */
13293   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13294     {
13295       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13296     }
13297   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13298
13299   M (IP_DUMP, mp);
13300   mp->is_ipv6 = ipv6_set;
13301   S (mp);
13302
13303   /* Use a control ping for synchronization */
13304   MPING (CONTROL_PING, mp_ping);
13305   S (mp_ping);
13306
13307   W (ret);
13308   return ret;
13309 }
13310
13311 static int
13312 api_ipsec_spd_add_del (vat_main_t * vam)
13313 {
13314   unformat_input_t *i = vam->input;
13315   vl_api_ipsec_spd_add_del_t *mp;
13316   u32 spd_id = ~0;
13317   u8 is_add = 1;
13318   int ret;
13319
13320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13321     {
13322       if (unformat (i, "spd_id %d", &spd_id))
13323         ;
13324       else if (unformat (i, "del"))
13325         is_add = 0;
13326       else
13327         {
13328           clib_warning ("parse error '%U'", format_unformat_error, i);
13329           return -99;
13330         }
13331     }
13332   if (spd_id == ~0)
13333     {
13334       errmsg ("spd_id must be set");
13335       return -99;
13336     }
13337
13338   M (IPSEC_SPD_ADD_DEL, mp);
13339
13340   mp->spd_id = ntohl (spd_id);
13341   mp->is_add = is_add;
13342
13343   S (mp);
13344   W (ret);
13345   return ret;
13346 }
13347
13348 static int
13349 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13350 {
13351   unformat_input_t *i = vam->input;
13352   vl_api_ipsec_interface_add_del_spd_t *mp;
13353   u32 sw_if_index;
13354   u8 sw_if_index_set = 0;
13355   u32 spd_id = (u32) ~ 0;
13356   u8 is_add = 1;
13357   int ret;
13358
13359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13360     {
13361       if (unformat (i, "del"))
13362         is_add = 0;
13363       else if (unformat (i, "spd_id %d", &spd_id))
13364         ;
13365       else
13366         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13367         sw_if_index_set = 1;
13368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13369         sw_if_index_set = 1;
13370       else
13371         {
13372           clib_warning ("parse error '%U'", format_unformat_error, i);
13373           return -99;
13374         }
13375
13376     }
13377
13378   if (spd_id == (u32) ~ 0)
13379     {
13380       errmsg ("spd_id must be set");
13381       return -99;
13382     }
13383
13384   if (sw_if_index_set == 0)
13385     {
13386       errmsg ("missing interface name or sw_if_index");
13387       return -99;
13388     }
13389
13390   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13391
13392   mp->spd_id = ntohl (spd_id);
13393   mp->sw_if_index = ntohl (sw_if_index);
13394   mp->is_add = is_add;
13395
13396   S (mp);
13397   W (ret);
13398   return ret;
13399 }
13400
13401 static int
13402 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13403 {
13404   unformat_input_t *i = vam->input;
13405   vl_api_ipsec_spd_entry_add_del_t *mp;
13406   u8 is_add = 1, is_outbound = 0;
13407   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13408   i32 priority = 0;
13409   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13410   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13411   vl_api_address_t laddr_start = { }, laddr_stop =
13412   {
13413   }, raddr_start =
13414   {
13415   }, raddr_stop =
13416   {
13417   };
13418   int ret;
13419
13420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13421     {
13422       if (unformat (i, "del"))
13423         is_add = 0;
13424       if (unformat (i, "outbound"))
13425         is_outbound = 1;
13426       if (unformat (i, "inbound"))
13427         is_outbound = 0;
13428       else if (unformat (i, "spd_id %d", &spd_id))
13429         ;
13430       else if (unformat (i, "sa_id %d", &sa_id))
13431         ;
13432       else if (unformat (i, "priority %d", &priority))
13433         ;
13434       else if (unformat (i, "protocol %d", &protocol))
13435         ;
13436       else if (unformat (i, "lport_start %d", &lport_start))
13437         ;
13438       else if (unformat (i, "lport_stop %d", &lport_stop))
13439         ;
13440       else if (unformat (i, "rport_start %d", &rport_start))
13441         ;
13442       else if (unformat (i, "rport_stop %d", &rport_stop))
13443         ;
13444       else if (unformat (i, "laddr_start %U",
13445                          unformat_vl_api_address, &laddr_start))
13446         ;
13447       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13448                          &laddr_stop))
13449         ;
13450       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13451                          &raddr_start))
13452         ;
13453       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13454                          &raddr_stop))
13455         ;
13456       else
13457         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13458         {
13459           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13460             {
13461               clib_warning ("unsupported action: 'resolve'");
13462               return -99;
13463             }
13464         }
13465       else
13466         {
13467           clib_warning ("parse error '%U'", format_unformat_error, i);
13468           return -99;
13469         }
13470
13471     }
13472
13473   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13474
13475   mp->is_add = is_add;
13476
13477   mp->entry.spd_id = ntohl (spd_id);
13478   mp->entry.priority = ntohl (priority);
13479   mp->entry.is_outbound = is_outbound;
13480
13481   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13482                sizeof (vl_api_address_t));
13483   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13484                sizeof (vl_api_address_t));
13485   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13486                sizeof (vl_api_address_t));
13487   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13488                sizeof (vl_api_address_t));
13489
13490   mp->entry.protocol = (u8) protocol;
13491   mp->entry.local_port_start = ntohs ((u16) lport_start);
13492   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13493   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13494   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13495   mp->entry.policy = (u8) policy;
13496   mp->entry.sa_id = ntohl (sa_id);
13497
13498   S (mp);
13499   W (ret);
13500   return ret;
13501 }
13502
13503 static int
13504 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13505 {
13506   unformat_input_t *i = vam->input;
13507   vl_api_ipsec_sad_entry_add_del_t *mp;
13508   u32 sad_id = 0, spi = 0;
13509   u8 *ck = 0, *ik = 0;
13510   u8 is_add = 1;
13511
13512   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13513   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13514   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13515   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13516   vl_api_address_t tun_src, tun_dst;
13517   int ret;
13518
13519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13520     {
13521       if (unformat (i, "del"))
13522         is_add = 0;
13523       else if (unformat (i, "sad_id %d", &sad_id))
13524         ;
13525       else if (unformat (i, "spi %d", &spi))
13526         ;
13527       else if (unformat (i, "esp"))
13528         protocol = IPSEC_API_PROTO_ESP;
13529       else
13530         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13531         {
13532           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13533           if (ADDRESS_IP6 == tun_src.af)
13534             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13535         }
13536       else
13537         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13538         {
13539           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13540           if (ADDRESS_IP6 == tun_src.af)
13541             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13542         }
13543       else
13544         if (unformat (i, "crypto_alg %U",
13545                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13546         ;
13547       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13548         ;
13549       else if (unformat (i, "integ_alg %U",
13550                          unformat_ipsec_api_integ_alg, &integ_alg))
13551         ;
13552       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13553         ;
13554       else
13555         {
13556           clib_warning ("parse error '%U'", format_unformat_error, i);
13557           return -99;
13558         }
13559
13560     }
13561
13562   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13563
13564   mp->is_add = is_add;
13565   mp->entry.sad_id = ntohl (sad_id);
13566   mp->entry.protocol = protocol;
13567   mp->entry.spi = ntohl (spi);
13568   mp->entry.flags = flags;
13569
13570   mp->entry.crypto_algorithm = crypto_alg;
13571   mp->entry.integrity_algorithm = integ_alg;
13572   mp->entry.crypto_key.length = vec_len (ck);
13573   mp->entry.integrity_key.length = vec_len (ik);
13574
13575   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13576     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13577
13578   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13579     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13580
13581   if (ck)
13582     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13583   if (ik)
13584     clib_memcpy (mp->entry.integrity_key.data, ik,
13585                  mp->entry.integrity_key.length);
13586
13587   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13588     {
13589       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13590                    sizeof (mp->entry.tunnel_src));
13591       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13592                    sizeof (mp->entry.tunnel_dst));
13593     }
13594
13595   S (mp);
13596   W (ret);
13597   return ret;
13598 }
13599
13600 static int
13601 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13602 {
13603   unformat_input_t *i = vam->input;
13604   vl_api_ipsec_tunnel_if_add_del_t *mp;
13605   u32 local_spi = 0, remote_spi = 0;
13606   u32 crypto_alg = 0, integ_alg = 0;
13607   u8 *lck = NULL, *rck = NULL;
13608   u8 *lik = NULL, *rik = NULL;
13609   vl_api_address_t local_ip = { 0 };
13610   vl_api_address_t remote_ip = { 0 };
13611   f64 before = 0;
13612   u8 is_add = 1;
13613   u8 esn = 0;
13614   u8 anti_replay = 0;
13615   u8 renumber = 0;
13616   u32 instance = ~0;
13617   u32 count = 1, jj;
13618   int ret = -1;
13619
13620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13621     {
13622       if (unformat (i, "del"))
13623         is_add = 0;
13624       else if (unformat (i, "esn"))
13625         esn = 1;
13626       else if (unformat (i, "anti-replay"))
13627         anti_replay = 1;
13628       else if (unformat (i, "count %d", &count))
13629         ;
13630       else if (unformat (i, "local_spi %d", &local_spi))
13631         ;
13632       else if (unformat (i, "remote_spi %d", &remote_spi))
13633         ;
13634       else
13635         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13636         ;
13637       else
13638         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13639         ;
13640       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13641         ;
13642       else
13643         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13644         ;
13645       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13646         ;
13647       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13648         ;
13649       else
13650         if (unformat
13651             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13652         {
13653           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13654             {
13655               errmsg ("unsupported crypto-alg: '%U'\n",
13656                       format_ipsec_crypto_alg, crypto_alg);
13657               return -99;
13658             }
13659         }
13660       else
13661         if (unformat
13662             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13663         {
13664           if (integ_alg >= IPSEC_INTEG_N_ALG)
13665             {
13666               errmsg ("unsupported integ-alg: '%U'\n",
13667                       format_ipsec_integ_alg, integ_alg);
13668               return -99;
13669             }
13670         }
13671       else if (unformat (i, "instance %u", &instance))
13672         renumber = 1;
13673       else
13674         {
13675           errmsg ("parse error '%U'\n", format_unformat_error, i);
13676           return -99;
13677         }
13678     }
13679
13680   if (count > 1)
13681     {
13682       /* Turn on async mode */
13683       vam->async_mode = 1;
13684       vam->async_errors = 0;
13685       before = vat_time_now (vam);
13686     }
13687
13688   for (jj = 0; jj < count; jj++)
13689     {
13690       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13691
13692       mp->is_add = is_add;
13693       mp->esn = esn;
13694       mp->anti_replay = anti_replay;
13695
13696       if (jj > 0)
13697         increment_address (&remote_ip);
13698
13699       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13700       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13701
13702       mp->local_spi = htonl (local_spi + jj);
13703       mp->remote_spi = htonl (remote_spi + jj);
13704       mp->crypto_alg = (u8) crypto_alg;
13705
13706       mp->local_crypto_key_len = 0;
13707       if (lck)
13708         {
13709           mp->local_crypto_key_len = vec_len (lck);
13710           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13711             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13712           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13713         }
13714
13715       mp->remote_crypto_key_len = 0;
13716       if (rck)
13717         {
13718           mp->remote_crypto_key_len = vec_len (rck);
13719           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13720             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13721           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13722         }
13723
13724       mp->integ_alg = (u8) integ_alg;
13725
13726       mp->local_integ_key_len = 0;
13727       if (lik)
13728         {
13729           mp->local_integ_key_len = vec_len (lik);
13730           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13731             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13732           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13733         }
13734
13735       mp->remote_integ_key_len = 0;
13736       if (rik)
13737         {
13738           mp->remote_integ_key_len = vec_len (rik);
13739           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13740             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13741           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13742         }
13743
13744       if (renumber)
13745         {
13746           mp->renumber = renumber;
13747           mp->show_instance = ntohl (instance);
13748         }
13749       S (mp);
13750     }
13751
13752   /* When testing multiple add/del ops, use a control-ping to sync */
13753   if (count > 1)
13754     {
13755       vl_api_control_ping_t *mp_ping;
13756       f64 after;
13757       f64 timeout;
13758
13759       /* Shut off async mode */
13760       vam->async_mode = 0;
13761
13762       MPING (CONTROL_PING, mp_ping);
13763       S (mp_ping);
13764
13765       timeout = vat_time_now (vam) + 1.0;
13766       while (vat_time_now (vam) < timeout)
13767         if (vam->result_ready == 1)
13768           goto out;
13769       vam->retval = -99;
13770
13771     out:
13772       if (vam->retval == -99)
13773         errmsg ("timeout");
13774
13775       if (vam->async_errors > 0)
13776         {
13777           errmsg ("%d asynchronous errors", vam->async_errors);
13778           vam->retval = -98;
13779         }
13780       vam->async_errors = 0;
13781       after = vat_time_now (vam);
13782
13783       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13784       if (jj > 0)
13785         count = jj;
13786
13787       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13788              count, after - before, count / (after - before));
13789     }
13790   else
13791     {
13792       /* Wait for a reply... */
13793       W (ret);
13794       return ret;
13795     }
13796
13797   return ret;
13798 }
13799
13800 static void
13801 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13802 {
13803   vat_main_t *vam = &vat_main;
13804
13805   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13806          "crypto_key %U integ_alg %u integ_key %U flags %x "
13807          "tunnel_src_addr %U tunnel_dst_addr %U "
13808          "salt %u seq_outbound %lu last_seq_inbound %lu "
13809          "replay_window %lu stat_index %u\n",
13810          ntohl (mp->entry.sad_id),
13811          ntohl (mp->sw_if_index),
13812          ntohl (mp->entry.spi),
13813          ntohl (mp->entry.protocol),
13814          ntohl (mp->entry.crypto_algorithm),
13815          format_hex_bytes, mp->entry.crypto_key.data,
13816          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13817          format_hex_bytes, mp->entry.integrity_key.data,
13818          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13819          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13820          &mp->entry.tunnel_dst, ntohl (mp->salt),
13821          clib_net_to_host_u64 (mp->seq_outbound),
13822          clib_net_to_host_u64 (mp->last_seq_inbound),
13823          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13824 }
13825
13826 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13827 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13828
13829 static void vl_api_ipsec_sa_details_t_handler_json
13830   (vl_api_ipsec_sa_details_t * mp)
13831 {
13832   vat_main_t *vam = &vat_main;
13833   vat_json_node_t *node = NULL;
13834   vl_api_ipsec_sad_flags_t flags;
13835
13836   if (VAT_JSON_ARRAY != vam->json_tree.type)
13837     {
13838       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13839       vat_json_init_array (&vam->json_tree);
13840     }
13841   node = vat_json_array_add (&vam->json_tree);
13842
13843   vat_json_init_object (node);
13844   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13845   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13846   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13847   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13848   vat_json_object_add_uint (node, "crypto_alg",
13849                             ntohl (mp->entry.crypto_algorithm));
13850   vat_json_object_add_uint (node, "integ_alg",
13851                             ntohl (mp->entry.integrity_algorithm));
13852   flags = ntohl (mp->entry.flags);
13853   vat_json_object_add_uint (node, "use_esn",
13854                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13855   vat_json_object_add_uint (node, "use_anti_replay",
13856                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13857   vat_json_object_add_uint (node, "is_tunnel",
13858                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13859   vat_json_object_add_uint (node, "is_tunnel_ip6",
13860                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13861   vat_json_object_add_uint (node, "udp_encap",
13862                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13863   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13864                              mp->entry.crypto_key.length);
13865   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13866                              mp->entry.integrity_key.length);
13867   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13868   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13869   vat_json_object_add_uint (node, "replay_window",
13870                             clib_net_to_host_u64 (mp->replay_window));
13871   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13872 }
13873
13874 static int
13875 api_ipsec_sa_dump (vat_main_t * vam)
13876 {
13877   unformat_input_t *i = vam->input;
13878   vl_api_ipsec_sa_dump_t *mp;
13879   vl_api_control_ping_t *mp_ping;
13880   u32 sa_id = ~0;
13881   int ret;
13882
13883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13884     {
13885       if (unformat (i, "sa_id %d", &sa_id))
13886         ;
13887       else
13888         {
13889           clib_warning ("parse error '%U'", format_unformat_error, i);
13890           return -99;
13891         }
13892     }
13893
13894   M (IPSEC_SA_DUMP, mp);
13895
13896   mp->sa_id = ntohl (sa_id);
13897
13898   S (mp);
13899
13900   /* Use a control ping for synchronization */
13901   M (CONTROL_PING, mp_ping);
13902   S (mp_ping);
13903
13904   W (ret);
13905   return ret;
13906 }
13907
13908 static int
13909 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13910 {
13911   unformat_input_t *i = vam->input;
13912   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13913   u32 sw_if_index = ~0;
13914   u32 sa_id = ~0;
13915   u8 is_outbound = (u8) ~ 0;
13916   int ret;
13917
13918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13919     {
13920       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13921         ;
13922       else if (unformat (i, "sa_id %d", &sa_id))
13923         ;
13924       else if (unformat (i, "outbound"))
13925         is_outbound = 1;
13926       else if (unformat (i, "inbound"))
13927         is_outbound = 0;
13928       else
13929         {
13930           clib_warning ("parse error '%U'", format_unformat_error, i);
13931           return -99;
13932         }
13933     }
13934
13935   if (sw_if_index == ~0)
13936     {
13937       errmsg ("interface must be specified");
13938       return -99;
13939     }
13940
13941   if (sa_id == ~0)
13942     {
13943       errmsg ("SA ID must be specified");
13944       return -99;
13945     }
13946
13947   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13948
13949   mp->sw_if_index = htonl (sw_if_index);
13950   mp->sa_id = htonl (sa_id);
13951   mp->is_outbound = is_outbound;
13952
13953   S (mp);
13954   W (ret);
13955
13956   return ret;
13957 }
13958
13959 static int
13960 api_get_first_msg_id (vat_main_t * vam)
13961 {
13962   vl_api_get_first_msg_id_t *mp;
13963   unformat_input_t *i = vam->input;
13964   u8 *name;
13965   u8 name_set = 0;
13966   int ret;
13967
13968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13969     {
13970       if (unformat (i, "client %s", &name))
13971         name_set = 1;
13972       else
13973         break;
13974     }
13975
13976   if (name_set == 0)
13977     {
13978       errmsg ("missing client name");
13979       return -99;
13980     }
13981   vec_add1 (name, 0);
13982
13983   if (vec_len (name) > 63)
13984     {
13985       errmsg ("client name too long");
13986       return -99;
13987     }
13988
13989   M (GET_FIRST_MSG_ID, mp);
13990   clib_memcpy (mp->name, name, vec_len (name));
13991   S (mp);
13992   W (ret);
13993   return ret;
13994 }
13995
13996 static int
13997 api_cop_interface_enable_disable (vat_main_t * vam)
13998 {
13999   unformat_input_t *line_input = vam->input;
14000   vl_api_cop_interface_enable_disable_t *mp;
14001   u32 sw_if_index = ~0;
14002   u8 enable_disable = 1;
14003   int ret;
14004
14005   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14006     {
14007       if (unformat (line_input, "disable"))
14008         enable_disable = 0;
14009       if (unformat (line_input, "enable"))
14010         enable_disable = 1;
14011       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14012                          vam, &sw_if_index))
14013         ;
14014       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14015         ;
14016       else
14017         break;
14018     }
14019
14020   if (sw_if_index == ~0)
14021     {
14022       errmsg ("missing interface name or sw_if_index");
14023       return -99;
14024     }
14025
14026   /* Construct the API message */
14027   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14028   mp->sw_if_index = ntohl (sw_if_index);
14029   mp->enable_disable = enable_disable;
14030
14031   /* send it... */
14032   S (mp);
14033   /* Wait for the reply */
14034   W (ret);
14035   return ret;
14036 }
14037
14038 static int
14039 api_cop_whitelist_enable_disable (vat_main_t * vam)
14040 {
14041   unformat_input_t *line_input = vam->input;
14042   vl_api_cop_whitelist_enable_disable_t *mp;
14043   u32 sw_if_index = ~0;
14044   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14045   u32 fib_id = 0;
14046   int ret;
14047
14048   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14049     {
14050       if (unformat (line_input, "ip4"))
14051         ip4 = 1;
14052       else if (unformat (line_input, "ip6"))
14053         ip6 = 1;
14054       else if (unformat (line_input, "default"))
14055         default_cop = 1;
14056       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14057                          vam, &sw_if_index))
14058         ;
14059       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14060         ;
14061       else if (unformat (line_input, "fib-id %d", &fib_id))
14062         ;
14063       else
14064         break;
14065     }
14066
14067   if (sw_if_index == ~0)
14068     {
14069       errmsg ("missing interface name or sw_if_index");
14070       return -99;
14071     }
14072
14073   /* Construct the API message */
14074   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14075   mp->sw_if_index = ntohl (sw_if_index);
14076   mp->fib_id = ntohl (fib_id);
14077   mp->ip4 = ip4;
14078   mp->ip6 = ip6;
14079   mp->default_cop = default_cop;
14080
14081   /* send it... */
14082   S (mp);
14083   /* Wait for the reply */
14084   W (ret);
14085   return ret;
14086 }
14087
14088 static int
14089 api_get_node_graph (vat_main_t * vam)
14090 {
14091   vl_api_get_node_graph_t *mp;
14092   int ret;
14093
14094   M (GET_NODE_GRAPH, mp);
14095
14096   /* send it... */
14097   S (mp);
14098   /* Wait for the reply */
14099   W (ret);
14100   return ret;
14101 }
14102
14103 /* *INDENT-OFF* */
14104 /** Used for parsing LISP eids */
14105 typedef CLIB_PACKED(struct{
14106   union {
14107           ip46_address_t ip;
14108           mac_address_t mac;
14109           lisp_nsh_api_t nsh;
14110   } addr;
14111   u32 len;       /**< prefix length if IP */
14112   u8 type;      /**< type of eid */
14113 }) lisp_eid_vat_t;
14114 /* *INDENT-ON* */
14115
14116 static uword
14117 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14118 {
14119   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14120
14121   clib_memset (a, 0, sizeof (a[0]));
14122
14123   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
14124     {
14125       a->type = 0;              /* ip prefix type */
14126     }
14127   else if (unformat (input, "%U", unformat_ethernet_address, a->addr.mac))
14128     {
14129       a->type = 1;              /* mac type */
14130     }
14131   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
14132     {
14133       a->type = 2;              /* NSH type */
14134       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
14135     }
14136   else
14137     {
14138       return 0;
14139     }
14140
14141   if (a->type == 0)
14142     {
14143       if (ip46_address_is_ip4 (&a->addr.ip))
14144         return a->len > 32 ? 1 : 0;
14145       else
14146         return a->len > 128 ? 1 : 0;
14147     }
14148
14149   return 1;
14150 }
14151
14152 static void
14153 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
14154 {
14155   eid->type = vat_eid->type;
14156   switch (eid->type)
14157     {
14158     case EID_TYPE_API_PREFIX:
14159       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
14160         {
14161           clib_memcpy (&eid->address.prefix.address.un.ip4,
14162                        &vat_eid->addr.ip.ip4, 4);
14163           eid->address.prefix.address.af = ADDRESS_IP4;
14164           eid->address.prefix.len = vat_eid->len;
14165         }
14166       else
14167         {
14168           clib_memcpy (&eid->address.prefix.address.un.ip6,
14169                        &vat_eid->addr.ip.ip6, 16);
14170           eid->address.prefix.address.af = ADDRESS_IP6;
14171           eid->address.prefix.len = vat_eid->len;
14172         }
14173       return;
14174     case EID_TYPE_API_MAC:
14175       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
14176                    sizeof (eid->address.mac));
14177       return;
14178     case EID_TYPE_API_NSH:
14179       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
14180                    sizeof (eid->address.nsh));
14181       return;
14182     default:
14183       ASSERT (0);
14184       return;
14185     }
14186 }
14187
14188 static int
14189 api_one_add_del_locator_set (vat_main_t * vam)
14190 {
14191   unformat_input_t *input = vam->input;
14192   vl_api_one_add_del_locator_set_t *mp;
14193   u8 is_add = 1;
14194   u8 *locator_set_name = NULL;
14195   u8 locator_set_name_set = 0;
14196   vl_api_local_locator_t locator, *locators = 0;
14197   u32 sw_if_index, priority, weight;
14198   u32 data_len = 0;
14199
14200   int ret;
14201   /* Parse args required to build the message */
14202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14203     {
14204       if (unformat (input, "del"))
14205         {
14206           is_add = 0;
14207         }
14208       else if (unformat (input, "locator-set %s", &locator_set_name))
14209         {
14210           locator_set_name_set = 1;
14211         }
14212       else if (unformat (input, "sw_if_index %u p %u w %u",
14213                          &sw_if_index, &priority, &weight))
14214         {
14215           locator.sw_if_index = htonl (sw_if_index);
14216           locator.priority = priority;
14217           locator.weight = weight;
14218           vec_add1 (locators, locator);
14219         }
14220       else
14221         if (unformat
14222             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14223              &sw_if_index, &priority, &weight))
14224         {
14225           locator.sw_if_index = htonl (sw_if_index);
14226           locator.priority = priority;
14227           locator.weight = weight;
14228           vec_add1 (locators, locator);
14229         }
14230       else
14231         break;
14232     }
14233
14234   if (locator_set_name_set == 0)
14235     {
14236       errmsg ("missing locator-set name");
14237       vec_free (locators);
14238       return -99;
14239     }
14240
14241   if (vec_len (locator_set_name) > 64)
14242     {
14243       errmsg ("locator-set name too long");
14244       vec_free (locator_set_name);
14245       vec_free (locators);
14246       return -99;
14247     }
14248   vec_add1 (locator_set_name, 0);
14249
14250   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14251
14252   /* Construct the API message */
14253   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14254
14255   mp->is_add = is_add;
14256   clib_memcpy (mp->locator_set_name, locator_set_name,
14257                vec_len (locator_set_name));
14258   vec_free (locator_set_name);
14259
14260   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14261   if (locators)
14262     clib_memcpy (mp->locators, locators, data_len);
14263   vec_free (locators);
14264
14265   /* send it... */
14266   S (mp);
14267
14268   /* Wait for a reply... */
14269   W (ret);
14270   return ret;
14271 }
14272
14273 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14274
14275 static int
14276 api_one_add_del_locator (vat_main_t * vam)
14277 {
14278   unformat_input_t *input = vam->input;
14279   vl_api_one_add_del_locator_t *mp;
14280   u32 tmp_if_index = ~0;
14281   u32 sw_if_index = ~0;
14282   u8 sw_if_index_set = 0;
14283   u8 sw_if_index_if_name_set = 0;
14284   u32 priority = ~0;
14285   u8 priority_set = 0;
14286   u32 weight = ~0;
14287   u8 weight_set = 0;
14288   u8 is_add = 1;
14289   u8 *locator_set_name = NULL;
14290   u8 locator_set_name_set = 0;
14291   int ret;
14292
14293   /* Parse args required to build the message */
14294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14295     {
14296       if (unformat (input, "del"))
14297         {
14298           is_add = 0;
14299         }
14300       else if (unformat (input, "locator-set %s", &locator_set_name))
14301         {
14302           locator_set_name_set = 1;
14303         }
14304       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14305                          &tmp_if_index))
14306         {
14307           sw_if_index_if_name_set = 1;
14308           sw_if_index = tmp_if_index;
14309         }
14310       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14311         {
14312           sw_if_index_set = 1;
14313           sw_if_index = tmp_if_index;
14314         }
14315       else if (unformat (input, "p %d", &priority))
14316         {
14317           priority_set = 1;
14318         }
14319       else if (unformat (input, "w %d", &weight))
14320         {
14321           weight_set = 1;
14322         }
14323       else
14324         break;
14325     }
14326
14327   if (locator_set_name_set == 0)
14328     {
14329       errmsg ("missing locator-set name");
14330       return -99;
14331     }
14332
14333   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14334     {
14335       errmsg ("missing sw_if_index");
14336       vec_free (locator_set_name);
14337       return -99;
14338     }
14339
14340   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14341     {
14342       errmsg ("cannot use both params interface name and sw_if_index");
14343       vec_free (locator_set_name);
14344       return -99;
14345     }
14346
14347   if (priority_set == 0)
14348     {
14349       errmsg ("missing locator-set priority");
14350       vec_free (locator_set_name);
14351       return -99;
14352     }
14353
14354   if (weight_set == 0)
14355     {
14356       errmsg ("missing locator-set weight");
14357       vec_free (locator_set_name);
14358       return -99;
14359     }
14360
14361   if (vec_len (locator_set_name) > 64)
14362     {
14363       errmsg ("locator-set name too long");
14364       vec_free (locator_set_name);
14365       return -99;
14366     }
14367   vec_add1 (locator_set_name, 0);
14368
14369   /* Construct the API message */
14370   M (ONE_ADD_DEL_LOCATOR, mp);
14371
14372   mp->is_add = is_add;
14373   mp->sw_if_index = ntohl (sw_if_index);
14374   mp->priority = priority;
14375   mp->weight = weight;
14376   clib_memcpy (mp->locator_set_name, locator_set_name,
14377                vec_len (locator_set_name));
14378   vec_free (locator_set_name);
14379
14380   /* send it... */
14381   S (mp);
14382
14383   /* Wait for a reply... */
14384   W (ret);
14385   return ret;
14386 }
14387
14388 #define api_lisp_add_del_locator api_one_add_del_locator
14389
14390 uword
14391 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14392 {
14393   u32 *key_id = va_arg (*args, u32 *);
14394   u8 *s = 0;
14395
14396   if (unformat (input, "%s", &s))
14397     {
14398       if (!strcmp ((char *) s, "sha1"))
14399         key_id[0] = HMAC_SHA_1_96;
14400       else if (!strcmp ((char *) s, "sha256"))
14401         key_id[0] = HMAC_SHA_256_128;
14402       else
14403         {
14404           clib_warning ("invalid key_id: '%s'", s);
14405           key_id[0] = HMAC_NO_KEY;
14406         }
14407     }
14408   else
14409     return 0;
14410
14411   vec_free (s);
14412   return 1;
14413 }
14414
14415 static int
14416 api_one_add_del_local_eid (vat_main_t * vam)
14417 {
14418   unformat_input_t *input = vam->input;
14419   vl_api_one_add_del_local_eid_t *mp;
14420   u8 is_add = 1;
14421   u8 eid_set = 0;
14422   lisp_eid_vat_t _eid, *eid = &_eid;
14423   u8 *locator_set_name = 0;
14424   u8 locator_set_name_set = 0;
14425   u32 vni = 0;
14426   u16 key_id = 0;
14427   u8 *key = 0;
14428   int ret;
14429
14430   /* Parse args required to build the message */
14431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14432     {
14433       if (unformat (input, "del"))
14434         {
14435           is_add = 0;
14436         }
14437       else if (unformat (input, "vni %d", &vni))
14438         {
14439           ;
14440         }
14441       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14442         {
14443           eid_set = 1;
14444         }
14445       else if (unformat (input, "locator-set %s", &locator_set_name))
14446         {
14447           locator_set_name_set = 1;
14448         }
14449       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14450         ;
14451       else if (unformat (input, "secret-key %_%v%_", &key))
14452         ;
14453       else
14454         break;
14455     }
14456
14457   if (locator_set_name_set == 0)
14458     {
14459       errmsg ("missing locator-set name");
14460       return -99;
14461     }
14462
14463   if (0 == eid_set)
14464     {
14465       errmsg ("EID address not set!");
14466       vec_free (locator_set_name);
14467       return -99;
14468     }
14469
14470   if (key && (0 == key_id))
14471     {
14472       errmsg ("invalid key_id!");
14473       return -99;
14474     }
14475
14476   if (vec_len (key) > 64)
14477     {
14478       errmsg ("key too long");
14479       vec_free (key);
14480       return -99;
14481     }
14482
14483   if (vec_len (locator_set_name) > 64)
14484     {
14485       errmsg ("locator-set name too long");
14486       vec_free (locator_set_name);
14487       return -99;
14488     }
14489   vec_add1 (locator_set_name, 0);
14490
14491   /* Construct the API message */
14492   M (ONE_ADD_DEL_LOCAL_EID, mp);
14493
14494   mp->is_add = is_add;
14495   lisp_eid_put_vat (&mp->eid, eid);
14496   mp->vni = clib_host_to_net_u32 (vni);
14497   mp->key.id = key_id;
14498   clib_memcpy (mp->locator_set_name, locator_set_name,
14499                vec_len (locator_set_name));
14500   clib_memcpy (mp->key.key, key, vec_len (key));
14501
14502   vec_free (locator_set_name);
14503   vec_free (key);
14504
14505   /* send it... */
14506   S (mp);
14507
14508   /* Wait for a reply... */
14509   W (ret);
14510   return ret;
14511 }
14512
14513 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14514
14515 static int
14516 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14517 {
14518   u32 dp_table = 0, vni = 0;;
14519   unformat_input_t *input = vam->input;
14520   vl_api_gpe_add_del_fwd_entry_t *mp;
14521   u8 is_add = 1;
14522   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14523   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14524   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14525   u32 action = ~0, w;
14526   ip4_address_t rmt_rloc4, lcl_rloc4;
14527   ip6_address_t rmt_rloc6, lcl_rloc6;
14528   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14529   int ret;
14530
14531   clib_memset (&rloc, 0, sizeof (rloc));
14532
14533   /* Parse args required to build the message */
14534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14535     {
14536       if (unformat (input, "del"))
14537         is_add = 0;
14538       else if (unformat (input, "add"))
14539         is_add = 1;
14540       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14541         {
14542           rmt_eid_set = 1;
14543         }
14544       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14545         {
14546           lcl_eid_set = 1;
14547         }
14548       else if (unformat (input, "vrf %d", &dp_table))
14549         ;
14550       else if (unformat (input, "bd %d", &dp_table))
14551         ;
14552       else if (unformat (input, "vni %d", &vni))
14553         ;
14554       else if (unformat (input, "w %d", &w))
14555         {
14556           if (!curr_rloc)
14557             {
14558               errmsg ("No RLOC configured for setting priority/weight!");
14559               return -99;
14560             }
14561           curr_rloc->weight = w;
14562         }
14563       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14564                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14565         {
14566           rloc.addr.af = 0;
14567           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14568           rloc.weight = 0;
14569           vec_add1 (lcl_locs, rloc);
14570
14571           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14572           vec_add1 (rmt_locs, rloc);
14573           /* weight saved in rmt loc */
14574           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14575         }
14576       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14577                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14578         {
14579           rloc.addr.af = 1;
14580           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14581           rloc.weight = 0;
14582           vec_add1 (lcl_locs, rloc);
14583
14584           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14585           vec_add1 (rmt_locs, rloc);
14586           /* weight saved in rmt loc */
14587           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14588         }
14589       else if (unformat (input, "action %d", &action))
14590         {
14591           ;
14592         }
14593       else
14594         {
14595           clib_warning ("parse error '%U'", format_unformat_error, input);
14596           return -99;
14597         }
14598     }
14599
14600   if (!rmt_eid_set)
14601     {
14602       errmsg ("remote eid addresses not set");
14603       return -99;
14604     }
14605
14606   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14607     {
14608       errmsg ("eid types don't match");
14609       return -99;
14610     }
14611
14612   if (0 == rmt_locs && (u32) ~ 0 == action)
14613     {
14614       errmsg ("action not set for negative mapping");
14615       return -99;
14616     }
14617
14618   /* Construct the API message */
14619   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14620       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14621
14622   mp->is_add = is_add;
14623   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14624   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14625   mp->dp_table = clib_host_to_net_u32 (dp_table);
14626   mp->vni = clib_host_to_net_u32 (vni);
14627   mp->action = action;
14628
14629   if (0 != rmt_locs && 0 != lcl_locs)
14630     {
14631       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14632       clib_memcpy (mp->locs, lcl_locs,
14633                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14634
14635       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14636       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14637                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14638     }
14639   vec_free (lcl_locs);
14640   vec_free (rmt_locs);
14641
14642   /* send it... */
14643   S (mp);
14644
14645   /* Wait for a reply... */
14646   W (ret);
14647   return ret;
14648 }
14649
14650 static int
14651 api_one_add_del_map_server (vat_main_t * vam)
14652 {
14653   unformat_input_t *input = vam->input;
14654   vl_api_one_add_del_map_server_t *mp;
14655   u8 is_add = 1;
14656   u8 ipv4_set = 0;
14657   u8 ipv6_set = 0;
14658   ip4_address_t ipv4;
14659   ip6_address_t ipv6;
14660   int ret;
14661
14662   /* Parse args required to build the message */
14663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14664     {
14665       if (unformat (input, "del"))
14666         {
14667           is_add = 0;
14668         }
14669       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14670         {
14671           ipv4_set = 1;
14672         }
14673       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14674         {
14675           ipv6_set = 1;
14676         }
14677       else
14678         break;
14679     }
14680
14681   if (ipv4_set && ipv6_set)
14682     {
14683       errmsg ("both eid v4 and v6 addresses set");
14684       return -99;
14685     }
14686
14687   if (!ipv4_set && !ipv6_set)
14688     {
14689       errmsg ("eid addresses not set");
14690       return -99;
14691     }
14692
14693   /* Construct the API message */
14694   M (ONE_ADD_DEL_MAP_SERVER, mp);
14695
14696   mp->is_add = is_add;
14697   if (ipv6_set)
14698     {
14699       mp->ip_address.af = 1;
14700       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14701     }
14702   else
14703     {
14704       mp->ip_address.af = 0;
14705       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14706     }
14707
14708   /* send it... */
14709   S (mp);
14710
14711   /* Wait for a reply... */
14712   W (ret);
14713   return ret;
14714 }
14715
14716 #define api_lisp_add_del_map_server api_one_add_del_map_server
14717
14718 static int
14719 api_one_add_del_map_resolver (vat_main_t * vam)
14720 {
14721   unformat_input_t *input = vam->input;
14722   vl_api_one_add_del_map_resolver_t *mp;
14723   u8 is_add = 1;
14724   u8 ipv4_set = 0;
14725   u8 ipv6_set = 0;
14726   ip4_address_t ipv4;
14727   ip6_address_t ipv6;
14728   int ret;
14729
14730   /* Parse args required to build the message */
14731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14732     {
14733       if (unformat (input, "del"))
14734         {
14735           is_add = 0;
14736         }
14737       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14738         {
14739           ipv4_set = 1;
14740         }
14741       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14742         {
14743           ipv6_set = 1;
14744         }
14745       else
14746         break;
14747     }
14748
14749   if (ipv4_set && ipv6_set)
14750     {
14751       errmsg ("both eid v4 and v6 addresses set");
14752       return -99;
14753     }
14754
14755   if (!ipv4_set && !ipv6_set)
14756     {
14757       errmsg ("eid addresses not set");
14758       return -99;
14759     }
14760
14761   /* Construct the API message */
14762   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14763
14764   mp->is_add = is_add;
14765   if (ipv6_set)
14766     {
14767       mp->ip_address.af = 1;
14768       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14769     }
14770   else
14771     {
14772       mp->ip_address.af = 0;
14773       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14774     }
14775
14776   /* send it... */
14777   S (mp);
14778
14779   /* Wait for a reply... */
14780   W (ret);
14781   return ret;
14782 }
14783
14784 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14785
14786 static int
14787 api_lisp_gpe_enable_disable (vat_main_t * vam)
14788 {
14789   unformat_input_t *input = vam->input;
14790   vl_api_gpe_enable_disable_t *mp;
14791   u8 is_set = 0;
14792   u8 is_enable = 1;
14793   int ret;
14794
14795   /* Parse args required to build the message */
14796   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14797     {
14798       if (unformat (input, "enable"))
14799         {
14800           is_set = 1;
14801           is_enable = 1;
14802         }
14803       else if (unformat (input, "disable"))
14804         {
14805           is_set = 1;
14806           is_enable = 0;
14807         }
14808       else
14809         break;
14810     }
14811
14812   if (is_set == 0)
14813     {
14814       errmsg ("Value not set");
14815       return -99;
14816     }
14817
14818   /* Construct the API message */
14819   M (GPE_ENABLE_DISABLE, mp);
14820
14821   mp->is_enable = is_enable;
14822
14823   /* send it... */
14824   S (mp);
14825
14826   /* Wait for a reply... */
14827   W (ret);
14828   return ret;
14829 }
14830
14831 static int
14832 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14833 {
14834   unformat_input_t *input = vam->input;
14835   vl_api_one_rloc_probe_enable_disable_t *mp;
14836   u8 is_set = 0;
14837   u8 is_enable = 0;
14838   int ret;
14839
14840   /* Parse args required to build the message */
14841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14842     {
14843       if (unformat (input, "enable"))
14844         {
14845           is_set = 1;
14846           is_enable = 1;
14847         }
14848       else if (unformat (input, "disable"))
14849         is_set = 1;
14850       else
14851         break;
14852     }
14853
14854   if (!is_set)
14855     {
14856       errmsg ("Value not set");
14857       return -99;
14858     }
14859
14860   /* Construct the API message */
14861   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14862
14863   mp->is_enable = is_enable;
14864
14865   /* send it... */
14866   S (mp);
14867
14868   /* Wait for a reply... */
14869   W (ret);
14870   return ret;
14871 }
14872
14873 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14874
14875 static int
14876 api_one_map_register_enable_disable (vat_main_t * vam)
14877 {
14878   unformat_input_t *input = vam->input;
14879   vl_api_one_map_register_enable_disable_t *mp;
14880   u8 is_set = 0;
14881   u8 is_enable = 0;
14882   int ret;
14883
14884   /* Parse args required to build the message */
14885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14886     {
14887       if (unformat (input, "enable"))
14888         {
14889           is_set = 1;
14890           is_enable = 1;
14891         }
14892       else if (unformat (input, "disable"))
14893         is_set = 1;
14894       else
14895         break;
14896     }
14897
14898   if (!is_set)
14899     {
14900       errmsg ("Value not set");
14901       return -99;
14902     }
14903
14904   /* Construct the API message */
14905   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14906
14907   mp->is_enable = is_enable;
14908
14909   /* send it... */
14910   S (mp);
14911
14912   /* Wait for a reply... */
14913   W (ret);
14914   return ret;
14915 }
14916
14917 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14918
14919 static int
14920 api_one_enable_disable (vat_main_t * vam)
14921 {
14922   unformat_input_t *input = vam->input;
14923   vl_api_one_enable_disable_t *mp;
14924   u8 is_set = 0;
14925   u8 is_enable = 0;
14926   int ret;
14927
14928   /* Parse args required to build the message */
14929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14930     {
14931       if (unformat (input, "enable"))
14932         {
14933           is_set = 1;
14934           is_enable = 1;
14935         }
14936       else if (unformat (input, "disable"))
14937         {
14938           is_set = 1;
14939         }
14940       else
14941         break;
14942     }
14943
14944   if (!is_set)
14945     {
14946       errmsg ("Value not set");
14947       return -99;
14948     }
14949
14950   /* Construct the API message */
14951   M (ONE_ENABLE_DISABLE, mp);
14952
14953   mp->is_enable = is_enable;
14954
14955   /* send it... */
14956   S (mp);
14957
14958   /* Wait for a reply... */
14959   W (ret);
14960   return ret;
14961 }
14962
14963 #define api_lisp_enable_disable api_one_enable_disable
14964
14965 static int
14966 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14967 {
14968   unformat_input_t *input = vam->input;
14969   vl_api_one_enable_disable_xtr_mode_t *mp;
14970   u8 is_set = 0;
14971   u8 is_enable = 0;
14972   int ret;
14973
14974   /* Parse args required to build the message */
14975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14976     {
14977       if (unformat (input, "enable"))
14978         {
14979           is_set = 1;
14980           is_enable = 1;
14981         }
14982       else if (unformat (input, "disable"))
14983         {
14984           is_set = 1;
14985         }
14986       else
14987         break;
14988     }
14989
14990   if (!is_set)
14991     {
14992       errmsg ("Value not set");
14993       return -99;
14994     }
14995
14996   /* Construct the API message */
14997   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14998
14999   mp->is_enable = is_enable;
15000
15001   /* send it... */
15002   S (mp);
15003
15004   /* Wait for a reply... */
15005   W (ret);
15006   return ret;
15007 }
15008
15009 static int
15010 api_one_show_xtr_mode (vat_main_t * vam)
15011 {
15012   vl_api_one_show_xtr_mode_t *mp;
15013   int ret;
15014
15015   /* Construct the API message */
15016   M (ONE_SHOW_XTR_MODE, mp);
15017
15018   /* send it... */
15019   S (mp);
15020
15021   /* Wait for a reply... */
15022   W (ret);
15023   return ret;
15024 }
15025
15026 static int
15027 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15028 {
15029   unformat_input_t *input = vam->input;
15030   vl_api_one_enable_disable_pitr_mode_t *mp;
15031   u8 is_set = 0;
15032   u8 is_enable = 0;
15033   int ret;
15034
15035   /* Parse args required to build the message */
15036   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15037     {
15038       if (unformat (input, "enable"))
15039         {
15040           is_set = 1;
15041           is_enable = 1;
15042         }
15043       else if (unformat (input, "disable"))
15044         {
15045           is_set = 1;
15046         }
15047       else
15048         break;
15049     }
15050
15051   if (!is_set)
15052     {
15053       errmsg ("Value not set");
15054       return -99;
15055     }
15056
15057   /* Construct the API message */
15058   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15059
15060   mp->is_enable = is_enable;
15061
15062   /* send it... */
15063   S (mp);
15064
15065   /* Wait for a reply... */
15066   W (ret);
15067   return ret;
15068 }
15069
15070 static int
15071 api_one_show_pitr_mode (vat_main_t * vam)
15072 {
15073   vl_api_one_show_pitr_mode_t *mp;
15074   int ret;
15075
15076   /* Construct the API message */
15077   M (ONE_SHOW_PITR_MODE, mp);
15078
15079   /* send it... */
15080   S (mp);
15081
15082   /* Wait for a reply... */
15083   W (ret);
15084   return ret;
15085 }
15086
15087 static int
15088 api_one_enable_disable_petr_mode (vat_main_t * vam)
15089 {
15090   unformat_input_t *input = vam->input;
15091   vl_api_one_enable_disable_petr_mode_t *mp;
15092   u8 is_set = 0;
15093   u8 is_enable = 0;
15094   int ret;
15095
15096   /* Parse args required to build the message */
15097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15098     {
15099       if (unformat (input, "enable"))
15100         {
15101           is_set = 1;
15102           is_enable = 1;
15103         }
15104       else if (unformat (input, "disable"))
15105         {
15106           is_set = 1;
15107         }
15108       else
15109         break;
15110     }
15111
15112   if (!is_set)
15113     {
15114       errmsg ("Value not set");
15115       return -99;
15116     }
15117
15118   /* Construct the API message */
15119   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15120
15121   mp->is_enable = is_enable;
15122
15123   /* send it... */
15124   S (mp);
15125
15126   /* Wait for a reply... */
15127   W (ret);
15128   return ret;
15129 }
15130
15131 static int
15132 api_one_show_petr_mode (vat_main_t * vam)
15133 {
15134   vl_api_one_show_petr_mode_t *mp;
15135   int ret;
15136
15137   /* Construct the API message */
15138   M (ONE_SHOW_PETR_MODE, mp);
15139
15140   /* send it... */
15141   S (mp);
15142
15143   /* Wait for a reply... */
15144   W (ret);
15145   return ret;
15146 }
15147
15148 static int
15149 api_show_one_map_register_state (vat_main_t * vam)
15150 {
15151   vl_api_show_one_map_register_state_t *mp;
15152   int ret;
15153
15154   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15155
15156   /* send */
15157   S (mp);
15158
15159   /* wait for reply */
15160   W (ret);
15161   return ret;
15162 }
15163
15164 #define api_show_lisp_map_register_state api_show_one_map_register_state
15165
15166 static int
15167 api_show_one_rloc_probe_state (vat_main_t * vam)
15168 {
15169   vl_api_show_one_rloc_probe_state_t *mp;
15170   int ret;
15171
15172   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15173
15174   /* send */
15175   S (mp);
15176
15177   /* wait for reply */
15178   W (ret);
15179   return ret;
15180 }
15181
15182 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15183
15184 static int
15185 api_one_add_del_ndp_entry (vat_main_t * vam)
15186 {
15187   vl_api_one_add_del_ndp_entry_t *mp;
15188   unformat_input_t *input = vam->input;
15189   u8 is_add = 1;
15190   u8 mac_set = 0;
15191   u8 bd_set = 0;
15192   u8 ip_set = 0;
15193   u8 mac[6] = { 0, };
15194   u8 ip6[16] = { 0, };
15195   u32 bd = ~0;
15196   int ret;
15197
15198   /* Parse args required to build the message */
15199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15200     {
15201       if (unformat (input, "del"))
15202         is_add = 0;
15203       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15204         mac_set = 1;
15205       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15206         ip_set = 1;
15207       else if (unformat (input, "bd %d", &bd))
15208         bd_set = 1;
15209       else
15210         {
15211           errmsg ("parse error '%U'", format_unformat_error, input);
15212           return -99;
15213         }
15214     }
15215
15216   if (!bd_set || !ip_set || (!mac_set && is_add))
15217     {
15218       errmsg ("Missing BD, IP or MAC!");
15219       return -99;
15220     }
15221
15222   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15223   mp->is_add = is_add;
15224   clib_memcpy (&mp->entry.mac, mac, 6);
15225   mp->bd = clib_host_to_net_u32 (bd);
15226   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15227
15228   /* send */
15229   S (mp);
15230
15231   /* wait for reply */
15232   W (ret);
15233   return ret;
15234 }
15235
15236 static int
15237 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15238 {
15239   vl_api_one_add_del_l2_arp_entry_t *mp;
15240   unformat_input_t *input = vam->input;
15241   u8 is_add = 1;
15242   u8 mac_set = 0;
15243   u8 bd_set = 0;
15244   u8 ip_set = 0;
15245   u8 mac[6] = { 0, };
15246   u32 ip4 = 0, bd = ~0;
15247   int ret;
15248
15249   /* Parse args required to build the message */
15250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15251     {
15252       if (unformat (input, "del"))
15253         is_add = 0;
15254       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15255         mac_set = 1;
15256       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15257         ip_set = 1;
15258       else if (unformat (input, "bd %d", &bd))
15259         bd_set = 1;
15260       else
15261         {
15262           errmsg ("parse error '%U'", format_unformat_error, input);
15263           return -99;
15264         }
15265     }
15266
15267   if (!bd_set || !ip_set || (!mac_set && is_add))
15268     {
15269       errmsg ("Missing BD, IP or MAC!");
15270       return -99;
15271     }
15272
15273   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15274   mp->is_add = is_add;
15275   clib_memcpy (&mp->entry.mac, mac, 6);
15276   mp->bd = clib_host_to_net_u32 (bd);
15277   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15278
15279   /* send */
15280   S (mp);
15281
15282   /* wait for reply */
15283   W (ret);
15284   return ret;
15285 }
15286
15287 static int
15288 api_one_ndp_bd_get (vat_main_t * vam)
15289 {
15290   vl_api_one_ndp_bd_get_t *mp;
15291   int ret;
15292
15293   M (ONE_NDP_BD_GET, mp);
15294
15295   /* send */
15296   S (mp);
15297
15298   /* wait for reply */
15299   W (ret);
15300   return ret;
15301 }
15302
15303 static int
15304 api_one_ndp_entries_get (vat_main_t * vam)
15305 {
15306   vl_api_one_ndp_entries_get_t *mp;
15307   unformat_input_t *input = vam->input;
15308   u8 bd_set = 0;
15309   u32 bd = ~0;
15310   int ret;
15311
15312   /* Parse args required to build the message */
15313   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15314     {
15315       if (unformat (input, "bd %d", &bd))
15316         bd_set = 1;
15317       else
15318         {
15319           errmsg ("parse error '%U'", format_unformat_error, input);
15320           return -99;
15321         }
15322     }
15323
15324   if (!bd_set)
15325     {
15326       errmsg ("Expected bridge domain!");
15327       return -99;
15328     }
15329
15330   M (ONE_NDP_ENTRIES_GET, mp);
15331   mp->bd = clib_host_to_net_u32 (bd);
15332
15333   /* send */
15334   S (mp);
15335
15336   /* wait for reply */
15337   W (ret);
15338   return ret;
15339 }
15340
15341 static int
15342 api_one_l2_arp_bd_get (vat_main_t * vam)
15343 {
15344   vl_api_one_l2_arp_bd_get_t *mp;
15345   int ret;
15346
15347   M (ONE_L2_ARP_BD_GET, mp);
15348
15349   /* send */
15350   S (mp);
15351
15352   /* wait for reply */
15353   W (ret);
15354   return ret;
15355 }
15356
15357 static int
15358 api_one_l2_arp_entries_get (vat_main_t * vam)
15359 {
15360   vl_api_one_l2_arp_entries_get_t *mp;
15361   unformat_input_t *input = vam->input;
15362   u8 bd_set = 0;
15363   u32 bd = ~0;
15364   int ret;
15365
15366   /* Parse args required to build the message */
15367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15368     {
15369       if (unformat (input, "bd %d", &bd))
15370         bd_set = 1;
15371       else
15372         {
15373           errmsg ("parse error '%U'", format_unformat_error, input);
15374           return -99;
15375         }
15376     }
15377
15378   if (!bd_set)
15379     {
15380       errmsg ("Expected bridge domain!");
15381       return -99;
15382     }
15383
15384   M (ONE_L2_ARP_ENTRIES_GET, mp);
15385   mp->bd = clib_host_to_net_u32 (bd);
15386
15387   /* send */
15388   S (mp);
15389
15390   /* wait for reply */
15391   W (ret);
15392   return ret;
15393 }
15394
15395 static int
15396 api_one_stats_enable_disable (vat_main_t * vam)
15397 {
15398   vl_api_one_stats_enable_disable_t *mp;
15399   unformat_input_t *input = vam->input;
15400   u8 is_set = 0;
15401   u8 is_enable = 0;
15402   int ret;
15403
15404   /* Parse args required to build the message */
15405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15406     {
15407       if (unformat (input, "enable"))
15408         {
15409           is_set = 1;
15410           is_enable = 1;
15411         }
15412       else if (unformat (input, "disable"))
15413         {
15414           is_set = 1;
15415         }
15416       else
15417         break;
15418     }
15419
15420   if (!is_set)
15421     {
15422       errmsg ("Value not set");
15423       return -99;
15424     }
15425
15426   M (ONE_STATS_ENABLE_DISABLE, mp);
15427   mp->is_enable = is_enable;
15428
15429   /* send */
15430   S (mp);
15431
15432   /* wait for reply */
15433   W (ret);
15434   return ret;
15435 }
15436
15437 static int
15438 api_show_one_stats_enable_disable (vat_main_t * vam)
15439 {
15440   vl_api_show_one_stats_enable_disable_t *mp;
15441   int ret;
15442
15443   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15444
15445   /* send */
15446   S (mp);
15447
15448   /* wait for reply */
15449   W (ret);
15450   return ret;
15451 }
15452
15453 static int
15454 api_show_one_map_request_mode (vat_main_t * vam)
15455 {
15456   vl_api_show_one_map_request_mode_t *mp;
15457   int ret;
15458
15459   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15460
15461   /* send */
15462   S (mp);
15463
15464   /* wait for reply */
15465   W (ret);
15466   return ret;
15467 }
15468
15469 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15470
15471 static int
15472 api_one_map_request_mode (vat_main_t * vam)
15473 {
15474   unformat_input_t *input = vam->input;
15475   vl_api_one_map_request_mode_t *mp;
15476   u8 mode = 0;
15477   int ret;
15478
15479   /* Parse args required to build the message */
15480   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15481     {
15482       if (unformat (input, "dst-only"))
15483         mode = 0;
15484       else if (unformat (input, "src-dst"))
15485         mode = 1;
15486       else
15487         {
15488           errmsg ("parse error '%U'", format_unformat_error, input);
15489           return -99;
15490         }
15491     }
15492
15493   M (ONE_MAP_REQUEST_MODE, mp);
15494
15495   mp->mode = mode;
15496
15497   /* send */
15498   S (mp);
15499
15500   /* wait for reply */
15501   W (ret);
15502   return ret;
15503 }
15504
15505 #define api_lisp_map_request_mode api_one_map_request_mode
15506
15507 /**
15508  * Enable/disable ONE proxy ITR.
15509  *
15510  * @param vam vpp API test context
15511  * @return return code
15512  */
15513 static int
15514 api_one_pitr_set_locator_set (vat_main_t * vam)
15515 {
15516   u8 ls_name_set = 0;
15517   unformat_input_t *input = vam->input;
15518   vl_api_one_pitr_set_locator_set_t *mp;
15519   u8 is_add = 1;
15520   u8 *ls_name = 0;
15521   int ret;
15522
15523   /* Parse args required to build the message */
15524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15525     {
15526       if (unformat (input, "del"))
15527         is_add = 0;
15528       else if (unformat (input, "locator-set %s", &ls_name))
15529         ls_name_set = 1;
15530       else
15531         {
15532           errmsg ("parse error '%U'", format_unformat_error, input);
15533           return -99;
15534         }
15535     }
15536
15537   if (!ls_name_set)
15538     {
15539       errmsg ("locator-set name not set!");
15540       return -99;
15541     }
15542
15543   M (ONE_PITR_SET_LOCATOR_SET, mp);
15544
15545   mp->is_add = is_add;
15546   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15547   vec_free (ls_name);
15548
15549   /* send */
15550   S (mp);
15551
15552   /* wait for reply */
15553   W (ret);
15554   return ret;
15555 }
15556
15557 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15558
15559 static int
15560 api_one_nsh_set_locator_set (vat_main_t * vam)
15561 {
15562   u8 ls_name_set = 0;
15563   unformat_input_t *input = vam->input;
15564   vl_api_one_nsh_set_locator_set_t *mp;
15565   u8 is_add = 1;
15566   u8 *ls_name = 0;
15567   int ret;
15568
15569   /* Parse args required to build the message */
15570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15571     {
15572       if (unformat (input, "del"))
15573         is_add = 0;
15574       else if (unformat (input, "ls %s", &ls_name))
15575         ls_name_set = 1;
15576       else
15577         {
15578           errmsg ("parse error '%U'", format_unformat_error, input);
15579           return -99;
15580         }
15581     }
15582
15583   if (!ls_name_set && is_add)
15584     {
15585       errmsg ("locator-set name not set!");
15586       return -99;
15587     }
15588
15589   M (ONE_NSH_SET_LOCATOR_SET, mp);
15590
15591   mp->is_add = is_add;
15592   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15593   vec_free (ls_name);
15594
15595   /* send */
15596   S (mp);
15597
15598   /* wait for reply */
15599   W (ret);
15600   return ret;
15601 }
15602
15603 static int
15604 api_show_one_pitr (vat_main_t * vam)
15605 {
15606   vl_api_show_one_pitr_t *mp;
15607   int ret;
15608
15609   if (!vam->json_output)
15610     {
15611       print (vam->ofp, "%=20s", "lisp status:");
15612     }
15613
15614   M (SHOW_ONE_PITR, mp);
15615   /* send it... */
15616   S (mp);
15617
15618   /* Wait for a reply... */
15619   W (ret);
15620   return ret;
15621 }
15622
15623 #define api_show_lisp_pitr api_show_one_pitr
15624
15625 static int
15626 api_one_use_petr (vat_main_t * vam)
15627 {
15628   unformat_input_t *input = vam->input;
15629   vl_api_one_use_petr_t *mp;
15630   u8 is_add = 0;
15631   ip_address_t ip;
15632   int ret;
15633
15634   clib_memset (&ip, 0, sizeof (ip));
15635
15636   /* Parse args required to build the message */
15637   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15638     {
15639       if (unformat (input, "disable"))
15640         is_add = 0;
15641       else
15642         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15643         {
15644           is_add = 1;
15645           ip_addr_version (&ip) = AF_IP4;
15646         }
15647       else
15648         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15649         {
15650           is_add = 1;
15651           ip_addr_version (&ip) = AF_IP6;
15652         }
15653       else
15654         {
15655           errmsg ("parse error '%U'", format_unformat_error, input);
15656           return -99;
15657         }
15658     }
15659
15660   M (ONE_USE_PETR, mp);
15661
15662   mp->is_add = is_add;
15663   if (is_add)
15664     {
15665       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15666       if (mp->ip_address.af)
15667         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15668       else
15669         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15670     }
15671
15672   /* send */
15673   S (mp);
15674
15675   /* wait for reply */
15676   W (ret);
15677   return ret;
15678 }
15679
15680 #define api_lisp_use_petr api_one_use_petr
15681
15682 static int
15683 api_show_one_nsh_mapping (vat_main_t * vam)
15684 {
15685   vl_api_show_one_use_petr_t *mp;
15686   int ret;
15687
15688   if (!vam->json_output)
15689     {
15690       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15691     }
15692
15693   M (SHOW_ONE_NSH_MAPPING, mp);
15694   /* send it... */
15695   S (mp);
15696
15697   /* Wait for a reply... */
15698   W (ret);
15699   return ret;
15700 }
15701
15702 static int
15703 api_show_one_use_petr (vat_main_t * vam)
15704 {
15705   vl_api_show_one_use_petr_t *mp;
15706   int ret;
15707
15708   if (!vam->json_output)
15709     {
15710       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15711     }
15712
15713   M (SHOW_ONE_USE_PETR, mp);
15714   /* send it... */
15715   S (mp);
15716
15717   /* Wait for a reply... */
15718   W (ret);
15719   return ret;
15720 }
15721
15722 #define api_show_lisp_use_petr api_show_one_use_petr
15723
15724 /**
15725  * Add/delete mapping between vni and vrf
15726  */
15727 static int
15728 api_one_eid_table_add_del_map (vat_main_t * vam)
15729 {
15730   unformat_input_t *input = vam->input;
15731   vl_api_one_eid_table_add_del_map_t *mp;
15732   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15733   u32 vni, vrf, bd_index;
15734   int ret;
15735
15736   /* Parse args required to build the message */
15737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15738     {
15739       if (unformat (input, "del"))
15740         is_add = 0;
15741       else if (unformat (input, "vrf %d", &vrf))
15742         vrf_set = 1;
15743       else if (unformat (input, "bd_index %d", &bd_index))
15744         bd_index_set = 1;
15745       else if (unformat (input, "vni %d", &vni))
15746         vni_set = 1;
15747       else
15748         break;
15749     }
15750
15751   if (!vni_set || (!vrf_set && !bd_index_set))
15752     {
15753       errmsg ("missing arguments!");
15754       return -99;
15755     }
15756
15757   if (vrf_set && bd_index_set)
15758     {
15759       errmsg ("error: both vrf and bd entered!");
15760       return -99;
15761     }
15762
15763   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15764
15765   mp->is_add = is_add;
15766   mp->vni = htonl (vni);
15767   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15768   mp->is_l2 = bd_index_set;
15769
15770   /* send */
15771   S (mp);
15772
15773   /* wait for reply */
15774   W (ret);
15775   return ret;
15776 }
15777
15778 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15779
15780 uword
15781 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15782 {
15783   u32 *action = va_arg (*args, u32 *);
15784   u8 *s = 0;
15785
15786   if (unformat (input, "%s", &s))
15787     {
15788       if (!strcmp ((char *) s, "no-action"))
15789         action[0] = 0;
15790       else if (!strcmp ((char *) s, "natively-forward"))
15791         action[0] = 1;
15792       else if (!strcmp ((char *) s, "send-map-request"))
15793         action[0] = 2;
15794       else if (!strcmp ((char *) s, "drop"))
15795         action[0] = 3;
15796       else
15797         {
15798           clib_warning ("invalid action: '%s'", s);
15799           action[0] = 3;
15800         }
15801     }
15802   else
15803     return 0;
15804
15805   vec_free (s);
15806   return 1;
15807 }
15808
15809 /**
15810  * Add/del remote mapping to/from ONE control plane
15811  *
15812  * @param vam vpp API test context
15813  * @return return code
15814  */
15815 static int
15816 api_one_add_del_remote_mapping (vat_main_t * vam)
15817 {
15818   unformat_input_t *input = vam->input;
15819   vl_api_one_add_del_remote_mapping_t *mp;
15820   u32 vni = 0;
15821   lisp_eid_vat_t _eid, *eid = &_eid;
15822   lisp_eid_vat_t _seid, *seid = &_seid;
15823   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15824   u32 action = ~0, p, w, data_len;
15825   ip4_address_t rloc4;
15826   ip6_address_t rloc6;
15827   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15828   int ret;
15829
15830   clib_memset (&rloc, 0, sizeof (rloc));
15831
15832   /* Parse args required to build the message */
15833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15834     {
15835       if (unformat (input, "del-all"))
15836         {
15837           del_all = 1;
15838         }
15839       else if (unformat (input, "del"))
15840         {
15841           is_add = 0;
15842         }
15843       else if (unformat (input, "add"))
15844         {
15845           is_add = 1;
15846         }
15847       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15848         {
15849           eid_set = 1;
15850         }
15851       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15852         {
15853           seid_set = 1;
15854         }
15855       else if (unformat (input, "vni %d", &vni))
15856         {
15857           ;
15858         }
15859       else if (unformat (input, "p %d w %d", &p, &w))
15860         {
15861           if (!curr_rloc)
15862             {
15863               errmsg ("No RLOC configured for setting priority/weight!");
15864               return -99;
15865             }
15866           curr_rloc->priority = p;
15867           curr_rloc->weight = w;
15868         }
15869       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15870         {
15871           rloc.ip_address.af = 0;
15872           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15873           vec_add1 (rlocs, rloc);
15874           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15875         }
15876       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15877         {
15878           rloc.ip_address.af = 1;
15879           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15880           vec_add1 (rlocs, rloc);
15881           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15882         }
15883       else if (unformat (input, "action %U",
15884                          unformat_negative_mapping_action, &action))
15885         {
15886           ;
15887         }
15888       else
15889         {
15890           clib_warning ("parse error '%U'", format_unformat_error, input);
15891           return -99;
15892         }
15893     }
15894
15895   if (0 == eid_set)
15896     {
15897       errmsg ("missing params!");
15898       return -99;
15899     }
15900
15901   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15902     {
15903       errmsg ("no action set for negative map-reply!");
15904       return -99;
15905     }
15906
15907   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15908
15909   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15910   mp->is_add = is_add;
15911   mp->vni = htonl (vni);
15912   mp->action = (u8) action;
15913   mp->is_src_dst = seid_set;
15914   mp->del_all = del_all;
15915   lisp_eid_put_vat (&mp->deid, eid);
15916   lisp_eid_put_vat (&mp->seid, seid);
15917
15918   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15919   clib_memcpy (mp->rlocs, rlocs, data_len);
15920   vec_free (rlocs);
15921
15922   /* send it... */
15923   S (mp);
15924
15925   /* Wait for a reply... */
15926   W (ret);
15927   return ret;
15928 }
15929
15930 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15931
15932 /**
15933  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15934  * forwarding entries in data-plane accordingly.
15935  *
15936  * @param vam vpp API test context
15937  * @return return code
15938  */
15939 static int
15940 api_one_add_del_adjacency (vat_main_t * vam)
15941 {
15942   unformat_input_t *input = vam->input;
15943   vl_api_one_add_del_adjacency_t *mp;
15944   u32 vni = 0;
15945   u8 is_add = 1;
15946   int ret;
15947   lisp_eid_vat_t leid, reid;
15948
15949   leid.type = reid.type = (u8) ~ 0;
15950
15951   /* Parse args required to build the message */
15952   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15953     {
15954       if (unformat (input, "del"))
15955         {
15956           is_add = 0;
15957         }
15958       else if (unformat (input, "add"))
15959         {
15960           is_add = 1;
15961         }
15962       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
15963                          &reid.addr.ip, &reid.len))
15964         {
15965           reid.type = 0;        /* ipv4 */
15966         }
15967       else if (unformat (input, "reid %U", unformat_ethernet_address,
15968                          &reid.addr.mac))
15969         {
15970           reid.type = 1;        /* mac */
15971         }
15972       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
15973                          &leid.addr.ip, &leid.len))
15974         {
15975           leid.type = 0;        /* ipv4 */
15976         }
15977       else if (unformat (input, "leid %U", unformat_ethernet_address,
15978                          &leid.addr.mac))
15979         {
15980           leid.type = 1;        /* mac */
15981         }
15982       else if (unformat (input, "vni %d", &vni))
15983         {
15984           ;
15985         }
15986       else
15987         {
15988           errmsg ("parse error '%U'", format_unformat_error, input);
15989           return -99;
15990         }
15991     }
15992
15993   if ((u8) ~ 0 == reid.type)
15994     {
15995       errmsg ("missing params!");
15996       return -99;
15997     }
15998
15999   if (leid.type != reid.type)
16000     {
16001       errmsg ("remote and local EIDs are of different types!");
16002       return -99;
16003     }
16004
16005   M (ONE_ADD_DEL_ADJACENCY, mp);
16006   mp->is_add = is_add;
16007   mp->vni = htonl (vni);
16008   lisp_eid_put_vat (&mp->leid, &leid);
16009   lisp_eid_put_vat (&mp->reid, &reid);
16010
16011   /* send it... */
16012   S (mp);
16013
16014   /* Wait for a reply... */
16015   W (ret);
16016   return ret;
16017 }
16018
16019 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16020
16021 uword
16022 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16023 {
16024   u32 *mode = va_arg (*args, u32 *);
16025
16026   if (unformat (input, "lisp"))
16027     *mode = 0;
16028   else if (unformat (input, "vxlan"))
16029     *mode = 1;
16030   else
16031     return 0;
16032
16033   return 1;
16034 }
16035
16036 static int
16037 api_gpe_get_encap_mode (vat_main_t * vam)
16038 {
16039   vl_api_gpe_get_encap_mode_t *mp;
16040   int ret;
16041
16042   /* Construct the API message */
16043   M (GPE_GET_ENCAP_MODE, mp);
16044
16045   /* send it... */
16046   S (mp);
16047
16048   /* Wait for a reply... */
16049   W (ret);
16050   return ret;
16051 }
16052
16053 static int
16054 api_gpe_set_encap_mode (vat_main_t * vam)
16055 {
16056   unformat_input_t *input = vam->input;
16057   vl_api_gpe_set_encap_mode_t *mp;
16058   int ret;
16059   u32 mode = 0;
16060
16061   /* Parse args required to build the message */
16062   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16063     {
16064       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16065         ;
16066       else
16067         break;
16068     }
16069
16070   /* Construct the API message */
16071   M (GPE_SET_ENCAP_MODE, mp);
16072
16073   mp->is_vxlan = mode;
16074
16075   /* send it... */
16076   S (mp);
16077
16078   /* Wait for a reply... */
16079   W (ret);
16080   return ret;
16081 }
16082
16083 static int
16084 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16085 {
16086   unformat_input_t *input = vam->input;
16087   vl_api_gpe_add_del_iface_t *mp;
16088   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16089   u32 dp_table = 0, vni = 0;
16090   int ret;
16091
16092   /* Parse args required to build the message */
16093   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16094     {
16095       if (unformat (input, "up"))
16096         {
16097           action_set = 1;
16098           is_add = 1;
16099         }
16100       else if (unformat (input, "down"))
16101         {
16102           action_set = 1;
16103           is_add = 0;
16104         }
16105       else if (unformat (input, "table_id %d", &dp_table))
16106         {
16107           dp_table_set = 1;
16108         }
16109       else if (unformat (input, "bd_id %d", &dp_table))
16110         {
16111           dp_table_set = 1;
16112           is_l2 = 1;
16113         }
16114       else if (unformat (input, "vni %d", &vni))
16115         {
16116           vni_set = 1;
16117         }
16118       else
16119         break;
16120     }
16121
16122   if (action_set == 0)
16123     {
16124       errmsg ("Action not set");
16125       return -99;
16126     }
16127   if (dp_table_set == 0 || vni_set == 0)
16128     {
16129       errmsg ("vni and dp_table must be set");
16130       return -99;
16131     }
16132
16133   /* Construct the API message */
16134   M (GPE_ADD_DEL_IFACE, mp);
16135
16136   mp->is_add = is_add;
16137   mp->dp_table = clib_host_to_net_u32 (dp_table);
16138   mp->is_l2 = is_l2;
16139   mp->vni = clib_host_to_net_u32 (vni);
16140
16141   /* send it... */
16142   S (mp);
16143
16144   /* Wait for a reply... */
16145   W (ret);
16146   return ret;
16147 }
16148
16149 static int
16150 api_one_map_register_fallback_threshold (vat_main_t * vam)
16151 {
16152   unformat_input_t *input = vam->input;
16153   vl_api_one_map_register_fallback_threshold_t *mp;
16154   u32 value = 0;
16155   u8 is_set = 0;
16156   int ret;
16157
16158   /* Parse args required to build the message */
16159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16160     {
16161       if (unformat (input, "%u", &value))
16162         is_set = 1;
16163       else
16164         {
16165           clib_warning ("parse error '%U'", format_unformat_error, input);
16166           return -99;
16167         }
16168     }
16169
16170   if (!is_set)
16171     {
16172       errmsg ("fallback threshold value is missing!");
16173       return -99;
16174     }
16175
16176   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16177   mp->value = clib_host_to_net_u32 (value);
16178
16179   /* send it... */
16180   S (mp);
16181
16182   /* Wait for a reply... */
16183   W (ret);
16184   return ret;
16185 }
16186
16187 static int
16188 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16189 {
16190   vl_api_show_one_map_register_fallback_threshold_t *mp;
16191   int ret;
16192
16193   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16194
16195   /* send it... */
16196   S (mp);
16197
16198   /* Wait for a reply... */
16199   W (ret);
16200   return ret;
16201 }
16202
16203 uword
16204 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16205 {
16206   u32 *proto = va_arg (*args, u32 *);
16207
16208   if (unformat (input, "udp"))
16209     *proto = 1;
16210   else if (unformat (input, "api"))
16211     *proto = 2;
16212   else
16213     return 0;
16214
16215   return 1;
16216 }
16217
16218 static int
16219 api_one_set_transport_protocol (vat_main_t * vam)
16220 {
16221   unformat_input_t *input = vam->input;
16222   vl_api_one_set_transport_protocol_t *mp;
16223   u8 is_set = 0;
16224   u32 protocol = 0;
16225   int ret;
16226
16227   /* Parse args required to build the message */
16228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16229     {
16230       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16231         is_set = 1;
16232       else
16233         {
16234           clib_warning ("parse error '%U'", format_unformat_error, input);
16235           return -99;
16236         }
16237     }
16238
16239   if (!is_set)
16240     {
16241       errmsg ("Transport protocol missing!");
16242       return -99;
16243     }
16244
16245   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16246   mp->protocol = (u8) protocol;
16247
16248   /* send it... */
16249   S (mp);
16250
16251   /* Wait for a reply... */
16252   W (ret);
16253   return ret;
16254 }
16255
16256 static int
16257 api_one_get_transport_protocol (vat_main_t * vam)
16258 {
16259   vl_api_one_get_transport_protocol_t *mp;
16260   int ret;
16261
16262   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16263
16264   /* send it... */
16265   S (mp);
16266
16267   /* Wait for a reply... */
16268   W (ret);
16269   return ret;
16270 }
16271
16272 static int
16273 api_one_map_register_set_ttl (vat_main_t * vam)
16274 {
16275   unformat_input_t *input = vam->input;
16276   vl_api_one_map_register_set_ttl_t *mp;
16277   u32 ttl = 0;
16278   u8 is_set = 0;
16279   int ret;
16280
16281   /* Parse args required to build the message */
16282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16283     {
16284       if (unformat (input, "%u", &ttl))
16285         is_set = 1;
16286       else
16287         {
16288           clib_warning ("parse error '%U'", format_unformat_error, input);
16289           return -99;
16290         }
16291     }
16292
16293   if (!is_set)
16294     {
16295       errmsg ("TTL value missing!");
16296       return -99;
16297     }
16298
16299   M (ONE_MAP_REGISTER_SET_TTL, mp);
16300   mp->ttl = clib_host_to_net_u32 (ttl);
16301
16302   /* send it... */
16303   S (mp);
16304
16305   /* Wait for a reply... */
16306   W (ret);
16307   return ret;
16308 }
16309
16310 static int
16311 api_show_one_map_register_ttl (vat_main_t * vam)
16312 {
16313   vl_api_show_one_map_register_ttl_t *mp;
16314   int ret;
16315
16316   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16317
16318   /* send it... */
16319   S (mp);
16320
16321   /* Wait for a reply... */
16322   W (ret);
16323   return ret;
16324 }
16325
16326 /**
16327  * Add/del map request itr rlocs from ONE control plane and updates
16328  *
16329  * @param vam vpp API test context
16330  * @return return code
16331  */
16332 static int
16333 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16334 {
16335   unformat_input_t *input = vam->input;
16336   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16337   u8 *locator_set_name = 0;
16338   u8 locator_set_name_set = 0;
16339   u8 is_add = 1;
16340   int ret;
16341
16342   /* Parse args required to build the message */
16343   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16344     {
16345       if (unformat (input, "del"))
16346         {
16347           is_add = 0;
16348         }
16349       else if (unformat (input, "%_%v%_", &locator_set_name))
16350         {
16351           locator_set_name_set = 1;
16352         }
16353       else
16354         {
16355           clib_warning ("parse error '%U'", format_unformat_error, input);
16356           return -99;
16357         }
16358     }
16359
16360   if (is_add && !locator_set_name_set)
16361     {
16362       errmsg ("itr-rloc is not set!");
16363       return -99;
16364     }
16365
16366   if (is_add && vec_len (locator_set_name) > 64)
16367     {
16368       errmsg ("itr-rloc locator-set name too long");
16369       vec_free (locator_set_name);
16370       return -99;
16371     }
16372
16373   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16374   mp->is_add = is_add;
16375   if (is_add)
16376     {
16377       clib_memcpy (mp->locator_set_name, locator_set_name,
16378                    vec_len (locator_set_name));
16379     }
16380   else
16381     {
16382       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16383     }
16384   vec_free (locator_set_name);
16385
16386   /* send it... */
16387   S (mp);
16388
16389   /* Wait for a reply... */
16390   W (ret);
16391   return ret;
16392 }
16393
16394 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16395
16396 static int
16397 api_one_locator_dump (vat_main_t * vam)
16398 {
16399   unformat_input_t *input = vam->input;
16400   vl_api_one_locator_dump_t *mp;
16401   vl_api_control_ping_t *mp_ping;
16402   u8 is_index_set = 0, is_name_set = 0;
16403   u8 *ls_name = 0;
16404   u32 ls_index = ~0;
16405   int ret;
16406
16407   /* Parse args required to build the message */
16408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16409     {
16410       if (unformat (input, "ls_name %_%v%_", &ls_name))
16411         {
16412           is_name_set = 1;
16413         }
16414       else if (unformat (input, "ls_index %d", &ls_index))
16415         {
16416           is_index_set = 1;
16417         }
16418       else
16419         {
16420           errmsg ("parse error '%U'", format_unformat_error, input);
16421           return -99;
16422         }
16423     }
16424
16425   if (!is_index_set && !is_name_set)
16426     {
16427       errmsg ("error: expected one of index or name!");
16428       return -99;
16429     }
16430
16431   if (is_index_set && is_name_set)
16432     {
16433       errmsg ("error: only one param expected!");
16434       return -99;
16435     }
16436
16437   if (vec_len (ls_name) > 62)
16438     {
16439       errmsg ("error: locator set name too long!");
16440       return -99;
16441     }
16442
16443   if (!vam->json_output)
16444     {
16445       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16446     }
16447
16448   M (ONE_LOCATOR_DUMP, mp);
16449   mp->is_index_set = is_index_set;
16450
16451   if (is_index_set)
16452     mp->ls_index = clib_host_to_net_u32 (ls_index);
16453   else
16454     {
16455       vec_add1 (ls_name, 0);
16456       strncpy ((char *) mp->ls_name, (char *) ls_name,
16457                sizeof (mp->ls_name) - 1);
16458     }
16459
16460   /* send it... */
16461   S (mp);
16462
16463   /* Use a control ping for synchronization */
16464   MPING (CONTROL_PING, mp_ping);
16465   S (mp_ping);
16466
16467   /* Wait for a reply... */
16468   W (ret);
16469   return ret;
16470 }
16471
16472 #define api_lisp_locator_dump api_one_locator_dump
16473
16474 static int
16475 api_one_locator_set_dump (vat_main_t * vam)
16476 {
16477   vl_api_one_locator_set_dump_t *mp;
16478   vl_api_control_ping_t *mp_ping;
16479   unformat_input_t *input = vam->input;
16480   u8 filter = 0;
16481   int ret;
16482
16483   /* Parse args required to build the message */
16484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16485     {
16486       if (unformat (input, "local"))
16487         {
16488           filter = 1;
16489         }
16490       else if (unformat (input, "remote"))
16491         {
16492           filter = 2;
16493         }
16494       else
16495         {
16496           errmsg ("parse error '%U'", format_unformat_error, input);
16497           return -99;
16498         }
16499     }
16500
16501   if (!vam->json_output)
16502     {
16503       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16504     }
16505
16506   M (ONE_LOCATOR_SET_DUMP, mp);
16507
16508   mp->filter = filter;
16509
16510   /* send it... */
16511   S (mp);
16512
16513   /* Use a control ping for synchronization */
16514   MPING (CONTROL_PING, mp_ping);
16515   S (mp_ping);
16516
16517   /* Wait for a reply... */
16518   W (ret);
16519   return ret;
16520 }
16521
16522 #define api_lisp_locator_set_dump api_one_locator_set_dump
16523
16524 static int
16525 api_one_eid_table_map_dump (vat_main_t * vam)
16526 {
16527   u8 is_l2 = 0;
16528   u8 mode_set = 0;
16529   unformat_input_t *input = vam->input;
16530   vl_api_one_eid_table_map_dump_t *mp;
16531   vl_api_control_ping_t *mp_ping;
16532   int ret;
16533
16534   /* Parse args required to build the message */
16535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16536     {
16537       if (unformat (input, "l2"))
16538         {
16539           is_l2 = 1;
16540           mode_set = 1;
16541         }
16542       else if (unformat (input, "l3"))
16543         {
16544           is_l2 = 0;
16545           mode_set = 1;
16546         }
16547       else
16548         {
16549           errmsg ("parse error '%U'", format_unformat_error, input);
16550           return -99;
16551         }
16552     }
16553
16554   if (!mode_set)
16555     {
16556       errmsg ("expected one of 'l2' or 'l3' parameter!");
16557       return -99;
16558     }
16559
16560   if (!vam->json_output)
16561     {
16562       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16563     }
16564
16565   M (ONE_EID_TABLE_MAP_DUMP, mp);
16566   mp->is_l2 = is_l2;
16567
16568   /* send it... */
16569   S (mp);
16570
16571   /* Use a control ping for synchronization */
16572   MPING (CONTROL_PING, mp_ping);
16573   S (mp_ping);
16574
16575   /* Wait for a reply... */
16576   W (ret);
16577   return ret;
16578 }
16579
16580 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16581
16582 static int
16583 api_one_eid_table_vni_dump (vat_main_t * vam)
16584 {
16585   vl_api_one_eid_table_vni_dump_t *mp;
16586   vl_api_control_ping_t *mp_ping;
16587   int ret;
16588
16589   if (!vam->json_output)
16590     {
16591       print (vam->ofp, "VNI");
16592     }
16593
16594   M (ONE_EID_TABLE_VNI_DUMP, mp);
16595
16596   /* send it... */
16597   S (mp);
16598
16599   /* Use a control ping for synchronization */
16600   MPING (CONTROL_PING, mp_ping);
16601   S (mp_ping);
16602
16603   /* Wait for a reply... */
16604   W (ret);
16605   return ret;
16606 }
16607
16608 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16609
16610 static int
16611 api_one_eid_table_dump (vat_main_t * vam)
16612 {
16613   unformat_input_t *i = vam->input;
16614   vl_api_one_eid_table_dump_t *mp;
16615   vl_api_control_ping_t *mp_ping;
16616   u8 filter = 0;
16617   int ret;
16618   u32 vni, t = 0;
16619   lisp_eid_vat_t eid;
16620   u8 eid_set = 0;
16621
16622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16623     {
16624       if (unformat
16625           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16626         {
16627           eid_set = 1;
16628           eid.type = 0;
16629         }
16630       else
16631         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16632         {
16633           eid_set = 1;
16634           eid.type = 1;
16635         }
16636       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16637         {
16638           eid_set = 1;
16639           eid.type = 2;
16640         }
16641       else if (unformat (i, "vni %d", &t))
16642         {
16643           vni = t;
16644         }
16645       else if (unformat (i, "local"))
16646         {
16647           filter = 1;
16648         }
16649       else if (unformat (i, "remote"))
16650         {
16651           filter = 2;
16652         }
16653       else
16654         {
16655           errmsg ("parse error '%U'", format_unformat_error, i);
16656           return -99;
16657         }
16658     }
16659
16660   if (!vam->json_output)
16661     {
16662       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16663              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16664     }
16665
16666   M (ONE_EID_TABLE_DUMP, mp);
16667
16668   mp->filter = filter;
16669   if (eid_set)
16670     {
16671       mp->eid_set = 1;
16672       mp->vni = htonl (vni);
16673       lisp_eid_put_vat (&mp->eid, &eid);
16674     }
16675
16676   /* send it... */
16677   S (mp);
16678
16679   /* Use a control ping for synchronization */
16680   MPING (CONTROL_PING, mp_ping);
16681   S (mp_ping);
16682
16683   /* Wait for a reply... */
16684   W (ret);
16685   return ret;
16686 }
16687
16688 #define api_lisp_eid_table_dump api_one_eid_table_dump
16689
16690 static int
16691 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16692 {
16693   unformat_input_t *i = vam->input;
16694   vl_api_gpe_fwd_entries_get_t *mp;
16695   u8 vni_set = 0;
16696   u32 vni = ~0;
16697   int ret;
16698
16699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16700     {
16701       if (unformat (i, "vni %d", &vni))
16702         {
16703           vni_set = 1;
16704         }
16705       else
16706         {
16707           errmsg ("parse error '%U'", format_unformat_error, i);
16708           return -99;
16709         }
16710     }
16711
16712   if (!vni_set)
16713     {
16714       errmsg ("vni not set!");
16715       return -99;
16716     }
16717
16718   if (!vam->json_output)
16719     {
16720       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16721              "leid", "reid");
16722     }
16723
16724   M (GPE_FWD_ENTRIES_GET, mp);
16725   mp->vni = clib_host_to_net_u32 (vni);
16726
16727   /* send it... */
16728   S (mp);
16729
16730   /* Wait for a reply... */
16731   W (ret);
16732   return ret;
16733 }
16734
16735 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16736 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16737 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16738 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16739 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16740 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16741 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16742 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16743
16744 static int
16745 api_one_adjacencies_get (vat_main_t * vam)
16746 {
16747   unformat_input_t *i = vam->input;
16748   vl_api_one_adjacencies_get_t *mp;
16749   u8 vni_set = 0;
16750   u32 vni = ~0;
16751   int ret;
16752
16753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16754     {
16755       if (unformat (i, "vni %d", &vni))
16756         {
16757           vni_set = 1;
16758         }
16759       else
16760         {
16761           errmsg ("parse error '%U'", format_unformat_error, i);
16762           return -99;
16763         }
16764     }
16765
16766   if (!vni_set)
16767     {
16768       errmsg ("vni not set!");
16769       return -99;
16770     }
16771
16772   if (!vam->json_output)
16773     {
16774       print (vam->ofp, "%s %40s", "leid", "reid");
16775     }
16776
16777   M (ONE_ADJACENCIES_GET, mp);
16778   mp->vni = clib_host_to_net_u32 (vni);
16779
16780   /* send it... */
16781   S (mp);
16782
16783   /* Wait for a reply... */
16784   W (ret);
16785   return ret;
16786 }
16787
16788 #define api_lisp_adjacencies_get api_one_adjacencies_get
16789
16790 static int
16791 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16792 {
16793   unformat_input_t *i = vam->input;
16794   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16795   int ret;
16796   u8 ip_family_set = 0, is_ip4 = 1;
16797
16798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16799     {
16800       if (unformat (i, "ip4"))
16801         {
16802           ip_family_set = 1;
16803           is_ip4 = 1;
16804         }
16805       else if (unformat (i, "ip6"))
16806         {
16807           ip_family_set = 1;
16808           is_ip4 = 0;
16809         }
16810       else
16811         {
16812           errmsg ("parse error '%U'", format_unformat_error, i);
16813           return -99;
16814         }
16815     }
16816
16817   if (!ip_family_set)
16818     {
16819       errmsg ("ip family not set!");
16820       return -99;
16821     }
16822
16823   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16824   mp->is_ip4 = is_ip4;
16825
16826   /* send it... */
16827   S (mp);
16828
16829   /* Wait for a reply... */
16830   W (ret);
16831   return ret;
16832 }
16833
16834 static int
16835 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16836 {
16837   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16838   int ret;
16839
16840   if (!vam->json_output)
16841     {
16842       print (vam->ofp, "VNIs");
16843     }
16844
16845   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16846
16847   /* send it... */
16848   S (mp);
16849
16850   /* Wait for a reply... */
16851   W (ret);
16852   return ret;
16853 }
16854
16855 static int
16856 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16857 {
16858   unformat_input_t *i = vam->input;
16859   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16860   int ret = 0;
16861   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16862   struct in_addr ip4;
16863   struct in6_addr ip6;
16864   u32 table_id = 0, nh_sw_if_index = ~0;
16865
16866   clib_memset (&ip4, 0, sizeof (ip4));
16867   clib_memset (&ip6, 0, sizeof (ip6));
16868
16869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16870     {
16871       if (unformat (i, "del"))
16872         is_add = 0;
16873       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16874                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16875         {
16876           ip_set = 1;
16877           is_ip4 = 1;
16878         }
16879       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16880                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16881         {
16882           ip_set = 1;
16883           is_ip4 = 0;
16884         }
16885       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16886         {
16887           ip_set = 1;
16888           is_ip4 = 1;
16889           nh_sw_if_index = ~0;
16890         }
16891       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16892         {
16893           ip_set = 1;
16894           is_ip4 = 0;
16895           nh_sw_if_index = ~0;
16896         }
16897       else if (unformat (i, "table %d", &table_id))
16898         ;
16899       else
16900         {
16901           errmsg ("parse error '%U'", format_unformat_error, i);
16902           return -99;
16903         }
16904     }
16905
16906   if (!ip_set)
16907     {
16908       errmsg ("nh addr not set!");
16909       return -99;
16910     }
16911
16912   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16913   mp->is_add = is_add;
16914   mp->table_id = clib_host_to_net_u32 (table_id);
16915   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16916   mp->nh_addr.af = is_ip4 ? 0 : 1;
16917   if (is_ip4)
16918     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16919   else
16920     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16921
16922   /* send it... */
16923   S (mp);
16924
16925   /* Wait for a reply... */
16926   W (ret);
16927   return ret;
16928 }
16929
16930 static int
16931 api_one_map_server_dump (vat_main_t * vam)
16932 {
16933   vl_api_one_map_server_dump_t *mp;
16934   vl_api_control_ping_t *mp_ping;
16935   int ret;
16936
16937   if (!vam->json_output)
16938     {
16939       print (vam->ofp, "%=20s", "Map server");
16940     }
16941
16942   M (ONE_MAP_SERVER_DUMP, mp);
16943   /* send it... */
16944   S (mp);
16945
16946   /* Use a control ping for synchronization */
16947   MPING (CONTROL_PING, mp_ping);
16948   S (mp_ping);
16949
16950   /* Wait for a reply... */
16951   W (ret);
16952   return ret;
16953 }
16954
16955 #define api_lisp_map_server_dump api_one_map_server_dump
16956
16957 static int
16958 api_one_map_resolver_dump (vat_main_t * vam)
16959 {
16960   vl_api_one_map_resolver_dump_t *mp;
16961   vl_api_control_ping_t *mp_ping;
16962   int ret;
16963
16964   if (!vam->json_output)
16965     {
16966       print (vam->ofp, "%=20s", "Map resolver");
16967     }
16968
16969   M (ONE_MAP_RESOLVER_DUMP, mp);
16970   /* send it... */
16971   S (mp);
16972
16973   /* Use a control ping for synchronization */
16974   MPING (CONTROL_PING, mp_ping);
16975   S (mp_ping);
16976
16977   /* Wait for a reply... */
16978   W (ret);
16979   return ret;
16980 }
16981
16982 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16983
16984 static int
16985 api_one_stats_flush (vat_main_t * vam)
16986 {
16987   vl_api_one_stats_flush_t *mp;
16988   int ret = 0;
16989
16990   M (ONE_STATS_FLUSH, mp);
16991   S (mp);
16992   W (ret);
16993   return ret;
16994 }
16995
16996 static int
16997 api_one_stats_dump (vat_main_t * vam)
16998 {
16999   vl_api_one_stats_dump_t *mp;
17000   vl_api_control_ping_t *mp_ping;
17001   int ret;
17002
17003   M (ONE_STATS_DUMP, mp);
17004   /* send it... */
17005   S (mp);
17006
17007   /* Use a control ping for synchronization */
17008   MPING (CONTROL_PING, mp_ping);
17009   S (mp_ping);
17010
17011   /* Wait for a reply... */
17012   W (ret);
17013   return ret;
17014 }
17015
17016 static int
17017 api_show_one_status (vat_main_t * vam)
17018 {
17019   vl_api_show_one_status_t *mp;
17020   int ret;
17021
17022   if (!vam->json_output)
17023     {
17024       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17025     }
17026
17027   M (SHOW_ONE_STATUS, mp);
17028   /* send it... */
17029   S (mp);
17030   /* Wait for a reply... */
17031   W (ret);
17032   return ret;
17033 }
17034
17035 #define api_show_lisp_status api_show_one_status
17036
17037 static int
17038 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17039 {
17040   vl_api_gpe_fwd_entry_path_dump_t *mp;
17041   vl_api_control_ping_t *mp_ping;
17042   unformat_input_t *i = vam->input;
17043   u32 fwd_entry_index = ~0;
17044   int ret;
17045
17046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17047     {
17048       if (unformat (i, "index %d", &fwd_entry_index))
17049         ;
17050       else
17051         break;
17052     }
17053
17054   if (~0 == fwd_entry_index)
17055     {
17056       errmsg ("no index specified!");
17057       return -99;
17058     }
17059
17060   if (!vam->json_output)
17061     {
17062       print (vam->ofp, "first line");
17063     }
17064
17065   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17066
17067   /* send it... */
17068   S (mp);
17069   /* Use a control ping for synchronization */
17070   MPING (CONTROL_PING, mp_ping);
17071   S (mp_ping);
17072
17073   /* Wait for a reply... */
17074   W (ret);
17075   return ret;
17076 }
17077
17078 static int
17079 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17080 {
17081   vl_api_one_get_map_request_itr_rlocs_t *mp;
17082   int ret;
17083
17084   if (!vam->json_output)
17085     {
17086       print (vam->ofp, "%=20s", "itr-rlocs:");
17087     }
17088
17089   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17090   /* send it... */
17091   S (mp);
17092   /* Wait for a reply... */
17093   W (ret);
17094   return ret;
17095 }
17096
17097 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17098
17099 static int
17100 api_af_packet_create (vat_main_t * vam)
17101 {
17102   unformat_input_t *i = vam->input;
17103   vl_api_af_packet_create_t *mp;
17104   u8 *host_if_name = 0;
17105   u8 hw_addr[6];
17106   u8 random_hw_addr = 1;
17107   int ret;
17108
17109   clib_memset (hw_addr, 0, sizeof (hw_addr));
17110
17111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17112     {
17113       if (unformat (i, "name %s", &host_if_name))
17114         vec_add1 (host_if_name, 0);
17115       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17116         random_hw_addr = 0;
17117       else
17118         break;
17119     }
17120
17121   if (!vec_len (host_if_name))
17122     {
17123       errmsg ("host-interface name must be specified");
17124       return -99;
17125     }
17126
17127   if (vec_len (host_if_name) > 64)
17128     {
17129       errmsg ("host-interface name too long");
17130       return -99;
17131     }
17132
17133   M (AF_PACKET_CREATE, mp);
17134
17135   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17136   clib_memcpy (mp->hw_addr, hw_addr, 6);
17137   mp->use_random_hw_addr = random_hw_addr;
17138   vec_free (host_if_name);
17139
17140   S (mp);
17141
17142   /* *INDENT-OFF* */
17143   W2 (ret,
17144       ({
17145         if (ret == 0)
17146           fprintf (vam->ofp ? vam->ofp : stderr,
17147                    " new sw_if_index = %d\n", vam->sw_if_index);
17148       }));
17149   /* *INDENT-ON* */
17150   return ret;
17151 }
17152
17153 static int
17154 api_af_packet_delete (vat_main_t * vam)
17155 {
17156   unformat_input_t *i = vam->input;
17157   vl_api_af_packet_delete_t *mp;
17158   u8 *host_if_name = 0;
17159   int ret;
17160
17161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17162     {
17163       if (unformat (i, "name %s", &host_if_name))
17164         vec_add1 (host_if_name, 0);
17165       else
17166         break;
17167     }
17168
17169   if (!vec_len (host_if_name))
17170     {
17171       errmsg ("host-interface name must be specified");
17172       return -99;
17173     }
17174
17175   if (vec_len (host_if_name) > 64)
17176     {
17177       errmsg ("host-interface name too long");
17178       return -99;
17179     }
17180
17181   M (AF_PACKET_DELETE, mp);
17182
17183   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17184   vec_free (host_if_name);
17185
17186   S (mp);
17187   W (ret);
17188   return ret;
17189 }
17190
17191 static void vl_api_af_packet_details_t_handler
17192   (vl_api_af_packet_details_t * mp)
17193 {
17194   vat_main_t *vam = &vat_main;
17195
17196   print (vam->ofp, "%-16s %d",
17197          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17198 }
17199
17200 static void vl_api_af_packet_details_t_handler_json
17201   (vl_api_af_packet_details_t * mp)
17202 {
17203   vat_main_t *vam = &vat_main;
17204   vat_json_node_t *node = NULL;
17205
17206   if (VAT_JSON_ARRAY != vam->json_tree.type)
17207     {
17208       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17209       vat_json_init_array (&vam->json_tree);
17210     }
17211   node = vat_json_array_add (&vam->json_tree);
17212
17213   vat_json_init_object (node);
17214   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17215   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17216 }
17217
17218 static int
17219 api_af_packet_dump (vat_main_t * vam)
17220 {
17221   vl_api_af_packet_dump_t *mp;
17222   vl_api_control_ping_t *mp_ping;
17223   int ret;
17224
17225   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17226   /* Get list of tap interfaces */
17227   M (AF_PACKET_DUMP, mp);
17228   S (mp);
17229
17230   /* Use a control ping for synchronization */
17231   MPING (CONTROL_PING, mp_ping);
17232   S (mp_ping);
17233
17234   W (ret);
17235   return ret;
17236 }
17237
17238 static int
17239 api_policer_add_del (vat_main_t * vam)
17240 {
17241   unformat_input_t *i = vam->input;
17242   vl_api_policer_add_del_t *mp;
17243   u8 is_add = 1;
17244   u8 *name = 0;
17245   u32 cir = 0;
17246   u32 eir = 0;
17247   u64 cb = 0;
17248   u64 eb = 0;
17249   u8 rate_type = 0;
17250   u8 round_type = 0;
17251   u8 type = 0;
17252   u8 color_aware = 0;
17253   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17254   int ret;
17255
17256   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17257   conform_action.dscp = 0;
17258   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17259   exceed_action.dscp = 0;
17260   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17261   violate_action.dscp = 0;
17262
17263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17264     {
17265       if (unformat (i, "del"))
17266         is_add = 0;
17267       else if (unformat (i, "name %s", &name))
17268         vec_add1 (name, 0);
17269       else if (unformat (i, "cir %u", &cir))
17270         ;
17271       else if (unformat (i, "eir %u", &eir))
17272         ;
17273       else if (unformat (i, "cb %u", &cb))
17274         ;
17275       else if (unformat (i, "eb %u", &eb))
17276         ;
17277       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17278                          &rate_type))
17279         ;
17280       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17281                          &round_type))
17282         ;
17283       else if (unformat (i, "type %U", unformat_policer_type, &type))
17284         ;
17285       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17286                          &conform_action))
17287         ;
17288       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17289                          &exceed_action))
17290         ;
17291       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17292                          &violate_action))
17293         ;
17294       else if (unformat (i, "color-aware"))
17295         color_aware = 1;
17296       else
17297         break;
17298     }
17299
17300   if (!vec_len (name))
17301     {
17302       errmsg ("policer name must be specified");
17303       return -99;
17304     }
17305
17306   if (vec_len (name) > 64)
17307     {
17308       errmsg ("policer name too long");
17309       return -99;
17310     }
17311
17312   M (POLICER_ADD_DEL, mp);
17313
17314   clib_memcpy (mp->name, name, vec_len (name));
17315   vec_free (name);
17316   mp->is_add = is_add;
17317   mp->cir = ntohl (cir);
17318   mp->eir = ntohl (eir);
17319   mp->cb = clib_net_to_host_u64 (cb);
17320   mp->eb = clib_net_to_host_u64 (eb);
17321   mp->rate_type = rate_type;
17322   mp->round_type = round_type;
17323   mp->type = type;
17324   mp->conform_action.type = conform_action.action_type;
17325   mp->conform_action.dscp = conform_action.dscp;
17326   mp->exceed_action.type = exceed_action.action_type;
17327   mp->exceed_action.dscp = exceed_action.dscp;
17328   mp->violate_action.type = violate_action.action_type;
17329   mp->violate_action.dscp = violate_action.dscp;
17330   mp->color_aware = color_aware;
17331
17332   S (mp);
17333   W (ret);
17334   return ret;
17335 }
17336
17337 static int
17338 api_policer_dump (vat_main_t * vam)
17339 {
17340   unformat_input_t *i = vam->input;
17341   vl_api_policer_dump_t *mp;
17342   vl_api_control_ping_t *mp_ping;
17343   u8 *match_name = 0;
17344   u8 match_name_valid = 0;
17345   int ret;
17346
17347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17348     {
17349       if (unformat (i, "name %s", &match_name))
17350         {
17351           vec_add1 (match_name, 0);
17352           match_name_valid = 1;
17353         }
17354       else
17355         break;
17356     }
17357
17358   M (POLICER_DUMP, mp);
17359   mp->match_name_valid = match_name_valid;
17360   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17361   vec_free (match_name);
17362   /* send it... */
17363   S (mp);
17364
17365   /* Use a control ping for synchronization */
17366   MPING (CONTROL_PING, mp_ping);
17367   S (mp_ping);
17368
17369   /* Wait for a reply... */
17370   W (ret);
17371   return ret;
17372 }
17373
17374 static int
17375 api_policer_classify_set_interface (vat_main_t * vam)
17376 {
17377   unformat_input_t *i = vam->input;
17378   vl_api_policer_classify_set_interface_t *mp;
17379   u32 sw_if_index;
17380   int sw_if_index_set;
17381   u32 ip4_table_index = ~0;
17382   u32 ip6_table_index = ~0;
17383   u32 l2_table_index = ~0;
17384   u8 is_add = 1;
17385   int ret;
17386
17387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17388     {
17389       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17390         sw_if_index_set = 1;
17391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17392         sw_if_index_set = 1;
17393       else if (unformat (i, "del"))
17394         is_add = 0;
17395       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17396         ;
17397       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17398         ;
17399       else if (unformat (i, "l2-table %d", &l2_table_index))
17400         ;
17401       else
17402         {
17403           clib_warning ("parse error '%U'", format_unformat_error, i);
17404           return -99;
17405         }
17406     }
17407
17408   if (sw_if_index_set == 0)
17409     {
17410       errmsg ("missing interface name or sw_if_index");
17411       return -99;
17412     }
17413
17414   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17415
17416   mp->sw_if_index = ntohl (sw_if_index);
17417   mp->ip4_table_index = ntohl (ip4_table_index);
17418   mp->ip6_table_index = ntohl (ip6_table_index);
17419   mp->l2_table_index = ntohl (l2_table_index);
17420   mp->is_add = is_add;
17421
17422   S (mp);
17423   W (ret);
17424   return ret;
17425 }
17426
17427 static int
17428 api_policer_classify_dump (vat_main_t * vam)
17429 {
17430   unformat_input_t *i = vam->input;
17431   vl_api_policer_classify_dump_t *mp;
17432   vl_api_control_ping_t *mp_ping;
17433   u8 type = POLICER_CLASSIFY_N_TABLES;
17434   int ret;
17435
17436   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17437     ;
17438   else
17439     {
17440       errmsg ("classify table type must be specified");
17441       return -99;
17442     }
17443
17444   if (!vam->json_output)
17445     {
17446       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17447     }
17448
17449   M (POLICER_CLASSIFY_DUMP, mp);
17450   mp->type = type;
17451   /* send it... */
17452   S (mp);
17453
17454   /* Use a control ping for synchronization */
17455   MPING (CONTROL_PING, mp_ping);
17456   S (mp_ping);
17457
17458   /* Wait for a reply... */
17459   W (ret);
17460   return ret;
17461 }
17462
17463 static u8 *
17464 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17465 {
17466   vl_api_fib_path_nh_proto_t proto =
17467     va_arg (*args, vl_api_fib_path_nh_proto_t);
17468
17469   switch (proto)
17470     {
17471     case FIB_API_PATH_NH_PROTO_IP4:
17472       s = format (s, "ip4");
17473       break;
17474     case FIB_API_PATH_NH_PROTO_IP6:
17475       s = format (s, "ip6");
17476       break;
17477     case FIB_API_PATH_NH_PROTO_MPLS:
17478       s = format (s, "mpls");
17479       break;
17480     case FIB_API_PATH_NH_PROTO_BIER:
17481       s = format (s, "bier");
17482       break;
17483     case FIB_API_PATH_NH_PROTO_ETHERNET:
17484       s = format (s, "ethernet");
17485       break;
17486     }
17487
17488   return (s);
17489 }
17490
17491 static u8 *
17492 format_vl_api_ip_address_union (u8 * s, va_list * args)
17493 {
17494   vl_api_address_family_t af = va_arg (*args, int);
17495   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17496
17497   switch (af)
17498     {
17499     case ADDRESS_IP4:
17500       s = format (s, "%U", format_ip4_address, u->ip4);
17501       break;
17502     case ADDRESS_IP6:
17503       s = format (s, "%U", format_ip6_address, u->ip6);
17504       break;
17505     }
17506   return (s);
17507 }
17508
17509 static u8 *
17510 format_vl_api_fib_path_type (u8 * s, va_list * args)
17511 {
17512   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17513
17514   switch (t)
17515     {
17516     case FIB_API_PATH_TYPE_NORMAL:
17517       s = format (s, "normal");
17518       break;
17519     case FIB_API_PATH_TYPE_LOCAL:
17520       s = format (s, "local");
17521       break;
17522     case FIB_API_PATH_TYPE_DROP:
17523       s = format (s, "drop");
17524       break;
17525     case FIB_API_PATH_TYPE_UDP_ENCAP:
17526       s = format (s, "udp-encap");
17527       break;
17528     case FIB_API_PATH_TYPE_BIER_IMP:
17529       s = format (s, "bier-imp");
17530       break;
17531     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17532       s = format (s, "unreach");
17533       break;
17534     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17535       s = format (s, "prohibit");
17536       break;
17537     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17538       s = format (s, "src-lookup");
17539       break;
17540     case FIB_API_PATH_TYPE_DVR:
17541       s = format (s, "dvr");
17542       break;
17543     case FIB_API_PATH_TYPE_INTERFACE_RX:
17544       s = format (s, "interface-rx");
17545       break;
17546     case FIB_API_PATH_TYPE_CLASSIFY:
17547       s = format (s, "classify");
17548       break;
17549     }
17550
17551   return (s);
17552 }
17553
17554 static void
17555 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17556 {
17557   print (vam->ofp,
17558          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17559          ntohl (fp->weight), ntohl (fp->sw_if_index),
17560          format_vl_api_fib_path_type, fp->type,
17561          format_fib_api_path_nh_proto, fp->proto,
17562          format_vl_api_ip_address_union, &fp->nh.address);
17563 }
17564
17565 static void
17566 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17567                                  vl_api_fib_path_t * fp)
17568 {
17569   struct in_addr ip4;
17570   struct in6_addr ip6;
17571
17572   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17573   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17574   vat_json_object_add_uint (node, "type", fp->type);
17575   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17576   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17577     {
17578       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17579       vat_json_object_add_ip4 (node, "next_hop", ip4);
17580     }
17581   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17582     {
17583       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17584       vat_json_object_add_ip6 (node, "next_hop", ip6);
17585     }
17586 }
17587
17588 static void
17589 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17590 {
17591   vat_main_t *vam = &vat_main;
17592   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17593   vl_api_fib_path_t *fp;
17594   i32 i;
17595
17596   print (vam->ofp, "sw_if_index %d via:",
17597          ntohl (mp->mt_tunnel.mt_sw_if_index));
17598   fp = mp->mt_tunnel.mt_paths;
17599   for (i = 0; i < count; i++)
17600     {
17601       vl_api_fib_path_print (vam, fp);
17602       fp++;
17603     }
17604
17605   print (vam->ofp, "");
17606 }
17607
17608 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17609 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17610
17611 static void
17612 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17613 {
17614   vat_main_t *vam = &vat_main;
17615   vat_json_node_t *node = NULL;
17616   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17617   vl_api_fib_path_t *fp;
17618   i32 i;
17619
17620   if (VAT_JSON_ARRAY != vam->json_tree.type)
17621     {
17622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17623       vat_json_init_array (&vam->json_tree);
17624     }
17625   node = vat_json_array_add (&vam->json_tree);
17626
17627   vat_json_init_object (node);
17628   vat_json_object_add_uint (node, "sw_if_index",
17629                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17630
17631   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17632
17633   fp = mp->mt_tunnel.mt_paths;
17634   for (i = 0; i < count; i++)
17635     {
17636       vl_api_mpls_fib_path_json_print (node, fp);
17637       fp++;
17638     }
17639 }
17640
17641 static int
17642 api_mpls_tunnel_dump (vat_main_t * vam)
17643 {
17644   vl_api_mpls_tunnel_dump_t *mp;
17645   vl_api_control_ping_t *mp_ping;
17646   int ret;
17647
17648   M (MPLS_TUNNEL_DUMP, mp);
17649
17650   S (mp);
17651
17652   /* Use a control ping for synchronization */
17653   MPING (CONTROL_PING, mp_ping);
17654   S (mp_ping);
17655
17656   W (ret);
17657   return ret;
17658 }
17659
17660 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17661 #define vl_api_mpls_table_details_t_print vl_noop_handler
17662
17663
17664 static void
17665 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17666 {
17667   vat_main_t *vam = &vat_main;
17668
17669   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17670 }
17671
17672 static void vl_api_mpls_table_details_t_handler_json
17673   (vl_api_mpls_table_details_t * mp)
17674 {
17675   vat_main_t *vam = &vat_main;
17676   vat_json_node_t *node = NULL;
17677
17678   if (VAT_JSON_ARRAY != vam->json_tree.type)
17679     {
17680       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17681       vat_json_init_array (&vam->json_tree);
17682     }
17683   node = vat_json_array_add (&vam->json_tree);
17684
17685   vat_json_init_object (node);
17686   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17687 }
17688
17689 static int
17690 api_mpls_table_dump (vat_main_t * vam)
17691 {
17692   vl_api_mpls_table_dump_t *mp;
17693   vl_api_control_ping_t *mp_ping;
17694   int ret;
17695
17696   M (MPLS_TABLE_DUMP, mp);
17697   S (mp);
17698
17699   /* Use a control ping for synchronization */
17700   MPING (CONTROL_PING, mp_ping);
17701   S (mp_ping);
17702
17703   W (ret);
17704   return ret;
17705 }
17706
17707 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17708 #define vl_api_mpls_route_details_t_print vl_noop_handler
17709
17710 static void
17711 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17712 {
17713   vat_main_t *vam = &vat_main;
17714   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17715   vl_api_fib_path_t *fp;
17716   int i;
17717
17718   print (vam->ofp,
17719          "table-id %d, label %u, ess_bit %u",
17720          ntohl (mp->mr_route.mr_table_id),
17721          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17722   fp = mp->mr_route.mr_paths;
17723   for (i = 0; i < count; i++)
17724     {
17725       vl_api_fib_path_print (vam, fp);
17726       fp++;
17727     }
17728 }
17729
17730 static void vl_api_mpls_route_details_t_handler_json
17731   (vl_api_mpls_route_details_t * mp)
17732 {
17733   vat_main_t *vam = &vat_main;
17734   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17735   vat_json_node_t *node = NULL;
17736   vl_api_fib_path_t *fp;
17737   int i;
17738
17739   if (VAT_JSON_ARRAY != vam->json_tree.type)
17740     {
17741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17742       vat_json_init_array (&vam->json_tree);
17743     }
17744   node = vat_json_array_add (&vam->json_tree);
17745
17746   vat_json_init_object (node);
17747   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17748   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17749   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17750   vat_json_object_add_uint (node, "path_count", count);
17751   fp = mp->mr_route.mr_paths;
17752   for (i = 0; i < count; i++)
17753     {
17754       vl_api_mpls_fib_path_json_print (node, fp);
17755       fp++;
17756     }
17757 }
17758
17759 static int
17760 api_mpls_route_dump (vat_main_t * vam)
17761 {
17762   unformat_input_t *input = vam->input;
17763   vl_api_mpls_route_dump_t *mp;
17764   vl_api_control_ping_t *mp_ping;
17765   u32 table_id;
17766   int ret;
17767
17768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17769     {
17770       if (unformat (input, "table_id %d", &table_id))
17771         ;
17772       else
17773         break;
17774     }
17775   if (table_id == ~0)
17776     {
17777       errmsg ("missing table id");
17778       return -99;
17779     }
17780
17781   M (MPLS_ROUTE_DUMP, mp);
17782
17783   mp->table.mt_table_id = ntohl (table_id);
17784   S (mp);
17785
17786   /* Use a control ping for synchronization */
17787   MPING (CONTROL_PING, mp_ping);
17788   S (mp_ping);
17789
17790   W (ret);
17791   return ret;
17792 }
17793
17794 #define vl_api_ip_table_details_t_endian vl_noop_handler
17795 #define vl_api_ip_table_details_t_print vl_noop_handler
17796
17797 static void
17798 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17799 {
17800   vat_main_t *vam = &vat_main;
17801
17802   print (vam->ofp,
17803          "%s; table-id %d, prefix %U/%d",
17804          mp->table.name, ntohl (mp->table.table_id));
17805 }
17806
17807
17808 static void vl_api_ip_table_details_t_handler_json
17809   (vl_api_ip_table_details_t * mp)
17810 {
17811   vat_main_t *vam = &vat_main;
17812   vat_json_node_t *node = NULL;
17813
17814   if (VAT_JSON_ARRAY != vam->json_tree.type)
17815     {
17816       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17817       vat_json_init_array (&vam->json_tree);
17818     }
17819   node = vat_json_array_add (&vam->json_tree);
17820
17821   vat_json_init_object (node);
17822   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17823 }
17824
17825 static int
17826 api_ip_table_dump (vat_main_t * vam)
17827 {
17828   vl_api_ip_table_dump_t *mp;
17829   vl_api_control_ping_t *mp_ping;
17830   int ret;
17831
17832   M (IP_TABLE_DUMP, mp);
17833   S (mp);
17834
17835   /* Use a control ping for synchronization */
17836   MPING (CONTROL_PING, mp_ping);
17837   S (mp_ping);
17838
17839   W (ret);
17840   return ret;
17841 }
17842
17843 static int
17844 api_ip_mtable_dump (vat_main_t * vam)
17845 {
17846   vl_api_ip_mtable_dump_t *mp;
17847   vl_api_control_ping_t *mp_ping;
17848   int ret;
17849
17850   M (IP_MTABLE_DUMP, mp);
17851   S (mp);
17852
17853   /* Use a control ping for synchronization */
17854   MPING (CONTROL_PING, mp_ping);
17855   S (mp_ping);
17856
17857   W (ret);
17858   return ret;
17859 }
17860
17861 static int
17862 api_ip_mroute_dump (vat_main_t * vam)
17863 {
17864   unformat_input_t *input = vam->input;
17865   vl_api_control_ping_t *mp_ping;
17866   vl_api_ip_mroute_dump_t *mp;
17867   int ret, is_ip6;
17868   u32 table_id;
17869
17870   is_ip6 = 0;
17871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17872     {
17873       if (unformat (input, "table_id %d", &table_id))
17874         ;
17875       else if (unformat (input, "ip6"))
17876         is_ip6 = 1;
17877       else if (unformat (input, "ip4"))
17878         is_ip6 = 0;
17879       else
17880         break;
17881     }
17882   if (table_id == ~0)
17883     {
17884       errmsg ("missing table id");
17885       return -99;
17886     }
17887
17888   M (IP_MROUTE_DUMP, mp);
17889   mp->table.table_id = table_id;
17890   mp->table.is_ip6 = is_ip6;
17891   S (mp);
17892
17893   /* Use a control ping for synchronization */
17894   MPING (CONTROL_PING, mp_ping);
17895   S (mp_ping);
17896
17897   W (ret);
17898   return ret;
17899 }
17900
17901 #define vl_api_ip_route_details_t_endian vl_noop_handler
17902 #define vl_api_ip_route_details_t_print vl_noop_handler
17903
17904 static void
17905 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17906 {
17907   vat_main_t *vam = &vat_main;
17908   u8 count = mp->route.n_paths;
17909   vl_api_fib_path_t *fp;
17910   int i;
17911
17912   print (vam->ofp,
17913          "table-id %d, prefix %U/%d",
17914          ntohl (mp->route.table_id),
17915          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17916   for (i = 0; i < count; i++)
17917     {
17918       fp = &mp->route.paths[i];
17919
17920       vl_api_fib_path_print (vam, fp);
17921       fp++;
17922     }
17923 }
17924
17925 static void vl_api_ip_route_details_t_handler_json
17926   (vl_api_ip_route_details_t * mp)
17927 {
17928   vat_main_t *vam = &vat_main;
17929   u8 count = mp->route.n_paths;
17930   vat_json_node_t *node = NULL;
17931   struct in_addr ip4;
17932   struct in6_addr ip6;
17933   vl_api_fib_path_t *fp;
17934   int i;
17935
17936   if (VAT_JSON_ARRAY != vam->json_tree.type)
17937     {
17938       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17939       vat_json_init_array (&vam->json_tree);
17940     }
17941   node = vat_json_array_add (&vam->json_tree);
17942
17943   vat_json_init_object (node);
17944   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17945   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17946     {
17947       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17948       vat_json_object_add_ip6 (node, "prefix", ip6);
17949     }
17950   else
17951     {
17952       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17953       vat_json_object_add_ip4 (node, "prefix", ip4);
17954     }
17955   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17956   vat_json_object_add_uint (node, "path_count", count);
17957   for (i = 0; i < count; i++)
17958     {
17959       fp = &mp->route.paths[i];
17960       vl_api_mpls_fib_path_json_print (node, fp);
17961     }
17962 }
17963
17964 static int
17965 api_ip_route_dump (vat_main_t * vam)
17966 {
17967   unformat_input_t *input = vam->input;
17968   vl_api_ip_route_dump_t *mp;
17969   vl_api_control_ping_t *mp_ping;
17970   u32 table_id;
17971   u8 is_ip6;
17972   int ret;
17973
17974   is_ip6 = 0;
17975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17976     {
17977       if (unformat (input, "table_id %d", &table_id))
17978         ;
17979       else if (unformat (input, "ip6"))
17980         is_ip6 = 1;
17981       else if (unformat (input, "ip4"))
17982         is_ip6 = 0;
17983       else
17984         break;
17985     }
17986   if (table_id == ~0)
17987     {
17988       errmsg ("missing table id");
17989       return -99;
17990     }
17991
17992   M (IP_ROUTE_DUMP, mp);
17993
17994   mp->table.table_id = table_id;
17995   mp->table.is_ip6 = is_ip6;
17996
17997   S (mp);
17998
17999   /* Use a control ping for synchronization */
18000   MPING (CONTROL_PING, mp_ping);
18001   S (mp_ping);
18002
18003   W (ret);
18004   return ret;
18005 }
18006
18007 int
18008 api_classify_table_ids (vat_main_t * vam)
18009 {
18010   vl_api_classify_table_ids_t *mp;
18011   int ret;
18012
18013   /* Construct the API message */
18014   M (CLASSIFY_TABLE_IDS, mp);
18015   mp->context = 0;
18016
18017   S (mp);
18018   W (ret);
18019   return ret;
18020 }
18021
18022 int
18023 api_classify_table_by_interface (vat_main_t * vam)
18024 {
18025   unformat_input_t *input = vam->input;
18026   vl_api_classify_table_by_interface_t *mp;
18027
18028   u32 sw_if_index = ~0;
18029   int ret;
18030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18031     {
18032       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18033         ;
18034       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18035         ;
18036       else
18037         break;
18038     }
18039   if (sw_if_index == ~0)
18040     {
18041       errmsg ("missing interface name or sw_if_index");
18042       return -99;
18043     }
18044
18045   /* Construct the API message */
18046   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18047   mp->context = 0;
18048   mp->sw_if_index = ntohl (sw_if_index);
18049
18050   S (mp);
18051   W (ret);
18052   return ret;
18053 }
18054
18055 int
18056 api_classify_table_info (vat_main_t * vam)
18057 {
18058   unformat_input_t *input = vam->input;
18059   vl_api_classify_table_info_t *mp;
18060
18061   u32 table_id = ~0;
18062   int ret;
18063   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18064     {
18065       if (unformat (input, "table_id %d", &table_id))
18066         ;
18067       else
18068         break;
18069     }
18070   if (table_id == ~0)
18071     {
18072       errmsg ("missing table id");
18073       return -99;
18074     }
18075
18076   /* Construct the API message */
18077   M (CLASSIFY_TABLE_INFO, mp);
18078   mp->context = 0;
18079   mp->table_id = ntohl (table_id);
18080
18081   S (mp);
18082   W (ret);
18083   return ret;
18084 }
18085
18086 int
18087 api_classify_session_dump (vat_main_t * vam)
18088 {
18089   unformat_input_t *input = vam->input;
18090   vl_api_classify_session_dump_t *mp;
18091   vl_api_control_ping_t *mp_ping;
18092
18093   u32 table_id = ~0;
18094   int ret;
18095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18096     {
18097       if (unformat (input, "table_id %d", &table_id))
18098         ;
18099       else
18100         break;
18101     }
18102   if (table_id == ~0)
18103     {
18104       errmsg ("missing table id");
18105       return -99;
18106     }
18107
18108   /* Construct the API message */
18109   M (CLASSIFY_SESSION_DUMP, mp);
18110   mp->context = 0;
18111   mp->table_id = ntohl (table_id);
18112   S (mp);
18113
18114   /* Use a control ping for synchronization */
18115   MPING (CONTROL_PING, mp_ping);
18116   S (mp_ping);
18117
18118   W (ret);
18119   return ret;
18120 }
18121
18122 static void
18123 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18124 {
18125   vat_main_t *vam = &vat_main;
18126
18127   print (vam->ofp, "collector_address %U, collector_port %d, "
18128          "src_address %U, vrf_id %d, path_mtu %u, "
18129          "template_interval %u, udp_checksum %d",
18130          format_ip4_address, mp->collector_address,
18131          ntohs (mp->collector_port),
18132          format_ip4_address, mp->src_address,
18133          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18134          ntohl (mp->template_interval), mp->udp_checksum);
18135
18136   vam->retval = 0;
18137   vam->result_ready = 1;
18138 }
18139
18140 static void
18141   vl_api_ipfix_exporter_details_t_handler_json
18142   (vl_api_ipfix_exporter_details_t * mp)
18143 {
18144   vat_main_t *vam = &vat_main;
18145   vat_json_node_t node;
18146   struct in_addr collector_address;
18147   struct in_addr src_address;
18148
18149   vat_json_init_object (&node);
18150   clib_memcpy (&collector_address, &mp->collector_address,
18151                sizeof (collector_address));
18152   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18153   vat_json_object_add_uint (&node, "collector_port",
18154                             ntohs (mp->collector_port));
18155   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18156   vat_json_object_add_ip4 (&node, "src_address", src_address);
18157   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18158   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18159   vat_json_object_add_uint (&node, "template_interval",
18160                             ntohl (mp->template_interval));
18161   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18162
18163   vat_json_print (vam->ofp, &node);
18164   vat_json_free (&node);
18165   vam->retval = 0;
18166   vam->result_ready = 1;
18167 }
18168
18169 int
18170 api_ipfix_exporter_dump (vat_main_t * vam)
18171 {
18172   vl_api_ipfix_exporter_dump_t *mp;
18173   int ret;
18174
18175   /* Construct the API message */
18176   M (IPFIX_EXPORTER_DUMP, mp);
18177   mp->context = 0;
18178
18179   S (mp);
18180   W (ret);
18181   return ret;
18182 }
18183
18184 static int
18185 api_ipfix_classify_stream_dump (vat_main_t * vam)
18186 {
18187   vl_api_ipfix_classify_stream_dump_t *mp;
18188   int ret;
18189
18190   /* Construct the API message */
18191   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18192   mp->context = 0;
18193
18194   S (mp);
18195   W (ret);
18196   return ret;
18197   /* NOTREACHED */
18198   return 0;
18199 }
18200
18201 static void
18202   vl_api_ipfix_classify_stream_details_t_handler
18203   (vl_api_ipfix_classify_stream_details_t * mp)
18204 {
18205   vat_main_t *vam = &vat_main;
18206   print (vam->ofp, "domain_id %d, src_port %d",
18207          ntohl (mp->domain_id), ntohs (mp->src_port));
18208   vam->retval = 0;
18209   vam->result_ready = 1;
18210 }
18211
18212 static void
18213   vl_api_ipfix_classify_stream_details_t_handler_json
18214   (vl_api_ipfix_classify_stream_details_t * mp)
18215 {
18216   vat_main_t *vam = &vat_main;
18217   vat_json_node_t node;
18218
18219   vat_json_init_object (&node);
18220   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18221   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18222
18223   vat_json_print (vam->ofp, &node);
18224   vat_json_free (&node);
18225   vam->retval = 0;
18226   vam->result_ready = 1;
18227 }
18228
18229 static int
18230 api_ipfix_classify_table_dump (vat_main_t * vam)
18231 {
18232   vl_api_ipfix_classify_table_dump_t *mp;
18233   vl_api_control_ping_t *mp_ping;
18234   int ret;
18235
18236   if (!vam->json_output)
18237     {
18238       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18239              "transport_protocol");
18240     }
18241
18242   /* Construct the API message */
18243   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18244
18245   /* send it... */
18246   S (mp);
18247
18248   /* Use a control ping for synchronization */
18249   MPING (CONTROL_PING, mp_ping);
18250   S (mp_ping);
18251
18252   W (ret);
18253   return ret;
18254 }
18255
18256 static void
18257   vl_api_ipfix_classify_table_details_t_handler
18258   (vl_api_ipfix_classify_table_details_t * mp)
18259 {
18260   vat_main_t *vam = &vat_main;
18261   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18262          mp->transport_protocol);
18263 }
18264
18265 static void
18266   vl_api_ipfix_classify_table_details_t_handler_json
18267   (vl_api_ipfix_classify_table_details_t * mp)
18268 {
18269   vat_json_node_t *node = NULL;
18270   vat_main_t *vam = &vat_main;
18271
18272   if (VAT_JSON_ARRAY != vam->json_tree.type)
18273     {
18274       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18275       vat_json_init_array (&vam->json_tree);
18276     }
18277
18278   node = vat_json_array_add (&vam->json_tree);
18279   vat_json_init_object (node);
18280
18281   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18282   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18283   vat_json_object_add_uint (node, "transport_protocol",
18284                             mp->transport_protocol);
18285 }
18286
18287 static int
18288 api_sw_interface_span_enable_disable (vat_main_t * vam)
18289 {
18290   unformat_input_t *i = vam->input;
18291   vl_api_sw_interface_span_enable_disable_t *mp;
18292   u32 src_sw_if_index = ~0;
18293   u32 dst_sw_if_index = ~0;
18294   u8 state = 3;
18295   int ret;
18296   u8 is_l2 = 0;
18297
18298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18299     {
18300       if (unformat
18301           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18302         ;
18303       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18304         ;
18305       else
18306         if (unformat
18307             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18308         ;
18309       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18310         ;
18311       else if (unformat (i, "disable"))
18312         state = 0;
18313       else if (unformat (i, "rx"))
18314         state = 1;
18315       else if (unformat (i, "tx"))
18316         state = 2;
18317       else if (unformat (i, "both"))
18318         state = 3;
18319       else if (unformat (i, "l2"))
18320         is_l2 = 1;
18321       else
18322         break;
18323     }
18324
18325   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18326
18327   mp->sw_if_index_from = htonl (src_sw_if_index);
18328   mp->sw_if_index_to = htonl (dst_sw_if_index);
18329   mp->state = state;
18330   mp->is_l2 = is_l2;
18331
18332   S (mp);
18333   W (ret);
18334   return ret;
18335 }
18336
18337 static void
18338 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18339                                             * mp)
18340 {
18341   vat_main_t *vam = &vat_main;
18342   u8 *sw_if_from_name = 0;
18343   u8 *sw_if_to_name = 0;
18344   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18345   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18346   char *states[] = { "none", "rx", "tx", "both" };
18347   hash_pair_t *p;
18348
18349   /* *INDENT-OFF* */
18350   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18351   ({
18352     if ((u32) p->value[0] == sw_if_index_from)
18353       {
18354         sw_if_from_name = (u8 *)(p->key);
18355         if (sw_if_to_name)
18356           break;
18357       }
18358     if ((u32) p->value[0] == sw_if_index_to)
18359       {
18360         sw_if_to_name = (u8 *)(p->key);
18361         if (sw_if_from_name)
18362           break;
18363       }
18364   }));
18365   /* *INDENT-ON* */
18366   print (vam->ofp, "%20s => %20s (%s) %s",
18367          sw_if_from_name, sw_if_to_name, states[mp->state],
18368          mp->is_l2 ? "l2" : "device");
18369 }
18370
18371 static void
18372   vl_api_sw_interface_span_details_t_handler_json
18373   (vl_api_sw_interface_span_details_t * mp)
18374 {
18375   vat_main_t *vam = &vat_main;
18376   vat_json_node_t *node = NULL;
18377   u8 *sw_if_from_name = 0;
18378   u8 *sw_if_to_name = 0;
18379   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18380   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18381   hash_pair_t *p;
18382
18383   /* *INDENT-OFF* */
18384   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18385   ({
18386     if ((u32) p->value[0] == sw_if_index_from)
18387       {
18388         sw_if_from_name = (u8 *)(p->key);
18389         if (sw_if_to_name)
18390           break;
18391       }
18392     if ((u32) p->value[0] == sw_if_index_to)
18393       {
18394         sw_if_to_name = (u8 *)(p->key);
18395         if (sw_if_from_name)
18396           break;
18397       }
18398   }));
18399   /* *INDENT-ON* */
18400
18401   if (VAT_JSON_ARRAY != vam->json_tree.type)
18402     {
18403       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18404       vat_json_init_array (&vam->json_tree);
18405     }
18406   node = vat_json_array_add (&vam->json_tree);
18407
18408   vat_json_init_object (node);
18409   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18410   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18411   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18412   if (0 != sw_if_to_name)
18413     {
18414       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18415     }
18416   vat_json_object_add_uint (node, "state", mp->state);
18417   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18418 }
18419
18420 static int
18421 api_sw_interface_span_dump (vat_main_t * vam)
18422 {
18423   unformat_input_t *input = vam->input;
18424   vl_api_sw_interface_span_dump_t *mp;
18425   vl_api_control_ping_t *mp_ping;
18426   u8 is_l2 = 0;
18427   int ret;
18428
18429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18430     {
18431       if (unformat (input, "l2"))
18432         is_l2 = 1;
18433       else
18434         break;
18435     }
18436
18437   M (SW_INTERFACE_SPAN_DUMP, mp);
18438   mp->is_l2 = is_l2;
18439   S (mp);
18440
18441   /* Use a control ping for synchronization */
18442   MPING (CONTROL_PING, mp_ping);
18443   S (mp_ping);
18444
18445   W (ret);
18446   return ret;
18447 }
18448
18449 int
18450 api_pg_create_interface (vat_main_t * vam)
18451 {
18452   unformat_input_t *input = vam->input;
18453   vl_api_pg_create_interface_t *mp;
18454
18455   u32 if_id = ~0, gso_size = 0;
18456   u8 gso_enabled = 0;
18457   int ret;
18458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18459     {
18460       if (unformat (input, "if_id %d", &if_id))
18461         ;
18462       else if (unformat (input, "gso-enabled"))
18463         {
18464           gso_enabled = 1;
18465           if (unformat (input, "gso-size %u", &gso_size))
18466             ;
18467           else
18468             {
18469               errmsg ("missing gso-size");
18470               return -99;
18471             }
18472         }
18473       else
18474         break;
18475     }
18476   if (if_id == ~0)
18477     {
18478       errmsg ("missing pg interface index");
18479       return -99;
18480     }
18481
18482   /* Construct the API message */
18483   M (PG_CREATE_INTERFACE, mp);
18484   mp->context = 0;
18485   mp->interface_id = ntohl (if_id);
18486   mp->gso_enabled = gso_enabled;
18487
18488   S (mp);
18489   W (ret);
18490   return ret;
18491 }
18492
18493 int
18494 api_pg_capture (vat_main_t * vam)
18495 {
18496   unformat_input_t *input = vam->input;
18497   vl_api_pg_capture_t *mp;
18498
18499   u32 if_id = ~0;
18500   u8 enable = 1;
18501   u32 count = 1;
18502   u8 pcap_file_set = 0;
18503   u8 *pcap_file = 0;
18504   int ret;
18505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18506     {
18507       if (unformat (input, "if_id %d", &if_id))
18508         ;
18509       else if (unformat (input, "pcap %s", &pcap_file))
18510         pcap_file_set = 1;
18511       else if (unformat (input, "count %d", &count))
18512         ;
18513       else if (unformat (input, "disable"))
18514         enable = 0;
18515       else
18516         break;
18517     }
18518   if (if_id == ~0)
18519     {
18520       errmsg ("missing pg interface index");
18521       return -99;
18522     }
18523   if (pcap_file_set > 0)
18524     {
18525       if (vec_len (pcap_file) > 255)
18526         {
18527           errmsg ("pcap file name is too long");
18528           return -99;
18529         }
18530     }
18531
18532   /* Construct the API message */
18533   M (PG_CAPTURE, mp);
18534   mp->context = 0;
18535   mp->interface_id = ntohl (if_id);
18536   mp->is_enabled = enable;
18537   mp->count = ntohl (count);
18538   if (pcap_file_set != 0)
18539     {
18540       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18541     }
18542   vec_free (pcap_file);
18543
18544   S (mp);
18545   W (ret);
18546   return ret;
18547 }
18548
18549 int
18550 api_pg_enable_disable (vat_main_t * vam)
18551 {
18552   unformat_input_t *input = vam->input;
18553   vl_api_pg_enable_disable_t *mp;
18554
18555   u8 enable = 1;
18556   u8 stream_name_set = 0;
18557   u8 *stream_name = 0;
18558   int ret;
18559   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18560     {
18561       if (unformat (input, "stream %s", &stream_name))
18562         stream_name_set = 1;
18563       else if (unformat (input, "disable"))
18564         enable = 0;
18565       else
18566         break;
18567     }
18568
18569   if (stream_name_set > 0)
18570     {
18571       if (vec_len (stream_name) > 255)
18572         {
18573           errmsg ("stream name too long");
18574           return -99;
18575         }
18576     }
18577
18578   /* Construct the API message */
18579   M (PG_ENABLE_DISABLE, mp);
18580   mp->context = 0;
18581   mp->is_enabled = enable;
18582   if (stream_name_set != 0)
18583     {
18584       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18585     }
18586   vec_free (stream_name);
18587
18588   S (mp);
18589   W (ret);
18590   return ret;
18591 }
18592
18593 int
18594 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18595 {
18596   unformat_input_t *input = vam->input;
18597   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18598
18599   u16 *low_ports = 0;
18600   u16 *high_ports = 0;
18601   u16 this_low;
18602   u16 this_hi;
18603   vl_api_prefix_t prefix;
18604   u32 tmp, tmp2;
18605   u8 prefix_set = 0;
18606   u32 vrf_id = ~0;
18607   u8 is_add = 1;
18608   int ret;
18609
18610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18611     {
18612       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18613         prefix_set = 1;
18614       else if (unformat (input, "vrf %d", &vrf_id))
18615         ;
18616       else if (unformat (input, "del"))
18617         is_add = 0;
18618       else if (unformat (input, "port %d", &tmp))
18619         {
18620           if (tmp == 0 || tmp > 65535)
18621             {
18622               errmsg ("port %d out of range", tmp);
18623               return -99;
18624             }
18625           this_low = tmp;
18626           this_hi = this_low + 1;
18627           vec_add1 (low_ports, this_low);
18628           vec_add1 (high_ports, this_hi);
18629         }
18630       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18631         {
18632           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18633             {
18634               errmsg ("incorrect range parameters");
18635               return -99;
18636             }
18637           this_low = tmp;
18638           /* Note: in debug CLI +1 is added to high before
18639              passing to real fn that does "the work"
18640              (ip_source_and_port_range_check_add_del).
18641              This fn is a wrapper around the binary API fn a
18642              control plane will call, which expects this increment
18643              to have occurred. Hence letting the binary API control
18644              plane fn do the increment for consistency between VAT
18645              and other control planes.
18646            */
18647           this_hi = tmp2;
18648           vec_add1 (low_ports, this_low);
18649           vec_add1 (high_ports, this_hi);
18650         }
18651       else
18652         break;
18653     }
18654
18655   if (prefix_set == 0)
18656     {
18657       errmsg ("<address>/<mask> not specified");
18658       return -99;
18659     }
18660
18661   if (vrf_id == ~0)
18662     {
18663       errmsg ("VRF ID required, not specified");
18664       return -99;
18665     }
18666
18667   if (vrf_id == 0)
18668     {
18669       errmsg
18670         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18671       return -99;
18672     }
18673
18674   if (vec_len (low_ports) == 0)
18675     {
18676       errmsg ("At least one port or port range required");
18677       return -99;
18678     }
18679
18680   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18681
18682   mp->is_add = is_add;
18683
18684   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18685
18686   mp->number_of_ranges = vec_len (low_ports);
18687
18688   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18689   vec_free (low_ports);
18690
18691   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18692   vec_free (high_ports);
18693
18694   mp->vrf_id = ntohl (vrf_id);
18695
18696   S (mp);
18697   W (ret);
18698   return ret;
18699 }
18700
18701 int
18702 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18703 {
18704   unformat_input_t *input = vam->input;
18705   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18706   u32 sw_if_index = ~0;
18707   int vrf_set = 0;
18708   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18709   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18710   u8 is_add = 1;
18711   int ret;
18712
18713   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18714     {
18715       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18716         ;
18717       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18718         ;
18719       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18720         vrf_set = 1;
18721       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18722         vrf_set = 1;
18723       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18724         vrf_set = 1;
18725       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18726         vrf_set = 1;
18727       else if (unformat (input, "del"))
18728         is_add = 0;
18729       else
18730         break;
18731     }
18732
18733   if (sw_if_index == ~0)
18734     {
18735       errmsg ("Interface required but not specified");
18736       return -99;
18737     }
18738
18739   if (vrf_set == 0)
18740     {
18741       errmsg ("VRF ID required but not specified");
18742       return -99;
18743     }
18744
18745   if (tcp_out_vrf_id == 0
18746       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18747     {
18748       errmsg
18749         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18750       return -99;
18751     }
18752
18753   /* Construct the API message */
18754   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18755
18756   mp->sw_if_index = ntohl (sw_if_index);
18757   mp->is_add = is_add;
18758   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18759   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18760   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18761   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18762
18763   /* send it... */
18764   S (mp);
18765
18766   /* Wait for a reply... */
18767   W (ret);
18768   return ret;
18769 }
18770
18771 static int
18772 api_set_punt (vat_main_t * vam)
18773 {
18774   unformat_input_t *i = vam->input;
18775   vl_api_address_family_t af;
18776   vl_api_set_punt_t *mp;
18777   u32 protocol = ~0;
18778   u32 port = ~0;
18779   int is_add = 1;
18780   int ret;
18781
18782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18783     {
18784       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18785         ;
18786       else if (unformat (i, "protocol %d", &protocol))
18787         ;
18788       else if (unformat (i, "port %d", &port))
18789         ;
18790       else if (unformat (i, "del"))
18791         is_add = 0;
18792       else
18793         {
18794           clib_warning ("parse error '%U'", format_unformat_error, i);
18795           return -99;
18796         }
18797     }
18798
18799   M (SET_PUNT, mp);
18800
18801   mp->is_add = (u8) is_add;
18802   mp->punt.type = PUNT_API_TYPE_L4;
18803   mp->punt.punt.l4.af = af;
18804   mp->punt.punt.l4.protocol = (u8) protocol;
18805   mp->punt.punt.l4.port = htons ((u16) port);
18806
18807   S (mp);
18808   W (ret);
18809   return ret;
18810 }
18811
18812 static int
18813 api_delete_subif (vat_main_t * vam)
18814 {
18815   unformat_input_t *i = vam->input;
18816   vl_api_delete_subif_t *mp;
18817   u32 sw_if_index = ~0;
18818   int ret;
18819
18820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18821     {
18822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18823         ;
18824       if (unformat (i, "sw_if_index %d", &sw_if_index))
18825         ;
18826       else
18827         break;
18828     }
18829
18830   if (sw_if_index == ~0)
18831     {
18832       errmsg ("missing sw_if_index");
18833       return -99;
18834     }
18835
18836   /* Construct the API message */
18837   M (DELETE_SUBIF, mp);
18838   mp->sw_if_index = ntohl (sw_if_index);
18839
18840   S (mp);
18841   W (ret);
18842   return ret;
18843 }
18844
18845 #define foreach_pbb_vtr_op      \
18846 _("disable",  L2_VTR_DISABLED)  \
18847 _("pop",  L2_VTR_POP_2)         \
18848 _("push",  L2_VTR_PUSH_2)
18849
18850 static int
18851 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18852 {
18853   unformat_input_t *i = vam->input;
18854   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18855   u32 sw_if_index = ~0, vtr_op = ~0;
18856   u16 outer_tag = ~0;
18857   u8 dmac[6], smac[6];
18858   u8 dmac_set = 0, smac_set = 0;
18859   u16 vlanid = 0;
18860   u32 sid = ~0;
18861   u32 tmp;
18862   int ret;
18863
18864   /* Shut up coverity */
18865   clib_memset (dmac, 0, sizeof (dmac));
18866   clib_memset (smac, 0, sizeof (smac));
18867
18868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18869     {
18870       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18871         ;
18872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18873         ;
18874       else if (unformat (i, "vtr_op %d", &vtr_op))
18875         ;
18876 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18877       foreach_pbb_vtr_op
18878 #undef _
18879         else if (unformat (i, "translate_pbb_stag"))
18880         {
18881           if (unformat (i, "%d", &tmp))
18882             {
18883               vtr_op = L2_VTR_TRANSLATE_2_1;
18884               outer_tag = tmp;
18885             }
18886           else
18887             {
18888               errmsg
18889                 ("translate_pbb_stag operation requires outer tag definition");
18890               return -99;
18891             }
18892         }
18893       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18894         dmac_set++;
18895       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18896         smac_set++;
18897       else if (unformat (i, "sid %d", &sid))
18898         ;
18899       else if (unformat (i, "vlanid %d", &tmp))
18900         vlanid = tmp;
18901       else
18902         {
18903           clib_warning ("parse error '%U'", format_unformat_error, i);
18904           return -99;
18905         }
18906     }
18907
18908   if ((sw_if_index == ~0) || (vtr_op == ~0))
18909     {
18910       errmsg ("missing sw_if_index or vtr operation");
18911       return -99;
18912     }
18913   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18914       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18915     {
18916       errmsg
18917         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18918       return -99;
18919     }
18920
18921   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18922   mp->sw_if_index = ntohl (sw_if_index);
18923   mp->vtr_op = ntohl (vtr_op);
18924   mp->outer_tag = ntohs (outer_tag);
18925   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18926   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18927   mp->b_vlanid = ntohs (vlanid);
18928   mp->i_sid = ntohl (sid);
18929
18930   S (mp);
18931   W (ret);
18932   return ret;
18933 }
18934
18935 static int
18936 api_flow_classify_set_interface (vat_main_t * vam)
18937 {
18938   unformat_input_t *i = vam->input;
18939   vl_api_flow_classify_set_interface_t *mp;
18940   u32 sw_if_index;
18941   int sw_if_index_set;
18942   u32 ip4_table_index = ~0;
18943   u32 ip6_table_index = ~0;
18944   u8 is_add = 1;
18945   int ret;
18946
18947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18948     {
18949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18950         sw_if_index_set = 1;
18951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18952         sw_if_index_set = 1;
18953       else if (unformat (i, "del"))
18954         is_add = 0;
18955       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18956         ;
18957       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18958         ;
18959       else
18960         {
18961           clib_warning ("parse error '%U'", format_unformat_error, i);
18962           return -99;
18963         }
18964     }
18965
18966   if (sw_if_index_set == 0)
18967     {
18968       errmsg ("missing interface name or sw_if_index");
18969       return -99;
18970     }
18971
18972   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18973
18974   mp->sw_if_index = ntohl (sw_if_index);
18975   mp->ip4_table_index = ntohl (ip4_table_index);
18976   mp->ip6_table_index = ntohl (ip6_table_index);
18977   mp->is_add = is_add;
18978
18979   S (mp);
18980   W (ret);
18981   return ret;
18982 }
18983
18984 static int
18985 api_flow_classify_dump (vat_main_t * vam)
18986 {
18987   unformat_input_t *i = vam->input;
18988   vl_api_flow_classify_dump_t *mp;
18989   vl_api_control_ping_t *mp_ping;
18990   u8 type = FLOW_CLASSIFY_N_TABLES;
18991   int ret;
18992
18993   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18994     ;
18995   else
18996     {
18997       errmsg ("classify table type must be specified");
18998       return -99;
18999     }
19000
19001   if (!vam->json_output)
19002     {
19003       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19004     }
19005
19006   M (FLOW_CLASSIFY_DUMP, mp);
19007   mp->type = type;
19008   /* send it... */
19009   S (mp);
19010
19011   /* Use a control ping for synchronization */
19012   MPING (CONTROL_PING, mp_ping);
19013   S (mp_ping);
19014
19015   /* Wait for a reply... */
19016   W (ret);
19017   return ret;
19018 }
19019
19020 static int
19021 api_feature_enable_disable (vat_main_t * vam)
19022 {
19023   unformat_input_t *i = vam->input;
19024   vl_api_feature_enable_disable_t *mp;
19025   u8 *arc_name = 0;
19026   u8 *feature_name = 0;
19027   u32 sw_if_index = ~0;
19028   u8 enable = 1;
19029   int ret;
19030
19031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19032     {
19033       if (unformat (i, "arc_name %s", &arc_name))
19034         ;
19035       else if (unformat (i, "feature_name %s", &feature_name))
19036         ;
19037       else
19038         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19039         ;
19040       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19041         ;
19042       else if (unformat (i, "disable"))
19043         enable = 0;
19044       else
19045         break;
19046     }
19047
19048   if (arc_name == 0)
19049     {
19050       errmsg ("missing arc name");
19051       return -99;
19052     }
19053   if (vec_len (arc_name) > 63)
19054     {
19055       errmsg ("arc name too long");
19056     }
19057
19058   if (feature_name == 0)
19059     {
19060       errmsg ("missing feature name");
19061       return -99;
19062     }
19063   if (vec_len (feature_name) > 63)
19064     {
19065       errmsg ("feature name too long");
19066     }
19067
19068   if (sw_if_index == ~0)
19069     {
19070       errmsg ("missing interface name or sw_if_index");
19071       return -99;
19072     }
19073
19074   /* Construct the API message */
19075   M (FEATURE_ENABLE_DISABLE, mp);
19076   mp->sw_if_index = ntohl (sw_if_index);
19077   mp->enable = enable;
19078   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19079   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19080   vec_free (arc_name);
19081   vec_free (feature_name);
19082
19083   S (mp);
19084   W (ret);
19085   return ret;
19086 }
19087
19088 static int
19089 api_feature_gso_enable_disable (vat_main_t * vam)
19090 {
19091   unformat_input_t *i = vam->input;
19092   vl_api_feature_gso_enable_disable_t *mp;
19093   u32 sw_if_index = ~0;
19094   u8 enable = 1;
19095   int ret;
19096
19097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19098     {
19099       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19100         ;
19101       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19102         ;
19103       else if (unformat (i, "enable"))
19104         enable = 1;
19105       else if (unformat (i, "disable"))
19106         enable = 0;
19107       else
19108         break;
19109     }
19110
19111   if (sw_if_index == ~0)
19112     {
19113       errmsg ("missing interface name or sw_if_index");
19114       return -99;
19115     }
19116
19117   /* Construct the API message */
19118   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19119   mp->sw_if_index = ntohl (sw_if_index);
19120   mp->enable_disable = enable;
19121
19122   S (mp);
19123   W (ret);
19124   return ret;
19125 }
19126
19127 static int
19128 api_sw_interface_tag_add_del (vat_main_t * vam)
19129 {
19130   unformat_input_t *i = vam->input;
19131   vl_api_sw_interface_tag_add_del_t *mp;
19132   u32 sw_if_index = ~0;
19133   u8 *tag = 0;
19134   u8 enable = 1;
19135   int ret;
19136
19137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19138     {
19139       if (unformat (i, "tag %s", &tag))
19140         ;
19141       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19142         ;
19143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19144         ;
19145       else if (unformat (i, "del"))
19146         enable = 0;
19147       else
19148         break;
19149     }
19150
19151   if (sw_if_index == ~0)
19152     {
19153       errmsg ("missing interface name or sw_if_index");
19154       return -99;
19155     }
19156
19157   if (enable && (tag == 0))
19158     {
19159       errmsg ("no tag specified");
19160       return -99;
19161     }
19162
19163   /* Construct the API message */
19164   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19165   mp->sw_if_index = ntohl (sw_if_index);
19166   mp->is_add = enable;
19167   if (enable)
19168     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19169   vec_free (tag);
19170
19171   S (mp);
19172   W (ret);
19173   return ret;
19174 }
19175
19176 static int
19177 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19178 {
19179   unformat_input_t *i = vam->input;
19180   vl_api_mac_address_t mac = { 0 };
19181   vl_api_sw_interface_add_del_mac_address_t *mp;
19182   u32 sw_if_index = ~0;
19183   u8 is_add = 1;
19184   u8 mac_set = 0;
19185   int ret;
19186
19187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19188     {
19189       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19190         ;
19191       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19192         ;
19193       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19194         mac_set++;
19195       else if (unformat (i, "del"))
19196         is_add = 0;
19197       else
19198         break;
19199     }
19200
19201   if (sw_if_index == ~0)
19202     {
19203       errmsg ("missing interface name or sw_if_index");
19204       return -99;
19205     }
19206
19207   if (!mac_set)
19208     {
19209       errmsg ("missing MAC address");
19210       return -99;
19211     }
19212
19213   /* Construct the API message */
19214   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19215   mp->sw_if_index = ntohl (sw_if_index);
19216   mp->is_add = is_add;
19217   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19218
19219   S (mp);
19220   W (ret);
19221   return ret;
19222 }
19223
19224 static void vl_api_l2_xconnect_details_t_handler
19225   (vl_api_l2_xconnect_details_t * mp)
19226 {
19227   vat_main_t *vam = &vat_main;
19228
19229   print (vam->ofp, "%15d%15d",
19230          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19231 }
19232
19233 static void vl_api_l2_xconnect_details_t_handler_json
19234   (vl_api_l2_xconnect_details_t * mp)
19235 {
19236   vat_main_t *vam = &vat_main;
19237   vat_json_node_t *node = NULL;
19238
19239   if (VAT_JSON_ARRAY != vam->json_tree.type)
19240     {
19241       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19242       vat_json_init_array (&vam->json_tree);
19243     }
19244   node = vat_json_array_add (&vam->json_tree);
19245
19246   vat_json_init_object (node);
19247   vat_json_object_add_uint (node, "rx_sw_if_index",
19248                             ntohl (mp->rx_sw_if_index));
19249   vat_json_object_add_uint (node, "tx_sw_if_index",
19250                             ntohl (mp->tx_sw_if_index));
19251 }
19252
19253 static int
19254 api_l2_xconnect_dump (vat_main_t * vam)
19255 {
19256   vl_api_l2_xconnect_dump_t *mp;
19257   vl_api_control_ping_t *mp_ping;
19258   int ret;
19259
19260   if (!vam->json_output)
19261     {
19262       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19263     }
19264
19265   M (L2_XCONNECT_DUMP, mp);
19266
19267   S (mp);
19268
19269   /* Use a control ping for synchronization */
19270   MPING (CONTROL_PING, mp_ping);
19271   S (mp_ping);
19272
19273   W (ret);
19274   return ret;
19275 }
19276
19277 static int
19278 api_hw_interface_set_mtu (vat_main_t * vam)
19279 {
19280   unformat_input_t *i = vam->input;
19281   vl_api_hw_interface_set_mtu_t *mp;
19282   u32 sw_if_index = ~0;
19283   u32 mtu = 0;
19284   int ret;
19285
19286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19287     {
19288       if (unformat (i, "mtu %d", &mtu))
19289         ;
19290       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19291         ;
19292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19293         ;
19294       else
19295         break;
19296     }
19297
19298   if (sw_if_index == ~0)
19299     {
19300       errmsg ("missing interface name or sw_if_index");
19301       return -99;
19302     }
19303
19304   if (mtu == 0)
19305     {
19306       errmsg ("no mtu specified");
19307       return -99;
19308     }
19309
19310   /* Construct the API message */
19311   M (HW_INTERFACE_SET_MTU, mp);
19312   mp->sw_if_index = ntohl (sw_if_index);
19313   mp->mtu = ntohs ((u16) mtu);
19314
19315   S (mp);
19316   W (ret);
19317   return ret;
19318 }
19319
19320 static int
19321 api_p2p_ethernet_add (vat_main_t * vam)
19322 {
19323   unformat_input_t *i = vam->input;
19324   vl_api_p2p_ethernet_add_t *mp;
19325   u32 parent_if_index = ~0;
19326   u32 sub_id = ~0;
19327   u8 remote_mac[6];
19328   u8 mac_set = 0;
19329   int ret;
19330
19331   clib_memset (remote_mac, 0, sizeof (remote_mac));
19332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19333     {
19334       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19335         ;
19336       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19337         ;
19338       else
19339         if (unformat
19340             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19341         mac_set++;
19342       else if (unformat (i, "sub_id %d", &sub_id))
19343         ;
19344       else
19345         {
19346           clib_warning ("parse error '%U'", format_unformat_error, i);
19347           return -99;
19348         }
19349     }
19350
19351   if (parent_if_index == ~0)
19352     {
19353       errmsg ("missing interface name or sw_if_index");
19354       return -99;
19355     }
19356   if (mac_set == 0)
19357     {
19358       errmsg ("missing remote mac address");
19359       return -99;
19360     }
19361   if (sub_id == ~0)
19362     {
19363       errmsg ("missing sub-interface id");
19364       return -99;
19365     }
19366
19367   M (P2P_ETHERNET_ADD, mp);
19368   mp->parent_if_index = ntohl (parent_if_index);
19369   mp->subif_id = ntohl (sub_id);
19370   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19371
19372   S (mp);
19373   W (ret);
19374   return ret;
19375 }
19376
19377 static int
19378 api_p2p_ethernet_del (vat_main_t * vam)
19379 {
19380   unformat_input_t *i = vam->input;
19381   vl_api_p2p_ethernet_del_t *mp;
19382   u32 parent_if_index = ~0;
19383   u8 remote_mac[6];
19384   u8 mac_set = 0;
19385   int ret;
19386
19387   clib_memset (remote_mac, 0, sizeof (remote_mac));
19388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19389     {
19390       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19391         ;
19392       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19393         ;
19394       else
19395         if (unformat
19396             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19397         mac_set++;
19398       else
19399         {
19400           clib_warning ("parse error '%U'", format_unformat_error, i);
19401           return -99;
19402         }
19403     }
19404
19405   if (parent_if_index == ~0)
19406     {
19407       errmsg ("missing interface name or sw_if_index");
19408       return -99;
19409     }
19410   if (mac_set == 0)
19411     {
19412       errmsg ("missing remote mac address");
19413       return -99;
19414     }
19415
19416   M (P2P_ETHERNET_DEL, mp);
19417   mp->parent_if_index = ntohl (parent_if_index);
19418   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19419
19420   S (mp);
19421   W (ret);
19422   return ret;
19423 }
19424
19425 static int
19426 api_lldp_config (vat_main_t * vam)
19427 {
19428   unformat_input_t *i = vam->input;
19429   vl_api_lldp_config_t *mp;
19430   int tx_hold = 0;
19431   int tx_interval = 0;
19432   u8 *sys_name = NULL;
19433   int ret;
19434
19435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19436     {
19437       if (unformat (i, "system-name %s", &sys_name))
19438         ;
19439       else if (unformat (i, "tx-hold %d", &tx_hold))
19440         ;
19441       else if (unformat (i, "tx-interval %d", &tx_interval))
19442         ;
19443       else
19444         {
19445           clib_warning ("parse error '%U'", format_unformat_error, i);
19446           return -99;
19447         }
19448     }
19449
19450   vec_add1 (sys_name, 0);
19451
19452   M (LLDP_CONFIG, mp);
19453   mp->tx_hold = htonl (tx_hold);
19454   mp->tx_interval = htonl (tx_interval);
19455   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19456   vec_free (sys_name);
19457
19458   S (mp);
19459   W (ret);
19460   return ret;
19461 }
19462
19463 static int
19464 api_sw_interface_set_lldp (vat_main_t * vam)
19465 {
19466   unformat_input_t *i = vam->input;
19467   vl_api_sw_interface_set_lldp_t *mp;
19468   u32 sw_if_index = ~0;
19469   u32 enable = 1;
19470   u8 *port_desc = NULL, *mgmt_oid = NULL;
19471   ip4_address_t ip4_addr;
19472   ip6_address_t ip6_addr;
19473   int ret;
19474
19475   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19476   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19477
19478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19479     {
19480       if (unformat (i, "disable"))
19481         enable = 0;
19482       else
19483         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19484         ;
19485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19486         ;
19487       else if (unformat (i, "port-desc %s", &port_desc))
19488         ;
19489       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19490         ;
19491       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19492         ;
19493       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19494         ;
19495       else
19496         break;
19497     }
19498
19499   if (sw_if_index == ~0)
19500     {
19501       errmsg ("missing interface name or sw_if_index");
19502       return -99;
19503     }
19504
19505   /* Construct the API message */
19506   vec_add1 (port_desc, 0);
19507   vec_add1 (mgmt_oid, 0);
19508   M (SW_INTERFACE_SET_LLDP, mp);
19509   mp->sw_if_index = ntohl (sw_if_index);
19510   mp->enable = enable;
19511   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19512   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19513   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19514   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19515   vec_free (port_desc);
19516   vec_free (mgmt_oid);
19517
19518   S (mp);
19519   W (ret);
19520   return ret;
19521 }
19522
19523 static int
19524 api_tcp_configure_src_addresses (vat_main_t * vam)
19525 {
19526   vl_api_tcp_configure_src_addresses_t *mp;
19527   unformat_input_t *i = vam->input;
19528   vl_api_address_t first, last;
19529   u8 range_set = 0;
19530   u32 vrf_id = 0;
19531   int ret;
19532
19533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19534     {
19535       if (unformat (i, "%U - %U",
19536                     unformat_vl_api_address, &first,
19537                     unformat_vl_api_address, &last))
19538         {
19539           if (range_set)
19540             {
19541               errmsg ("one range per message (range already set)");
19542               return -99;
19543             }
19544           range_set = 1;
19545         }
19546       else if (unformat (i, "vrf %d", &vrf_id))
19547         ;
19548       else
19549         break;
19550     }
19551
19552   if (range_set == 0)
19553     {
19554       errmsg ("address range not set");
19555       return -99;
19556     }
19557
19558   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19559
19560   mp->vrf_id = ntohl (vrf_id);
19561   clib_memcpy (&mp->first_address, &first, sizeof (first));
19562   clib_memcpy (&mp->last_address, &last, sizeof (last));
19563
19564   S (mp);
19565   W (ret);
19566   return ret;
19567 }
19568
19569 static void vl_api_app_namespace_add_del_reply_t_handler
19570   (vl_api_app_namespace_add_del_reply_t * mp)
19571 {
19572   vat_main_t *vam = &vat_main;
19573   i32 retval = ntohl (mp->retval);
19574   if (vam->async_mode)
19575     {
19576       vam->async_errors += (retval < 0);
19577     }
19578   else
19579     {
19580       vam->retval = retval;
19581       if (retval == 0)
19582         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19583       vam->result_ready = 1;
19584     }
19585 }
19586
19587 static void vl_api_app_namespace_add_del_reply_t_handler_json
19588   (vl_api_app_namespace_add_del_reply_t * mp)
19589 {
19590   vat_main_t *vam = &vat_main;
19591   vat_json_node_t node;
19592
19593   vat_json_init_object (&node);
19594   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19595   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19596
19597   vat_json_print (vam->ofp, &node);
19598   vat_json_free (&node);
19599
19600   vam->retval = ntohl (mp->retval);
19601   vam->result_ready = 1;
19602 }
19603
19604 static int
19605 api_app_namespace_add_del (vat_main_t * vam)
19606 {
19607   vl_api_app_namespace_add_del_t *mp;
19608   unformat_input_t *i = vam->input;
19609   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19610   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19611   u64 secret;
19612   int ret;
19613
19614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19615     {
19616       if (unformat (i, "id %_%v%_", &ns_id))
19617         ;
19618       else if (unformat (i, "secret %lu", &secret))
19619         secret_set = 1;
19620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19621         sw_if_index_set = 1;
19622       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19623         ;
19624       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19625         ;
19626       else
19627         break;
19628     }
19629   if (!ns_id || !secret_set || !sw_if_index_set)
19630     {
19631       errmsg ("namespace id, secret and sw_if_index must be set");
19632       return -99;
19633     }
19634   if (vec_len (ns_id) > 64)
19635     {
19636       errmsg ("namespace id too long");
19637       return -99;
19638     }
19639   M (APP_NAMESPACE_ADD_DEL, mp);
19640
19641   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19642   mp->secret = clib_host_to_net_u64 (secret);
19643   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19644   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19645   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19646   vec_free (ns_id);
19647   S (mp);
19648   W (ret);
19649   return ret;
19650 }
19651
19652 static int
19653 api_sock_init_shm (vat_main_t * vam)
19654 {
19655 #if VPP_API_TEST_BUILTIN == 0
19656   unformat_input_t *i = vam->input;
19657   vl_api_shm_elem_config_t *config = 0;
19658   u64 size = 64 << 20;
19659   int rv;
19660
19661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19662     {
19663       if (unformat (i, "size %U", unformat_memory_size, &size))
19664         ;
19665       else
19666         break;
19667     }
19668
19669   /*
19670    * Canned custom ring allocator config.
19671    * Should probably parse all of this
19672    */
19673   vec_validate (config, 6);
19674   config[0].type = VL_API_VLIB_RING;
19675   config[0].size = 256;
19676   config[0].count = 32;
19677
19678   config[1].type = VL_API_VLIB_RING;
19679   config[1].size = 1024;
19680   config[1].count = 16;
19681
19682   config[2].type = VL_API_VLIB_RING;
19683   config[2].size = 4096;
19684   config[2].count = 2;
19685
19686   config[3].type = VL_API_CLIENT_RING;
19687   config[3].size = 256;
19688   config[3].count = 32;
19689
19690   config[4].type = VL_API_CLIENT_RING;
19691   config[4].size = 1024;
19692   config[4].count = 16;
19693
19694   config[5].type = VL_API_CLIENT_RING;
19695   config[5].size = 4096;
19696   config[5].count = 2;
19697
19698   config[6].type = VL_API_QUEUE;
19699   config[6].count = 128;
19700   config[6].size = sizeof (uword);
19701
19702   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19703   if (!rv)
19704     vam->client_index_invalid = 1;
19705   return rv;
19706 #else
19707   return -99;
19708 #endif
19709 }
19710
19711 static void
19712 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19713 {
19714   vat_main_t *vam = &vat_main;
19715   fib_prefix_t lcl, rmt;
19716
19717   ip_prefix_decode (&mp->lcl, &lcl);
19718   ip_prefix_decode (&mp->rmt, &rmt);
19719
19720   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19721     {
19722       print (vam->ofp,
19723              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19724              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19725              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19726              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19727              &rmt.fp_addr.ip4, rmt.fp_len,
19728              clib_net_to_host_u16 (mp->rmt_port),
19729              clib_net_to_host_u32 (mp->action_index), mp->tag);
19730     }
19731   else
19732     {
19733       print (vam->ofp,
19734              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19735              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19736              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19737              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19738              &rmt.fp_addr.ip6, rmt.fp_len,
19739              clib_net_to_host_u16 (mp->rmt_port),
19740              clib_net_to_host_u32 (mp->action_index), mp->tag);
19741     }
19742 }
19743
19744 static void
19745 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19746                                              mp)
19747 {
19748   vat_main_t *vam = &vat_main;
19749   vat_json_node_t *node = NULL;
19750   struct in6_addr ip6;
19751   struct in_addr ip4;
19752
19753   fib_prefix_t lcl, rmt;
19754
19755   ip_prefix_decode (&mp->lcl, &lcl);
19756   ip_prefix_decode (&mp->rmt, &rmt);
19757
19758   if (VAT_JSON_ARRAY != vam->json_tree.type)
19759     {
19760       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19761       vat_json_init_array (&vam->json_tree);
19762     }
19763   node = vat_json_array_add (&vam->json_tree);
19764   vat_json_init_object (node);
19765
19766   vat_json_object_add_uint (node, "appns_index",
19767                             clib_net_to_host_u32 (mp->appns_index));
19768   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19769   vat_json_object_add_uint (node, "scope", mp->scope);
19770   vat_json_object_add_uint (node, "action_index",
19771                             clib_net_to_host_u32 (mp->action_index));
19772   vat_json_object_add_uint (node, "lcl_port",
19773                             clib_net_to_host_u16 (mp->lcl_port));
19774   vat_json_object_add_uint (node, "rmt_port",
19775                             clib_net_to_host_u16 (mp->rmt_port));
19776   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19777   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19778   vat_json_object_add_string_copy (node, "tag", mp->tag);
19779   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19780     {
19781       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19782       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19783       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19784       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19785     }
19786   else
19787     {
19788       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19789       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19790       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19791       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19792     }
19793 }
19794
19795 static int
19796 api_session_rule_add_del (vat_main_t * vam)
19797 {
19798   vl_api_session_rule_add_del_t *mp;
19799   unformat_input_t *i = vam->input;
19800   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19801   u32 appns_index = 0, scope = 0;
19802   ip4_address_t lcl_ip4, rmt_ip4;
19803   ip6_address_t lcl_ip6, rmt_ip6;
19804   u8 is_ip4 = 1, conn_set = 0;
19805   u8 is_add = 1, *tag = 0;
19806   int ret;
19807   fib_prefix_t lcl, rmt;
19808
19809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19810     {
19811       if (unformat (i, "del"))
19812         is_add = 0;
19813       else if (unformat (i, "add"))
19814         ;
19815       else if (unformat (i, "proto tcp"))
19816         proto = 0;
19817       else if (unformat (i, "proto udp"))
19818         proto = 1;
19819       else if (unformat (i, "appns %d", &appns_index))
19820         ;
19821       else if (unformat (i, "scope %d", &scope))
19822         ;
19823       else if (unformat (i, "tag %_%v%_", &tag))
19824         ;
19825       else
19826         if (unformat
19827             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19828              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19829              &rmt_port))
19830         {
19831           is_ip4 = 1;
19832           conn_set = 1;
19833         }
19834       else
19835         if (unformat
19836             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19837              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19838              &rmt_port))
19839         {
19840           is_ip4 = 0;
19841           conn_set = 1;
19842         }
19843       else if (unformat (i, "action %d", &action))
19844         ;
19845       else
19846         break;
19847     }
19848   if (proto == ~0 || !conn_set || action == ~0)
19849     {
19850       errmsg ("transport proto, connection and action must be set");
19851       return -99;
19852     }
19853
19854   if (scope > 3)
19855     {
19856       errmsg ("scope should be 0-3");
19857       return -99;
19858     }
19859
19860   M (SESSION_RULE_ADD_DEL, mp);
19861
19862   clib_memset (&lcl, 0, sizeof (lcl));
19863   clib_memset (&rmt, 0, sizeof (rmt));
19864   if (is_ip4)
19865     {
19866       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19867       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19868       lcl.fp_len = lcl_plen;
19869       rmt.fp_len = rmt_plen;
19870     }
19871   else
19872     {
19873       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19874       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19875       lcl.fp_len = lcl_plen;
19876       rmt.fp_len = rmt_plen;
19877     }
19878
19879
19880   ip_prefix_encode (&lcl, &mp->lcl);
19881   ip_prefix_encode (&rmt, &mp->rmt);
19882   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19883   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19884   mp->transport_proto =
19885     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19886   mp->action_index = clib_host_to_net_u32 (action);
19887   mp->appns_index = clib_host_to_net_u32 (appns_index);
19888   mp->scope = scope;
19889   mp->is_add = is_add;
19890   if (tag)
19891     {
19892       clib_memcpy (mp->tag, tag, vec_len (tag));
19893       vec_free (tag);
19894     }
19895
19896   S (mp);
19897   W (ret);
19898   return ret;
19899 }
19900
19901 static int
19902 api_session_rules_dump (vat_main_t * vam)
19903 {
19904   vl_api_session_rules_dump_t *mp;
19905   vl_api_control_ping_t *mp_ping;
19906   int ret;
19907
19908   if (!vam->json_output)
19909     {
19910       print (vam->ofp, "%=20s", "Session Rules");
19911     }
19912
19913   M (SESSION_RULES_DUMP, mp);
19914   /* send it... */
19915   S (mp);
19916
19917   /* Use a control ping for synchronization */
19918   MPING (CONTROL_PING, mp_ping);
19919   S (mp_ping);
19920
19921   /* Wait for a reply... */
19922   W (ret);
19923   return ret;
19924 }
19925
19926 static int
19927 api_ip_container_proxy_add_del (vat_main_t * vam)
19928 {
19929   vl_api_ip_container_proxy_add_del_t *mp;
19930   unformat_input_t *i = vam->input;
19931   u32 sw_if_index = ~0;
19932   vl_api_prefix_t pfx = { };
19933   u8 is_add = 1;
19934   int ret;
19935
19936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19937     {
19938       if (unformat (i, "del"))
19939         is_add = 0;
19940       else if (unformat (i, "add"))
19941         ;
19942       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19943         ;
19944       else if (unformat (i, "sw_if_index %u", &sw_if_index))
19945         ;
19946       else
19947         break;
19948     }
19949   if (sw_if_index == ~0 || pfx.len == 0)
19950     {
19951       errmsg ("address and sw_if_index must be set");
19952       return -99;
19953     }
19954
19955   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
19956
19957   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19958   mp->is_add = is_add;
19959   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
19960
19961   S (mp);
19962   W (ret);
19963   return ret;
19964 }
19965
19966 static int
19967 api_qos_record_enable_disable (vat_main_t * vam)
19968 {
19969   unformat_input_t *i = vam->input;
19970   vl_api_qos_record_enable_disable_t *mp;
19971   u32 sw_if_index, qs = 0xff;
19972   u8 sw_if_index_set = 0;
19973   u8 enable = 1;
19974   int ret;
19975
19976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19977     {
19978       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19979         sw_if_index_set = 1;
19980       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19981         sw_if_index_set = 1;
19982       else if (unformat (i, "%U", unformat_qos_source, &qs))
19983         ;
19984       else if (unformat (i, "disable"))
19985         enable = 0;
19986       else
19987         {
19988           clib_warning ("parse error '%U'", format_unformat_error, i);
19989           return -99;
19990         }
19991     }
19992
19993   if (sw_if_index_set == 0)
19994     {
19995       errmsg ("missing interface name or sw_if_index");
19996       return -99;
19997     }
19998   if (qs == 0xff)
19999     {
20000       errmsg ("input location must be specified");
20001       return -99;
20002     }
20003
20004   M (QOS_RECORD_ENABLE_DISABLE, mp);
20005
20006   mp->record.sw_if_index = ntohl (sw_if_index);
20007   mp->record.input_source = qs;
20008   mp->enable = enable;
20009
20010   S (mp);
20011   W (ret);
20012   return ret;
20013 }
20014
20015
20016 static int
20017 q_or_quit (vat_main_t * vam)
20018 {
20019 #if VPP_API_TEST_BUILTIN == 0
20020   longjmp (vam->jump_buf, 1);
20021 #endif
20022   return 0;                     /* not so much */
20023 }
20024
20025 static int
20026 q (vat_main_t * vam)
20027 {
20028   return q_or_quit (vam);
20029 }
20030
20031 static int
20032 quit (vat_main_t * vam)
20033 {
20034   return q_or_quit (vam);
20035 }
20036
20037 static int
20038 comment (vat_main_t * vam)
20039 {
20040   return 0;
20041 }
20042
20043 static int
20044 elog_save (vat_main_t * vam)
20045 {
20046 #if VPP_API_TEST_BUILTIN == 0
20047   elog_main_t *em = &vam->elog_main;
20048   unformat_input_t *i = vam->input;
20049   char *file, *chroot_file;
20050   clib_error_t *error;
20051
20052   if (!unformat (i, "%s", &file))
20053     {
20054       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20055       return 0;
20056     }
20057
20058   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20059   if (strstr (file, "..") || index (file, '/'))
20060     {
20061       errmsg ("illegal characters in filename '%s'", file);
20062       return 0;
20063     }
20064
20065   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20066
20067   vec_free (file);
20068
20069   errmsg ("Saving %wd of %wd events to %s",
20070           elog_n_events_in_buffer (em),
20071           elog_buffer_capacity (em), chroot_file);
20072
20073   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20074   vec_free (chroot_file);
20075
20076   if (error)
20077     clib_error_report (error);
20078 #else
20079   errmsg ("Use the vpp event loger...");
20080 #endif
20081
20082   return 0;
20083 }
20084
20085 static int
20086 elog_setup (vat_main_t * vam)
20087 {
20088 #if VPP_API_TEST_BUILTIN == 0
20089   elog_main_t *em = &vam->elog_main;
20090   unformat_input_t *i = vam->input;
20091   u32 nevents = 128 << 10;
20092
20093   (void) unformat (i, "nevents %d", &nevents);
20094
20095   elog_init (em, nevents);
20096   vl_api_set_elog_main (em);
20097   vl_api_set_elog_trace_api_messages (1);
20098   errmsg ("Event logger initialized with %u events", nevents);
20099 #else
20100   errmsg ("Use the vpp event loger...");
20101 #endif
20102   return 0;
20103 }
20104
20105 static int
20106 elog_enable (vat_main_t * vam)
20107 {
20108 #if VPP_API_TEST_BUILTIN == 0
20109   elog_main_t *em = &vam->elog_main;
20110
20111   elog_enable_disable (em, 1 /* enable */ );
20112   vl_api_set_elog_trace_api_messages (1);
20113   errmsg ("Event logger enabled...");
20114 #else
20115   errmsg ("Use the vpp event loger...");
20116 #endif
20117   return 0;
20118 }
20119
20120 static int
20121 elog_disable (vat_main_t * vam)
20122 {
20123 #if VPP_API_TEST_BUILTIN == 0
20124   elog_main_t *em = &vam->elog_main;
20125
20126   elog_enable_disable (em, 0 /* enable */ );
20127   vl_api_set_elog_trace_api_messages (1);
20128   errmsg ("Event logger disabled...");
20129 #else
20130   errmsg ("Use the vpp event loger...");
20131 #endif
20132   return 0;
20133 }
20134
20135 static int
20136 statseg (vat_main_t * vam)
20137 {
20138   ssvm_private_t *ssvmp = &vam->stat_segment;
20139   ssvm_shared_header_t *shared_header = ssvmp->sh;
20140   vlib_counter_t **counters;
20141   u64 thread0_index1_packets;
20142   u64 thread0_index1_bytes;
20143   f64 vector_rate, input_rate;
20144   uword *p;
20145
20146   uword *counter_vector_by_name;
20147   if (vam->stat_segment_lockp == 0)
20148     {
20149       errmsg ("Stat segment not mapped...");
20150       return -99;
20151     }
20152
20153   /* look up "/if/rx for sw_if_index 1 as a test */
20154
20155   clib_spinlock_lock (vam->stat_segment_lockp);
20156
20157   counter_vector_by_name = (uword *) shared_header->opaque[1];
20158
20159   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20160   if (p == 0)
20161     {
20162       clib_spinlock_unlock (vam->stat_segment_lockp);
20163       errmsg ("/if/tx not found?");
20164       return -99;
20165     }
20166
20167   /* Fish per-thread vector of combined counters from shared memory */
20168   counters = (vlib_counter_t **) p[0];
20169
20170   if (vec_len (counters[0]) < 2)
20171     {
20172       clib_spinlock_unlock (vam->stat_segment_lockp);
20173       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20174       return -99;
20175     }
20176
20177   /* Read thread 0 sw_if_index 1 counter */
20178   thread0_index1_packets = counters[0][1].packets;
20179   thread0_index1_bytes = counters[0][1].bytes;
20180
20181   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20182   if (p == 0)
20183     {
20184       clib_spinlock_unlock (vam->stat_segment_lockp);
20185       errmsg ("vector_rate not found?");
20186       return -99;
20187     }
20188
20189   vector_rate = *(f64 *) (p[0]);
20190   p = hash_get_mem (counter_vector_by_name, "input_rate");
20191   if (p == 0)
20192     {
20193       clib_spinlock_unlock (vam->stat_segment_lockp);
20194       errmsg ("input_rate not found?");
20195       return -99;
20196     }
20197   input_rate = *(f64 *) (p[0]);
20198
20199   clib_spinlock_unlock (vam->stat_segment_lockp);
20200
20201   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20202          vector_rate, input_rate);
20203   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20204          thread0_index1_packets, thread0_index1_bytes);
20205
20206   return 0;
20207 }
20208
20209 static int
20210 cmd_cmp (void *a1, void *a2)
20211 {
20212   u8 **c1 = a1;
20213   u8 **c2 = a2;
20214
20215   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20216 }
20217
20218 static int
20219 help (vat_main_t * vam)
20220 {
20221   u8 **cmds = 0;
20222   u8 *name = 0;
20223   hash_pair_t *p;
20224   unformat_input_t *i = vam->input;
20225   int j;
20226
20227   if (unformat (i, "%s", &name))
20228     {
20229       uword *hs;
20230
20231       vec_add1 (name, 0);
20232
20233       hs = hash_get_mem (vam->help_by_name, name);
20234       if (hs)
20235         print (vam->ofp, "usage: %s %s", name, hs[0]);
20236       else
20237         print (vam->ofp, "No such msg / command '%s'", name);
20238       vec_free (name);
20239       return 0;
20240     }
20241
20242   print (vam->ofp, "Help is available for the following:");
20243
20244     /* *INDENT-OFF* */
20245     hash_foreach_pair (p, vam->function_by_name,
20246     ({
20247       vec_add1 (cmds, (u8 *)(p->key));
20248     }));
20249     /* *INDENT-ON* */
20250
20251   vec_sort_with_function (cmds, cmd_cmp);
20252
20253   for (j = 0; j < vec_len (cmds); j++)
20254     print (vam->ofp, "%s", cmds[j]);
20255
20256   vec_free (cmds);
20257   return 0;
20258 }
20259
20260 static int
20261 set (vat_main_t * vam)
20262 {
20263   u8 *name = 0, *value = 0;
20264   unformat_input_t *i = vam->input;
20265
20266   if (unformat (i, "%s", &name))
20267     {
20268       /* The input buffer is a vector, not a string. */
20269       value = vec_dup (i->buffer);
20270       vec_delete (value, i->index, 0);
20271       /* Almost certainly has a trailing newline */
20272       if (value[vec_len (value) - 1] == '\n')
20273         value[vec_len (value) - 1] = 0;
20274       /* Make sure it's a proper string, one way or the other */
20275       vec_add1 (value, 0);
20276       (void) clib_macro_set_value (&vam->macro_main,
20277                                    (char *) name, (char *) value);
20278     }
20279   else
20280     errmsg ("usage: set <name> <value>");
20281
20282   vec_free (name);
20283   vec_free (value);
20284   return 0;
20285 }
20286
20287 static int
20288 unset (vat_main_t * vam)
20289 {
20290   u8 *name = 0;
20291
20292   if (unformat (vam->input, "%s", &name))
20293     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20294       errmsg ("unset: %s wasn't set", name);
20295   vec_free (name);
20296   return 0;
20297 }
20298
20299 typedef struct
20300 {
20301   u8 *name;
20302   u8 *value;
20303 } macro_sort_t;
20304
20305
20306 static int
20307 macro_sort_cmp (void *a1, void *a2)
20308 {
20309   macro_sort_t *s1 = a1;
20310   macro_sort_t *s2 = a2;
20311
20312   return strcmp ((char *) (s1->name), (char *) (s2->name));
20313 }
20314
20315 static int
20316 dump_macro_table (vat_main_t * vam)
20317 {
20318   macro_sort_t *sort_me = 0, *sm;
20319   int i;
20320   hash_pair_t *p;
20321
20322     /* *INDENT-OFF* */
20323     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20324     ({
20325       vec_add2 (sort_me, sm, 1);
20326       sm->name = (u8 *)(p->key);
20327       sm->value = (u8 *) (p->value[0]);
20328     }));
20329     /* *INDENT-ON* */
20330
20331   vec_sort_with_function (sort_me, macro_sort_cmp);
20332
20333   if (vec_len (sort_me))
20334     print (vam->ofp, "%-15s%s", "Name", "Value");
20335   else
20336     print (vam->ofp, "The macro table is empty...");
20337
20338   for (i = 0; i < vec_len (sort_me); i++)
20339     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20340   return 0;
20341 }
20342
20343 static int
20344 dump_node_table (vat_main_t * vam)
20345 {
20346   int i, j;
20347   vlib_node_t *node, *next_node;
20348
20349   if (vec_len (vam->graph_nodes) == 0)
20350     {
20351       print (vam->ofp, "Node table empty, issue get_node_graph...");
20352       return 0;
20353     }
20354
20355   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20356     {
20357       node = vam->graph_nodes[0][i];
20358       print (vam->ofp, "[%d] %s", i, node->name);
20359       for (j = 0; j < vec_len (node->next_nodes); j++)
20360         {
20361           if (node->next_nodes[j] != ~0)
20362             {
20363               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20364               print (vam->ofp, "  [%d] %s", j, next_node->name);
20365             }
20366         }
20367     }
20368   return 0;
20369 }
20370
20371 static int
20372 value_sort_cmp (void *a1, void *a2)
20373 {
20374   name_sort_t *n1 = a1;
20375   name_sort_t *n2 = a2;
20376
20377   if (n1->value < n2->value)
20378     return -1;
20379   if (n1->value > n2->value)
20380     return 1;
20381   return 0;
20382 }
20383
20384
20385 static int
20386 dump_msg_api_table (vat_main_t * vam)
20387 {
20388   api_main_t *am = vlibapi_get_main ();
20389   name_sort_t *nses = 0, *ns;
20390   hash_pair_t *hp;
20391   int i;
20392
20393   /* *INDENT-OFF* */
20394   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20395   ({
20396     vec_add2 (nses, ns, 1);
20397     ns->name = (u8 *)(hp->key);
20398     ns->value = (u32) hp->value[0];
20399   }));
20400   /* *INDENT-ON* */
20401
20402   vec_sort_with_function (nses, value_sort_cmp);
20403
20404   for (i = 0; i < vec_len (nses); i++)
20405     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20406   vec_free (nses);
20407   return 0;
20408 }
20409
20410 static int
20411 get_msg_id (vat_main_t * vam)
20412 {
20413   u8 *name_and_crc;
20414   u32 message_index;
20415
20416   if (unformat (vam->input, "%s", &name_and_crc))
20417     {
20418       message_index = vl_msg_api_get_msg_index (name_and_crc);
20419       if (message_index == ~0)
20420         {
20421           print (vam->ofp, " '%s' not found", name_and_crc);
20422           return 0;
20423         }
20424       print (vam->ofp, " '%s' has message index %d",
20425              name_and_crc, message_index);
20426       return 0;
20427     }
20428   errmsg ("name_and_crc required...");
20429   return 0;
20430 }
20431
20432 static int
20433 search_node_table (vat_main_t * vam)
20434 {
20435   unformat_input_t *line_input = vam->input;
20436   u8 *node_to_find;
20437   int j;
20438   vlib_node_t *node, *next_node;
20439   uword *p;
20440
20441   if (vam->graph_node_index_by_name == 0)
20442     {
20443       print (vam->ofp, "Node table empty, issue get_node_graph...");
20444       return 0;
20445     }
20446
20447   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20448     {
20449       if (unformat (line_input, "%s", &node_to_find))
20450         {
20451           vec_add1 (node_to_find, 0);
20452           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20453           if (p == 0)
20454             {
20455               print (vam->ofp, "%s not found...", node_to_find);
20456               goto out;
20457             }
20458           node = vam->graph_nodes[0][p[0]];
20459           print (vam->ofp, "[%d] %s", p[0], node->name);
20460           for (j = 0; j < vec_len (node->next_nodes); j++)
20461             {
20462               if (node->next_nodes[j] != ~0)
20463                 {
20464                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20465                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20466                 }
20467             }
20468         }
20469
20470       else
20471         {
20472           clib_warning ("parse error '%U'", format_unformat_error,
20473                         line_input);
20474           return -99;
20475         }
20476
20477     out:
20478       vec_free (node_to_find);
20479
20480     }
20481
20482   return 0;
20483 }
20484
20485
20486 static int
20487 script (vat_main_t * vam)
20488 {
20489 #if (VPP_API_TEST_BUILTIN==0)
20490   u8 *s = 0;
20491   char *save_current_file;
20492   unformat_input_t save_input;
20493   jmp_buf save_jump_buf;
20494   u32 save_line_number;
20495
20496   FILE *new_fp, *save_ifp;
20497
20498   if (unformat (vam->input, "%s", &s))
20499     {
20500       new_fp = fopen ((char *) s, "r");
20501       if (new_fp == 0)
20502         {
20503           errmsg ("Couldn't open script file %s", s);
20504           vec_free (s);
20505           return -99;
20506         }
20507     }
20508   else
20509     {
20510       errmsg ("Missing script name");
20511       return -99;
20512     }
20513
20514   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20515   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20516   save_ifp = vam->ifp;
20517   save_line_number = vam->input_line_number;
20518   save_current_file = (char *) vam->current_file;
20519
20520   vam->input_line_number = 0;
20521   vam->ifp = new_fp;
20522   vam->current_file = s;
20523   do_one_file (vam);
20524
20525   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20526   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20527   vam->ifp = save_ifp;
20528   vam->input_line_number = save_line_number;
20529   vam->current_file = (u8 *) save_current_file;
20530   vec_free (s);
20531
20532   return 0;
20533 #else
20534   clib_warning ("use the exec command...");
20535   return -99;
20536 #endif
20537 }
20538
20539 static int
20540 echo (vat_main_t * vam)
20541 {
20542   print (vam->ofp, "%v", vam->input->buffer);
20543   return 0;
20544 }
20545
20546 /* List of API message constructors, CLI names map to api_xxx */
20547 #define foreach_vpe_api_msg                                             \
20548 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20549 _(sw_interface_dump,"")                                                 \
20550 _(sw_interface_set_flags,                                               \
20551   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20552 _(sw_interface_add_del_address,                                         \
20553   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20554 _(sw_interface_set_rx_mode,                                             \
20555   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20556 _(sw_interface_set_rx_placement,                                        \
20557   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20558 _(sw_interface_rx_placement_dump,                                       \
20559   "[<intfc> | sw_if_index <id>]")                                         \
20560 _(sw_interface_set_table,                                               \
20561   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20562 _(sw_interface_set_mpls_enable,                                         \
20563   "<intfc> | sw_if_index [disable | dis]")                              \
20564 _(sw_interface_set_vpath,                                               \
20565   "<intfc> | sw_if_index <id> enable | disable")                        \
20566 _(sw_interface_set_vxlan_bypass,                                        \
20567   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20568 _(sw_interface_set_geneve_bypass,                                       \
20569   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20570 _(sw_interface_set_l2_xconnect,                                         \
20571   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20572   "enable | disable")                                                   \
20573 _(sw_interface_set_l2_bridge,                                           \
20574   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20575   "[shg <split-horizon-group>] [bvi]\n"                                 \
20576   "enable | disable")                                                   \
20577 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20578 _(bridge_domain_add_del,                                                \
20579   "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") \
20580 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20581 _(l2fib_add_del,                                                        \
20582   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20583 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20584 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20585 _(l2_flags,                                                             \
20586   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20587 _(bridge_flags,                                                         \
20588   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20589 _(tap_create_v2,                                                        \
20590   "id <num> [hw-addr <mac-addr>] [host-if-name <name>] [host-ns <name>] [num-rx-queues <num>] [rx-ring-size <num>] [tx-ring-size <num>] [host-bridge <name>] [host-mac-addr <mac-addr>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6addr/mask>] [host-mtu-size <mtu>] [gso | no-gso | csum-offload] [persist] [attach]") \
20591 _(tap_delete_v2,                                                        \
20592   "<vpp-if-name> | sw_if_index <id>")                                   \
20593 _(sw_interface_tap_v2_dump, "")                                         \
20594 _(virtio_pci_create,                                                    \
20595   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20596 _(virtio_pci_delete,                                                    \
20597   "<vpp-if-name> | sw_if_index <id>")                                   \
20598 _(sw_interface_virtio_pci_dump, "")                                     \
20599 _(bond_create,                                                          \
20600   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20601   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20602   "[id <if-id>]")                                                       \
20603 _(bond_delete,                                                          \
20604   "<vpp-if-name> | sw_if_index <id>")                                   \
20605 _(bond_enslave,                                                         \
20606   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20607 _(bond_detach_slave,                                                    \
20608   "sw_if_index <n>")                                                    \
20609  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20610 _(sw_interface_bond_dump, "")                                           \
20611 _(sw_interface_slave_dump,                                              \
20612   "<vpp-if-name> | sw_if_index <id>")                                   \
20613 _(ip_table_add_del,                                                     \
20614   "table <n> [ipv6] [add | del]\n")                                     \
20615 _(ip_route_add_del,                                                     \
20616   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20617   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20618   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20619   "[multipath] [count <n>] [del]")                                      \
20620 _(ip_mroute_add_del,                                                    \
20621   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20622   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20623 _(mpls_table_add_del,                                                   \
20624   "table <n> [add | del]\n")                                            \
20625 _(mpls_route_add_del,                                                   \
20626   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20627   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20628   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20629   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20630   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20631   "[count <n>] [del]")                                                  \
20632 _(mpls_ip_bind_unbind,                                                  \
20633   "<label> <addr/len>")                                                 \
20634 _(mpls_tunnel_add_del,                                                  \
20635   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20636   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20637   "[l2-only]  [out-label <n>]")                                         \
20638 _(sr_mpls_policy_add,                                                   \
20639   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20640 _(sr_mpls_policy_del,                                                   \
20641   "bsid <id>")                                                          \
20642 _(bier_table_add_del,                                                   \
20643   "<label> <sub-domain> <set> <bsl> [del]")                             \
20644 _(bier_route_add_del,                                                   \
20645   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20646   "[<intfc> | sw_if_index <id>]"                                        \
20647   "[weight <n>] [del] [multipath]")                                     \
20648 _(sw_interface_set_unnumbered,                                          \
20649   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20650 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20651 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20652   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20653   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20654   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20655 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20656 _(ip_table_flush, "table <n> [ipv6]")                                   \
20657 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20658 _(set_ip_flow_hash,                                                     \
20659   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20660 _(sw_interface_ip6_enable_disable,                                      \
20661   "<intfc> | sw_if_index <id> enable | disable")                        \
20662 _(l2_patch_add_del,                                                     \
20663   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20664   "enable | disable")                                                   \
20665 _(sr_localsid_add_del,                                                  \
20666   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20667   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20668 _(classify_add_del_table,                                               \
20669   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20670   " [del] [del-chain] mask <mask-value>\n"                              \
20671   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20672   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20673 _(classify_add_del_session,                                             \
20674   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20675   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20676   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20677   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20678 _(classify_set_interface_ip_table,                                      \
20679   "<intfc> | sw_if_index <nn> table <nn>")                              \
20680 _(classify_set_interface_l2_tables,                                     \
20681   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20682   "  [other-table <nn>]")                                               \
20683 _(get_node_index, "node <node-name")                                    \
20684 _(add_node_next, "node <node-name> next <next-node-name>")              \
20685 _(l2tpv3_create_tunnel,                                                 \
20686   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20687   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20688   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20689 _(l2tpv3_set_tunnel_cookies,                                            \
20690   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20691   "[new_remote_cookie <nn>]\n")                                         \
20692 _(l2tpv3_interface_enable_disable,                                      \
20693   "<intfc> | sw_if_index <nn> enable | disable")                        \
20694 _(l2tpv3_set_lookup_key,                                                \
20695   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20696 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20697 _(vxlan_offload_rx,                                                     \
20698   "hw { <interface name> | hw_if_index <nn>} "                          \
20699   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20700 _(vxlan_add_del_tunnel,                                                 \
20701   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20702   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20703   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20704 _(geneve_add_del_tunnel,                                                \
20705   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20706   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20707   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20708 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20709 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20710 _(gre_tunnel_add_del,                                                   \
20711   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20712   "[teb | erspan <session-id>] [del]")                                  \
20713 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20714 _(l2_fib_clear_table, "")                                               \
20715 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20716 _(l2_interface_vlan_tag_rewrite,                                        \
20717   "<intfc> | sw_if_index <nn> \n"                                       \
20718   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20719   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20720 _(create_vhost_user_if,                                                 \
20721         "socket <filename> [server] [renumber <dev_instance>] "         \
20722         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20723         "[mac <mac_address>] [packed]")                                 \
20724 _(modify_vhost_user_if,                                                 \
20725         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20726         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20727 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20728 _(sw_interface_vhost_user_dump, "")                                     \
20729 _(show_version, "")                                                     \
20730 _(show_threads, "")                                                     \
20731 _(vxlan_gpe_add_del_tunnel,                                             \
20732   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20733   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20734   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20735   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20736 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20737 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20738 _(interface_name_renumber,                                              \
20739   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20740 _(input_acl_set_interface,                                              \
20741   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20742   "  [l2-table <nn>] [del]")                                            \
20743 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20744 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20745 _(ip_dump, "ipv4 | ipv6")                                               \
20746 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20747 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20748   "  spid_id <n> ")                                                     \
20749 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20750   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20751   "  integ_alg <alg> integ_key <hex>")                                  \
20752 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20753   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20754   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20755   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20756 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20757   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20758   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20759   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20760   "  [instance <n>]")     \
20761 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20762 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20763 _(delete_loopback,"sw_if_index <nn>")                                   \
20764 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20765 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20766 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20767 _(want_interface_events,  "enable|disable")                             \
20768 _(get_first_msg_id, "client <name>")                                    \
20769 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20770 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20771   "fib-id <nn> [ip4][ip6][default]")                                    \
20772 _(get_node_graph, " ")                                                  \
20773 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20774 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20775 _(ioam_disable, "")                                                     \
20776 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20777                             " sw_if_index <sw_if_index> p <priority> "  \
20778                             "w <weight>] [del]")                        \
20779 _(one_add_del_locator, "locator-set <locator_name> "                    \
20780                         "iface <intf> | sw_if_index <sw_if_index> "     \
20781                         "p <priority> w <weight> [del]")                \
20782 _(one_add_del_local_eid,"vni <vni> eid "                                \
20783                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20784                          "locator-set <locator_name> [del]"             \
20785                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20786 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20787 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20788 _(one_enable_disable, "enable|disable")                                 \
20789 _(one_map_register_enable_disable, "enable|disable")                    \
20790 _(one_map_register_fallback_threshold, "<value>")                       \
20791 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20792 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20793                                "[seid <seid>] "                         \
20794                                "rloc <locator> p <prio> "               \
20795                                "w <weight> [rloc <loc> ... ] "          \
20796                                "action <action> [del-all]")             \
20797 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20798                           "<local-eid>")                                \
20799 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20800 _(one_use_petr, "ip-address> | disable")                                \
20801 _(one_map_request_mode, "src-dst|dst-only")                             \
20802 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20803 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20804 _(one_locator_set_dump, "[local | remote]")                             \
20805 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20806 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20807                        "[local] | [remote]")                            \
20808 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20809 _(one_ndp_bd_get, "")                                                   \
20810 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20811 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20812 _(one_l2_arp_bd_get, "")                                                \
20813 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20814 _(one_stats_enable_disable, "enable|disable")                           \
20815 _(show_one_stats_enable_disable, "")                                    \
20816 _(one_eid_table_vni_dump, "")                                           \
20817 _(one_eid_table_map_dump, "l2|l3")                                      \
20818 _(one_map_resolver_dump, "")                                            \
20819 _(one_map_server_dump, "")                                              \
20820 _(one_adjacencies_get, "vni <vni>")                                     \
20821 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20822 _(show_one_rloc_probe_state, "")                                        \
20823 _(show_one_map_register_state, "")                                      \
20824 _(show_one_status, "")                                                  \
20825 _(one_stats_dump, "")                                                   \
20826 _(one_stats_flush, "")                                                  \
20827 _(one_get_map_request_itr_rlocs, "")                                    \
20828 _(one_map_register_set_ttl, "<ttl>")                                    \
20829 _(one_set_transport_protocol, "udp|api")                                \
20830 _(one_get_transport_protocol, "")                                       \
20831 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20832 _(one_show_xtr_mode, "")                                                \
20833 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20834 _(one_show_pitr_mode, "")                                               \
20835 _(one_enable_disable_petr_mode, "enable|disable")                       \
20836 _(one_show_petr_mode, "")                                               \
20837 _(show_one_nsh_mapping, "")                                             \
20838 _(show_one_pitr, "")                                                    \
20839 _(show_one_use_petr, "")                                                \
20840 _(show_one_map_request_mode, "")                                        \
20841 _(show_one_map_register_ttl, "")                                        \
20842 _(show_one_map_register_fallback_threshold, "")                         \
20843 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20844                             " sw_if_index <sw_if_index> p <priority> "  \
20845                             "w <weight>] [del]")                        \
20846 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20847                         "iface <intf> | sw_if_index <sw_if_index> "     \
20848                         "p <priority> w <weight> [del]")                \
20849 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20850                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20851                          "locator-set <locator_name> [del]"             \
20852                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20853 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20854 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20855 _(lisp_enable_disable, "enable|disable")                                \
20856 _(lisp_map_register_enable_disable, "enable|disable")                   \
20857 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20858 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20859                                "[seid <seid>] "                         \
20860                                "rloc <locator> p <prio> "               \
20861                                "w <weight> [rloc <loc> ... ] "          \
20862                                "action <action> [del-all]")             \
20863 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20864                           "<local-eid>")                                \
20865 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20866 _(lisp_use_petr, "<ip-address> | disable")                              \
20867 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20868 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20869 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20870 _(lisp_locator_set_dump, "[local | remote]")                            \
20871 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20872 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20873                        "[local] | [remote]")                            \
20874 _(lisp_eid_table_vni_dump, "")                                          \
20875 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20876 _(lisp_map_resolver_dump, "")                                           \
20877 _(lisp_map_server_dump, "")                                             \
20878 _(lisp_adjacencies_get, "vni <vni>")                                    \
20879 _(gpe_fwd_entry_vnis_get, "")                                           \
20880 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20881 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20882                                 "[table <table-id>]")                   \
20883 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20884 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20885 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20886 _(gpe_get_encap_mode, "")                                               \
20887 _(lisp_gpe_add_del_iface, "up|down")                                    \
20888 _(lisp_gpe_enable_disable, "enable|disable")                            \
20889 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20890   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20891 _(show_lisp_rloc_probe_state, "")                                       \
20892 _(show_lisp_map_register_state, "")                                     \
20893 _(show_lisp_status, "")                                                 \
20894 _(lisp_get_map_request_itr_rlocs, "")                                   \
20895 _(show_lisp_pitr, "")                                                   \
20896 _(show_lisp_use_petr, "")                                               \
20897 _(show_lisp_map_request_mode, "")                                       \
20898 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20899 _(af_packet_delete, "name <host interface name>")                       \
20900 _(af_packet_dump, "")                                                   \
20901 _(policer_add_del, "name <policer name> <params> [del]")                \
20902 _(policer_dump, "[name <policer name>]")                                \
20903 _(policer_classify_set_interface,                                       \
20904   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20905   "  [l2-table <nn>] [del]")                                            \
20906 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20907 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20908 _(mpls_table_dump, "")                                                  \
20909 _(mpls_route_dump, "table-id <ID>")                                     \
20910 _(classify_table_ids, "")                                               \
20911 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20912 _(classify_table_info, "table_id <nn>")                                 \
20913 _(classify_session_dump, "table_id <nn>")                               \
20914 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20915     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20916     "[template_interval <nn>] [udp_checksum]")                          \
20917 _(ipfix_exporter_dump, "")                                              \
20918 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20919 _(ipfix_classify_stream_dump, "")                                       \
20920 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20921 _(ipfix_classify_table_dump, "")                                        \
20922 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20923 _(sw_interface_span_dump, "[l2]")                                           \
20924 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20925 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20926 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20927 _(pg_enable_disable, "[stream <id>] disable")                           \
20928 _(ip_source_and_port_range_check_add_del,                               \
20929   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20930 _(ip_source_and_port_range_check_interface_add_del,                     \
20931   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20932   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20933 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20934 _(l2_interface_pbb_tag_rewrite,                                         \
20935   "<intfc> | sw_if_index <nn> \n"                                       \
20936   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20937   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20938 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20939 _(flow_classify_set_interface,                                          \
20940   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20941 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20942 _(ip_table_dump, "")                                                    \
20943 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20944 _(ip_mtable_dump, "")                                                   \
20945 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
20946 _(feature_enable_disable, "arc_name <arc_name> "                        \
20947   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20948 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
20949   "[enable | disable] ")                                                \
20950 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20951 "[disable]")                                                            \
20952 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
20953   "mac <mac-address> [del]")                                            \
20954 _(l2_xconnect_dump, "")                                                 \
20955 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
20956 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20957 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20958 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20959 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20960 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
20961   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
20962 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
20963 _(sock_init_shm, "size <nnn>")                                          \
20964 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
20965 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
20966   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
20967 _(session_rules_dump, "")                                               \
20968 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
20969 _(output_acl_set_interface,                                             \
20970   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20971   "  [l2-table <nn>] [del]")                                            \
20972 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
20973
20974 /* List of command functions, CLI names map directly to functions */
20975 #define foreach_cli_function                                    \
20976 _(comment, "usage: comment <ignore-rest-of-line>")              \
20977 _(dump_interface_table, "usage: dump_interface_table")          \
20978 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20979 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20980 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20981 _(dump_macro_table, "usage: dump_macro_table ")                 \
20982 _(dump_node_table, "usage: dump_node_table")                    \
20983 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20984 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
20985 _(elog_disable, "usage: elog_disable")                          \
20986 _(elog_enable, "usage: elog_enable")                            \
20987 _(elog_save, "usage: elog_save <filename>")                     \
20988 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20989 _(echo, "usage: echo <message>")                                \
20990 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20991 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20992 _(help, "usage: help")                                          \
20993 _(q, "usage: quit")                                             \
20994 _(quit, "usage: quit")                                          \
20995 _(search_node_table, "usage: search_node_table <name>...")      \
20996 _(set, "usage: set <variable-name> <value>")                    \
20997 _(script, "usage: script <file-name>")                          \
20998 _(statseg, "usage: statseg")                                    \
20999 _(unset, "usage: unset <variable-name>")
21000
21001 #define _(N,n)                                  \
21002     static void vl_api_##n##_t_handler_uni      \
21003     (vl_api_##n##_t * mp)                       \
21004     {                                           \
21005         vat_main_t * vam = &vat_main;           \
21006         if (vam->json_output) {                 \
21007             vl_api_##n##_t_handler_json(mp);    \
21008         } else {                                \
21009             vl_api_##n##_t_handler(mp);         \
21010         }                                       \
21011     }
21012 foreach_vpe_api_reply_msg;
21013 #if VPP_API_TEST_BUILTIN == 0
21014 foreach_standalone_reply_msg;
21015 #endif
21016 #undef _
21017
21018 void
21019 vat_api_hookup (vat_main_t * vam)
21020 {
21021 #define _(N,n)                                                  \
21022     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21023                            vl_api_##n##_t_handler_uni,          \
21024                            vl_noop_handler,                     \
21025                            vl_api_##n##_t_endian,               \
21026                            vl_api_##n##_t_print,                \
21027                            sizeof(vl_api_##n##_t), 1);
21028   foreach_vpe_api_reply_msg;
21029 #if VPP_API_TEST_BUILTIN == 0
21030   foreach_standalone_reply_msg;
21031 #endif
21032 #undef _
21033
21034 #if (VPP_API_TEST_BUILTIN==0)
21035   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21036
21037   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21038
21039   vam->function_by_name = hash_create_string (0, sizeof (uword));
21040
21041   vam->help_by_name = hash_create_string (0, sizeof (uword));
21042 #endif
21043
21044   /* API messages we can send */
21045 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21046   foreach_vpe_api_msg;
21047 #undef _
21048
21049   /* Help strings */
21050 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21051   foreach_vpe_api_msg;
21052 #undef _
21053
21054   /* CLI functions */
21055 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21056   foreach_cli_function;
21057 #undef _
21058
21059   /* Help strings */
21060 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21061   foreach_cli_function;
21062 #undef _
21063 }
21064
21065 #if VPP_API_TEST_BUILTIN
21066 static clib_error_t *
21067 vat_api_hookup_shim (vlib_main_t * vm)
21068 {
21069   vat_api_hookup (&vat_main);
21070   return 0;
21071 }
21072
21073 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21074 #endif
21075
21076 /*
21077  * fd.io coding-style-patch-verification: ON
21078  *
21079  * Local Variables:
21080  * eval: (c-set-style "gnu")
21081  * End:
21082  */